def main(): """validates existence of config file, as well as each key's value""" consts.CONFIG_DIR.mkdir(exist_ok=True) config_dict = {} file_credentials = _credentials_from_file() if not consts.CONFIG_JSON.is_file() and file_credentials is None: halt.err(f"{consts.CONFIG_JSON.name} not found from config directory.", " An IAM user access key is needed to interact with AWS.", " Set access key with \"ec2mc configure access_key\".") elif consts.CONFIG_JSON.is_file(): config_dict = os2.parse_json(consts.CONFIG_JSON) # Validate config.json adheres to its schema. schema = os2.get_json_schema("config") os2.validate_dict(config_dict, schema, "config.json") if 'use_handler' not in config_dict: config_dict['use_handler'] = True consts.USE_HANDLER = config_dict['use_handler'] if 'access_key' not in config_dict: if file_credentials is None: halt.err("IAM user access key not set.", " Set with \"ec2mc configure access_key\".") config_dict['access_key'] = file_credentials os2.save_json(config_dict, consts.CONFIG_JSON) # Validate config's IAM user access key and save to consts. _validate_user(config_dict) print(f"Access key validated as IAM user \"{consts.IAM_NAME}\".") # Validate config's region whitelist and save to consts. _validate_region_whitelist(config_dict)
def _delete_user_access_keys(self, user_name): """delete IAM user's access key(s)""" aws_access_keys = self._iam_client.list_access_keys( UserName=user_name)['AccessKeyMetadata'] for access_key in aws_access_keys: self._iam_client.delete_access_key( UserName=user_name, AccessKeyId=access_key['AccessKeyId']) # Remove IAM user's backed up access key from config config_dict = os2.parse_json(consts.CONFIG_JSON) if 'backup_keys' in config_dict: config_dict['backup_keys'].pop(access_key['AccessKeyId'], None) if not config_dict['backup_keys']: del config_dict['backup_keys'] os2.save_json(config_dict, consts.CONFIG_JSON)
def _update_config_dict(new_key, old_key_ids): """remove old access keys and place new one in config""" config_dict = os2.parse_json(consts.CONFIG_JSON) if 'backup_keys' in config_dict: for old_key_id in old_key_ids: config_dict['backup_keys'].pop(old_key_id, None) if not config_dict['backup_keys']: del config_dict['backup_keys'] if next(iter(config_dict['access_key'])) in old_key_ids: config_dict['access_key'] = new_key else: config_dict.setdefault('backup_keys', {}).update(new_key) os2.save_json(config_dict, consts.CONFIG_JSON)
def main(self, cmd_args): """create a new IAM user under an IAM group""" iam_client = aws.iam_client() path_prefix = f"/{consts.NAMESPACE}/" aws.validate_group_exists(path_prefix, cmd_args.group) # IAM user created and added to group (given the name is unique) try: iam_client.create_user(Path=path_prefix, UserName=cmd_args.name) except ClientError as e: if e.response['Error']['Code'] == "EntityAlreadyExists": halt.err(f"IAM user \"{cmd_args.name}\" already exists.") halt.err(str(e)) iam_client.add_user_to_group(GroupName=cmd_args.group, UserName=cmd_args.name) print("") print(f"IAM user \"{cmd_args.name}\" created on AWS.") # IAM user access key generated and saved to dictionary new_key = iam_client.create_access_key( UserName=cmd_args.name)['AccessKey'] new_key = {new_key['AccessKeyId']: new_key['SecretAccessKey']} self._access_key_usable_waiter(new_key) config_dict = os2.parse_json(consts.CONFIG_JSON) if 'backup_keys' not in config_dict: config_dict['backup_keys'] = {} if cmd_args.default: # Modify existing config instead of creating new one config_dict['backup_keys'].update(config_dict['access_key']) config_dict['access_key'] = new_key os2.save_json(config_dict, consts.CONFIG_JSON) print(" User's access key set as default in config.") else: # Back up new IAM user's access key in config file config_dict['backup_keys'].update(new_key) os2.save_json(config_dict, consts.CONFIG_JSON) os2.create_configuration_zip(cmd_args.name, new_key, cmd_args.ssh_key) print(" User's zipped configuration created in config.")
def _switch_access_key(user_name): """set access key stored in backup access keys list as default""" config_dict = os2.parse_json(consts.CONFIG_JSON) if 'backup_keys' not in config_dict: halt.err("No backup access keys stored in config.") for key_id, key_secret in config_dict['backup_keys'].items(): # TODO: Validate access key is active key_owner = aws.access_key_owner(key_id) if key_owner is None: continue if key_owner.lower() == user_name.lower(): # Swap default access key with requested IAM user's in config config_dict['backup_keys'].update(config_dict['access_key']) config_dict['access_key'] = {key_id: key_secret} del config_dict['backup_keys'][key_id] os2.save_json(config_dict, consts.CONFIG_JSON) return key_owner halt.err(f"Backup access key for IAM user \"{user_name}\" not found.")
def main(self, cmd_args): """configure, for example, the default IAM user access key""" # validate_config:main normally does this, but it wasn't called. consts.CONFIG_DIR.mkdir(exist_ok=True) config_dict = {} if consts.CONFIG_JSON.is_file(): schema = os2.get_json_schema("config") config_dict = os2.parse_json(consts.CONFIG_JSON) os2.validate_dict(config_dict, schema, "config.json") if cmd_args.subcommand == "access_key": config_dict = self._set_access_key( config_dict, cmd_args.key_id, cmd_args.key_secret) elif cmd_args.subcommand == "whitelist": self._set_region_whitelist(config_dict, cmd_args.regions) elif cmd_args.subcommand == "use_handler": config_dict['use_handler'] = cmd_args.boolean print(f"IP handler usage set to {str(cmd_args.boolean)}.") os2.save_json(config_dict, consts.CONFIG_JSON)
def _validate_region_whitelist(config_dict): """validate config's region whitelist and save to consts.REGIONS tuple Requires ec2:DescribeRegions permission. """ response = aws.ec2_client_no_validate("us-east-1").describe_regions() region_names = [region['RegionName'] for region in response['Regions']] if 'region_whitelist' in config_dict: whitelist = tuple(config_dict['region_whitelist']) if not set(whitelist).issubset(set(region_names)): halt.err("Following invalid region(s) in config whitelist:", *(set(whitelist) - set(region_names))) consts.REGIONS = sorted(whitelist) else: print("Searching for closest AWS EC2 region...") closest_region = find_closest_region.main(region_names) print(f" Region with lowest average latency is {closest_region}.") config_dict['region_whitelist'] = [closest_region] os2.save_json(config_dict, consts.CONFIG_JSON) print(f" {closest_region} configured as your region whitelist.") consts.REGIONS = (closest_region, )