def test_get_gw_info(self): gw_info = self._stub.GetGatewayInfo(Void()) gw_ip_get = str(ipaddress.ip_address(gw_info.ip.address)) def_gw_cmd = shlex.split("ip route show") p = subprocess.Popen(def_gw_cmd, stdout=subprocess.PIPE) output = p.stdout.read().decode("utf-8") def_ip = None for line in output.splitlines(): if 'default ' in line: tokens = line.split() def_ip = tokens[2] break self.assertEqual(def_ip, gw_ip_get)
def test_set_gw_info(self): mac1 = "22:22:c6:d0:02:3c" ipaddr1 = ipaddress.ip_address("10.1.1.11") gwinfo_msg = GWInfo() gwinfo_msg.ip.version = IPBlock.IPV4 gwinfo_msg.ip.address = ipaddr1.packed gwinfo_msg.mac = mac1 gwinfo_msg.vlan = "" self._stub.SetGatewayInfo(gwinfo_msg) gw_info_list = self._stub.ListGatewayInfo(Void()) for gw_info in gw_info_list.gw_list: gw_ip_get = ipaddress.ip_address(gw_info.ip.address) self.assertEqual(ipaddr1, gw_ip_get) self.assertEqual(mac1, gw_info.mac)
def test_get_subscriber_ip_table(self): """ test GetSubscriberIPTable """ self._stub.AddIPBlock(self._block_msg) resp = self._stub.GetSubscriberIPTable(Void()) self.assertEqual(len(resp.entries), 0) alloc_request0 = AllocateIPRequest(sid=self._sid0, version=AllocateIPRequest.IPV4, apn=self._apn0) ip_msg0 = self._stub.AllocateIPAddress(alloc_request0) entry0 = SubscriberIPTableEntry(sid=self._sid0, ip=ip_msg0, apn=self._apn0) resp = self._stub.GetSubscriberIPTable(Void()) self.assertTrue(entry0 in resp.entries) alloc_request1 = AllocateIPRequest(sid=self._sid1, version=AllocateIPRequest.IPV4, apn=self._apn1) ip_msg1 = self._stub.AllocateIPAddress(alloc_request1) entry1 = SubscriberIPTableEntry(sid=self._sid1, ip=ip_msg1, apn=self._apn1) resp = self._stub.GetSubscriberIPTable(Void()) self.assertTrue(entry0 in resp.entries) self.assertTrue(entry1 in resp.entries) # keep in table after in release release_request0 = ReleaseIPRequest(sid=self._sid0, ip=ip_msg0, apn=self._apn0) resp = self._stub.ReleaseIPAddress(release_request0) resp = self._stub.GetSubscriberIPTable(Void()) self.assertTrue(entry0 in resp.entries) self.assertTrue(entry1 in resp.entries)
def test_service_run(self, mock_get_proxy_config): """ Test if the service starts and stops gracefully. """ self.assertEqual(self._service.state, ServiceInfo.STARTING) mock_get_proxy_config.return_value = { 'cloud_address': '127.0.0.1', 'proxy_cloud_connections': True } # Start the service and pause the loop self._service.loop.stop() self._service.run() asyncio.set_event_loop(self._service.loop) self._service.log_counter._periodic_task.cancel() self.assertEqual(self._service.state, ServiceInfo.ALIVE) # Create a rpc stub and query the Service303 interface ServiceRegistry.add_service('test', '0.0.0.0', self._service.port) channel = ServiceRegistry.get_rpc_channel('test', ServiceRegistry.LOCAL) self._stub = Service303Stub(channel) info = ServiceInfo(name='test', version='0.0.0', state=ServiceInfo.ALIVE, health=ServiceInfo.APP_HEALTHY, start_time_secs=12345) self.assertEqual(self._stub.GetServiceInfo(Void()), info) # Stop the service self._stub.StopService(Void()) self._service.loop.run_forever() self.assertEqual(self._service.state, ServiceInfo.STOPPED)
def test_remove_unallocated_assigned_block(self): """ remove should return nothing """ self._stub.AddIPBlock(self._block_msg) remove_request0 = RemoveIPBlockRequest(ip_blocks=[self._block_msg], force=False) resp = self._stub.RemoveIPBlock(remove_request0) expect = RemoveIPBlockResponse() expect.ip_blocks.extend([self._block_msg]) self.assertEqual(expect, resp) resp = self._stub.ListAddedIPv4Blocks(Void()) expect = ListAddedIPBlocksResponse() self.assertEqual(expect, resp)
def get_gateway_service_mconfigs(services: List[str]) -> Dict[str, Any]: """ Get the managed configurations of some gateway services. Args: services: List of service names to fetch configs for Returns: service mconfigs keyed by name """ ret = {} magmad_stub = MagmadStub(get_rpc_channel('magmad')) stub_response = magmad_stub.GetConfigs(Void()) for srv in services: ret[srv] = unpack_mconfig_any(stub_response.configs_by_key[srv]) return ret
def get_table_assignment(client, args): response = client.GetAllTableAssignments(Void()) table_assignments = response.table_assignments if args.apps: app_filter = args.apps.split(',') table_assignments = [table_assignment for table_assignment in table_assignments if table_assignment.app_name in app_filter] table_template = '{:<25}{:<20}{:<25}' print(table_template.format('App', 'Main Table', 'Scratch Tables')) print('-' * 70) for table_assignment in table_assignments: print(table_template.format( table_assignment.app_name, table_assignment.main_table, str([table for table in table_assignment.scratch_tables])))
def get_all_enb_state() -> Optional[Dict[int, int]]: """ Make RPC call to 'GetENBState' method of s1ap service """ try: chan = ServiceRegistry.get_rpc_channel(S1AP_SERVICE_NAME, ServiceRegistry.LOCAL) except ValueError: logger.error('Cant get RPC channel to %s', S1AP_SERVICE_NAME) return {} client = S1apServiceStub(chan) try: res = client.GetENBState(Void(), DEFAULT_GRPC_TIMEOUT) return res.enb_state_map except grpc.RpcError as err: logger.warning("GetEnbState error: [%s] %s", err.code(), err.details()) return {}
def gateway_health_status(): config = load_service_mconfig_as_json('mme') # eNB status for #eNBs connected chan = ServiceRegistry.get_rpc_channel('enodebd', ServiceRegistry.LOCAL) client = EnodebdStub(chan) status = client.GetStatus(Void()) mme_log_path = '/var/log/mme.log' health_summary = AGWHealthSummary( relay_enabled=config['relayEnabled'], nb_enbs_connected=status.meta['n_enodeb_connected'], allocated_ips=get_allocated_ips(), subscriber_table=get_subscriber_table(), registration_success_rate=get_registration_success_rate(mme_log_path), ) return str(health_summary)
def mobilityd_list_ip_blocks(): """ Make RPC call to query all ip-blocks. """ try: chan = ServiceRegistry.get_rpc_channel(SERVICE_NAME, ServiceRegistry.LOCAL) except ValueError: logging.error('Cant get RPC channel to %s', SERVICE_NAME) return client = MobilityServiceStub(chan) try: resp = client.ListAddedIPv4Blocks(Void()) return resp except grpc.RpcError as err: logging.error("List IpBlock error[%s] %s", err.code(), err.details())
def get_mobilityd_gw_info() -> GWInfo: """ Make RPC call to 'GetGatewayInfo' method of local mobilityD service """ try: chan = ServiceRegistry.get_rpc_channel(SERVICE_NAME, ServiceRegistry.LOCAL) except ValueError: logging.error('Cant get RPC channel to %s', SERVICE_NAME) return GWInfo() client = MobilityServiceStub(chan) try: return client.GetGatewayInfo(Void()) except grpc.RpcError as err: logging.error("GetGatewayInfoRequest error[%s] %s", err.code(), err.details())
def list_allocated_ips_handler(client, args): list_blocks_resp = client.ListAddedIPv4Blocks(Void()) for block_msg in list_blocks_resp.ip_block_list: ip = ipaddress.ip_address(block_msg.net_address) block = ipaddress.ip_network("%s/%d" % (ip, block_msg.prefix_len)) print("IPs allocated from block %s:" % block) list_ips_resp = client.ListAllocatedIPs(block_msg) for ip_msg in list_ips_resp.ip_list: if ip_msg.version == IPAddress.IPV4: ip = ipaddress.IPv4Address(ip_msg.address) elif ip_msg.address == IPAddress.IPV6: ip = ipaddress.IPv6Address(ip_msg.address) else: print("Unsupported IP Version") continue print("\t%s" % ip)
def _build_release_ip_data(client): release_ip_reqs = [] table = client.GetSubscriberIPTable(Void()) if not table.entries: print('No IPs allocated to be freed, please run allocate test first') exit(1) for entry in table.entries: release_ip_req = ReleaseIPRequest( sid=entry.sid, ip=entry.ip, apn=entry.apn, ) release_ip_dict = json_format.MessageToDict(release_ip_req) # Dumping ReleaseIP request into json release_ip_reqs.append(release_ip_dict) with open('release_data.json', 'w') as file: json.dump(release_ip_reqs, file)
def get_allocated_ips(): chan = ServiceRegistry.get_rpc_channel('mobilityd', ServiceRegistry.LOCAL) client = MobilityServiceStub(chan) res = [] list_blocks_resp = client.ListAddedIPv4Blocks(Void()) for block_msg in list_blocks_resp.ip_block_list: list_ips_resp = client.ListAllocatedIPs(block_msg) for ip_msg in list_ips_resp.ip_list: if ip_msg.version == IPAddress.IPV4: ip = ipaddress.IPv4Address(ip_msg.address) elif ip_msg.address == IPAddress.IPV6: ip = ipaddress.IPv6Address(ip_msg.address) else: continue res.append(ip) return res
def list_added_blocks(self): try: response = self._mobility_stub.ListAddedIPv4Blocks(Void()) ip_block_list = [] for block in response.ip_block_list: address_bytes = block.net_address address_int = int.from_bytes(address_bytes, byteorder='big') address = ipaddress.ip_address(address_int) ip_block_list.append( ipaddress.ip_network("%s/%d" % (address, block.prefix_len))) return 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 test_get_gw_info(self): def_gw_cmd = shlex.split("ip route show") p = subprocess.Popen(def_gw_cmd, stdout=subprocess.PIPE) output = p.stdout.read().decode("utf-8") def_ip = None for line in output.splitlines(): if 'default ' in line: tokens = line.split() def_ip = tokens[2] break gw_info_list = self._stub.ListGatewayInfo(Void()) for gw_info in gw_info_list.gw_list: gw_ip_get = str(ipaddress.ip_address(gw_info.ip.address)) if gw_ip_get == def_ip: return assert 0
async def _get_state(self, service: MagmaService) -> Optional[States]: client = self._get_client(service) if client is None: return None try: states = [] future = client.GetOperationalStates.future( Void(), self.GET_STATE_TIMEOUT, ) result = await grpc_async_wrapper(future, self._loop) for i in range(len(result.states)): states.append(result.states[i]) return states except Exception as err: logging.error("GetOperationalStates Error for %s! [%s]", service, err) return None
async def _get_operational_states(self, service: str) -> List[States]: client = get_service303_client(service, ServiceRegistry.LOCAL) if client is None: return [] try: states = [] future = client.GetOperationalStates.future( Void(), self._mconfig.checkin_timeout, ) result = await grpc_async_wrapper(future, self._loop) for i in range(len(result.states)): states.append(result.states[i]) return states except Exception as err: logging.error("GetOperationalStates Error for %s! [%s] %s", service, err.code(), err.details()) return []
async def _get_subscribers(self) -> List[IPAddress]: """ Sends gRPC call to mobilityd to get all subscribers table. Returns: List of [Subscriber ID => IP address, APN] entries """ try: mobilityd_chan = ServiceRegistry.get_rpc_channel( 'mobilityd', ServiceRegistry.LOCAL) mobilityd_stub = MobilityServiceStub(mobilityd_chan) response = await grpc_async_wrapper( mobilityd_stub.GetSubscriberIPTable.future( Void(), TIMEOUT_SECS), self._loop) return response.entries except grpc.RpcError as err: logging.error("GetSubscribers Error for %s! %s", err.code(), err.details()) return []
def test_set_gw_info_vlan(self): mac1 = "22:22:c6:d0:02:3c" ipaddr1 = ipaddress.ip_address("10.1.1.11") gwinfo_msg = GWInfo(ip=IPAddress(version=IPAddress.IPV4, address=ipaddr1.packed), mac=mac1, vlan="1") self._stub.SetGatewayInfo(gwinfo_msg) gw_info_list = self._stub.ListGatewayInfo(Void()) for gw_info in gw_info_list.gw_list: if gw_info.vlan == "1": gw_ip_get = ipaddress.ip_address(gw_info.ip.address) self.assertEqual(ipaddr1, gw_ip_get) self.assertEqual(mac1, gw_info.mac) return assert 0
def test_remove_allocated_assigned_block_with_force(self): """ remove should return nothing """ self._stub.AddIPBlock(self._block_msg) alloc_request0 = AllocateIPRequest(sid=self._sid0, version=AllocateIPRequest.IPV4) self._stub.AllocateIPAddress(alloc_request0) remove_request0 = RemoveIPBlockRequest(ip_blocks=[self._block_msg], force=True) resp = self._stub.RemoveIPBlock(remove_request0) expect = RemoveIPBlockResponse() expect.ip_blocks.extend([self._block_msg]) self.assertEqual(expect, resp) resp = self._stub.ListAddedIPv4Blocks(Void()) expect = ListAddedIPBlocksResponse() self.assertEqual(expect, resp)
def _display_flows(client, apps=None): pipelined_config = load_service_config('pipelined') bridge_name = pipelined_config['bridge_name'] response = client.GetAllTableAssignments(Void()) table_assignments = { table_assignment.app_name: Tables(main_table=table_assignment.main_table, type=None, scratch_tables=table_assignment.scratch_tables) for table_assignment in response.table_assignments} try: flows = BridgeTools.get_annotated_flows_for_bridge( bridge_name, table_assignments, apps) except subprocess.CalledProcessError as e: if e.returncode == errno.EPERM: print("Need to run as root to dump flows") return for flow in flows: print(flow)
def GetStatus(self, _=None, context=None) -> ServiceStatus: """ Get eNodeB status Note: input variable defaults used so this can be either called locally or as an RPC. """ print_grpc( Void(), self._print_grpc_payload, "GetStatus Request:", ) status = dict(get_service_status(self.state_machine_manager)) status_message = ServiceStatus() status_message.meta.update(status) print_grpc( status_message, self._print_grpc_payload, "GetStatus Response:", ) return status_message
def get_all_records(retries: int = 3, sleep_time: float = 0.1) -> [dict]: """ Make RPC call to 'GetAllDirectoryRecords' method of local directoryD service """ try: chan = ServiceRegistry.get_rpc_channel(DIRECTORYD_SERVICE_NAME, ServiceRegistry.LOCAL) except ValueError: logging.error('Cant get RPC channel to %s', DIRECTORYD_SERVICE_NAME) return client = GatewayDirectoryServiceStub(chan) for _ in range(0, retries): try: res = client.GetAllDirectoryRecords(Void(), DEFAULT_GRPC_TIMEOUT) if res.records is not None: return res.records hub.sleep(sleep_time) except grpc.RpcError as err: logging.error("GetAllDirectoryRecords error! [%s] %s", err.code(), err.details()) return []
def collect(self, service_name): """ Calls into Service303 to get service metrics samples and reschedule collection. """ chan = ServiceRegistry.get_rpc_channel( service_name, ServiceRegistry.LOCAL, ) client = Service303Stub(chan) future = client.GetMetrics.future(Void(), self.grpc_timeout) future.add_done_callback( lambda future: self._loop.call_soon_threadsafe( self.collect_done, service_name, future, ), ) self._loop.call_later( self.collect_interval, self.collect, service_name, )
async def _get_service_info(self): """ Make RPC calls to 'GetServiceInfo' functions of other services, to get current status. """ for service in list(self._service_info): # Check whether service provides service303 interface if service in self._config['non_service303_services']: continue try: chan = ServiceRegistry.get_rpc_channel( service, ServiceRegistry.LOCAL, ) except ValueError: # Service can't be contacted logging.error('Cant get RPC channel to %s', service) continue client = Service303Stub(chan) try: future = client.GetServiceInfo.future( Void(), self.GET_STATUS_TIMEOUT, ) info = await grpc_async_wrapper(future, self._loop) self._service_info[service].update( info.start_time_secs, info.status, ) self._service_info[service].continuous_timeouts = 0 except grpc.RpcError as err: logging.error( "GetServiceInfo Error for %s! [%s] %s", service, err.code(), err.details(), extra=EXCLUDE_FROM_ERROR_MONITORING if indicates_connection_error(err) else None, ) self._service_info[service].continuous_timeouts += 1
def gateway_health_status(self): config = load_service_mconfig_as_json('mme') # eNB status for #eNBs connected chan = ServiceRegistry.get_rpc_channel( 'enodebd', ServiceRegistry.LOCAL, ) client = EnodebdStub(chan) status = client.GetStatus(Void()) mme_log_path = '/var/log/mme.log' health_summary = AGWHealthSummary( hss_relay_enabled=config.get('hssRelayEnabled', False), nb_enbs_connected=status.meta.get('n_enodeb_connected', 0), allocated_ips=self.get_allocated_ips(), subscriber_table=self.get_subscriber_table(), core_dumps=self.get_core_dumps(), registration_success_rate=self.get_registration_success_rate( mme_log_path, ), ) return health_summary
async def get_ping_targets(self, service_loop) -> PingedTargets: """ Sends gRPC call to mobilityd to get all subscribers table. Returns: List of [Subscriber ID => IP address, APN] entries """ try: mobilityd_chan = ServiceRegistry.get_rpc_channel( 'mobilityd', ServiceRegistry.LOCAL) mobilityd_stub = MobilityServiceStub(mobilityd_chan) response = await grpc_async_wrapper( mobilityd_stub.GetSubscriberIPTable.future(Void(), 10), service_loop) for sub in response.entries: ip = _get_addr_from_subscribers(sub.ip) self.ping_addresses.append(ip) self.ping_targets[sub.sid.id] = ip except grpc.RpcError as err: logging.error("GetSubscribers Error for %s! %s", err.code(), err.details()) return PingedTargets(self.ping_targets, self.ping_addresses)
def test_release_ip_address(self): """ test ReleaseIPAddress """ self._stub.AddIPBlock(self._block_msg) alloc_request0 = AllocateIPRequest( sid=self._sid0, version=AllocateIPRequest.IPV4, apn=self._apn0, ) ip_msg0 = self._stub.AllocateIPAddress(alloc_request0) alloc_request1 = AllocateIPRequest( sid=self._sid1, version=AllocateIPRequest.IPV4, apn=self._apn0, ) ip_msg1 = self._stub.AllocateIPAddress(alloc_request1) # release ip_msg0 release_request0 = ReleaseIPRequest( sid=self._sid0, ip=ip_msg0.ip_list[0], apn=self._apn0, ) resp = self._stub.ReleaseIPAddress(release_request0) self.assertEqual(resp, Void()) resp = self._stub.ListAllocatedIPs(self._block_msg) tmp = ListAllocatedIPsResponse() tmp.ip_list.extend([ip_msg1.ip_list[0]]) self.assertEqual(resp, tmp) # release ip_msg1 release_request1 = ReleaseIPRequest( sid=self._sid1, ip=ip_msg1.ip_list[0], apn=self._apn0, ) resp = self._stub.ReleaseIPAddress(release_request1) resp = self._stub.ListAllocatedIPs(self._block_msg) self.assertEqual(len(resp.ip_list), 0)
def test_set_gw_info_vlan2(self): mac1 = "22:22:c6:d0:02:3c" ipaddr1 = ipaddress.ip_address("10.1.1.11") gwinfo_msg1 = GWInfo( ip=IPAddress( version=IPAddress.IPV4, address=ipaddr1.packed, ), mac=mac1, vlan="1", ) self._stub.SetGatewayInfo(gwinfo_msg1) mac2 = "33:22:c6:d0:02:3c" ipaddr2 = ipaddress.ip_address("20.1.1.11") gwinfo_msg2 = GWInfo( ip=IPAddress( version=IPAddress.IPV4, address=ipaddr2.packed, ), mac=mac2, vlan="2", ) self._stub.SetGatewayInfo(gwinfo_msg2) gw_info_list = self._stub.ListGatewayInfo(Void()) count1 = 0 count2 = 0 for gw_info in gw_info_list.gw_list: if gw_info == gwinfo_msg1: count1 = count1 + 1 if gw_info == gwinfo_msg2: count2 = count2 + 1 self.assertEqual(count1, 1) self.assertEqual(count2, 1)