Esempio n. 1
0
class IPAllocatorStaticWrapper(IPAllocator):
    def __init__(
        self,
        store: MobilityStore,
        subscriberdb_rpc_stub: SubscriberDBStub,
        ip_allocator: IPAllocator,
        ipv6: bool = False,
    ):
        """ Initializes a static IP allocator
            This is wrapper around other configured Ip allocator. If subscriber
            does have static IP, it uses underlying IP allocator to allocate IP
            for the subscriber.
        """
        self._store = store
        self._subscriber_client = SubscriberDbClient(subscriberdb_rpc_stub)
        self._ip_allocator = ip_allocator
        if ipv6:
            self._ip_version = 6
        else:
            self._ip_version = 4

    def add_ip_block(self, ipblock: IPNetwork):
        """ Add a block of IP addresses to the free IP list
        """
        self._ip_allocator.add_ip_block(ipblock)

    def remove_ip_blocks(
        self,
        ipblocks: List[IPNetwork],
        force: bool = False,
    ) -> List[IPNetwork]:
        """ Remove allocated IP blocks.
        """
        return self._ip_allocator.remove_ip_blocks(ipblocks, force)

    def list_added_ip_blocks(self) -> List[IPNetwork]:
        """ List IP blocks added to the IP allocator
        Return:
             copy of the list of assigned IP blocks
        """
        return self._ip_allocator.list_added_ip_blocks()

    def list_allocated_ips(self, ipblock: IPNetwork) -> List[IPAddress]:
        """ List IP addresses allocated from a given IP block
        """
        return self._ip_allocator.list_allocated_ips(ipblock)

    def alloc_ip_address(self, sid: str, vlan_id: int) -> IPDesc:
        """ Check if subscriber has static IP assigned.
        If it is not allocated use IP allocator to assign an IP.
        """
        ip_desc = self._allocate_static_ip(sid)
        if ip_desc is None:
            ip_desc = self._ip_allocator.alloc_ip_address(sid, vlan_id)
        return ip_desc

    def release_ip(self, ip_desc: IPDesc):
        """
        Statically allocated IPs do not need to do any update on
        ip release
        """
        if ip_desc.type == IPType.STATIC:
            self._store.ip_state_map.remove_ip_from_state(
                ip_desc.ip,
                IPState.FREE,
            )
            ip_block_network = ip_network(ip_desc.ip_block)
            logging.debug(
                "assigned blocks: %s remove: %s",
                self._store.assigned_ip_blocks,
                ip_block_network,
            )
            if ip_block_network in self._store.assigned_ip_blocks:
                self._store.assigned_ip_blocks.remove(ip_block_network)
        else:
            self._ip_allocator.release_ip(ip_desc)

    def _allocate_static_ip(self, sid: str) -> Optional[IPDesc]:
        """
        Check if static IP allocation is enabled and then check
        subscriber DB for assigned static IP for the SID
        """
        ip_addr_info = self._subscriber_client.get_subscriber_ip(sid)
        if ip_addr_info is None:
            return None
        logging.debug(
            "Found static IP: sid: %s ip_addr_info: %s",
            sid,
            str(ip_addr_info),
        )
        if ip_addr_info.ip.version != self._ip_version:
            logging.debug("IP version mismatch, expected version: %d",
                          self._ip_version)
            return None
        # Validate static IP is not in any of IP pool.
        for ip_pool in self._store.assigned_ip_blocks:
            if ip_addr_info.ip in ip_pool:
                log_error_and_raise(
                    DuplicateIPAssignmentError,
                    "Static Ip %s Overlap with IP-POOL: %s",
                    ip_addr_info.ip,
                    ip_pool,
                )

        # update gw info if available.
        if ip_addr_info.net_info.gw_ip:
            self._store.dhcp_gw_info.update_ip(
                ip_addr_info.net_info.gw_ip,
                ip_addr_info.net_info.vlan,
            )
            # update mac if IP is present.
            if ip_addr_info.net_info.gw_mac != "":
                self._store.dhcp_gw_info.update_mac(
                    ip_addr_info.net_info.gw_ip,
                    ip_addr_info.net_info.gw_mac,
                    ip_addr_info.net_info.vlan,
                )
        ip_block = ip_network(ip_addr_info.ip)
        self._store.assigned_ip_blocks.add(ip_block)
        return IPDesc(
            ip=ip_addr_info.ip,
            state=IPState.ALLOCATED,
            sid=sid,
            ip_block=ip_block,
            ip_type=IPType.STATIC,
            vlan_id=ip_addr_info.net_info.vlan,
        )
