Ejemplo n.º 1
0
def load_arguments(self, _):
    def base64(value):
        value = bytes(value, 'utf-8')

        # Pad the invalid base64 strings because Azure is stupid
        while len(value) % 4 != 0:
            value += "="

        return urlsafe_b64decode(value)

    vault_name_type = CLIArgumentType(
        help='Name of the key vault.',
        options_list=['--vault-name'],
        metavar='NAME',
        id_part=None,
        completer=get_resource_name_completion_list(
            'Microsoft.KeyVault/vaults'))

    for scope in ['wrap', 'unwrap']:
        with self.argument_context('keyvault key {}'.format(scope)) as c:
            c.argument('vault_base_url',
                       vault_name_type,
                       type=get_vault_base_url_type(self.cli_ctx),
                       id_part=None)

            c.argument('key_name',
                       options_list=['--name', '-n'],
                       help='Name of the key.',
                       id_part='child_name_1',
                       required=True,
                       completer=get_keyvault_name_completion_list('key'))
            c.argument(
                'key_version',
                options_list=['--version'],
                help='The key version. If omitted, uses the latest version.',
                default='',
                required=False,
                completer=get_keyvault_version_completion_list('key'))

            c.argument('value',
                       options_list=['--value', '-v'],
                       help='Wrapped secret value.',
                       type=base64,
                       required=True)
            c.argument('algorithm',
                       options_list=['--alg', '-a'],
                       help='The algorithm for wrapping.',
                       required=True)
