def RemoveIPBlock(self, request, context): """ Attempt to remove IP blocks and return the removed blocks """ logging.debug("Received RemoveIPBlock") self._print_grpc(request) removed_blocks = self._ip_address_man.remove_ip_blocks( *[ self._ipblock_msg_to_ipblock(ipblock_msg, context) for ipblock_msg in request.ip_blocks ], force=request.force, ) removed_block_msgs = [] for block in removed_blocks: if block.version == 4: removed_block_msgs.append( IPBlock( version=IPAddress.IPV4, net_address=block.network_address.packed, prefix_len=block.prefixlen, ), ) elif block.version == 6: removed_block_msgs.append( IPBlock( version=IPAddress.IPV6, net_address=block.network_address.packed, prefix_len=block.prefixlen, ), ) resp = RemoveIPBlockResponse() resp.ip_blocks.extend(removed_block_msgs) self._print_grpc(resp) return resp
def _get_ip_data(block): """ Construct an IPBlock message from a given IP block. Args: block (ipaddress.ip_network): the IP block to embed """ ipblock_msg = IPBlock() ipblock_msg.version = IPBlock.IPV4 ipblock_msg.net_address = block.network_address.packed ipblock_msg.prefix_len = block.prefixlen return ipblock_msg
def setUp(self): # Bind the rpc server to a free port thread_pool = futures.ThreadPoolExecutor(max_workers=10) self._rpc_server = grpc.server(thread_pool) port = self._rpc_server.add_insecure_port('0.0.0.0:0') store = MobilityStore(get_default_client(), False, 3980) store.dhcp_gw_info.read_default_gw() ip_allocator = IpAllocatorPool(store) ipv6_allocator = IPv6AllocatorPool( store, session_prefix_alloc_mode='RANDOM', ) self._allocator = IPAddressManager( ip_allocator, ipv6_allocator, store, ) # Add the servicer self._servicer = MobilityServiceRpcServicer(self._allocator, False) self._servicer.add_to_server(self._rpc_server) self._rpc_server.start() # Create a rpc stub channel = grpc.insecure_channel('0.0.0.0:{}'.format(port)) self._stub = MobilityServiceStub(channel) # variables shared across tests self._netaddr = '192.168.0.0' self._prefix_len = 28 ip_bytes = bytes(map(int, self._netaddr.split('.'))) self._block_msg = IPBlock( version=IPBlock.IPV4, net_address=ip_bytes, prefix_len=self._prefix_len, ) self._ipv6_block = ipaddress.ip_network('fdee:5:6c::/48') self._ipv6_netaddr = self._ipv6_block.network_address.packed self._ipv6_block_msg = IPBlock( version=IPBlock.IPV6, net_address=self._ipv6_netaddr, prefix_len=self._ipv6_block.prefixlen, ) self._block = ipaddress.ip_network( "%s/%s" % (self._netaddr, self._prefix_len), ) self._sid0 = SIDUtils.to_pb('IMSI0') self._sid1 = SIDUtils.to_pb('IMSI1') self._sid2 = SIDUtils.to_pb('IMSI2') self._apn0 = 'Internet' self._apn1 = 'IMS'
def add_ip_block_handler(client, args): try: ipblock = ipaddress.ip_network(args.ipblock) except ValueError: print("Error: invalid IP block format: %s" % args.ipblock) return ipblock_msg = IPBlock() if ipblock.version == 4: ipblock_msg.version = IPBlock.IPV4 else: print("Error: IP version %d is not supported yet" % ipblock.version) return ipblock_msg.net_address = ipblock.network_address.packed ipblock_msg.prefix_len = ipblock.prefixlen client.AddIPBlock(ipblock_msg)
def deserialize_ip_block(serialized): """ Deserialize protobuf string to an IP block. Args: serialized (bytes): object to deserialize Returns: block (ipaddress.ip_network): deserialized object """ proto = IPBlock() proto.ParseFromString(serialized) address_str = ip_address(proto.net_address).exploded network_str = '{}/{}'.format(address_str, proto.prefix_len) block = ip_network(network_str) return block
def test_ipv6_unimplemented(self): """ ipv6 requests should raise UNIMPLEMENTED """ ip = ipaddress.ip_address("fc::") block = IPBlock(version=IPBlock.IPV6, net_address=ip.packed, prefix_len=120) # AddIPBlock with self.assertRaises(grpc.RpcError) as err: self._stub.AddIPBlock(block) self.assertEqual(err.exception.code(), grpc.StatusCode.UNIMPLEMENTED) # ListAllocatedIPs with self.assertRaises(grpc.RpcError) as err: self._stub.ListAllocatedIPs(block) self.assertEqual(err.exception.code(), grpc.StatusCode.UNIMPLEMENTED) # AllocateIPAddress request = AllocateIPRequest(sid=self._sid1, version=AllocateIPRequest.IPV6, apn=self._apn0) with self.assertRaises(grpc.RpcError) as err: self._stub.AllocateIPAddress(request) self.assertEqual(err.exception.code(), grpc.StatusCode.UNIMPLEMENTED) # ReleaseIPAddress release_request = ReleaseIPRequest( sid=self._sid0, ip=IPAddress(version=IPAddress.IPV6), apn=self._apn0) with self.assertRaises(grpc.RpcError) as err: self._stub.ReleaseIPAddress(release_request) self.assertEqual(err.exception.code(), grpc.StatusCode.UNIMPLEMENTED)
def test_list_invalid_ip_block(self): """ listing invalid ipblock should raise INVALID_ARGUMENT """ block_msg = IPBlock() with self.assertRaises(grpc.RpcError) as err: self._stub.ListAllocatedIPs(block_msg) self.assertEqual(err.exception.code(), grpc.StatusCode.INVALID_ARGUMENT)
def setUp(self): # Bind the rpc server to a free port thread_pool = futures.ThreadPoolExecutor(max_workers=10) self._rpc_server = grpc.server(thread_pool) port = self._rpc_server.add_insecure_port('0.0.0.0:0') # Create a mock "mconfig" for the servicer to use mconfig = unittest.mock.Mock() mconfig.ip_block = None # Add the servicer config = {'persist_to_redis': False, 'redis_port': None} self._servicer = MobilityServiceRpcServicer(mconfig, config) self._servicer.add_to_server(self._rpc_server) self._rpc_server.start() # Create a rpc stub channel = grpc.insecure_channel('0.0.0.0:{}'.format(port)) self._stub = MobilityServiceStub(channel) # variables shared across tests self._netaddr = '192.168.0.0' self._prefix_len = 28 ip_bytes = bytes(map(int, self._netaddr.split('.'))) self._block_msg = IPBlock(version=IPBlock.IPV4, net_address=ip_bytes, prefix_len=self._prefix_len) self._block = ipaddress.ip_network("%s/%s" % (self._netaddr, self._prefix_len)) self._sid0 = SIDUtils.to_pb('IMSI0') self._sid1 = SIDUtils.to_pb('IMSI1') self._sid2 = SIDUtils.to_pb('IMSI2') self._apn0 = 'Internet' self._apn1 = 'IMS'
def _ip_desc_to_proto(desc): """ Convert an IP descriptor to protobuf. Args: desc (magma.mobilityd.IPDesc): IP descriptor Returns: proto (protos.keyval_pb2.IPDesc): protobuf of :desc: """ ip = IPAddress( version=_ip_version_int_to_proto(desc.ip_block.version), address=desc.ip.packed, ) ip_block = IPBlock( version=_ip_version_int_to_proto(desc.ip_block.version), net_address=desc.ip_block.network_address.packed, prefix_len=desc.ip_block.prefixlen, ) state = _desc_state_str_to_proto(desc.state) sid = SubscriberID( id=desc.sid, type=SubscriberID.IMSI, ) proto = IPDesc(ip=ip, ip_block=ip_block, state=state, sid=sid) return proto
def serialize_ip_block(block): """ Serialize an IP block to protobuf string. Args: block (ipaddress.ip_network): object to serialize Returns: serialized (bytes): serialized object """ proto = IPBlock( version=_ip_version_int_to_proto(block.version), net_address=block.network_address.packed, prefix_len=block.prefixlen, ) serialized = proto.SerializeToString() return serialized
def remove_ip_blocks(self, blocks): try: ip_blocks = [ IPBlock(version={ 4: IPAddress.IPV4, 6: IPAddress.IPV6 }[block.version], net_address=block.network_address.packed, prefix_len=block.prefixlen) for block in blocks ] response = self._mobility_stub.RemoveIPBlock( RemoveIPBlockRequest(ip_blocks=ip_blocks, force=False)) removed_ip_block_list = () for block in response.ip_blocks: address_bytes = block.net_address address_int = int.from_bytes(address_bytes, byteorder='big') address = ipaddress.ip_address(address_int) removed_ip_block_list += (ipaddress.ip_network( "%s/%d" % (address, block.prefix_len)), ) return removed_ip_block_list except grpc.RpcError as error: err_code = error.exception().code() if (err_code == grpc.StatusCode.FAILED_PRECONDITION): logging.info("Ignoring FAILED_PRECONDITION exception") else: raise
def add_to_ip_blocks_list(subnet: str): block = ipaddress.ip_network(subnet) ip_block = IPBlock( version=IPAddress.IPV4, net_address=block.network_address.packed, prefix_len=block.prefixlen, ) ip_blocks_list.append(ip_block)
def _setup_ip_block(client): ip_blocks_rsp = client.ListAddedIPv4Blocks(Void()) remove_blocks_req = RemoveIPBlockRequest(force=True) for block in ip_blocks_rsp.ip_block_list: remove_blocks_req.ip_blocks.append(block) client.RemoveIPBlock(remove_blocks_req) ip_block = ipaddress.ip_network('192.168.128.0/20') client.AddIPBlock(IPBlock(version=IPBlock.IPV4, net_address=ip_block.network_address.packed, prefix_len=ip_block.prefixlen))
def test_list_allocated_ips_from_unknown_ipblock(self): """ test list allocated IPs from an unknown IP block """ self._stub.AddIPBlock(self._block_msg) ip_bytes = bytes(map(int, '10.0.0.0'.split('.'))) block_msg = IPBlock(version=IPBlock.IPV4, net_address=ip_bytes, prefix_len=30) with self.assertRaises(grpc.RpcError) as err: self._stub.ListAllocatedIPs(block_msg) self.assertEqual(err.exception.code(), grpc.StatusCode.FAILED_PRECONDITION)
def remove_ip_block_handler(client, args): ipblock_msgs = () for ipblock in args.ipblocks: ipblock_msg = IPBlock() if ipblock.version == 4: ipblock_msg.version = IPBlock.IPV4 else: print("Error: IP version %d is not supported yet" % ipblock.version) return ipblock_msg.net_address = ipblock.network_address.packed ipblock_msg.prefix_len = ipblock.prefixlen ipblock_msgs += (ipblock_msg, ) request = RemoveIPBlockRequest(ip_blocks=ipblock_msgs, force=args.force) remove_response = client.RemoveIPBlock(request) print("IPv4 Blocks Removed: ") for block_msg in remove_response.ip_blocks: ip = ipaddress.ip_address(block_msg.net_address) block = ipaddress.ip_network("%s/%d" % (ip, block_msg.prefix_len)) print("\t%s" % block)
def ListAddedIPv4Blocks(self, void, context): """ Return a list of IPv4 blocks assigned """ resp = ListAddedIPBlocksResponse() ip_blocks = self._ipv4_allocator.list_added_ip_blocks() ip_block_msg_list = [IPBlock(version=IPAddress.IPV4, net_address=block.network_address.packed, prefix_len=block.prefixlen) for block in ip_blocks] resp.ip_block_list.extend(ip_block_msg_list) return resp
def test_add_overlapped_ip_block(self): """ overlaping IPBlocks should raise FAILED_PRECONDITION """ self._stub.AddIPBlock(self._block_msg) # overlaped block ip_bytes = bytes(map(int, self._netaddr.split('.'))) block_msg = IPBlock(version=IPBlock.IPV4, net_address=ip_bytes, prefix_len=30) with self.assertRaises(grpc.RpcError) as err: self._stub.AddIPBlock(block_msg) self.assertEqual(err.exception.code(), grpc.StatusCode.FAILED_PRECONDITION)
def RemoveIPBlock(self, request, context): """ Attempt to remove IP blocks and return the removed blocks """ removed_blocks = self._ipv4_allocator.remove_ip_blocks( *[self._ipblock_msg_to_ipblock(ipblock_msg, context) for ipblock_msg in request.ip_blocks], force=request.force) removed_block_msgs = [IPBlock(version=IPAddress.IPV4, net_address=block.network_address.packed, prefix_len=block.prefixlen) for block in removed_blocks] resp = RemoveIPBlockResponse() resp.ip_blocks.extend(removed_block_msgs) return resp
def ListAddedIPv4Blocks(self, void, context): """ Return a list of IPv4 blocks assigned """ logging.debug("Received ListAddedIPv4Blocks") self._print_grpc(void) resp = ListAddedIPBlocksResponse() ip_blocks = self._ip_address_man.list_added_ip_blocks() ip_block_msg_list = [ IPBlock(version=IPAddress.IPV4, net_address=block.network_address.packed, prefix_len=block.prefixlen) for block in ip_blocks ] resp.ip_block_list.extend(ip_block_msg_list) self._print_grpc(resp) return resp
def ListAddedIPv6Blocks(self, request, context): """ Return a list of IPv6 blocks assigned """ self._print_grpc(request) resp = ListAddedIPBlocksResponse() ip_blocks = self._ip_address_man.get_assigned_ipv6_block() ip_block_msg_list = [ IPBlock( version=IPAddress.IPV6, net_address=block.network_address.packed, prefix_len=block.prefixlen, ) for block in ip_blocks ] resp.ip_block_list.extend(ip_block_msg_list) self._print_grpc(resp) return resp