def get_next_available_gateway_id( network_id: str, admin_cert: types.ClientCert = types.ClientCert( cert='./../../.cache/test_certs/admin_operator.pem', key='./../../.cache/test_certs/admin_operator.key.pem', ), ) -> str: """ Returns the next available gateway ID in the sequence gwN for the given network. Args: network_id: Network to check for available gateways admin_cert: Client cert to use with the API Returns: Next available gateway ID in the form gwN """ # gateways is a dict mapping gw ID to full resource gateways = cloud_get( f'networks/{network_id}/gateways', admin_cert=admin_cert, ) n = len(gateways) + 1 candidate = f'gw{n}' while candidate in gateways: n += 1 candidate = f'gw{n}' return candidate
def is_hw_id_registered( network_id: str, hw_id: str, admin_cert: types.ClientCert = types.ClientCert( cert='./../../.cache/test_certs/admin_operator.pem', key='./../../.cache/test_certs/admin_operator.key.pem', ), ) -> (bool, str): """ Check if a hardware ID is already registered for a given network. Note that this is not a true guarantee that a VM is not already registered, as the HW ID could be taken on another network. Args: network_id: Network to check hw_id: HW ID to check admin_cert: Cert for API access Returns: (True, gw_id) if the HWID is already registered, (False, '') otherwise """ # gateways is a dict mapping gw ID to full resource gateways = cloud_get( f'networks/{network_id}/gateways', admin_cert=admin_cert, ) for gw in gateways.values(): if gw['device']['hardware_id'] == hw_id: return True, gw['id'] return False, ''
def cloud_post( resource: str, data: Any, params: Dict[str, str] = None, admin_cert: types.ClientCert = types.ClientCert( cert='./../../.cache/test_certs/admin_operator.pem', key='./../../.cache/test_certs/admin_operator.key.pem', ), ): """ Send a POST request to an API URI Args: resource: URI to request data: JSON-serializable payload params: Params to include with the request admin_cert: API client certificate """ resp = requests.post( PORTAL_URL + resource, data=jsonpickle.pickler.encode(data), params=params, headers={'content-type': 'application/json'}, verify=False, cert=admin_cert, ) if resp.status_code not in [200, 201, 204]: raise Exception( 'Received a %d response: %s' % (resp.status_code, resp.text), )
def register_generic_gateway( network_id: str, vm_name: str, admin_cert: types.ClientCert = types.ClientCert( cert='./../../.cache/test_certs/admin_operator.pem', key='./../../.cache/test_certs/admin_operator.key.pem', ), ) -> None: """ Register a generic magmad gateway. Args: network_id: Network to register inside vm_name: Vagrant VM name to pull HWID from admin_cert: Cert for API access """ if not does_network_exist(network_id, admin_cert=admin_cert): network_payload = types.GenericNetwork( id=network_id, name='Test Network', description='Test Network', dns=types.NetworkDNSConfig(enable_caching=True, local_ttl=60) ) cloud_post('networks', network_payload, admin_cert=admin_cert) create_tier_if_not_exists(network_id, 'default') hw_id = get_hardware_id_from_vagrant(vm_name=vm_name) already_registered, registered_as = is_hw_id_registered(network_id, hw_id) if already_registered: print(f'VM is already registered as {registered_as}') return gw_id = get_next_available_gateway_id(network_id) payload = construct_magmad_gateway_payload(gw_id, hw_id) cloud_post(f'networks/{network_id}/gateways', payload) print(f'Gateway {gw_id} successfully provisioned')
def create_tier_if_not_exists( network_id: str, tier_id: str, admin_cert: types.ClientCert = types.ClientCert( cert='./../../.cache/test_certs/admin_operator.pem', key='./../../.cache/test_certs/admin_operator.key.pem', ), ) -> None: """ Create a placeholder tier on Orchestrator if the specified one doesn't already exist. Args: network_id: Network the tier belongs to tier_id: ID for the tier admin_cert: Cert for API access """ tiers = cloud_get(f'networks/{network_id}/tiers', admin_cert=admin_cert) if tier_id in tiers: return tier_payload = types.Tier( id=tier_id, version='0.0.0-0', images=[], gateways=[], ) cloud_post( f'networks/{network_id}/tiers', tier_payload, admin_cert=admin_cert, )
def register_vm_remote(certs_dir: str, network_id: str, url: str): """ Register local VM gateway with remote controller. Example usage: fab -f dev_tools.py register_vm_remote:certs_dir=~/certs,network_id=test,url=https://api.stable.magmaeng.org """ if None in {certs_dir, url, network_id}: print() print('==============================================================') print('Must provide the following arguments: certs_dir,url,network_id') print('==============================================================') return admin_cert = types.ClientCert( cert=os.path.expanduser(f'{certs_dir}/admin_operator.pem'), key=os.path.expanduser(f'{certs_dir}/admin_operator.key.pem'), ) full_url = url + '/magma/v1/' _register_agw( LTE_NETWORK_TYPE, url=full_url, admin_cert=admin_cert, network_id=network_id, )
def cloud_delete( resource: str, url: Optional[str] = None, admin_cert: Optional[types.ClientCert] = None, ) -> Any: """ Send a delete request to an API URI Args: resource: URI to request url: API base URL admin_cert: API client certificate Returns: JSON-encoded response content """ url = url or PORTAL_URL admin_cert = admin_cert or types.ClientCert( cert='./../../.cache/test_certs/admin_operator.pem', key='./../../.cache/test_certs/admin_operator.key.pem', ) if resource.startswith("/"): resource = resource[1:] resp = requests.delete(url + resource, verify=False, cert=admin_cert) if resp.status_code not in [200, 201, 204]: raise Exception( 'Delete Request failed: \n%s \nReceived a %d response: %s\nFAILED!' % (resp.url, resp.status_code, resp.text), )
def cloud_get( resource: str, url: Optional[str] = None, admin_cert: Optional[types.ClientCert] = None, ) -> Any: """ Send a GET request to an API URI Args: resource: URI to request url: API base URL admin_cert: API client certificate Returns: JSON-encoded response content """ url = url or PORTAL_URL admin_cert = admin_cert or types.ClientCert( cert='./../../.cache/test_certs/admin_operator.pem', key='./../../.cache/test_certs/admin_operator.key.pem', ) if resource.startswith("/"): resource = resource[1:] resp = requests.get(url + resource, verify=False, cert=admin_cert) if resp.status_code != 200: raise Exception( 'Received a %d response: %s' % (resp.status_code, resp.text), ) return resp.json()
def does_network_exist( network_id: str, admin_cert: types.ClientCert = types.ClientCert( cert='./../../.cache/test_certs/admin_operator.pem', key='./../../.cache/test_certs/admin_operator.key.pem', ), ) -> bool: """ Check for the existence of a network ID Args: network_id: Network to check admin_cert: Cert for API access Returns: True if the network exists, False otherwise """ networks = cloud_get('/networks', admin_cert) return network_id in networks
def does_network_exist( network_id: str, admin_cert: types.ClientCert = types.ClientCert( cert=ADMIN_CERT, key=ADMIN_KEY, ), ) -> bool: """ Check for the existence of a network ID Args: network_id: Network to check admin_cert: Cert for API access Returns: True if the network exists, False otherwise """ networks = cloud_get('/networks', admin_cert) return network_id in networks
def cloud_get( resource: str, admin_cert: types.ClientCert = types.ClientCert( cert='./../../.cache/test_certs/admin_operator.pem', key='./../../.cache/test_certs/admin_operator.key.pem', ), ) -> Any: """ Send a GET request to an API URI Args: resource: URI to request admin_cert: API client certificate Returns: JSON-encoded response content """ resp = requests.get(PORTAL_URL + resource, verify=False, cert=admin_cert) if resp.status_code != 200: raise Exception('Received a %d response: %s' % (resp.status_code, resp.text)) return resp.json()
def cloud_post( resource: str, data: Any, params: Dict[str, str] = None, url: Optional[str] = None, admin_cert: Optional[types.ClientCert] = None, ): """ Send a POST request to an API URI Args: resource: URI to request data: JSON-serializable payload params: Params to include with the request url: API base URL admin_cert: API client certificate """ url = url or PORTAL_URL admin_cert = admin_cert or types.ClientCert( cert='./../../.cache/test_certs/admin_operator.pem', key='./../../.cache/test_certs/admin_operator.key.pem', ) resp = requests.post( url + resource, data=jsonpickle.pickler.encode(data), params=params, headers={'content-type': 'application/json'}, verify=False, cert=admin_cert, ) if resp.status_code not in [200, 201, 204]: parsed = json.loads(jsonpickle.pickler.encode(data)) raise Exception( 'Post Request failed: \n%s\n%s \nReceived a %d response: %s\nFAILED!' % (resp.url, json.dumps(parsed, indent=4, sort_keys=False), resp.status_code, resp.text), )