Esempio n. 1
0
 def __init__(self):
     self.free_ips = []
     self.reserved_ips = []
     self.ips = {}
     self.num_ips = 1
     self.num_addrs = 0
     self.nat = NAT()
     self._init_state_db()
Esempio n. 2
0
 def __init__(self):
     self.free_ips = []
     self.reserved_ips = []
     self.ips = {}
     self.num_ips = 1
     self.num_addrs = 0
     self.nat = NAT()
     self._init_state_db()
Esempio n. 3
0
class DHCP(object):
    def __init__(self):
        self.free_ips = []
        self.reserved_ips = []
        self.ips = {}
        self.num_ips = 1
        self.num_addrs = 0
        self.nat = NAT()
        self._init_state_db()

    def assign_cidr(self, cidr_block):
        if self.num_addrs == 0:
            self.cidr_collection.insert({'cidr': cidr_block})
            self._parse_cidr(cidr_block)

    def _parse_cidr(self, cidr_block):
        self.gw_ip, self.prefix = self._parse_cidr_address(cidr_block)
        addr = map(int, self.gw_ip.split("."))
        if self.prefix == 24:
            self.latest_ip = "%d.%d.%d.0" % (addr[0], addr[1], addr[2])
        elif self.prefix == 16:
            self.latest_ip = "%d.%d.0.0" % (addr[0], addr[1])
        self.num_addrs = 2**(32 - self.prefix)

    def _init_state_db(self):
        self.mongo = MongoClient(os.environ['MONGODB'],
                                 27017,
                                 connectTimeoutMS=6000)
        self.dhcp_collection = self.mongo['network']['dhcp']
        self.cidr_collection = self.mongo['network']['cidr']

        cidr = self.cidr_collection.find_one()
        if cidr:
            logging.warning("recovering network gateway: " + str(cidr['cidr']))
            self._parse_cidr(cidr['cidr'])

        all_ips = self.dhcp_collection.find()
        if all_ips:
            logging.warning("recovering assigned IP addresses")
            for ip_status in all_ips:
                ip = ip_status['ip']
                status = ip_status['status']
                self.num_ips += 1
                self.ips[ip] = {'status': status}

                if status == 'free':
                    self.free_ips.append(ip)
                else:
                    self.ips[ip]['container'] = ip_status['container']

                self._recover_latest_ip(ip)

    def _recover_latest_ip(self, ip):
        l = map(int, self.latest_ip.split("."))
        s = map(int, ip.split("."))

        for i in [0, 1, 2, 3]:
            if s[i] > l[i]:
                self.latest_ip = ip
                break
            elif l[i] > s[i]:
                break

    def _parse_cidr_address(self, block):
        s = block.split("/")
        return s[0], int(s[1])

    def _increment_ip(self):
        if self.num_ips < self.num_addrs:
            s = map(int, self.latest_ip.split("."))
            for i in [3, 2, 1, 0]:
                if s[i] < 255:
                    s[i] += 1
                    break
                else:
                    s[i] = 0

            # Make sure we skip over the gateway IP.
            self.latest_ip = "%d.%d.%d.%d" % (s[0], s[1], s[2], s[3])
            if self.latest_ip == self.gw_ip:
                return self._increment_ip()
            elif self.latest_ip in self.reserved_ips:
                return self._increment_ip()
            else:
                self.num_ips += 1
                return self.latest_ip

    def _get_new_ip(self):
        if len(self.free_ips) > 0:
            return self.free_ips.pop(0)
        else:
            return self._increment_ip()

    def random_port(self):
        """
        Get a random port
        """
        return self.nat.random_port()

    def clean_rules(self):
        """
        Clean all rules
        """
        self.nat._clear_nat()

    def delete_rule(self, dest_ip, dest_port):
        """
        Delete port forwarding
        """
        self.nat.delete_rule(dest_ip, dest_port)

    def forward_rule(self, source_ip, source_port, dest_ip, dest_port):
        """
        Port forwarding
        """
        self.nat.forward_rule(source_ip, source_port, dest_ip, dest_port)

    def stop_ip(self, ip):
        """
        Store the container's IP for future use. 
        """
        self.ips[ip]['status'] = 'stopped'
        self.dhcp_collection.update({'ip': ip}, {'$set': self.ips[ip]},
                                    upsert=True)

    def reserve_ip(self, ip):
        """
        Reserve an IP. This basically takes this IP out of commission. 
        """
        self.reserved_ips.append(ip)

    def assign_ip(self, container):
        """
        Assign a new IP address. If the container is on the stopped list
        then re-assign the same IP address. 
        """
        if 'container' in container:
            for k in self.ips.keys():
                v = self.ips[k]
                if v['container'] == container['container']:
                    self.ips[k]['status'] = 'active'
                    self.dhcp_collection.update({'ip': k},
                                                {'$set': {
                                                    'status': 'active'
                                                }})

                    return k

        new_ip = self._get_new_ip()
        self.ips[new_ip] = {'status': 'active', 'container': None}
        self.dhcp_collection.update({'ip': new_ip}, {'$set': self.ips[new_ip]},
                                    upsert=True)
        return new_ip

    def free_ip(self, ip):
        """
        Container is being removed and the IP address should be freed. 
        """
        self.free_ips.append(ip)
        self.ips[ip] = {'status': 'free'}
        self.dhcp_collection.update({'ip': ip}, {'$set': self.ips[ip]})

    def set_owner(self, ip, container):
        """
        Set the owner of this IP address. 
        """
        self.ips[ip]['container'] = container
        self.dhcp_collection.update({'ip': ip},
                                    {'$set': {
                                        'container': container
                                    }})
