def configure(file, account_name_pattern, saml_user, saml_password, dry_run): '''Configure one or more AWS account(s) matching the provided pattern''' config = yaml.safe_load(file) accounts = config.get('accounts', {}) account_names = sorted(fnmatch.filter(accounts.keys(), account_name_pattern)) if not account_names: error('No configuration found for account {}'.format(account_name_pattern)) return trusted_addresses = None global_cfg = config.get('global', {}) for account_name in account_names: cfg = accounts.get(account_name) or {} for key, val in global_cfg.items(): if key not in cfg: cfg[key] = val saml_url = cfg.get('saml_identity_provider_url') saml_role = cfg.get('saml_admin_login_role') if saml_user and saml_url and saml_role: if not saml_password: saml_password = keyring.get_password('sevenseconds', saml_user) if not saml_password: saml_password = click.prompt('Please enter your SAML password', hide_input=True) with Action('Authenticating against {}..'.format(saml_url)): saml_xml, roles = authenticate(saml_url, saml_user, saml_password) keyring.set_password('sevenseconds', saml_user, saml_password) account_alias = cfg.get('alias', account_name).format(account_name=account_name) matching_roles = [(parn, rarn, aname) for parn, rarn, aname in roles if aname == account_alias and rarn.endswith(saml_role)] if not matching_roles: error('No matching role found for account {}: {}'.format(account_name, roles)) warning('Skipping account configuration of {} due to missing credentials'.format(account_name)) continue role = matching_roles[0] with Action('Assuming role {}..'.format(role)): key_id, secret, session_token = assume_role(saml_xml, role[0], role[1]) write_aws_credentials('default', key_id, secret, session_token) if not trusted_addresses: trusted_addresses = get_trusted_addresses(config) try: configure_account(account_name, cfg, trusted_addresses, dry_run) except Exception: error('Error while configuring {}: {}'.format(account_name, traceback.format_exc()))
def get_aws_credentials(saml_user, saml_password, saml_url, saml_role, account_alias, credential_name): if not saml_password: saml_password = keyring.get_password('sevenseconds', saml_user) if not saml_password: saml_password = click.prompt('Please enter your SAML password', hide_input=True) with Action('[{}] Authenticating against {}..'.format(credential_name, saml_url)): saml_xml, roles = authenticate(saml_url, saml_user, saml_password) keyring.set_password('sevenseconds', saml_user, saml_password) matching_roles = [(parn, rarn, aname) for parn, rarn, aname in roles if aname == account_alias and rarn.endswith(saml_role)] if not matching_roles: error('[{}] No matching role found for account {}'.format(credential_name, account_alias)) return False else: role = matching_roles[0] with Action('[{}] Assuming role {}..'.format(credential_name, role)): key_id, secret, session_token = assume_role(saml_xml, role[0], role[1]) write_aws_credentials(credential_name, key_id, secret, session_token) return True
def saml_login(user, url): ring_user = '******'.format(user, url) saml_password = keyring.get_password('mai', ring_user) saml_xml = None while not saml_xml: if not saml_password: saml_password = click.prompt('Please enter your SAML password', hide_input=True) with Action('Authenticating against {url}..', url=url) as act: try: saml_xml, roles = authenticate(url, user, saml_password) except aws_saml_login.saml.AuthenticationFailed: act.error('Authentication Failed') info('Please check your username/password and try again.') saml_password = None keyring.set_password('mai', ring_user, saml_password) return saml_xml, roles
def get_aws_credentials(saml_batch, saml_user, saml_password): if not saml_password: saml_password = keyring.get_password('sevenseconds', saml_user) if not saml_password: saml_password = click.prompt('Please enter your SAML password', hide_input=True) credentials = {} worker_result = [] for saml_url in saml_batch: with ActionOnExit('Authenticating against {}..'.format(saml_url)): saml_xml, roles = authenticate(saml_url, saml_user, saml_password) keyring.set_password('sevenseconds', saml_user, saml_password) with multiprocessing.Pool(processes=os.cpu_count() * 4) as pool: worker_result = pool.starmap(assume_role_worker, zip(saml_batch[saml_url].values(), repeat(roles), repeat(saml_xml))) for worker_value in worker_result: if isinstance(worker_value, dict): credentials.update(worker_value) return credentials
def saml_login(user, url): ring_user = "******".format(user, url) saml_password = keyring.get_password("mai", ring_user) saml_xml = None while not saml_xml: if not saml_password: saml_password = click.prompt("Please enter your SAML password", hide_input=True) saml_otp = click.prompt("Please enter your One-Time-Password (eg. Google Authenticate or Yubikey)") with Action("Authenticating against {url}..", url=url) as act: try: saml_xml, roles = authenticate(url, user, saml_password, saml_otp) except aws_saml_login.saml.AuthenticationFailed: act.error("Authentication Failed") info("Please check your username/password/token and try again.") saml_password = None saml_otp = None keyring.set_password("mai", ring_user, saml_password) return saml_xml, roles