Exemplo n.º 1
0
def set_peer_ids(clients, ids=None) -> data_types.BulkOperationResult:
    """Set peer ids for all clients. Assume order of clients passed as ids

    Arguments:
        clients {List[VNS3Client]}

    Returns:
        BulkOperationResult
    """
    def _set_peer_id(_client, i):
        get_resp = _client.peering.get_peering_status()
        if get_resp.response.id == i:
            _client.add_to_state(VNS3Attr.peer_id, i)
            return get_resp

        resp = _client.peering.put_self_peering_id(id=i)
        _client.add_to_state(VNS3Attr.peer_id, i)
        return resp

    ordered_ids = ids or range(1, len(clients) + 1)

    bound_api_calls = [
        bind(_set_peer_id, client, ordered_ids[index])
        for index, client in enumerate(clients)
    ]

    Logger.debug("Setting peer IDS: %s" % ordered_ids)
    return api_ops.__bulk_call_api(bound_api_calls, parallelize=True)
Exemplo n.º 2
0
def create_peer_mesh_local_gw_routes(
    clients, subnets=None, address_type=VNS3Attr.primary_private_ip
):
    """Create explicit routes between VNS3 peers for peering traffic by pointing peer ips
    to the local gateway.

    For example, for clients = [[email protected], [email protected]]
    in private clouds that are peered where 10.0.1.5 in 10.0.1.0/24 and
    10.0.2.10 in 10.0.2.0/24

    This func  will create the following routes:
        On [email protected]:
            Route: cidr=10.0.2.10/32 on eth0 to network gateway at 10.0.1.1
        On [email protected]:
            Route: cidr=10.0.1.5/32 on eth0 to network gateway at 10.0.2.1

    Assumptions:
        - IF subnets list not passed, Clients need to have the VPC/VNet network they are contained
        in set on their state.
            e.g. client.update_state({"network": "10.0.1.0/24"}); client.query_state("network");
            This function queries the following keys: network

    Arguments:
        clients {List[VNS3Client]}

    Keyword Arguments:
        subnets: List[str] - list of subnets for each client.
        address_type {str} -- Type of address to use for cidr route. (default: {VNS3Attr.primary_private_ip})
    """
    create_client_routes_funcs = []
    client_ips = [
        state.fetch_client_state_attribute(client, address_type) for client in clients
    ]

    if subnets:
        assert len(subnets) == len(
            clients
        ), "If subnets passed, must be same number of clients passed"

    for i, client in enumerate(clients):
        client_subnet_cidr = subnets[i] if subnets else client.query_state("subnet")
        client_ip = state.fetch_client_state_attribute(client, address_type)
        assert (
            client_subnet_cidr
        ), "Each client must have 'subnet' set on client.state if subnets arg not passed"
        create_client_routes_funcs.append(
            bind(
                create_local_gateway_routes_for_peers,
                client,
                client_subnet_cidr,
                list(set(client_ips) - set([client_ip])),
            )
        )

    return api_operations.__bulk_call_api(create_client_routes_funcs, parallelize=True)
Exemplo n.º 3
0
def create_route_advertisements(
    clients, local_subnets
) -> data_types.BulkOperationResult:
    """create_route_advertisements Create a route advertisement for controllers network

    Arguments:
        clients {List[VNS3Client]}
        local_subnets {List[str]} - order should correspond with clients list

    Returns:
        data_types.BulkOperationResult
    """
    assert len(clients) == len(
        local_subnets
    ), "clients list length must equal local_subnets list length"

    invalid = []
    for index, client in enumerate(clients):
        private_ip = state.get_primary_private_ip(client)
        if not network_math.subnet_contains_ipv4(private_ip, local_subnets[index]):
            invalid.append("%s not in %s" % (private_ip, local_subnets[index]))

    if len(invalid):
        raise AssertionError(
            "Invalid subnets provided for clients: %s." % ",".join(invalid)
        )

    def _create_route(_client, subnet):
        return _client.routing.post_create_route(
            **{
                "cidr": subnet,
                "description": "Local subnet advertisement",
                "advertise": True,
                "gateway": "",
            }
        )

    bound_api_calls = [
        bind(_create_route, client, local_subnets[index])
        for index, client in enumerate(clients)
    ]

    return api_operations.__bulk_call_api(bound_api_calls)
