Ejemplo n.º 1
0
def build_desired_state_vpc_single_cluster(cluster_info, ocm: OCM,
                                           awsapi: AWSApi):
    desired_state = []

    peering_info = cluster_info['peering']
    peer_connections = peering_info['connections']
    cluster = cluster_info['name']

    for peer_connection in peer_connections:
        # We only care about account-vpc peering providers
        peer_connection_provider = peer_connection['provider']
        if not peer_connection_provider == 'account-vpc':
            continue
        # requester is the cluster's AWS account
        requester = {
            'cidr_block': cluster_info['network']['vpc'],
            'region': cluster_info['spec']['region']
        }
        connection_name = peer_connection['name']
        peer_vpc = peer_connection['vpc']
        # accepter is the peered AWS account
        accepter = {
            'vpc_id': peer_vpc['vpc_id'],
            'cidr_block': peer_vpc['cidr_block'],
            'region': peer_vpc['region']
        }
        account = peer_vpc['account']
        # assume_role is the role to assume to provision the peering
        # connection request, through the accepter AWS account.
        account['assume_role'] = \
            ocm.get_aws_infrastructure_access_terraform_assume_role(
            cluster,
            peer_vpc['account']['uid'],
            peer_vpc['account']['terraformUsername']
        )
        account['assume_region'] = requester['region']
        account['assume_cidr'] = requester['cidr_block']
        requester_vpc_id, requester_route_table_ids, _ = \
            awsapi.get_cluster_vpc_details(
                account,
                route_tables=peer_connection.get('manageRoutes')
            )

        if requester_vpc_id is None:
            raise BadTerraformPeeringState(
                f'[{cluster} could not find VPC ID for cluster')
        requester['vpc_id'] = requester_vpc_id
        requester['route_table_ids'] = requester_route_table_ids
        requester['account'] = account
        accepter['account'] = account
        item = {
            'connection_provider': peer_connection_provider,
            'connection_name': connection_name,
            'requester': requester,
            'accepter': accepter,
            'deleted': peer_connection.get('delete', False)
        }
        desired_state.append(item)
    return desired_state
def build_desired_state_tgw_attachments(clusters, ocm_map: OCMMap,
                                        awsapi: AWSApi):
    """
    Fetch state for TGW attachments between a cluster and all TGWs
    in an account in the same region as the cluster
    """
    desired_state = []
    error = False

    for cluster_info in clusters:
        cluster = cluster_info["name"]
        ocm = ocm_map.get(cluster)
        peering_info = cluster_info["peering"]
        peer_connections = peering_info["connections"]
        for peer_connection in peer_connections:
            # We only care about account-tgw peering providers
            peer_connection_provider = peer_connection["provider"]
            if not peer_connection_provider == "account-tgw":
                continue
            # accepter is the cluster's AWS account
            cluster_region = cluster_info["spec"]["region"]
            cluster_cidr_block = cluster_info["network"]["vpc"]
            accepter = {
                "cidr_block": cluster_cidr_block,
                "region": cluster_region
            }

            account = peer_connection["account"]
            # assume_role is the role to assume to provision the
            # peering connection request, through the accepter AWS account.
            provided_assume_role = peer_connection.get("assumeRole")
            # if an assume_role is provided, it means we don't need
            # to get the information from OCM. it likely means that
            # there is no OCM at all.
            if provided_assume_role:
                account["assume_role"] = provided_assume_role
            else:
                account[
                    "assume_role"] = ocm.get_aws_infrastructure_access_terraform_assume_role(
                        cluster, account["uid"], account["terraformUsername"])
            account["assume_region"] = accepter["region"]
            account["assume_cidr"] = accepter["cidr_block"]
            (
                accepter_vpc_id,
                accepter_route_table_ids,
                accepter_subnets_id_az,
            ) = awsapi.get_cluster_vpc_details(
                account,
                route_tables=peer_connection.get("manageRoutes"),
                subnets=True,
            )

            if accepter_vpc_id is None:
                logging.error(f"[{cluster} could not find VPC ID for cluster")
                error = True
                continue
            accepter["vpc_id"] = accepter_vpc_id
            accepter["route_table_ids"] = accepter_route_table_ids
            accepter["subnets_id_az"] = accepter_subnets_id_az
            accepter["account"] = account

            account_tgws = awsapi.get_tgws_details(
                account,
                cluster_region,
                cluster_cidr_block,
                tags=json.loads(peer_connection.get("tags") or "{}"),
                route_tables=peer_connection.get("manageRoutes"),
                security_groups=peer_connection.get("manageSecurityGroups"),
            )
            for tgw in account_tgws:
                tgw_id = tgw["tgw_id"]
                connection_name = (f"{peer_connection['name']}_" +
                                   f"{account['name']}-{tgw_id}")
                requester = {
                    "tgw_id": tgw_id,
                    "tgw_arn": tgw["tgw_arn"],
                    "region": tgw["region"],
                    "routes": tgw.get("routes"),
                    "rules": tgw.get("rules"),
                    "cidr_block": peer_connection.get("cidrBlock"),
                    "account": account,
                }
                item = {
                    "connection_provider": peer_connection_provider,
                    "connection_name": connection_name,
                    "requester": requester,
                    "accepter": accepter,
                    "deleted": peer_connection.get("delete", False),
                }
                desired_state.append(item)

    return desired_state, error
