示例#1
0
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
示例#2
0
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, ''
示例#3
0
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), )
示例#4
0
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')
示例#5
0
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,
    )
示例#6
0
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,
    )
示例#7
0
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), )
示例#8
0
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()
示例#9
0
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
示例#10
0
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
示例#11
0
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()
示例#12
0
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), )