Exemplo n.º 4
0
def fetch_state_attribute(clients,
                          attribute,
                          bust_cache=False) -> data_types.BulkOperationResult:
    """Fetch state attribute for all clients

    Arguments:
        clients {List[VNS3Client]}
        attribute {str}

    Keyword Arguments:
        bust_cache {bool}

    Returns:
        [BulkOperationResult] -- [description]
    """
    assert attribute in StateLibrary, "Attribute %s not currently supported" % attribute
    fetch_func = StateLibrary.get(attribute)
    api_calls = [
        bind(fetch_func, client, bust_cache=bust_cache) for client in clients
    ]
    return api_op.__bulk_call_api(api_calls, parallelize=True)
Exemplo n.º 5
0
def peer_mesh(
    clients,
    peer_address_map=None,
    address_type=VNS3Attr.primary_private_ip,
    delay_configure=False,
    mtu=None,
):
    """peer_mesh Create a peering mesh by adding each client as peer for other clients.
       The order of the list of clients is the assumed peering id, i.e. client at clients[0]
       has peering id of 1, clients[1] has peering id of 2. Each TLS connection between peers
       is then automatically negotiated.

    Arguments:
        clients {List[VNS3Client]}

    Keyword Arguments:
        peer_address_map {Dict} - Optional map for peering addresses {
            [from_peer_id: str]: {
                [to_peer_id_1: str]: [peer_address_1: str],
                [to_peer_id_2: str]: [peer_address_2: str],
                ...
            }
        }
        address_type {str} - which address to use. Options: primary_private_ip, secondary_private_ip, public_ip or public_dns
        delay_configure {bool} -- delay automatic negotiation of peer (default: False)
        mtu {int} -- Override MTU for the peering TLS connection. VNS3 defaults to 1500. (default: {None})

    Raises:
        CohesiveSDKException

    Returns:
        data_types.BulkOperationResult
    """
    # fetch peer ids and set on clients
    ensure_peer_ids_result = fetch_state_attribute(clients, VNS3Attr.peer_id)
    if api_ops.bulk_operation_failed(ensure_peer_ids_result):
        errors_str = api_ops.stringify_bulk_result_exception(
            ensure_peer_ids_result)
        Logger.error("Failed to fetch peering Ids for all clients",
                     errors=errors_str)
        raise CohesiveSDKException(
            "Failed to fetch peering Ids for all clients: %s" % errors_str)

    # constructu peer address mapping
    if peer_address_map is not None:
        Logger.debug("Using address map passed for peering mesh.")
        peer_id_to_client = {
            c.query_state(VNS3Attr.peer_id): c
            for c in clients
        }
        peer_address_mapping_tuples = [
            (peer_id_to_client[from_peer_id], to_peers_map)
            for from_peer_id, to_peers_map in peer_address_map.items()
        ]
    else:
        Logger.debug("Constructing peering mesh")
        peer_address_mapping_tuples = _construct_peer_address_mapping(
            clients, address_type)

    common_peer_kwargs = {}
    if delay_configure:
        common_peer_kwargs.update(force=False)
    if mtu:
        common_peer_kwargs.update(overlay_mtu=mtu)

    def create_all_peers_for_client(client, post_peer_kwargs):
        return [
            client.peering.post_create_peer(
                **dict(peering_request, **common_peer_kwargs))
            for peering_request in post_peer_kwargs
        ]

    run_peering_funcs = []
    # bind api function calls for peer creations
    for vns3_client, peer_mapping in peer_address_mapping_tuples:
        run_peering_funcs.append(
            bind(
                create_all_peers_for_client,
                vns3_client,
                [{
                    "id": peer_id,
                    "name": peer_address
                } for peer_id, peer_address in peer_mapping.items()],
            ))

    Logger.debug("Creating %d-way peering mesh." % len(clients))
    return api_ops.__bulk_call_api(run_peering_funcs, parallelize=True)