def build_desired_state_tgw_attachments(clusters, ocm_map, settings):
    """
    Fetch state for TGW attachments between a cluster and all TGWs
    in an account in the same region as the cluster
    """
    desired_state = []
    error = False

    for cluster_info in clusters:
        cluster = cluster_info['name']
        ocm = ocm_map.get(cluster)
        peering_info = cluster_info['peering']
        peer_connections = peering_info['connections']
        for peer_connection in peer_connections:
            # We only care about account-tgw peering providers
            peer_connection_provider = peer_connection['provider']
            if not peer_connection_provider == 'account-tgw':
                continue
            # accepter is the cluster's AWS account
            cluster_region = cluster_info['spec']['region']
            cluster_cidr_block = cluster_info['network']['vpc']
            accepter = {
                'cidr_block': cluster_cidr_block,
                'region': cluster_region
            }

            account = peer_connection['account']
            # assume_role is the role to assume to provision the
            # peering connection request, through the accepter AWS account.
            account['assume_role'] = \
                ocm.get_aws_infrastructure_access_terraform_assume_role(
                    cluster,
                    account['uid'],
                    account['terraformUsername']
                )
            account['assume_region'] = accepter['region']
            account['assume_cidr'] = accepter['cidr_block']
            aws_api = AWSApi(1, [account], settings=settings)
            accepter_vpc_id, accepter_route_table_ids, \
                accepter_subnets_id_az = \
                aws_api.get_cluster_vpc_details(
                    account,
                    route_tables=peer_connection.get('manageRoutes'),
                    subnets=True,
                )

            if accepter_vpc_id is None:
                logging.error(f'[{cluster} could not find VPC ID for cluster')
                error = True
                continue
            accepter['vpc_id'] = accepter_vpc_id
            accepter['route_table_ids'] = accepter_route_table_ids
            accepter['subnets_id_az'] = accepter_subnets_id_az
            accepter['account'] = account

            account_tgws = \
                aws_api.get_tgws_details(
                    account,
                    cluster_region,
                    cluster_cidr_block,
                    tags=json.loads(peer_connection.get('tags') or {}),
                    route_tables=peer_connection.get('manageRoutes'),
                    security_groups=peer_connection.get(
                        'manageSecurityGroups'),
                )
            for tgw in account_tgws:
                tgw_id = tgw['tgw_id']
                connection_name = \
                    f"{peer_connection['name']}_" + \
                    f"{account['name']}-{tgw_id}"
                requester = {
                    'tgw_id': tgw_id,
                    'tgw_arn': tgw['tgw_arn'],
                    'region': tgw['region'],
                    'routes': tgw.get('routes'),
                    'rules': tgw.get('rules'),
                    'cidr_block': peer_connection.get('cidrBlock'),
                    'account': account,
                }
                item = {
                    'connection_provider': peer_connection_provider,
                    'connection_name': connection_name,
                    'requester': requester,
                    'accepter': accepter,
                    'deleted': peer_connection.get('delete', False)
                }
                desired_state.append(item)

    return desired_state, error