Esempio n. 2
0
class IPAllocatorStaticWrapper(IPAllocator):

    def __init__(self, subscriberdb_rpc_stub, ip_allocator: IPAllocator,
                 gw_info: UplinkGatewayInfo,
                 assigned_ip_blocks: Set[ip_network],
                 ip_state_map: IpDescriptorMap):
        """ Initializes a static IP allocator
            This is wrapper around other configured Ip allocator. If subscriber
            does have static IP, it uses underlying IP allocator to allocate IP
            for the subscriber.
        """
        self._subscriber_client = SubscriberDbClient(subscriberdb_rpc_stub)
        self._ip_allocator = ip_allocator
        self._gw_info = gw_info
        self._ip_state_map = ip_state_map  # {state=>{ip=>ip_desc}}
        self._assigned_ip_blocks = assigned_ip_blocks

    def add_ip_block(self, ipblock: ip_network):
        """ Add a block of IP addresses to the free IP list
        """
        self._ip_allocator.add_ip_block(ipblock)

    def remove_ip_blocks(self, ipblocks: List[ip_network],
                         _force: bool = False) -> List[ip_network]:
        """ Remove allocated IP blocks.
        """
        return self._ip_allocator.remove_ip_blocks(ipblocks, _force)

    def list_added_ip_blocks(self) -> List[ip_network]:
        """ List IP blocks added to the IP allocator
        Return:
             copy of the list of assigned IP blocks
        """
        return self._ip_allocator.list_added_ip_blocks()

    def list_allocated_ips(self, ipblock: ip_network) -> List[ip_address]:
        """ List IP addresses allocated from a given IP block
        """
        return self._ip_allocator.list_allocated_ips(ipblock)

    def alloc_ip_address(self, sid: str, vlan: int) -> IPDesc:
        """ Check if subscriber has static IP assigned.
        If it is not allocated use IP allocator to assign an IP.
        """
        ip_desc = self._allocate_static_ip(sid)
        if ip_desc is None:
            ip_desc = self._ip_allocator.alloc_ip_address(sid, vlan)
        return ip_desc

    def release_ip(self, ip_desc: IPDesc):
        """
        Statically allocated IPs do not need to do any update on
        ip release
        """
        if ip_desc.type == IPType.STATIC:
            self._ip_state_map.remove_ip_from_state(ip_desc.ip, IPState.FREE)
            ip_block_network = ip_network(ip_desc.ip_block)
            if ip_block_network in self._assigned_ip_blocks:
                self._assigned_ip_blocks.remove(ip_block_network)
        else:
            self._ip_allocator.release_ip(ip_desc)

    def _allocate_static_ip(self, sid: str) -> Optional[IPDesc]:
        """
        Check if static IP allocation is enabled and then check
        subscriber DB for assigned static IP for the SID
        """
        ip_addr_info = self._subscriber_client.get_subscriber_ip(sid)
        if ip_addr_info is None:
            return None
        logging.debug("Found static IP: sid: %s ip_addr_info: %s",
                      sid, str(ip_addr_info))
        # update gw info if available.
        if ip_addr_info.gw_ip:
            self._gw_info.update_ip(ip_addr_info.gw_ip, str(ip_addr_info.vlan))
            # update mac if IP is present.
            if ip_addr_info.gw_mac != "":
                self._gw_info.update_mac(ip_addr_info.gw_ip,
                                         ip_addr_info.gw_mac,
                                         str(ip_addr_info.vlan))
        ip_block = ip_network(ip_addr_info.ip)
        self._assigned_ip_blocks.add(ip_block)
        return IPDesc(ip=ip_addr_info.ip, state=IPState.ALLOCATED,
                      sid=sid, ip_block=ip_block, ip_type=IPType.STATIC,
                      vlan_id=ip_addr_info.vlan)
Esempio n. 3
0
class IPAllocatorStaticWrapper(IPAllocator):

    def __init__(self, subscriberdb_rpc_stub, ip_allocator: IPAllocator):
        """ Initializes a static IP allocator
            This is wrapper around other configured Ip allocator. If subscriber
            does have static IP, it uses underlying IP allocator to allocate IP
            for the subscriber.
        """
        self._subscriber_client = SubscriberDbClient(subscriberdb_rpc_stub)
        self._ip_allocator = ip_allocator

    def add_ip_block(self, ipblock: ip_network):
        """ Add a block of IP addresses to the free IP list
        """
        self._ip_allocator.add_ip_block(ipblock)

    def remove_ip_blocks(self, ipblocks: List[ip_network],
                         _force: bool = False) -> List[ip_network]:
        """ Remove allocated IP blocks.
        """
        return self._ip_allocator.remove_ip_blocks(ipblocks, _force)

    def list_added_ip_blocks(self) -> List[ip_network]:
        """ List IP blocks added to the IP allocator
        Return:
             copy of the list of assigned IP blocks
        """
        return self._ip_allocator.list_added_ip_blocks()

    def list_allocated_ips(self, ipblock: ip_network) -> List[ip_address]:
        """ List IP addresses allocated from a given IP block
        """
        return self._ip_allocator.list_allocated_ips(ipblock)

    def alloc_ip_address(self, sid: str) -> IPDesc:
        """ Check if subscriber has static IP assigned.
        If it is not allocated use IP allocator to assign an IP.
        """
        ip_desc = self._allocate_static_ip(sid)
        if ip_desc is None:
            ip_desc = self._ip_allocator.alloc_ip_address(sid)
        return ip_desc

    def release_ip(self, ip_desc: IPDesc):
        """
        Statically allocated IPs do not need to do any update on
        ip release
        """
        if ip_desc.type != IPType.STATIC:
            self._ip_allocator.release_ip(ip_desc)

    def _allocate_static_ip(self, sid: str) -> IPDesc:
        """
        Check if static IP allocation is enabled and then check
        subscriber DB for assigned static IP for the SID
        """
        ip_addr = self._subscriber_client.get_subscriber_ip(sid)
        if ip_addr is None:
            return None
        return IPDesc(ip=ip_addr, state=IPState.ALLOCATED,
                      sid=sid, ip_block=ip_addr, ip_type=IPType.STATIC)