Ejemplo n.º 2
0
def load_arguments(self, _):
    (JsonWebKeyOperation, KeyAttributes, JsonWebKeyType, JsonWebKeyCurveName, SasTokenType,
     SasDefinitionAttributes, SecretAttributes, CertificateAttributes, StorageAccountAttributes,
     JsonWebKeyEncryptionAlgorithm) = self.get_models(
         'JsonWebKeyOperation', 'KeyAttributes', 'JsonWebKeyType', 'JsonWebKeyCurveName', 'SasTokenType',
         'SasDefinitionAttributes', 'SecretAttributes', 'CertificateAttributes', 'StorageAccountAttributes',
         'JsonWebKeyEncryptionAlgorithm',
         resource_type=ResourceType.DATA_KEYVAULT)

    class CLIJsonWebKeyOperation(str, Enum):
        encrypt = "encrypt"
        decrypt = "decrypt"
        sign = "sign"
        verify = "verify"
        wrap_key = "wrapKey"
        unwrap_key = "unwrapKey"
        import_ = "import"
        export = "export"

    JsonWebKeyOperation = CLIJsonWebKeyOperation  # TODO: Remove this patch when new SDK is released

    class CLIJsonWebKeyType(str, Enum):
        ec = "EC"  #: Elliptic Curve.
        ec_hsm = "EC-HSM"  #: Elliptic Curve with a private key which is not exportable from the HSM.
        rsa = "RSA"  #: RSA (https://tools.ietf.org/html/rfc3447)
        rsa_hsm = "RSA-HSM"  #: RSA with a private key which is not exportable from the HSM.
        oct = "oct"  #: Octet sequence (used to represent symmetric keys)
        oct_hsm = "oct-HSM"  #: Oct with a private key which is not exportable from the HSM.

    JsonWebKeyType = CLIJsonWebKeyType  # TODO: Remove this patch when new SDK is released

    class CLIKeyTypeForBYOKImport(str, Enum):
        ec = "EC"  #: Elliptic Curve.
        rsa = "RSA"  #: RSA (https://tools.ietf.org/html/rfc3447)

    class CLIJsonWebKeyCurveName(str, Enum):
        p_256 = "P-256"  #: The NIST P-256 elliptic curve, AKA SECG curve SECP256R1.
        p_256k = "P-256K"  #: The SECG SECP256K1 elliptic curve.
        p_384 = "P-384"  #: The NIST P-384 elliptic curve, AKA SECG curve SECP384R1.
        p_521 = "P-521"  #: The NIST P-521 elliptic curve, AKA SECG curve SECP521R1.

    class CLISecurityDomainOperation(str, Enum):
        download = "download"  #: Download operation
        upload = "upload"  #: Upload operation

    (KeyPermissions, SecretPermissions, CertificatePermissions, StoragePermissions,
     NetworkRuleBypassOptions, NetworkRuleAction) = self.get_models(
         'KeyPermissions', 'SecretPermissions', 'CertificatePermissions', 'StoragePermissions',
         'NetworkRuleBypassOptions', 'NetworkRuleAction', resource_type=ResourceType.MGMT_KEYVAULT)

    # ARGUMENT DEFINITIONS
    vault_name_type = CLIArgumentType(
        help='Name of the Vault.', options_list=['--vault-name'], metavar='NAME', id_part=None,
        completer=get_resource_name_completion_list('Microsoft.KeyVault/vaults'))

    deleted_vault_name_type = CLIArgumentType(
        help='Name of the deleted Vault.', options_list=['--vault-name'], metavar='NAME', id_part=None)

    hsm_name_type = CLIArgumentType(help='Name of the HSM.',
                                    options_list=['--hsm-name'], id_part=None)
    hsm_url_type = CLIArgumentType(help='Name of the HSM.', type=get_hsm_base_url_type(self.cli_ctx),
                                   options_list=['--hsm-name'], id_part=None)

    mgmt_plane_hsm_name_type = CLIArgumentType(help='Name of the HSM. (--hsm-name and --name/-n are mutually '
                                                    'exclusive, please specify just one of them)',
                                               options_list=['--hsm-name'], id_part=None,
                                               validator=validate_vault_name_and_hsm_name)

    data_plane_hsm_name_type = CLIArgumentType(help='Name of the HSM. (--hsm-name and --vault-name are '
                                                    'mutually exclusive, please specify just one of them)',
                                               type=get_hsm_base_url_type(self.cli_ctx),
                                               options_list=['--hsm-name'], id_part=None,
                                               validator=set_vault_base_url)

    deleted_hsm_name_type = CLIArgumentType(help='Name of the deleted HSM. (--hsm-name and --name/-n are '
                                                 'mutually exclusive, please specify just one of them)',
                                            options_list=['--hsm-name'], id_part=None,
                                            validator=validate_vault_name_and_hsm_name)

    # region vault (management)
    with self.argument_context('keyvault') as c:
        c.argument('resource_group_name', resource_group_name_type, id_part=None, required=False,
                   help='Proceed only if Key Vault belongs to the specified resource group.',
                   validator=validate_resource_group_name)
        c.argument('vault_name', vault_name_type, options_list=['--name', '-n'])
        c.argument('object_id', help='a GUID that identifies the principal that will receive permissions')
        c.argument('spn', help='name of a service principal that will receive permissions')
        c.argument('upn', help='name of a user principal that will receive permissions')
        c.argument('tags', tags_type)
        c.argument('enabled_for_deployment', arg_type=get_three_state_flag(),
                   help='[Vault Only] Property to specify whether Azure Virtual Machines are permitted to retrieve '
                        'certificates stored as secrets from the key vault.')
        c.argument('enabled_for_disk_encryption', arg_type=get_three_state_flag(),
                   help='[Vault Only] Property to specify whether Azure Disk Encryption is permitted to retrieve '
                        'secrets from the vault and unwrap keys.')
        c.argument('enabled_for_template_deployment', arg_type=get_three_state_flag(),
                   help='[Vault Only] Property to specify whether Azure Resource Manager is permitted to retrieve '
                        'secrets from the key vault.')
        c.argument('enable_rbac_authorization', arg_type=get_three_state_flag())
        c.argument('enable_soft_delete', arg_type=get_three_state_flag(), deprecate_info=c.deprecate(
            message_func=lambda x: 'Warning! The ability to create new key vaults with soft delete disabled will be '
                                   'deprecated by December 2020. All key vaults will be required to have soft delete '
                                   'enabled. Please see the following documentation for additional guidance.\n'
                                   'https://docs.microsoft.com/azure/key-vault/general/soft-delete-change'),
                   help='[Vault Only] Property to specify whether the \'soft delete\' functionality is enabled for '
                        'this key vault. If it\'s not set to any value (true or false) when creating new key vault, it '
                        'will be set to true by default. Once set to true, it cannot be reverted to false.')
        c.argument('enable_purge_protection', arg_type=get_three_state_flag())

    with self.argument_context('keyvault', arg_group='Network Rule', min_api='2018-02-14') as c:
        c.argument('bypass', arg_type=get_enum_type(NetworkRuleBypassOptions),
                   help='Bypass traffic for space-separated uses.')
        c.argument('default_action', arg_type=get_enum_type(NetworkRuleAction),
                   help='Default action to apply when no rule matches.')

    for item in ['show', 'delete', 'create']:
        with self.argument_context('keyvault {}'.format(item)) as c:
            c.argument('hsm_name', mgmt_plane_hsm_name_type)

    with self.argument_context('keyvault create') as c:
        c.argument('resource_group_name', resource_group_name_type, required=True, completer=None, validator=None)
        c.argument('vault_name', vault_name_type, options_list=['--name', '-n'])
        c.argument('administrators', nargs='+',
                   help='[HSM Only] Administrator role for data plane operations for Managed HSM. '
                        'It accepts a space separated list of OIDs that will be assigned.')
        c.argument('sku', help='Required. SKU details. Allowed values for Vault: premium, standard. Default: standard.'
                               ' Allowed values for HSM: Standard_B1, Custom_B32. Default: Standard_B1')
        c.argument('no_self_perms', arg_type=get_three_state_flag(),
                   help='[Vault Only] Don\'t add permissions for the current user/service principal in the new vault.')
        c.argument('location', validator=get_default_location_from_resource_group)
        c.argument('retention_days', help='Soft delete data retention days. It accepts >=7 and <=90.', default='90')

    with self.argument_context('keyvault create', arg_group='Network Rule') as c:
        c.argument('network_acls', type=validate_file_or_dict,
                   help='Network ACLs. It accepts a JSON filename or a JSON string. JSON format: '
                        '`{\\"ip\\":[<ip1>, <ip2>...],\\"vnet\\":[<vnet_name_1>/<subnet_name_1>,<subnet_id2>...]}`')
        c.argument('network_acls_ips', nargs='*', help='Network ACLs IP rules. Space-separated list of IP addresses.')
        c.argument('network_acls_vnets', nargs='*', help='Network ACLS VNet rules. Space-separated list of '
                                                         'Vnet/subnet pairs or subnet resource ids.')

    with self.argument_context('keyvault update') as c:
        c.argument('vault_name', vault_name_type, options_list=['--name', '-n'])
        c.argument('retention_days', help='Soft delete data retention days. It accepts >=7 and <=90.')

    with self.argument_context('keyvault update-hsm') as c:
        c.argument('name', hsm_name_type)
        c.argument('enable_purge_protection', options_list=['--enable-purge-protection', '-e'])
        c.argument('secondary_locations', nargs='+',
                   help='--secondary-locations extends/contracts an HSM pool to listed regions. The primary location '
                        'where the resource was originally created CANNOT be removed.')

    with self.argument_context('keyvault wait-hsm') as c:
        c.argument('hsm_name', hsm_name_type)
        c.argument('resource_group_name', options_list=['--resource-group', '-g'],
                   help='Proceed only if HSM belongs to the specified resource group.')

    with self.argument_context('keyvault recover') as c:
        c.argument('vault_name', deleted_vault_name_type, options_list=['--name', '-n'],
                   validator=validate_deleted_vault_or_hsm_name)
        c.argument('hsm_name', deleted_hsm_name_type)
        c.argument('resource_group_name', resource_group_name_type, id_part=None, required=False,
                   help='Resource group of the deleted Vault or HSM')
        c.argument('location', help='Location of the deleted Vault or HSM', required=False)

    with self.argument_context('keyvault purge') as c:
        c.argument('vault_name', deleted_vault_name_type, options_list=['--name', '-n'],
                   validator=validate_deleted_vault_or_hsm_name)
        c.argument('hsm_name', deleted_hsm_name_type)
        c.argument('location', help='Location of the deleted Vault or HSM', required=False)

    with self.argument_context('keyvault list') as c:
        c.argument('resource_group_name', resource_group_name_type, validator=None)
        c.argument('resource_type', help='When --resource-type is not present the command will list all Vaults and HSMs.'
                                         ' Possible values for --resource-type are vault and hsm.')

    with self.argument_context('keyvault list-deleted') as c:
        c.argument('resource_type', help='When --resource-type is not present the command will list all deleted Vaults '
                                         'and HSMs. Possible values for --resource-type are vault and hsm.')

    with self.argument_context('keyvault show-deleted') as c:
        c.argument('vault_name', deleted_vault_name_type, options_list=['--name', '-n'],
                   validator=validate_deleted_vault_or_hsm_name)
        c.argument('hsm_name', deleted_hsm_name_type)
        c.argument('location', help='Location of the deleted Vault or HSM', required=False)

    with self.argument_context('keyvault delete-policy') as c:
        c.argument('object_id', validator=validate_principal)

    with self.argument_context('keyvault set-policy', arg_group='Permission') as c:
        c.argument('object_id', validator=validate_principal)
        c.argument('key_permissions', arg_type=get_enum_type(KeyPermissions), metavar='PERM', nargs='*',
                   help='Space-separated list of key permissions to assign.', validator=validate_policy_permissions)
        c.argument('secret_permissions', arg_type=get_enum_type(SecretPermissions), metavar='PERM', nargs='*',
                   help='Space-separated list of secret permissions to assign.')
        c.argument('certificate_permissions', arg_type=get_enum_type(CertificatePermissions), metavar='PERM', nargs='*',
                   help='Space-separated list of certificate permissions to assign.')
        c.argument('storage_permissions', arg_type=get_enum_type(StoragePermissions), metavar='PERM', nargs='*',
                   help='Space-separated list of storage permissions to assign.')

    with self.argument_context('keyvault network-rule', min_api='2018-02-14') as c:
        c.argument('ip_address', help='IPv4 address or CIDR range.')
        c.argument('subnet', help='Name or ID of subnet. If name is supplied, `--vnet-name` must be supplied.')
        c.argument('vnet_name', help='Name of a virtual network.', validator=validate_subnet)

    for item in ['approve', 'reject', 'delete', 'show', 'wait']:
        with self.argument_context('keyvault private-endpoint-connection {}'.format(item), min_api='2018-02-14') as c:
            c.extra('connection_id', options_list=['--id'], required=False,
                    help='The ID of the private endpoint connection associated with the Key Vault. '
                         'If specified --vault-name and --name/-n, this should be omitted.')
            c.argument('description', help='Comments for the {} operation.'.format(item))
            c.argument('private_endpoint_connection_name', options_list=['--name', '-n'], required=False,
                       help='The name of the private endpoint connection associated with the Key Vault. '
                            'Required if --id is not specified')
            c.argument('vault_name', vault_name_type, required=False,
                       help='Name of the Key Vault. Required if --id is not specified')

    with self.argument_context('keyvault private-link-resource', min_api='2018-02-14') as c:
        c.argument('vault_name', vault_name_type)
    # endregion

    # region Shared
    for item in ['key', 'secret', 'certificate']:
        with self.argument_context('keyvault ' + item, arg_group='Id') as c:
            c.argument(item + '_name', options_list=['--name', '-n'], help='Name of the {}.'.format(item),
                       id_part='child_name_1', completer=get_keyvault_name_completion_list(item))
            c.argument('vault_base_url', vault_name_type, type=get_vault_base_url_type(self.cli_ctx), id_part=None)
            c.argument(item + '_version', options_list=['--version', '-v'],
                       help='The {} version. If omitted, uses the latest version.'.format(item), default='',
                       required=False, completer=get_keyvault_version_completion_list(item))

        for cmd in ['backup', 'decrypt', 'delete', 'download', 'encrypt', 'list-versions', 'set-attributes', 'show',
                    'list']:
            with self.argument_context('keyvault {} {}'.format(item, cmd), arg_group='Id') as c:
                try:
                    if cmd in ['list']:
                        c.extra('identifier', options_list=['--id'],
                                help='Id of the Vault or HSM. '
                                     'If specified all other \'Id\' arguments should be omitted.',
                                validator=validate_vault_or_hsm)
                    else:
                        c.extra('identifier', options_list=['--id'],
                                help='Id of the {}. '
                                     'If specified all other \'Id\' arguments should be omitted.'.format(item),
                                validator=validate_key_id(item))
                except ValueError:
                    pass
                c.argument(item + '_name', help='Name of the {}. Required if --id is not specified.'.format(item),
                           required=False)
                c.argument('vault_base_url', vault_name_type, required=False,
                           help='Name of the Key Vault. Required if --id is not specified.')
                c.argument(item + '_version', required=False)

        for cmd in ['purge', 'recover', 'show-deleted']:
            with self.argument_context('keyvault {} {}'.format(item, cmd), arg_group='Id') as c:
                c.extra('identifier', options_list=['--id'],
                        help='The recovery id of the {}. '
                             'If specified all other \'Id\' arguments should be omitted.'.format(item),
                        validator=validate_key_id('deleted' + item))
                c.argument(item + '_name', help='Name of the {}. Required if --id is not specified.'.format(item),
                           required=False)
                c.argument('vault_base_url', help='Name of the Vault. Required if --id is not specified.',
                           required=False)
                c.argument(item + '_version', required=False)

        for cmd in ['list', 'list-deleted']:
            with self.argument_context('keyvault {} {}'.format(item, cmd)) as c:
                c.argument('include_pending', arg_type=get_three_state_flag())

            with self.argument_context('keyvault {} {}'.format(item, cmd), arg_group='Id') as c:
                if cmd in ['list-deleted']:
                    c.extra('identifier', options_list=['--id'],
                            help='Id of the Vault{}. '
                                 'If specified all other \'Id\' arguments should be '
                                 'omitted.'.format(' or HSM' if item == 'key' else ''),
                            validator=validate_vault_or_hsm)
    # endregion

    # region keys
    with self.argument_context('keyvault key') as c:
        c.argument('key_ops', arg_type=get_enum_type(JsonWebKeyOperation), options_list=['--ops'], nargs='*',
                   help='Space-separated list of permitted JSON web key operations.')

    # custom functions
    for item in ['backup', 'create', 'download', 'import', 'restore']:
        with self.argument_context('keyvault key {}'.format(item), arg_group='Id') as c:
            if item in ['create', 'backup', 'download', 'import']:
                c.argument('identifier', options_list=['--id'],
                           help='Id of the Vault or HSM. '
                                'If specified all other \'Id\' arguments should be omitted.',
                           validator=validate_key_id('key'))
                c.argument('hsm_name', data_plane_hsm_name_type)
            else:
                c.argument('identifier', options_list=['--id'],
                           help='Id of the Vault or HSM. '
                                'If specified all other \'Id\' arguments should be omitted.',
                           validator=validate_vault_or_hsm)
                c.argument('hsm_name', data_plane_hsm_name_type, validator=None)

    # SDK functions
    for item in ['delete', 'list', 'list-deleted', 'list-versions', 'purge', 'recover',
                 'set-attributes', 'show', 'show-deleted', 'encrypt', 'decrypt']:
        with self.argument_context('keyvault key {}'.format(item), arg_group='Id') as c:
            c.ignore('cls')
            if item in ['list', 'list-deleted']:
                c.argument('vault_base_url', vault_name_type, required=False)
            c.extra('hsm_name', data_plane_hsm_name_type)

    for item in ['create', 'import', 'set-attributes']:
        with self.argument_context('keyvault key {}'.format(item)) as c:
            if item != 'set-attributes':
                c.argument('protection', arg_type=get_enum_type(['software', 'hsm']), options_list=['--protection', '-p'],
                           help='Specifies the type of key protection.')
                c.argument('disabled', arg_type=get_three_state_flag(), help='Create key in disabled state.')
                c.argument('key_size', options_list=['--size'], type=int,
                           help='The key size in bits. For example: 2048, 3072, or 4096 for RSA. 128, 192, or 256 for oct.')
                c.argument('expires', default=None, help='Expiration UTC datetime  (Y-m-d\'T\'H:M:S\'Z\').',
                           type=datetime_type)
                c.argument('not_before', default=None, type=datetime_type,
                           help='Key not usable before the provided UTC datetime  (Y-m-d\'T\'H:M:S\'Z\').')

    with self.argument_context('keyvault key create') as c:
        c.argument('kty', arg_type=get_enum_type(JsonWebKeyType), validator=validate_key_type,
                   help='The type of key to create. For valid values, see: https://docs.microsoft.com/en-us/rest/api/keyvault/createkey/createkey#jsonwebkeytype')
        c.argument('curve', arg_type=get_enum_type(JsonWebKeyCurveName),
                   help='Elliptic curve name. For valid values, see: https://docs.microsoft.com/en-us/rest/api/keyvault/createkey/createkey#jsonwebkeycurvename')

    with self.argument_context('keyvault key import') as c:
        c.argument('kty', arg_type=get_enum_type(CLIKeyTypeForBYOKImport), validator=validate_key_import_type,
                   help='The type of key to import (only for BYOK).')
        c.argument('curve', arg_type=get_enum_type(CLIJsonWebKeyCurveName), validator=validate_key_import_type,
                   help='The curve name of the key to import (only for BYOK).')

    with self.argument_context('keyvault key import', arg_group='Key Source') as c:
        c.argument('pem_file', type=file_type, help='PEM file containing the key to be imported.', completer=FilesCompleter(), validator=validate_key_import_source)
        c.argument('pem_string', type=file_type, help='PEM string containing the key to be imported.', validator=validate_key_import_source)
        c.argument('pem_password', help='Password of PEM file.')
        c.argument('byok_file', type=file_type, help='BYOK file containing the key to be imported. Must not be password protected.', completer=FilesCompleter(), validator=validate_key_import_source)
        c.argument('byok_string', type=file_type, help='BYOK string containing the key to be imported. Must not be password protected.', validator=validate_key_import_source)

    with self.argument_context('keyvault key backup') as c:
        c.argument('file_path', options_list=['--file', '-f'], type=file_type, completer=FilesCompleter(),
                   help='Local file path in which to store key backup.')

    with self.argument_context('keyvault key download') as c:
        c.argument('file_path', options_list=['--file', '-f'], type=file_type, completer=FilesCompleter(),
                   help='File to receive the key contents.')
        c.argument('encoding', arg_type=get_enum_type(key_format_values), options_list=['--encoding', '-e'],
                   help='Encoding of the key, default: PEM', default='PEM')

    with self.argument_context('keyvault key restore') as c:
        c.argument('file_path', options_list=['--file', '-f'], type=file_type, completer=FilesCompleter(),
                   help='Local key backup from which to restore key.')

    with self.argument_context('keyvault key restore', arg_group='Storage Id') as c:
        c.argument('storage_resource_uri', options_list=['--storage-resource-uri', '-u'],
                   help='Azure Blob storage container Uri. If specified, all '
                        'other \'Storage Id\' arguments should be omitted')
        c.argument('storage_account_name', help='Name of Azure Storage Account.')
        c.argument('blob_container_name', help='Name of Blob Container.')

    with self.argument_context('keyvault key restore', arg_group='Restoring keys from storage account') as c:
        c.argument('token', options_list=['--storage-container-SAS-token', '-t'],
                   help='The SAS token pointing to an Azure Blob storage container')
        c.argument('backup_folder', help='Name of the blob container which contains the backup')
        c.argument('key_name', options_list=['--name', '-n'],
                   help='Name of the key. (Only for restoring from storage account)')

    with self.argument_context('keyvault key set-attributes') as c:
        c.attributes_argument('key', KeyAttributes)

    for scope in ['encrypt', 'decrypt']:
        with self.argument_context('keyvault key {}'.format(scope)) as c:
            c.argument('algorithm', options_list=['--algorithm', '-a'], arg_type=get_enum_type(JsonWebKeyEncryptionAlgorithm))

    with self.argument_context('keyvault key encrypt') as c:
        c.argument('value', help='The value to be encrypted. Default data type is Base64 encoded string.',
                   validator=validate_encryption)
        c.extra('data_type', help='The type of the original data.', arg_type=get_enum_type(KeyEncryptionDataType),
                default='base64')

    with self.argument_context('keyvault key decrypt') as c:
        c.argument('value', help='The value to be decrypted, which should be the result of "az keyvault encrypt"',
                   validator=validate_decryption)
        c.extra('data_type', help='The type of the original data.', arg_type=get_enum_type(KeyEncryptionDataType),
                default='base64')

    for scope in ['list', 'list-deleted', 'list-versions']:
        with self.argument_context('keyvault key {}'.format(scope)) as c:
            c.argument('maxresults', options_list=['--maxresults'], type=int)

    with self.argument_context('keyvault key list') as c:
        c.extra('include_managed', arg_type=get_three_state_flag(), default=False,
                help='Include managed keys. Default: false')
    # endregion

    # region KeyVault Secret
    with self.argument_context('keyvault secret set') as c:
        c.argument('content_type', options_list=['--description'],
                   help='Description of the secret contents (e.g. password, connection string, etc)')
        c.attributes_argument('secret', SecretAttributes, create=True)

    with self.argument_context('keyvault secret set', arg_group='Content Source') as c:
        c.argument('value', options_list=['--value'],
                   help="Plain text secret value. Cannot be used with '--file' or '--encoding'", required=False)
        c.extra('file_path', options_list=['--file', '-f'], type=file_type,
                help="Source file for secret. Use in conjunction with '--encoding'", completer=FilesCompleter())
        c.extra('encoding', arg_type=get_enum_type(secret_encoding_values, default='utf-8'),
                options_list=['--encoding', '-e'],
                help='Source file encoding. The value is saved as a tag (`file-encoding=<val>`) '
                     'and used during download to automatically encode the resulting file.')

    with self.argument_context('keyvault secret set-attributes') as c:
        c.attributes_argument('secret', SecretAttributes)

    with self.argument_context('keyvault secret download') as c:
        c.argument('file_path', options_list=['--file', '-f'], type=file_type, completer=FilesCompleter(),
                   help='File to receive the secret contents.')
        c.argument('encoding', arg_type=get_enum_type(secret_encoding_values), options_list=['--encoding', '-e'],
                   help="Encoding of the secret. By default, will look for the 'file-encoding' tag on the secret. "
                        "Otherwise will assume 'utf-8'.", default=None)

    for scope in ['backup', 'restore']:
        with self.argument_context('keyvault secret {}'.format(scope)) as c:
            c.argument('file_path', options_list=['--file', '-f'], type=file_type, completer=FilesCompleter(),
                       help='File to receive the secret contents.')

    for scope in ['list', 'list-deleted', 'list-versions']:
        with self.argument_context('keyvault secret {}'.format(scope)) as c:
            c.argument('maxresults', options_list=['--maxresults'], type=int)

    with self.argument_context('keyvault secret list') as c:
        c.extra('include_managed', arg_type=get_three_state_flag(), default=False,
                help='Include managed secrets. Default: false')
    # endregion

    # region keyvault security-domain
    for scope in ['init-recovery', 'download', 'upload']:
        with self.argument_context('keyvault security-domain {}'.format(scope), arg_group='HSM Id') as c:
            c.argument('hsm_name', hsm_url_type, required=False,
                       help='Name of the HSM. Can be omitted if --id is specified.')
            c.extra('identifier', options_list=['--id'], validator=validate_vault_or_hsm, help='Id of the HSM.')
            c.ignore('vault_base_url')

    with self.argument_context('keyvault security-domain init-recovery') as c:
        c.argument('sd_exchange_key', help='Local file path to store the exported key.')

    with self.argument_context('keyvault security-domain upload') as c:
        c.argument('sd_file', help='This file contains security domain encrypted using SD Exchange file downloaded '
                                   'in security-domain init-recovery command.')
        c.argument('sd_exchange_key', help='The exchange key for security domain.')
        c.argument('sd_wrapping_keys', nargs='*',
                   help='Space-separated file paths to PEM files containing private keys.')
        c.argument('passwords', nargs='*', help='Space-separated password list for --sd-wrapping-keys. '
                                                'CLI will match them in order. Can be omitted if your keys are without '
                                                'password protection.')

    with self.argument_context('keyvault security-domain download') as c:
        c.argument('sd_wrapping_keys', nargs='*',
                   help='Space-separated file paths to PEM files containing public keys.')
        c.argument('security_domain_file',
                   help='Path to a file where the JSON blob returned by this command is stored.')
        c.argument('sd_quorum', type=int, help='The minimum number of shares required to decrypt the security domain '
                                               'for recovery.')

    with self.argument_context('keyvault security-domain wait') as c:
        c.argument('hsm_name', hsm_url_type, help='Name of the HSM. Can be omitted if --id is specified.',
                   required=False)
        c.argument('identifier', options_list=['--id'], validator=validate_vault_or_hsm, help='Id of the HSM.')
        c.argument('resource_group_name', options_list=['--resource-group', '-g'],
                   help='Proceed only if HSM belongs to the specified resource group.')
        c.argument('target_operation', arg_type=get_enum_type(CLISecurityDomainOperation),
                   help='Target operation that needs waiting.')
        c.ignore('vault_base_url')
    # endregion

    # region keyvault backup/restore
    for item in ['backup', 'restore']:
        for scope in ['start']:  # TODO add 'status' when SDK is ready
            with self.argument_context('keyvault {} {}'.format(item, scope), arg_group='HSM Id') as c:
                c.argument('hsm_name', hsm_url_type, required=False,
                           help='Name of the HSM. Can be omitted if --id is specified.')
                c.extra('identifier', options_list=['--id'], validator=validate_vault_or_hsm, help='Id of the HSM.')
                c.ignore('cls')

    with self.argument_context('keyvault backup start', arg_group='Storage Id') as c:
        c.argument('storage_resource_uri', required=False,
                   help='Azure Blob storage container Uri. If specified all other \'Storage Id\' arguments '
                        'should be omitted')
        c.extra('storage_account_name', help='Name of Azure Storage Account.')
        c.extra('blob_container_name', help='Name of Blob Container.')

    for command_group in ['backup', 'restore']:
        with self.argument_context('keyvault {} start'.format(command_group)) as c:
            c.argument('token', options_list=['--storage-container-SAS-token', '-t'], required=True,
                       help='The SAS token pointing to an Azure Blob storage container')

    with self.argument_context('keyvault restore start') as c:
        c.argument('folder_to_restore', options_list=['--backup-folder'],
                   help='Name of the blob container which contains the backup')

    with self.argument_context('keyvault restore start', arg_group='Storage Id') as c:
        c.extra('storage_resource_uri', required=False,
                help='Azure Blob storage container Uri. If specified all other \'Storage Id\' '
                     'arguments should be omitted')
        c.extra('storage_account_name', help='Name of Azure Storage Account.')
        c.extra('blob_container_name', help='Name of Blob Container.')

    # endregion

    # region KeyVault Storage Account
    with self.argument_context('keyvault storage', arg_group='Id') as c:
        c.argument('storage_account_name', options_list=['--name', '-n'],
                   help='Name to identify the storage account in the vault.', id_part='child_name_1',
                   completer=get_keyvault_name_completion_list('storage_account'))
        c.argument('vault_base_url', vault_name_type, type=get_vault_base_url_type(self.cli_ctx), id_part=None)

    for scope in ['keyvault storage add', 'keyvault storage update']:
        with self.argument_context(scope) as c:
            c.extra('disabled', arg_type=get_three_state_flag(), help='Add the storage account in a disabled state.',
                    validator=validate_storage_disabled_attribute(
                        'storage_account_attributes', StorageAccountAttributes))
            c.ignore('storage_account_attributes')
            c.argument('auto_regenerate_key', arg_type=get_three_state_flag(), required=False)
            c.argument('regeneration_period', help='The key regeneration time duration specified in ISO-8601 format, '
                                                   'such as "P30D" for rotation every 30 days.')
    for scope in ['backup', 'show', 'update', 'remove', 'regenerate-key']:
        with self.argument_context('keyvault storage ' + scope, arg_group='Id') as c:
            c.extra('identifier', options_list=['--id'],
                    help='Id of the storage account.  If specified all other \'Id\' arguments should be omitted.',
                    validator=validate_storage_account_id)
            c.argument('storage_account_name', required=False,
                       help='Name to identify the storage account in the vault. Required if --id is not specified.')
            c.argument('vault_base_url', help='Name of the Key Vault. Required if --id is not specified.',
                       required=False)

    with self.argument_context('keyvault storage backup') as c:
        c.argument('file_path', options_list=['--file', '-f'], type=file_type, completer=FilesCompleter(),
                   help='Local file path in which to store storage account backup.')

    with self.argument_context('keyvault storage restore') as c:
        c.argument('file_path', options_list=['--file', '-f'], type=file_type, completer=FilesCompleter(),
                   help='Local key backup from which to restore storage account.')

    with self.argument_context('keyvault storage sas-definition', arg_group='Id') as c:
        c.argument('storage_account_name', options_list=['--account-name'],
                   help='Name to identify the storage account in the vault.', id_part='child_name_1',
                   completer=get_keyvault_name_completion_list('storage_account'))
        c.argument('sas_definition_name', options_list=['--name', '-n'],
                   help='Name to identify the SAS definition in the vault.', id_part='child_name_2')

    for scope in ['keyvault storage sas-definition create', 'keyvault storage sas-definition update']:
        with self.argument_context(scope) as c:
            c.extra('disabled', arg_type=get_three_state_flag(), help='Add the storage account in a disabled state.',
                    validator=validate_storage_disabled_attribute('sas_definition_attributes', SasDefinitionAttributes))
            c.ignore('sas_definition_attributes')
            c.argument('sas_type', arg_type=get_enum_type(SasTokenType))
            c.argument('template_uri',
                       help='The SAS definition token template signed with the key 00000000. '
                            'In the case of an account token this is only the sas token itself, for service tokens, '
                            'the full service endpoint url along with the sas token.  Tokens created according to the '
                            'SAS definition will have the same properties as the template.')
            c.argument('validity_period',
                       help='The validity period of SAS tokens created according to the SAS definition in ISO-8601, '
                            'such as "PT12H" for 12 hour tokens.')
            c.argument('auto_regenerate_key', arg_type=get_three_state_flag())

    for scope in ['keyvault storage sas-definition delete', 'keyvault storage sas-definition show',
                  'keyvault storage sas-definition update']:
        with self.argument_context(scope, arg_group='Id') as c:
            c.extra('identifier', options_list=['--id'],
                    help='Id of the SAS definition. If specified all other \'Id\' arguments should be omitted.',
                    validator=validate_sas_definition_id)
            c.argument('storage_account_name', required=False,
                       help='Name to identify the storage account in the vault. Required if --id is not specified.')
            c.argument('sas_definition_name', required=False,
                       help='Name to identify the SAS definition in the vault. Required if --id is not specified.')
            c.argument('vault_base_url', help='Name of the Key Vault. Required if --id is not specified.',
                       required=False)
    # endregion

    # KeyVault Certificate
    with self.argument_context('keyvault certificate') as c:
        c.argument('validity', type=int,
                   help='Number of months the certificate is valid for. Overrides the value specified with --policy/-p')

    # TODO: Remove workaround when https://github.com/Azure/azure-rest-api-specs/issues/1153 is fixed
    with self.argument_context('keyvault certificate create') as c:
        c.attributes_argument('certificate', CertificateAttributes, True, ignore=['expires', 'not_before'])

    with self.argument_context('keyvault certificate set-attributes') as c:
        c.attributes_argument('certificate', CertificateAttributes, ignore=['expires', 'not_before'])

    with self.argument_context('keyvault certificate backup') as c:
        c.argument('file_path', options_list=['--file', '-f'], type=file_type, completer=FilesCompleter(),
                   help='Local file path in which to store certificate backup.')

    with self.argument_context('keyvault certificate restore') as c:
        c.argument('file_path', options_list=['--file', '-f'], type=file_type, completer=FilesCompleter(),
                   help='Local certificate backup from which to restore certificate.')

    for item in ['create', 'set-attributes', 'import']:
        with self.argument_context('keyvault certificate ' + item) as c:
            c.argument('certificate_policy', options_list=['--policy', '-p'],
                       help='JSON encoded policy definition. Use @{file} to load from a file(e.g. @my_policy.json).',
                       type=get_json_object)

    with self.argument_context('keyvault certificate import') as c:
        c.argument('certificate_data', options_list=['--file', '-f'], completer=FilesCompleter(),
                   help='PKCS12 file or PEM file containing the certificate and private key.',
                   type=certificate_type)
        c.argument('password', help="If the private key in certificate is encrypted, the password used for encryption.")
        c.extra('disabled', arg_type=get_three_state_flag(), help='Import the certificate in disabled state.')

    with self.argument_context('keyvault certificate download') as c:
        c.argument('file_path', options_list=['--file', '-f'], type=file_type, completer=FilesCompleter(),
                   help='File to receive the binary certificate contents.')
        c.argument('encoding', arg_type=get_enum_type(certificate_format_values), options_list=['--encoding', '-e'],
                   help='Encoding of the certificate. DER will create a binary DER formatted x509 certificate, '
                        'and PEM will create a base64 PEM x509 certificate.')

    # TODO: Fix once service side issue is fixed that there is no way to list pending certificates
    with self.argument_context('keyvault certificate pending') as c:
        c.argument('certificate_name', options_list=['--name', '-n'], help='Name of the pending certificate.',
                   id_part='child_name_1', completer=None)

    with self.argument_context('keyvault certificate pending merge') as c:
        c.argument('x509_certificates', options_list=['--file', '-f'], type=file_type, completer=FilesCompleter(),
                   help='File containing the certificate or certificate chain to merge.',
                   validator=validate_x509_certificate_chain)
        c.attributes_argument('certificate', CertificateAttributes, True)

    with self.argument_context('keyvault certificate pending cancel') as c:
        c.ignore('cancellation_requested')

    with self.argument_context('keyvault certificate contact') as c:
        c.argument('contact_email', options_list=['--email'], help='Contact e-mail address. Must be unique.')
        c.argument('contact_name', options_list=['--name'], help='Full contact name.')
        c.argument('contact_phone', options_list=['--phone'], help='Contact phone number.')

    with self.argument_context('keyvault certificate issuer admin') as c:
        c.argument('email', help='Admin e-mail address. Must be unique within the vault.')
        c.argument('name', help='Full admin name.')
        c.argument('phone', help='Admin phone number.')
        c.argument('first_name', help='Admin first name.')
        c.argument('last_name', help='Admin last name.')

    with self.argument_context('keyvault certificate issuer') as c:
        c.argument('issuer_name', help='Certificate issuer name.')
        c.argument('disabled', arg_type=get_three_state_flag(), help='Set issuer to disabled state.')
        c.argument('enabled', arg_type=get_three_state_flag(), help='Set issuer enabled state.')

    with self.argument_context('keyvault certificate issuer', arg_group='Issuer Credential') as c:
        c.argument('account_id')
        c.argument('password')

    with self.argument_context('keyvault certificate issuer', arg_group='Organization Detail') as c:
        c.argument('organization_id')
        c.argument('admin_first_name')
        c.argument('admin_last_name')
        c.argument('admin_email')
        c.argument('admin_phone')

    for item in ['list', 'list-deleted', 'list-versions']:
        with self.argument_context('keyvault certificate {}'.format(item)) as c:
            c.argument('maxresults', options_list=['--maxresults'], type=int)

    with self.argument_context('keyvault role') as c:
        c.argument('scope',
                   help='scope at which the role assignment or definition applies to, '
                        'e.g., "/" or "/keys" or "/keys/{keyname}"')

    with self.argument_context('keyvault role', arg_group='Id') as c:
        c.argument('hsm_name', hsm_url_type)
        c.argument('identifier', options_list=['--id'],
                   help='Id of the HSM. If specified all other \'Id\' arguments should be omitted.',
                   validator=process_hsm_name)

    with self.argument_context('keyvault role assignment') as c:
        c.argument('role_assignment_name', options_list=['--name', '-n'], help='Name of the role assignment.')
        c.argument('assignee', help='represent a user, group, or service principal. '
                                    'supported format: object id, user sign-in name, or service principal name')
        c.argument('assignee_object_id',
                   help='Use this parameter instead of \'--assignee\' to bypass graph permission issues. '
                        'This parameter only works with object ids for users, groups, service principals, and '
                        'managed identities. For managed identities use the principal id. For service principals, '
                        'use the object id and not the app id.')
        c.argument('ids', nargs='+', help='space-separated role assignment ids')
        c.argument('role', help='role name or id')

    with self.argument_context('keyvault role definition') as c:
        c.argument('hsm_name', hsm_url_type)
        c.argument('role_definition', help='Description of a role as JSON, or a path to a file containing a JSON description.')
        c.argument('role_id', help='The role definition ID.')
        c.argument('role_definition_name', options_list=['--name', '-n'], help='The role definition name. '
                   'This is a GUID in the "name" property of a role definition.')

    with self.argument_context('keyvault role definition list') as c:
        c.argument('custom_role_only', arg_type=get_three_state_flag(), help='Only show custom role definitions.')

    class PrincipalType(str, Enum):  # Copied from azure.mgmt.authorization v2018_09_01_preview
        user = "******"
        group = "Group"
        service_principal = "ServicePrincipal"
        unknown = "Unknown"
        directory_role_template = "DirectoryRoleTemplate"
        foreign_group = "ForeignGroup"
        application = "Application"
        msi = "MSI"
        directory_object_or_group = "DirectoryObjectOrGroup"
        everyone = "Everyone"

    with self.argument_context('keyvault role assignment create') as c:
        c.argument('assignee_principal_type', options_list=['--assignee-principal-type', '-t'],
                   arg_type=get_enum_type(PrincipalType), help='The principal type of assignee.')