Ejemplo n.º 4
0
def build_desired_state_cluster(clusters, ocm_map, settings):
    """
    Fetch state for VPC peerings between two OCM clusters
    """
    desired_state = []
    error = False

    for cluster_info in clusters:
        cluster_name = cluster_info['name']

        # Find an aws account with the "network-mgmt" access level on the
        # requester cluster and use that as the account for the requester
        req_aws = aws_account_from_infrastructure_access(
            cluster_info, 'network-mgmt', ocm_map)
        if not req_aws:
            msg = f"could not find an AWS account with the " \
                  f"'network-mgmt' access level on the cluster {cluster_name}"
            logging.error(msg)
            error = True
            continue
        req_aws['assume_region'] = cluster_info['spec']['region']
        req_aws['assume_cidr'] = cluster_info['network']['vpc']

        peering_info = cluster_info['peering']
        peer_connections = peering_info['connections']
        for peer_connection in peer_connections:
            # We only care about cluster-vpc-requester peering providers
            peer_connection_provider = peer_connection['provider']
            if not peer_connection_provider == 'cluster-vpc-requester':
                continue

            peer_connection_name = peer_connection['name']
            peer_cluster = peer_connection['cluster']
            peer_cluster_name = peer_cluster['name']
            requester_manage_routes = peer_connection.get('manageRoutes')

            # Ensure we have a matching peering connection
            peer_info = find_matching_peering(cluster_info, peer_connection,
                                              peer_cluster,
                                              'cluster-vpc-accepter')
            if not peer_info:
                msg = f"could not find a matching peering connection for " \
                      f"cluster {cluster_name}, " \
                      f"connection {peer_connection_name}"
                logging.error(msg)
                error = True
                continue
            accepter_manage_routes = peer_info.get('manageRoutes')

            aws_api = AWSApi(1, [req_aws], settings=settings)
            requester_vpc_id, requester_route_table_ids, _ = \
                aws_api.get_cluster_vpc_details(
                    req_aws,
                    route_tables=requester_manage_routes
                )
            if requester_vpc_id is None:
                msg = f'[{cluster_name} could not find VPC ID for cluster'
                logging.error(msg)
                error = True
                continue
            requester = {
                'cidr_block': cluster_info['network']['vpc'],
                'region': cluster_info['spec']['region'],
                'vpc_id': requester_vpc_id,
                'route_table_ids': requester_route_table_ids,
                'account': req_aws
            }

            # Find an aws account with the "network-mgmt" access level on the
            # peer cluster and use that as the account for the accepter
            acc_aws = aws_account_from_infrastructure_access(
                peer_cluster, 'network-mgmt', ocm_map)
            if not acc_aws:
                msg = "could not find an AWS account with the " \
                    "'network-mgmt' access level on the cluster"
                logging.error(msg)
                error = True
                continue
            acc_aws['assume_region'] = peer_cluster['spec']['region']
            acc_aws['assume_cidr'] = peer_cluster['network']['vpc']

            aws_api = AWSApi(1, [acc_aws], settings=settings)
            accepter_vpc_id, accepter_route_table_ids, _ = \
                aws_api.get_cluster_vpc_details(
                    acc_aws,
                    route_tables=accepter_manage_routes
                )
            if accepter_vpc_id is None:
                msg = f'[{peer_cluster_name} could not find VPC ID for cluster'
                logging.error(msg)
                error = True
                continue
            requester['peer_owner_id'] = acc_aws['assume_role'].split(':')[4]
            accepter = {
                'cidr_block': peer_cluster['network']['vpc'],
                'region': peer_cluster['spec']['region'],
                'vpc_id': accepter_vpc_id,
                'route_table_ids': accepter_route_table_ids,
                'account': acc_aws
            }

            item = {
                'connection_provider': peer_connection_provider,
                'connection_name': peer_connection_name,
                'requester': requester,
                'accepter': accepter,
                'deleted': peer_connection.get('delete', False)
            }
            desired_state.append(item)

    return desired_state, error
