import logging import boto3 import progressbar sts_client = None iam_client = None ses_client = None cache = None def init(boto_config, cache3_cache): """Initialize the module. Args: boto_config: AWS configuration. cache3_cache: Cache engine instance. """ global sts_client, iam_client, ses_client, cache sts_client = boto3.client('sts', config=boto_config) iam_client = boto3.client('iam', config=boto_config) ses_client = boto3.client('ses', config=boto_config) cache = cache3_cache def get_account_id(): """Get AWS account ID. Returns: string: Account ID number. """ response = sts_client.get_caller_identity() return response['Account'] def get_account_aliases(): """Get AWS account IAM aliases. Returns: list: Account aliases. """ response = iam_client.list_account_aliases() return response['AccountAliases'] def get_iam_users(): """Get IAM users with all related data. Returns: list: List of all IAM users. """ logging.info('Fetching IAM user list') iam_users = _get_iam_user_list() logging.info('Fetching IAM user tags') _update_users_with_tags(iam_users) logging.info('Fetching IAM user login profiles') _update_users_with_login_profile(iam_users) logging.info('Fetching IAM user MFA devices') _update_users_with_mfa_devices(iam_users) logging.info('Fetching IAM user access keys') _update_users_with_access_keys(iam_users) logging.info('Fetching IAM user access key details') _update_users_with_access_key_details(iam_users) return iam_users def send_email(addr, subject, body): """Send email. Args: addr: Email address. subject: Subject. body: Content. """ ses_client.send_email(Source='noreply@theorchard.com', Destination={'ToAddresses': [addr]}, Message={ 'Subject': {'Data': subject}, 'Body': {'Text': {'Data': body}} }) def _get_iam_user_list(): """Get IAM users. Returns: list: List of all IAM users. """ iam_users = [] cache_key = 'users' if cache_key in cache: iam_users = cache[cache_key] else: paginator = iam_client.get_paginator('list_users') response_iterator = paginator.paginate( PaginationConfig={ 'MaxItems': 5000, 'PageSize': 100, } ) for page in response_iterator: iam_users.extend(page['Users']) cache[cache_key] = iam_users return iam_users def _update_users_with_tags(iam_users): """Update IAM user list with tags. Args: iam_users: List of all IAM users. """ for iam_user in progressbar.progressbar(iam_users, redirect_stdout=True): cache_key = 'tags/{}'.format(iam_user['UserName']) if cache_key in cache: iam_user['Tags'] = cache[cache_key] else: response = iam_client.list_user_tags( UserName=iam_user['UserName'] ) iam_user['Tags'] = response['Tags'] cache[cache_key] = response['Tags'] def _update_users_with_login_profile(iam_users): """Update IAM user list with login profile. Args: iam_users: List of all IAM users. """ for iam_user in progressbar.progressbar(iam_users, redirect_stdout=True): cache_key = 'login_profiles/{}'.format(iam_user['UserName']) if cache_key in cache: iam_user['LoginProfile'] = cache[cache_key] else: try: response = iam_client.get_login_profile( UserName=iam_user['UserName'] ) iam_user['LoginProfile'] = response['LoginProfile'] cache[cache_key] = response['LoginProfile'] except iam_client.exceptions.NoSuchEntityException: iam_user['LoginProfile'] = {} cache[cache_key] = {} def _update_users_with_mfa_devices(iam_users): """Update IAM user list with MFA devices. Args: iam_users: List of all IAM users. """ for iam_user in progressbar.progressbar(iam_users, redirect_stdout=True): cache_key = 'mfa_devices/{}'.format(iam_user['UserName']) if cache_key in cache: iam_user['MFADevices'] = cache[cache_key] else: try: response = iam_client.list_mfa_devices( UserName=iam_user['UserName'] ) iam_user['MFADevices'] = response['MFADevices'] cache[cache_key] = response['MFADevices'] except iam_client.exceptions.NoSuchEntityException: iam_user['MFADevices'] = {} cache[cache_key] = {} def _update_users_with_access_keys(iam_users): """Update IAM user list with access keys. Args: iam_users: List of all IAM users. """ for iam_user in progressbar.progressbar(iam_users, redirect_stdout=True): cache_key = 'access_keys_metadata/{}'.format(iam_user['UserName']) if cache_key in cache: iam_user['AccessKeyMetadata'] = cache[cache_key] else: response = iam_client.list_access_keys( UserName=iam_user['UserName'] ) iam_user['AccessKeyMetadata'] = response['AccessKeyMetadata'] cache[cache_key] = response['AccessKeyMetadata'] def _update_users_with_access_key_details(iam_users): """Update IAM user access keys with last used info. Args: iam_users: List of all IAM users. """ for iam_user in progressbar.progressbar(iam_users, redirect_stdout=True): for i, key in enumerate(iam_user['AccessKeyMetadata']): cache_key = 'access_key_last_used/{}'.format(key['AccessKeyId']) if cache_key in cache: key['AccessKeyLastUsed'] = cache[cache_key] else: response = iam_client.get_access_key_last_used( AccessKeyId=key['AccessKeyId'] ) key['AccessKeyLastUsed'] = response['AccessKeyLastUsed'] cache[cache_key] = response['AccessKeyLastUsed']