Ejemplo n.º 3
0
def load_arguments(self, _):
    from azure.keyvault.models import JsonWebKeyOperation
    from azure.keyvault.models import KeyAttributes, SecretAttributes, CertificateAttributes
    from azure.mgmt.keyvault.models.key_vault_management_client_enums import (
        SkuName, KeyPermissions, SecretPermissions, CertificatePermissions)

    # ARGUMENT DEFINITIONS
    vault_name_type = CLIArgumentType(
        help='Name of the key vault.', options_list=['--vault-name'], metavar='NAME', id_part=None,
        completer=get_resource_name_completion_list('Microsoft.KeyVault/vaults'))

    # region vault (management)
    with self.argument_context('keyvault') as c:
        c.argument('resource_group_name', resource_group_name_type, id_part=None, required=False, help='Proceed only if Key Vault belongs to the specified resource group.', validator=validate_resource_group_name)
        c.argument('vault_name', vault_name_type, options_list=['--name', '-n'])
        c.argument('object_id', help='a GUID that identifies the principal that will receive permissions')
        c.argument('spn', help='name of a service principal that will receive permissions')
        c.argument('upn', help='name of a user principal that will receive permissions')
        c.argument('tags', tags_type)
        c.argument('enabled_for_deployment', arg_type=get_three_state_flag(), help='Allow Virtual Machines to retrieve certificates stored as secrets from the vault.')
        c.argument('enabled_for_disk_encryption', arg_type=get_three_state_flag(), help='Allow Disk Encryption to retrieve secrets from the vault and unwrap keys.')
        c.argument('enabled_for_template_deployment', arg_type=get_three_state_flag(), help='Allow Resource Manager to retrieve secrets from the vault.')
        c.argument('enable_soft_delete', arg_type=get_three_state_flag(), help='Enable vault deletion recovery for the vault, and all contained entities')

    with self.argument_context('keyvault create') as c:
        c.argument('resource_group_name', resource_group_name_type, required=True, completer=None, validator=None)
        c.argument('vault_name', completer=None)
        c.argument('sku', arg_type=get_enum_type(SkuName, default=SkuName.standard.value))
        c.argument('no_self_perms', arg_type=get_three_state_flag(), help="Don't add permissions for the current user/service principal in the new vault.")
        c.argument('location', validator=get_default_location_from_resource_group)

    with self.argument_context('keyvault list') as c:
        c.argument('resource_group_name', resource_group_name_type, validator=None)

    with self.argument_context('keyvault delete-policy') as c:
        c.argument('object_id', validator=validate_principal)

    with self.argument_context('keyvault set-policy', arg_group='Permission') as c:
        c.argument('key_permissions', arg_type=get_enum_type(KeyPermissions), metavar='PERM', nargs='*', help='Space-separated list of key permissions to assign.', validator=validate_policy_permissions)
        c.argument('secret_permissions', arg_type=get_enum_type(SecretPermissions), metavar='PERM', nargs='*', help='Space-separated list of secret permissions to assign.')
        c.argument('certificate_permissions', arg_type=get_enum_type(CertificatePermissions), metavar='PERM', nargs='*', help='Space-separated list of certificate permissions to assign.')
    # endregion

    # region Shared
    for item in ['key', 'secret', 'certificate']:
        with self.argument_context('keyvault ' + item) as c:
            c.argument(item + '_name', options_list=['--name', '-n'], help='Name of the {}.'.format(item), id_part='child_name_1', completer=get_keyvault_name_completion_list(item))
            c.argument('vault_base_url', vault_name_type, type=get_vault_base_url_type(self.cli_ctx), id_part=None)
    # endregion

    # region keys
    with self.argument_context('keyvault key') as c:
        c.argument('key_ops', arg_type=get_enum_type(JsonWebKeyOperation), options_list=['--ops'], nargs='*', help='Space-separated list of permitted JSON web key operations.')
        c.argument('key_version', options_list=['--version', '-v'], help='The key version. If omitted, uses the latest version.', default='', required=False, completer=get_keyvault_version_completion_list('key'))

    for scope in ['keyvault key create', 'keyvault key import']:
        with self.argument_context(scope) as c:
            c.argument('destination', arg_type=get_enum_type(['software', 'hsm']), options_list=['--protection', '-p'], help='Specifies the type of key protection.', validator=validate_key_type)
            c.argument('disabled', arg_type=get_three_state_flag(), help='Create key in disabled state.')
            c.argument('key_size', options_list=['--size'], type=int)
            c.argument('expires', default=None, help='Expiration UTC datetime  (Y-m-d\'T\'H:M:S\'Z\').', type=datetime_type)
            c.argument('not_before', default=None, help='Key not usable before the provided UTC datetime  (Y-m-d\'T\'H:M:S\'Z\').', type=datetime_type)

    with self.argument_context('keyvault key import', arg_group='Key Source') as c:
        c.argument('pem_file', type=file_type, help='PEM file containing the key to be imported.', completer=FilesCompleter(), validator=validate_key_import_source)
        c.argument('pem_password', help='Password of PEM file.')
        c.argument('byok_file', type=file_type, help='BYOK file containing the key to be imported. Must not be password protected.', completer=FilesCompleter())

    with self.argument_context('keyvault key backup') as c:
        c.argument('file_path', options_list=['--file', '-f'], type=file_type, completer=FilesCompleter(), help='Local file path in which to store key backup.')

    with self.argument_context('keyvault key restore') as c:
        c.argument('file_path', options_list=['--file', '-f'], type=file_type, completer=FilesCompleter(), help='Local key backup from which to restore key.')

    with self.argument_context('keyvault key set-attributes') as c:
        c.attributes_argument('key', KeyAttributes)
    # endregion

    # region KeyVault Secret
    with self.argument_context('keyvault secret') as c:
        c.argument('secret_version', options_list=['--version', '-v'], help='The secret version. If omitted, uses the latest version.', default='', required=False, completer=get_keyvault_version_completion_list('secret'))

    with self.argument_context('keyvault secret set') as c:
        c.argument('content_type', options_list=['--description'], help='Description of the secret contents (e.g. password, connection string, etc)')
        c.attributes_argument('secret', SecretAttributes, create=True)

    with self.argument_context('keyvault secret set', arg_group='Content Source') as c:
        c.argument('value', options_list=['--value'], help="Plain text secret value. Cannot be used with '--file' or '--encoding'", required=False)
        c.extra('file_path', options_list=['--file', '-f'], type=file_type, help="Source file for secret. Use in conjunction with '--encoding'", completer=FilesCompleter())
        c.extra('encoding', arg_type=get_enum_type(secret_encoding_values, default='utf-8'), options_list=['--encoding', '-e'], help='Source file encoding. The value is saved as a tag (`file-encoding=<val>`) and used during download to automatically encode the resulting file.')

    with self.argument_context('keyvault secret set-attributes') as c:
        c.attributes_argument('secret', SecretAttributes)

    with self.argument_context('keyvault secret download') as c:
        c.argument('file_path', options_list=['--file', '-f'], type=file_type, completer=FilesCompleter(), help='File to receive the secret contents.')
        c.argument('encoding', arg_type=get_enum_type(secret_encoding_values), options_list=['--encoding', '-e'], help="Encoding of the destination file. By default, will look for the 'file-encoding' tag on the secret. Otherwise will assume 'utf-8'.", default=None)
    # endregion

    # KeyVault Certificate
    with self.argument_context('keyvault certificate') as c:
        c.argument('certificate_version', options_list=['--version', '-v'], help='The certificate version. If omitted, uses the latest version.', default='', required=False, completer=get_keyvault_version_completion_list('certificate'))
        c.argument('validity', type=int, help='Number of months the certificate is valid for. Overrides the value specified with --policy/-p')

    # TODO: Remove workaround when https://github.com/Azure/azure-rest-api-specs/issues/1153 is fixed
    with self.argument_context('keyvault certificate create') as c:
        c.attributes_argument('certificate', CertificateAttributes, True, ignore=['expires', 'not_before'])

    with self.argument_context('keyvault certificate set-attributes') as c:
        c.attributes_argument('certificate', CertificateAttributes, ignore=['expires', 'not_before'])

    for item in ['create', 'set-attributes', 'import']:
        with self.argument_context('keyvault certificate ' + item) as c:
            c.argument('certificate_policy', options_list=['--policy', '-p'], help='JSON encoded policy defintion. Use @{file} to load from a file.', type=get_json_object)

    with self.argument_context('keyvault certificate import') as c:
        c.argument('certificate_data', options_list=['--file', '-f'], completer=FilesCompleter(), help='PKCS12 file or PEM file containing the certificate and private key.', type=certificate_type)
        c.argument('password', help="If the private key in certificate is encrypted, the password used for encryption.")
        c.extra('disabled', arg_type=get_three_state_flag(), help='Import the certificate in disabled state.')

    with self.argument_context('keyvault certificate download') as c:
        c.argument('file_path', options_list=['--file', '-f'], type=file_type, completer=FilesCompleter(), help='File to receive the binary certificate contents.')
        c.argument('encoding', arg_type=get_enum_type(certificate_format_values), options_list=['--encoding', '-e'], help='Encoding of the certificate. DER will create a binary DER formatted x509 certificate, and PEM will create a base64 PEM x509 certificate.')

    # TODO: Fix once service side issue is fixed that there is no way to list pending certificates
    with self.argument_context('keyvault certificate pending') as c:
        c.argument('certificate_name', options_list=['--name', '-n'], help='Name of the pending certificate.', id_part='child_name_1', completer=None)

    with self.argument_context('keyvault certificate pending merge') as c:
        c.argument('x509_certificates', options_list=['--file', '-f'], type=file_type, completer=FilesCompleter(), help='File containing the certificate or certificate chain to merge.', validator=validate_x509_certificate_chain)
        c.attributes_argument('certificate', CertificateAttributes, True)

    with self.argument_context('keyvault certificate pending cancel') as c:
        c.ignore('cancellation_requested')

    with self.argument_context('keyvault certificate contact') as c:
        c.argument('contact_email', options_list=['--email'], help='Contact e-mail address. Must be unique.')
        c.argument('contact_name', options_list=['--name'], help='Full contact name.')
        c.argument('contact_phone', options_list=['--phone'], help='Contact phone number.')

    with self.argument_context('keyvault certificate issuer admin') as c:
        c.argument('email', options_list=['--email'], help='Admin e-mail address. Must be unique within the vault.')
        c.argument('name', options_list=['--name'], help='Full admin name.')
        c.argument('phone', options_list=['--phone'], help='Amin phone number.')

    with self.argument_context('keyvault certificate issuer') as c:
        c.argument('issuer_name', help='Certificate issuer name.')
        c.argument('disabled', arg_type=get_three_state_flag(), help='Set issuer to disabled state.')
        c.argument('enabled', arg_type=get_three_state_flag(), help='Set issuer enabled state.')

    with self.argument_context('keyvault certificate issuer', arg_group='Issuer Credential') as c:
        c.argument('account_id')
        c.argument('password')

    with self.argument_context('keyvault certificate issuer', arg_group='Organization Detail') as c:
        c.argument('organization_id')
        c.argument('admin_first_name')
        c.argument('admin_last_name')
        c.argument('admin_email')
        c.argument('admin_phone')