Ejemplo n.º 5
0
def build_desired_state_vpc(clusters, ocm_map, settings):
    """
    Fetch state for VPC peerings between a cluster and a VPC (account)
    """
    desired_state = []
    error = False

    for cluster_info in clusters:
        cluster = cluster_info['name']
        ocm = ocm_map.get(cluster)
        peering_info = cluster_info['peering']
        peer_connections = peering_info['connections']
        for peer_connection in peer_connections:
            # We only care about account-vpc peering providers
            peer_connection_provider = peer_connection['provider']
            if not peer_connection_provider == 'account-vpc':
                continue
            # requester is the cluster's AWS account
            requester = {
                'cidr_block': cluster_info['network']['vpc'],
                'region': cluster_info['spec']['region']
            }

            connection_name = peer_connection['name']
            peer_vpc = peer_connection['vpc']
            # accepter is the peered AWS account
            accepter = {
                'vpc_id': peer_vpc['vpc_id'],
                'cidr_block': peer_vpc['cidr_block'],
                'region': peer_vpc['region']
            }
            account = peer_vpc['account']
            # assume_role is the role to assume to provision the
            # peering connection request, through the accepter AWS account.
            account['assume_role'] = \
                ocm.get_aws_infrastructure_access_terraform_assume_role(
                    cluster,
                    peer_vpc['account']['uid'],
                    peer_vpc['account']['terraformUsername']
                )
            account['assume_region'] = requester['region']
            account['assume_cidr'] = requester['cidr_block']
            aws_api = AWSApi(1, [account], settings=settings)
            requester_vpc_id, requester_route_table_ids, _ = \
                aws_api.get_cluster_vpc_details(
                    account,
                    route_tables=peer_connection.get('manageRoutes')
                )

            if requester_vpc_id is None:
                logging.error(f'[{cluster} could not find VPC ID for cluster')
                error = True
                continue
            requester['vpc_id'] = requester_vpc_id
            requester['route_table_ids'] = requester_route_table_ids
            requester['account'] = account
            accepter['account'] = account
            item = {
                'connection_provider': peer_connection_provider,
                'connection_name': connection_name,
                'requester': requester,
                'accepter': accepter,
                'deleted': peer_connection.get('delete', False)
            }
            desired_state.append(item)
    return desired_state, error
