| #! /usr/bin/python3 |
| # Licensed to the Apache Software Foundation (ASF) under one |
| # or more contributor license agreements. See the NOTICE file |
| # distributed with this work for additional information |
| # regarding copyright ownership. The ASF licenses this file |
| # to you under the Apache License, Version 2.0 (the |
| # "License"); you may not use this file except in compliance |
| # with the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, |
| # software distributed under the License is distributed on an |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| # KIND, either express or implied. See the License for the |
| # specific language governing permissions and limitations |
| # under the License. |
| |
| |
| |
| |
| |
| import web |
| import socket, struct |
| import cloud_utils |
| from cloud_utils import Command |
| urls = ("/ipallocator", "ipallocator") |
| app = web.application(urls, globals()) |
| |
| augtool = Command("augtool") |
| service = Command("service") |
| class dhcp: |
| _instance = None |
| def __init__(self): |
| self.availIP=[] |
| self.router=None |
| self.netmask=None |
| self.initialized=False |
| |
| options = augtool.match("/files/etc/dnsmasq.conf/dhcp-option").stdout.decode('utf-8').strip() |
| for option in options.splitlines(): |
| if option.find("option:router") != -1: |
| self.router = option.split("=")[1].strip().split(",")[1] |
| print(self.router) |
| |
| dhcp_range = augtool.get("/files/etc/dnsmasq.conf/dhcp-range").stdout.decode('utf-8').strip() |
| dhcp_start = dhcp_range.split("=")[1].strip().split(",")[0] |
| dhcp_end = dhcp_range.split("=")[1].strip().split(",")[1] |
| self.netmask = dhcp_range.split("=")[1].strip().split(",")[2] |
| print(dhcp_start, dhcp_end, self.netmask) |
| |
| start_ip_num = self.ipToNum(dhcp_start); |
| end_ip_num = self.ipToNum(dhcp_end) |
| print(start_ip_num, end_ip_num) |
| |
| for ip in range(start_ip_num, end_ip_num + 1): |
| self.availIP.append(ip) |
| print(self.availIP[0], self.availIP[len(self.availIP) - 1]) |
| |
| #load the ip already allocated |
| self.reloadAllocatedIP() |
| |
| def ipToNum(self, ip): |
| return struct.unpack("!I", socket.inet_aton(ip))[0] |
| |
| def numToIp(self, num): |
| return socket.inet_ntoa(struct.pack('!I', num)) |
| |
| def getFreeIP(self): |
| if len(self.availIP) > 0: |
| ip = self.numToIp(self.availIP[0]) |
| self.availIP.remove(self.availIP[0]) |
| return ip |
| else: |
| return None |
| |
| def getNetmask(self): |
| return self.netmask |
| |
| def getRouter(self): |
| return self.router |
| |
| def getInstance(): |
| if not dhcp._instance: |
| dhcp._instance = dhcp() |
| return dhcp._instance |
| getInstance = staticmethod(getInstance) |
| |
| def reloadAllocatedIP(self): |
| dhcp_hosts = augtool.match("/files/etc/dnsmasq.conf/dhcp-host").stdout.decode('utf-8').strip().splitlines() |
| |
| for host in dhcp_hosts: |
| if host.find("dhcp-host") != -1: |
| allocatedIP = self.ipToNum(host.split("=")[1].strip().split(",")[1]) |
| if allocatedIP in self.availIP: |
| self.availIP.remove(allocatedIP) |
| |
| def allocateIP(self, mac): |
| newIP = self.getFreeIP() |
| dhcp_host = augtool.match("/files/etc/dnsmasq.conf/dhcp-host").stdout.decode('utf-8').strip() |
| cnt = len(dhcp_host.splitlines()) + 1 |
| script = """set %s %s |
| save"""%("/files/etc/dnsmasq.conf/dhcp-host[" + str(cnt) + "]", str(mac) + "," + newIP) |
| augtool < script |
| #reset dnsmasq |
| service("dnsmasq", "restart", stdout=None, stderr=None) |
| return newIP |
| |
| def releaseIP(self, ip): |
| dhcp_host = augtool.match("/files/etc/dnsmasq.conf/dhcp-host").stdout.decode('utf-8').strip() |
| path = None |
| for host in dhcp_host.splitlines(): |
| if host.find(ip) != -1: |
| path = host.split("=")[0].strip() |
| |
| if path == None: |
| print("Can't find " + str(ip) + " in conf file") |
| return None |
| |
| print(path) |
| script = """rm %s |
| save"""%(path) |
| augtool < script |
| |
| self.availIP.remove(ip) |
| |
| #reset dnsmasq |
| service("dnsmasq", "restart", stdout=None, stderr=None) |
| |
| class ipallocator: |
| def GET(self): |
| try: |
| user_data = web.input() |
| command = user_data.command |
| print("Processing: " + command) |
| |
| dhcpInit = dhcp.getInstance() |
| |
| if command == "getIpAddr": |
| mac = user_data.mac |
| zone_id = user_data.dc |
| pod_id = user_data.pod |
| print(mac, zone_id, pod_id) |
| freeIP = dhcpInit.allocateIP(mac) |
| if not freeIP: |
| return "0,0,0" |
| print("Find an available IP: " + freeIP) |
| |
| return freeIP + "," + dhcpInit.getNetmask() + "," + dhcpInit.getRouter() |
| elif command == "releaseIpAddr": |
| ip = user_data.ip |
| zone_id = user_data.dc |
| pod_id = user_data.pod |
| dhcpInit.releaseIP(ip) |
| except: |
| return None |
| |
| if __name__ == "__main__": |
| app.run() |