Esempio n. 1
0
async def retrieve_accounts_from_swag() -> CloudAccountModelArray:
    function: str = f"{sys._getframe().f_code.co_name}"
    expected_owners: List = config.get(
        "retrieve_accounts_from_swag.expected_owners", [])

    swag_base_url = config.get("retrieve_accounts_from_swag.base_url")
    if not swag_base_url:
        raise MissingConfigurationValue(
            "Unable to find Swag URL in configuration")
    swag_url = swag_base_url + "api/1/accounts"

    try:
        http_client = AsyncHTTPClient(force_instance=True)
        resp = await http_client.fetch(
            swag_url,
            headers={
                "Content-Type": "application/json",
                "Accept": "application/json"
            },
        )

    except (ConnectionError, HTTPClientError) as e:
        log.error(
            {
                "message": "Unable to connect to SWAG",
                "error": str(e),
                "function": function,
            },
            exc_info=True,
        )
        stats.count(f"{function}.connectionerror")
        raise
    swag_accounts = json.loads(resp.body)
    cloud_accounts = []
    for account in swag_accounts:
        # Ignore third party accounts
        if expected_owners and account.get("owner") not in expected_owners:
            continue
        account_status = account["account_status"]
        sync_enabled = False
        if account_status == "ready":
            account_status = "active"
            sync_enabled = True
        cloud_accounts.append(
            CloudAccountModel(
                id=account["id"],
                name=account["name"],
                email=account["email"],
                status=account_status,
                sync_enabled=sync_enabled,
                sensitive=account["sensitive"],
                environment=account["environment"],
                aliases=account["aliases"],
                type="aws",
            ))
    return CloudAccountModelArray(accounts=cloud_accounts)
Esempio n. 2
0
async def get_cloud_account_model_array(status="active",
                                        environment=None,
                                        force_sync=False):
    redis_key = config.get("cache_cloud_accounts.redis.key.all_accounts_key",
                           "ALL_AWS_ACCOUNTS")
    accounts = await retrieve_json_data_from_redis_or_s3(redis_key, default={})
    if force_sync or not accounts or not accounts.get("accounts"):
        # Force a re-sync and then retry
        await cache_cloud_accounts()
        accounts = await retrieve_json_data_from_redis_or_s3(redis_key,
                                                             default={})
    all_accounts = CloudAccountModelArray.parse_obj(accounts)
    filtered_accounts = CloudAccountModelArray(accounts=[])
    for account in all_accounts.accounts:
        if status and account.status.value != status:
            continue
        if environment and account.environment.value != environment:
            continue
        filtered_accounts.accounts.append(account)
    return filtered_accounts
Esempio n. 3
0
async def retrieve_accounts_from_aws_organizations() -> CloudAccountModelArray:
    """
    Polls AWS Organizations for our Account ID to Account Name mapping
    :param: null
    :return: CloudAccountModelArray
    """

    cloud_accounts = []
    for organization in config.get("cache_accounts_from_aws_organizations", []):
        organizations_master_account_id = organization.get(
            "organizations_master_account_id"
        )
        role_to_assume = organization.get(
            "organizations_master_role_to_assume",
            config.get("policies.role_name"),
        )
        if not organizations_master_account_id:
            raise MissingConfigurationValue(
                "Your AWS Organizations Master Account ID is not specified in configuration. "
                "Unable to sync accounts from "
                "AWS Organizations"
            )

        if not role_to_assume:
            raise MissingConfigurationValue(
                "ConsoleMe doesn't know what role to assume to retrieve account information "
                "from AWS Organizations. please set the appropriate configuration value."
            )
        client = await sync_to_async(boto3_cached_conn)(
            "organizations",
            account_number=organizations_master_account_id,
            assume_role=role_to_assume,
            session_name="ConsoleMeOrganizationsSync",
        )
        paginator = await sync_to_async(client.get_paginator)("list_accounts")
        page_iterator = await sync_to_async(paginator.paginate)()
        accounts = []
        for page in page_iterator:
            accounts.extend(page["Accounts"])

        for account in accounts:
            status = account["Status"].lower()
            cloud_accounts.append(
                CloudAccountModel(
                    id=account["Id"],
                    name=account["Name"],
                    email=account["Email"],
                    status=status,
                    type="aws",
                    sync_enabled=True,  # TODO: Check for tag to disable sync?
                )
            )

    return CloudAccountModelArray(accounts=cloud_accounts)
Esempio n. 4
0
async def retrieve_accounts_from_config() -> CloudAccountModelArray:
    cloud_accounts = []
    accounts_in_configuration = config.get(
        "dynamic_config.account_ids_to_name", {})
    accounts_in_configuration.update(config.get("account_ids_to_name", {}))
    for account_id, names in accounts_in_configuration.items():
        account_name = names
        # Legacy support for a list of account names (with aliases)
        if account_name and isinstance(account_name, list):
            account_name = account_name[0]
        cloud_accounts.append(
            CloudAccountModel(
                id=account_id,
                name=account_name,
                status="active",
                sync_enabled=True,
                type="aws",
            ))
    return CloudAccountModelArray(accounts=cloud_accounts)
Esempio n. 5
0
async def retrieve_current_account() -> CloudAccountModelArray:
    client = boto3.client("sts")
    identity = client.get_caller_identity()
    account_aliases = boto3.client("iam").list_account_aliases()["AccountAliases"]
    account_id = None
    if identity and identity.get("Account"):
        account_id = identity.get("Account")
    account_name = account_id

    if account_aliases:
        account_name = account_aliases[0]

    cloud_account = [
        CloudAccountModel(
            id=account_id,
            name=account_name,
            status="active",
            sync_enabled=True,
            type="aws",
        )
    ]
    return CloudAccountModelArray(accounts=cloud_account)