def build_desired_state_vpc_single_cluster(cluster_info, ocm: Optional[OCM],
                                           awsapi: AWSApi):
    desired_state = []

    peering_info = cluster_info['peering']
    peer_connections = peering_info['connections']
    cluster = cluster_info['name']

    for peer_connection in peer_connections:
        # We only care about account-vpc peering providers
        peer_connection_provider = peer_connection['provider']
        if not peer_connection_provider == 'account-vpc':
            continue
        # requester is the cluster's AWS account
        requester = {
            'cidr_block': cluster_info['network']['vpc'],
            'region': cluster_info['spec']['region']
        }
        connection_name = peer_connection['name']
        peer_vpc = peer_connection['vpc']
        # accepter is the peered AWS account
        accepter = {
            'vpc_id': peer_vpc['vpc_id'],
            'cidr_block': peer_vpc['cidr_block'],
            'region': peer_vpc['region']
        }
        account = peer_vpc['account']
        # assume_role is the role to assume to provision the peering
        # connection request, through the accepter AWS account.
        provided_assume_role = peer_connection.get('assumeRole')
        # if an assume_role is provided, it means we don't need
        # to get the information from OCM. it likely means that
        # there is no OCM at all.
        if provided_assume_role:
            account['assume_role'] = provided_assume_role
        elif ocm is not None:
            account['assume_role'] = \
                ocm.get_aws_infrastructure_access_terraform_assume_role(
                cluster,
                peer_vpc['account']['uid'],
                peer_vpc['account']['terraformUsername']
            )
        else:
            raise KeyError(
                f'[{cluster}] peering connection '
                f'{connection_name} must either specify assumeRole '
                'or ocm should be defined to obtain role to assume')
        account['assume_region'] = requester['region']
        account['assume_cidr'] = requester['cidr_block']
        requester_vpc_id, requester_route_table_ids, _ = \
            awsapi.get_cluster_vpc_details(
                account,
                route_tables=peer_connection.get('manageRoutes')
            )

        if requester_vpc_id is None:
            raise BadTerraformPeeringState(
                f'[{cluster}] could not find VPC ID for cluster'
            )
        requester['vpc_id'] = requester_vpc_id
        requester['route_table_ids'] = requester_route_table_ids
        requester['account'] = account
        accepter['account'] = account
        item = {
            'connection_provider': peer_connection_provider,
            'connection_name': connection_name,
            'requester': requester,
            'accepter': accepter,
            'deleted': peer_connection.get('delete', False)
        }
        desired_state.append(item)
    return desired_state
def build_desired_state_single_cluster(cluster_info, ocm: OCM,
                                       awsapi: AWSApi):
    cluster_name = cluster_info['name']

    peerings = []

    peering_info = cluster_info['peering']
    peer_connections = peering_info['connections']
    for peer_connection in peer_connections:
        # We only care about cluster-vpc-requester peering providers
        peer_connection_provider = peer_connection['provider']
        if peer_connection_provider != 'cluster-vpc-requester':
            continue

        peer_connection_name = peer_connection['name']
        peer_cluster = peer_connection['cluster']
        peer_cluster_name = peer_cluster['name']
        requester_manage_routes = peer_connection.get('manageRoutes')
        # Ensure we have a matching peering connection
        peer_info = find_matching_peering(cluster_info,
                                          peer_cluster,
                                          'cluster-vpc-accepter')
        if not peer_info:
            raise BadTerraformPeeringState(
                "[no_matching_peering] could not find a matching peering "
                f"connection for cluster {cluster_name}, connection "
                f"{peer_connection_name}"
            )

        accepter_manage_routes = peer_info.get('manageRoutes')

        req_aws, acc_aws = aws_assume_roles_for_cluster_vpc_peering(
            cluster_info,
            peer_info,
            peer_cluster,
            ocm
        )

        requester_vpc_id, requester_route_table_ids, _ = \
            awsapi.get_cluster_vpc_details(
                req_aws,
                route_tables=requester_manage_routes
            )
        if requester_vpc_id is None:
            raise BadTerraformPeeringState(
                f'[{cluster_name}] could not find VPC ID for cluster'
            )

        requester = {
            'cidr_block': cluster_info['network']['vpc'],
            'region': cluster_info['spec']['region'],
            'vpc_id': requester_vpc_id,
            'route_table_ids': requester_route_table_ids,
            'account': req_aws
        }

        accepter_vpc_id, accepter_route_table_ids, _ = \
            awsapi.get_cluster_vpc_details(
                acc_aws,
                route_tables=accepter_manage_routes
            )
        if accepter_vpc_id is None:
            raise BadTerraformPeeringState(
                f'[{peer_cluster_name}] could not find VPC ID for cluster'
            )

        requester['peer_owner_id'] = acc_aws['assume_role'].split(':')[4]
        accepter = {
            'cidr_block': peer_cluster['network']['vpc'],
            'region': peer_cluster['spec']['region'],
            'vpc_id': accepter_vpc_id,
            'route_table_ids': accepter_route_table_ids,
            'account': acc_aws
        }

        item = {
            'connection_provider': peer_connection_provider,
            'connection_name': peer_connection_name,
            'requester': requester,
            'accepter': accepter,
            'deleted': peer_connection.get('delete', False)
        }
        peerings.append(item)

    return peerings