Ejemplo n.º 4
0
def load_arguments(self, _):
    from azure.keyvault.models import JsonWebKeyOperation
    from azure.keyvault.models import KeyAttributes, SecretAttributes, CertificateAttributes
    from azure.mgmt.keyvault.models.key_vault_management_client_enums import (
        SkuName, KeyPermissions, SecretPermissions, CertificatePermissions)

    # ARGUMENT DEFINITIONS
    vault_name_type = CLIArgumentType(
        help='Name of the key vault.',
        options_list=['--vault-name'],
        metavar='NAME',
        id_part=None,
        completer=get_resource_name_completion_list(
            'Microsoft.KeyVault/vaults'))

    # region vault (management)
    with self.argument_context('keyvault') as c:
        c.argument(
            'resource_group_name',
            resource_group_name_type,
            id_part=None,
            required=False,
            help=
            'Proceed only if Key Vault belongs to the specified resource group.',
            validator=validate_resource_group_name)
        c.argument('vault_name',
                   vault_name_type,
                   options_list=['--name', '-n'])
        c.argument(
            'object_id',
            help=
            'a GUID that identifies the principal that will receive permissions'
        )
        c.argument(
            'spn',
            help='name of a service principal that will receive permissions')
        c.argument(
            'upn',
            help='name of a user principal that will receive permissions')
        c.argument('tags', tags_type)
        c.argument(
            'enabled_for_deployment',
            arg_type=get_three_state_flag(),
            help=
            'Allow Virtual Machines to retrieve certificates stored as secrets from the vault.'
        )
        c.argument(
            'enabled_for_disk_encryption',
            arg_type=get_three_state_flag(),
            help=
            'Allow Disk Encryption to retrieve secrets from the vault and unwrap keys.'
        )
        c.argument(
            'enabled_for_template_deployment',
            arg_type=get_three_state_flag(),
            help='Allow Resource Manager to retrieve secrets from the vault.')
        c.argument(
            'enable_soft_delete',
            arg_type=get_three_state_flag(),
            help=
            'Enable vault deletion recovery for the vault, and all contained entities'
        )

    with self.argument_context('keyvault create') as c:
        c.argument('resource_group_name',
                   resource_group_name_type,
                   required=True,
                   completer=None,
                   validator=None)
        c.argument('vault_name', completer=None)
        c.argument('sku', arg_type=get_enum_type(SkuName))
        c.argument(
            'no_self_perms',
            arg_type=get_three_state_flag(),
            help=
            "Don't add permissions for the current user/service principal in the new vault."
        )
        c.argument('location',
                   validator=get_default_location_from_resource_group)

    with self.argument_context('keyvault list') as c:
        c.argument('resource_group_name',
                   resource_group_name_type,
                   validator=None)

    with self.argument_context('keyvault delete-policy') as c:
        c.argument('object_id', validator=validate_principal)

    with self.argument_context('keyvault set-policy',
                               arg_group='Permission') as c:
        c.argument('key_permissions',
                   arg_type=get_enum_type(KeyPermissions),
                   metavar='PERM',
                   nargs='*',
                   help='Space separated list of key permissions to assign.',
                   validator=validate_policy_permissions)
        c.argument(
            'secret_permissions',
            arg_type=get_enum_type(SecretPermissions),
            metavar='PERM',
            nargs='*',
            help='Space separated list of secret permissions to assign.')
        c.argument(
            'certificate_permissions',
            arg_type=get_enum_type(CertificatePermissions),
            metavar='PERM',
            nargs='*',
            help='Space separated list of certificate permissions to assign.')
    # endregion

    # region Shared
    for item in ['key', 'secret', 'certificate']:
        with self.argument_context('keyvault ' + item) as c:
            c.argument(item + '_name',
                       options_list=['--name', '-n'],
                       help='Name of the {}.'.format(item),
                       id_part='child_name_1',
                       completer=get_keyvault_name_completion_list(item))
            c.argument('vault_base_url',
                       vault_name_type,
                       type=get_vault_base_url_type(self.cli_ctx),
                       id_part=None)
    # endregion

    # region keys
    with self.argument_context('keyvault key') as c:
        c.argument(
            'key_ops',
            arg_type=get_enum_type(JsonWebKeyOperation),
            options_list=['--ops'],
            nargs='*',
            help='Space separated list of permitted JSON web key operations.')
        c.argument(
            'key_version',
            options_list=['--version', '-v'],
            help='The key version. If omitted, uses the latest version.',
            default='',
            required=False,
            completer=get_keyvault_version_completion_list('key'))

    for scope in ['keyvault key create', 'keyvault key import']:
        with self.argument_context(scope) as c:
            c.argument('destination',
                       arg_type=get_enum_type(['software', 'hsm']),
                       options_list=['--protection', '-p'],
                       help='Specifies the type of key protection.',
                       validator=validate_key_type)
            c.argument('disabled',
                       arg_type=get_three_state_flag(),
                       help='Create key in disabled state.')
            c.argument('key_size', options_list=['--size'], type=int)
            c.argument('expires',
                       default=None,
                       help='Expiration UTC datetime  (Y-m-d\'T\'H:M:S\'Z\').',
                       type=datetime_type)
            c.argument(
                'not_before',
                default=None,
                help=
                'Key not usable before the provided UTC datetime  (Y-m-d\'T\'H:M:S\'Z\').',
                type=datetime_type)

    with self.argument_context('keyvault key import',
                               arg_group='Key Source') as c:
        c.argument('pem_file',
                   type=file_type,
                   help='PEM file containing the key to be imported.',
                   completer=FilesCompleter(),
                   validator=validate_key_import_source)
        c.argument('pem_password', help='Password of PEM file.')
        c.argument(
            'byok_file',
            type=file_type,
            help=
            'BYOK file containing the key to be imported. Must not be password protected.',
            completer=FilesCompleter())

    with self.argument_context('keyvault key backup') as c:
        c.argument('file_path',
                   options_list=['--file', '-f'],
                   type=file_type,
                   completer=FilesCompleter(),
                   help='Local file path in which to store key backup.')

    with self.argument_context('keyvault key restore') as c:
        c.argument('file_path',
                   options_list=['--file', '-f'],
                   type=file_type,
                   completer=FilesCompleter(),
                   help='Local key backup from which to restore key.')

    with self.argument_context('keyvault key set-attributes') as c:
        c.attributes_argument('key', KeyAttributes)
    # endregion

    # region KeyVault Secret
    with self.argument_context('keyvault secret') as c:
        c.argument(
            'secret_version',
            options_list=['--version', '-v'],
            help='The secret version. If omitted, uses the latest version.',
            default='',
            required=False,
            completer=get_keyvault_version_completion_list('secret'))

    with self.argument_context('keyvault secret set') as c:
        c.argument(
            'content_type',
            options_list=['--description'],
            help=
            'Description of the secret contents (e.g. password, connection string, etc)'
        )
        c.attributes_argument('secret', SecretAttributes, create=True)

    with self.argument_context('keyvault secret set',
                               arg_group='Content Source') as c:
        c.argument(
            'value',
            options_list=['--value'],
            help=
            "Plain text secret value. Cannot be used with '--file' or '--encoding'",
            required=False)
        c.extra(
            'file_path',
            options_list=['--file', '-f'],
            type=file_type,
            help="Source file for secret. Use in conjunction with '--encoding'",
            completer=FilesCompleter())
        c.extra(
            'encoding',
            arg_type=get_enum_type(secret_encoding_values, default='utf-8'),
            options_list=['--encoding', '-e'],
            help=
            'Source file encoding. The value is saved as a tag (`file-encoding=<val>`) and used during download to automatically encode the resulting file.'
        )

    with self.argument_context('keyvault secret set-attributes') as c:
        c.attributes_argument('secret', SecretAttributes)

    with self.argument_context('keyvault secret download') as c:
        c.argument('file_path',
                   options_list=['--file', '-f'],
                   type=file_type,
                   completer=FilesCompleter(),
                   help='File to receive the secret contents.')
        c.argument(
            'encoding',
            arg_type=get_enum_type(secret_encoding_values),
            options_list=['--encoding', '-e'],
            help=
            "Encoding of the destination file. By default, will look for the 'file-encoding' tag on the secret. Otherwise will assume 'utf-8'.",
            default=None)
    # endregion

    # KeyVault Certificate
    with self.argument_context('keyvault certificate') as c:
        c.argument(
            'certificate_version',
            options_list=['--version', '-v'],
            help=
            'The certificate version. If omitted, uses the latest version.',
            default='',
            required=False,
            completer=get_keyvault_version_completion_list('certificate'))
        c.argument(
            'validity',
            type=int,
            help=
            'Number of months the certificate is valid for. Overrides the value specified with --policy/-p'
        )

    # TODO: Remove workaround when https://github.com/Azure/azure-rest-api-specs/issues/1153 is fixed
    with self.argument_context('keyvault certificate create') as c:
        c.attributes_argument('certificate',
                              CertificateAttributes,
                              True,
                              ignore=['expires', 'not_before'])

    with self.argument_context('keyvault certificate set-attributes') as c:
        c.attributes_argument('certificate',
                              CertificateAttributes,
                              ignore=['expires', 'not_before'])

    for item in ['create', 'set-attributes', 'import']:
        with self.argument_context('keyvault certificate ' + item) as c:
            c.argument(
                'certificate_policy',
                options_list=['--policy', '-p'],
                help=
                'JSON encoded policy defintion. Use @{file} to load from a file.',
                type=get_json_object)

    with self.argument_context('keyvault certificate import') as c:
        c.argument(
            'certificate_data',
            options_list=['--file', '-f'],
            completer=FilesCompleter(),
            help=
            'PKCS12 file or PEM file containing the certificate and private key.',
            type=certificate_type)
        c.argument(
            'password',
            help=
            "If the private key in certificate is encrypted, the password used for encryption."
        )
        c.extra('disabled',
                arg_type=get_three_state_flag(),
                help='Import the certificate in disabled state.')

    with self.argument_context('keyvault certificate download') as c:
        c.argument('file_path',
                   options_list=['--file', '-f'],
                   type=file_type,
                   completer=FilesCompleter(),
                   help='File to receive the binary certificate contents.')
        c.argument(
            'encoding',
            arg_type=get_enum_type(certificate_format_values),
            options_list=['--encoding', '-e'],
            help=
            'Encoding of the certificate. DER will create a binary DER formatted x509 certificate, and PEM will create a base64 PEM x509 certificate.'
        )

    # TODO: Fix once service side issue is fixed that there is no way to list pending certificates
    with self.argument_context('keyvault certificate pending') as c:
        c.argument('certificate_name',
                   options_list=['--name', '-n'],
                   help='Name of the pending certificate.',
                   id_part='child_name_1',
                   completer=None)

    with self.argument_context('keyvault certificate pending merge') as c:
        c.argument(
            'x509_certificates',
            options_list=['--file', '-f'],
            type=file_type,
            completer=FilesCompleter(),
            help=
            'File containing the certificate or certificate chain to merge.',
            validator=validate_x509_certificate_chain)
        c.attributes_argument('certificate', CertificateAttributes, True)

    with self.argument_context('keyvault certificate pending cancel') as c:
        c.ignore('cancellation_requested')

    with self.argument_context('keyvault certificate contact') as c:
        c.argument('contact_email',
                   options_list=['--email'],
                   help='Contact e-mail address. Must be unique.')
        c.argument('contact_name',
                   options_list=['--name'],
                   help='Full contact name.')
        c.argument('contact_phone',
                   options_list=['--phone'],
                   help='Contact phone number.')

    with self.argument_context('keyvault certificate issuer admin') as c:
        c.argument(
            'email',
            options_list=['--email'],
            help='Admin e-mail address. Must be unique within the vault.')
        c.argument('name', options_list=['--name'], help='Full admin name.')
        c.argument('phone',
                   options_list=['--phone'],
                   help='Amin phone number.')

    with self.argument_context('keyvault certificate issuer') as c:
        c.argument('issuer_name', help='Certificate issuer name.')
        c.argument('disabled',
                   arg_type=get_three_state_flag(),
                   help='Set issuer to disabled state.')
        c.argument('enabled',
                   arg_type=get_three_state_flag(),
                   help='Set issuer enabled state.')

    with self.argument_context('keyvault certificate issuer',
                               arg_group='Issuer Credential') as c:
        c.argument('account_id')
        c.argument('password')

    with self.argument_context('keyvault certificate issuer',
                               arg_group='Organization Detail') as c:
        c.argument('organization_id')
        c.argument('admin_first_name')
        c.argument('admin_last_name')
        c.argument('admin_email')
        c.argument('admin_phone')