Esempio n. 4
0
class DHCP(object):
    def __init__(self):
        self.free_ips = []
        self.reserved_ips = []
        self.ips = {}
        self.num_ips = 1
        self.num_addrs = 0
        self.nat = NAT()
        self._init_state_db()

    def assign_cidr(self, cidr_block):
        if self.num_addrs == 0:
            self.cidr_collection.insert( { 'cidr' : cidr_block } )
            self._parse_cidr(cidr_block)

    def _parse_cidr(self, cidr_block):
        self.gw_ip, self.prefix = self._parse_cidr_address(cidr_block)
        addr = map(int, self.gw_ip.split("."))
        if self.prefix == 24:
            self.latest_ip = "%d.%d.%d.0" % (addr[0], addr[1], addr[2])
        elif self.prefix == 16:
            self.latest_ip = "%d.%d.0.0" % (addr[0], addr[1])
        self.num_addrs = 2**(32 - self.prefix)

    def _init_state_db(self):
        self.mongo = MongoClient(os.environ['MONGODB'], 27017, connectTimeoutMS=6000)
        self.dhcp_collection = self.mongo['network']['dhcp']
        self.cidr_collection = self.mongo['network']['cidr']

        cidr = self.cidr_collection.find_one()
        if cidr:
            logging.warning("recovering network gateway: " + str(cidr['cidr']))
            self._parse_cidr(cidr['cidr'])

        all_ips = self.dhcp_collection.find()
        if all_ips:
            logging.warning("recovering assigned IP addresses")
            for ip_status in all_ips:
                ip = ip_status['ip']
                status = ip_status['status']
                self.num_ips += 1
                self.ips[ip] = { 'status' : status }

                if status == 'free':
                    self.free_ips.append(ip)
                else:
                    self.ips[ip]['container'] = ip_status['container']

                self._recover_latest_ip(ip)

    def _recover_latest_ip(self, ip):
        l = map(int, self.latest_ip.split("."))
        s = map(int, ip.split("."))

        for i in [0, 1, 2, 3]:
            if s[i] > l[i]:
                self.latest_ip = ip
                break
            elif l[i] > s[i]:
                break
                
    def _parse_cidr_address(self, block):
        s = block.split("/")
        return s[0], int(s[1])

    def _increment_ip(self):
        if self.num_ips < self.num_addrs:
            s = map(int, self.latest_ip.split("."))
            for i in [3, 2, 1, 0]:
                if s[i] < 255:
                    s[i] += 1
                    break
                else:
                    s[i] = 0

            # Make sure we skip over the gateway IP. 
            self.latest_ip = "%d.%d.%d.%d" % (s[0], s[1], s[2], s[3])
            if self.latest_ip == self.gw_ip:
                return self._increment_ip()
            elif self.latest_ip in self.reserved_ips:
                return self._increment_ip()
            else:
                self.num_ips += 1
                return self.latest_ip

    def _get_new_ip(self):
        if len(self.free_ips) > 0:
            return self.free_ips.pop(0)
        else:
            return self._increment_ip()

    def random_port(self):
        """
        Get a random port
        """
        return self.nat.random_port()

    def clean_rules(self):
        """
        Clean all rules
        """
        self.nat._clear_nat()

    def delete_rule(self, dest_ip, dest_port):
        """
        Delete port forwarding
        """
        self.nat.delete_rule(dest_ip, dest_port)

    def forward_rule(self, source_ip, source_port, dest_ip, dest_port):
        """
        Port forwarding
        """
        self.nat.forward_rule(source_ip, source_port, dest_ip, dest_port)

    def stop_ip(self, ip):
        """
        Store the container's IP for future use. 
        """
        self.ips[ip]['status'] = 'stopped'
        self.dhcp_collection.update( { 'ip' : ip },
                                     { '$set' : self.ips[ip] },
                                     upsert = True )

    def reserve_ip(self, ip):
        """
        Reserve an IP. This basically takes this IP out of commission. 
        """
        self.reserved_ips.append(ip)

    def assign_ip(self, container):
        """
        Assign a new IP address. If the container is on the stopped list
        then re-assign the same IP address. 
        """
        if 'container' in container:
            for k in self.ips.keys():
                v = self.ips[k]
                if v['container'] == container['container']:
                    self.ips[k]['status'] = 'active'
                    self.dhcp_collection.update( { 'ip' : k },
                                                 { '$set' : { 'status' : 'active' }} )
                                                 
                    return k
            
        new_ip = self._get_new_ip()
        self.ips[new_ip] = { 'status': 'active',
                             'container': None }
        self.dhcp_collection.update( { 'ip' : new_ip },
                                     { '$set' : self.ips[new_ip]},
                                     upsert = True )
        return new_ip

    def free_ip(self, ip):
        """
        Container is being removed and the IP address should be freed. 
        """
        self.free_ips.append(ip)
        self.ips[ip] = { 'status': 'free' }
        self.dhcp_collection.update( { 'ip' : ip },
                                     { '$set' : self.ips[ip] } )

    def set_owner(self, ip, container):
        """
        Set the owner of this IP address. 
        """
        self.ips[ip]['container'] = container
        self.dhcp_collection.update( { 'ip' : ip },
                                     { '$set' : { 'container' : container}} )