Ejemplo n.º 8
0
def build_desired_state_single_cluster(cluster_info, ocm_map: OCMMap,
                                       awsapi: AWSApi):
    cluster_name = cluster_info['name']

    peerings = []
    # Find an aws account with the "network-mgmt" access level on the
    # requester cluster and use that as the account for the requester
    req_aws = aws_account_from_infrastructure_access(cluster_info,
                                                     'network-mgmt', ocm_map)
    if not req_aws:
        raise BadTerraformPeeringState(
            "could not find an AWS account with the "
            f"'network-mgmt' access level on the cluster {cluster_name}")

    peering_info = cluster_info['peering']
    peer_connections = peering_info['connections']
    for peer_connection in peer_connections:
        # We only care about cluster-vpc-requester peering providers
        peer_connection_provider = peer_connection['provider']
        if peer_connection_provider != 'cluster-vpc-requester':
            continue

        peer_connection_name = peer_connection['name']
        peer_cluster = peer_connection['cluster']
        peer_cluster_name = peer_cluster['name']
        requester_manage_routes = peer_connection.get('manageRoutes')
        # Ensure we have a matching peering connection
        peer_info = find_matching_peering(cluster_info, peer_connection,
                                          peer_cluster, 'cluster-vpc-accepter')
        if not peer_info:
            raise BadTerraformPeeringState(
                "could not find a matching peering connection for "
                f"cluster {cluster_name}, connection {peer_connection_name}")

        accepter_manage_routes = peer_info.get('manageRoutes')

        requester_vpc_id, requester_route_table_ids, _ = \
            awsapi.get_cluster_vpc_details(
                req_aws,
                route_tables=requester_manage_routes
            )
        if requester_vpc_id is None:
            raise BadTerraformPeeringState(
                f'[{cluster_name} could not find VPC ID for cluster')

        requester = {
            'cidr_block': cluster_info['network']['vpc'],
            'region': cluster_info['spec']['region'],
            'vpc_id': requester_vpc_id,
            'route_table_ids': requester_route_table_ids,
            'account': req_aws
        }

        # Find an aws account with the "network-mgmt" access level on
        # the peer cluster and use that as the account for the
        # accepter
        acc_aws = aws_account_from_infrastructure_access(
            peer_cluster, 'network-mgmt', ocm_map)
        if not acc_aws:
            raise BadTerraformPeeringState(
                "could not find an AWS account with the "
                f"'network-mgmt' access level on cluster {cluster_name}, "
                f"peering {peer_connection_name}")

        accepter_vpc_id, accepter_route_table_ids, _ = \
            awsapi.get_cluster_vpc_details(
                acc_aws,
                route_tables=accepter_manage_routes
            )
        if accepter_vpc_id is None:
            raise BadTerraformPeeringState(
                f'{peer_cluster_name} could not find VPC ID for cluster')

        requester['peer_owner_id'] = acc_aws['assume_role'].split(':')[4]
        accepter = {
            'cidr_block': peer_cluster['network']['vpc'],
            'region': peer_cluster['spec']['region'],
            'vpc_id': accepter_vpc_id,
            'route_table_ids': accepter_route_table_ids,
            'account': acc_aws
        }

        item = {
            'connection_provider': peer_connection_provider,
            'connection_name': peer_connection_name,
            'requester': requester,
            'accepter': accepter,
            'deleted': peer_connection.get('delete', False)
        }
        peerings.append(item)

    return peerings