Exemple #1
0
    def _create_policy(self, policy_name):
        """create new IAM policy on AWS"""
        local_policy_document = os2.parse_json(self._policy_dir /
                                               f"{policy_name}.json")
        policy_description = self._iam_policy_setup[policy_name]

        self._iam_client.create_policy(
            PolicyName=policy_name,
            Path=self._path_prefix,
            PolicyDocument=json.dumps(local_policy_document),
            Description=policy_description)
def _validate_iam_policies(config_aws_setup):
    """validate aws_setup.json reflects contents of iam_policies dir"""
    policy_dir = consts.AWS_SETUP_DIR / "iam_policies"

    # Policies described in aws_setup/aws_setup.json
    setup_policy_list = [
        f"{policy}.json" for policy in config_aws_setup['IAM']['Policies']
    ]
    # Actual policy JSON files located in aws_setup/iam_policies/
    iam_policy_files = os2.dir_files(policy_dir, ext=".json")

    # Halt if any IAM policy file contains invalid JSON
    for iam_policy_file in iam_policy_files:
        os2.parse_json(policy_dir / iam_policy_file)

    # Halt if aws_setup.json describes policies not found in iam_policies
    if not set(setup_policy_list).issubset(set(iam_policy_files)):
        halt.err(
            "Following policy(s) not found from aws_setup/iam_policies/:", *[
                policy for policy in setup_policy_list
                if policy not in iam_policy_files
            ])
Exemple #3
0
    def _update_policy(self, policy_name, aws_policies):
        """update IAM policy that already exists on AWS"""
        local_policy_document = os2.parse_json(self._policy_dir /
                                               f"{policy_name}.json")

        aws_policy = next(aws_policy for aws_policy in aws_policies
                          if aws_policy['PolicyName'] == policy_name)

        # Delete beforehand to avoid error of 5 versions already existing
        self._delete_old_policy_versions(aws_policy['Arn'])
        self._iam_client.create_policy_version(
            PolicyArn=aws_policy['Arn'],
            PolicyDocument=json.dumps(local_policy_document),
            SetAsDefault=True)
Exemple #4
0
    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)
Exemple #5
0
    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)
Exemple #6
0
    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.")
Exemple #7
0
    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_vpc_security_groups(config_aws_setup):
    """validate aws_setup.json reflects contents of vpc_security_groups dir"""
    sg_dir = consts.AWS_SETUP_DIR / "vpc_security_groups"

    # SGs described in aws_setup/aws_setup.json
    setup_sg_list = [
        f"{sg_name}.json"
        for sg_name in config_aws_setup['VPC']['SecurityGroups']
    ]
    # Actual SG json files located in aws_setup/vpc_security_groups/
    vpc_sg_json_files = os2.dir_files(sg_dir, ext=".json")

    # Halt if aws_setup.json describes SGs not found in sg_dir
    if not set(setup_sg_list).issubset(set(vpc_sg_json_files)):
        halt.err(
            "Following SG(s) not found from aws_setup/vpc_security_groups/:",
            *[sg for sg in setup_sg_list if sg not in vpc_sg_json_files])

    # Halt if any security group missing Ingress key
    schema = os2.get_json_schema("vpc_security_groups")
    for sg_file in vpc_sg_json_files:
        sg_dict = os2.parse_json(sg_dir / sg_file)
        os2.validate_dict(sg_dict, schema, f"SG {sg_file}")
Exemple #10
0
 def _get_json_sg_ingress(sg_name):
     """retrieve local security group ingress rule(s) dict"""
     sg_dir = consts.AWS_SETUP_DIR / "vpc_security_groups"
     return os2.parse_json(sg_dir / f"{sg_name}.json")['Ingress']