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 __init__(self, subscriberdb_rpc_stub, ip_allocator: IPAllocator): """ Initializes a Multi APN IP allocator This is wrapper around other configured Ip allocator. If subscriber has vlan configured in APN config, it would be used for allocating IP address by underlying IP allocator. For DHCP it means using vlan tag for DHCP request, for IP pool allocator it does not change behaviour. """ self._subscriber_client = SubscriberDbClient(subscriberdb_rpc_stub) self._ip_allocator = ip_allocator
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
class IPAllocatorMultiAPNWrapper(IPAllocator): def __init__(self, subscriberdb_rpc_stub, ip_allocator: IPAllocator): """ Initializes a Multi APN IP allocator This is wrapper around other configured Ip allocator. If subscriber has vlan configured in APN config, it would be used for allocating IP address by underlying IP allocator. For DHCP it means using vlan tag for DHCP request, for IP pool allocator it does not change behaviour. TODO: Add support of per APN IP-POOL """ 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, vlan_id: int) -> IPDesc: """ Check if subscriber has APN configuration and vlan. once we have APN specific info use IP allocator to assign an IP. """ vlan_id = self._subscriber_client.get_subscriber_apn_vlan(sid) logging.info("got vlan: [%s]", vlan_id) ip_desc = self._ip_allocator.alloc_ip_address(sid, vlan_id) if ip_desc: ip_desc.vlan_id = vlan_id logging.info("sid %s vlan %s", sid, vlan_id) return ip_desc def release_ip(self, ip_desc: IPDesc): """ Multi APN allocated IPs do not need to do any update on ip release, let actual IP allocator release the IP. """ if ip_desc.type != IPType.STATIC: self._ip_allocator.release_ip(ip_desc)
class IPAllocatorMultiAPNWrapper(IPAllocator): def __init__(self, store: MobilityStore, subscriberdb_rpc_stub, ip_allocator: IPAllocator): """ Initializes a Multi APN IP allocator This is wrapper around other configured Ip allocator. If subscriber has vlan configured in APN config, it would be used for allocating IP address by underlying IP allocator. For DHCP it means using vlan tag for DHCP request, for IP pool allocator it does not change behaviour. """ self._store = store 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, vlan_id: int) -> IPDesc: """ Check if subscriber has APN configuration and vlan. once we have APN specific info use IP allocator to assign an IP. """ network_info = self._subscriber_client.get_subscriber_apn_network_info( sid) # Update GW info from subscriber DB data. # This could be overwritten by DHCP response. self._store.dhcp_gw_info.update_mac(network_info.gw_ip, network_info.gw_mac, network_info.vlan) return self._ip_allocator.alloc_ip_address(sid, network_info.vlan) def release_ip(self, ip_desc: IPDesc): """ Multi APN allocated IPs do not need to do any update on ip release, let actual IP allocator release the IP. """ self._ip_allocator.release_ip(ip_desc)
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
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)
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, )
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)