diff --git a/sdk/keyvault/azure-keyvault-administration/MANIFEST.in b/sdk/keyvault/azure-keyvault-administration/MANIFEST.in index e3240617f61a..1d02a90df18c 100644 --- a/sdk/keyvault/azure-keyvault-administration/MANIFEST.in +++ b/sdk/keyvault/azure-keyvault-administration/MANIFEST.in @@ -1,7 +1,7 @@ include *.md include LICENSE -include azure/__init__.py -include azure/keyvault/__init__.py -recursive-include samples *.py -recursive-include tests *.py include azure/keyvault/administration/py.typed +recursive-include tests *.py +recursive-include samples *.py *.md +include azure/__init__.py +include azure/keyvault/__init__.py \ No newline at end of file diff --git a/sdk/keyvault/azure-keyvault-administration/_meta.json b/sdk/keyvault/azure-keyvault-administration/_meta.json new file mode 100644 index 000000000000..c68528fd964e --- /dev/null +++ b/sdk/keyvault/azure-keyvault-administration/_meta.json @@ -0,0 +1,6 @@ +{ + "commit": "2d9a495c439ab16c8e3b19c67bdf59ab8c4bd1a1", + "repository_url": "https://github.com/Azure/azure-rest-api-specs", + "typespec_src": "specification/keyvault/Security.KeyVault.Administration", + "@azure-tools/typespec-python": "0.38.3" +} \ No newline at end of file diff --git a/sdk/keyvault/azure-keyvault-administration/apiview-properties.json b/sdk/keyvault/azure-keyvault-administration/apiview-properties.json new file mode 100644 index 000000000000..b23adb0ea313 --- /dev/null +++ b/sdk/keyvault/azure-keyvault-administration/apiview-properties.json @@ -0,0 +1,51 @@ +{ + "CrossLanguagePackageId": "KeyVault", + "CrossLanguageDefinitionId": { + "azure.keyvault.administration.models.FullBackupOperation": "KeyVault.FullBackupOperation", + "azure.keyvault.administration.models.FullBackupOperationError": "KeyVault.FullBackupOperation.error.anonymous", + "azure.keyvault.administration.models.KeyVaultError": "KeyVaultError", + "azure.keyvault.administration.models.Permission": "KeyVault.Permission", + "azure.keyvault.administration.models.PreBackupOperationParameters": "KeyVault.PreBackupOperationParameters", + "azure.keyvault.administration.models.PreRestoreOperationParameters": "KeyVault.PreRestoreOperationParameters", + "azure.keyvault.administration.models.RestoreOperation": "KeyVault.RestoreOperation", + "azure.keyvault.administration.models.RestoreOperationParameters": "KeyVault.RestoreOperationParameters", + "azure.keyvault.administration.models.RoleAssignment": "KeyVault.RoleAssignment", + "azure.keyvault.administration.models.RoleAssignmentCreateParameters": "KeyVault.RoleAssignmentCreateParameters", + "azure.keyvault.administration.models.RoleAssignmentProperties": "KeyVault.RoleAssignmentProperties", + "azure.keyvault.administration.models.RoleAssignmentPropertiesWithScope": "KeyVault.RoleAssignmentPropertiesWithScope", + "azure.keyvault.administration.models.RoleDefinition": "KeyVault.RoleDefinition", + "azure.keyvault.administration.models.RoleDefinitionCreateParameters": "KeyVault.RoleDefinitionCreateParameters", + "azure.keyvault.administration.models.RoleDefinitionProperties": "KeyVault.RoleDefinitionProperties", + "azure.keyvault.administration.models.SASTokenParameter": "KeyVault.SASTokenParameter", + "azure.keyvault.administration.models.SelectiveKeyRestoreOperation": "KeyVault.SelectiveKeyRestoreOperation", + "azure.keyvault.administration.models.SelectiveKeyRestoreOperationParameters": "KeyVault.SelectiveKeyRestoreOperationParameters", + "azure.keyvault.administration.models.Setting": "KeyVault.Setting", + "azure.keyvault.administration.models.SettingsListResult": "KeyVault.SettingsListResult", + "azure.keyvault.administration.models.UpdateSettingRequest": "KeyVault.UpdateSettingRequest", + "azure.keyvault.administration.models.RoleDefinitionType": "KeyVault.RoleDefinitionType", + "azure.keyvault.administration.models.RoleType": "KeyVault.RoleType", + "azure.keyvault.administration.models.DataAction": "KeyVault.DataAction", + "azure.keyvault.administration.models.RoleScope": "KeyVault.RoleScope", + "azure.keyvault.administration.models.OperationStatus": "KeyVault.OperationStatus", + "azure.keyvault.administration.models.SettingTypeEnum": "KeyVault.SettingTypeEnum", + "azure.keyvault.administration.KeyVaultClient.role_definitions.delete": "KeyVault.RoleDefinitions.delete", + "azure.keyvault.administration.KeyVaultClient.role_definitions.create_or_update": "KeyVault.RoleDefinitions.createOrUpdate", + "azure.keyvault.administration.KeyVaultClient.role_definitions.get": "KeyVault.RoleDefinitions.get", + "azure.keyvault.administration.KeyVaultClient.role_definitions.list": "KeyVault.RoleDefinitions.list", + "azure.keyvault.administration.KeyVaultClient.role_assignments.delete": "KeyVault.RoleAssignments.delete", + "azure.keyvault.administration.KeyVaultClient.role_assignments.create": "KeyVault.RoleAssignments.create", + "azure.keyvault.administration.KeyVaultClient.role_assignments.get": "KeyVault.RoleAssignments.get", + "azure.keyvault.administration.KeyVaultClient.role_assignments.list_for_scope": "KeyVault.RoleAssignments.listForScope", + "azure.keyvault.administration.KeyVaultClient.full_backup_status": "KeyVault.fullBackupStatus", + "azure.keyvault.administration.KeyVaultClient.begin_full_backup": "KeyVault.fullBackup", + "azure.keyvault.administration.KeyVaultClient.begin_pre_full_backup": "KeyVault.preFullBackup", + "azure.keyvault.administration.KeyVaultClient.restore_status": "KeyVault.restoreStatus", + "azure.keyvault.administration.KeyVaultClient.begin_pre_full_restore_operation": "KeyVault.preFullRestoreOperation", + "azure.keyvault.administration.KeyVaultClient.begin_full_restore_operation": "KeyVault.fullRestoreOperation", + "azure.keyvault.administration.KeyVaultClient.selective_key_restore_status": "KeyVault.selectiveKeyRestoreStatus", + "azure.keyvault.administration.KeyVaultClient.begin_selective_key_restore_operation": "KeyVault.selectiveKeyRestoreOperation", + "azure.keyvault.administration.KeyVaultClient.update_setting": "KeyVault.updateSetting", + "azure.keyvault.administration.KeyVaultClient.get_setting": "KeyVault.getSetting", + "azure.keyvault.administration.KeyVaultClient.get_settings": "KeyVault.getSettings" + } +} \ No newline at end of file diff --git a/sdk/keyvault/azure-keyvault-administration/azure/__init__.py b/sdk/keyvault/azure-keyvault-administration/azure/__init__.py index 679ab6995134..d55ccad1f573 100644 --- a/sdk/keyvault/azure-keyvault-administration/azure/__init__.py +++ b/sdk/keyvault/azure-keyvault-administration/azure/__init__.py @@ -1,5 +1 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ __path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/__init__.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/__init__.py index 679ab6995134..d55ccad1f573 100644 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/__init__.py +++ b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/__init__.py @@ -1,5 +1 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ __path__ = __import__("pkgutil").extend_path(__path__, __name__) # type: ignore diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/__init__.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/__init__.py index 5e6b3233b362..4f7962408227 100644 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/__init__.py +++ b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/__init__.py @@ -1,37 +1,32 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from ._access_control_client import KeyVaultAccessControlClient -from ._backup_client import KeyVaultBackupClient -from ._enums import KeyVaultRoleScope, KeyVaultDataAction, KeyVaultSettingType -from ._internal.client_base import ApiVersion -from ._models import ( - KeyVaultBackupResult, - KeyVaultPermission, - KeyVaultRoleAssignment, - KeyVaultRoleAssignmentProperties, - KeyVaultRoleDefinition, - KeyVaultSetting, -) -from ._settings_client import KeyVaultSettingsClient +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +# pylint: disable=wrong-import-position +from typing import TYPE_CHECKING -__all__ = [ - "ApiVersion", - "KeyVaultBackupResult", - "KeyVaultAccessControlClient", - "KeyVaultBackupClient", - "KeyVaultDataAction", - "KeyVaultPermission", - "KeyVaultRoleAssignment", - "KeyVaultRoleAssignmentProperties", - "KeyVaultRoleDefinition", - "KeyVaultRoleScope", - "KeyVaultSetting", - "KeyVaultSettingsClient", - "KeyVaultSettingType", -] +if TYPE_CHECKING: + from ._patch import * # pylint: disable=unused-wildcard-import +from ._client import KeyVaultClient # type: ignore from ._version import VERSION + __version__ = VERSION + +try: + from ._patch import __all__ as _patch_all + from ._patch import * +except ImportError: + _patch_all = [] +from ._patch import patch_sdk as _patch_sdk + +__all__ = [ + "KeyVaultClient", +] +__all__.extend([p for p in _patch_all if p not in __all__]) # pyright: ignore + +_patch_sdk() diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_access_control_client.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_access_control_client.py deleted file mode 100644 index 9b0ea75c1d42..000000000000 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_access_control_client.py +++ /dev/null @@ -1,268 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from typing import Any, List, Optional, Union -from uuid import UUID, uuid4 - -from azure.core.exceptions import ResourceNotFoundError -from azure.core.paging import ItemPaged -from azure.core.tracing.decorator import distributed_trace - -from ._enums import KeyVaultRoleScope -from ._models import KeyVaultPermission, KeyVaultRoleAssignment, KeyVaultRoleDefinition -from ._internal import KeyVaultClientBase - - -class KeyVaultAccessControlClient(KeyVaultClientBase): - """Manages role-based access to Azure Key Vault. - - :param str vault_url: URL of the vault the client will manage. This is also called the vault's "DNS Name". - You should validate that this URL references a valid Key Vault or Managed HSM resource. - See https://aka.ms/azsdk/blog/vault-uri for details. - :param credential: An object which can provide an access token for the vault, such as a credential from - :mod:`azure.identity` - :type credential: ~azure.core.credentials.TokenCredential - - :keyword api_version: Version of the service API to use. Defaults to the most recent. - :paramtype api_version: ~azure.keyvault.administration.ApiVersion or str - :keyword bool verify_challenge_resource: Whether to verify the authentication challenge resource matches the Key - Vault or Managed HSM domain. Defaults to True. - """ - - # pylint:disable=protected-access - - @distributed_trace - def create_role_assignment( - self, - scope: Union[str, KeyVaultRoleScope], - definition_id: str, - principal_id: str, - *, - name: Optional[Union[str, UUID]] = None, - **kwargs: Any, - ) -> KeyVaultRoleAssignment: - """Create a role assignment. - - :param scope: scope the role assignment will apply over. :class:`KeyVaultRoleScope` defines common - broad scopes. Specify a narrower scope as a string. - :type scope: str or KeyVaultRoleScope - :param str definition_id: ID of the role's definition - :param str principal_id: Azure Active Directory object ID of the principal which will be assigned the role. The - principal can be a user, service principal, or security group. - - :keyword name: a name for the role assignment. Must be a UUID. - :paramtype name: str or uuid.UUID or None - - :returns: The created role assignment. - :rtype: ~azure.keyvault.administration.KeyVaultRoleAssignment - """ - assignment_name = name or uuid4() - - create_parameters = self._client.role_assignments.models.RoleAssignmentCreateParameters( - properties=self._client.role_assignments.models.RoleAssignmentProperties( - principal_id=principal_id, role_definition_id=str(definition_id) - ) - ) - assignment = self._client.role_assignments.create( - vault_base_url=self._vault_url, - scope=scope, - role_assignment_name=str(assignment_name), - parameters=create_parameters, - **kwargs - ) - return KeyVaultRoleAssignment._from_generated(assignment) - - @distributed_trace - def delete_role_assignment( - self, scope: Union[str, KeyVaultRoleScope], name: Union[str, UUID], **kwargs: Any - ) -> None: - """Delete a role assignment. - - :param scope: the assignment's scope, for example "/", "/keys", or "/keys/" - :class:`KeyVaultRoleScope` defines common broad scopes. Specify a narrower scope as a string. - :type scope: str or KeyVaultRoleScope - :param name: the role assignment's name. - :type name: str or uuid.UUID - - :returns: None - :rtype: None - """ - try: - self._client.role_assignments.delete( - vault_base_url=self._vault_url, scope=scope, role_assignment_name=str(name), **kwargs - ) - except ResourceNotFoundError: - pass - - @distributed_trace - def get_role_assignment( - self, scope: Union[str, KeyVaultRoleScope], name: Union[str, UUID], **kwargs: Any - ) -> KeyVaultRoleAssignment: - """Get a role assignment. - - :param scope: the assignment's scope, for example "/", "/keys", or "/keys/" - :class:`KeyVaultRoleScope` defines common broad scopes. Specify a narrower scope as a string. - :type scope: str or KeyVaultRoleScope - :param name: the role assignment's name. - :type name: str or uuid.UUID - - :returns: The fetched role assignment. - :rtype: ~azure.keyvault.administration.KeyVaultRoleAssignment - """ - assignment = self._client.role_assignments.get( - vault_base_url=self._vault_url, scope=scope, role_assignment_name=str(name), **kwargs - ) - return KeyVaultRoleAssignment._from_generated(assignment) - - @distributed_trace - def list_role_assignments( - self, scope: Union[str, KeyVaultRoleScope], **kwargs: Any - ) -> ItemPaged[KeyVaultRoleAssignment]: - """List all role assignments for a scope. - - :param scope: scope of the role assignments. :class:`KeyVaultRoleScope` defines common broad scopes. - Specify a narrower scope as a string. - :type scope: str or KeyVaultRoleScope - - :returns: A paged response containing the role assignments for the specified scope. - :rtype: ~azure.core.paging.ItemPaged[~azure.keyvault.administration.KeyVaultRoleAssignment] - """ - return self._client.role_assignments.list_for_scope( - vault_base_url=self._vault_url, - scope=scope, - cls=lambda result: [KeyVaultRoleAssignment._from_generated(a) for a in result], - **kwargs - ) - - @distributed_trace - def set_role_definition( - self, - scope: Union[str, KeyVaultRoleScope], - *, - name: Optional[Union[str, UUID]] = None, - role_name: Optional[str] = None, - description: Optional[str] = None, - permissions: Optional[List[KeyVaultPermission]] = None, - assignable_scopes: Optional[Union[List[str], List[KeyVaultRoleScope]]] = None, - **kwargs: Any, - ) -> KeyVaultRoleDefinition: - """Creates or updates a custom role definition. - - To update a role definition, specify the definition's ``name``. - - :param scope: scope of the role definition. :class:`KeyVaultRoleScope` defines common broad scopes. - Specify a narrower scope as a string. Managed HSM only supports '/', or KeyVaultRoleScope.GLOBAL. - :type scope: str or KeyVaultRoleScope - - :keyword name: the role definition's name, a UUID. When this argument has a value, the client will create a new - role definition with this name or update an existing role definition, if one exists with the given name. - When this argument has no value, a new role definition will be created with a generated name. - :paramtype name: str or uuid.UUID or None - :keyword role_name: the role's display name. If unspecified when creating or updating a role definition, the - role name will be set to an empty string. - :paramtype role_name: str or None - :keyword description: a description of the role definition. If unspecified when creating or updating a role - definition, the description will be set to an empty string. - :paramtype description: str or None - :keyword permissions: the role definition's permissions. If unspecified when creating or updating a role - definition, the role definition will have no action permissions. - :paramtype permissions: list[KeyVaultPermission] or None - :keyword assignable_scopes: the scopes for which the role definition can be assigned. - :paramtype assignable_scopes: list[str] or list[KeyVaultRoleScope] or None - - :returns: The created or updated role definition - :rtype: ~azure.keyvault.administration.KeyVaultRoleDefinition - """ - role_permissions = [ - self._client.role_definitions.models.Permission( - actions=p.actions, - not_actions=p.not_actions, - data_actions=p.data_actions, - not_data_actions=p.not_data_actions, - ) - for p in permissions or [] - ] - - properties = self._client.role_definitions.models.RoleDefinitionProperties( - role_name=role_name, - description=description, - permissions=role_permissions, - assignable_scopes=assignable_scopes, - ) - parameters = self._client.role_definitions.models.RoleDefinitionCreateParameters(properties=properties) - - definition = self._client.role_definitions.create_or_update( - vault_base_url=self._vault_url, - scope=scope, - role_definition_name=str(name or uuid4()), - parameters=parameters, - **kwargs - ) - return KeyVaultRoleDefinition._from_generated(definition) - - @distributed_trace - def get_role_definition( - self, scope: Union[str, KeyVaultRoleScope], name: Union[str, UUID], **kwargs: Any - ) -> KeyVaultRoleDefinition: - """Get the specified role definition. - - :param scope: scope of the role definition. :class:`KeyVaultRoleScope` defines common broad scopes. - Specify a narrower scope as a string. Managed HSM only supports '/', or KeyVaultRoleScope.GLOBAL. - :type scope: str or KeyVaultRoleScope - :param name: the role definition's name. - :type name: str or uuid.UUID - - :returns: The fetched role definition. - :rtype: ~azure.keyvault.administration.KeyVaultRoleDefinition - """ - definition = self._client.role_definitions.get( - vault_base_url=self._vault_url, scope=scope, role_definition_name=str(name), **kwargs - ) - return KeyVaultRoleDefinition._from_generated(definition) - - @distributed_trace - def delete_role_definition( - self, scope: Union[str, KeyVaultRoleScope], name: Union[str, UUID], **kwargs: Any - ) -> None: - """Deletes a custom role definition. - - :param scope: scope of the role definition. :class:`KeyVaultRoleScope` defines common broad scopes. - Specify a narrower scope as a string. Managed HSM only supports '/', or KeyVaultRoleScope.GLOBAL. - :type scope: str or KeyVaultRoleScope - :param name: the role definition's name. - :type name: str or uuid.UUID - - :returns: None - :rtype: None - """ - try: - self._client.role_definitions.delete( - vault_base_url=self._vault_url, scope=scope, role_definition_name=str(name), **kwargs - ) - except ResourceNotFoundError: - pass - - @distributed_trace - def list_role_definitions( - self, scope: Union[str, KeyVaultRoleScope], **kwargs: Any - ) -> ItemPaged[KeyVaultRoleDefinition]: - """List all role definitions applicable at and above a scope. - - :param scope: scope of the role definitions. :class:`KeyVaultRoleScope` defines common broad scopes. - Specify a narrower scope as a string. - :type scope: str or KeyVaultRoleScope - - :returns: A paged response containing the role definitions for the specified scope. - :rtype: ~azure.core.paging.ItemPaged[~azure.keyvault.administration.KeyVaultRoleDefinition] - """ - return self._client.role_definitions.list( - vault_base_url=self._vault_url, - scope=scope, - cls=lambda result: [KeyVaultRoleDefinition._from_generated(d) for d in result], - **kwargs - ) - - def __enter__(self) -> "KeyVaultAccessControlClient": - self._client.__enter__() - return self diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_backup_client.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_backup_client.py deleted file mode 100644 index ebd9ee49290f..000000000000 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_backup_client.py +++ /dev/null @@ -1,259 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -import base64 -import functools -import pickle -from typing import Any, Optional, overload -from urllib.parse import urlparse - -from typing_extensions import Literal - -from azure.core.polling import LROPoller -from azure.core.tracing.decorator import distributed_trace - -from ._models import KeyVaultBackupResult -from ._internal import KeyVaultClientBase, parse_folder_url -from ._internal.polling import KeyVaultBackupClientPolling, KeyVaultBackupClientPollingMethod - - -def _parse_status_url(url): - parsed = urlparse(url) - job_id = parsed.path.split("/")[2] - return job_id - - -class KeyVaultBackupClient(KeyVaultClientBase): - """Performs Key Vault backup and restore operations. - - :param str vault_url: URL of the vault on which the client will operate. This is also called the vault's "DNS Name". - You should validate that this URL references a valid Key Vault or Managed HSM resource. - See https://aka.ms/azsdk/blog/vault-uri for details. - :param credential: An object which can provide an access token for the vault, such as a credential from - :mod:`azure.identity` - :type credential: ~azure.core.credentials.TokenCredential - - :keyword api_version: Version of the service API to use. Defaults to the most recent. - :paramtype api_version: ~azure.keyvault.administration.ApiVersion or str - :keyword bool verify_challenge_resource: Whether to verify the authentication challenge resource matches the Key - Vault or Managed HSM domain. Defaults to True. - """ - - @overload - def begin_backup( - self, - blob_storage_url: str, - *, - use_managed_identity: Literal[True], - continuation_token: Optional[str] = None, - **kwargs: Any, - ) -> LROPoller[KeyVaultBackupResult]: - ... - - @overload - def begin_backup( - self, - blob_storage_url: str, - *, - sas_token: str, - continuation_token: Optional[str] = None, - **kwargs: Any, - ) -> LROPoller[KeyVaultBackupResult]: - ... - - # Disabling pylint checks because they don't correctly handle overloads - @distributed_trace - def begin_backup( # pylint: disable=docstring-missing-param,docstring-keyword-should-match-keyword-only - self, blob_storage_url: str, *args: str, **kwargs: Any - ) -> LROPoller[KeyVaultBackupResult]: - """Begin a full backup of the Key Vault. - - :param str blob_storage_url: URL of the blob storage container in which the backup will be stored, for example - https://.blob.core.windows.net/backup. - - :keyword str sas_token: Optional Shared Access Signature (SAS) token to authorize access to the blob. Required - unless `use_managed_identity` is set to True. - :keyword use_managed_identity: Indicates which authentication method should be used. If set to True, Managed HSM - will use the configured user-assigned managed identity to authenticate with Azure Storage. Otherwise, a SAS - token has to be specified. - :paramtype use_managed_identity: bool - :keyword str continuation_token: A continuation token to restart polling from a saved state. - - :returns: An :class:`~azure.core.polling.LROPoller` instance. Call `result()` on this object to wait for the - operation to complete and get a :class:`KeyVaultBackupResult`. - :rtype: ~azure.core.polling.LROPoller[~azure.keyvault.administration.KeyVaultBackupResult] - - Example: - .. literalinclude:: ../tests/test_examples_administration.py - :start-after: [START begin_backup] - :end-before: [END begin_backup] - :language: python - :caption: Create a vault backup - :dedent: 8 - """ - polling_interval = kwargs.pop("_polling_interval", 5) - continuation_token = kwargs.pop("continuation_token", None) - use_managed_identity = kwargs.pop("use_managed_identity", None) - # `sas_token` was formerly a required positional parameter - try: - sas_token: Optional[str] = args[0] - except IndexError: - sas_token = kwargs.pop("sas_token", None) - sas_parameter = self._models.SASTokenParameter( - storage_resource_uri=blob_storage_url, token=sas_token, use_managed_identity=use_managed_identity - ) - - status_response = None - if continuation_token: - status_url = base64.b64decode(continuation_token.encode()).decode("ascii") - try: - job_id = _parse_status_url(status_url) - except Exception as ex: # pylint: disable=broad-except - raise ValueError( - "The provided continuation_token is malformed. A valid token can be obtained from the " - + "operation poller's continuation_token() method" - ) from ex - - pipeline_response = self._client.full_backup_status( - vault_base_url=self._vault_url, job_id=job_id, cls=lambda pipeline_response, _, __: pipeline_response - ) - if "azure-asyncoperation" not in pipeline_response.http_response.headers: - pipeline_response.http_response.headers["azure-asyncoperation"] = status_url - status_response = base64.b64encode(pickle.dumps(pipeline_response)).decode("ascii") - - return self._client.begin_full_backup( - vault_base_url=self._vault_url, - azure_storage_blob_container_uri=sas_parameter, - cls=KeyVaultBackupResult._from_generated, # pylint: disable=protected-access - continuation_token=status_response, - polling=KeyVaultBackupClientPollingMethod( - lro_algorithms=[KeyVaultBackupClientPolling()], timeout=polling_interval, **kwargs - ), - **kwargs, - ) - - @overload - def begin_restore( - self, - folder_url: str, - *, - use_managed_identity: Literal[True], - key_name: Optional[str] = None, - continuation_token: Optional[str] = None, - **kwargs: Any, - ) -> LROPoller[None]: - ... - - @overload - def begin_restore( - self, - folder_url: str, - *, - sas_token: str, - key_name: Optional[str] = None, - continuation_token: Optional[str] = None, - **kwargs: Any, - ) -> LROPoller[None]: - ... - - # Disabling pylint checks because they don't correctly handle overloads - @distributed_trace - def begin_restore( # pylint: disable=docstring-missing-param,docstring-keyword-should-match-keyword-only - self, folder_url: str, *args: str, **kwargs: Any - ) -> LROPoller[None]: - """Restore a Key Vault backup. - - This method restores either a complete Key Vault backup or when ``key_name`` has a value, a single key. - - :param str folder_url: URL of the blob holding the backup. This would be the `folder_url` of a - :class:`KeyVaultBackupResult` returned by :func:`begin_backup`, for example - https://.blob.core.windows.net/backup/mhsm-account-2020090117323313 - - :keyword str sas_token: Optional Shared Access Signature (SAS) token to authorize access to the blob. Required - unless `use_managed_identity` is set to True. - :keyword use_managed_identity: Indicates which authentication method should be used. If set to True, Managed HSM - will use the configured user-assigned managed identity to authenticate with Azure Storage. Otherwise, a SAS - token has to be specified. - :paramtype use_managed_identity: bool - :keyword str key_name: Name of a single key in the backup. When set, only this key will be restored. - :keyword str continuation_token: A continuation token to restart polling from a saved state. - - :returns: An :class:`~azure.core.polling.LROPoller` instance. Call `wait()` or `result()` on this object to wait - for the operation to complete (the return value is None in either case). - :rtype: ~azure.core.polling.LROPoller - - Examples: - .. literalinclude:: ../tests/test_examples_administration.py - :start-after: [START begin_restore] - :end-before: [END begin_restore] - :language: python - :caption: Restore a vault backup - :dedent: 8 - - .. literalinclude:: ../tests/test_examples_administration.py - :start-after: [START begin_selective_restore] - :end-before: [END begin_selective_restore] - :language: python - :caption: Restore a single key - :dedent: 8 - """ - status_response = None - polling_interval = kwargs.pop("_polling_interval", 5) - continuation_token = kwargs.pop("continuation_token", None) - key_name = kwargs.pop("key_name", None) - use_managed_identity = kwargs.pop("use_managed_identity", None) - # `sas_token` was formerly a required positional parameter - try: - sas_token: Optional[str] = args[0] - except IndexError: - sas_token = kwargs.pop("sas_token", None) - - if continuation_token: - status_url = base64.b64decode(continuation_token.encode()).decode("ascii") - try: - job_id = _parse_status_url(status_url) - except Exception as ex: # pylint: disable=broad-except - raise ValueError( - "The provided continuation_token is malformed. A valid token can be obtained from the " - + "operation poller's continuation_token() method" - ) from ex - - pipeline_response = self._client.restore_status( - vault_base_url=self._vault_url, job_id=job_id, cls=lambda pipeline_response, _, __: pipeline_response - ) - if "azure-asyncoperation" not in pipeline_response.http_response.headers: - pipeline_response.http_response.headers["azure-asyncoperation"] = status_url - status_response = base64.b64encode(pickle.dumps(pipeline_response)).decode("ascii") - - container_url, folder_name = parse_folder_url(folder_url) - sas_parameter = self._models.SASTokenParameter( - storage_resource_uri=container_url, token=sas_token, use_managed_identity=use_managed_identity - ) - polling = KeyVaultBackupClientPollingMethod( - lro_algorithms=[KeyVaultBackupClientPolling()], timeout=polling_interval, **kwargs - ) - - if key_name: - client_method = functools.partial(self._client.begin_selective_key_restore_operation, key_name=key_name) - restore_details = self._models.SelectiveKeyRestoreOperationParameters( - sas_token_parameters=sas_parameter, folder=folder_name - ) - else: - client_method = self._client.begin_full_restore_operation - restore_details = self._models.RestoreOperationParameters( - sas_token_parameters=sas_parameter, folder_to_restore=folder_name - ) - - return client_method( - vault_base_url=self._vault_url, - restore_blob_details=restore_details, - cls=lambda *_: None, # poller.result() returns None - continuation_token=status_response, - polling=polling, - **kwargs, - ) - - def __enter__(self) -> "KeyVaultBackupClient": - self._client.__enter__() - return self diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/_client.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_client.py similarity index 73% rename from sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/_client.py rename to sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_client.py index 967c30cd54ae..41b4ece69f31 100644 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/_client.py +++ b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_client.py @@ -2,41 +2,48 @@ # -------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for license information. -# Code generated by Microsoft (R) AutoRest Code Generator. +# Code generated by Microsoft (R) Python Code Generator. # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- from copy import deepcopy -from typing import Any +from typing import Any, TYPE_CHECKING +from typing_extensions import Self from azure.core import PipelineClient from azure.core.pipeline import policies from azure.core.rest import HttpRequest, HttpResponse -from . import models as _models from ._configuration import KeyVaultClientConfiguration from ._serialization import Deserializer, Serializer from .operations import KeyVaultClientOperationsMixin, RoleAssignmentsOperations, RoleDefinitionsOperations +if TYPE_CHECKING: + from azure.core.credentials import TokenCredential -class KeyVaultClient(KeyVaultClientOperationsMixin): # pylint: disable=client-accepts-api-version-keyword + +class KeyVaultClient(KeyVaultClientOperationsMixin): """The key vault client performs cryptographic key operations and vault operations against the Key Vault service. :ivar role_definitions: RoleDefinitionsOperations operations - :vartype role_definitions: azure.keyvault.v7_5.operations.RoleDefinitionsOperations + :vartype role_definitions: azure.keyvault.administration.operations.RoleDefinitionsOperations :ivar role_assignments: RoleAssignmentsOperations operations - :vartype role_assignments: azure.keyvault.v7_5.operations.RoleAssignmentsOperations - :keyword api_version: Api Version. Default value is "7.5". Note that overriding this default - value may result in unsupported behavior. + :vartype role_assignments: azure.keyvault.administration.operations.RoleAssignmentsOperations + :param vault_base_url: Required. + :type vault_base_url: str + :param credential: Credential used to authenticate requests to the service. Required. + :type credential: ~azure.core.credentials.TokenCredential + :keyword api_version: The API version to use for this operation. Default value is + "7.6-preview.2". Note that overriding this default value may result in unsupported behavior. :paramtype api_version: str :keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present. """ - def __init__(self, **kwargs: Any) -> None: # pylint: disable=missing-client-constructor-parameter-credential + def __init__(self, vault_base_url: str, credential: "TokenCredential", **kwargs: Any) -> None: _endpoint = "{vaultBaseUrl}" - self._config = KeyVaultClientConfiguration(**kwargs) + self._config = KeyVaultClientConfiguration(vault_base_url=vault_base_url, credential=credential, **kwargs) _policies = kwargs.pop("policies", None) if _policies is None: _policies = [ @@ -56,10 +63,8 @@ def __init__(self, **kwargs: Any) -> None: # pylint: disable=missing-client-con ] self._client: PipelineClient = PipelineClient(base_url=_endpoint, policies=_policies, **kwargs) - client_models = {k: v for k, v in _models._models.__dict__.items() if isinstance(v, type)} - client_models.update({k: v for k, v in _models.__dict__.items() if isinstance(v, type)}) - self._serialize = Serializer(client_models) - self._deserialize = Deserializer(client_models) + self._serialize = Serializer() + self._deserialize = Deserializer() self._serialize.client_side_validation = False self.role_definitions = RoleDefinitionsOperations( self._client, self._config, self._serialize, self._deserialize @@ -87,13 +92,19 @@ def send_request(self, request: HttpRequest, *, stream: bool = False, **kwargs: """ request_copy = deepcopy(request) - request_copy.url = self._client.format_url(request_copy.url) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + + request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments) return self._client.send_request(request_copy, stream=stream, **kwargs) # type: ignore def close(self) -> None: self._client.close() - def __enter__(self) -> "KeyVaultClient": + def __enter__(self) -> Self: self._client.__enter__() return self diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/_configuration.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_configuration.py similarity index 54% rename from sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/_configuration.py rename to sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_configuration.py index c7b4428506e3..6aad1e7d34c9 100644 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/_configuration.py +++ b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_configuration.py @@ -2,15 +2,18 @@ # -------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for license information. -# Code generated by Microsoft (R) AutoRest Code Generator. +# Code generated by Microsoft (R) Python Code Generator. # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from typing import Any +from typing import Any, TYPE_CHECKING from azure.core.pipeline import policies -VERSION = "unknown" +from ._version import VERSION + +if TYPE_CHECKING: + from azure.core.credentials import TokenCredential class KeyVaultClientConfiguration: # pylint: disable=too-many-instance-attributes @@ -19,16 +22,28 @@ class KeyVaultClientConfiguration: # pylint: disable=too-many-instance-attribut Note that all parameters used to create this instance are saved as instance attributes. - :keyword api_version: Api Version. Default value is "7.5". Note that overriding this default - value may result in unsupported behavior. + :param vault_base_url: Required. + :type vault_base_url: str + :param credential: Credential used to authenticate requests to the service. Required. + :type credential: ~azure.core.credentials.TokenCredential + :keyword api_version: The API version to use for this operation. Default value is + "7.6-preview.2". Note that overriding this default value may result in unsupported behavior. :paramtype api_version: str """ - def __init__(self, **kwargs: Any) -> None: - api_version: str = kwargs.pop("api_version", "7.5") + def __init__(self, vault_base_url: str, credential: "TokenCredential", **kwargs: Any) -> None: + api_version: str = kwargs.pop("api_version", "7.6-preview.2") + + if vault_base_url is None: + raise ValueError("Parameter 'vault_base_url' must not be None.") + if credential is None: + raise ValueError("Parameter 'credential' must not be None.") + self.vault_base_url = vault_base_url + self.credential = credential self.api_version = api_version - kwargs.setdefault("sdk_moniker", "keyvault/{}".format(VERSION)) + self.credential_scopes = kwargs.pop("credential_scopes", ["https://vault.azure.net/.default"]) + kwargs.setdefault("sdk_moniker", "keyvault-administration/{}".format(VERSION)) self.polling_interval = kwargs.get("polling_interval", 30) self._configure(**kwargs) @@ -42,3 +57,7 @@ def _configure(self, **kwargs: Any) -> None: self.redirect_policy = kwargs.get("redirect_policy") or policies.RedirectPolicy(**kwargs) self.retry_policy = kwargs.get("retry_policy") or policies.RetryPolicy(**kwargs) self.authentication_policy = kwargs.get("authentication_policy") + if self.credential and not self.authentication_policy: + self.authentication_policy = policies.BearerTokenCredentialPolicy( + self.credential, *self.credential_scopes, **kwargs + ) diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_enums.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_enums.py deleted file mode 100644 index 63e51e265e23..000000000000 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_enums.py +++ /dev/null @@ -1,93 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from enum import Enum - -from azure.core import CaseInsensitiveEnumMeta - - -class KeyVaultRoleScope(str, Enum, metaclass=CaseInsensitiveEnumMeta): - """Collection of well known role scopes. This list is not exhaustive.""" - - GLOBAL = "/" #: use this if you want role assignments to apply to everything on the resource - KEYS = "/keys" #: use this if you want role assignments to apply to all keys - - -class KeyVaultDataAction(str, Enum, metaclass=CaseInsensitiveEnumMeta): - """Supported permissions for data actions.""" - - #: Read HSM key metadata. - READ_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/read/action" - #: Update an HSM key. - WRITE_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/write/action" - #: Read deleted HSM key. - READ_DELETED_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/deletedKeys/read/action" - #: Recover deleted HSM key. - RECOVER_DELETED_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/deletedKeys/recover/action" - #: Backup HSM keys. - BACKUP_HSM_KEYS = "Microsoft.KeyVault/managedHsm/keys/backup/action" - #: Restore HSM keys. - RESTORE_HSM_KEYS = "Microsoft.KeyVault/managedHsm/keys/restore/action" - #: Delete role assignment. - DELETE_ROLE_ASSIGNMENT = "Microsoft.KeyVault/managedHsm/roleAssignments/delete/action" - #: Get role assignment. - GET_ROLE_ASSIGNMENT = "Microsoft.KeyVault/managedHsm/roleAssignments/read/action" - #: Create or update role assignment. - WRITE_ROLE_ASSIGNMENT = "Microsoft.KeyVault/managedHsm/roleAssignments/write/action" - #: Get role definition. - READ_ROLE_DEFINITION = "Microsoft.KeyVault/managedHsm/roleDefinitions/read/action" - #: Create or update role definition. - WRITE_ROLE_DEFINITION = "Microsoft.KeyVault/managedHsm/roleDefinitions/write/action" - #: Delete role definition. - DELETE_ROLE_DEFINITION = "Microsoft.KeyVault/managedHsm/roleDefinitions/delete/action" - #: Encrypt using an HSM key. - ENCRYPT_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/encrypt/action" - #: Decrypt using an HSM key. - DECRYPT_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/decrypt/action" - #: Wrap using an HSM key. - WRAP_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/wrap/action" - #: Unwrap using an HSM key. - UNWRAP_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/unwrap/action" - #: Sign using an HSM key. - SIGN_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/sign/action" - #: Verify using an HSM key. - VERIFY_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/verify/action" - #: Create an HSM key. - CREATE_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/create" - #: Delete an HSM key. - DELETE_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/delete" - #: Export an HSM key. - EXPORT_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/export/action" - #: Release an HSM key using Secure Key Release. - RELEASE_KEY = "Microsoft.KeyVault/managedHsm/keys/release/action" - #: Import an HSM key. - IMPORT_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/import/action" - #: Purge a deleted HSM key. - PURGE_DELETED_HSM_KEY = "Microsoft.KeyVault/managedHsm/keys/deletedKeys/delete" - #: Download an HSM security domain. - DOWNLOAD_HSM_SECURITY_DOMAIN = "Microsoft.KeyVault/managedHsm/securitydomain/download/action" - #: Check status of HSM security domain download. - DOWNLOAD_HSM_SECURITY_DOMAIN_STATUS = "Microsoft.KeyVault/managedHsm/securitydomain/download/read" - #: Upload an HSM security domain. - UPLOAD_HSM_SECURITY_DOMAIN = "Microsoft.KeyVault/managedHsm/securitydomain/upload/action" - #: Check the status of the HSM security domain exchange file. - READ_HSM_SECURITY_DOMAIN_STATUS = "Microsoft.KeyVault/managedHsm/securitydomain/upload/read" - #: Download an HSM security domain transfer key. - READ_HSM_SECURITY_DOMAIN_TRANSFER_KEY = "Microsoft.KeyVault/managedHsm/securitydomain/transferkey/read" - #: Start an HSM backup. - START_HSM_BACKUP = "Microsoft.KeyVault/managedHsm/backup/start/action" - #: Start an HSM restore. - START_HSM_RESTORE = "Microsoft.KeyVault/managedHsm/restore/start/action" - #: Read an HSM backup status. - READ_HSM_BACKUP_STATUS = "Microsoft.KeyVault/managedHsm/backup/status/action" - #: Read an HSM restore status. - READ_HSM_RESTORE_STATUS = "Microsoft.KeyVault/managedHsm/restore/status/action" - #: Generate random numbers. - RANDOM_NUMBERS_GENERATE = "Microsoft.KeyVault/managedHsm/rng/action" - - -class KeyVaultSettingType(str, Enum, metaclass=CaseInsensitiveEnumMeta): - """The type specifier of the setting value.""" - - BOOLEAN = "boolean" diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/__init__.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/__init__.py deleted file mode 100644 index 1e535724e551..000000000000 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -# coding=utf-8 -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for license information. -# Code generated by Microsoft (R) AutoRest Code Generator. -# Changes may cause incorrect behavior and will be lost if the code is regenerated. -# -------------------------------------------------------------------------- - -from ._client import KeyVaultClient - -try: - from ._patch import __all__ as _patch_all - from ._patch import * # pylint: disable=unused-wildcard-import -except ImportError: - _patch_all = [] -from ._patch import patch_sdk as _patch_sdk - -__all__ = [ - "KeyVaultClient", -] -__all__.extend([p for p in _patch_all if p not in __all__]) - -_patch_sdk() diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/aio/__init__.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/aio/__init__.py deleted file mode 100644 index 1e535724e551..000000000000 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/aio/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -# coding=utf-8 -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for license information. -# Code generated by Microsoft (R) AutoRest Code Generator. -# Changes may cause incorrect behavior and will be lost if the code is regenerated. -# -------------------------------------------------------------------------- - -from ._client import KeyVaultClient - -try: - from ._patch import __all__ as _patch_all - from ._patch import * # pylint: disable=unused-wildcard-import -except ImportError: - _patch_all = [] -from ._patch import patch_sdk as _patch_sdk - -__all__ = [ - "KeyVaultClient", -] -__all__.extend([p for p in _patch_all if p not in __all__]) - -_patch_sdk() diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/models/__init__.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/models/__init__.py deleted file mode 100644 index de229e347c31..000000000000 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/models/__init__.py +++ /dev/null @@ -1,71 +0,0 @@ -# coding=utf-8 -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for license information. -# Code generated by Microsoft (R) AutoRest Code Generator. -# Changes may cause incorrect behavior and will be lost if the code is regenerated. -# -------------------------------------------------------------------------- - -from ._models import Attributes -from ._models import Error -from ._models import FullBackupOperation -from ._models import KeyVaultError -from ._models import Permission -from ._models import RestoreOperation -from ._models import RestoreOperationParameters -from ._models import RoleAssignment -from ._models import RoleAssignmentCreateParameters -from ._models import RoleAssignmentFilter -from ._models import RoleAssignmentProperties -from ._models import RoleAssignmentPropertiesWithScope -from ._models import RoleDefinition -from ._models import RoleDefinitionCreateParameters -from ._models import RoleDefinitionFilter -from ._models import RoleDefinitionProperties -from ._models import SASTokenParameter -from ._models import SelectiveKeyRestoreOperation -from ._models import SelectiveKeyRestoreOperationParameters -from ._models import Setting -from ._models import SettingsListResult -from ._models import UpdateSettingRequest - -from ._enums import DataAction -from ._enums import RoleDefinitionType -from ._enums import RoleScope -from ._enums import RoleType -from ._enums import SettingTypeEnum -from ._patch import __all__ as _patch_all -from ._patch import * # pylint: disable=unused-wildcard-import -from ._patch import patch_sdk as _patch_sdk - -__all__ = [ - "Attributes", - "Error", - "FullBackupOperation", - "KeyVaultError", - "Permission", - "RestoreOperation", - "RestoreOperationParameters", - "RoleAssignment", - "RoleAssignmentCreateParameters", - "RoleAssignmentFilter", - "RoleAssignmentProperties", - "RoleAssignmentPropertiesWithScope", - "RoleDefinition", - "RoleDefinitionCreateParameters", - "RoleDefinitionFilter", - "RoleDefinitionProperties", - "SASTokenParameter", - "SelectiveKeyRestoreOperation", - "SelectiveKeyRestoreOperationParameters", - "Setting", - "SettingsListResult", - "UpdateSettingRequest", - "DataAction", - "RoleDefinitionType", - "RoleScope", - "RoleType", - "SettingTypeEnum", -] -__all__.extend([p for p in _patch_all if p not in __all__]) -_patch_sdk() diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/models/_models.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/models/_models.py deleted file mode 100644 index 1945baf797ad..000000000000 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/models/_models.py +++ /dev/null @@ -1,935 +0,0 @@ -# coding=utf-8 -# pylint: disable=too-many-lines -# -------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See License.txt in the project root for license information. -# Code generated by Microsoft (R) AutoRest Code Generator. -# Changes may cause incorrect behavior and will be lost if the code is regenerated. -# -------------------------------------------------------------------------- - -import datetime -from typing import Any, List, Optional, TYPE_CHECKING, Union - -from .. import _serialization - -if TYPE_CHECKING: - # pylint: disable=unused-import,ungrouped-imports - from .. import models as _models - - -class Attributes(_serialization.Model): - """The object attributes managed by the KeyVault service. - - Variables are only populated by the server, and will be ignored when sending a request. - - :ivar enabled: Determines whether the object is enabled. - :vartype enabled: bool - :ivar not_before: Not before date in UTC. - :vartype not_before: ~datetime.datetime - :ivar expires: Expiry date in UTC. - :vartype expires: ~datetime.datetime - :ivar created: Creation time in UTC. - :vartype created: ~datetime.datetime - :ivar updated: Last updated time in UTC. - :vartype updated: ~datetime.datetime - """ - - _validation = { - "created": {"readonly": True}, - "updated": {"readonly": True}, - } - - _attribute_map = { - "enabled": {"key": "enabled", "type": "bool"}, - "not_before": {"key": "nbf", "type": "unix-time"}, - "expires": {"key": "exp", "type": "unix-time"}, - "created": {"key": "created", "type": "unix-time"}, - "updated": {"key": "updated", "type": "unix-time"}, - } - - def __init__( - self, - *, - enabled: Optional[bool] = None, - not_before: Optional[datetime.datetime] = None, - expires: Optional[datetime.datetime] = None, - **kwargs: Any - ) -> None: - """ - :keyword enabled: Determines whether the object is enabled. - :paramtype enabled: bool - :keyword not_before: Not before date in UTC. - :paramtype not_before: ~datetime.datetime - :keyword expires: Expiry date in UTC. - :paramtype expires: ~datetime.datetime - """ - super().__init__(**kwargs) - self.enabled = enabled - self.not_before = not_before - self.expires = expires - self.created = None - self.updated = None - - -class Error(_serialization.Model): - """The key vault server error. - - Variables are only populated by the server, and will be ignored when sending a request. - - :ivar code: The error code. - :vartype code: str - :ivar message: The error message. - :vartype message: str - :ivar inner_error: The key vault server error. - :vartype inner_error: ~azure.keyvault.v7_5.models.Error - """ - - _validation = { - "code": {"readonly": True}, - "message": {"readonly": True}, - "inner_error": {"readonly": True}, - } - - _attribute_map = { - "code": {"key": "code", "type": "str"}, - "message": {"key": "message", "type": "str"}, - "inner_error": {"key": "innererror", "type": "Error"}, - } - - def __init__(self, **kwargs: Any) -> None: - """ """ - super().__init__(**kwargs) - self.code = None - self.message = None - self.inner_error = None - - -class FullBackupOperation(_serialization.Model): - """Full backup operation. - - :ivar status: Status of the backup operation. - :vartype status: str - :ivar status_details: The status details of backup operation. - :vartype status_details: str - :ivar error: Error encountered, if any, during the full backup operation. - :vartype error: ~azure.keyvault.v7_5.models.Error - :ivar start_time: The start time of the backup operation in UTC. - :vartype start_time: ~datetime.datetime - :ivar end_time: The end time of the backup operation in UTC. - :vartype end_time: ~datetime.datetime - :ivar job_id: Identifier for the full backup operation. - :vartype job_id: str - :ivar azure_storage_blob_container_uri: The Azure blob storage container Uri which contains the - full backup. - :vartype azure_storage_blob_container_uri: str - """ - - _attribute_map = { - "status": {"key": "status", "type": "str"}, - "status_details": {"key": "statusDetails", "type": "str"}, - "error": {"key": "error", "type": "Error"}, - "start_time": {"key": "startTime", "type": "unix-time"}, - "end_time": {"key": "endTime", "type": "unix-time"}, - "job_id": {"key": "jobId", "type": "str"}, - "azure_storage_blob_container_uri": {"key": "azureStorageBlobContainerUri", "type": "str"}, - } - - def __init__( - self, - *, - status: Optional[str] = None, - status_details: Optional[str] = None, - error: Optional["_models.Error"] = None, - start_time: Optional[datetime.datetime] = None, - end_time: Optional[datetime.datetime] = None, - job_id: Optional[str] = None, - azure_storage_blob_container_uri: Optional[str] = None, - **kwargs: Any - ) -> None: - """ - :keyword status: Status of the backup operation. - :paramtype status: str - :keyword status_details: The status details of backup operation. - :paramtype status_details: str - :keyword error: Error encountered, if any, during the full backup operation. - :paramtype error: ~azure.keyvault.v7_5.models.Error - :keyword start_time: The start time of the backup operation in UTC. - :paramtype start_time: ~datetime.datetime - :keyword end_time: The end time of the backup operation in UTC. - :paramtype end_time: ~datetime.datetime - :keyword job_id: Identifier for the full backup operation. - :paramtype job_id: str - :keyword azure_storage_blob_container_uri: The Azure blob storage container Uri which contains - the full backup. - :paramtype azure_storage_blob_container_uri: str - """ - super().__init__(**kwargs) - self.status = status - self.status_details = status_details - self.error = error - self.start_time = start_time - self.end_time = end_time - self.job_id = job_id - self.azure_storage_blob_container_uri = azure_storage_blob_container_uri - - -class KeyVaultError(_serialization.Model): - """The key vault error exception. - - Variables are only populated by the server, and will be ignored when sending a request. - - :ivar error: The key vault server error. - :vartype error: ~azure.keyvault.v7_5.models.Error - """ - - _validation = { - "error": {"readonly": True}, - } - - _attribute_map = { - "error": {"key": "error", "type": "Error"}, - } - - def __init__(self, **kwargs: Any) -> None: - """ """ - super().__init__(**kwargs) - self.error = None - - -class Permission(_serialization.Model): - """Role definition permissions. - - :ivar actions: Action permissions that are granted. - :vartype actions: list[str] - :ivar not_actions: Action permissions that are excluded but not denied. They may be granted by - other role definitions assigned to a principal. - :vartype not_actions: list[str] - :ivar data_actions: Data action permissions that are granted. - :vartype data_actions: list[str or ~azure.keyvault.v7_5.models.DataAction] - :ivar not_data_actions: Data action permissions that are excluded but not denied. They may be - granted by other role definitions assigned to a principal. - :vartype not_data_actions: list[str or ~azure.keyvault.v7_5.models.DataAction] - """ - - _attribute_map = { - "actions": {"key": "actions", "type": "[str]"}, - "not_actions": {"key": "notActions", "type": "[str]"}, - "data_actions": {"key": "dataActions", "type": "[str]"}, - "not_data_actions": {"key": "notDataActions", "type": "[str]"}, - } - - def __init__( - self, - *, - actions: Optional[List[str]] = None, - not_actions: Optional[List[str]] = None, - data_actions: Optional[List[Union[str, "_models.DataAction"]]] = None, - not_data_actions: Optional[List[Union[str, "_models.DataAction"]]] = None, - **kwargs: Any - ) -> None: - """ - :keyword actions: Action permissions that are granted. - :paramtype actions: list[str] - :keyword not_actions: Action permissions that are excluded but not denied. They may be granted - by other role definitions assigned to a principal. - :paramtype not_actions: list[str] - :keyword data_actions: Data action permissions that are granted. - :paramtype data_actions: list[str or ~azure.keyvault.v7_5.models.DataAction] - :keyword not_data_actions: Data action permissions that are excluded but not denied. They may - be granted by other role definitions assigned to a principal. - :paramtype not_data_actions: list[str or ~azure.keyvault.v7_5.models.DataAction] - """ - super().__init__(**kwargs) - self.actions = actions - self.not_actions = not_actions - self.data_actions = data_actions - self.not_data_actions = not_data_actions - - -class RestoreOperation(_serialization.Model): - """Restore operation. - - :ivar status: Status of the restore operation. - :vartype status: str - :ivar status_details: The status details of restore operation. - :vartype status_details: str - :ivar error: Error encountered, if any, during the restore operation. - :vartype error: ~azure.keyvault.v7_5.models.Error - :ivar job_id: Identifier for the restore operation. - :vartype job_id: str - :ivar start_time: The start time of the restore operation. - :vartype start_time: ~datetime.datetime - :ivar end_time: The end time of the restore operation. - :vartype end_time: ~datetime.datetime - """ - - _attribute_map = { - "status": {"key": "status", "type": "str"}, - "status_details": {"key": "statusDetails", "type": "str"}, - "error": {"key": "error", "type": "Error"}, - "job_id": {"key": "jobId", "type": "str"}, - "start_time": {"key": "startTime", "type": "unix-time"}, - "end_time": {"key": "endTime", "type": "unix-time"}, - } - - def __init__( - self, - *, - status: Optional[str] = None, - status_details: Optional[str] = None, - error: Optional["_models.Error"] = None, - job_id: Optional[str] = None, - start_time: Optional[datetime.datetime] = None, - end_time: Optional[datetime.datetime] = None, - **kwargs: Any - ) -> None: - """ - :keyword status: Status of the restore operation. - :paramtype status: str - :keyword status_details: The status details of restore operation. - :paramtype status_details: str - :keyword error: Error encountered, if any, during the restore operation. - :paramtype error: ~azure.keyvault.v7_5.models.Error - :keyword job_id: Identifier for the restore operation. - :paramtype job_id: str - :keyword start_time: The start time of the restore operation. - :paramtype start_time: ~datetime.datetime - :keyword end_time: The end time of the restore operation. - :paramtype end_time: ~datetime.datetime - """ - super().__init__(**kwargs) - self.status = status - self.status_details = status_details - self.error = error - self.job_id = job_id - self.start_time = start_time - self.end_time = end_time - - -class RestoreOperationParameters(_serialization.Model): - """RestoreOperationParameters. - - All required parameters must be populated in order to send to server. - - :ivar sas_token_parameters: Required. - :vartype sas_token_parameters: ~azure.keyvault.v7_5.models.SASTokenParameter - :ivar folder_to_restore: The Folder name of the blob where the previous successful full backup - was stored. Required. - :vartype folder_to_restore: str - """ - - _validation = { - "sas_token_parameters": {"required": True}, - "folder_to_restore": {"required": True}, - } - - _attribute_map = { - "sas_token_parameters": {"key": "sasTokenParameters", "type": "SASTokenParameter"}, - "folder_to_restore": {"key": "folderToRestore", "type": "str"}, - } - - def __init__( - self, *, sas_token_parameters: "_models.SASTokenParameter", folder_to_restore: str, **kwargs: Any - ) -> None: - """ - :keyword sas_token_parameters: Required. - :paramtype sas_token_parameters: ~azure.keyvault.v7_5.models.SASTokenParameter - :keyword folder_to_restore: The Folder name of the blob where the previous successful full - backup was stored. Required. - :paramtype folder_to_restore: str - """ - super().__init__(**kwargs) - self.sas_token_parameters = sas_token_parameters - self.folder_to_restore = folder_to_restore - - -class RoleAssignment(_serialization.Model): - """Role Assignments. - - Variables are only populated by the server, and will be ignored when sending a request. - - :ivar id: The role assignment ID. - :vartype id: str - :ivar name: The role assignment name. - :vartype name: str - :ivar type: The role assignment type. - :vartype type: str - :ivar properties: Role assignment properties. - :vartype properties: ~azure.keyvault.v7_5.models.RoleAssignmentPropertiesWithScope - """ - - _validation = { - "id": {"readonly": True}, - "name": {"readonly": True}, - "type": {"readonly": True}, - } - - _attribute_map = { - "id": {"key": "id", "type": "str"}, - "name": {"key": "name", "type": "str"}, - "type": {"key": "type", "type": "str"}, - "properties": {"key": "properties", "type": "RoleAssignmentPropertiesWithScope"}, - } - - def __init__( - self, *, properties: Optional["_models.RoleAssignmentPropertiesWithScope"] = None, **kwargs: Any - ) -> None: - """ - :keyword properties: Role assignment properties. - :paramtype properties: ~azure.keyvault.v7_5.models.RoleAssignmentPropertiesWithScope - """ - super().__init__(**kwargs) - self.id = None - self.name = None - self.type = None - self.properties = properties - - -class RoleAssignmentCreateParameters(_serialization.Model): - """Role assignment create parameters. - - All required parameters must be populated in order to send to server. - - :ivar properties: Role assignment properties. Required. - :vartype properties: ~azure.keyvault.v7_5.models.RoleAssignmentProperties - """ - - _validation = { - "properties": {"required": True}, - } - - _attribute_map = { - "properties": {"key": "properties", "type": "RoleAssignmentProperties"}, - } - - def __init__(self, *, properties: "_models.RoleAssignmentProperties", **kwargs: Any) -> None: - """ - :keyword properties: Role assignment properties. Required. - :paramtype properties: ~azure.keyvault.v7_5.models.RoleAssignmentProperties - """ - super().__init__(**kwargs) - self.properties = properties - - -class RoleAssignmentFilter(_serialization.Model): - """Role Assignments filter. - - :ivar principal_id: Returns role assignment of the specific principal. - :vartype principal_id: str - """ - - _attribute_map = { - "principal_id": {"key": "principalId", "type": "str"}, - } - - def __init__(self, *, principal_id: Optional[str] = None, **kwargs: Any) -> None: - """ - :keyword principal_id: Returns role assignment of the specific principal. - :paramtype principal_id: str - """ - super().__init__(**kwargs) - self.principal_id = principal_id - - -class RoleAssignmentListResult(_serialization.Model): - """Role assignment list operation result. - - :ivar value: Role assignment list. - :vartype value: list[~azure.keyvault.v7_5.models.RoleAssignment] - :ivar next_link: The URL to use for getting the next set of results. - :vartype next_link: str - """ - - _attribute_map = { - "value": {"key": "value", "type": "[RoleAssignment]"}, - "next_link": {"key": "nextLink", "type": "str"}, - } - - def __init__( - self, *, value: Optional[List["_models.RoleAssignment"]] = None, next_link: Optional[str] = None, **kwargs: Any - ) -> None: - """ - :keyword value: Role assignment list. - :paramtype value: list[~azure.keyvault.v7_5.models.RoleAssignment] - :keyword next_link: The URL to use for getting the next set of results. - :paramtype next_link: str - """ - super().__init__(**kwargs) - self.value = value - self.next_link = next_link - - -class RoleAssignmentProperties(_serialization.Model): - """Role assignment properties. - - All required parameters must be populated in order to send to server. - - :ivar role_definition_id: The role definition ID used in the role assignment. Required. - :vartype role_definition_id: str - :ivar principal_id: The principal ID assigned to the role. This maps to the ID inside the - Active Directory. It can point to a user, service principal, or security group. Required. - :vartype principal_id: str - """ - - _validation = { - "role_definition_id": {"required": True}, - "principal_id": {"required": True}, - } - - _attribute_map = { - "role_definition_id": {"key": "roleDefinitionId", "type": "str"}, - "principal_id": {"key": "principalId", "type": "str"}, - } - - def __init__(self, *, role_definition_id: str, principal_id: str, **kwargs: Any) -> None: - """ - :keyword role_definition_id: The role definition ID used in the role assignment. Required. - :paramtype role_definition_id: str - :keyword principal_id: The principal ID assigned to the role. This maps to the ID inside the - Active Directory. It can point to a user, service principal, or security group. Required. - :paramtype principal_id: str - """ - super().__init__(**kwargs) - self.role_definition_id = role_definition_id - self.principal_id = principal_id - - -class RoleAssignmentPropertiesWithScope(_serialization.Model): - """Role assignment properties with scope. - - :ivar scope: The role scope. Known values are: "/" and "/keys". - :vartype scope: str or ~azure.keyvault.v7_5.models.RoleScope - :ivar role_definition_id: The role definition ID. - :vartype role_definition_id: str - :ivar principal_id: The principal ID. - :vartype principal_id: str - """ - - _attribute_map = { - "scope": {"key": "scope", "type": "str"}, - "role_definition_id": {"key": "roleDefinitionId", "type": "str"}, - "principal_id": {"key": "principalId", "type": "str"}, - } - - def __init__( - self, - *, - scope: Optional[Union[str, "_models.RoleScope"]] = None, - role_definition_id: Optional[str] = None, - principal_id: Optional[str] = None, - **kwargs: Any - ) -> None: - """ - :keyword scope: The role scope. Known values are: "/" and "/keys". - :paramtype scope: str or ~azure.keyvault.v7_5.models.RoleScope - :keyword role_definition_id: The role definition ID. - :paramtype role_definition_id: str - :keyword principal_id: The principal ID. - :paramtype principal_id: str - """ - super().__init__(**kwargs) - self.scope = scope - self.role_definition_id = role_definition_id - self.principal_id = principal_id - - -class RoleDefinition(_serialization.Model): - """Role definition. - - Variables are only populated by the server, and will be ignored when sending a request. - - :ivar id: The role definition ID. - :vartype id: str - :ivar name: The role definition name. - :vartype name: str - :ivar type: The role definition type. "Microsoft.Authorization/roleDefinitions" - :vartype type: str or ~azure.keyvault.v7_5.models.RoleDefinitionType - :ivar properties: Role definition properties. - :vartype properties: ~azure.keyvault.v7_5.models.RoleDefinitionProperties - """ - - _validation = { - "id": {"readonly": True}, - "name": {"readonly": True}, - "type": {"readonly": True}, - } - - _attribute_map = { - "id": {"key": "id", "type": "str"}, - "name": {"key": "name", "type": "str"}, - "type": {"key": "type", "type": "str"}, - "properties": {"key": "properties", "type": "RoleDefinitionProperties"}, - } - - def __init__(self, *, properties: Optional["_models.RoleDefinitionProperties"] = None, **kwargs: Any) -> None: - """ - :keyword properties: Role definition properties. - :paramtype properties: ~azure.keyvault.v7_5.models.RoleDefinitionProperties - """ - super().__init__(**kwargs) - self.id = None - self.name = None - self.type = None - self.properties = properties - - -class RoleDefinitionCreateParameters(_serialization.Model): - """Role definition create parameters. - - All required parameters must be populated in order to send to server. - - :ivar properties: Role definition properties. Required. - :vartype properties: ~azure.keyvault.v7_5.models.RoleDefinitionProperties - """ - - _validation = { - "properties": {"required": True}, - } - - _attribute_map = { - "properties": {"key": "properties", "type": "RoleDefinitionProperties"}, - } - - def __init__(self, *, properties: "_models.RoleDefinitionProperties", **kwargs: Any) -> None: - """ - :keyword properties: Role definition properties. Required. - :paramtype properties: ~azure.keyvault.v7_5.models.RoleDefinitionProperties - """ - super().__init__(**kwargs) - self.properties = properties - - -class RoleDefinitionFilter(_serialization.Model): - """Role Definitions filter. - - :ivar role_name: Returns role definition with the specific name. - :vartype role_name: str - """ - - _attribute_map = { - "role_name": {"key": "roleName", "type": "str"}, - } - - def __init__(self, *, role_name: Optional[str] = None, **kwargs: Any) -> None: - """ - :keyword role_name: Returns role definition with the specific name. - :paramtype role_name: str - """ - super().__init__(**kwargs) - self.role_name = role_name - - -class RoleDefinitionListResult(_serialization.Model): - """Role definition list operation result. - - :ivar value: Role definition list. - :vartype value: list[~azure.keyvault.v7_5.models.RoleDefinition] - :ivar next_link: The URL to use for getting the next set of results. - :vartype next_link: str - """ - - _attribute_map = { - "value": {"key": "value", "type": "[RoleDefinition]"}, - "next_link": {"key": "nextLink", "type": "str"}, - } - - def __init__( - self, *, value: Optional[List["_models.RoleDefinition"]] = None, next_link: Optional[str] = None, **kwargs: Any - ) -> None: - """ - :keyword value: Role definition list. - :paramtype value: list[~azure.keyvault.v7_5.models.RoleDefinition] - :keyword next_link: The URL to use for getting the next set of results. - :paramtype next_link: str - """ - super().__init__(**kwargs) - self.value = value - self.next_link = next_link - - -class RoleDefinitionProperties(_serialization.Model): - """Role definition properties. - - :ivar role_name: The role name. - :vartype role_name: str - :ivar description: The role definition description. - :vartype description: str - :ivar role_type: The role type. Known values are: "AKVBuiltInRole" and "CustomRole". - :vartype role_type: str or ~azure.keyvault.v7_5.models.RoleType - :ivar permissions: Role definition permissions. - :vartype permissions: list[~azure.keyvault.v7_5.models.Permission] - :ivar assignable_scopes: Role definition assignable scopes. - :vartype assignable_scopes: list[str or ~azure.keyvault.v7_5.models.RoleScope] - """ - - _attribute_map = { - "role_name": {"key": "roleName", "type": "str"}, - "description": {"key": "description", "type": "str"}, - "role_type": {"key": "type", "type": "str"}, - "permissions": {"key": "permissions", "type": "[Permission]"}, - "assignable_scopes": {"key": "assignableScopes", "type": "[str]"}, - } - - def __init__( - self, - *, - role_name: Optional[str] = None, - description: Optional[str] = None, - role_type: Optional[Union[str, "_models.RoleType"]] = None, - permissions: Optional[List["_models.Permission"]] = None, - assignable_scopes: Optional[List[Union[str, "_models.RoleScope"]]] = None, - **kwargs: Any - ) -> None: - """ - :keyword role_name: The role name. - :paramtype role_name: str - :keyword description: The role definition description. - :paramtype description: str - :keyword role_type: The role type. Known values are: "AKVBuiltInRole" and "CustomRole". - :paramtype role_type: str or ~azure.keyvault.v7_5.models.RoleType - :keyword permissions: Role definition permissions. - :paramtype permissions: list[~azure.keyvault.v7_5.models.Permission] - :keyword assignable_scopes: Role definition assignable scopes. - :paramtype assignable_scopes: list[str or ~azure.keyvault.v7_5.models.RoleScope] - """ - super().__init__(**kwargs) - self.role_name = role_name - self.description = description - self.role_type = role_type - self.permissions = permissions - self.assignable_scopes = assignable_scopes - - -class SASTokenParameter(_serialization.Model): - """SASTokenParameter. - - All required parameters must be populated in order to send to server. - - :ivar storage_resource_uri: Azure Blob storage container Uri. Required. - :vartype storage_resource_uri: str - :ivar token: The SAS token pointing to an Azure Blob storage container. - :vartype token: str - :ivar use_managed_identity: Indicates which authentication method should be used. If set to - true, Managed HSM will use the configured user-assigned managed identity to authenticate with - Azure Storage. Otherwise, a SAS token has to be specified. - :vartype use_managed_identity: bool - """ - - _validation = { - "storage_resource_uri": {"required": True}, - } - - _attribute_map = { - "storage_resource_uri": {"key": "storageResourceUri", "type": "str"}, - "token": {"key": "token", "type": "str"}, - "use_managed_identity": {"key": "useManagedIdentity", "type": "bool"}, - } - - def __init__( - self, - *, - storage_resource_uri: str, - token: Optional[str] = None, - use_managed_identity: bool = False, - **kwargs: Any - ) -> None: - """ - :keyword storage_resource_uri: Azure Blob storage container Uri. Required. - :paramtype storage_resource_uri: str - :keyword token: The SAS token pointing to an Azure Blob storage container. - :paramtype token: str - :keyword use_managed_identity: Indicates which authentication method should be used. If set to - true, Managed HSM will use the configured user-assigned managed identity to authenticate with - Azure Storage. Otherwise, a SAS token has to be specified. - :paramtype use_managed_identity: bool - """ - super().__init__(**kwargs) - self.storage_resource_uri = storage_resource_uri - self.token = token - self.use_managed_identity = use_managed_identity - - -class SelectiveKeyRestoreOperation(_serialization.Model): - """Selective Key Restore operation. - - :ivar status: Status of the restore operation. - :vartype status: str - :ivar status_details: The status details of restore operation. - :vartype status_details: str - :ivar error: Error encountered, if any, during the selective key restore operation. - :vartype error: ~azure.keyvault.v7_5.models.Error - :ivar job_id: Identifier for the selective key restore operation. - :vartype job_id: str - :ivar start_time: The start time of the restore operation. - :vartype start_time: ~datetime.datetime - :ivar end_time: The end time of the restore operation. - :vartype end_time: ~datetime.datetime - """ - - _attribute_map = { - "status": {"key": "status", "type": "str"}, - "status_details": {"key": "statusDetails", "type": "str"}, - "error": {"key": "error", "type": "Error"}, - "job_id": {"key": "jobId", "type": "str"}, - "start_time": {"key": "startTime", "type": "unix-time"}, - "end_time": {"key": "endTime", "type": "unix-time"}, - } - - def __init__( - self, - *, - status: Optional[str] = None, - status_details: Optional[str] = None, - error: Optional["_models.Error"] = None, - job_id: Optional[str] = None, - start_time: Optional[datetime.datetime] = None, - end_time: Optional[datetime.datetime] = None, - **kwargs: Any - ) -> None: - """ - :keyword status: Status of the restore operation. - :paramtype status: str - :keyword status_details: The status details of restore operation. - :paramtype status_details: str - :keyword error: Error encountered, if any, during the selective key restore operation. - :paramtype error: ~azure.keyvault.v7_5.models.Error - :keyword job_id: Identifier for the selective key restore operation. - :paramtype job_id: str - :keyword start_time: The start time of the restore operation. - :paramtype start_time: ~datetime.datetime - :keyword end_time: The end time of the restore operation. - :paramtype end_time: ~datetime.datetime - """ - super().__init__(**kwargs) - self.status = status - self.status_details = status_details - self.error = error - self.job_id = job_id - self.start_time = start_time - self.end_time = end_time - - -class SelectiveKeyRestoreOperationParameters(_serialization.Model): - """SelectiveKeyRestoreOperationParameters. - - All required parameters must be populated in order to send to server. - - :ivar sas_token_parameters: Required. - :vartype sas_token_parameters: ~azure.keyvault.v7_5.models.SASTokenParameter - :ivar folder: The Folder name of the blob where the previous successful full backup was stored. - Required. - :vartype folder: str - """ - - _validation = { - "sas_token_parameters": {"required": True}, - "folder": {"required": True}, - } - - _attribute_map = { - "sas_token_parameters": {"key": "sasTokenParameters", "type": "SASTokenParameter"}, - "folder": {"key": "folder", "type": "str"}, - } - - def __init__(self, *, sas_token_parameters: "_models.SASTokenParameter", folder: str, **kwargs: Any) -> None: - """ - :keyword sas_token_parameters: Required. - :paramtype sas_token_parameters: ~azure.keyvault.v7_5.models.SASTokenParameter - :keyword folder: The Folder name of the blob where the previous successful full backup was - stored. Required. - :paramtype folder: str - """ - super().__init__(**kwargs) - self.sas_token_parameters = sas_token_parameters - self.folder = folder - - -class Setting(_serialization.Model): - """Setting. - - All required parameters must be populated in order to send to server. - - :ivar name: The account setting to be updated. Required. - :vartype name: str - :ivar value: The value of the pool setting. Required. - :vartype value: str - :ivar type: The type specifier of the value. "boolean" - :vartype type: str or ~azure.keyvault.v7_5.models.SettingTypeEnum - """ - - _validation = { - "name": {"required": True}, - "value": {"required": True}, - } - - _attribute_map = { - "name": {"key": "name", "type": "str"}, - "value": {"key": "value", "type": "str"}, - "type": {"key": "type", "type": "str"}, - } - - def __init__( - self, *, name: str, value: str, type: Optional[Union[str, "_models.SettingTypeEnum"]] = None, **kwargs: Any - ) -> None: - """ - :keyword name: The account setting to be updated. Required. - :paramtype name: str - :keyword value: The value of the pool setting. Required. - :paramtype value: str - :keyword type: The type specifier of the value. "boolean" - :paramtype type: str or ~azure.keyvault.v7_5.models.SettingTypeEnum - """ - super().__init__(**kwargs) - self.name = name - self.value = value - self.type = type - - -class SettingsListResult(_serialization.Model): - """The settings list result. - - Variables are only populated by the server, and will be ignored when sending a request. - - :ivar settings: A response message containing a list of account settings with their associated - value. - :vartype settings: list[~azure.keyvault.v7_5.models.Setting] - """ - - _validation = { - "settings": {"readonly": True}, - } - - _attribute_map = { - "settings": {"key": "settings", "type": "[Setting]"}, - } - - def __init__(self, **kwargs: Any) -> None: - """ """ - super().__init__(**kwargs) - self.settings = None - - -class UpdateSettingRequest(_serialization.Model): - """The update settings request object. - - All required parameters must be populated in order to send to server. - - :ivar value: The value of the pool setting. Required. - :vartype value: str - """ - - _validation = { - "value": {"required": True}, - } - - _attribute_map = { - "value": {"key": "value", "type": "str"}, - } - - def __init__(self, *, value: str, **kwargs: Any) -> None: - """ - :keyword value: The value of the pool setting. Required. - :paramtype value: str - """ - super().__init__(**kwargs) - self.value = value diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/py.typed b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/py.typed deleted file mode 100644 index e5aff4f83af8..000000000000 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/py.typed +++ /dev/null @@ -1 +0,0 @@ -# Marker file for PEP 561. \ No newline at end of file diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/__init__.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/__init__.py deleted file mode 100644 index f8b42fa3f5c4..000000000000 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/__init__.py +++ /dev/null @@ -1,90 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from collections import namedtuple - -from urllib.parse import urlparse - -from .challenge_auth_policy import ChallengeAuthPolicy -from .client_base import KeyVaultClientBase -from .http_challenge import HttpChallenge -from . import http_challenge_cache - -HttpChallengeCache = http_challenge_cache # to avoid aliasing pylint error (C4745) - -__all__ = [ - "ChallengeAuthPolicy", - "HttpChallenge", - "HttpChallengeCache", - "KeyVaultClientBase", -] - -_VaultId = namedtuple("_VaultId", ["vault_url", "collection", "name", "version"]) - - -def parse_vault_id(url: str) -> "_VaultId": - try: - parsed_uri = urlparse(url) - except Exception as exc: # pylint: disable=broad-except - raise ValueError(f"'{url}' is not a valid url") from exc - if not (parsed_uri.scheme and parsed_uri.hostname): - raise ValueError(f"'{url}' is not a valid url") - - path = list(filter(None, parsed_uri.path.split("/"))) - - if len(path) < 2 or len(path) > 3: - raise ValueError(f"'{url}' is not a valid vault url") - - return _VaultId( - vault_url=f"{parsed_uri.scheme}://{parsed_uri.hostname}", - collection=path[0], - name=path[1], - version=path[2] if len(path) == 3 else None, - ) - - -BackupLocation = namedtuple("BackupLocation", ["container_url", "folder_name"]) - - -def parse_folder_url(folder_url: str) -> "BackupLocation": - """Parse the blob container URL and folder name from a backup's blob storage URL. - - For example, https://.blob.core.windows.net/backup/mhsm-account-2020090117323313 parses to - (container_url="https://.blob.core.windows.net/backup", folder_name="mhsm-account-2020090117323313"). - - :param str folder_url: The URL to a backup's blob storage folder. - - :returns: A named tuple with a `container_url` and `folder_name`, representing the location of the backup. - :rtype: BackupLocation - """ - - try: - parsed = urlparse(folder_url) - - # the first segment of the path is the container name - stripped_path = parsed.path.strip("/") - container = stripped_path.split("/", maxsplit=1)[0] - - # the rest of the path is the folder name - folder_name = stripped_path[len(container) + 1 :] - - # this intentionally discards any SAS token in the URL--methods require the SAS token as a separate parameter - container_url = f"{parsed.scheme}://{parsed.netloc}/{container}" - - return BackupLocation(container_url, folder_name) - except Exception as exc: # pylint:disable=broad-except - raise ValueError( - '"folder_url" should be the URL of a blob holding a Key Vault backup, for example ' - '"https://.blob.core.windows.net/backup/mhsm-account-2020090117323313"' - ) from exc - - -try: - # pylint:disable=unused-import - from .async_challenge_auth_policy import AsyncChallengeAuthPolicy - from .async_client_base import AsyncKeyVaultClientBase - - __all__.extend(["AsyncChallengeAuthPolicy", "AsyncKeyVaultClientBase"]) -except (SyntaxError, ImportError): - pass diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/async_challenge_auth_policy.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/async_challenge_auth_policy.py deleted file mode 100644 index dad851f8f58c..000000000000 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/async_challenge_auth_policy.py +++ /dev/null @@ -1,262 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -"""Policy implementing Key Vault's challenge authentication protocol. - -Normally the protocol is only used for the client's first service request, upon which: -1. The challenge authentication policy sends a copy of the request, without authorization or content. -2. Key Vault responds 401 with a header (the 'challenge') detailing how the client should authenticate such a request. -3. The policy authenticates according to the challenge and sends the original request with authorization. - -The policy caches the challenge and thus knows how to authenticate future requests. However, authentication -requirements can change. For example, a vault may move to a new tenant. In such a case the policy will attempt the -protocol again. -""" - -from copy import deepcopy -import sys -import time -from typing import Any, Callable, cast, Optional, overload, TypeVar, Union -from urllib.parse import urlparse - -from typing_extensions import ParamSpec - -from azure.core.credentials import AccessToken, AccessTokenInfo, TokenRequestOptions -from azure.core.credentials_async import AsyncSupportsTokenInfo, AsyncTokenCredential, AsyncTokenProvider -from azure.core.pipeline import PipelineRequest, PipelineResponse -from azure.core.pipeline.policies import AsyncBearerTokenCredentialPolicy -from azure.core.rest import AsyncHttpResponse, HttpRequest - -from .http_challenge import HttpChallenge -from . import http_challenge_cache as ChallengeCache -from .challenge_auth_policy import _enforce_tls, _has_claims, _update_challenge - -if sys.version_info < (3, 9): - from typing import Awaitable -else: - from collections.abc import Awaitable - - -P = ParamSpec("P") -T = TypeVar("T") - - -@overload -async def await_result(func: Callable[P, Awaitable[T]], *args: P.args, **kwargs: P.kwargs) -> T: ... - - -@overload -async def await_result(func: Callable[P, T], *args: P.args, **kwargs: P.kwargs) -> T: ... - - -async def await_result(func: Callable[P, Union[T, Awaitable[T]]], *args: P.args, **kwargs: P.kwargs) -> T: - """If func returns an awaitable, await it. - - :param func: The function to run. - :type func: callable - :param args: The positional arguments to pass to the function. - :type args: list - :rtype: any - :return: The result of the function - """ - result = func(*args, **kwargs) - if isinstance(result, Awaitable): - return await result - return result - - -class AsyncChallengeAuthPolicy(AsyncBearerTokenCredentialPolicy): - """Policy for handling HTTP authentication challenges. - - :param credential: An object which can provide an access token for the vault, such as a credential from - :mod:`azure.identity.aio` - :type credential: ~azure.core.credentials_async.AsyncTokenProvider - """ - - def __init__(self, credential: AsyncTokenProvider, *scopes: str, **kwargs: Any) -> None: - # Pass `enable_cae` so `enable_cae=True` is always passed through self.authorize_request - super().__init__(credential, *scopes, enable_cae=True, **kwargs) - self._credential: AsyncTokenProvider = credential - self._token: Optional[Union["AccessToken", "AccessTokenInfo"]] = None - self._verify_challenge_resource = kwargs.pop("verify_challenge_resource", True) - self._request_copy: Optional[HttpRequest] = None - - async def send( - self, request: PipelineRequest[HttpRequest] - ) -> PipelineResponse[HttpRequest, AsyncHttpResponse]: - """Authorize request with a bearer token and send it to the next policy. - - We implement this method to account for the valid scenario where a Key Vault authentication challenge is - immediately followed by a CAE claims challenge. The base class's implementation would return the second 401 to - the caller, but we should handle that second challenge as well (and only return any third 401 response). - - :param request: The pipeline request object - :type request: ~azure.core.pipeline.PipelineRequest - :return: The pipeline response object - :rtype: ~azure.core.pipeline.PipelineResponse - """ - await await_result(self.on_request, request) - response: PipelineResponse[HttpRequest, AsyncHttpResponse] - try: - response = await self.next.send(request) - except Exception: # pylint:disable=broad-except - await await_result(self.on_exception, request) - raise - await await_result(self.on_response, request, response) - - if response.http_response.status_code == 401: - return await self.handle_challenge_flow(request, response) - return response - - async def handle_challenge_flow( - self, - request: PipelineRequest[HttpRequest], - response: PipelineResponse[HttpRequest, AsyncHttpResponse], - consecutive_challenge: bool = False, - ) -> PipelineResponse[HttpRequest, AsyncHttpResponse]: - """Handle the challenge flow of Key Vault and CAE authentication. - - :param request: The pipeline request object - :type request: ~azure.core.pipeline.PipelineRequest - :param response: The pipeline response object - :type response: ~azure.core.pipeline.PipelineResponse - :param bool consecutive_challenge: Whether the challenge is arriving immediately after another challenge. - Consecutive challenges can only be valid if a Key Vault challenge is followed by a CAE claims challenge. - True if the preceding challenge was a Key Vault challenge; False otherwise. - - :return: The pipeline response object - :rtype: ~azure.core.pipeline.PipelineResponse - """ - self._token = None # any cached token is invalid - if "WWW-Authenticate" in response.http_response.headers: - # If the previous challenge was a KV challenge and this one is too, return the 401 - claims_challenge = _has_claims(response.http_response.headers["WWW-Authenticate"]) - if consecutive_challenge and not claims_challenge: - return response - - request_authorized = await self.on_challenge(request, response) - if request_authorized: - # if we receive a challenge response, we retrieve a new token - # which matches the new target. In this case, we don't want to remove - # token from the request so clear the 'insecure_domain_change' tag - request.context.options.pop("insecure_domain_change", False) - try: - response = await self.next.send(request) - except Exception: # pylint:disable=broad-except - await await_result(self.on_exception, request) - raise - - # If consecutive_challenge == True, this could be a third consecutive 401 - if response.http_response.status_code == 401 and not consecutive_challenge: - # If the previous challenge wasn't from CAE, we can try this function one more time - if not claims_challenge: - return await self.handle_challenge_flow(request, response, consecutive_challenge=True) - await await_result(self.on_response, request, response) - return response - - - async def on_request(self, request: PipelineRequest) -> None: - _enforce_tls(request) - challenge = ChallengeCache.get_challenge_for_url(request.http_request.url) - if challenge: - # Note that if the vault has moved to a new tenant since our last request for it, this request will fail. - if self._need_new_token(): - # azure-identity credentials require an AADv2 scope but the challenge may specify an AADv1 resource - scope = challenge.get_scope() or challenge.get_resource() + "/.default" - await self._request_kv_token(scope, challenge) - - bearer_token = cast(Union[AccessToken, AccessTokenInfo], self._token).token - request.http_request.headers["Authorization"] = f"Bearer {bearer_token}" - return - - # else: discover authentication information by eliciting a challenge from Key Vault. Remove any request data, - # saving it for later. Key Vault will reject the request as unauthorized and respond with a challenge. - # on_challenge will parse that challenge, use the original request including the body, authorize the - # request, and tell super to send it again. - if request.http_request.content: - self._request_copy = request.http_request - bodiless_request = HttpRequest( - method=request.http_request.method, - url=request.http_request.url, - headers=deepcopy(request.http_request.headers), - ) - bodiless_request.headers["Content-Length"] = "0" - request.http_request = bodiless_request - - - async def on_challenge(self, request: PipelineRequest, response: PipelineResponse) -> bool: - try: - # CAE challenges may not include a scope or tenant; cache from the previous challenge to use if necessary - old_scope: Optional[str] = None - old_tenant: Optional[str] = None - cached_challenge = ChallengeCache.get_challenge_for_url(request.http_request.url) - if cached_challenge: - old_scope = cached_challenge.get_scope() or cached_challenge.get_resource() + "/.default" - old_tenant = cached_challenge.tenant_id - - challenge = _update_challenge(request, response) - # CAE challenges may not include a scope or tenant; use the previous challenge's values if necessary - if challenge.claims and old_scope: - challenge._parameters["scope"] = old_scope # pylint:disable=protected-access - challenge.tenant_id = old_tenant - # azure-identity credentials require an AADv2 scope but the challenge may specify an AADv1 resource - scope = challenge.get_scope() or challenge.get_resource() + "/.default" - except ValueError: - return False - - if self._verify_challenge_resource: - resource_domain = urlparse(scope).netloc - if not resource_domain: - raise ValueError(f"The challenge contains invalid scope '{scope}'.") - - request_domain = urlparse(request.http_request.url).netloc - if not request_domain.lower().endswith(f".{resource_domain.lower()}"): - raise ValueError( - f"The challenge resource '{resource_domain}' does not match the requested domain. Pass " - "`verify_challenge_resource=False` to your client's constructor to disable this verification. " - "See https://aka.ms/azsdk/blog/vault-uri for more information." - ) - - # If we had created a request copy in on_request, use it now to send along the original body content - if self._request_copy: - request.http_request = self._request_copy - - # The tenant parsed from AD FS challenges is "adfs"; we don't actually need a tenant for AD FS authentication - # For AD FS we skip cross-tenant authentication per https://github.com/Azure/azure-sdk-for-python/issues/28648 - if challenge.tenant_id and challenge.tenant_id.lower().endswith("adfs"): - await self.authorize_request(request, scope, claims=challenge.claims) - else: - await self.authorize_request( - request, scope, claims=challenge.claims, tenant_id=challenge.tenant_id - ) - - return True - - def _need_new_token(self) -> bool: - now = time.time() - refresh_on = getattr(self._token, "refresh_on", None) - return not self._token or (refresh_on and refresh_on <= now) or self._token.expires_on - now < 300 - - async def _request_kv_token(self, scope: str, challenge: HttpChallenge) -> None: - """Implementation of BearerTokenCredentialPolicy's _request_token method, but specific to Key Vault. - - :param str scope: The scope for which to request a token. - :param challenge: The challenge for the request being made. - :type challenge: HttpChallenge - """ - # Exclude tenant for AD FS authentication - exclude_tenant = challenge.tenant_id and challenge.tenant_id.lower().endswith("adfs") - # The AsyncSupportsTokenInfo protocol needs TokenRequestOptions for token requests instead of kwargs - if hasattr(self._credential, "get_token_info"): - options: TokenRequestOptions = {"enable_cae": True} - if challenge.tenant_id and not exclude_tenant: - options["tenant_id"] = challenge.tenant_id - self._token = await cast(AsyncSupportsTokenInfo, self._credential).get_token_info(scope, options=options) - else: - if exclude_tenant: - self._token = await self._credential.get_token(scope, enable_cae=True) - else: - self._token = await cast(AsyncTokenCredential, self._credential).get_token( - scope, tenant_id=challenge.tenant_id, enable_cae=True - ) diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/async_client_base.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/async_client_base.py deleted file mode 100644 index 3ca4483ea763..000000000000 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/async_client_base.py +++ /dev/null @@ -1,116 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -import sys -from typing import Any - -from azure.core.credentials_async import AsyncTokenCredential -from azure.core.pipeline.policies import HttpLoggingPolicy -from azure.core.rest import AsyncHttpResponse, HttpRequest -from azure.core.tracing.decorator_async import distributed_trace_async - -from . import AsyncChallengeAuthPolicy -from .client_base import ApiVersion, DEFAULT_VERSION, _format_api_version, _SERIALIZER -from .._sdk_moniker import SDK_MONIKER -from .._generated.aio import KeyVaultClient as _KeyVaultClient -from .._generated import models as _models - -if sys.version_info < (3, 9): - from typing import Awaitable -else: - from collections.abc import Awaitable - - -class AsyncKeyVaultClientBase(object): - # pylint:disable=protected-access - def __init__(self, vault_url: str, credential: AsyncTokenCredential, **kwargs: Any) -> None: - if not credential: - raise ValueError( - "credential should be an object supporting the AsyncTokenCredential protocol, " - "such as a credential from azure-identity" - ) - if not vault_url: - raise ValueError("vault_url must be the URL of an Azure Key Vault") - - try: - self.api_version = kwargs.pop("api_version", DEFAULT_VERSION) - # If API version was provided as an enum value, need to make a plain string for 3.11 compatibility - if hasattr(self.api_version, "value"): - self.api_version = self.api_version.value - self._vault_url = vault_url.strip(" /") - client = kwargs.get("generated_client") - if client: - # caller provided a configured client -> only models left to initialize - self._client = client - models = kwargs.get("generated_models") - self._models = models or _models - return - - http_logging_policy = HttpLoggingPolicy(**kwargs) - http_logging_policy.allowed_header_names.update( - { - "x-ms-keyvault-network-info", - "x-ms-keyvault-region", - "x-ms-keyvault-service-version" - } - ) - - verify_challenge = kwargs.pop("verify_challenge_resource", True) - self._client = _KeyVaultClient( - api_version=self.api_version, - authentication_policy=AsyncChallengeAuthPolicy(credential, verify_challenge_resource=verify_challenge), - sdk_moniker=SDK_MONIKER, - http_logging_policy=http_logging_policy, - **kwargs - ) - self._models = _models - except ValueError as exc: - raise NotImplementedError( - f"This package doesn't support API version '{self.api_version}'. " - + f"Supported versions: {', '.join(v.value for v in ApiVersion)}" - ) from exc - - @property - def vault_url(self) -> str: - return self._vault_url - - async def __aenter__(self) -> "AsyncKeyVaultClientBase": - await self._client.__aenter__() - return self - - async def __aexit__(self, *args: "Any") -> None: - await self._client.__aexit__(*args) - - async def close(self) -> None: - """Close sockets opened by the client. - - Calling this method is unnecessary when using the client as a context manager. - """ - await self._client.close() - - @distributed_trace_async - def send_request( - self, request: HttpRequest, *, stream: bool = False, **kwargs: Any - ) -> Awaitable[AsyncHttpResponse]: - """Runs a network request using the client's existing pipeline. - - The request URL can be relative to the vault URL. The service API version used for the request is the same as - the client's unless otherwise specified. This method does not raise if the response is an error; to raise an - exception, call `raise_for_status()` on the returned response object. For more information about how to send - custom requests with this method, see https://aka.ms/azsdk/dpcodegen/python/send_request. - - :param request: The network request you want to make. - :type request: ~azure.core.rest.HttpRequest - - :keyword bool stream: Whether the response payload will be streamed. Defaults to False. - - :return: The response of your network call. Does not do error handling on your response. - :rtype: ~azure.core.rest.AsyncHttpResponse - """ - request_copy = _format_api_version(request, self.api_version) - path_format_arguments = { - "vaultBaseUrl": _SERIALIZER.url("vault_base_url", self._vault_url, "str", skip_quote=True), - } - request_copy.url = self._client._client.format_url(request_copy.url, **path_format_arguments) - return self._client._client.send_request(request_copy, stream=stream, **kwargs) diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/async_polling.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/async_polling.py deleted file mode 100644 index bd77ebd79e4e..000000000000 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/async_polling.py +++ /dev/null @@ -1,12 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -import base64 - -from azure.core.polling.async_base_polling import AsyncLROBasePolling - - -class KeyVaultAsyncBackupClientPollingMethod(AsyncLROBasePolling): - def get_continuation_token(self) -> str: - return base64.b64encode(self._operation.get_polling_url().encode()).decode("ascii") diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/challenge_auth_policy.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/challenge_auth_policy.py deleted file mode 100644 index eb4073d0e699..000000000000 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/challenge_auth_policy.py +++ /dev/null @@ -1,270 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -"""Policy implementing Key Vault's challenge authentication protocol. - -Normally the protocol is only used for the client's first service request, upon which: -1. The challenge authentication policy sends a copy of the request, without authorization or content. -2. Key Vault responds 401 with a header (the 'challenge') detailing how the client should authenticate such a request. -3. The policy authenticates according to the challenge and sends the original request with authorization. - -The policy caches the challenge and thus knows how to authenticate future requests. However, authentication -requirements can change. For example, a vault may move to a new tenant. In such a case the policy will attempt the -protocol again. -""" - -from copy import deepcopy -import time -from typing import Any, cast, Optional, Union -from urllib.parse import urlparse - -from azure.core.credentials import ( - AccessToken, - AccessTokenInfo, - TokenCredential, - TokenProvider, - TokenRequestOptions, - SupportsTokenInfo, -) -from azure.core.exceptions import ServiceRequestError -from azure.core.pipeline import PipelineRequest, PipelineResponse -from azure.core.pipeline.policies import BearerTokenCredentialPolicy -from azure.core.rest import HttpRequest, HttpResponse - -from .http_challenge import HttpChallenge -from . import http_challenge_cache as ChallengeCache - - -def _enforce_tls(request: PipelineRequest) -> None: - if not request.http_request.url.lower().startswith("https"): - raise ServiceRequestError( - "Bearer token authentication is not permitted for non-TLS protected (non-https) URLs." - ) - - -def _has_claims(challenge: str) -> bool: - """Check if a challenge header contains claims. - - :param challenge: The challenge header to check. - :type challenge: str - - :returns: True if the challenge contains claims; False otherwise. - :rtype: bool - """ - # Split the challenge into its scheme and parameters, then check if any parameter contains claims - split_challenge = challenge.strip().split(" ", 1) - return any("claims=" in item for item in split_challenge[1].split(",")) - - -def _update_challenge(request: PipelineRequest, challenger: PipelineResponse) -> HttpChallenge: - """Parse challenge from a challenge response, cache it, and return it. - - :param request: The pipeline request that prompted the challenge response. - :type request: ~azure.core.pipeline.PipelineRequest - :param challenger: The pipeline response containing the authentication challenge. - :type challenger: ~azure.core.pipeline.PipelineResponse - - :returns: An HttpChallenge object representing the authentication challenge. - :rtype: HttpChallenge - """ - - challenge = HttpChallenge( - request.http_request.url, - challenger.http_response.headers.get("WWW-Authenticate"), - response_headers=challenger.http_response.headers, - ) - ChallengeCache.set_challenge_for_url(request.http_request.url, challenge) - return challenge - - -class ChallengeAuthPolicy(BearerTokenCredentialPolicy): - """Policy for handling HTTP authentication challenges. - - :param credential: An object which can provide an access token for the vault, such as a credential from - :mod:`azure.identity` - :type credential: ~azure.core.credentials.TokenProvider - :param str scopes: Lets you specify the type of access needed. - """ - - def __init__(self, credential: TokenProvider, *scopes: str, **kwargs: Any) -> None: - # Pass `enable_cae` so `enable_cae=True` is always passed through self.authorize_request - super(ChallengeAuthPolicy, self).__init__(credential, *scopes, enable_cae=True, **kwargs) - self._credential: TokenProvider = credential - self._token: Optional[Union["AccessToken", "AccessTokenInfo"]] = None - self._verify_challenge_resource = kwargs.pop("verify_challenge_resource", True) - self._request_copy: Optional[HttpRequest] = None - - def send(self, request: PipelineRequest[HttpRequest]) -> PipelineResponse[HttpRequest, HttpResponse]: - """Authorize request with a bearer token and send it to the next policy. - - We implement this method to account for the valid scenario where a Key Vault authentication challenge is - immediately followed by a CAE claims challenge. The base class's implementation would return the second 401 to - the caller, but we should handle that second challenge as well (and only return any third 401 response). - - :param request: The pipeline request object - :type request: ~azure.core.pipeline.PipelineRequest - - :return: The pipeline response object - :rtype: ~azure.core.pipeline.PipelineResponse - """ - self.on_request(request) - try: - response = self.next.send(request) - except Exception: # pylint:disable=broad-except - self.on_exception(request) - raise - - self.on_response(request, response) - if response.http_response.status_code == 401: - return self.handle_challenge_flow(request, response) - return response - - def handle_challenge_flow( - self, - request: PipelineRequest[HttpRequest], - response: PipelineResponse[HttpRequest, HttpResponse], - consecutive_challenge: bool = False, - ) -> PipelineResponse[HttpRequest, HttpResponse]: - """Handle the challenge flow of Key Vault and CAE authentication. - - :param request: The pipeline request object - :type request: ~azure.core.pipeline.PipelineRequest - :param response: The pipeline response object - :type response: ~azure.core.pipeline.PipelineResponse - :param bool consecutive_challenge: Whether the challenge is arriving immediately after another challenge. - Consecutive challenges can only be valid if a Key Vault challenge is followed by a CAE claims challenge. - True if the preceding challenge was a Key Vault challenge; False otherwise. - - :return: The pipeline response object - :rtype: ~azure.core.pipeline.PipelineResponse - """ - self._token = None # any cached token is invalid - if "WWW-Authenticate" in response.http_response.headers: - # If the previous challenge was a KV challenge and this one is too, return the 401 - claims_challenge = _has_claims(response.http_response.headers["WWW-Authenticate"]) - if consecutive_challenge and not claims_challenge: - return response - - request_authorized = self.on_challenge(request, response) - if request_authorized: - # if we receive a challenge response, we retrieve a new token - # which matches the new target. In this case, we don't want to remove - # token from the request so clear the 'insecure_domain_change' tag - request.context.options.pop("insecure_domain_change", False) - try: - response = self.next.send(request) - except Exception: # pylint:disable=broad-except - self.on_exception(request) - raise - - # If consecutive_challenge == True, this could be a third consecutive 401 - if response.http_response.status_code == 401 and not consecutive_challenge: - # If the previous challenge wasn't from CAE, we can try this function one more time - if not claims_challenge: - return self.handle_challenge_flow(request, response, consecutive_challenge=True) - self.on_response(request, response) - return response - - def on_request(self, request: PipelineRequest) -> None: - _enforce_tls(request) - challenge = ChallengeCache.get_challenge_for_url(request.http_request.url) - if challenge: - # Note that if the vault has moved to a new tenant since our last request for it, this request will fail. - if self._need_new_token: - # azure-identity credentials require an AADv2 scope but the challenge may specify an AADv1 resource - scope = challenge.get_scope() or challenge.get_resource() + "/.default" - self._request_kv_token(scope, challenge) - - bearer_token = cast(Union["AccessToken", "AccessTokenInfo"], self._token).token - request.http_request.headers["Authorization"] = f"Bearer {bearer_token}" - return - - # else: discover authentication information by eliciting a challenge from Key Vault. Remove any request data, - # saving it for later. Key Vault will reject the request as unauthorized and respond with a challenge. - # on_challenge will parse that challenge, use the original request including the body, authorize the - # request, and tell super to send it again. - if request.http_request.content: - self._request_copy = request.http_request - bodiless_request = HttpRequest( - method=request.http_request.method, - url=request.http_request.url, - headers=deepcopy(request.http_request.headers), - ) - bodiless_request.headers["Content-Length"] = "0" - request.http_request = bodiless_request - - def on_challenge(self, request: PipelineRequest, response: PipelineResponse) -> bool: - try: - # CAE challenges may not include a scope or tenant; cache from the previous challenge to use if necessary - old_scope: Optional[str] = None - old_tenant: Optional[str] = None - cached_challenge = ChallengeCache.get_challenge_for_url(request.http_request.url) - if cached_challenge: - old_scope = cached_challenge.get_scope() or cached_challenge.get_resource() + "/.default" - old_tenant = cached_challenge.tenant_id - - challenge = _update_challenge(request, response) - # CAE challenges may not include a scope or tenant; use the previous challenge's values if necessary - if challenge.claims and old_scope: - challenge._parameters["scope"] = old_scope # pylint:disable=protected-access - challenge.tenant_id = old_tenant - # azure-identity credentials require an AADv2 scope but the challenge may specify an AADv1 resource - scope = challenge.get_scope() or challenge.get_resource() + "/.default" - except ValueError: - return False - - if self._verify_challenge_resource: - resource_domain = urlparse(scope).netloc - if not resource_domain: - raise ValueError(f"The challenge contains invalid scope '{scope}'.") - - request_domain = urlparse(request.http_request.url).netloc - if not request_domain.lower().endswith(f".{resource_domain.lower()}"): - raise ValueError( - f"The challenge resource '{resource_domain}' does not match the requested domain. Pass " - "`verify_challenge_resource=False` to your client's constructor to disable this verification. " - "See https://aka.ms/azsdk/blog/vault-uri for more information." - ) - - # If we had created a request copy in on_request, use it now to send along the original body content - if self._request_copy: - request.http_request = self._request_copy - - # The tenant parsed from AD FS challenges is "adfs"; we don't actually need a tenant for AD FS authentication - # For AD FS we skip cross-tenant authentication per https://github.com/Azure/azure-sdk-for-python/issues/28648 - if challenge.tenant_id and challenge.tenant_id.lower().endswith("adfs"): - self.authorize_request(request, scope, claims=challenge.claims) - else: - self.authorize_request(request, scope, claims=challenge.claims, tenant_id=challenge.tenant_id) - - return True - - @property - def _need_new_token(self) -> bool: - now = time.time() - refresh_on = getattr(self._token, "refresh_on", None) - return not self._token or (refresh_on and refresh_on <= now) or self._token.expires_on - now < 300 - - def _request_kv_token(self, scope: str, challenge: HttpChallenge) -> None: - """Implementation of BearerTokenCredentialPolicy's _request_token method, but specific to Key Vault. - - :param str scope: The scope for which to request a token. - :param challenge: The challenge for the request being made. - :type challenge: HttpChallenge - """ - # Exclude tenant for AD FS authentication - exclude_tenant = challenge.tenant_id and challenge.tenant_id.lower().endswith("adfs") - # The SupportsTokenInfo protocol needs TokenRequestOptions for token requests instead of kwargs - if hasattr(self._credential, "get_token_info"): - options: TokenRequestOptions = {"enable_cae": True} - if challenge.tenant_id and not exclude_tenant: - options["tenant_id"] = challenge.tenant_id - self._token = cast(SupportsTokenInfo, self._credential).get_token_info(scope, options=options) - else: - if exclude_tenant: - self._token = self._credential.get_token(scope, enable_cae=True) - else: - self._token = cast(TokenCredential, self._credential).get_token( - scope, tenant_id=challenge.tenant_id, enable_cae=True - ) diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/client_base.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/client_base.py deleted file mode 100644 index 600d1be20446..000000000000 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/client_base.py +++ /dev/null @@ -1,152 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from copy import deepcopy -from enum import Enum -from typing import Any -from urllib.parse import urlparse - -from azure.core import CaseInsensitiveEnumMeta -from azure.core.credentials import TokenCredential -from azure.core.pipeline.policies import HttpLoggingPolicy -from azure.core.rest import HttpRequest, HttpResponse -from azure.core.tracing.decorator import distributed_trace - -from . import ChallengeAuthPolicy -from .._generated import KeyVaultClient as _KeyVaultClient -from .._generated import models as _models -from .._generated._serialization import Serializer -from .._sdk_moniker import SDK_MONIKER - - -class ApiVersion(str, Enum, metaclass=CaseInsensitiveEnumMeta): - """Key Vault API versions supported by this package""" - - #: this is the default version - V7_5 = "7.5" - V7_4 = "7.4" - V7_3 = "7.3" - V7_2 = "7.2" - - -DEFAULT_VERSION = ApiVersion.V7_5 - -_SERIALIZER = Serializer() -_SERIALIZER.client_side_validation = False - - -def _format_api_version(request: HttpRequest, api_version: str) -> HttpRequest: - """Returns a request copy that includes an api-version query parameter if one wasn't originally present. - - :param request: The HTTP request being sent. - :type request: ~azure.core.rest.HttpRequest - :param str api_version: The service API version that the request should include. - - :returns: A copy of the request that includes an api-version query parameter. - :rtype: ~azure.core.rest.HttpRequest - """ - request_copy = deepcopy(request) - params = {"api-version": api_version} # By default, we want to use the client's API version - query = urlparse(request_copy.url).query - - if query: - request_copy.url = request_copy.url.partition("?")[0] - existing_params = {p[0]: p[-1] for p in [p.partition("=") for p in query.split("&")]} - params.update(existing_params) # If an api-version was provided, this will overwrite our default - - # Reconstruct the query parameters onto the URL - query_params = [] - for k, v in params.items(): - query_params.append("{}={}".format(k, v)) - query = "?" + "&".join(query_params) - request_copy.url = request_copy.url + query - return request_copy - - -class KeyVaultClientBase(object): - # pylint:disable=protected-access - def __init__(self, vault_url: str, credential: TokenCredential, **kwargs: Any) -> None: - if not credential: - raise ValueError( - "credential should be an object supporting the TokenCredential protocol, " - "such as a credential from azure-identity" - ) - if not vault_url: - raise ValueError("vault_url must be the URL of an Azure Key Vault") - - try: - self.api_version = kwargs.pop("api_version", DEFAULT_VERSION) - # If API version was provided as an enum value, need to make a plain string for 3.11 compatibility - if hasattr(self.api_version, "value"): - self.api_version = self.api_version.value - self._vault_url = vault_url.strip(" /") - client = kwargs.get("generated_client") - if client: - # caller provided a configured client -> only models left to initialize - self._client = client - models = kwargs.get("generated_models") - self._models = models or _models - return - - http_logging_policy = HttpLoggingPolicy(**kwargs) - http_logging_policy.allowed_header_names.update( - {"x-ms-keyvault-network-info", "x-ms-keyvault-region", "x-ms-keyvault-service-version"} - ) - - verify_challenge = kwargs.pop("verify_challenge_resource", True) - self._client = _KeyVaultClient( - api_version=self.api_version, - authentication_policy=ChallengeAuthPolicy(credential, verify_challenge_resource=verify_challenge), - sdk_moniker=SDK_MONIKER, - http_logging_policy=http_logging_policy, - **kwargs - ) - self._models = _models - except ValueError as exc: - raise NotImplementedError( - f"This package doesn't support API version '{self.api_version}'. " - + f"Supported versions: {', '.join(v.value for v in ApiVersion)}" - ) from exc - - @property - def vault_url(self) -> str: - return self._vault_url - - def __enter__(self) -> "KeyVaultClientBase": - self._client.__enter__() - return self - - def __exit__(self, *args: "Any") -> None: - self._client.__exit__(*args) - - def close(self) -> None: - """Close sockets opened by the client. - - Calling this method is unnecessary when using the client as a context manager. - """ - self._client.close() - - @distributed_trace - def send_request(self, request: HttpRequest, *, stream: bool = False, **kwargs: Any) -> HttpResponse: - """Runs a network request using the client's existing pipeline. - - The request URL can be relative to the vault URL. The service API version used for the request is the same as - the client's unless otherwise specified. This method does not raise if the response is an error; to raise an - exception, call `raise_for_status()` on the returned response object. For more information about how to send - custom requests with this method, see https://aka.ms/azsdk/dpcodegen/python/send_request. - - :param request: The network request you want to make. - :type request: ~azure.core.rest.HttpRequest - - :keyword bool stream: Whether the response payload will be streamed. Defaults to False. - - :return: The response of your network call. Does not do error handling on your response. - :rtype: ~azure.core.rest.HttpResponse - """ - request_copy = _format_api_version(request, self.api_version) - path_format_arguments = { - "vaultBaseUrl": _SERIALIZER.url("vault_base_url", self._vault_url, "str", skip_quote=True), - } - request_copy.url = self._client._client.format_url(request_copy.url, **path_format_arguments) - return self._client._client.send_request(request_copy, stream=stream, **kwargs) diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/http_challenge.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/http_challenge.py deleted file mode 100644 index 0320df5a868b..000000000000 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/http_challenge.py +++ /dev/null @@ -1,182 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -import base64 -from typing import Dict, MutableMapping, Optional -from urllib import parse - - -class HttpChallenge(object): - """An object representing the content of a Key Vault authentication challenge. - - :param str request_uri: The URI of the HTTP request that prompted this challenge. - :param str challenge: The WWW-Authenticate header of the challenge response. - :param response_headers: Optional. The headers attached to the challenge response. - :type response_headers: MutableMapping[str, str] or None - """ - - def __init__( - self, request_uri: str, challenge: str, response_headers: "Optional[MutableMapping[str, str]]" = None - ) -> None: - """Parses an HTTP WWW-Authentication Bearer challenge from a server. - - Example challenge with claims: - Bearer authorization="https://login.windows-ppe.net/", error="invalid_token", - error_description="User session has been revoked", - claims="eyJhY2Nlc3NfdG9rZW4iOnsibmJmIjp7ImVzc2VudGlhbCI6dHJ1ZSwgInZhbHVlIjoiMTYwMzc0MjgwMCJ9fX0=" - """ - self.source_authority = self._validate_request_uri(request_uri) - self.source_uri = request_uri - self._parameters: "Dict[str, str]" = {} - - # get the scheme of the challenge and remove from the challenge string - trimmed_challenge = self._validate_challenge(challenge) - split_challenge = trimmed_challenge.split(" ", 1) - self.scheme = split_challenge[0] - trimmed_challenge = split_challenge[1] - - self.claims = None - # split trimmed challenge into comma-separated name=value pairs. Values are expected - # to be surrounded by quotes which are stripped here. - for item in trimmed_challenge.split(","): - # Special case for claims, which can contain = symbols as padding. Assume at most one claim per challenge - if "claims=" in item: - encoded_claims = item[item.index("=") + 1 :].strip(" \"'") - padding_needed = -len(encoded_claims) % 4 - try: - decoded_claims = base64.urlsafe_b64decode(encoded_claims + "=" * padding_needed).decode() - self.claims = decoded_claims - except Exception: # pylint:disable=broad-except - continue - # process name=value pairs - else: - comps = item.split("=") - if len(comps) == 2: - key = comps[0].strip(' "') - value = comps[1].strip(' "') - if key: - self._parameters[key] = value - - # minimum set of parameters - if not self._parameters: - raise ValueError("Invalid challenge parameters") - - # must specify authorization or authorization_uri - if "authorization" not in self._parameters and "authorization_uri" not in self._parameters: - raise ValueError("Invalid challenge parameters") - - authorization_uri = self.get_authorization_server() - # the authorization server URI should look something like https://login.windows.net/tenant-id - raw_uri_path = str(parse.urlparse(authorization_uri).path) - uri_path = raw_uri_path.lstrip("/") - self.tenant_id = uri_path.split("/", maxsplit=1)[0] or None - - # if the response headers were supplied - if response_headers: - # get the message signing key and message key encryption key from the headers - self.server_signature_key = response_headers.get("x-ms-message-signing-key", None) - self.server_encryption_key = response_headers.get("x-ms-message-encryption-key", None) - - def is_bearer_challenge(self) -> bool: - """Tests whether the HttpChallenge is a Bearer challenge. - - :returns: True if the challenge is a Bearer challenge; False otherwise. - :rtype: bool - """ - if not self.scheme: - return False - - return self.scheme.lower() == "bearer" - - def is_pop_challenge(self) -> bool: - """Tests whether the HttpChallenge is a proof of possession challenge. - - :returns: True if the challenge is a proof of possession challenge; False otherwise. - :rtype: bool - """ - if not self.scheme: - return False - - return self.scheme.lower() == "pop" - - def get_value(self, key: str) -> "Optional[str]": - return self._parameters.get(key) - - def get_authorization_server(self) -> str: - """Returns the URI for the authorization server if present, otherwise an empty string. - - :returns: The URI for the authorization server if present, otherwise an empty string. - :rtype: str - """ - value = "" - for key in ["authorization_uri", "authorization"]: - value = self.get_value(key) or "" - if value: - break - return value - - def get_resource(self) -> str: - """Returns the resource if present, otherwise an empty string. - - :returns: The challenge resource if present, otherwise an empty string. - :rtype: str - """ - return self.get_value("resource") or "" - - def get_scope(self) -> str: - """Returns the scope if present, otherwise an empty string. - - :returns: The challenge scope if present, otherwise an empty string. - :rtype: str - """ - return self.get_value("scope") or "" - - def supports_pop(self) -> bool: - """Returns True if the challenge supports proof of possession token auth; False otherwise. - - :returns: True if the challenge supports proof of possession token auth; False otherwise. - :rtype: bool - """ - return self._parameters.get("supportspop", "").lower() == "true" - - def supports_message_protection(self) -> bool: - """Returns True if the challenge vault supports message protection; False otherwise. - - :returns: True if the challenge vault supports message protection; False otherwise. - :rtype: bool - """ - return self.supports_pop() and self.server_encryption_key and self.server_signature_key # type: ignore - - def _validate_challenge(self, challenge: str) -> str: # pylint:disable=bad-option-value,useless-option-value,no-self-use - """Verifies that the challenge is a valid auth challenge and returns the key=value pairs. - - :param str challenge: The WWW-Authenticate header of the challenge response. - - :returns: The challenge key/value pairs, with whitespace removed, as a string. - :rtype: str - """ - if not challenge: - raise ValueError("Challenge cannot be empty") - - return challenge.strip() - - def _validate_request_uri(self, uri: str) -> str: # pylint:disable=bad-option-value,useless-option-value,no-self-use - """Extracts the host authority from the given URI. - - :param str uri: The URI of the HTTP request that prompted the challenge. - - :returns: The challenge host authority. - :rtype: str - """ - if not uri: - raise ValueError("request_uri cannot be empty") - - parsed = parse.urlparse(uri) - if not parsed.netloc: - raise ValueError("request_uri must be an absolute URI") - - if parsed.scheme.lower() not in ["http", "https"]: - raise ValueError("request_uri must be HTTP or HTTPS") - - return parsed.netloc diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/http_challenge_cache.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/http_challenge_cache.py deleted file mode 100644 index f1448cc53391..000000000000 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/http_challenge_cache.py +++ /dev/null @@ -1,93 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -import threading -from typing import Dict, Optional -from urllib import parse - -from .http_challenge import HttpChallenge - - -_cache: "Dict[str, HttpChallenge]" = {} -_lock = threading.Lock() - - -def get_challenge_for_url(url: str) -> "Optional[HttpChallenge]": - """Gets the challenge for the cached URL. - - :param str url: the URL the challenge is cached for. - - :returns: The challenge for the cached request URL, or None if the request URL isn't cached. - :rtype: HttpChallenge or None - """ - - if not url: - raise ValueError("URL cannot be None") - - key = _get_cache_key(url) - - with _lock: - return _cache.get(key) - - -def _get_cache_key(url: str) -> str: - """Use the URL's netloc as cache key except when the URL specifies the default port for its scheme. In that case - use the netloc without the port. That is to say, https://foo.bar and https://foo.bar:443 are considered equivalent. - - This equivalency prevents an unnecessary challenge when using Key Vault's paging API. The Key Vault client doesn't - specify ports, but Key Vault's next page links do, so a redundant challenge would otherwise be executed when the - client requests the next page. - - :param str url: The HTTP request URL. - - :returns: The URL's `netloc`, minus any port attached to the URL. - :rtype: str - """ - - parsed = parse.urlparse(url) - if parsed.scheme == "https" and parsed.port == 443: - return parsed.netloc[:-4] - return parsed.netloc - - -def remove_challenge_for_url(url: str) -> None: - """Removes the cached challenge for the specified URL. - - :param str url: the URL for which to remove the cached challenge - """ - if not url: - raise ValueError("URL cannot be empty") - - parsed = parse.urlparse(url) - - with _lock: - del _cache[parsed.netloc] - - -def set_challenge_for_url(url: str, challenge: "HttpChallenge") -> None: - """Caches the challenge for the specified URL. - - :param str url: the URL for which to cache the challenge - :param challenge: the challenge to cache - :type challenge: HttpChallenge - """ - if not url: - raise ValueError("URL cannot be empty") - - if not challenge: - raise ValueError("Challenge cannot be empty") - - src_url = parse.urlparse(url) - if src_url.netloc != challenge.source_authority: - raise ValueError("Source URL and Challenge URL do not match") - - with _lock: - _cache[src_url.netloc] = challenge - - -def clear() -> None: - """Clears the cache.""" - - with _lock: - _cache.clear() diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/polling.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/polling.py deleted file mode 100644 index eba971b80c47..000000000000 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_internal/polling.py +++ /dev/null @@ -1,37 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -import base64 -from typing import TYPE_CHECKING - -from azure.core.polling.base_polling import LROBasePolling, OperationFailed, OperationResourcePolling - -if TYPE_CHECKING: - from azure.core.pipeline import PipelineResponse - from azure.core.rest import HttpResponse - - -class KeyVaultBackupClientPolling(OperationResourcePolling): - def __init__(self) -> None: - self._polling_url = "" - super(KeyVaultBackupClientPolling, self).__init__(operation_location_header="azure-asyncoperation") - - def get_polling_url(self) -> str: - return self._polling_url - - def get_final_get_url(self, pipeline_response: "PipelineResponse") -> None: - return None - - def set_initial_status(self, pipeline_response: "PipelineResponse") -> str: - response = pipeline_response.http_response # type: HttpResponse - self._polling_url = response.headers["azure-asyncoperation"] - - if response.status_code in {200, 201, 202, 204}: - return self.get_status(pipeline_response) - raise OperationFailed("Operation failed or canceled") - - -class KeyVaultBackupClientPollingMethod(LROBasePolling): - def get_continuation_token(self) -> str: - return base64.b64encode(self._operation.get_polling_url().encode()).decode("ascii") diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_model_base.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_model_base.py new file mode 100644 index 000000000000..3072ee252ed9 --- /dev/null +++ b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_model_base.py @@ -0,0 +1,1235 @@ +# pylint: disable=too-many-lines +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +# pylint: disable=protected-access, broad-except + +import copy +import calendar +import decimal +import functools +import sys +import logging +import base64 +import re +import typing +import enum +import email.utils +from datetime import datetime, date, time, timedelta, timezone +from json import JSONEncoder +import xml.etree.ElementTree as ET +from typing_extensions import Self +import isodate +from azure.core.exceptions import DeserializationError +from azure.core import CaseInsensitiveEnumMeta +from azure.core.pipeline import PipelineResponse +from azure.core.serialization import _Null + +if sys.version_info >= (3, 9): + from collections.abc import MutableMapping +else: + from typing import MutableMapping + +_LOGGER = logging.getLogger(__name__) + +__all__ = ["SdkJSONEncoder", "Model", "rest_field", "rest_discriminator"] + +TZ_UTC = timezone.utc +_T = typing.TypeVar("_T") + + +def _timedelta_as_isostr(td: timedelta) -> str: + """Converts a datetime.timedelta object into an ISO 8601 formatted string, e.g. 'P4DT12H30M05S' + + Function adapted from the Tin Can Python project: https://github.com/RusticiSoftware/TinCanPython + + :param timedelta td: The timedelta to convert + :rtype: str + :return: ISO8601 version of this timedelta + """ + + # Split seconds to larger units + seconds = td.total_seconds() + minutes, seconds = divmod(seconds, 60) + hours, minutes = divmod(minutes, 60) + days, hours = divmod(hours, 24) + + days, hours, minutes = list(map(int, (days, hours, minutes))) + seconds = round(seconds, 6) + + # Build date + date_str = "" + if days: + date_str = "%sD" % days + + if hours or minutes or seconds: + # Build time + time_str = "T" + + # Hours + bigger_exists = date_str or hours + if bigger_exists: + time_str += "{:02}H".format(hours) + + # Minutes + bigger_exists = bigger_exists or minutes + if bigger_exists: + time_str += "{:02}M".format(minutes) + + # Seconds + try: + if seconds.is_integer(): + seconds_string = "{:02}".format(int(seconds)) + else: + # 9 chars long w/ leading 0, 6 digits after decimal + seconds_string = "%09.6f" % seconds + # Remove trailing zeros + seconds_string = seconds_string.rstrip("0") + except AttributeError: # int.is_integer() raises + seconds_string = "{:02}".format(seconds) + + time_str += "{}S".format(seconds_string) + else: + time_str = "" + + return "P" + date_str + time_str + + +def _serialize_bytes(o, format: typing.Optional[str] = None) -> str: + encoded = base64.b64encode(o).decode() + if format == "base64url": + return encoded.strip("=").replace("+", "-").replace("/", "_") + return encoded + + +def _serialize_datetime(o, format: typing.Optional[str] = None): + if hasattr(o, "year") and hasattr(o, "hour"): + if format == "rfc7231": + return email.utils.format_datetime(o, usegmt=True) + if format == "unix-timestamp": + return int(calendar.timegm(o.utctimetuple())) + + # astimezone() fails for naive times in Python 2.7, so make make sure o is aware (tzinfo is set) + if not o.tzinfo: + iso_formatted = o.replace(tzinfo=TZ_UTC).isoformat() + else: + iso_formatted = o.astimezone(TZ_UTC).isoformat() + # Replace the trailing "+00:00" UTC offset with "Z" (RFC 3339: https://www.ietf.org/rfc/rfc3339.txt) + return iso_formatted.replace("+00:00", "Z") + # Next try datetime.date or datetime.time + return o.isoformat() + + +def _is_readonly(p): + try: + return p._visibility == ["read"] + except AttributeError: + return False + + +class SdkJSONEncoder(JSONEncoder): + """A JSON encoder that's capable of serializing datetime objects and bytes.""" + + def __init__(self, *args, exclude_readonly: bool = False, format: typing.Optional[str] = None, **kwargs): + super().__init__(*args, **kwargs) + self.exclude_readonly = exclude_readonly + self.format = format + + def default(self, o): # pylint: disable=too-many-return-statements + if _is_model(o): + if self.exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + return {k: v for k, v in o.items() if k not in readonly_props} + return dict(o.items()) + try: + return super(SdkJSONEncoder, self).default(o) + except TypeError: + if isinstance(o, _Null): + return None + if isinstance(o, decimal.Decimal): + return float(o) + if isinstance(o, (bytes, bytearray)): + return _serialize_bytes(o, self.format) + try: + # First try datetime.datetime + return _serialize_datetime(o, self.format) + except AttributeError: + pass + # Last, try datetime.timedelta + try: + return _timedelta_as_isostr(o) + except AttributeError: + # This will be raised when it hits value.total_seconds in the method above + pass + return super(SdkJSONEncoder, self).default(o) + + +_VALID_DATE = re.compile(r"\d{4}[-]\d{2}[-]\d{2}T\d{2}:\d{2}:\d{2}" + r"\.?\d*Z?[-+]?[\d{2}]?:?[\d{2}]?") +_VALID_RFC7231 = re.compile( + r"(Mon|Tue|Wed|Thu|Fri|Sat|Sun),\s\d{2}\s" + r"(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s\d{4}\s\d{2}:\d{2}:\d{2}\sGMT" +) + + +def _deserialize_datetime(attr: typing.Union[str, datetime]) -> datetime: + """Deserialize ISO-8601 formatted string into Datetime object. + + :param str attr: response string to be deserialized. + :rtype: ~datetime.datetime + :returns: The datetime object from that input + """ + if isinstance(attr, datetime): + # i'm already deserialized + return attr + attr = attr.upper() + match = _VALID_DATE.match(attr) + if not match: + raise ValueError("Invalid datetime string: " + attr) + + check_decimal = attr.split(".") + if len(check_decimal) > 1: + decimal_str = "" + for digit in check_decimal[1]: + if digit.isdigit(): + decimal_str += digit + else: + break + if len(decimal_str) > 6: + attr = attr.replace(decimal_str, decimal_str[0:6]) + + date_obj = isodate.parse_datetime(attr) + test_utc = date_obj.utctimetuple() + if test_utc.tm_year > 9999 or test_utc.tm_year < 1: + raise OverflowError("Hit max or min date") + return date_obj + + +def _deserialize_datetime_rfc7231(attr: typing.Union[str, datetime]) -> datetime: + """Deserialize RFC7231 formatted string into Datetime object. + + :param str attr: response string to be deserialized. + :rtype: ~datetime.datetime + :returns: The datetime object from that input + """ + if isinstance(attr, datetime): + # i'm already deserialized + return attr + match = _VALID_RFC7231.match(attr) + if not match: + raise ValueError("Invalid datetime string: " + attr) + + return email.utils.parsedate_to_datetime(attr) + + +def _deserialize_datetime_unix_timestamp(attr: typing.Union[float, datetime]) -> datetime: + """Deserialize unix timestamp into Datetime object. + + :param str attr: response string to be deserialized. + :rtype: ~datetime.datetime + :returns: The datetime object from that input + """ + if isinstance(attr, datetime): + # i'm already deserialized + return attr + return datetime.fromtimestamp(attr, TZ_UTC) + + +def _deserialize_date(attr: typing.Union[str, date]) -> date: + """Deserialize ISO-8601 formatted string into Date object. + :param str attr: response string to be deserialized. + :rtype: date + :returns: The date object from that input + """ + # This must NOT use defaultmonth/defaultday. Using None ensure this raises an exception. + if isinstance(attr, date): + return attr + return isodate.parse_date(attr, defaultmonth=None, defaultday=None) # type: ignore + + +def _deserialize_time(attr: typing.Union[str, time]) -> time: + """Deserialize ISO-8601 formatted string into time object. + + :param str attr: response string to be deserialized. + :rtype: datetime.time + :returns: The time object from that input + """ + if isinstance(attr, time): + return attr + return isodate.parse_time(attr) + + +def _deserialize_bytes(attr): + if isinstance(attr, (bytes, bytearray)): + return attr + return bytes(base64.b64decode(attr)) + + +def _deserialize_bytes_base64(attr): + if isinstance(attr, (bytes, bytearray)): + return attr + padding = "=" * (3 - (len(attr) + 3) % 4) # type: ignore + attr = attr + padding # type: ignore + encoded = attr.replace("-", "+").replace("_", "/") + return bytes(base64.b64decode(encoded)) + + +def _deserialize_duration(attr): + if isinstance(attr, timedelta): + return attr + return isodate.parse_duration(attr) + + +def _deserialize_decimal(attr): + if isinstance(attr, decimal.Decimal): + return attr + return decimal.Decimal(str(attr)) + + +def _deserialize_int_as_str(attr): + if isinstance(attr, int): + return attr + return int(attr) + + +_DESERIALIZE_MAPPING = { + datetime: _deserialize_datetime, + date: _deserialize_date, + time: _deserialize_time, + bytes: _deserialize_bytes, + bytearray: _deserialize_bytes, + timedelta: _deserialize_duration, + typing.Any: lambda x: x, + decimal.Decimal: _deserialize_decimal, +} + +_DESERIALIZE_MAPPING_WITHFORMAT = { + "rfc3339": _deserialize_datetime, + "rfc7231": _deserialize_datetime_rfc7231, + "unix-timestamp": _deserialize_datetime_unix_timestamp, + "base64": _deserialize_bytes, + "base64url": _deserialize_bytes_base64, +} + + +def get_deserializer(annotation: typing.Any, rf: typing.Optional["_RestField"] = None): + if annotation is int and rf and rf._format == "str": + return _deserialize_int_as_str + if rf and rf._format: + return _DESERIALIZE_MAPPING_WITHFORMAT.get(rf._format) + return _DESERIALIZE_MAPPING.get(annotation) # pyright: ignore + + +def _get_type_alias_type(module_name: str, alias_name: str): + types = { + k: v + for k, v in sys.modules[module_name].__dict__.items() + if isinstance(v, typing._GenericAlias) # type: ignore + } + if alias_name not in types: + return alias_name + return types[alias_name] + + +def _get_model(module_name: str, model_name: str): + models = {k: v for k, v in sys.modules[module_name].__dict__.items() if isinstance(v, type)} + module_end = module_name.rsplit(".", 1)[0] + models.update({k: v for k, v in sys.modules[module_end].__dict__.items() if isinstance(v, type)}) + if isinstance(model_name, str): + model_name = model_name.split(".")[-1] + if model_name not in models: + return model_name + return models[model_name] + + +_UNSET = object() + + +class _MyMutableMapping(MutableMapping[str, typing.Any]): # pylint: disable=unsubscriptable-object + def __init__(self, data: typing.Dict[str, typing.Any]) -> None: + self._data = data + + def __contains__(self, key: typing.Any) -> bool: + return key in self._data + + def __getitem__(self, key: str) -> typing.Any: + return self._data.__getitem__(key) + + def __setitem__(self, key: str, value: typing.Any) -> None: + self._data.__setitem__(key, value) + + def __delitem__(self, key: str) -> None: + self._data.__delitem__(key) + + def __iter__(self) -> typing.Iterator[typing.Any]: + return self._data.__iter__() + + def __len__(self) -> int: + return self._data.__len__() + + def __ne__(self, other: typing.Any) -> bool: + return not self.__eq__(other) + + def keys(self) -> typing.KeysView[str]: + """ + :returns: a set-like object providing a view on D's keys + :rtype: ~typing.KeysView + """ + return self._data.keys() + + def values(self) -> typing.ValuesView[typing.Any]: + """ + :returns: an object providing a view on D's values + :rtype: ~typing.ValuesView + """ + return self._data.values() + + def items(self) -> typing.ItemsView[str, typing.Any]: + """ + :returns: set-like object providing a view on D's items + :rtype: ~typing.ItemsView + """ + return self._data.items() + + def get(self, key: str, default: typing.Any = None) -> typing.Any: + """ + Get the value for key if key is in the dictionary, else default. + :param str key: The key to look up. + :param any default: The value to return if key is not in the dictionary. Defaults to None + :returns: D[k] if k in D, else d. + :rtype: any + """ + try: + return self[key] + except KeyError: + return default + + @typing.overload + def pop(self, key: str) -> typing.Any: ... + + @typing.overload + def pop(self, key: str, default: _T) -> _T: ... + + @typing.overload + def pop(self, key: str, default: typing.Any) -> typing.Any: ... + + def pop(self, key: str, default: typing.Any = _UNSET) -> typing.Any: + """ + Removes specified key and return the corresponding value. + :param str key: The key to pop. + :param any default: The value to return if key is not in the dictionary + :returns: The value corresponding to the key. + :rtype: any + :raises KeyError: If key is not found and default is not given. + """ + if default is _UNSET: + return self._data.pop(key) + return self._data.pop(key, default) + + def popitem(self) -> typing.Tuple[str, typing.Any]: + """ + Removes and returns some (key, value) pair + :returns: The (key, value) pair. + :rtype: tuple + :raises KeyError: if D is empty. + """ + return self._data.popitem() + + def clear(self) -> None: + """ + Remove all items from D. + """ + self._data.clear() + + def update(self, *args: typing.Any, **kwargs: typing.Any) -> None: + """ + Updates D from mapping/iterable E and F. + :param any args: Either a mapping object or an iterable of key-value pairs. + """ + self._data.update(*args, **kwargs) + + @typing.overload + def setdefault(self, key: str, default: None = None) -> None: ... + + @typing.overload + def setdefault(self, key: str, default: typing.Any) -> typing.Any: ... + + def setdefault(self, key: str, default: typing.Any = _UNSET) -> typing.Any: + """ + Same as calling D.get(k, d), and setting D[k]=d if k not found + :param str key: The key to look up. + :param any default: The value to set if key is not in the dictionary + :returns: D[k] if k in D, else d. + :rtype: any + """ + if default is _UNSET: + return self._data.setdefault(key) + return self._data.setdefault(key, default) + + def __eq__(self, other: typing.Any) -> bool: + try: + other_model = self.__class__(other) + except Exception: + return False + return self._data == other_model._data + + def __repr__(self) -> str: + return str(self._data) + + +def _is_model(obj: typing.Any) -> bool: + return getattr(obj, "_is_model", False) + + +def _serialize(o, format: typing.Optional[str] = None): # pylint: disable=too-many-return-statements + if isinstance(o, list): + return [_serialize(x, format) for x in o] + if isinstance(o, dict): + return {k: _serialize(v, format) for k, v in o.items()} + if isinstance(o, set): + return {_serialize(x, format) for x in o} + if isinstance(o, tuple): + return tuple(_serialize(x, format) for x in o) + if isinstance(o, (bytes, bytearray)): + return _serialize_bytes(o, format) + if isinstance(o, decimal.Decimal): + return float(o) + if isinstance(o, enum.Enum): + return o.value + if isinstance(o, int): + if format == "str": + return str(o) + return o + try: + # First try datetime.datetime + return _serialize_datetime(o, format) + except AttributeError: + pass + # Last, try datetime.timedelta + try: + return _timedelta_as_isostr(o) + except AttributeError: + # This will be raised when it hits value.total_seconds in the method above + pass + return o + + +def _get_rest_field( + attr_to_rest_field: typing.Dict[str, "_RestField"], rest_name: str +) -> typing.Optional["_RestField"]: + try: + return next(rf for rf in attr_to_rest_field.values() if rf._rest_name == rest_name) + except StopIteration: + return None + + +def _create_value(rf: typing.Optional["_RestField"], value: typing.Any) -> typing.Any: + if not rf: + return _serialize(value, None) + if rf._is_multipart_file_input: + return value + if rf._is_model: + return _deserialize(rf._type, value) + if isinstance(value, ET.Element): + value = _deserialize(rf._type, value) + return _serialize(value, rf._format) + + +class Model(_MyMutableMapping): + _is_model = True + # label whether current class's _attr_to_rest_field has been calculated + # could not see _attr_to_rest_field directly because subclass inherits it from parent class + _calculated: typing.Set[str] = set() + + def __init__(self, *args: typing.Any, **kwargs: typing.Any) -> None: + class_name = self.__class__.__name__ + if len(args) > 1: + raise TypeError(f"{class_name}.__init__() takes 2 positional arguments but {len(args) + 1} were given") + dict_to_pass = { + rest_field._rest_name: rest_field._default + for rest_field in self._attr_to_rest_field.values() + if rest_field._default is not _UNSET + } + if args: # pylint: disable=too-many-nested-blocks + if isinstance(args[0], ET.Element): + existed_attr_keys = [] + model_meta = getattr(self, "_xml", {}) + + for rf in self._attr_to_rest_field.values(): + prop_meta = getattr(rf, "_xml", {}) + xml_name = prop_meta.get("name", rf._rest_name) + xml_ns = prop_meta.get("ns", model_meta.get("ns", None)) + if xml_ns: + xml_name = "{" + xml_ns + "}" + xml_name + + # attribute + if prop_meta.get("attribute", False) and args[0].get(xml_name) is not None: + existed_attr_keys.append(xml_name) + dict_to_pass[rf._rest_name] = _deserialize(rf._type, args[0].get(xml_name)) + continue + + # unwrapped element is array + if prop_meta.get("unwrapped", False): + # unwrapped array could either use prop items meta/prop meta + if prop_meta.get("itemsName"): + xml_name = prop_meta.get("itemsName") + xml_ns = prop_meta.get("itemNs") + if xml_ns: + xml_name = "{" + xml_ns + "}" + xml_name + items = args[0].findall(xml_name) # pyright: ignore + if len(items) > 0: + existed_attr_keys.append(xml_name) + dict_to_pass[rf._rest_name] = _deserialize(rf._type, items) + continue + + # text element is primitive type + if prop_meta.get("text", False): + if args[0].text is not None: + dict_to_pass[rf._rest_name] = _deserialize(rf._type, args[0].text) + continue + + # wrapped element could be normal property or array, it should only have one element + item = args[0].find(xml_name) + if item is not None: + existed_attr_keys.append(xml_name) + dict_to_pass[rf._rest_name] = _deserialize(rf._type, item) + + # rest thing is additional properties + for e in args[0]: + if e.tag not in existed_attr_keys: + dict_to_pass[e.tag] = _convert_element(e) + else: + dict_to_pass.update( + {k: _create_value(_get_rest_field(self._attr_to_rest_field, k), v) for k, v in args[0].items()} + ) + else: + non_attr_kwargs = [k for k in kwargs if k not in self._attr_to_rest_field] + if non_attr_kwargs: + # actual type errors only throw the first wrong keyword arg they see, so following that. + raise TypeError(f"{class_name}.__init__() got an unexpected keyword argument '{non_attr_kwargs[0]}'") + dict_to_pass.update( + { + self._attr_to_rest_field[k]._rest_name: _create_value(self._attr_to_rest_field[k], v) + for k, v in kwargs.items() + if v is not None + } + ) + super().__init__(dict_to_pass) + + def copy(self) -> "Model": + return Model(self.__dict__) + + def __new__(cls, *args: typing.Any, **kwargs: typing.Any) -> Self: + if f"{cls.__module__}.{cls.__qualname__}" not in cls._calculated: + # we know the last nine classes in mro are going to be 'Model', '_MyMutableMapping', 'MutableMapping', + # 'Mapping', 'Collection', 'Sized', 'Iterable', 'Container' and 'object' + mros = cls.__mro__[:-9][::-1] # ignore parents, and reverse the mro order + attr_to_rest_field: typing.Dict[str, _RestField] = { # map attribute name to rest_field property + k: v for mro_class in mros for k, v in mro_class.__dict__.items() if k[0] != "_" and hasattr(v, "_type") + } + annotations = { + k: v + for mro_class in mros + if hasattr(mro_class, "__annotations__") + for k, v in mro_class.__annotations__.items() + } + for attr, rf in attr_to_rest_field.items(): + rf._module = cls.__module__ + if not rf._type: + rf._type = rf._get_deserialize_callable_from_annotation(annotations.get(attr, None)) + if not rf._rest_name_input: + rf._rest_name_input = attr + cls._attr_to_rest_field: typing.Dict[str, _RestField] = dict(attr_to_rest_field.items()) + cls._calculated.add(f"{cls.__module__}.{cls.__qualname__}") + + return super().__new__(cls) # pylint: disable=no-value-for-parameter + + def __init_subclass__(cls, discriminator: typing.Optional[str] = None) -> None: + for base in cls.__bases__: + if hasattr(base, "__mapping__"): + base.__mapping__[discriminator or cls.__name__] = cls # type: ignore + + @classmethod + def _get_discriminator(cls, exist_discriminators) -> typing.Optional["_RestField"]: + for v in cls.__dict__.values(): + if isinstance(v, _RestField) and v._is_discriminator and v._rest_name not in exist_discriminators: + return v + return None + + @classmethod + def _deserialize(cls, data, exist_discriminators): + if not hasattr(cls, "__mapping__"): + return cls(data) + discriminator = cls._get_discriminator(exist_discriminators) + if discriminator is None: + return cls(data) + exist_discriminators.append(discriminator._rest_name) + if isinstance(data, ET.Element): + model_meta = getattr(cls, "_xml", {}) + prop_meta = getattr(discriminator, "_xml", {}) + xml_name = prop_meta.get("name", discriminator._rest_name) + xml_ns = prop_meta.get("ns", model_meta.get("ns", None)) + if xml_ns: + xml_name = "{" + xml_ns + "}" + xml_name + + if data.get(xml_name) is not None: + discriminator_value = data.get(xml_name) + else: + discriminator_value = data.find(xml_name).text # pyright: ignore + else: + discriminator_value = data.get(discriminator._rest_name) + mapped_cls = cls.__mapping__.get(discriminator_value, cls) # pyright: ignore + return mapped_cls._deserialize(data, exist_discriminators) + + def as_dict(self, *, exclude_readonly: bool = False) -> typing.Dict[str, typing.Any]: + """Return a dict that can be turned into json using json.dump. + + :keyword bool exclude_readonly: Whether to remove the readonly properties. + :returns: A dict JSON compatible object + :rtype: dict + """ + + result = {} + readonly_props = [] + if exclude_readonly: + readonly_props = [p._rest_name for p in self._attr_to_rest_field.values() if _is_readonly(p)] + for k, v in self.items(): + if exclude_readonly and k in readonly_props: # pyright: ignore + continue + is_multipart_file_input = False + try: + is_multipart_file_input = next( + rf for rf in self._attr_to_rest_field.values() if rf._rest_name == k + )._is_multipart_file_input + except StopIteration: + pass + result[k] = v if is_multipart_file_input else Model._as_dict_value(v, exclude_readonly=exclude_readonly) + return result + + @staticmethod + def _as_dict_value(v: typing.Any, exclude_readonly: bool = False) -> typing.Any: + if v is None or isinstance(v, _Null): + return None + if isinstance(v, (list, tuple, set)): + return type(v)(Model._as_dict_value(x, exclude_readonly=exclude_readonly) for x in v) + if isinstance(v, dict): + return {dk: Model._as_dict_value(dv, exclude_readonly=exclude_readonly) for dk, dv in v.items()} + return v.as_dict(exclude_readonly=exclude_readonly) if hasattr(v, "as_dict") else v + + +def _deserialize_model(model_deserializer: typing.Optional[typing.Callable], obj): + if _is_model(obj): + return obj + return _deserialize(model_deserializer, obj) + + +def _deserialize_with_optional(if_obj_deserializer: typing.Optional[typing.Callable], obj): + if obj is None: + return obj + return _deserialize_with_callable(if_obj_deserializer, obj) + + +def _deserialize_with_union(deserializers, obj): + for deserializer in deserializers: + try: + return _deserialize(deserializer, obj) + except DeserializationError: + pass + raise DeserializationError() + + +def _deserialize_dict( + value_deserializer: typing.Optional[typing.Callable], + module: typing.Optional[str], + obj: typing.Dict[typing.Any, typing.Any], +): + if obj is None: + return obj + if isinstance(obj, ET.Element): + obj = {child.tag: child for child in obj} + return {k: _deserialize(value_deserializer, v, module) for k, v in obj.items()} + + +def _deserialize_multiple_sequence( + entry_deserializers: typing.List[typing.Optional[typing.Callable]], + module: typing.Optional[str], + obj, +): + if obj is None: + return obj + return type(obj)(_deserialize(deserializer, entry, module) for entry, deserializer in zip(obj, entry_deserializers)) + + +def _deserialize_sequence( + deserializer: typing.Optional[typing.Callable], + module: typing.Optional[str], + obj, +): + if obj is None: + return obj + if isinstance(obj, ET.Element): + obj = list(obj) + return type(obj)(_deserialize(deserializer, entry, module) for entry in obj) + + +def _sorted_annotations(types: typing.List[typing.Any]) -> typing.List[typing.Any]: + return sorted( + types, + key=lambda x: hasattr(x, "__name__") and x.__name__.lower() in ("str", "float", "int", "bool"), + ) + + +def _get_deserialize_callable_from_annotation( # pylint: disable=too-many-return-statements, too-many-branches + annotation: typing.Any, + module: typing.Optional[str], + rf: typing.Optional["_RestField"] = None, +) -> typing.Optional[typing.Callable[[typing.Any], typing.Any]]: + if not annotation: + return None + + # is it a type alias? + if isinstance(annotation, str): + if module is not None: + annotation = _get_type_alias_type(module, annotation) + + # is it a forward ref / in quotes? + if isinstance(annotation, (str, typing.ForwardRef)): + try: + model_name = annotation.__forward_arg__ # type: ignore + except AttributeError: + model_name = annotation + if module is not None: + annotation = _get_model(module, model_name) # type: ignore + + try: + if module and _is_model(annotation): + if rf: + rf._is_model = True + + return functools.partial(_deserialize_model, annotation) # pyright: ignore + except Exception: + pass + + # is it a literal? + try: + if annotation.__origin__ is typing.Literal: # pyright: ignore + return None + except AttributeError: + pass + + # is it optional? + try: + if any(a for a in annotation.__args__ if a == type(None)): # pyright: ignore + if len(annotation.__args__) <= 2: # pyright: ignore + if_obj_deserializer = _get_deserialize_callable_from_annotation( + next(a for a in annotation.__args__ if a != type(None)), module, rf # pyright: ignore + ) + + return functools.partial(_deserialize_with_optional, if_obj_deserializer) + # the type is Optional[Union[...]], we need to remove the None type from the Union + annotation_copy = copy.copy(annotation) + annotation_copy.__args__ = [a for a in annotation_copy.__args__ if a != type(None)] # pyright: ignore + return _get_deserialize_callable_from_annotation(annotation_copy, module, rf) + except AttributeError: + pass + + # is it union? + if getattr(annotation, "__origin__", None) is typing.Union: + # initial ordering is we make `string` the last deserialization option, because it is often them most generic + deserializers = [ + _get_deserialize_callable_from_annotation(arg, module, rf) + for arg in _sorted_annotations(annotation.__args__) # pyright: ignore + ] + + return functools.partial(_deserialize_with_union, deserializers) + + try: + if annotation._name == "Dict": # pyright: ignore + value_deserializer = _get_deserialize_callable_from_annotation( + annotation.__args__[1], module, rf # pyright: ignore + ) + + return functools.partial( + _deserialize_dict, + value_deserializer, + module, + ) + except (AttributeError, IndexError): + pass + try: + if annotation._name in ["List", "Set", "Tuple", "Sequence"]: # pyright: ignore + if len(annotation.__args__) > 1: # pyright: ignore + entry_deserializers = [ + _get_deserialize_callable_from_annotation(dt, module, rf) + for dt in annotation.__args__ # pyright: ignore + ] + return functools.partial(_deserialize_multiple_sequence, entry_deserializers, module) + deserializer = _get_deserialize_callable_from_annotation( + annotation.__args__[0], module, rf # pyright: ignore + ) + + return functools.partial(_deserialize_sequence, deserializer, module) + except (TypeError, IndexError, AttributeError, SyntaxError): + pass + + def _deserialize_default( + deserializer, + obj, + ): + if obj is None: + return obj + try: + return _deserialize_with_callable(deserializer, obj) + except Exception: + pass + return obj + + if get_deserializer(annotation, rf): + return functools.partial(_deserialize_default, get_deserializer(annotation, rf)) + + return functools.partial(_deserialize_default, annotation) + + +def _deserialize_with_callable( + deserializer: typing.Optional[typing.Callable[[typing.Any], typing.Any]], + value: typing.Any, +): # pylint: disable=too-many-return-statements + try: + if value is None or isinstance(value, _Null): + return None + if isinstance(value, ET.Element): + if deserializer is str: + return value.text or "" + if deserializer is int: + return int(value.text) if value.text else None + if deserializer is float: + return float(value.text) if value.text else None + if deserializer is bool: + return value.text == "true" if value.text else None + if deserializer is None: + return value + if deserializer in [int, float, bool]: + return deserializer(value) + if isinstance(deserializer, CaseInsensitiveEnumMeta): + try: + return deserializer(value) + except ValueError: + # for unknown value, return raw value + return value + if isinstance(deserializer, type) and issubclass(deserializer, Model): + return deserializer._deserialize(value, []) + return typing.cast(typing.Callable[[typing.Any], typing.Any], deserializer)(value) + except Exception as e: + raise DeserializationError() from e + + +def _deserialize( + deserializer: typing.Any, + value: typing.Any, + module: typing.Optional[str] = None, + rf: typing.Optional["_RestField"] = None, + format: typing.Optional[str] = None, +) -> typing.Any: + if isinstance(value, PipelineResponse): + value = value.http_response.json() + if rf is None and format: + rf = _RestField(format=format) + if not isinstance(deserializer, functools.partial): + deserializer = _get_deserialize_callable_from_annotation(deserializer, module, rf) + return _deserialize_with_callable(deserializer, value) + + +def _failsafe_deserialize( + deserializer: typing.Any, + value: typing.Any, + module: typing.Optional[str] = None, + rf: typing.Optional["_RestField"] = None, + format: typing.Optional[str] = None, +) -> typing.Any: + try: + return _deserialize(deserializer, value, module, rf, format) + except DeserializationError: + _LOGGER.warning( + "Ran into a deserialization error. Ignoring since this is failsafe deserialization", exc_info=True + ) + return None + + +def _failsafe_deserialize_xml( + deserializer: typing.Any, + value: typing.Any, +) -> typing.Any: + try: + return _deserialize_xml(deserializer, value) + except DeserializationError: + _LOGGER.warning( + "Ran into a deserialization error. Ignoring since this is failsafe deserialization", exc_info=True + ) + return None + + +class _RestField: + def __init__( + self, + *, + name: typing.Optional[str] = None, + type: typing.Optional[typing.Callable] = None, # pylint: disable=redefined-builtin + is_discriminator: bool = False, + visibility: typing.Optional[typing.List[str]] = None, + default: typing.Any = _UNSET, + format: typing.Optional[str] = None, + is_multipart_file_input: bool = False, + xml: typing.Optional[typing.Dict[str, typing.Any]] = None, + ): + self._type = type + self._rest_name_input = name + self._module: typing.Optional[str] = None + self._is_discriminator = is_discriminator + self._visibility = visibility + self._is_model = False + self._default = default + self._format = format + self._is_multipart_file_input = is_multipart_file_input + self._xml = xml if xml is not None else {} + + @property + def _class_type(self) -> typing.Any: + return getattr(self._type, "args", [None])[0] + + @property + def _rest_name(self) -> str: + if self._rest_name_input is None: + raise ValueError("Rest name was never set") + return self._rest_name_input + + def __get__(self, obj: Model, type=None): # pylint: disable=redefined-builtin + # by this point, type and rest_name will have a value bc we default + # them in __new__ of the Model class + item = obj.get(self._rest_name) + if item is None: + return item + if self._is_model: + return item + return _deserialize(self._type, _serialize(item, self._format), rf=self) + + def __set__(self, obj: Model, value) -> None: + if value is None: + # we want to wipe out entries if users set attr to None + try: + obj.__delitem__(self._rest_name) + except KeyError: + pass + return + if self._is_model: + if not _is_model(value): + value = _deserialize(self._type, value) + obj.__setitem__(self._rest_name, value) + return + obj.__setitem__(self._rest_name, _serialize(value, self._format)) + + def _get_deserialize_callable_from_annotation( + self, annotation: typing.Any + ) -> typing.Optional[typing.Callable[[typing.Any], typing.Any]]: + return _get_deserialize_callable_from_annotation(annotation, self._module, self) + + +def rest_field( + *, + name: typing.Optional[str] = None, + type: typing.Optional[typing.Callable] = None, # pylint: disable=redefined-builtin + visibility: typing.Optional[typing.List[str]] = None, + default: typing.Any = _UNSET, + format: typing.Optional[str] = None, + is_multipart_file_input: bool = False, + xml: typing.Optional[typing.Dict[str, typing.Any]] = None, +) -> typing.Any: + return _RestField( + name=name, + type=type, + visibility=visibility, + default=default, + format=format, + is_multipart_file_input=is_multipart_file_input, + xml=xml, + ) + + +def rest_discriminator( + *, + name: typing.Optional[str] = None, + type: typing.Optional[typing.Callable] = None, # pylint: disable=redefined-builtin + visibility: typing.Optional[typing.List[str]] = None, + xml: typing.Optional[typing.Dict[str, typing.Any]] = None, +) -> typing.Any: + return _RestField(name=name, type=type, is_discriminator=True, visibility=visibility, xml=xml) + + +def serialize_xml(model: Model, exclude_readonly: bool = False) -> str: + """Serialize a model to XML. + + :param Model model: The model to serialize. + :param bool exclude_readonly: Whether to exclude readonly properties. + :returns: The XML representation of the model. + :rtype: str + """ + return ET.tostring(_get_element(model, exclude_readonly), encoding="unicode") # type: ignore + + +def _get_element( + o: typing.Any, + exclude_readonly: bool = False, + parent_meta: typing.Optional[typing.Dict[str, typing.Any]] = None, + wrapped_element: typing.Optional[ET.Element] = None, +) -> typing.Union[ET.Element, typing.List[ET.Element]]: + if _is_model(o): + model_meta = getattr(o, "_xml", {}) + + # if prop is a model, then use the prop element directly, else generate a wrapper of model + if wrapped_element is None: + wrapped_element = _create_xml_element( + model_meta.get("name", o.__class__.__name__), + model_meta.get("prefix"), + model_meta.get("ns"), + ) + + readonly_props = [] + if exclude_readonly: + readonly_props = [p._rest_name for p in o._attr_to_rest_field.values() if _is_readonly(p)] + + for k, v in o.items(): + # do not serialize readonly properties + if exclude_readonly and k in readonly_props: + continue + + prop_rest_field = _get_rest_field(o._attr_to_rest_field, k) + if prop_rest_field: + prop_meta = getattr(prop_rest_field, "_xml").copy() + # use the wire name as xml name if no specific name is set + if prop_meta.get("name") is None: + prop_meta["name"] = k + else: + # additional properties will not have rest field, use the wire name as xml name + prop_meta = {"name": k} + + # if no ns for prop, use model's + if prop_meta.get("ns") is None and model_meta.get("ns"): + prop_meta["ns"] = model_meta.get("ns") + prop_meta["prefix"] = model_meta.get("prefix") + + if prop_meta.get("unwrapped", False): + # unwrapped could only set on array + wrapped_element.extend(_get_element(v, exclude_readonly, prop_meta)) + elif prop_meta.get("text", False): + # text could only set on primitive type + wrapped_element.text = _get_primitive_type_value(v) + elif prop_meta.get("attribute", False): + xml_name = prop_meta.get("name", k) + if prop_meta.get("ns"): + ET.register_namespace(prop_meta.get("prefix"), prop_meta.get("ns")) # pyright: ignore + xml_name = "{" + prop_meta.get("ns") + "}" + xml_name # pyright: ignore + # attribute should be primitive type + wrapped_element.set(xml_name, _get_primitive_type_value(v)) + else: + # other wrapped prop element + wrapped_element.append(_get_wrapped_element(v, exclude_readonly, prop_meta)) + return wrapped_element + if isinstance(o, list): + return [_get_element(x, exclude_readonly, parent_meta) for x in o] # type: ignore + if isinstance(o, dict): + result = [] + for k, v in o.items(): + result.append( + _get_wrapped_element( + v, + exclude_readonly, + { + "name": k, + "ns": parent_meta.get("ns") if parent_meta else None, + "prefix": parent_meta.get("prefix") if parent_meta else None, + }, + ) + ) + return result + + # primitive case need to create element based on parent_meta + if parent_meta: + return _get_wrapped_element( + o, + exclude_readonly, + { + "name": parent_meta.get("itemsName", parent_meta.get("name")), + "prefix": parent_meta.get("itemsPrefix", parent_meta.get("prefix")), + "ns": parent_meta.get("itemsNs", parent_meta.get("ns")), + }, + ) + + raise ValueError("Could not serialize value into xml: " + o) + + +def _get_wrapped_element( + v: typing.Any, + exclude_readonly: bool, + meta: typing.Optional[typing.Dict[str, typing.Any]], +) -> ET.Element: + wrapped_element = _create_xml_element( + meta.get("name") if meta else None, meta.get("prefix") if meta else None, meta.get("ns") if meta else None + ) + if isinstance(v, (dict, list)): + wrapped_element.extend(_get_element(v, exclude_readonly, meta)) + elif _is_model(v): + _get_element(v, exclude_readonly, meta, wrapped_element) + else: + wrapped_element.text = _get_primitive_type_value(v) + return wrapped_element + + +def _get_primitive_type_value(v) -> str: + if v is True: + return "true" + if v is False: + return "false" + if isinstance(v, _Null): + return "" + return str(v) + + +def _create_xml_element(tag, prefix=None, ns=None): + if prefix and ns: + ET.register_namespace(prefix, ns) + if ns: + return ET.Element("{" + ns + "}" + tag) + return ET.Element(tag) + + +def _deserialize_xml( + deserializer: typing.Any, + value: str, +) -> typing.Any: + element = ET.fromstring(value) # nosec + return _deserialize(deserializer, element) + + +def _convert_element(e: ET.Element): + # dict case + if len(e.attrib) > 0 or len({child.tag for child in e}) > 1: + dict_result: typing.Dict[str, typing.Any] = {} + for child in e: + if dict_result.get(child.tag) is not None: + if isinstance(dict_result[child.tag], list): + dict_result[child.tag].append(_convert_element(child)) + else: + dict_result[child.tag] = [dict_result[child.tag], _convert_element(child)] + else: + dict_result[child.tag] = _convert_element(child) + dict_result.update(e.attrib) + return dict_result + # array case + if len(e) > 0: + array_result: typing.List[typing.Any] = [] + for child in e: + array_result.append(_convert_element(child)) + return array_result + # primitive case + return e.text diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_models.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_models.py deleted file mode 100644 index b944ed0c3e91..000000000000 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_models.py +++ /dev/null @@ -1,232 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from typing import Any, Dict, Optional, Union - -from azure.core.rest import HttpResponse - -from ._enums import KeyVaultSettingType -from ._generated.models import ( - FullBackupOperation, - Permission, - RoleAssignment, - RoleAssignmentProperties, - RoleAssignmentPropertiesWithScope, - RoleDefinition, - Setting, -) - - -class KeyVaultPermission(object): - """Role definition permissions. - - :ivar list[str] actions: Action permissions that are granted. - :ivar list[str] not_actions: Action permissions that are excluded but not denied. They may be granted by other role - definitions assigned to a principal. - :ivar list[str] data_actions: Data action permissions that are granted. - :ivar list[str] not_data_actions: Data action permissions that are excluded but not denied. They may be granted by - other role definitions assigned to a principal. - """ - - def __init__(self, **kwargs: Any) -> None: - self.actions = kwargs.get("actions") - self.not_actions = kwargs.get("not_actions") - self.data_actions = kwargs.get("data_actions") - self.not_data_actions = kwargs.get("not_data_actions") - - @classmethod - def _from_generated(cls, permissions: Permission) -> "KeyVaultPermission": - return cls( - actions=permissions.actions, - not_actions=permissions.not_actions, - data_actions=permissions.data_actions, - not_data_actions=permissions.not_data_actions, - ) - - -class KeyVaultRoleAssignment(object): - """Represents the assignment to a principal of a role over a scope - - :ivar str name: the assignment's name - :ivar KeyVaultRoleAssignmentProperties properties: the assignment's properties - :ivar str role_assignment_id: unique identifier for the assignment - :ivar str type: type of the assignment - """ - - def __init__(self, **kwargs: Any) -> None: - self.name = kwargs.get("name") - self.properties = kwargs.get("properties") - self.role_assignment_id = kwargs.get("role_assignment_id") - self.type = kwargs.get("assignment_type") - - def __repr__(self) -> str: - return f"KeyVaultRoleAssignment<{self.role_assignment_id}>" - - @classmethod - def _from_generated(cls, role_assignment: RoleAssignment) -> "KeyVaultRoleAssignment": - # pylint:disable=protected-access - return cls( - role_assignment_id=role_assignment.id, - name=role_assignment.name, - assignment_type=role_assignment.type, - properties=KeyVaultRoleAssignmentProperties._from_generated(role_assignment.properties) - if role_assignment.properties - else KeyVaultRoleAssignmentProperties(), - ) - - -class KeyVaultRoleAssignmentProperties(object): - """Properties of a role assignment - - :ivar str principal_id: ID of the principal the assignment applies to. This maps to an Active Directory user, - service principal, or security group. - :ivar str role_definition_id: ID of the scope's role definition - :ivar str scope: the scope of the assignment - """ - - def __init__(self, **kwargs: Any) -> None: - self.principal_id = kwargs.get("principal_id") - self.role_definition_id = kwargs.get("role_definition_id") - self.scope = kwargs.get("scope") - - def __repr__(self) -> str: - string = ( - f"KeyVaultRoleAssignmentProperties(principal_id={self.principal_id}, " - + f"role_definition_id={self.role_definition_id}, scope={self.scope})" - ) - return string[:1024] - - @classmethod - def _from_generated( - cls, role_assignment_properties: Union[RoleAssignmentProperties, RoleAssignmentPropertiesWithScope] - ) -> "KeyVaultRoleAssignmentProperties": - # the generated RoleAssignmentProperties and RoleAssignmentPropertiesWithScope - # models differ only in that the latter has a "scope" attribute - return cls( - principal_id=role_assignment_properties.principal_id, - role_definition_id=role_assignment_properties.role_definition_id, - scope=getattr(role_assignment_properties, "scope", None), - ) - - -class KeyVaultRoleDefinition(object): - """The definition of a role over one or more scopes - - :ivar list[str] assignable_scopes: scopes the role can be assigned over - :ivar str description: description of the role definition - :ivar str id: unique identifier for this role definition - :ivar str name: the role definition's name - :ivar list[KeyVaultPermission] permissions: permissions defined for the role - :ivar str role_name: the role's name - :ivar str role_type: type of the role - :ivar str type: type of the role definition - """ - - def __init__(self, **kwargs: Any) -> None: - self.assignable_scopes = kwargs.get("assignable_scopes") - self.description = kwargs.get("description") - self.id = kwargs.get("id") - self.name = kwargs.get("name") - self.permissions = kwargs.get("permissions") - self.role_name = kwargs.get("role_name") - self.role_type = kwargs.get("role_type") - self.type = kwargs.get("type") - - def __repr__(self) -> str: - return f"KeyVaultRoleDefinition<{self.id}>" - - @classmethod - def _from_generated(cls, definition: RoleDefinition) -> "KeyVaultRoleDefinition": - # pylint:disable=protected-access - return cls( - assignable_scopes=definition.properties.assignable_scopes if definition.properties else None, - description=definition.properties.description if definition.properties else None, - id=definition.id, - name=definition.name, - permissions=[KeyVaultPermission._from_generated(p) for p in definition.properties.permissions or []] - if definition.properties - else None, - role_name=definition.properties.role_name if definition.properties else None, - role_type=definition.properties.role_type if definition.properties else None, - type=definition.type, - ) - - -class KeyVaultBackupResult(object): - """A Key Vault full backup operation result - - :ivar str folder_url: URL of the Azure Blob Storage container containing the backup - """ - - # pylint:disable=unused-argument - - def __init__(self, **kwargs: Any) -> None: - self.folder_url: Optional[str] = kwargs.get("folder_url") - - @classmethod - def _from_generated( - cls, response: HttpResponse, deserialized_operation: FullBackupOperation, response_headers: Dict - ) -> "KeyVaultBackupResult": - return cls(folder_url=deserialized_operation.azure_storage_blob_container_uri) - - -class KeyVaultSetting(object): - """A Key Vault setting. - - :ivar str name: The name of the account setting. - :ivar str value: The value of the account setting. - :ivar setting_type: The type specifier of the value. - :vartype setting_type: str or KeyVaultSettingType or None - - :param str name: The name of the account setting. - :param str value: The value of the account setting. - :param setting_type: The type specifier of the value. - :type setting_type: str or KeyVaultSettingType or None - """ - - def __init__( - self, - name: str, - value: Union[str, bool], - setting_type: Optional[Union[str, KeyVaultSettingType]] = None, - **kwargs, # pylint:disable=unused-argument - ) -> None: - self.name = name - self.value = value if isinstance(value, str) else str(value) # `value` is stored as a string - if setting_type == KeyVaultSettingType.BOOLEAN: - self.setting_type: Optional[Union[str, KeyVaultSettingType]] = KeyVaultSettingType.BOOLEAN - else: - self.setting_type = setting_type.lower() if isinstance(setting_type, str) else setting_type - - # If a setting type isn't provided, set it based on `value`'s type (without inferring from the value itself) - if self.setting_type is None: - if isinstance(value, bool): - self.setting_type = KeyVaultSettingType.BOOLEAN - - # If the setting is a boolean, lower-case the string for serialization - if self.setting_type == KeyVaultSettingType.BOOLEAN: - self.value = self.value.lower() - - def getboolean(self) -> bool: - """Gets the account setting value as a boolean if the ``setting_type`` is ``KeyVaultSettingType.BOOLEAN``. - - :returns: The account setting value as a boolean. - :rtype: bool - - :raises ValueError: if the ``setting_type`` is not boolean or the value cannot be represented as a boolean. - """ - if self.setting_type == KeyVaultSettingType.BOOLEAN: - if self.value == "true": - return True - if self.value == "false": - return False - raise ValueError( - 'The `setting_type` of the setting must be `KeyVaultSettingType.BOOLEAN` and the `value` must be "true" ' - 'or "false" in order to use `getboolean`.' - ) - - @classmethod - def _from_generated(cls, setting: Setting) -> "KeyVaultSetting": - setting_type = KeyVaultSettingType.BOOLEAN if setting.type == "boolean" else setting.type - return cls(name=setting.name, value=setting.value, setting_type=setting_type) diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/_patch.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_patch.py similarity index 100% rename from sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/_patch.py rename to sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_patch.py diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_sdk_moniker.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_sdk_moniker.py deleted file mode 100644 index c66afba3db94..000000000000 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_sdk_moniker.py +++ /dev/null @@ -1,7 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from ._version import VERSION - -SDK_MONIKER = f"keyvault-administration/{VERSION}" diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/_serialization.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_serialization.py similarity index 82% rename from sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/_serialization.py rename to sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_serialization.py index baa661cb82d2..a066e16a64dd 100644 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/_serialization.py +++ b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_serialization.py @@ -1,3 +1,4 @@ +# pylint: disable=too-many-lines # -------------------------------------------------------------------------- # # Copyright (c) Microsoft Corporation. All rights reserved. @@ -24,7 +25,6 @@ # # -------------------------------------------------------------------------- -# pylint: skip-file # pyright: reportUnnecessaryTypeIgnoreComment=false from base64 import b64decode, b64encode @@ -48,11 +48,8 @@ IO, Mapping, Callable, - TypeVar, MutableMapping, - Type, List, - Mapping, ) try: @@ -62,13 +59,13 @@ import xml.etree.ElementTree as ET import isodate # type: ignore +from typing_extensions import Self from azure.core.exceptions import DeserializationError, SerializationError from azure.core.serialization import NULL as CoreNull _BOM = codecs.BOM_UTF8.decode(encoding="utf-8") -ModelType = TypeVar("ModelType", bound="Model") JSON = MutableMapping[str, Any] @@ -91,6 +88,8 @@ def deserialize_from_text(cls, data: Optional[Union[AnyStr, IO]], content_type: :param data: Input, could be bytes or stream (will be decoded with UTF8) or text :type data: str or bytes or IO :param str content_type: The content type. + :return: The deserialized data. + :rtype: object """ if hasattr(data, "read"): # Assume a stream @@ -112,7 +111,7 @@ def deserialize_from_text(cls, data: Optional[Union[AnyStr, IO]], content_type: try: return json.loads(data_as_str) except ValueError as err: - raise DeserializationError("JSON is invalid: {}".format(err), err) + raise DeserializationError("JSON is invalid: {}".format(err), err) from err elif "xml" in (content_type or []): try: @@ -144,6 +143,8 @@ def _json_attemp(data): # context otherwise. _LOGGER.critical("Wasn't XML not JSON, failing") raise DeserializationError("XML is invalid") from err + elif content_type.startswith("text/"): + return data_as_str raise DeserializationError("Cannot deserialize content-type: {}".format(content_type)) @classmethod @@ -153,6 +154,11 @@ def deserialize_from_http_generics(cls, body_bytes: Optional[Union[AnyStr, IO]], Use bytes and headers to NOT use any requests/aiohttp or whatever specific implementation. Headers will tested for "content-type" + + :param bytes body_bytes: The body of the response. + :param dict headers: The headers of the response. + :returns: The deserialized data. + :rtype: object """ # Try to use content-type from headers if available content_type = None @@ -170,13 +176,6 @@ def deserialize_from_http_generics(cls, body_bytes: Optional[Union[AnyStr, IO]], return None -try: - basestring # type: ignore - unicode_str = unicode # type: ignore -except NameError: - basestring = str - unicode_str = str - _LOGGER = logging.getLogger(__name__) try: @@ -184,80 +183,31 @@ def deserialize_from_http_generics(cls, body_bytes: Optional[Union[AnyStr, IO]], except NameError: _long_type = int - -class UTC(datetime.tzinfo): - """Time Zone info for handling UTC""" - - def utcoffset(self, dt): - """UTF offset for UTC is 0.""" - return datetime.timedelta(0) - - def tzname(self, dt): - """Timestamp representation.""" - return "Z" - - def dst(self, dt): - """No daylight saving for UTC.""" - return datetime.timedelta(hours=1) - - -try: - from datetime import timezone as _FixedOffset # type: ignore -except ImportError: # Python 2.7 - - class _FixedOffset(datetime.tzinfo): # type: ignore - """Fixed offset in minutes east from UTC. - Copy/pasted from Python doc - :param datetime.timedelta offset: offset in timedelta format - """ - - def __init__(self, offset): - self.__offset = offset - - def utcoffset(self, dt): - return self.__offset - - def tzname(self, dt): - return str(self.__offset.total_seconds() / 3600) - - def __repr__(self): - return "".format(self.tzname(None)) - - def dst(self, dt): - return datetime.timedelta(0) - - def __getinitargs__(self): - return (self.__offset,) - - -try: - from datetime import timezone - - TZ_UTC = timezone.utc -except ImportError: - TZ_UTC = UTC() # type: ignore +TZ_UTC = datetime.timezone.utc _FLATTEN = re.compile(r"(? None: self.additional_properties: Optional[Dict[str, Any]] = {} - for k in kwargs: + for k in kwargs: # pylint: disable=consider-using-dict-items if k not in self._attribute_map: _LOGGER.warning("%s is not a known attribute of class %s and will be ignored", k, self.__class__) elif k in self._validation and self._validation[k].get("readonly", False): @@ -305,13 +262,23 @@ def __init__(self, **kwargs: Any) -> None: setattr(self, k, kwargs[k]) def __eq__(self, other: Any) -> bool: - """Compare objects by comparing all attributes.""" + """Compare objects by comparing all attributes. + + :param object other: The object to compare + :returns: True if objects are equal + :rtype: bool + """ if isinstance(other, self.__class__): return self.__dict__ == other.__dict__ return False def __ne__(self, other: Any) -> bool: - """Compare objects by comparing all attributes.""" + """Compare objects by comparing all attributes. + + :param object other: The object to compare + :returns: True if objects are not equal + :rtype: bool + """ return not self.__eq__(other) def __str__(self) -> str: @@ -331,7 +298,11 @@ def is_xml_model(cls) -> bool: @classmethod def _create_xml_node(cls): - """Create XML node.""" + """Create XML node. + + :returns: The XML node + :rtype: xml.etree.ElementTree.Element + """ try: xml_map = cls._xml_map # type: ignore except AttributeError: @@ -351,7 +322,9 @@ def serialize(self, keep_readonly: bool = False, **kwargs: Any) -> JSON: :rtype: dict """ serializer = Serializer(self._infer_class_models()) - return serializer._serialize(self, keep_readonly=keep_readonly, **kwargs) # type: ignore + return serializer._serialize( # type: ignore # pylint: disable=protected-access + self, keep_readonly=keep_readonly, **kwargs + ) def as_dict( self, @@ -385,12 +358,15 @@ def my_key_transformer(key, attr_desc, value): If you want XML serialization, you can pass the kwargs is_xml=True. + :param bool keep_readonly: If you want to serialize the readonly attributes :param function key_transformer: A key transformer function. :returns: A dict JSON compatible object :rtype: dict """ serializer = Serializer(self._infer_class_models()) - return serializer._serialize(self, key_transformer=key_transformer, keep_readonly=keep_readonly, **kwargs) # type: ignore + return serializer._serialize( # type: ignore # pylint: disable=protected-access + self, key_transformer=key_transformer, keep_readonly=keep_readonly, **kwargs + ) @classmethod def _infer_class_models(cls): @@ -400,30 +376,31 @@ def _infer_class_models(cls): client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)} if cls.__name__ not in client_models: raise ValueError("Not Autorest generated code") - except Exception: + except Exception: # pylint: disable=broad-exception-caught # Assume it's not Autorest generated (tests?). Add ourselves as dependencies. client_models = {cls.__name__: cls} return client_models @classmethod - def deserialize(cls: Type[ModelType], data: Any, content_type: Optional[str] = None) -> ModelType: + def deserialize(cls, data: Any, content_type: Optional[str] = None) -> Self: """Parse a str using the RestAPI syntax and return a model. :param str data: A str using RestAPI structure. JSON by default. :param str content_type: JSON by default, set application/xml if XML. :returns: An instance of this model - :raises: DeserializationError if something went wrong + :raises DeserializationError: if something went wrong + :rtype: Self """ deserializer = Deserializer(cls._infer_class_models()) return deserializer(cls.__name__, data, content_type=content_type) # type: ignore @classmethod def from_dict( - cls: Type[ModelType], + cls, data: Any, key_extractors: Optional[Callable[[str, Dict[str, Any], Any], Any]] = None, content_type: Optional[str] = None, - ) -> ModelType: + ) -> Self: """Parse a dict using given key extractor return a model. By default consider key @@ -431,9 +408,11 @@ def from_dict( and last_rest_key_case_insensitive_extractor) :param dict data: A dict using RestAPI structure + :param function key_extractors: A key extractor function. :param str content_type: JSON by default, set application/xml if XML. :returns: An instance of this model :raises: DeserializationError if something went wrong + :rtype: Self """ deserializer = Deserializer(cls._infer_class_models()) deserializer.key_extractors = ( # type: ignore @@ -453,21 +432,25 @@ def _flatten_subtype(cls, key, objects): return {} result = dict(cls._subtype_map[key]) for valuetype in cls._subtype_map[key].values(): - result.update(objects[valuetype]._flatten_subtype(key, objects)) + result.update(objects[valuetype]._flatten_subtype(key, objects)) # pylint: disable=protected-access return result @classmethod def _classify(cls, response, objects): """Check the class _subtype_map for any child classes. We want to ignore any inherited _subtype_maps. - Remove the polymorphic key from the initial data. + + :param dict response: The initial data + :param dict objects: The class objects + :returns: The class to be used + :rtype: class """ for subtype_key in cls.__dict__.get("_subtype_map", {}).keys(): subtype_value = None if not isinstance(response, ET.Element): rest_api_response_key = cls._get_rest_key_parts(subtype_key)[-1] - subtype_value = response.pop(rest_api_response_key, None) or response.pop(subtype_key, None) + subtype_value = response.get(rest_api_response_key, None) or response.get(subtype_key, None) else: subtype_value = xml_key_extractor(subtype_key, cls._attribute_map[subtype_key], response) if subtype_value: @@ -506,11 +489,13 @@ def _decode_attribute_map_key(key): inside the received data. :param str key: A key string from the generated code + :returns: The decoded key + :rtype: str """ return key.replace("\\.", ".") -class Serializer(object): +class Serializer: # pylint: disable=too-many-public-methods """Request object model serializer.""" basic_types = {str: "str", int: "int", bool: "bool", float: "float"} @@ -545,7 +530,7 @@ class Serializer(object): "multiple": lambda x, y: x % y != 0, } - def __init__(self, classes: Optional[Mapping[str, Type[ModelType]]] = None): + def __init__(self, classes: Optional[Mapping[str, type]] = None) -> None: self.serialize_type = { "iso-8601": Serializer.serialize_iso, "rfc-1123": Serializer.serialize_rfc, @@ -561,17 +546,20 @@ def __init__(self, classes: Optional[Mapping[str, Type[ModelType]]] = None): "[]": self.serialize_iter, "{}": self.serialize_dict, } - self.dependencies: Dict[str, Type[ModelType]] = dict(classes) if classes else {} + self.dependencies: Dict[str, type] = dict(classes) if classes else {} self.key_transformer = full_restapi_key_transformer self.client_side_validation = True - def _serialize(self, target_obj, data_type=None, **kwargs): + def _serialize( # pylint: disable=too-many-nested-blocks, too-many-branches, too-many-statements, too-many-locals + self, target_obj, data_type=None, **kwargs + ): """Serialize data into a string according to type. - :param target_obj: The data to be serialized. + :param object target_obj: The data to be serialized. :param str data_type: The type to be serialized from. :rtype: str, dict - :raises: SerializationError if serialization fails. + :raises SerializationError: if serialization fails. + :returns: The serialized data. """ key_transformer = kwargs.get("key_transformer", self.key_transformer) keep_readonly = kwargs.get("keep_readonly", False) @@ -597,12 +585,14 @@ def _serialize(self, target_obj, data_type=None, **kwargs): serialized = {} if is_xml_model_serialization: - serialized = target_obj._create_xml_node() + serialized = target_obj._create_xml_node() # pylint: disable=protected-access try: - attributes = target_obj._attribute_map + attributes = target_obj._attribute_map # pylint: disable=protected-access for attr, attr_desc in attributes.items(): attr_name = attr - if not keep_readonly and target_obj._validation.get(attr_name, {}).get("readonly", False): + if not keep_readonly and target_obj._validation.get( # pylint: disable=protected-access + attr_name, {} + ).get("readonly", False): continue if attr_name == "additional_properties" and attr_desc["key"] == "": @@ -638,7 +628,8 @@ def _serialize(self, target_obj, data_type=None, **kwargs): if isinstance(new_attr, list): serialized.extend(new_attr) # type: ignore elif isinstance(new_attr, ET.Element): - # If the down XML has no XML/Name, we MUST replace the tag with the local tag. But keeping the namespaces. + # If the down XML has no XML/Name, + # we MUST replace the tag with the local tag. But keeping the namespaces. if "name" not in getattr(orig_attr, "_xml_map", {}): splitted_tag = new_attr.tag.split("}") if len(splitted_tag) == 2: # Namespace @@ -649,7 +640,7 @@ def _serialize(self, target_obj, data_type=None, **kwargs): else: # That's a basic type # Integrate namespace if necessary local_node = _create_xml_node(xml_name, xml_prefix, xml_ns) - local_node.text = unicode_str(new_attr) + local_node.text = str(new_attr) serialized.append(local_node) # type: ignore else: # JSON for k in reversed(keys): # type: ignore @@ -669,17 +660,17 @@ def _serialize(self, target_obj, data_type=None, **kwargs): except (AttributeError, KeyError, TypeError) as err: msg = "Attribute {} in object {} cannot be serialized.\n{}".format(attr_name, class_name, str(target_obj)) raise SerializationError(msg) from err - else: - return serialized + return serialized def body(self, data, data_type, **kwargs): """Serialize data intended for a request body. - :param data: The data to be serialized. + :param object data: The data to be serialized. :param str data_type: The type to be serialized from. :rtype: dict - :raises: SerializationError if serialization fails. - :raises: ValueError if data is None + :raises SerializationError: if serialization fails. + :raises ValueError: if data is None + :returns: The serialized request body """ # Just in case this is a dict @@ -708,7 +699,7 @@ def body(self, data, data_type, **kwargs): attribute_key_case_insensitive_extractor, last_rest_key_case_insensitive_extractor, ] - data = deserializer._deserialize(data_type, data) + data = deserializer._deserialize(data_type, data) # pylint: disable=protected-access except DeserializationError as err: raise SerializationError("Unable to build a model: " + str(err)) from err @@ -717,11 +708,13 @@ def body(self, data, data_type, **kwargs): def url(self, name, data, data_type, **kwargs): """Serialize data intended for a URL path. - :param data: The data to be serialized. + :param str name: The name of the URL path parameter. + :param object data: The data to be serialized. :param str data_type: The type to be serialized from. :rtype: str - :raises: TypeError if serialization fails. - :raises: ValueError if data is None + :returns: The serialized URL path + :raises TypeError: if serialization fails. + :raises ValueError: if data is None """ try: output = self.serialize_data(data, data_type, **kwargs) @@ -733,21 +726,20 @@ def url(self, name, data, data_type, **kwargs): output = output.replace("{", quote("{")).replace("}", quote("}")) else: output = quote(str(output), safe="") - except SerializationError: - raise TypeError("{} must be type {}.".format(name, data_type)) - else: - return output + except SerializationError as exc: + raise TypeError("{} must be type {}.".format(name, data_type)) from exc + return output def query(self, name, data, data_type, **kwargs): """Serialize data intended for a URL query. - :param data: The data to be serialized. + :param str name: The name of the query parameter. + :param object data: The data to be serialized. :param str data_type: The type to be serialized from. - :keyword bool skip_quote: Whether to skip quote the serialized result. - Defaults to False. :rtype: str, list - :raises: TypeError if serialization fails. - :raises: ValueError if data is None + :raises TypeError: if serialization fails. + :raises ValueError: if data is None + :returns: The serialized query parameter """ try: # Treat the list aside, since we don't want to encode the div separator @@ -764,19 +756,20 @@ def query(self, name, data, data_type, **kwargs): output = str(output) else: output = quote(str(output), safe="") - except SerializationError: - raise TypeError("{} must be type {}.".format(name, data_type)) - else: - return str(output) + except SerializationError as exc: + raise TypeError("{} must be type {}.".format(name, data_type)) from exc + return str(output) def header(self, name, data, data_type, **kwargs): """Serialize data intended for a request header. - :param data: The data to be serialized. + :param str name: The name of the header. + :param object data: The data to be serialized. :param str data_type: The type to be serialized from. :rtype: str - :raises: TypeError if serialization fails. - :raises: ValueError if data is None + :raises TypeError: if serialization fails. + :raises ValueError: if data is None + :returns: The serialized header """ try: if data_type in ["[str]"]: @@ -785,21 +778,20 @@ def header(self, name, data, data_type, **kwargs): output = self.serialize_data(data, data_type, **kwargs) if data_type == "bool": output = json.dumps(output) - except SerializationError: - raise TypeError("{} must be type {}.".format(name, data_type)) - else: - return str(output) + except SerializationError as exc: + raise TypeError("{} must be type {}.".format(name, data_type)) from exc + return str(output) def serialize_data(self, data, data_type, **kwargs): """Serialize generic data according to supplied data type. - :param data: The data to be serialized. + :param object data: The data to be serialized. :param str data_type: The type to be serialized from. - :param bool required: Whether it's essential that the data not be - empty or None - :raises: AttributeError if required data is None. - :raises: ValueError if data is None - :raises: SerializationError if serialization fails. + :raises AttributeError: if required data is None. + :raises ValueError: if data is None + :raises SerializationError: if serialization fails. + :returns: The serialized data. + :rtype: str, int, float, bool, dict, list """ if data is None: raise ValueError("No value for given attribute") @@ -810,7 +802,7 @@ def serialize_data(self, data, data_type, **kwargs): if data_type in self.basic_types.values(): return self.serialize_basic(data, data_type, **kwargs) - elif data_type in self.serialize_type: + if data_type in self.serialize_type: return self.serialize_type[data_type](data, **kwargs) # If dependencies is empty, try with current data class @@ -826,11 +818,10 @@ def serialize_data(self, data, data_type, **kwargs): except (ValueError, TypeError) as err: msg = "Unable to serialize value: {!r} as type: {!r}." raise SerializationError(msg.format(data, data_type)) from err - else: - return self._serialize(data, **kwargs) + return self._serialize(data, **kwargs) @classmethod - def _get_custom_serializers(cls, data_type, **kwargs): + def _get_custom_serializers(cls, data_type, **kwargs): # pylint: disable=inconsistent-return-statements custom_serializer = kwargs.get("basic_types_serializers", {}).get(data_type) if custom_serializer: return custom_serializer @@ -846,23 +837,26 @@ def serialize_basic(cls, data, data_type, **kwargs): - basic_types_serializers dict[str, callable] : If set, use the callable as serializer - is_xml bool : If set, use xml_basic_types_serializers - :param data: Object to be serialized. + :param obj data: Object to be serialized. :param str data_type: Type of object in the iterable. + :rtype: str, int, float, bool + :return: serialized object """ custom_serializer = cls._get_custom_serializers(data_type, **kwargs) if custom_serializer: return custom_serializer(data) if data_type == "str": return cls.serialize_unicode(data) - return eval(data_type)(data) # nosec + return eval(data_type)(data) # nosec # pylint: disable=eval-used @classmethod def serialize_unicode(cls, data): """Special handling for serializing unicode strings in Py2. Encode to UTF-8 if unicode, otherwise handle as a str. - :param data: Object to be serialized. + :param str data: Object to be serialized. :rtype: str + :return: serialized object """ try: # If I received an enum, return its value return data.value @@ -876,8 +870,7 @@ def serialize_unicode(cls, data): return data except NameError: return str(data) - else: - return str(data) + return str(data) def serialize_iter(self, data, iter_type, div=None, **kwargs): """Serialize iterable. @@ -887,15 +880,13 @@ def serialize_iter(self, data, iter_type, div=None, **kwargs): serialization_ctxt['type'] should be same as data_type. - is_xml bool : If set, serialize as XML - :param list attr: Object to be serialized. + :param list data: Object to be serialized. :param str iter_type: Type of object in the iterable. - :param bool required: Whether the objects in the iterable must - not be None or empty. :param str div: If set, this str will be used to combine the elements in the iterable into a combined string. Default is 'None'. - :keyword bool do_quote: Whether to quote the serialized result of each iterable element. Defaults to False. :rtype: list, str + :return: serialized iterable """ if isinstance(data, str): raise SerializationError("Refuse str type as a valid iter type.") @@ -950,9 +941,8 @@ def serialize_dict(self, attr, dict_type, **kwargs): :param dict attr: Object to be serialized. :param str dict_type: Type of object in the dictionary. - :param bool required: Whether the objects in the dictionary must - not be None or empty. :rtype: dict + :return: serialized dictionary """ serialization_ctxt = kwargs.get("serialization_ctxt", {}) serialized = {} @@ -976,7 +966,7 @@ def serialize_dict(self, attr, dict_type, **kwargs): return serialized - def serialize_object(self, attr, **kwargs): + def serialize_object(self, attr, **kwargs): # pylint: disable=too-many-return-statements """Serialize a generic object. This will be handled as a dictionary. If object passed in is not a basic type (str, int, float, dict, list) it will simply be @@ -984,6 +974,7 @@ def serialize_object(self, attr, **kwargs): :param dict attr: Object to be serialized. :rtype: dict or str + :return: serialized object """ if attr is None: return None @@ -994,7 +985,7 @@ def serialize_object(self, attr, **kwargs): return self.serialize_basic(attr, self.basic_types[obj_type], **kwargs) if obj_type is _long_type: return self.serialize_long(attr) - if obj_type is unicode_str: + if obj_type is str: return self.serialize_unicode(attr) if obj_type is datetime.datetime: return self.serialize_iso(attr) @@ -1008,7 +999,7 @@ def serialize_object(self, attr, **kwargs): return self.serialize_decimal(attr) # If it's a model or I know this dependency, serialize as a Model - elif obj_type in self.dependencies.values() or isinstance(attr, Model): + if obj_type in self.dependencies.values() or isinstance(attr, Model): return self._serialize(attr) if obj_type == dict: @@ -1039,56 +1030,61 @@ def serialize_enum(attr, enum_obj=None): try: enum_obj(result) # type: ignore return result - except ValueError: + except ValueError as exc: for enum_value in enum_obj: # type: ignore if enum_value.value.lower() == str(attr).lower(): return enum_value.value error = "{!r} is not valid value for enum {!r}" - raise SerializationError(error.format(attr, enum_obj)) + raise SerializationError(error.format(attr, enum_obj)) from exc @staticmethod - def serialize_bytearray(attr, **kwargs): + def serialize_bytearray(attr, **kwargs): # pylint: disable=unused-argument """Serialize bytearray into base-64 string. - :param attr: Object to be serialized. + :param str attr: Object to be serialized. :rtype: str + :return: serialized base64 """ return b64encode(attr).decode() @staticmethod - def serialize_base64(attr, **kwargs): + def serialize_base64(attr, **kwargs): # pylint: disable=unused-argument """Serialize str into base-64 string. - :param attr: Object to be serialized. + :param str attr: Object to be serialized. :rtype: str + :return: serialized base64 """ encoded = b64encode(attr).decode("ascii") return encoded.strip("=").replace("+", "-").replace("/", "_") @staticmethod - def serialize_decimal(attr, **kwargs): + def serialize_decimal(attr, **kwargs): # pylint: disable=unused-argument """Serialize Decimal object to float. - :param attr: Object to be serialized. + :param decimal attr: Object to be serialized. :rtype: float + :return: serialized decimal """ return float(attr) @staticmethod - def serialize_long(attr, **kwargs): + def serialize_long(attr, **kwargs): # pylint: disable=unused-argument """Serialize long (Py2) or int (Py3). - :param attr: Object to be serialized. + :param int attr: Object to be serialized. :rtype: int/long + :return: serialized long """ return _long_type(attr) @staticmethod - def serialize_date(attr, **kwargs): + def serialize_date(attr, **kwargs): # pylint: disable=unused-argument """Serialize Date object into ISO-8601 formatted string. :param Date attr: Object to be serialized. :rtype: str + :return: serialized date """ if isinstance(attr, str): attr = isodate.parse_date(attr) @@ -1096,11 +1092,12 @@ def serialize_date(attr, **kwargs): return t @staticmethod - def serialize_time(attr, **kwargs): + def serialize_time(attr, **kwargs): # pylint: disable=unused-argument """Serialize Time object into ISO-8601 formatted string. :param datetime.time attr: Object to be serialized. :rtype: str + :return: serialized time """ if isinstance(attr, str): attr = isodate.parse_time(attr) @@ -1110,30 +1107,32 @@ def serialize_time(attr, **kwargs): return t @staticmethod - def serialize_duration(attr, **kwargs): + def serialize_duration(attr, **kwargs): # pylint: disable=unused-argument """Serialize TimeDelta object into ISO-8601 formatted string. :param TimeDelta attr: Object to be serialized. :rtype: str + :return: serialized duration """ if isinstance(attr, str): attr = isodate.parse_duration(attr) return isodate.duration_isoformat(attr) @staticmethod - def serialize_rfc(attr, **kwargs): + def serialize_rfc(attr, **kwargs): # pylint: disable=unused-argument """Serialize Datetime object into RFC-1123 formatted string. :param Datetime attr: Object to be serialized. :rtype: str - :raises: TypeError if format invalid. + :raises TypeError: if format invalid. + :return: serialized rfc """ try: if not attr.tzinfo: _LOGGER.warning("Datetime with no tzinfo will be considered UTC.") utc = attr.utctimetuple() - except AttributeError: - raise TypeError("RFC1123 object must be valid Datetime object.") + except AttributeError as exc: + raise TypeError("RFC1123 object must be valid Datetime object.") from exc return "{}, {:02} {} {:04} {:02}:{:02}:{:02} GMT".format( Serializer.days[utc.tm_wday], @@ -1146,12 +1145,13 @@ def serialize_rfc(attr, **kwargs): ) @staticmethod - def serialize_iso(attr, **kwargs): + def serialize_iso(attr, **kwargs): # pylint: disable=unused-argument """Serialize Datetime object into ISO-8601 formatted string. :param Datetime attr: Object to be serialized. :rtype: str - :raises: SerializationError if format invalid. + :raises SerializationError: if format invalid. + :return: serialized iso """ if isinstance(attr, str): attr = isodate.parse_datetime(attr) @@ -1177,13 +1177,14 @@ def serialize_iso(attr, **kwargs): raise TypeError(msg) from err @staticmethod - def serialize_unix(attr, **kwargs): + def serialize_unix(attr, **kwargs): # pylint: disable=unused-argument """Serialize Datetime object into IntTime format. This is represented as seconds. :param Datetime attr: Object to be serialized. :rtype: int - :raises: SerializationError if format invalid + :raises SerializationError: if format invalid + :return: serialied unix """ if isinstance(attr, int): return attr @@ -1191,11 +1192,11 @@ def serialize_unix(attr, **kwargs): if not attr.tzinfo: _LOGGER.warning("Datetime with no tzinfo will be considered UTC.") return int(calendar.timegm(attr.utctimetuple())) - except AttributeError: - raise TypeError("Unix time object must be valid Datetime object.") + except AttributeError as exc: + raise TypeError("Unix time object must be valid Datetime object.") from exc -def rest_key_extractor(attr, attr_desc, data): +def rest_key_extractor(attr, attr_desc, data): # pylint: disable=unused-argument key = attr_desc["key"] working_data = data @@ -1216,7 +1217,9 @@ def rest_key_extractor(attr, attr_desc, data): return working_data.get(key) -def rest_key_case_insensitive_extractor(attr, attr_desc, data): +def rest_key_case_insensitive_extractor( # pylint: disable=unused-argument, inconsistent-return-statements + attr, attr_desc, data +): key = attr_desc["key"] working_data = data @@ -1237,17 +1240,29 @@ def rest_key_case_insensitive_extractor(attr, attr_desc, data): return attribute_key_case_insensitive_extractor(key, None, working_data) -def last_rest_key_extractor(attr, attr_desc, data): - """Extract the attribute in "data" based on the last part of the JSON path key.""" +def last_rest_key_extractor(attr, attr_desc, data): # pylint: disable=unused-argument + """Extract the attribute in "data" based on the last part of the JSON path key. + + :param str attr: The attribute to extract + :param dict attr_desc: The attribute description + :param dict data: The data to extract from + :rtype: object + :returns: The extracted attribute + """ key = attr_desc["key"] dict_keys = _FLATTEN.split(key) return attribute_key_extractor(dict_keys[-1], None, data) -def last_rest_key_case_insensitive_extractor(attr, attr_desc, data): +def last_rest_key_case_insensitive_extractor(attr, attr_desc, data): # pylint: disable=unused-argument """Extract the attribute in "data" based on the last part of the JSON path key. This is the case insensitive version of "last_rest_key_extractor" + :param str attr: The attribute to extract + :param dict attr_desc: The attribute description + :param dict data: The data to extract from + :rtype: object + :returns: The extracted attribute """ key = attr_desc["key"] dict_keys = _FLATTEN.split(key) @@ -1284,7 +1299,7 @@ def _extract_name_from_internal_type(internal_type): return xml_name -def xml_key_extractor(attr, attr_desc, data): +def xml_key_extractor(attr, attr_desc, data): # pylint: disable=unused-argument,too-many-return-statements if isinstance(data, dict): return None @@ -1336,22 +1351,21 @@ def xml_key_extractor(attr, attr_desc, data): if is_iter_type: if is_wrapped: return None # is_wrapped no node, we want None - else: - return [] # not wrapped, assume empty list + return [] # not wrapped, assume empty list return None # Assume it's not there, maybe an optional node. # If is_iter_type and not wrapped, return all found children if is_iter_type: if not is_wrapped: return children - else: # Iter and wrapped, should have found one node only (the wrap one) - if len(children) != 1: - raise DeserializationError( - "Tried to deserialize an array not wrapped, and found several nodes '{}'. Maybe you should declare this array as wrapped?".format( - xml_name - ) + # Iter and wrapped, should have found one node only (the wrap one) + if len(children) != 1: + raise DeserializationError( + "Tried to deserialize an array not wrapped, and found several nodes '{}'. Maybe you should declare this array as wrapped?".format( # pylint: disable=line-too-long + xml_name ) - return list(children[0]) # Might be empty list and that's ok. + ) + return list(children[0]) # Might be empty list and that's ok. # Here it's not a itertype, we should have found one element only or empty if len(children) > 1: @@ -1359,7 +1373,7 @@ def xml_key_extractor(attr, attr_desc, data): return children[0] -class Deserializer(object): +class Deserializer: """Response object model deserializer. :param dict classes: Class type dictionary for deserializing complex types. @@ -1368,9 +1382,9 @@ class Deserializer(object): basic_types = {str: "str", int: "int", bool: "bool", float: "float"} - valid_date = re.compile(r"\d{4}[-]\d{2}[-]\d{2}T\d{2}:\d{2}:\d{2}" r"\.?\d*Z?[-+]?[\d{2}]?:?[\d{2}]?") + valid_date = re.compile(r"\d{4}[-]\d{2}[-]\d{2}T\d{2}:\d{2}:\d{2}\.?\d*Z?[-+]?[\d{2}]?:?[\d{2}]?") - def __init__(self, classes: Optional[Mapping[str, Type[ModelType]]] = None): + def __init__(self, classes: Optional[Mapping[str, type]] = None) -> None: self.deserialize_type = { "iso-8601": Deserializer.deserialize_iso, "rfc-1123": Deserializer.deserialize_rfc, @@ -1390,7 +1404,7 @@ def __init__(self, classes: Optional[Mapping[str, Type[ModelType]]] = None): "duration": (isodate.Duration, datetime.timedelta), "iso-8601": (datetime.datetime), } - self.dependencies: Dict[str, Type[ModelType]] = dict(classes) if classes else {} + self.dependencies: Dict[str, type] = dict(classes) if classes else {} self.key_extractors = [rest_key_extractor, xml_key_extractor] # Additional properties only works if the "rest_key_extractor" is used to # extract the keys. Making it to work whatever the key extractor is too much @@ -1406,27 +1420,29 @@ def __call__(self, target_obj, response_data, content_type=None): :param str target_obj: Target data type to deserialize to. :param requests.Response response_data: REST response object. :param str content_type: Swagger "produces" if available. - :raises: DeserializationError if deserialization fails. + :raises DeserializationError: if deserialization fails. :return: Deserialized object. + :rtype: object """ data = self._unpack_content(response_data, content_type) return self._deserialize(target_obj, data) - def _deserialize(self, target_obj, data): + def _deserialize(self, target_obj, data): # pylint: disable=inconsistent-return-statements """Call the deserializer on a model. Data needs to be already deserialized as JSON or XML ElementTree :param str target_obj: Target data type to deserialize to. :param object data: Object to deserialize. - :raises: DeserializationError if deserialization fails. + :raises DeserializationError: if deserialization fails. :return: Deserialized object. + :rtype: object """ # This is already a model, go recursive just in case if hasattr(data, "_attribute_map"): constants = [name for name, config in getattr(data, "_validation", {}).items() if config.get("constant")] try: - for attr, mapconfig in data._attribute_map.items(): + for attr, mapconfig in data._attribute_map.items(): # pylint: disable=protected-access if attr in constants: continue value = getattr(data, attr) @@ -1443,15 +1459,15 @@ def _deserialize(self, target_obj, data): response, class_name = self._classify_target(target_obj, data) - if isinstance(response, basestring): + if isinstance(response, str): return self.deserialize_data(data, response) - elif isinstance(response, type) and issubclass(response, Enum): + if isinstance(response, type) and issubclass(response, Enum): return self.deserialize_enum(data, response) - if data is None: + if data is None or data is CoreNull: return data try: - attributes = response._attribute_map # type: ignore + attributes = response._attribute_map # type: ignore # pylint: disable=protected-access d_attrs = {} for attr, attr_desc in attributes.items(): # Check empty string. If it's not empty, someone has a real "additionalProperties"... @@ -1481,9 +1497,8 @@ def _deserialize(self, target_obj, data): except (AttributeError, TypeError, KeyError) as err: msg = "Unable to deserialize to object: " + class_name # type: ignore raise DeserializationError(msg) from err - else: - additional_properties = self._build_additional_properties(attributes, data) - return self._instantiate_model(response, d_attrs, additional_properties) + additional_properties = self._build_additional_properties(attributes, data) + return self._instantiate_model(response, d_attrs, additional_properties) def _build_additional_properties(self, attribute_map, data): if not self.additional_properties_detection: @@ -1510,18 +1525,20 @@ def _classify_target(self, target, data): :param str target: The target object type to deserialize to. :param str/dict data: The response data to deserialize. + :return: The classified target object and its class name. + :rtype: tuple """ if target is None: return None, None - if isinstance(target, basestring): + if isinstance(target, str): try: target = self.dependencies[target] except KeyError: return target, target try: - target = target._classify(data, self.dependencies) + target = target._classify(data, self.dependencies) # type: ignore # pylint: disable=protected-access except AttributeError: pass # Target is not a Model, no classify return target, target.__class__.__name__ # type: ignore @@ -1536,10 +1553,12 @@ def failsafe_deserialize(self, target_obj, data, content_type=None): :param str target_obj: The target object type to deserialize to. :param str/dict data: The response data to deserialize. :param str content_type: Swagger "produces" if available. + :return: Deserialized object. + :rtype: object """ try: return self(target_obj, data, content_type=content_type) - except: + except: # pylint: disable=bare-except _LOGGER.debug( "Ran into a deserialization error. Ignoring since this is failsafe deserialization", exc_info=True ) @@ -1557,10 +1576,12 @@ def _unpack_content(raw_data, content_type=None): If raw_data is something else, bypass all logic and return it directly. - :param raw_data: Data to be processed. - :param content_type: How to parse if raw_data is a string/bytes. + :param obj raw_data: Data to be processed. + :param str content_type: How to parse if raw_data is a string/bytes. :raises JSONDecodeError: If JSON is requested and parsing is impossible. :raises UnicodeDecodeError: If bytes is not UTF8 + :rtype: object + :return: Unpacked content. """ # Assume this is enough to detect a Pipeline Response without importing it context = getattr(raw_data, "context", {}) @@ -1577,31 +1598,42 @@ def _unpack_content(raw_data, content_type=None): if hasattr(raw_data, "_content_consumed"): return RawDeserializer.deserialize_from_http_generics(raw_data.text, raw_data.headers) - if isinstance(raw_data, (basestring, bytes)) or hasattr(raw_data, "read"): + if isinstance(raw_data, (str, bytes)) or hasattr(raw_data, "read"): return RawDeserializer.deserialize_from_text(raw_data, content_type) # type: ignore return raw_data def _instantiate_model(self, response, attrs, additional_properties=None): """Instantiate a response model passing in deserialized args. - :param response: The response model class. - :param d_attrs: The deserialized response attributes. + :param Response response: The response model class. + :param dict attrs: The deserialized response attributes. + :param dict additional_properties: Additional properties to be set. + :rtype: Response + :return: The instantiated response model. """ if callable(response): subtype = getattr(response, "_subtype_map", {}) try: - readonly = [k for k, v in response._validation.items() if v.get("readonly")] - const = [k for k, v in response._validation.items() if v.get("constant")] + readonly = [ + k + for k, v in response._validation.items() # pylint: disable=protected-access # type: ignore + if v.get("readonly") + ] + const = [ + k + for k, v in response._validation.items() # pylint: disable=protected-access # type: ignore + if v.get("constant") + ] kwargs = {k: v for k, v in attrs.items() if k not in subtype and k not in readonly + const} response_obj = response(**kwargs) for attr in readonly: setattr(response_obj, attr, attrs.get(attr)) if additional_properties: - response_obj.additional_properties = additional_properties + response_obj.additional_properties = additional_properties # type: ignore return response_obj except TypeError as err: msg = "Unable to deserialize {} into model {}. ".format(kwargs, response) # type: ignore - raise DeserializationError(msg + str(err)) + raise DeserializationError(msg + str(err)) from err else: try: for attr, value in attrs.items(): @@ -1610,15 +1642,16 @@ def _instantiate_model(self, response, attrs, additional_properties=None): except Exception as exp: msg = "Unable to populate response model. " msg += "Type: {}, Error: {}".format(type(response), exp) - raise DeserializationError(msg) + raise DeserializationError(msg) from exp - def deserialize_data(self, data, data_type): + def deserialize_data(self, data, data_type): # pylint: disable=too-many-return-statements """Process data for deserialization according to data type. :param str data: The response string to be deserialized. :param str data_type: The type to deserialize to. - :raises: DeserializationError if deserialization fails. + :raises DeserializationError: if deserialization fails. :return: Deserialized object. + :rtype: object """ if data is None: return data @@ -1632,7 +1665,11 @@ def deserialize_data(self, data, data_type): if isinstance(data, self.deserialize_expected_types.get(data_type, tuple())): return data - is_a_text_parsing_type = lambda x: x not in ["object", "[]", r"{}"] + is_a_text_parsing_type = lambda x: x not in [ # pylint: disable=unnecessary-lambda-assignment + "object", + "[]", + r"{}", + ] if isinstance(data, ET.Element) and is_a_text_parsing_type(data_type) and not data.text: return None data_val = self.deserialize_type[data_type](data) @@ -1652,14 +1689,14 @@ def deserialize_data(self, data, data_type): msg = "Unable to deserialize response data." msg += " Data: {}, {}".format(data, data_type) raise DeserializationError(msg) from err - else: - return self._deserialize(obj_type, data) + return self._deserialize(obj_type, data) def deserialize_iter(self, attr, iter_type): """Deserialize an iterable. :param list attr: Iterable to be deserialized. :param str iter_type: The type of object in the iterable. + :return: Deserialized iterable. :rtype: list """ if attr is None: @@ -1676,6 +1713,7 @@ def deserialize_dict(self, attr, dict_type): :param dict/list attr: Dictionary to be deserialized. Also accepts a list of key, value pairs. :param str dict_type: The object type of the items in the dictionary. + :return: Deserialized dictionary. :rtype: dict """ if isinstance(attr, list): @@ -1686,20 +1724,21 @@ def deserialize_dict(self, attr, dict_type): attr = {el.tag: el.text for el in attr} return {k: self.deserialize_data(v, dict_type) for k, v in attr.items()} - def deserialize_object(self, attr, **kwargs): + def deserialize_object(self, attr, **kwargs): # pylint: disable=too-many-return-statements """Deserialize a generic object. This will be handled as a dictionary. :param dict attr: Dictionary to be deserialized. + :return: Deserialized object. :rtype: dict - :raises: TypeError if non-builtin datatype encountered. + :raises TypeError: if non-builtin datatype encountered. """ if attr is None: return None if isinstance(attr, ET.Element): # Do no recurse on XML, just return the tree as-is return attr - if isinstance(attr, basestring): + if isinstance(attr, str): return self.deserialize_basic(attr, "str") obj_type = type(attr) if obj_type in self.basic_types: @@ -1725,11 +1764,10 @@ def deserialize_object(self, attr, **kwargs): pass return deserialized - else: - error = "Cannot deserialize generic object with type: " - raise TypeError(error + str(obj_type)) + error = "Cannot deserialize generic object with type: " + raise TypeError(error + str(obj_type)) - def deserialize_basic(self, attr, data_type): + def deserialize_basic(self, attr, data_type): # pylint: disable=too-many-return-statements """Deserialize basic builtin data type from string. Will attempt to convert to str, int, float and bool. This function will also accept '1', '0', 'true' and 'false' as @@ -1737,8 +1775,9 @@ def deserialize_basic(self, attr, data_type): :param str attr: response string to be deserialized. :param str data_type: deserialization data type. + :return: Deserialized basic type. :rtype: str, int, float or bool - :raises: TypeError if string format is not valid. + :raises TypeError: if string format is not valid. """ # If we're here, data is supposed to be a basic type. # If it's still an XML node, take the text @@ -1748,24 +1787,23 @@ def deserialize_basic(self, attr, data_type): if data_type == "str": # None or '', node is empty string. return "" - else: - # None or '', node with a strong type is None. - # Don't try to model "empty bool" or "empty int" - return None + # None or '', node with a strong type is None. + # Don't try to model "empty bool" or "empty int" + return None if data_type == "bool": if attr in [True, False, 1, 0]: return bool(attr) - elif isinstance(attr, basestring): + if isinstance(attr, str): if attr.lower() in ["true", "1"]: return True - elif attr.lower() in ["false", "0"]: + if attr.lower() in ["false", "0"]: return False raise TypeError("Invalid boolean value: {}".format(attr)) if data_type == "str": return self.deserialize_unicode(attr) - return eval(data_type)(attr) # nosec + return eval(data_type)(attr) # nosec # pylint: disable=eval-used @staticmethod def deserialize_unicode(data): @@ -1773,6 +1811,7 @@ def deserialize_unicode(data): as a string. :param str data: response string to be deserialized. + :return: Deserialized string. :rtype: str or unicode """ # We might be here because we have an enum modeled as string, @@ -1786,8 +1825,7 @@ def deserialize_unicode(data): return data except NameError: return str(data) - else: - return str(data) + return str(data) @staticmethod def deserialize_enum(data, enum_obj): @@ -1799,6 +1837,7 @@ def deserialize_enum(data, enum_obj): :param str data: Response string to be deserialized. If this value is None or invalid it will be returned as-is. :param Enum enum_obj: Enum object to deserialize to. + :return: Deserialized enum object. :rtype: Enum """ if isinstance(data, enum_obj) or data is None: @@ -1809,9 +1848,9 @@ def deserialize_enum(data, enum_obj): # Workaround. We might consider remove it in the future. try: return list(enum_obj.__members__.values())[data] - except IndexError: + except IndexError as exc: error = "{!r} is not a valid index for enum {!r}" - raise DeserializationError(error.format(data, enum_obj)) + raise DeserializationError(error.format(data, enum_obj)) from exc try: return enum_obj(str(data)) except ValueError: @@ -1827,8 +1866,9 @@ def deserialize_bytearray(attr): """Deserialize string into bytearray. :param str attr: response string to be deserialized. + :return: Deserialized bytearray :rtype: bytearray - :raises: TypeError if string format invalid. + :raises TypeError: if string format invalid. """ if isinstance(attr, ET.Element): attr = attr.text @@ -1839,8 +1879,9 @@ def deserialize_base64(attr): """Deserialize base64 encoded string into string. :param str attr: response string to be deserialized. + :return: Deserialized base64 string :rtype: bytearray - :raises: TypeError if string format invalid. + :raises TypeError: if string format invalid. """ if isinstance(attr, ET.Element): attr = attr.text @@ -1854,8 +1895,9 @@ def deserialize_decimal(attr): """Deserialize string into Decimal object. :param str attr: response string to be deserialized. - :rtype: Decimal - :raises: DeserializationError if string format invalid. + :return: Deserialized decimal + :raises DeserializationError: if string format invalid. + :rtype: decimal """ if isinstance(attr, ET.Element): attr = attr.text @@ -1870,8 +1912,9 @@ def deserialize_long(attr): """Deserialize string into long (Py2) or int (Py3). :param str attr: response string to be deserialized. + :return: Deserialized int :rtype: long or int - :raises: ValueError if string format invalid. + :raises ValueError: if string format invalid. """ if isinstance(attr, ET.Element): attr = attr.text @@ -1882,8 +1925,9 @@ def deserialize_duration(attr): """Deserialize ISO-8601 formatted string into TimeDelta object. :param str attr: response string to be deserialized. + :return: Deserialized duration :rtype: TimeDelta - :raises: DeserializationError if string format invalid. + :raises DeserializationError: if string format invalid. """ if isinstance(attr, ET.Element): attr = attr.text @@ -1892,16 +1936,16 @@ def deserialize_duration(attr): except (ValueError, OverflowError, AttributeError) as err: msg = "Cannot deserialize duration object." raise DeserializationError(msg) from err - else: - return duration + return duration @staticmethod def deserialize_date(attr): """Deserialize ISO-8601 formatted string into Date object. :param str attr: response string to be deserialized. + :return: Deserialized date :rtype: Date - :raises: DeserializationError if string format invalid. + :raises DeserializationError: if string format invalid. """ if isinstance(attr, ET.Element): attr = attr.text @@ -1915,8 +1959,9 @@ def deserialize_time(attr): """Deserialize ISO-8601 formatted string into time object. :param str attr: response string to be deserialized. + :return: Deserialized time :rtype: datetime.time - :raises: DeserializationError if string format invalid. + :raises DeserializationError: if string format invalid. """ if isinstance(attr, ET.Element): attr = attr.text @@ -1929,31 +1974,32 @@ def deserialize_rfc(attr): """Deserialize RFC-1123 formatted string into Datetime object. :param str attr: response string to be deserialized. + :return: Deserialized RFC datetime :rtype: Datetime - :raises: DeserializationError if string format invalid. + :raises DeserializationError: if string format invalid. """ if isinstance(attr, ET.Element): attr = attr.text try: parsed_date = email.utils.parsedate_tz(attr) # type: ignore date_obj = datetime.datetime( - *parsed_date[:6], tzinfo=_FixedOffset(datetime.timedelta(minutes=(parsed_date[9] or 0) / 60)) + *parsed_date[:6], tzinfo=datetime.timezone(datetime.timedelta(minutes=(parsed_date[9] or 0) / 60)) ) if not date_obj.tzinfo: date_obj = date_obj.astimezone(tz=TZ_UTC) except ValueError as err: msg = "Cannot deserialize to rfc datetime object." raise DeserializationError(msg) from err - else: - return date_obj + return date_obj @staticmethod def deserialize_iso(attr): """Deserialize ISO-8601 formatted string into Datetime object. :param str attr: response string to be deserialized. + :return: Deserialized ISO datetime :rtype: Datetime - :raises: DeserializationError if string format invalid. + :raises DeserializationError: if string format invalid. """ if isinstance(attr, ET.Element): attr = attr.text @@ -1981,8 +2027,7 @@ def deserialize_iso(attr): except (ValueError, OverflowError, AttributeError) as err: msg = "Cannot deserialize datetime object." raise DeserializationError(msg) from err - else: - return date_obj + return date_obj @staticmethod def deserialize_unix(attr): @@ -1990,8 +2035,9 @@ def deserialize_unix(attr): This is represented as seconds. :param int attr: Object to be serialized. + :return: Deserialized datetime :rtype: Datetime - :raises: DeserializationError if format invalid + :raises DeserializationError: if format invalid """ if isinstance(attr, ET.Element): attr = int(attr.text) # type: ignore @@ -2001,5 +2047,4 @@ def deserialize_unix(attr): except ValueError as err: msg = "Cannot deserialize to unix datetime object." raise DeserializationError(msg) from err - else: - return date_obj + return date_obj diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_settings_client.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_settings_client.py deleted file mode 100644 index 8328052949af..000000000000 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_settings_client.py +++ /dev/null @@ -1,88 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from typing import Any - -from azure.core.paging import ItemPaged -from azure.core.tracing.decorator import distributed_trace - -from ._generated.models import UpdateSettingRequest -from ._internal import KeyVaultClientBase -from ._models import KeyVaultSetting - - -class KeyVaultSettingsClient(KeyVaultClientBase): - """Provides methods to update, get, and list Managed HSM account settings. - - :param str vault_url: URL of the vault on which the client will operate. This is also called the vault's "DNS Name". - You should validate that this URL references a valid Key Vault or Managed HSM resource. - See https://aka.ms/azsdk/blog/vault-uri for details. - :param credential: An object which can provide an access token for the vault, such as a credential from - :mod:`azure.identity` - :type credential: ~azure.core.credentials.TokenCredential - - :keyword api_version: Version of the service API to use. Defaults to the most recent. - :paramtype api_version: ~azure.keyvault.administration.ApiVersion or str - :keyword bool verify_challenge_resource: Whether to verify the authentication challenge resource matches the Key - Vault or Managed HSM domain. Defaults to True. - """ - # pylint:disable=protected-access - - @distributed_trace - def get_setting(self, name: str, **kwargs: Any) -> KeyVaultSetting: - """Gets the setting with the specified name. - - :param str name: The name of the account setting. - - :returns: The account setting, as a :class:`~azure.keyvault.administration.KeyVaultSetting`. - :rtype: ~azure.keyvault.administration.KeyVaultSetting - :raises ~azure.core.exceptions.HttpResponseError: - """ - result = self._client.get_setting(vault_base_url=self._vault_url, setting_name=name, **kwargs) - return KeyVaultSetting._from_generated(result) - - @distributed_trace - def list_settings(self, **kwargs: Any) -> ItemPaged[KeyVaultSetting]: - """Lists all account settings. - - :returns: A paged object containing the account's settings. - :rtype: ~azure.core.paging.ItemPaged[~azure.keyvault.administration.KeyVaultSetting] - :raises ~azure.core.exceptions.HttpResponseError: - """ - result = self._client.get_settings(vault_base_url=self._vault_url, *kwargs) - converted_result = [KeyVaultSetting._from_generated(setting) for setting in result.settings] - - # We don't actually get a paged response from the generated method, so we mock the typical iteration methods - def get_next(_=None): - return converted_result - - def extract_data(_): - return None, converted_result - - return ItemPaged(get_next, extract_data) - - @distributed_trace - def update_setting(self, setting: KeyVaultSetting, **kwargs: Any) -> KeyVaultSetting: - """Updates the named account setting with the provided value. - - :param setting: A azure.keyvault.administration.KeyVaultSetting to update. The account setting with - the provided name will be updated to have the provided value. - :type setting: ~azure.keyvault.administration.KeyVaultSetting - - :returns: The updated account setting, as a :class:`~azure.keyvault.administration.KeyVaultSetting`. - :rtype: ~azure.keyvault.administration.KeyVaultSetting - :raises ~azure.core.exceptions.HttpResponseError: - """ - parameters = UpdateSettingRequest(value=setting.value) - result = self._client.update_setting( - vault_base_url=self._vault_url, - setting_name=setting.name, - parameters=parameters, - **kwargs - ) - return KeyVaultSetting._from_generated(result) - - def __enter__(self) -> "KeyVaultSettingsClient": - self._client.__enter__() - return self diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_validation.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_validation.py new file mode 100644 index 000000000000..752b2822f9d3 --- /dev/null +++ b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_validation.py @@ -0,0 +1,50 @@ +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +import functools + + +def api_version_validation(**kwargs): + params_added_on = kwargs.pop("params_added_on", {}) + method_added_on = kwargs.pop("method_added_on", "") + + def decorator(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + try: + # this assumes the client has an _api_version attribute + client = args[0] + client_api_version = client._config.api_version # pylint: disable=protected-access + except AttributeError: + return func(*args, **kwargs) + + if method_added_on > client_api_version: + raise ValueError( + f"'{func.__name__}' is not available in API version " + f"{client_api_version}. Pass service API version {method_added_on} or newer to your client." + ) + + unsupported = { + parameter: api_version + for api_version, parameters in params_added_on.items() + for parameter in parameters + if parameter in kwargs and api_version > client_api_version + } + if unsupported: + raise ValueError( + "".join( + [ + f"'{param}' is not available in API version {client_api_version}. " + f"Use service API version {version} or newer.\n" + for param, version in unsupported.items() + ] + ) + ) + return func(*args, **kwargs) + + return wrapper + + return decorator diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/_vendor.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_vendor.py similarity index 88% rename from sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/_vendor.py rename to sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_vendor.py index db923753c642..3790083b97e3 100644 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/_vendor.py +++ b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_vendor.py @@ -1,7 +1,7 @@ # -------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for license information. -# Code generated by Microsoft (R) AutoRest Code Generator. +# Code generated by Microsoft (R) Python Code Generator. # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- @@ -11,7 +11,6 @@ from ._configuration import KeyVaultClientConfiguration if TYPE_CHECKING: - # pylint: disable=unused-import,ungrouped-imports from azure.core import PipelineClient from ._serialization import Deserializer, Serializer diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_version.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_version.py index 2416c4af1d7a..b4c415482fb9 100644 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_version.py +++ b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_version.py @@ -1,6 +1,9 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- -VERSION = "4.5.1" +VERSION = "4.5.0b1" diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/__init__.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/__init__.py index d1f1bd6d374a..8c996b993b8a 100644 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/__init__.py +++ b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/__init__.py @@ -1,9 +1,29 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from ._access_control_client import KeyVaultAccessControlClient -from ._backup_client import KeyVaultBackupClient -from ._settings_client import KeyVaultSettingsClient - -__all__ = ["KeyVaultAccessControlClient", "KeyVaultBackupClient", "KeyVaultSettingsClient"] +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +# pylint: disable=wrong-import-position + +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from ._patch import * # pylint: disable=unused-wildcard-import + +from ._client import KeyVaultClient # type: ignore + +try: + from ._patch import __all__ as _patch_all + from ._patch import * +except ImportError: + _patch_all = [] +from ._patch import patch_sdk as _patch_sdk + +__all__ = [ + "KeyVaultClient", +] +__all__.extend([p for p in _patch_all if p not in __all__]) # pyright: ignore + +_patch_sdk() diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/_access_control_client.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/_access_control_client.py deleted file mode 100644 index 1498a845b6ca..000000000000 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/_access_control_client.py +++ /dev/null @@ -1,269 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from typing import Any, List, Optional, Union -from uuid import UUID, uuid4 - -from azure.core.async_paging import AsyncItemPaged -from azure.core.exceptions import ResourceNotFoundError -from azure.core.tracing.decorator import distributed_trace -from azure.core.tracing.decorator_async import distributed_trace_async - -from .._enums import KeyVaultRoleScope -from .._models import KeyVaultPermission, KeyVaultRoleAssignment, KeyVaultRoleDefinition -from .._internal import AsyncKeyVaultClientBase - - -class KeyVaultAccessControlClient(AsyncKeyVaultClientBase): - """Manages role-based access to Azure Key Vault. - - :param str vault_url: URL of the vault the client will manage. This is also called the vault's "DNS Name". - You should validate that this URL references a valid Key Vault or Managed HSM resource. - See https://aka.ms/azsdk/blog/vault-uri for details. - :param credential: An object which can provide an access token for the vault, such as a credential from - :mod:`azure.identity.aio` - :type credential: ~azure.core.credentials_async.AsyncTokenCredential - - :keyword api_version: Version of the service API to use. Defaults to the most recent. - :paramtype api_version: ~azure.keyvault.administration.ApiVersion or str - :keyword bool verify_challenge_resource: Whether to verify the authentication challenge resource matches the Key - Vault or Managed HSM domain. Defaults to True. - """ - - # pylint:disable=protected-access - - @distributed_trace_async - async def create_role_assignment( - self, - scope: Union[str, KeyVaultRoleScope], - definition_id: str, - principal_id: str, - *, - name: Optional[Union[str, UUID]] = None, - **kwargs: Any, - ) -> KeyVaultRoleAssignment: - """Create a role assignment. - - :param scope: scope the role assignment will apply over. :class:`KeyVaultRoleScope` defines common broad - scopes. Specify a narrower scope as a string. - :type scope: str or KeyVaultRoleScope - :param str definition_id: ID of the role's definition - :param str principal_id: Azure Active Directory object ID of the principal which will be assigned the role. The - principal can be a user, service principal, or security group. - - :keyword name: a name for the role assignment. Must be a UUID. - :paramtype name: str or uuid.UUID or None - - :returns: The created role assignment. - :rtype: ~azure.keyvault.administration.KeyVaultRoleAssignment - """ - assignment_name = name or uuid4() - - create_parameters = self._client.role_assignments.models.RoleAssignmentCreateParameters( - properties=self._client.role_assignments.models.RoleAssignmentProperties( - principal_id=principal_id, role_definition_id=str(definition_id) - ) - ) - assignment = await self._client.role_assignments.create( - vault_base_url=self._vault_url, - scope=scope, - role_assignment_name=str(assignment_name), - parameters=create_parameters, - **kwargs - ) - return KeyVaultRoleAssignment._from_generated(assignment) - - @distributed_trace_async - async def delete_role_assignment( - self, scope: Union[str, KeyVaultRoleScope], name: Union[str, UUID], **kwargs: Any - ) -> None: - """Delete a role assignment. - - :param scope: the assignment's scope, for example "/", "/keys", or "/keys/". - :class:`KeyVaultRoleScope` defines common broad scopes. Specify a narrower scope as a string. - :type scope: str or KeyVaultRoleScope - :param name: the role assignment's name. - :type name: str or uuid.UUID - - :returns: None - :rtype: None - """ - try: - await self._client.role_assignments.delete( - vault_base_url=self._vault_url, scope=scope, role_assignment_name=str(name), **kwargs - ) - except ResourceNotFoundError: - pass - - @distributed_trace_async - async def get_role_assignment( - self, scope: Union[str, KeyVaultRoleScope], name: Union[str, UUID], **kwargs: Any - ) -> KeyVaultRoleAssignment: - """Get a role assignment. - - :param scope: the assignment's scope, for example "/", "/keys", or "/keys/". - :class:`KeyVaultRoleScope` defines common broad scopes. Specify a narrower scope as a string. - :type scope: str or KeyVaultRoleScope - :param name: the role assignment's name. - :type name: str or uuid.UUID - - :returns: The fetched role assignment. - :rtype: ~azure.keyvault.administration.KeyVaultRoleAssignment - """ - assignment = await self._client.role_assignments.get( - vault_base_url=self._vault_url, scope=scope, role_assignment_name=str(name), **kwargs - ) - return KeyVaultRoleAssignment._from_generated(assignment) - - @distributed_trace - def list_role_assignments( - self, scope: Union[str, KeyVaultRoleScope], **kwargs: Any - ) -> AsyncItemPaged[KeyVaultRoleAssignment]: - """List all role assignments for a scope. - - :param scope: scope of the role assignments. :class:`KeyVaultRoleScope` defines common broad - scopes. Specify a narrower scope as a string. - :type scope: str or KeyVaultRoleScope - - :returns: A paged response containing the role assignments for the specified scope. - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.administration.KeyVaultRoleAssignment] - """ - return self._client.role_assignments.list_for_scope( - vault_base_url=self._vault_url, - scope=scope, - cls=lambda result: [KeyVaultRoleAssignment._from_generated(a) for a in result], - **kwargs - ) - - @distributed_trace_async - async def set_role_definition( - self, - scope: Union[str, KeyVaultRoleScope], - *, - name: Optional[Union[str, UUID]] = None, - role_name: Optional[str] = None, - description: Optional[str] = None, - permissions: Optional[List[KeyVaultPermission]] = None, - assignable_scopes: Optional[Union[List[str], List[KeyVaultRoleScope]]] = None, - **kwargs: Any, - ) -> KeyVaultRoleDefinition: - """Creates or updates a custom role definition. - - To update a role definition, specify the definition's ``name``. - - :param scope: scope of the role definition. :class:`KeyVaultRoleScope` defines common broad scopes. - Specify a narrower scope as a string. Managed HSM only supports '/', or KeyVaultRoleScope.GLOBAL. - :type scope: str or KeyVaultRoleScope - - :keyword name: the role definition's name, a UUID. When this argument has a value, the client will create a new - role definition with this name or update an existing role definition, if one exists with the given name. - When this argument has no value, a new role definition will be created with a generated name. - :paramtype name: str or uuid.UUID or None - :keyword role_name: the role's display name. If unspecified when creating or updating a role definition, the - role name will be set to an empty string. - :paramtype role_name: str or None - :keyword description: a description of the role definition. If unspecified when creating or updating a role - definition, the description will be set to an empty string. - :paramtype description: str or None - :keyword permissions: the role definition's permissions. If unspecified when creating or updating a role - definition, the role definition will have no action permissions. - :paramtype permissions: list[KeyVaultPermission] or None - :keyword assignable_scopes: the scopes for which the role definition can be assigned. - :paramtype assignable_scopes: list[str] or list[KeyVaultRoleScope] or None - - :returns: The created or updated role definition - :rtype: ~azure.keyvault.administration.KeyVaultRoleDefinition - """ - role_permissions = [ - self._client.role_definitions.models.Permission( - actions=p.actions, - not_actions=p.not_actions, - data_actions=p.data_actions, - not_data_actions=p.not_data_actions, - ) - for p in permissions or [] - ] - - properties = self._client.role_definitions.models.RoleDefinitionProperties( - role_name=role_name, - description=description, - permissions=role_permissions, - assignable_scopes=assignable_scopes, - ) - parameters = self._client.role_definitions.models.RoleDefinitionCreateParameters(properties=properties) - - definition = await self._client.role_definitions.create_or_update( - vault_base_url=self._vault_url, - scope=scope, - role_definition_name=str(name or uuid4()), - parameters=parameters, - **kwargs - ) - return KeyVaultRoleDefinition._from_generated(definition) - - @distributed_trace_async - async def get_role_definition( - self, scope: Union[str, KeyVaultRoleScope], name: Union[str, UUID], **kwargs: Any - ) -> KeyVaultRoleDefinition: - """Get the specified role definition. - - :param scope: scope of the role definition. :class:`KeyVaultRoleScope` defines common broad scopes. - Specify a narrower scope as a string. Managed HSM only supports '/', or KeyVaultRoleScope.GLOBAL. - :type scope: str or KeyVaultRoleScope - :param name: the role definition's name. - :type name: str or uuid.UUID - - :returns: The fetched role definition. - :rtype: ~azure.keyvault.administration.KeyVaultRoleDefinition - """ - definition = await self._client.role_definitions.get( - vault_base_url=self._vault_url, scope=scope, role_definition_name=str(name), **kwargs - ) - return KeyVaultRoleDefinition._from_generated(definition) - - @distributed_trace_async - async def delete_role_definition( - self, scope: Union[str, KeyVaultRoleScope], name: Union[str, UUID], **kwargs: Any - ) -> None: - """Deletes a custom role definition. - - :param scope: scope of the role definition. :class:`KeyVaultRoleScope` defines common broad scopes. - Specify a narrower scope as a string. Managed HSM only supports '/', or KeyVaultRoleScope.GLOBAL. - :type scope: str or KeyVaultRoleScope - :param name: the role definition's name. - :type name: str or uuid.UUID - - :returns: None - :rtype: None - """ - try: - await self._client.role_definitions.delete( - vault_base_url=self._vault_url, scope=scope, role_definition_name=str(name), **kwargs - ) - except ResourceNotFoundError: - pass - - @distributed_trace - def list_role_definitions( - self, scope: Union[str, KeyVaultRoleScope], **kwargs: Any - ) -> AsyncItemPaged[KeyVaultRoleDefinition]: - """List all role definitions applicable at and above a scope. - - :param scope: scope of the role definitions. :class:`KeyVaultRoleScope` defines common broad - scopes. Specify a narrower scope as a string. - :type scope: str or KeyVaultRoleScope - - :returns: A paged response containing the role definitions for the specified scope. - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.administration.KeyVaultRoleDefinition] - """ - return self._client.role_definitions.list( - vault_base_url=self._vault_url, - scope=scope, - cls=lambda result: [KeyVaultRoleDefinition._from_generated(d) for d in result], - **kwargs - ) - - async def __aenter__(self) -> "KeyVaultAccessControlClient": - await self._client.__aenter__() - return self diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/_backup_client.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/_backup_client.py deleted file mode 100644 index 8e3619c802af..000000000000 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/_backup_client.py +++ /dev/null @@ -1,254 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -import base64 -import functools -import pickle -from typing import Any, Optional, overload - -from typing_extensions import Literal - -from azure.core.polling import AsyncLROPoller -from azure.core.tracing.decorator_async import distributed_trace_async - -from .._backup_client import _parse_status_url -from .._internal import AsyncKeyVaultClientBase, parse_folder_url -from .._internal.async_polling import KeyVaultAsyncBackupClientPollingMethod -from .._internal.polling import KeyVaultBackupClientPolling -from .._models import KeyVaultBackupResult - - -class KeyVaultBackupClient(AsyncKeyVaultClientBase): - """Performs Key Vault backup and restore operations. - - :param str vault_url: URL of the vault on which the client will operate. This is also called the vault's "DNS Name". - You should validate that this URL references a valid Key Vault or Managed HSM resource. - See https://aka.ms/azsdk/blog/vault-uri for details. - :param credential: An object which can provide an access token for the vault, such as a credential from - :mod:`azure.identity.aio` - :type credential: ~azure.core.credentials_async.AsyncTokenCredential - - :keyword api_version: Version of the service API to use. Defaults to the most recent. - :paramtype api_version: ~azure.keyvault.administration.ApiVersion or str - :keyword bool verify_challenge_resource: Whether to verify the authentication challenge resource matches the Key - Vault or Managed HSM domain. Defaults to True. - """ - - @overload - async def begin_backup( - self, - blob_storage_url: str, - *, - use_managed_identity: Literal[True], - continuation_token: Optional[str] = None, - **kwargs: Any, - ) -> AsyncLROPoller[KeyVaultBackupResult]: - ... - - @overload - async def begin_backup( - self, - blob_storage_url: str, - *, - sas_token: str, - continuation_token: Optional[str] = None, - **kwargs: Any, - ) -> AsyncLROPoller[KeyVaultBackupResult]: - ... - - # Disabling pylint checks because they don't correctly handle overloads - @distributed_trace_async - async def begin_backup( # pylint: disable=docstring-missing-param,docstring-keyword-should-match-keyword-only - self, blob_storage_url: str, *args: str, **kwargs: Any - ) -> AsyncLROPoller[KeyVaultBackupResult]: - """Begin a full backup of the Key Vault. - - :param str blob_storage_url: URL of the blob storage container in which the backup will be stored, for example - https://.blob.core.windows.net/backup. - - :keyword str sas_token: Optional Shared Access Signature (SAS) token to authorize access to the blob. Required - unless `use_managed_identity` is set to True. - :keyword use_managed_identity: Indicates which authentication method should be used. If set to True, Managed HSM - will use the configured user-assigned managed identity to authenticate with Azure Storage. Otherwise, a SAS - token has to be specified. - :paramtype use_managed_identity: bool - :keyword str continuation_token: A continuation token to restart polling from a saved state. - - :returns: An AsyncLROPoller. Call `result()` on this object to get a :class:`KeyVaultBackupResult`. - :rtype: ~azure.core.polling.AsyncLROPoller[~azure.keyvault.administration.KeyVaultBackupResult] - - Example: - .. literalinclude:: ../tests/test_examples_administration_async.py - :start-after: [START begin_backup] - :end-before: [END begin_backup] - :language: python - :caption: Create a vault backup - :dedent: 8 - """ - polling_interval = kwargs.pop("_polling_interval", 5) - continuation_token = kwargs.pop("continuation_token", None) - use_managed_identity = kwargs.pop("use_managed_identity", None) - # `sas_token` was formerly a required positional parameter - try: - sas_token: Optional[str] = args[0] - except IndexError: - sas_token = kwargs.pop("sas_token", None) - sas_parameter = self._models.SASTokenParameter( - storage_resource_uri=blob_storage_url, token=sas_token, use_managed_identity=use_managed_identity - ) - - status_response = None - if continuation_token: - status_url = base64.b64decode(continuation_token.encode()).decode("ascii") - try: - job_id = _parse_status_url(status_url) - except Exception as ex: # pylint: disable=broad-except - raise ValueError( - "The provided continuation_token is malformed. A valid token can be obtained from the operation " - + "poller's continuation_token() method" - ) from ex - - pipeline_response = await self._client.full_backup_status( - vault_base_url=self._vault_url, job_id=job_id, cls=lambda pipeline_response, _, __: pipeline_response - ) - if "azure-asyncoperation" not in pipeline_response.http_response.headers: - pipeline_response.http_response.headers["azure-asyncoperation"] = status_url - status_response = base64.b64encode(pickle.dumps(pipeline_response)).decode("ascii") - - return await self._client.begin_full_backup( - vault_base_url=self._vault_url, - azure_storage_blob_container_uri=sas_parameter, - cls=KeyVaultBackupResult._from_generated, # pylint: disable=protected-access - continuation_token=status_response, - polling=KeyVaultAsyncBackupClientPollingMethod( - lro_algorithms=[KeyVaultBackupClientPolling()], timeout=polling_interval, **kwargs - ), - **kwargs, - ) - - @overload - async def begin_restore( - self, - folder_url: str, - *, - use_managed_identity: Literal[True], - key_name: Optional[str] = None, - continuation_token: Optional[str] = None, - **kwargs: Any, - ) -> AsyncLROPoller[None]: - ... - - @overload - async def begin_restore( - self, - folder_url: str, - *, - sas_token: str, - key_name: Optional[str] = None, - continuation_token: Optional[str] = None, - **kwargs: Any, - ) -> AsyncLROPoller[None]: - ... - - # Disabling pylint checks because they don't correctly handle overloads - @distributed_trace_async - async def begin_restore( # pylint: disable=docstring-missing-param,docstring-keyword-should-match-keyword-only - self, folder_url: str, *args: str, **kwargs: Any - ) -> AsyncLROPoller[None]: - """Restore a Key Vault backup. - - This method restores either a complete Key Vault backup or when ``key_name`` has a value, a single key. - - :param str folder_url: URL for the blob storage resource, including the path to the blob holding the - backup. This would be the `folder_url` of a :class:`KeyVaultBackupResult` returned by - :func:`begin_backup`, for example - https://.blob.core.windows.net/backup/mhsm-account-2020090117323313 - - :keyword str sas_token: Optional Shared Access Signature (SAS) token to authorize access to the blob. Required - unless `use_managed_identity` is set to True. - :keyword use_managed_identity: Indicates which authentication method should be used. If set to True, Managed HSM - will use the configured user-assigned managed identity to authenticate with Azure Storage. Otherwise, a SAS - token has to be specified. - :paramtype use_managed_identity: bool - :keyword str key_name: Name of a single key in the backup. When set, only this key will be restored. - :keyword str continuation_token: A continuation token to restart polling from a saved state. - - :returns: An AsyncLROPoller. Call `wait()` or `result()` on this object to wait for the operation to complete - (the return value is None in either case). - :rtype: ~azure.core.polling.AsyncLROPoller - - Examples: - .. literalinclude:: ../tests/test_examples_administration_async.py - :start-after: [START begin_restore] - :end-before: [END begin_restore] - :language: python - :caption: Restore a vault backup - :dedent: 8 - - .. literalinclude:: ../tests/test_examples_administration_async.py - :start-after: [START begin_selective_restore] - :end-before: [END begin_selective_restore] - :language: python - :caption: Restore a single key - :dedent: 8 - """ - status_response = None - polling_interval = kwargs.pop("_polling_interval", 5) - continuation_token = kwargs.pop("continuation_token", None) - key_name = kwargs.pop("key_name", None) - use_managed_identity = kwargs.pop("use_managed_identity", None) - # `sas_token` was formerly a required positional parameter - try: - sas_token: Optional[str] = args[0] - except IndexError: - sas_token = kwargs.pop("sas_token", None) - - if continuation_token: - status_url = base64.b64decode(continuation_token.encode()).decode("ascii") - try: - job_id = _parse_status_url(status_url) - except Exception as ex: # pylint: disable=broad-except - raise ValueError( - "The provided continuation_token is malformed. A valid token can be obtained from the operation " - + "poller's continuation_token() method" - ) from ex - - pipeline_response = await self._client.restore_status( - vault_base_url=self._vault_url, job_id=job_id, cls=lambda pipeline_response, _, __: pipeline_response - ) - if "azure-asyncoperation" not in pipeline_response.http_response.headers: - pipeline_response.http_response.headers["azure-asyncoperation"] = status_url - status_response = base64.b64encode(pickle.dumps(pipeline_response)).decode("ascii") - - container_url, folder_name = parse_folder_url(folder_url) - sas_parameter = self._models.SASTokenParameter( - storage_resource_uri=container_url, token=sas_token, use_managed_identity=use_managed_identity - ) - polling = KeyVaultAsyncBackupClientPollingMethod( - lro_algorithms=[KeyVaultBackupClientPolling()], timeout=polling_interval, **kwargs - ) - - if key_name: - client_method = functools.partial(self._client.begin_selective_key_restore_operation, key_name=key_name) - restore_details = self._models.SelectiveKeyRestoreOperationParameters( - sas_token_parameters=sas_parameter, folder=folder_name - ) - else: - client_method = self._client.begin_full_restore_operation - restore_details = self._models.RestoreOperationParameters( - sas_token_parameters=sas_parameter, folder_to_restore=folder_name - ) - - return await client_method( - vault_base_url=self._vault_url, - restore_blob_details=restore_details, - cls=lambda *_: None, # poller.result() returns None - continuation_token=status_response, - polling=polling, - **kwargs, - ) - - async def __aenter__(self) -> "KeyVaultBackupClient": - await self._client.__aenter__() - return self diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/aio/_client.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/_client.py similarity index 72% rename from sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/aio/_client.py rename to sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/_client.py index f57b604341ab..5ec6bfd51c58 100644 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/aio/_client.py +++ b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/_client.py @@ -2,41 +2,50 @@ # -------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for license information. -# Code generated by Microsoft (R) AutoRest Code Generator. +# Code generated by Microsoft (R) Python Code Generator. # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- from copy import deepcopy -from typing import Any, Awaitable +from typing import Any, Awaitable, TYPE_CHECKING +from typing_extensions import Self from azure.core import AsyncPipelineClient from azure.core.pipeline import policies from azure.core.rest import AsyncHttpResponse, HttpRequest -from .. import models as _models from .._serialization import Deserializer, Serializer from ._configuration import KeyVaultClientConfiguration from .operations import KeyVaultClientOperationsMixin, RoleAssignmentsOperations, RoleDefinitionsOperations +if TYPE_CHECKING: + from azure.core.credentials_async import AsyncTokenCredential -class KeyVaultClient(KeyVaultClientOperationsMixin): # pylint: disable=client-accepts-api-version-keyword + +class KeyVaultClient(KeyVaultClientOperationsMixin): """The key vault client performs cryptographic key operations and vault operations against the Key Vault service. :ivar role_definitions: RoleDefinitionsOperations operations - :vartype role_definitions: azure.keyvault.v7_5.aio.operations.RoleDefinitionsOperations + :vartype role_definitions: + azure.keyvault.administration.aio.operations.RoleDefinitionsOperations :ivar role_assignments: RoleAssignmentsOperations operations - :vartype role_assignments: azure.keyvault.v7_5.aio.operations.RoleAssignmentsOperations - :keyword api_version: Api Version. Default value is "7.5". Note that overriding this default - value may result in unsupported behavior. + :vartype role_assignments: + azure.keyvault.administration.aio.operations.RoleAssignmentsOperations + :param vault_base_url: Required. + :type vault_base_url: str + :param credential: Credential used to authenticate requests to the service. Required. + :type credential: ~azure.core.credentials_async.AsyncTokenCredential + :keyword api_version: The API version to use for this operation. Default value is + "7.6-preview.2". Note that overriding this default value may result in unsupported behavior. :paramtype api_version: str :keyword int polling_interval: Default waiting time between two polls for LRO operations if no Retry-After header is present. """ - def __init__(self, **kwargs: Any) -> None: # pylint: disable=missing-client-constructor-parameter-credential + def __init__(self, vault_base_url: str, credential: "AsyncTokenCredential", **kwargs: Any) -> None: _endpoint = "{vaultBaseUrl}" - self._config = KeyVaultClientConfiguration(**kwargs) + self._config = KeyVaultClientConfiguration(vault_base_url=vault_base_url, credential=credential, **kwargs) _policies = kwargs.pop("policies", None) if _policies is None: _policies = [ @@ -56,10 +65,8 @@ def __init__(self, **kwargs: Any) -> None: # pylint: disable=missing-client-con ] self._client: AsyncPipelineClient = AsyncPipelineClient(base_url=_endpoint, policies=_policies, **kwargs) - client_models = {k: v for k, v in _models._models.__dict__.items() if isinstance(v, type)} - client_models.update({k: v for k, v in _models.__dict__.items() if isinstance(v, type)}) - self._serialize = Serializer(client_models) - self._deserialize = Deserializer(client_models) + self._serialize = Serializer() + self._deserialize = Deserializer() self._serialize.client_side_validation = False self.role_definitions = RoleDefinitionsOperations( self._client, self._config, self._serialize, self._deserialize @@ -89,13 +96,19 @@ def send_request( """ request_copy = deepcopy(request) - request_copy.url = self._client.format_url(request_copy.url) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + + request_copy.url = self._client.format_url(request_copy.url, **path_format_arguments) return self._client.send_request(request_copy, stream=stream, **kwargs) # type: ignore async def close(self) -> None: await self._client.close() - async def __aenter__(self) -> "KeyVaultClient": + async def __aenter__(self) -> Self: await self._client.__aenter__() return self diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/aio/_configuration.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/_configuration.py similarity index 54% rename from sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/aio/_configuration.py rename to sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/_configuration.py index 8dd6125e8e1d..1afbc4f32c16 100644 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/aio/_configuration.py +++ b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/_configuration.py @@ -2,15 +2,18 @@ # -------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for license information. -# Code generated by Microsoft (R) AutoRest Code Generator. +# Code generated by Microsoft (R) Python Code Generator. # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- -from typing import Any +from typing import Any, TYPE_CHECKING from azure.core.pipeline import policies -VERSION = "unknown" +from .._version import VERSION + +if TYPE_CHECKING: + from azure.core.credentials_async import AsyncTokenCredential class KeyVaultClientConfiguration: # pylint: disable=too-many-instance-attributes @@ -19,16 +22,28 @@ class KeyVaultClientConfiguration: # pylint: disable=too-many-instance-attribut Note that all parameters used to create this instance are saved as instance attributes. - :keyword api_version: Api Version. Default value is "7.5". Note that overriding this default - value may result in unsupported behavior. + :param vault_base_url: Required. + :type vault_base_url: str + :param credential: Credential used to authenticate requests to the service. Required. + :type credential: ~azure.core.credentials_async.AsyncTokenCredential + :keyword api_version: The API version to use for this operation. Default value is + "7.6-preview.2". Note that overriding this default value may result in unsupported behavior. :paramtype api_version: str """ - def __init__(self, **kwargs: Any) -> None: - api_version: str = kwargs.pop("api_version", "7.5") + def __init__(self, vault_base_url: str, credential: "AsyncTokenCredential", **kwargs: Any) -> None: + api_version: str = kwargs.pop("api_version", "7.6-preview.2") + + if vault_base_url is None: + raise ValueError("Parameter 'vault_base_url' must not be None.") + if credential is None: + raise ValueError("Parameter 'credential' must not be None.") + self.vault_base_url = vault_base_url + self.credential = credential self.api_version = api_version - kwargs.setdefault("sdk_moniker", "keyvault/{}".format(VERSION)) + self.credential_scopes = kwargs.pop("credential_scopes", ["https://vault.azure.net/.default"]) + kwargs.setdefault("sdk_moniker", "keyvault-administration/{}".format(VERSION)) self.polling_interval = kwargs.get("polling_interval", 30) self._configure(**kwargs) @@ -42,3 +57,7 @@ def _configure(self, **kwargs: Any) -> None: self.redirect_policy = kwargs.get("redirect_policy") or policies.AsyncRedirectPolicy(**kwargs) self.retry_policy = kwargs.get("retry_policy") or policies.AsyncRetryPolicy(**kwargs) self.authentication_policy = kwargs.get("authentication_policy") + if self.credential and not self.authentication_policy: + self.authentication_policy = policies.AsyncBearerTokenCredentialPolicy( + self.credential, *self.credential_scopes, **kwargs + ) diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/aio/_patch.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/_patch.py similarity index 100% rename from sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/aio/_patch.py rename to sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/_patch.py diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/_settings_client.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/_settings_client.py deleted file mode 100644 index 67b71815ce53..000000000000 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/_settings_client.py +++ /dev/null @@ -1,91 +0,0 @@ -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -from typing import Any - -from azure.core.async_paging import AsyncItemPaged, AsyncList -from azure.core.tracing.decorator import distributed_trace -from azure.core.tracing.decorator_async import distributed_trace_async - -from .._generated.models import UpdateSettingRequest -from .._internal import AsyncKeyVaultClientBase -from .._models import KeyVaultSetting - - -class KeyVaultSettingsClient(AsyncKeyVaultClientBase): - """Provides methods to update, get, and list Managed HSM account settings. - - :param str vault_url: URL of the vault on which the client will operate. This is also called the vault's "DNS Name". - You should validate that this URL references a valid Key Vault or Managed HSM resource. - See https://aka.ms/azsdk/blog/vault-uri for details. - :param credential: An object which can provide an access token for the vault, such as a credential from - :mod:`azure.identity.aio` - :type credential: ~azure.core.credentials_async.AsyncTokenCredential - - :keyword api_version: Version of the service API to use. Defaults to the most recent. - :paramtype api_version: ~azure.keyvault.administration.ApiVersion or str - :keyword bool verify_challenge_resource: Whether to verify the authentication challenge resource matches the Key - Vault or Managed HSM domain. Defaults to True. - """ - # pylint:disable=protected-access - - @distributed_trace_async - async def get_setting(self, name: str, **kwargs: Any) -> KeyVaultSetting: - """Gets the setting with the specified name. - - :param str name: The name of the account setting. - - :returns: The account setting, as a :class:`~azure.keyvault.administration.KeyVaultSetting`. - :rtype: ~azure.keyvault.administration.KeyVaultSetting - :raises ~azure.core.exceptions.HttpResponseError: - """ - result = await self._client.get_setting(vault_base_url=self._vault_url, setting_name=name, **kwargs) - return KeyVaultSetting._from_generated(result) - - @distributed_trace - def list_settings(self, **kwargs: Any) -> AsyncItemPaged[KeyVaultSetting]: - """Lists all account settings. - - :returns: A paged object containing the account's settings. - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.administration.KeyVaultSetting] - :raises ~azure.core.exceptions.HttpResponseError: - """ - result = self._client.get_settings(vault_base_url=self._vault_url, *kwargs) - - # We don't actually get a paged response from the generated method, so we mock the typical iteration methods - async def get_next(_=None): - # There's only one page of results (the `get_settings` result), so we return the awaited result directly - return await result - - async def extract_data(pipeline_response): - # `pipeline_response` is the awaited `get_settings` result that we returned in `get_next` - converted_result = [KeyVaultSetting._from_generated(setting) for setting in pipeline_response.settings] - return None, AsyncList(converted_result) - - return AsyncItemPaged(get_next, extract_data) - - @distributed_trace_async - async def update_setting(self, setting: KeyVaultSetting, **kwargs: Any) -> KeyVaultSetting: - """Updates the named account setting with the provided value. - - :param setting: A azure.keyvault.administration.KeyVaultSetting to update. The account setting with - the provided name will be updated to have the provided value. - :type setting: ~azure.keyvault.administration.KeyVaultSetting - - :returns: The updated account setting, as a :class:`~azure.keyvault.administration.KeyVaultSetting`. - :rtype: ~azure.keyvault.administration.KeyVaultSetting - :raises ~azure.core.exceptions.HttpResponseError: - """ - parameters = UpdateSettingRequest(value=setting.value) - result = await self._client.update_setting( - vault_base_url=self._vault_url, - setting_name=setting.name, - parameters=parameters, - **kwargs - ) - return KeyVaultSetting._from_generated(result) - - async def __aenter__(self) -> "KeyVaultSettingsClient": - await self._client.__aenter__() - return self diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/aio/_vendor.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/_vendor.py similarity index 88% rename from sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/aio/_vendor.py rename to sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/_vendor.py index 92c6d827acd9..2b1f525d61ea 100644 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/aio/_vendor.py +++ b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/_vendor.py @@ -1,7 +1,7 @@ # -------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for license information. -# Code generated by Microsoft (R) AutoRest Code Generator. +# Code generated by Microsoft (R) Python Code Generator. # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- @@ -11,7 +11,6 @@ from ._configuration import KeyVaultClientConfiguration if TYPE_CHECKING: - # pylint: disable=unused-import,ungrouped-imports from azure.core import AsyncPipelineClient from .._serialization import Deserializer, Serializer diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/aio/operations/__init__.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/operations/__init__.py similarity index 54% rename from sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/aio/operations/__init__.py rename to sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/operations/__init__.py index 523c12525d4f..2318933b2c83 100644 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/aio/operations/__init__.py +++ b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/operations/__init__.py @@ -2,22 +2,28 @@ # -------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for license information. -# Code generated by Microsoft (R) AutoRest Code Generator. +# Code generated by Microsoft (R) Python Code Generator. # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- +# pylint: disable=wrong-import-position -from ._operations import KeyVaultClientOperationsMixin -from ._operations import RoleDefinitionsOperations -from ._operations import RoleAssignmentsOperations +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from ._patch import * # pylint: disable=unused-wildcard-import + +from ._operations import RoleDefinitionsOperations # type: ignore +from ._operations import RoleAssignmentsOperations # type: ignore +from ._operations import KeyVaultClientOperationsMixin # type: ignore from ._patch import __all__ as _patch_all -from ._patch import * # pylint: disable=unused-wildcard-import +from ._patch import * from ._patch import patch_sdk as _patch_sdk __all__ = [ - "KeyVaultClientOperationsMixin", "RoleDefinitionsOperations", "RoleAssignmentsOperations", + "KeyVaultClientOperationsMixin", ] -__all__.extend([p for p in _patch_all if p not in __all__]) +__all__.extend([p for p in _patch_all if p not in __all__]) # pyright: ignore _patch_sdk() diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/aio/operations/_operations.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/operations/_operations.py similarity index 52% rename from sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/aio/operations/_operations.py rename to sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/operations/_operations.py index 9d24fbf316e1..269df1967b53 100644 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/aio/operations/_operations.py +++ b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/operations/_operations.py @@ -1,15 +1,18 @@ -# pylint: disable=too-many-lines,too-many-statements +# pylint: disable=too-many-lines # coding=utf-8 # -------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for license information. -# Code generated by Microsoft (R) AutoRest Code Generator. +# Code generated by Microsoft (R) Python Code Generator. # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- from io import IOBase -from typing import Any, AsyncIterable, Callable, Dict, IO, Optional, TypeVar, Union, cast, overload +import json +import sys +from typing import Any, AsyncIterable, AsyncIterator, Callable, Dict, IO, List, Optional, TypeVar, Union, cast, overload import urllib.parse +from azure.core import AsyncPipelineClient from azure.core.async_paging import AsyncItemPaged, AsyncList from azure.core.exceptions import ( ClientAuthenticationError, @@ -17,6 +20,8 @@ ResourceExistsError, ResourceNotFoundError, ResourceNotModifiedError, + StreamClosedError, + StreamConsumedError, map_error, ) from azure.core.pipeline import PipelineResponse @@ -28,14 +33,20 @@ from azure.core.utils import case_insensitive_dict from ... import models as _models +from ..._model_base import SdkJSONEncoder, _deserialize, _failsafe_deserialize +from ..._serialization import Deserializer, Serializer +from ..._validation import api_version_validation from ...operations._operations import ( build_key_vault_full_backup_request, build_key_vault_full_backup_status_request, build_key_vault_full_restore_operation_request, build_key_vault_get_setting_request, build_key_vault_get_settings_request, + build_key_vault_pre_full_backup_request, + build_key_vault_pre_full_restore_operation_request, build_key_vault_restore_status_request, build_key_vault_selective_key_restore_operation_request, + build_key_vault_selective_key_restore_status_request, build_key_vault_update_setting_request, build_role_assignments_create_request, build_role_assignments_delete_request, @@ -46,20 +57,49 @@ build_role_definitions_get_request, build_role_definitions_list_request, ) +from .._configuration import KeyVaultClientConfiguration from .._vendor import KeyVaultClientMixinABC +if sys.version_info >= (3, 9): + from collections.abc import MutableMapping +else: + from typing import MutableMapping # type: ignore +JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object T = TypeVar("T") ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] -class KeyVaultClientOperationsMixin(KeyVaultClientMixinABC): - async def _full_backup_initial( - self, - vault_base_url: str, - azure_storage_blob_container_uri: Optional[Union[_models.SASTokenParameter, IO[bytes]]] = None, - **kwargs: Any - ) -> _models.FullBackupOperation: - error_map = { +class RoleDefinitionsOperations: + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.keyvault.administration.aio.KeyVaultClient`'s + :attr:`role_definitions` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: KeyVaultClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace_async + async def delete(self, scope: str, role_definition_name: str, **kwargs: Any) -> _models.RoleDefinition: + """Deletes a custom role definition. + + :param scope: The scope of the role definition to delete. Managed HSM only supports '/'. + Required. + :type scope: str + :param role_definition_name: The name (GUID) of the role definition to delete. Required. + :type role_definition_name: str + :return: RoleDefinition. The RoleDefinition is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RoleDefinition + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, @@ -67,212 +107,161 @@ async def _full_backup_initial( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.FullBackupOperation] = kwargs.pop("cls", None) - - content_type = content_type or "application/json" - _json = None - _content = None - if isinstance(azure_storage_blob_container_uri, (IOBase, bytes)): - _content = azure_storage_blob_container_uri - else: - if azure_storage_blob_container_uri is not None: - _json = self._serialize.body(azure_storage_blob_container_uri, "SASTokenParameter") - else: - _json = None + cls: ClsType[_models.RoleDefinition] = kwargs.pop("cls", None) - _request = build_key_vault_full_backup_request( - content_type=content_type, + _request = build_role_definitions_delete_request( + scope=scope, + role_definition_name=role_definition_name, api_version=self._config.api_version, - json=_json, - content=_content, headers=_headers, params=_params, ) path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [202]: + if response.status_code not in [200]: if _stream: - await response.read() # Load the body in memory and close the socket + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) raise HttpResponseError(response=response, model=error) - response_headers = {} - response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) - response_headers["Azure-AsyncOperation"] = self._deserialize( - "str", response.headers.get("Azure-AsyncOperation") - ) - - deserialized = self._deserialize("FullBackupOperation", pipeline_response) + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize(_models.RoleDefinition, response.json()) if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore @overload - async def begin_full_backup( + async def create_or_update( self, - vault_base_url: str, - azure_storage_blob_container_uri: Optional[_models.SASTokenParameter] = None, + scope: str, + role_definition_name: str, + parameters: _models.RoleDefinitionCreateParameters, *, content_type: str = "application/json", **kwargs: Any - ) -> AsyncLROPoller[_models.FullBackupOperation]: - """Creates a full backup using a user-provided SAS token to an Azure blob storage container. + ) -> _models.RoleDefinition: + """Creates or updates a custom role definition. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param azure_storage_blob_container_uri: Azure blob shared access signature token pointing to a - valid Azure blob container where full backup needs to be stored. This token needs to be valid - for at least next 24 hours from the time of making this call. Default value is None. - :type azure_storage_blob_container_uri: ~azure.keyvault.v7_5.models.SASTokenParameter + :param scope: The scope of the role definition to create or update. Managed HSM only supports + '/'. Required. + :type scope: str + :param role_definition_name: The name of the role definition to create or update. It can be any + valid GUID. Required. + :type role_definition_name: str + :param parameters: Parameters for the role definition. Required. + :type parameters: ~azure.keyvault.administration.models.RoleDefinitionCreateParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: An instance of AsyncLROPoller that returns FullBackupOperation - :rtype: ~azure.core.polling.AsyncLROPoller[~azure.keyvault.v7_5.models.FullBackupOperation] + :return: RoleDefinition. The RoleDefinition is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RoleDefinition :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def begin_full_backup( + async def create_or_update( self, - vault_base_url: str, - azure_storage_blob_container_uri: Optional[IO[bytes]] = None, + scope: str, + role_definition_name: str, + parameters: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> AsyncLROPoller[_models.FullBackupOperation]: - """Creates a full backup using a user-provided SAS token to an Azure blob storage container. + ) -> _models.RoleDefinition: + """Creates or updates a custom role definition. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param azure_storage_blob_container_uri: Azure blob shared access signature token pointing to a - valid Azure blob container where full backup needs to be stored. This token needs to be valid - for at least next 24 hours from the time of making this call. Default value is None. - :type azure_storage_blob_container_uri: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + :param scope: The scope of the role definition to create or update. Managed HSM only supports + '/'. Required. + :type scope: str + :param role_definition_name: The name of the role definition to create or update. It can be any + valid GUID. Required. + :type role_definition_name: str + :param parameters: Parameters for the role definition. Required. + :type parameters: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: An instance of AsyncLROPoller that returns FullBackupOperation - :rtype: ~azure.core.polling.AsyncLROPoller[~azure.keyvault.v7_5.models.FullBackupOperation] + :return: RoleDefinition. The RoleDefinition is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RoleDefinition :raises ~azure.core.exceptions.HttpResponseError: """ - @distributed_trace_async - async def begin_full_backup( + @overload + async def create_or_update( self, - vault_base_url: str, - azure_storage_blob_container_uri: Optional[Union[_models.SASTokenParameter, IO[bytes]]] = None, + scope: str, + role_definition_name: str, + parameters: IO[bytes], + *, + content_type: str = "application/json", **kwargs: Any - ) -> AsyncLROPoller[_models.FullBackupOperation]: - """Creates a full backup using a user-provided SAS token to an Azure blob storage container. + ) -> _models.RoleDefinition: + """Creates or updates a custom role definition. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param azure_storage_blob_container_uri: Azure blob shared access signature token pointing to a - valid Azure blob container where full backup needs to be stored. This token needs to be valid - for at least next 24 hours from the time of making this call. Is either a SASTokenParameter - type or a IO[bytes] type. Default value is None. - :type azure_storage_blob_container_uri: ~azure.keyvault.v7_5.models.SASTokenParameter or - IO[bytes] - :keyword content_type: Body Parameter content-type. Known values are: 'application/json'. - Default value is None. + :param scope: The scope of the role definition to create or update. Managed HSM only supports + '/'. Required. + :type scope: str + :param role_definition_name: The name of the role definition to create or update. It can be any + valid GUID. Required. + :type role_definition_name: str + :param parameters: Parameters for the role definition. Required. + :type parameters: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". :paramtype content_type: str - :return: An instance of AsyncLROPoller that returns FullBackupOperation - :rtype: ~azure.core.polling.AsyncLROPoller[~azure.keyvault.v7_5.models.FullBackupOperation] + :return: RoleDefinition. The RoleDefinition is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RoleDefinition :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} - - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.FullBackupOperation] = kwargs.pop("cls", None) - polling: Union[bool, AsyncPollingMethod] = kwargs.pop("polling", True) - lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) - cont_token: Optional[str] = kwargs.pop("continuation_token", None) - if cont_token is None: - raw_result = await self._full_backup_initial( - vault_base_url=vault_base_url, - azure_storage_blob_container_uri=azure_storage_blob_container_uri, - content_type=content_type, - cls=lambda x, y, z: x, - headers=_headers, - params=_params, - **kwargs - ) - kwargs.pop("error_map", None) - - def get_long_running_output(pipeline_response): - response_headers = {} - response = pipeline_response.http_response - response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) - response_headers["Azure-AsyncOperation"] = self._deserialize( - "str", response.headers.get("Azure-AsyncOperation") - ) - - deserialized = self._deserialize("FullBackupOperation", pipeline_response) - if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore - return deserialized - - path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), - } - - if polling is True: - polling_method: AsyncPollingMethod = cast( - AsyncPollingMethod, - AsyncLROBasePolling( - lro_delay, - lro_options={"final-state-via": "azure-async-operation"}, - path_format_arguments=path_format_arguments, - **kwargs - ), - ) - elif polling is False: - polling_method = cast(AsyncPollingMethod, AsyncNoPolling()) - else: - polling_method = polling - if cont_token: - return AsyncLROPoller[_models.FullBackupOperation].from_continuation_token( - polling_method=polling_method, - continuation_token=cont_token, - client=self._client, - deserialization_callback=get_long_running_output, - ) - return AsyncLROPoller[_models.FullBackupOperation]( - self._client, raw_result, get_long_running_output, polling_method # type: ignore - ) @distributed_trace_async - async def full_backup_status(self, vault_base_url: str, job_id: str, **kwargs: Any) -> _models.FullBackupOperation: - """Returns the status of full backup operation. + async def create_or_update( + self, + scope: str, + role_definition_name: str, + parameters: Union[_models.RoleDefinitionCreateParameters, JSON, IO[bytes]], + **kwargs: Any + ) -> _models.RoleDefinition: + """Creates or updates a custom role definition. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param job_id: The id returned as part of the backup request. Required. - :type job_id: str - :return: FullBackupOperation - :rtype: ~azure.keyvault.v7_5.models.FullBackupOperation + :param scope: The scope of the role definition to create or update. Managed HSM only supports + '/'. Required. + :type scope: str + :param role_definition_name: The name of the role definition to create or update. It can be any + valid GUID. Required. + :type role_definition_name: str + :param parameters: Parameters for the role definition. Is one of the following types: + RoleDefinitionCreateParameters, JSON, IO[bytes] Required. + :type parameters: ~azure.keyvault.administration.models.RoleDefinitionCreateParameters or JSON + or IO[bytes] + :return: RoleDefinition. The RoleDefinition is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RoleDefinition :raises ~azure.core.exceptions.HttpResponseError: """ - error_map = { + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, @@ -280,50 +269,75 @@ async def full_backup_status(self, vault_base_url: str, job_id: str, **kwargs: A } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.FullBackupOperation] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.RoleDefinition] = kwargs.pop("cls", None) - _request = build_key_vault_full_backup_status_request( - job_id=job_id, + content_type = content_type or "application/json" + _content = None + if isinstance(parameters, (IOBase, bytes)): + _content = parameters + else: + _content = json.dumps(parameters, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_role_definitions_create_or_update_request( + scope=scope, + role_definition_name=role_definition_name, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: + if response.status_code not in [201]: if _stream: - await response.read() # Load the body in memory and close the socket + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) raise HttpResponseError(response=response, model=error) - deserialized = self._deserialize("FullBackupOperation", pipeline_response) + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize(_models.RoleDefinition, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - async def _full_restore_operation_initial( - self, - vault_base_url: str, - restore_blob_details: Optional[Union[_models.RestoreOperationParameters, IO[bytes]]] = None, - **kwargs: Any - ) -> _models.RestoreOperation: - error_map = { + @distributed_trace_async + async def get(self, scope: str, role_definition_name: str, **kwargs: Any) -> _models.RoleDefinition: + """Get the specified role definition. + + :param scope: The scope of the role definition to get. Managed HSM only supports '/'. Required. + :type scope: str + :param role_definition_name: The name of the role definition to get. Required. + :type role_definition_name: str + :return: RoleDefinition. The RoleDefinition is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RoleDefinition + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, @@ -331,57 +345,684 @@ async def _full_restore_operation_initial( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.RestoreOperation] = kwargs.pop("cls", None) - - content_type = content_type or "application/json" - _json = None - _content = None - if isinstance(restore_blob_details, (IOBase, bytes)): - _content = restore_blob_details - else: - if restore_blob_details is not None: - _json = self._serialize.body(restore_blob_details, "RestoreOperationParameters") - else: - _json = None + cls: ClsType[_models.RoleDefinition] = kwargs.pop("cls", None) - _request = build_key_vault_full_restore_operation_request( - content_type=content_type, + _request = build_role_definitions_get_request( + scope=scope, + role_definition_name=role_definition_name, api_version=self._config.api_version, - json=_json, - content=_content, headers=_headers, params=_params, ) path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [202]: + if response.status_code not in [200]: if _stream: - await response.read() # Load the body in memory and close the socket + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) raise HttpResponseError(response=response, model=error) - response_headers = {} - response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) - response_headers["Azure-AsyncOperation"] = self._deserialize( + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize(_models.RoleDefinition, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list( + self, scope: str, *, filter: Optional[str] = None, **kwargs: Any + ) -> AsyncIterable["_models.RoleDefinition"]: + """Get all role definitions that are applicable at scope and above. + + :param scope: The scope of the role definition. Required. + :type scope: str + :keyword filter: The filter to apply on the operation. Use atScopeAndBelow filter to search + below the given scope as well. Default value is None. + :paramtype filter: str + :return: An iterator like instance of RoleDefinition + :rtype: + ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.administration.models.RoleDefinition] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.RoleDefinition]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_role_definitions_list_request( + scope=scope, + filter=filter, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params + ) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize(List[_models.RoleDefinition], deserialized["value"]) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + + +class RoleAssignmentsOperations: + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.keyvault.administration.aio.KeyVaultClient`'s + :attr:`role_assignments` attribute. + """ + + def __init__(self, *args, **kwargs) -> None: + input_args = list(args) + self._client: AsyncPipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: KeyVaultClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace_async + async def delete(self, scope: str, role_assignment_name: str, **kwargs: Any) -> _models.RoleAssignment: + """Deletes a role assignment. + + :param scope: The scope of the role assignment to delete. Required. + :type scope: str + :param role_assignment_name: The name of the role assignment to delete. Required. + :type role_assignment_name: str + :return: RoleAssignment. The RoleAssignment is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RoleAssignment + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.RoleAssignment] = kwargs.pop("cls", None) + + _request = build_role_assignments_delete_request( + scope=scope, + role_assignment_name=role_assignment_name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize(_models.RoleAssignment, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @overload + async def create( + self, + scope: str, + role_assignment_name: str, + parameters: _models.RoleAssignmentCreateParameters, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.RoleAssignment: + """Creates a role assignment. + + :param scope: The scope of the role assignment to create. Required. + :type scope: str + :param role_assignment_name: The name of the role assignment to create. It can be any valid + GUID. Required. + :type role_assignment_name: str + :param parameters: Parameters for the role assignment. Required. + :type parameters: ~azure.keyvault.administration.models.RoleAssignmentCreateParameters + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: RoleAssignment. The RoleAssignment is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RoleAssignment + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def create( + self, + scope: str, + role_assignment_name: str, + parameters: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.RoleAssignment: + """Creates a role assignment. + + :param scope: The scope of the role assignment to create. Required. + :type scope: str + :param role_assignment_name: The name of the role assignment to create. It can be any valid + GUID. Required. + :type role_assignment_name: str + :param parameters: Parameters for the role assignment. Required. + :type parameters: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: RoleAssignment. The RoleAssignment is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RoleAssignment + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def create( + self, + scope: str, + role_assignment_name: str, + parameters: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.RoleAssignment: + """Creates a role assignment. + + :param scope: The scope of the role assignment to create. Required. + :type scope: str + :param role_assignment_name: The name of the role assignment to create. It can be any valid + GUID. Required. + :type role_assignment_name: str + :param parameters: Parameters for the role assignment. Required. + :type parameters: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: RoleAssignment. The RoleAssignment is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RoleAssignment + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + async def create( + self, + scope: str, + role_assignment_name: str, + parameters: Union[_models.RoleAssignmentCreateParameters, JSON, IO[bytes]], + **kwargs: Any + ) -> _models.RoleAssignment: + """Creates a role assignment. + + :param scope: The scope of the role assignment to create. Required. + :type scope: str + :param role_assignment_name: The name of the role assignment to create. It can be any valid + GUID. Required. + :type role_assignment_name: str + :param parameters: Parameters for the role assignment. Is one of the following types: + RoleAssignmentCreateParameters, JSON, IO[bytes] Required. + :type parameters: ~azure.keyvault.administration.models.RoleAssignmentCreateParameters or JSON + or IO[bytes] + :return: RoleAssignment. The RoleAssignment is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RoleAssignment + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.RoleAssignment] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(parameters, (IOBase, bytes)): + _content = parameters + else: + _content = json.dumps(parameters, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_role_assignments_create_request( + scope=scope, + role_assignment_name=role_assignment_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [201]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize(_models.RoleAssignment, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace_async + async def get(self, scope: str, role_assignment_name: str, **kwargs: Any) -> _models.RoleAssignment: + """Get the specified role assignment. + + :param scope: The scope of the role assignment. Required. + :type scope: str + :param role_assignment_name: The name of the role assignment to get. Required. + :type role_assignment_name: str + :return: RoleAssignment. The RoleAssignment is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RoleAssignment + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.RoleAssignment] = kwargs.pop("cls", None) + + _request = build_role_assignments_get_request( + scope=scope, + role_assignment_name=role_assignment_name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize(_models.RoleAssignment, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list_for_scope( + self, scope: str, *, filter: Optional[str] = None, **kwargs: Any + ) -> AsyncIterable["_models.RoleAssignment"]: + """Gets role assignments for a scope. + + :param scope: The scope of the role assignments. Required. + :type scope: str + :keyword filter: The filter to apply on the operation. Use $filter=atScope() to return all role + assignments at or above the scope. Use $filter=principalId eq {id} to return all role + assignments at, above or below the scope for the specified principal. Default value is None. + :paramtype filter: str + :return: An iterator like instance of RoleAssignment + :rtype: + ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.administration.models.RoleAssignment] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.RoleAssignment]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_role_assignments_list_for_scope_request( + scope=scope, + filter=filter, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params + ) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + async def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize(List[_models.RoleAssignment], deserialized["value"]) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return AsyncItemPaged(get_next, extract_data) + + +class KeyVaultClientOperationsMixin(KeyVaultClientMixinABC): + + @distributed_trace_async + async def full_backup_status(self, job_id: str, **kwargs: Any) -> _models.FullBackupOperation: + """Returns the status of full backup operation. + + :param job_id: The id returned as part of the backup request. Required. + :type job_id: str + :return: FullBackupOperation. The FullBackupOperation is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.FullBackupOperation + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.FullBackupOperation] = kwargs.pop("cls", None) + + _request = build_key_vault_full_backup_status_request( + job_id=job_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize(_models.FullBackupOperation, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + async def _full_backup_initial( + self, azure_storage_blob_container_uri: Union[_models.SASTokenParameter, JSON, IO[bytes]], **kwargs: Any + ) -> AsyncIterator[bytes]: + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(azure_storage_blob_container_uri, (IOBase, bytes)): + _content = azure_storage_blob_container_uri + else: + _content = json.dumps(azure_storage_blob_container_uri, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_key_vault_full_backup_request( + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = True + pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [202]: + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["Azure-AsyncOperation"] = self._deserialize( "str", response.headers.get("Azure-AsyncOperation") ) + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) - deserialized = self._deserialize("RestoreOperation", pipeline_response) + deserialized = response.iter_bytes() if cls: return cls(pipeline_response, deserialized, response_headers) # type: ignore @@ -389,205 +1030,156 @@ async def _full_restore_operation_initial( return deserialized # type: ignore @overload - async def begin_full_restore_operation( + async def begin_full_backup( self, - vault_base_url: str, - restore_blob_details: Optional[_models.RestoreOperationParameters] = None, + azure_storage_blob_container_uri: _models.SASTokenParameter, *, content_type: str = "application/json", **kwargs: Any - ) -> AsyncLROPoller[_models.RestoreOperation]: - """Restores all key materials using the SAS token pointing to a previously stored Azure Blob - storage backup folder. + ) -> AsyncLROPoller[_models.FullBackupOperation]: + """Creates a full backup using a user-provided SAS token to an Azure blob storage container. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous - successful full backup was stored. Default value is None. - :type restore_blob_details: ~azure.keyvault.v7_5.models.RestoreOperationParameters + :param azure_storage_blob_container_uri: Azure blob shared access signature token pointing to a + valid Azure blob container where full backup needs to be stored. This token needs to be valid + for at least next 24 hours from the time of making this call. Required. + :type azure_storage_blob_container_uri: ~azure.keyvault.administration.models.SASTokenParameter :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: An instance of AsyncLROPoller that returns RestoreOperation - :rtype: ~azure.core.polling.AsyncLROPoller[~azure.keyvault.v7_5.models.RestoreOperation] + :return: An instance of AsyncLROPoller that returns FullBackupOperation. The + FullBackupOperation is compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.keyvault.administration.models.FullBackupOperation] :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def begin_full_restore_operation( - self, - vault_base_url: str, - restore_blob_details: Optional[IO[bytes]] = None, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> AsyncLROPoller[_models.RestoreOperation]: - """Restores all key materials using the SAS token pointing to a previously stored Azure Blob - storage backup folder. + async def begin_full_backup( + self, azure_storage_blob_container_uri: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> AsyncLROPoller[_models.FullBackupOperation]: + """Creates a full backup using a user-provided SAS token to an Azure blob storage container. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous - successful full backup was stored. Default value is None. - :type restore_blob_details: IO[bytes] + :param azure_storage_blob_container_uri: Azure blob shared access signature token pointing to a + valid Azure blob container where full backup needs to be stored. This token needs to be valid + for at least next 24 hours from the time of making this call. Required. + :type azure_storage_blob_container_uri: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of AsyncLROPoller that returns FullBackupOperation. The + FullBackupOperation is compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.keyvault.administration.models.FullBackupOperation] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def begin_full_backup( + self, azure_storage_blob_container_uri: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> AsyncLROPoller[_models.FullBackupOperation]: + """Creates a full backup using a user-provided SAS token to an Azure blob storage container. + + :param azure_storage_blob_container_uri: Azure blob shared access signature token pointing to a + valid Azure blob container where full backup needs to be stored. This token needs to be valid + for at least next 24 hours from the time of making this call. Required. + :type azure_storage_blob_container_uri: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: An instance of AsyncLROPoller that returns RestoreOperation - :rtype: ~azure.core.polling.AsyncLROPoller[~azure.keyvault.v7_5.models.RestoreOperation] + :return: An instance of AsyncLROPoller that returns FullBackupOperation. The + FullBackupOperation is compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.keyvault.administration.models.FullBackupOperation] :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace_async - async def begin_full_restore_operation( - self, - vault_base_url: str, - restore_blob_details: Optional[Union[_models.RestoreOperationParameters, IO[bytes]]] = None, - **kwargs: Any - ) -> AsyncLROPoller[_models.RestoreOperation]: - """Restores all key materials using the SAS token pointing to a previously stored Azure Blob - storage backup folder. + async def begin_full_backup( + self, azure_storage_blob_container_uri: Union[_models.SASTokenParameter, JSON, IO[bytes]], **kwargs: Any + ) -> AsyncLROPoller[_models.FullBackupOperation]: + """Creates a full backup using a user-provided SAS token to an Azure blob storage container. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous - successful full backup was stored. Is either a RestoreOperationParameters type or a IO[bytes] - type. Default value is None. - :type restore_blob_details: ~azure.keyvault.v7_5.models.RestoreOperationParameters or IO[bytes] - :keyword content_type: Body Parameter content-type. Known values are: 'application/json'. - Default value is None. - :paramtype content_type: str - :return: An instance of AsyncLROPoller that returns RestoreOperation - :rtype: ~azure.core.polling.AsyncLROPoller[~azure.keyvault.v7_5.models.RestoreOperation] + :param azure_storage_blob_container_uri: Azure blob shared access signature token pointing to a + valid Azure blob container where full backup needs to be stored. This token needs to be valid + for at least next 24 hours from the time of making this call. Is one of the following types: + SASTokenParameter, JSON, IO[bytes] Required. + :type azure_storage_blob_container_uri: ~azure.keyvault.administration.models.SASTokenParameter + or JSON or IO[bytes] + :return: An instance of AsyncLROPoller that returns FullBackupOperation. The + FullBackupOperation is compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.keyvault.administration.models.FullBackupOperation] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.RestoreOperation] = kwargs.pop("cls", None) + cls: ClsType[_models.FullBackupOperation] = kwargs.pop("cls", None) polling: Union[bool, AsyncPollingMethod] = kwargs.pop("polling", True) lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) cont_token: Optional[str] = kwargs.pop("continuation_token", None) if cont_token is None: - raw_result = await self._full_restore_operation_initial( - vault_base_url=vault_base_url, - restore_blob_details=restore_blob_details, + raw_result = await self._full_backup_initial( + azure_storage_blob_container_uri=azure_storage_blob_container_uri, content_type=content_type, cls=lambda x, y, z: x, headers=_headers, params=_params, **kwargs ) + await raw_result.http_response.read() # type: ignore kwargs.pop("error_map", None) def get_long_running_output(pipeline_response): response_headers = {} response = pipeline_response.http_response - response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) response_headers["Azure-AsyncOperation"] = self._deserialize( "str", response.headers.get("Azure-AsyncOperation") ) + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) - deserialized = self._deserialize("RestoreOperation", pipeline_response) + deserialized = _deserialize(_models.FullBackupOperation, response.json()) if cls: return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } if polling is True: polling_method: AsyncPollingMethod = cast( AsyncPollingMethod, - AsyncLROBasePolling( - lro_delay, - lro_options={"final-state-via": "azure-async-operation"}, - path_format_arguments=path_format_arguments, - **kwargs - ), + AsyncLROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs), ) elif polling is False: polling_method = cast(AsyncPollingMethod, AsyncNoPolling()) else: polling_method = polling if cont_token: - return AsyncLROPoller[_models.RestoreOperation].from_continuation_token( + return AsyncLROPoller[_models.FullBackupOperation].from_continuation_token( polling_method=polling_method, - continuation_token=cont_token, - client=self._client, - deserialization_callback=get_long_running_output, - ) - return AsyncLROPoller[_models.RestoreOperation]( - self._client, raw_result, get_long_running_output, polling_method # type: ignore - ) - - @distributed_trace_async - async def restore_status(self, vault_base_url: str, job_id: str, **kwargs: Any) -> _models.RestoreOperation: - """Returns the status of restore operation. - - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param job_id: The Job Id returned part of the restore operation. Required. - :type job_id: str - :return: RestoreOperation - :rtype: ~azure.keyvault.v7_5.models.RestoreOperation - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[_models.RestoreOperation] = kwargs.pop("cls", None) - - _request = build_key_vault_restore_status_request( - job_id=job_id, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - - response = pipeline_response.http_response - - if response.status_code not in [200]: - if _stream: - await response.read() # Load the body in memory and close the socket - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) - raise HttpResponseError(response=response, model=error) - - deserialized = self._deserialize("RestoreOperation", pipeline_response) - - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output, + ) + return AsyncLROPoller[_models.FullBackupOperation]( + self._client, raw_result, get_long_running_output, polling_method # type: ignore + ) - async def _selective_key_restore_operation_initial( + @api_version_validation( + method_added_on="7.6-preview.2", + params_added_on={"7.6-preview.2": ["api_version", "content_type", "accept"]}, + ) + async def _pre_full_backup_initial( self, - vault_base_url: str, - key_name: str, - restore_blob_details: Optional[Union[_models.SelectiveKeyRestoreOperationParameters, IO[bytes]]] = None, + pre_backup_operation_parameters: Union[_models.PreBackupOperationParameters, JSON, IO[bytes]], **kwargs: Any - ) -> _models.SelectiveKeyRestoreOperation: - error_map = { + ) -> AsyncIterator[bytes]: + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, @@ -599,34 +1191,30 @@ async def _selective_key_restore_operation_initial( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.SelectiveKeyRestoreOperation] = kwargs.pop("cls", None) + cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) content_type = content_type or "application/json" - _json = None _content = None - if isinstance(restore_blob_details, (IOBase, bytes)): - _content = restore_blob_details + if isinstance(pre_backup_operation_parameters, (IOBase, bytes)): + _content = pre_backup_operation_parameters else: - if restore_blob_details is not None: - _json = self._serialize.body(restore_blob_details, "SelectiveKeyRestoreOperationParameters") - else: - _json = None + _content = json.dumps(pre_backup_operation_parameters, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_key_vault_selective_key_restore_operation_request( - key_name=key_name, + _request = build_key_vault_pre_full_backup_request( content_type=content_type, api_version=self._config.api_version, - json=_json, content=_content, headers=_headers, params=_params, ) path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _stream = True pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access _request, stream=_stream, **kwargs ) @@ -634,19 +1222,21 @@ async def _selective_key_restore_operation_initial( response = pipeline_response.http_response if response.status_code not in [202]: - if _stream: + try: await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) raise HttpResponseError(response=response, model=error) response_headers = {} - response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) response_headers["Azure-AsyncOperation"] = self._deserialize( "str", response.headers.get("Azure-AsyncOperation") ) + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) - deserialized = self._deserialize("SelectiveKeyRestoreOperation", pipeline_response) + deserialized = response.iter_bytes() if cls: return cls(pipeline_response, deserialized, response_headers) # type: ignore @@ -654,243 +1244,160 @@ async def _selective_key_restore_operation_initial( return deserialized # type: ignore @overload - async def begin_selective_key_restore_operation( + async def begin_pre_full_backup( self, - vault_base_url: str, - key_name: str, - restore_blob_details: Optional[_models.SelectiveKeyRestoreOperationParameters] = None, + pre_backup_operation_parameters: _models.PreBackupOperationParameters, *, content_type: str = "application/json", **kwargs: Any - ) -> AsyncLROPoller[_models.SelectiveKeyRestoreOperation]: - """Restores all key versions of a given key using user supplied SAS token pointing to a previously - stored Azure Blob storage backup folder. + ) -> AsyncLROPoller[_models.FullBackupOperation]: + """Pre-backup operation for checking whether the customer can perform a full backup operation. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param key_name: The name of the key to be restored from the user supplied backup. Required. - :type key_name: str - :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous - successful full backup was stored. Default value is None. - :type restore_blob_details: ~azure.keyvault.v7_5.models.SelectiveKeyRestoreOperationParameters + :param pre_backup_operation_parameters: Optional parameters to validate prior to performing a + full backup operation. Required. + :type pre_backup_operation_parameters: + ~azure.keyvault.administration.models.PreBackupOperationParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: An instance of AsyncLROPoller that returns SelectiveKeyRestoreOperation + :return: An instance of AsyncLROPoller that returns FullBackupOperation. The + FullBackupOperation is compatible with MutableMapping :rtype: - ~azure.core.polling.AsyncLROPoller[~azure.keyvault.v7_5.models.SelectiveKeyRestoreOperation] + ~azure.core.polling.AsyncLROPoller[~azure.keyvault.administration.models.FullBackupOperation] :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def begin_selective_key_restore_operation( - self, - vault_base_url: str, - key_name: str, - restore_blob_details: Optional[IO[bytes]] = None, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> AsyncLROPoller[_models.SelectiveKeyRestoreOperation]: - """Restores all key versions of a given key using user supplied SAS token pointing to a previously - stored Azure Blob storage backup folder. + async def begin_pre_full_backup( + self, pre_backup_operation_parameters: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> AsyncLROPoller[_models.FullBackupOperation]: + """Pre-backup operation for checking whether the customer can perform a full backup operation. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param key_name: The name of the key to be restored from the user supplied backup. Required. - :type key_name: str - :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous - successful full backup was stored. Default value is None. - :type restore_blob_details: IO[bytes] + :param pre_backup_operation_parameters: Optional parameters to validate prior to performing a + full backup operation. Required. + :type pre_backup_operation_parameters: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of AsyncLROPoller that returns FullBackupOperation. The + FullBackupOperation is compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.keyvault.administration.models.FullBackupOperation] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def begin_pre_full_backup( + self, pre_backup_operation_parameters: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> AsyncLROPoller[_models.FullBackupOperation]: + """Pre-backup operation for checking whether the customer can perform a full backup operation. + + :param pre_backup_operation_parameters: Optional parameters to validate prior to performing a + full backup operation. Required. + :type pre_backup_operation_parameters: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: An instance of AsyncLROPoller that returns SelectiveKeyRestoreOperation + :return: An instance of AsyncLROPoller that returns FullBackupOperation. The + FullBackupOperation is compatible with MutableMapping :rtype: - ~azure.core.polling.AsyncLROPoller[~azure.keyvault.v7_5.models.SelectiveKeyRestoreOperation] + ~azure.core.polling.AsyncLROPoller[~azure.keyvault.administration.models.FullBackupOperation] :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace_async - async def begin_selective_key_restore_operation( + @api_version_validation( + method_added_on="7.6-preview.2", + params_added_on={"7.6-preview.2": ["api_version", "content_type", "accept"]}, + ) + async def begin_pre_full_backup( self, - vault_base_url: str, - key_name: str, - restore_blob_details: Optional[Union[_models.SelectiveKeyRestoreOperationParameters, IO[bytes]]] = None, + pre_backup_operation_parameters: Union[_models.PreBackupOperationParameters, JSON, IO[bytes]], **kwargs: Any - ) -> AsyncLROPoller[_models.SelectiveKeyRestoreOperation]: - """Restores all key versions of a given key using user supplied SAS token pointing to a previously - stored Azure Blob storage backup folder. - - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param key_name: The name of the key to be restored from the user supplied backup. Required. - :type key_name: str - :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous - successful full backup was stored. Is either a SelectiveKeyRestoreOperationParameters type or a - IO[bytes] type. Default value is None. - :type restore_blob_details: ~azure.keyvault.v7_5.models.SelectiveKeyRestoreOperationParameters - or IO[bytes] - :keyword content_type: Body Parameter content-type. Known values are: 'application/json'. - Default value is None. - :paramtype content_type: str - :return: An instance of AsyncLROPoller that returns SelectiveKeyRestoreOperation + ) -> AsyncLROPoller[_models.FullBackupOperation]: + """Pre-backup operation for checking whether the customer can perform a full backup operation. + + :param pre_backup_operation_parameters: Optional parameters to validate prior to performing a + full backup operation. Is one of the following types: PreBackupOperationParameters, JSON, + IO[bytes] Required. + :type pre_backup_operation_parameters: + ~azure.keyvault.administration.models.PreBackupOperationParameters or JSON or IO[bytes] + :return: An instance of AsyncLROPoller that returns FullBackupOperation. The + FullBackupOperation is compatible with MutableMapping :rtype: - ~azure.core.polling.AsyncLROPoller[~azure.keyvault.v7_5.models.SelectiveKeyRestoreOperation] + ~azure.core.polling.AsyncLROPoller[~azure.keyvault.administration.models.FullBackupOperation] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.SelectiveKeyRestoreOperation] = kwargs.pop("cls", None) + cls: ClsType[_models.FullBackupOperation] = kwargs.pop("cls", None) polling: Union[bool, AsyncPollingMethod] = kwargs.pop("polling", True) lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) cont_token: Optional[str] = kwargs.pop("continuation_token", None) if cont_token is None: - raw_result = await self._selective_key_restore_operation_initial( - vault_base_url=vault_base_url, - key_name=key_name, - restore_blob_details=restore_blob_details, + raw_result = await self._pre_full_backup_initial( + pre_backup_operation_parameters=pre_backup_operation_parameters, content_type=content_type, cls=lambda x, y, z: x, headers=_headers, params=_params, **kwargs ) + await raw_result.http_response.read() # type: ignore kwargs.pop("error_map", None) def get_long_running_output(pipeline_response): response_headers = {} response = pipeline_response.http_response - response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) response_headers["Azure-AsyncOperation"] = self._deserialize( "str", response.headers.get("Azure-AsyncOperation") ) + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) - deserialized = self._deserialize("SelectiveKeyRestoreOperation", pipeline_response) + deserialized = _deserialize(_models.FullBackupOperation, response.json()) if cls: return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } if polling is True: polling_method: AsyncPollingMethod = cast( AsyncPollingMethod, - AsyncLROBasePolling( - lro_delay, - lro_options={"final-state-via": "azure-async-operation"}, - path_format_arguments=path_format_arguments, - **kwargs - ), + AsyncLROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs), ) elif polling is False: polling_method = cast(AsyncPollingMethod, AsyncNoPolling()) else: polling_method = polling if cont_token: - return AsyncLROPoller[_models.SelectiveKeyRestoreOperation].from_continuation_token( + return AsyncLROPoller[_models.FullBackupOperation].from_continuation_token( polling_method=polling_method, continuation_token=cont_token, client=self._client, deserialization_callback=get_long_running_output, ) - return AsyncLROPoller[_models.SelectiveKeyRestoreOperation]( + return AsyncLROPoller[_models.FullBackupOperation]( self._client, raw_result, get_long_running_output, polling_method # type: ignore ) - @overload - async def update_setting( - self, - vault_base_url: str, - setting_name: str, - parameters: _models.UpdateSettingRequest, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.Setting: - """Updates key vault account setting, stores it, then returns the setting name and value to the - client. - - Description of the pool setting to be updated. - - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param setting_name: The name of the account setting. Must be a valid settings option. - Required. - :type setting_name: str - :param parameters: The parameters to update an account setting. Required. - :type parameters: ~azure.keyvault.v7_5.models.UpdateSettingRequest - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: Setting - :rtype: ~azure.keyvault.v7_5.models.Setting - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - async def update_setting( - self, - vault_base_url: str, - setting_name: str, - parameters: IO[bytes], - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.Setting: - """Updates key vault account setting, stores it, then returns the setting name and value to the - client. - - Description of the pool setting to be updated. - - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param setting_name: The name of the account setting. Must be a valid settings option. - Required. - :type setting_name: str - :param parameters: The parameters to update an account setting. Required. - :type parameters: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: Setting - :rtype: ~azure.keyvault.v7_5.models.Setting - :raises ~azure.core.exceptions.HttpResponseError: - """ - @distributed_trace_async - async def update_setting( - self, - vault_base_url: str, - setting_name: str, - parameters: Union[_models.UpdateSettingRequest, IO[bytes]], - **kwargs: Any - ) -> _models.Setting: - """Updates key vault account setting, stores it, then returns the setting name and value to the - client. - - Description of the pool setting to be updated. + async def restore_status(self, job_id: str, **kwargs: Any) -> _models.RestoreOperation: + """Returns the status of restore operation. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param setting_name: The name of the account setting. Must be a valid settings option. - Required. - :type setting_name: str - :param parameters: The parameters to update an account setting. Is either a - UpdateSettingRequest type or a IO[bytes] type. Required. - :type parameters: ~azure.keyvault.v7_5.models.UpdateSettingRequest or IO[bytes] - :keyword content_type: Body Parameter content-type. Known values are: 'application/json'. - Default value is None. - :paramtype content_type: str - :return: Setting - :rtype: ~azure.keyvault.v7_5.models.Setting + :param job_id: The Job Id returned part of the restore operation. Required. + :type job_id: str + :return: RestoreOperation. The RestoreOperation is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RestoreOperation :raises ~azure.core.exceptions.HttpResponseError: """ - error_map = { + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, @@ -898,35 +1405,25 @@ async def update_setting( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.Setting] = kwargs.pop("cls", None) - - content_type = content_type or "application/json" - _json = None - _content = None - if isinstance(parameters, (IOBase, bytes)): - _content = parameters - else: - _json = self._serialize.body(parameters, "UpdateSettingRequest") + cls: ClsType[_models.RestoreOperation] = kwargs.pop("cls", None) - _request = build_key_vault_update_setting_request( - setting_name=setting_name, - content_type=content_type, + _request = build_key_vault_restore_status_request( + job_id=job_id, api_version=self._config.api_version, - json=_json, - content=_content, headers=_headers, params=_params, ) path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access _request, stream=_stream, **kwargs ) @@ -935,34 +1432,34 @@ async def update_setting( if response.status_code not in [200]: if _stream: - await response.read() # Load the body in memory and close the socket + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) raise HttpResponseError(response=response, model=error) - deserialized = self._deserialize("Setting", pipeline_response) + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize(_models.RestoreOperation, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @distributed_trace_async - async def get_setting(self, vault_base_url: str, setting_name: str, **kwargs: Any) -> _models.Setting: - """Get specified account setting object. - - Retrieves the setting object of a specified setting name. - - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param setting_name: The name of the account setting. Must be a valid settings option. - Required. - :type setting_name: str - :return: Setting - :rtype: ~azure.keyvault.v7_5.models.Setting - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map = { + @api_version_validation( + method_added_on="7.6-preview.2", + params_added_on={"7.6-preview.2": ["api_version", "content_type", "accept"]}, + ) + async def _pre_full_restore_operation_initial( + self, + pre_restore_operation_parameters: Union[_models.PreRestoreOperationParameters, JSON, IO[bytes]], + **kwargs: Any + ) -> AsyncIterator[bytes]: + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, @@ -970,137 +1467,210 @@ async def get_setting(self, vault_base_url: str, setting_name: str, **kwargs: An } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.Setting] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) - _request = build_key_vault_get_setting_request( - setting_name=setting_name, + content_type = content_type or "application/json" + _content = None + if isinstance(pre_restore_operation_parameters, (IOBase, bytes)): + _content = pre_restore_operation_parameters + else: + _content = json.dumps(pre_restore_operation_parameters, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_key_vault_pre_full_restore_operation_request( + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _stream = True pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: + if response.status_code not in [202]: + try: await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) raise HttpResponseError(response=response, model=error) - deserialized = self._deserialize("Setting", pipeline_response) + response_headers = {} + response_headers["Azure-AsyncOperation"] = self._deserialize( + "str", response.headers.get("Azure-AsyncOperation") + ) + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) + + deserialized = response.iter_bytes() if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore - @distributed_trace_async - async def get_settings(self, vault_base_url: str, **kwargs: Any) -> _models.SettingsListResult: - """List account settings. + @overload + async def begin_pre_full_restore_operation( + self, + pre_restore_operation_parameters: _models.PreRestoreOperationParameters, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> AsyncLROPoller[_models.RestoreOperation]: + """Pre-restore operation for checking whether the customer can perform a full restore operation. - Retrieves a list of all the available account settings that can be configured. + :param pre_restore_operation_parameters: Optional pre restore parameters to validate prior to + performing a full restore operation. Required. + :type pre_restore_operation_parameters: + ~azure.keyvault.administration.models.PreRestoreOperationParameters + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of AsyncLROPoller that returns RestoreOperation. The RestoreOperation is + compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.keyvault.administration.models.RestoreOperation] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def begin_pre_full_restore_operation( + self, pre_restore_operation_parameters: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> AsyncLROPoller[_models.RestoreOperation]: + """Pre-restore operation for checking whether the customer can perform a full restore operation. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :return: SettingsListResult - :rtype: ~azure.keyvault.v7_5.models.SettingsListResult + :param pre_restore_operation_parameters: Optional pre restore parameters to validate prior to + performing a full restore operation. Required. + :type pre_restore_operation_parameters: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of AsyncLROPoller that returns RestoreOperation. The RestoreOperation is + compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.keyvault.administration.models.RestoreOperation] :raises ~azure.core.exceptions.HttpResponseError: """ - error_map = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} + @overload + async def begin_pre_full_restore_operation( + self, pre_restore_operation_parameters: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> AsyncLROPoller[_models.RestoreOperation]: + """Pre-restore operation for checking whether the customer can perform a full restore operation. + + :param pre_restore_operation_parameters: Optional pre restore parameters to validate prior to + performing a full restore operation. Required. + :type pre_restore_operation_parameters: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of AsyncLROPoller that returns RestoreOperation. The RestoreOperation is + compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.keyvault.administration.models.RestoreOperation] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace_async + @api_version_validation( + method_added_on="7.6-preview.2", + params_added_on={"7.6-preview.2": ["api_version", "content_type", "accept"]}, + ) + async def begin_pre_full_restore_operation( + self, + pre_restore_operation_parameters: Union[_models.PreRestoreOperationParameters, JSON, IO[bytes]], + **kwargs: Any + ) -> AsyncLROPoller[_models.RestoreOperation]: + """Pre-restore operation for checking whether the customer can perform a full restore operation. + + :param pre_restore_operation_parameters: Optional pre restore parameters to validate prior to + performing a full restore operation. Is one of the following types: + PreRestoreOperationParameters, JSON, IO[bytes] Required. + :type pre_restore_operation_parameters: + ~azure.keyvault.administration.models.PreRestoreOperationParameters or JSON or IO[bytes] + :return: An instance of AsyncLROPoller that returns RestoreOperation. The RestoreOperation is + compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.keyvault.administration.models.RestoreOperation] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.RestoreOperation] = kwargs.pop("cls", None) + polling: Union[bool, AsyncPollingMethod] = kwargs.pop("polling", True) + lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) + cont_token: Optional[str] = kwargs.pop("continuation_token", None) + if cont_token is None: + raw_result = await self._pre_full_restore_operation_initial( + pre_restore_operation_parameters=pre_restore_operation_parameters, + content_type=content_type, + cls=lambda x, y, z: x, + headers=_headers, + params=_params, + **kwargs + ) + await raw_result.http_response.read() # type: ignore + kwargs.pop("error_map", None) + + def get_long_running_output(pipeline_response): + response_headers = {} + response = pipeline_response.http_response + response_headers["Azure-AsyncOperation"] = self._deserialize( + "str", response.headers.get("Azure-AsyncOperation") + ) + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) - cls: ClsType[_models.SettingsListResult] = kwargs.pop("cls", None) + deserialized = _deserialize(_models.RestoreOperation, response.json()) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + return deserialized - _request = build_key_vault_get_settings_request( - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access - _request, stream=_stream, **kwargs + if polling is True: + polling_method: AsyncPollingMethod = cast( + AsyncPollingMethod, + AsyncLROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs), + ) + elif polling is False: + polling_method = cast(AsyncPollingMethod, AsyncNoPolling()) + else: + polling_method = polling + if cont_token: + return AsyncLROPoller[_models.RestoreOperation].from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output, + ) + return AsyncLROPoller[_models.RestoreOperation]( + self._client, raw_result, get_long_running_output, polling_method # type: ignore ) - response = pipeline_response.http_response - - if response.status_code not in [200]: - if _stream: - await response.read() # Load the body in memory and close the socket - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) - raise HttpResponseError(response=response, model=error) - - deserialized = self._deserialize("SettingsListResult", pipeline_response) - - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore - - -class RoleDefinitionsOperations: - """ - .. warning:: - **DO NOT** instantiate this class directly. - - Instead, you should access the following operations through - :class:`~azure.keyvault.v7_5.aio.KeyVaultClient`'s - :attr:`role_definitions` attribute. - """ - - models = _models - - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client = input_args.pop(0) if input_args else kwargs.pop("client") - self._config = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize = input_args.pop(0) if input_args else kwargs.pop("deserializer") - - @distributed_trace_async - async def delete( - self, vault_base_url: str, scope: str, role_definition_name: str, **kwargs: Any - ) -> _models.RoleDefinition: - """Deletes a custom role definition. - - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param scope: The scope of the role definition to delete. Managed HSM only supports '/'. - Required. - :type scope: str - :param role_definition_name: The name (GUID) of the role definition to delete. Required. - :type role_definition_name: str - :return: RoleDefinition - :rtype: ~azure.keyvault.v7_5.models.RoleDefinition - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map = { + async def _full_restore_operation_initial( + self, restore_blob_details: Union[_models.RestoreOperationParameters, JSON, IO[bytes]], **kwargs: Any + ) -> AsyncIterator[bytes]: + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, @@ -1108,210 +1678,274 @@ async def delete( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.RoleDefinition] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) - _request = build_role_definitions_delete_request( - scope=scope, - role_definition_name=role_definition_name, + content_type = content_type or "application/json" + _content = None + if isinstance(restore_blob_details, (IOBase, bytes)): + _content = restore_blob_details + else: + _content = json.dumps(restore_blob_details, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_key_vault_full_restore_operation_request( + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _stream = True + pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: + if response.status_code not in [202]: + try: await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) raise HttpResponseError(response=response, model=error) - deserialized = self._deserialize("RoleDefinition", pipeline_response) + response_headers = {} + response_headers["Azure-AsyncOperation"] = self._deserialize( + "str", response.headers.get("Azure-AsyncOperation") + ) + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) + + deserialized = response.iter_bytes() if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore @overload - async def create_or_update( + async def begin_full_restore_operation( self, - vault_base_url: str, - scope: str, - role_definition_name: str, - parameters: _models.RoleDefinitionCreateParameters, + restore_blob_details: _models.RestoreOperationParameters, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.RoleDefinition: - """Creates or updates a custom role definition. + ) -> AsyncLROPoller[_models.RestoreOperation]: + """Restores all key materials using the SAS token pointing to a previously stored Azure Blob + storage backup folder. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param scope: The scope of the role definition to create or update. Managed HSM only supports - '/'. Required. - :type scope: str - :param role_definition_name: The name of the role definition to create or update. It can be any - valid GUID. Required. - :type role_definition_name: str - :param parameters: Parameters for the role definition. Required. - :type parameters: ~azure.keyvault.v7_5.models.RoleDefinitionCreateParameters + :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous + successful full backup was stored. Required. + :type restore_blob_details: ~azure.keyvault.administration.models.RestoreOperationParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: RoleDefinition - :rtype: ~azure.keyvault.v7_5.models.RoleDefinition + :return: An instance of AsyncLROPoller that returns RestoreOperation. The RestoreOperation is + compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.keyvault.administration.models.RestoreOperation] :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def create_or_update( - self, - vault_base_url: str, - scope: str, - role_definition_name: str, - parameters: IO[bytes], - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.RoleDefinition: - """Creates or updates a custom role definition. + async def begin_full_restore_operation( + self, restore_blob_details: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> AsyncLROPoller[_models.RestoreOperation]: + """Restores all key materials using the SAS token pointing to a previously stored Azure Blob + storage backup folder. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param scope: The scope of the role definition to create or update. Managed HSM only supports - '/'. Required. - :type scope: str - :param role_definition_name: The name of the role definition to create or update. It can be any - valid GUID. Required. - :type role_definition_name: str - :param parameters: Parameters for the role definition. Required. - :type parameters: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous + successful full backup was stored. Required. + :type restore_blob_details: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: RoleDefinition - :rtype: ~azure.keyvault.v7_5.models.RoleDefinition + :return: An instance of AsyncLROPoller that returns RestoreOperation. The RestoreOperation is + compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.keyvault.administration.models.RestoreOperation] :raises ~azure.core.exceptions.HttpResponseError: """ - @distributed_trace_async - async def create_or_update( - self, - vault_base_url: str, - scope: str, - role_definition_name: str, - parameters: Union[_models.RoleDefinitionCreateParameters, IO[bytes]], - **kwargs: Any - ) -> _models.RoleDefinition: - """Creates or updates a custom role definition. + @overload + async def begin_full_restore_operation( + self, restore_blob_details: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> AsyncLROPoller[_models.RestoreOperation]: + """Restores all key materials using the SAS token pointing to a previously stored Azure Blob + storage backup folder. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param scope: The scope of the role definition to create or update. Managed HSM only supports - '/'. Required. - :type scope: str - :param role_definition_name: The name of the role definition to create or update. It can be any - valid GUID. Required. - :type role_definition_name: str - :param parameters: Parameters for the role definition. Is either a - RoleDefinitionCreateParameters type or a IO[bytes] type. Required. - :type parameters: ~azure.keyvault.v7_5.models.RoleDefinitionCreateParameters or IO[bytes] - :keyword content_type: Body Parameter content-type. Known values are: 'application/json'. - Default value is None. + :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous + successful full backup was stored. Required. + :type restore_blob_details: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". :paramtype content_type: str - :return: RoleDefinition - :rtype: ~azure.keyvault.v7_5.models.RoleDefinition + :return: An instance of AsyncLROPoller that returns RestoreOperation. The RestoreOperation is + compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.keyvault.administration.models.RestoreOperation] :raises ~azure.core.exceptions.HttpResponseError: """ - error_map = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) + @distributed_trace_async + async def begin_full_restore_operation( + self, restore_blob_details: Union[_models.RestoreOperationParameters, JSON, IO[bytes]], **kwargs: Any + ) -> AsyncLROPoller[_models.RestoreOperation]: + """Restores all key materials using the SAS token pointing to a previously stored Azure Blob + storage backup folder. + + :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous + successful full backup was stored. Is one of the following types: RestoreOperationParameters, + JSON, IO[bytes] Required. + :type restore_blob_details: ~azure.keyvault.administration.models.RestoreOperationParameters or + JSON or IO[bytes] + :return: An instance of AsyncLROPoller that returns RestoreOperation. The RestoreOperation is + compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.keyvault.administration.models.RestoreOperation] + :raises ~azure.core.exceptions.HttpResponseError: + """ _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.RoleDefinition] = kwargs.pop("cls", None) + cls: ClsType[_models.RestoreOperation] = kwargs.pop("cls", None) + polling: Union[bool, AsyncPollingMethod] = kwargs.pop("polling", True) + lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) + cont_token: Optional[str] = kwargs.pop("continuation_token", None) + if cont_token is None: + raw_result = await self._full_restore_operation_initial( + restore_blob_details=restore_blob_details, + content_type=content_type, + cls=lambda x, y, z: x, + headers=_headers, + params=_params, + **kwargs + ) + await raw_result.http_response.read() # type: ignore + kwargs.pop("error_map", None) - content_type = content_type or "application/json" - _json = None - _content = None - if isinstance(parameters, (IOBase, bytes)): - _content = parameters + def get_long_running_output(pipeline_response): + response_headers = {} + response = pipeline_response.http_response + response_headers["Azure-AsyncOperation"] = self._deserialize( + "str", response.headers.get("Azure-AsyncOperation") + ) + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) + + deserialized = _deserialize(_models.RestoreOperation, response.json()) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + return deserialized + + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + + if polling is True: + polling_method: AsyncPollingMethod = cast( + AsyncPollingMethod, + AsyncLROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs), + ) + elif polling is False: + polling_method = cast(AsyncPollingMethod, AsyncNoPolling()) else: - _json = self._serialize.body(parameters, "RoleDefinitionCreateParameters") + polling_method = polling + if cont_token: + return AsyncLROPoller[_models.RestoreOperation].from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output, + ) + return AsyncLROPoller[_models.RestoreOperation]( + self._client, raw_result, get_long_running_output, polling_method # type: ignore + ) + + @distributed_trace_async + async def selective_key_restore_status(self, job_id: str, **kwargs: Any) -> _models.SelectiveKeyRestoreOperation: + """Returns the status of the selective key restore operation. + + :param job_id: The Job Id returned part of the restore operation. Required. + :type job_id: str + :return: SelectiveKeyRestoreOperation. The SelectiveKeyRestoreOperation is compatible with + MutableMapping + :rtype: ~azure.keyvault.administration.models.SelectiveKeyRestoreOperation + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) - _request = build_role_definitions_create_or_update_request( - scope=scope, - role_definition_name=role_definition_name, - content_type=content_type, + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.SelectiveKeyRestoreOperation] = kwargs.pop("cls", None) + + _request = build_key_vault_selective_key_restore_status_request( + job_id=job_id, api_version=self._config.api_version, - json=_json, - content=_content, headers=_headers, params=_params, ) path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [201]: + if response.status_code not in [200]: if _stream: - await response.read() # Load the body in memory and close the socket + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) raise HttpResponseError(response=response, model=error) - deserialized = self._deserialize("RoleDefinition", pipeline_response) + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize(_models.SelectiveKeyRestoreOperation, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @distributed_trace_async - async def get( - self, vault_base_url: str, scope: str, role_definition_name: str, **kwargs: Any - ) -> _models.RoleDefinition: - """Get the specified role definition. - - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param scope: The scope of the role definition to get. Managed HSM only supports '/'. Required. - :type scope: str - :param role_definition_name: The name of the role definition to get. Required. - :type role_definition_name: str - :return: RoleDefinition - :rtype: ~azure.keyvault.v7_5.models.RoleDefinition - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map = { + async def _selective_key_restore_operation_initial( + self, + key_name: str, + restore_blob_details: Union[_models.SelectiveKeyRestoreOperationParameters, JSON, IO[bytes]], + **kwargs: Any + ) -> AsyncIterator[bytes]: + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, @@ -1319,311 +1953,311 @@ async def get( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.RoleDefinition] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[AsyncIterator[bytes]] = kwargs.pop("cls", None) - _request = build_role_definitions_get_request( - scope=scope, - role_definition_name=role_definition_name, + content_type = content_type or "application/json" + _content = None + if isinstance(restore_blob_details, (IOBase, bytes)): + _content = restore_blob_details + else: + _content = json.dumps(restore_blob_details, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_key_vault_selective_key_restore_operation_request( + key_name=key_name, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _stream = True + pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: + if response.status_code not in [202]: + try: await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) raise HttpResponseError(response=response, model=error) - deserialized = self._deserialize("RoleDefinition", pipeline_response) + response_headers = {} + response_headers["Azure-AsyncOperation"] = self._deserialize( + "str", response.headers.get("Azure-AsyncOperation") + ) + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) + + deserialized = response.iter_bytes() if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore - @distributed_trace - def list( - self, vault_base_url: str, scope: str, *, filter: Optional[str] = None, **kwargs: Any - ) -> AsyncIterable["_models.RoleDefinition"]: - """Get all role definitions that are applicable at scope and above. + @overload + async def begin_selective_key_restore_operation( + self, + key_name: str, + restore_blob_details: _models.SelectiveKeyRestoreOperationParameters, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> AsyncLROPoller[_models.SelectiveKeyRestoreOperation]: + """Restores all key versions of a given key using user supplied SAS token pointing to a previously + stored Azure Blob storage backup folder. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param scope: The scope of the role definition. Required. - :type scope: str - :keyword filter: The filter to apply on the operation. Use atScopeAndBelow filter to search - below the given scope as well. Default value is None. - :paramtype filter: str - :return: An iterator like instance of RoleDefinition - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.v7_5.models.RoleDefinition] + :param key_name: The name of the key to be restored from the user supplied backup. Required. + :type key_name: str + :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous + successful full backup was stored. Required. + :type restore_blob_details: + ~azure.keyvault.administration.models.SelectiveKeyRestoreOperationParameters + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of AsyncLROPoller that returns SelectiveKeyRestoreOperation. The + SelectiveKeyRestoreOperation is compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.keyvault.administration.models.SelectiveKeyRestoreOperation] :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[_models._models.RoleDefinitionListResult] = kwargs.pop( # pylint: disable=protected-access - "cls", None - ) - - error_map = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - def prepare_request(next_link=None): - if not next_link: - - _request = build_role_definitions_list_request( - scope=scope, - filter=filter, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params - ) - path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - return _request - - async def extract_data(pipeline_response): - deserialized = self._deserialize( - _models._models.RoleDefinitionListResult, pipeline_response # pylint: disable=protected-access - ) - list_of_elem = deserialized.value - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.next_link or None, AsyncList(list_of_elem) - - async def get_next(next_link=None): - _request = prepare_request(next_link) - - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response - - if response.status_code not in [200]: - if _stream: - await response.read() # Load the body in memory and close the socket - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) - raise HttpResponseError(response=response, model=error) - return pipeline_response - - return AsyncItemPaged(get_next, extract_data) - - -class RoleAssignmentsOperations: - """ - .. warning:: - **DO NOT** instantiate this class directly. + @overload + async def begin_selective_key_restore_operation( + self, key_name: str, restore_blob_details: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> AsyncLROPoller[_models.SelectiveKeyRestoreOperation]: + """Restores all key versions of a given key using user supplied SAS token pointing to a previously + stored Azure Blob storage backup folder. - Instead, you should access the following operations through - :class:`~azure.keyvault.v7_5.aio.KeyVaultClient`'s - :attr:`role_assignments` attribute. - """ + :param key_name: The name of the key to be restored from the user supplied backup. Required. + :type key_name: str + :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous + successful full backup was stored. Required. + :type restore_blob_details: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of AsyncLROPoller that returns SelectiveKeyRestoreOperation. The + SelectiveKeyRestoreOperation is compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.keyvault.administration.models.SelectiveKeyRestoreOperation] + :raises ~azure.core.exceptions.HttpResponseError: + """ - models = _models + @overload + async def begin_selective_key_restore_operation( + self, key_name: str, restore_blob_details: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> AsyncLROPoller[_models.SelectiveKeyRestoreOperation]: + """Restores all key versions of a given key using user supplied SAS token pointing to a previously + stored Azure Blob storage backup folder. - def __init__(self, *args, **kwargs) -> None: - input_args = list(args) - self._client = input_args.pop(0) if input_args else kwargs.pop("client") - self._config = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize = input_args.pop(0) if input_args else kwargs.pop("deserializer") + :param key_name: The name of the key to be restored from the user supplied backup. Required. + :type key_name: str + :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous + successful full backup was stored. Required. + :type restore_blob_details: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of AsyncLROPoller that returns SelectiveKeyRestoreOperation. The + SelectiveKeyRestoreOperation is compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.keyvault.administration.models.SelectiveKeyRestoreOperation] + :raises ~azure.core.exceptions.HttpResponseError: + """ @distributed_trace_async - async def delete( - self, vault_base_url: str, scope: str, role_assignment_name: str, **kwargs: Any - ) -> _models.RoleAssignment: - """Deletes a role assignment. + async def begin_selective_key_restore_operation( + self, + key_name: str, + restore_blob_details: Union[_models.SelectiveKeyRestoreOperationParameters, JSON, IO[bytes]], + **kwargs: Any + ) -> AsyncLROPoller[_models.SelectiveKeyRestoreOperation]: + """Restores all key versions of a given key using user supplied SAS token pointing to a previously + stored Azure Blob storage backup folder. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param scope: The scope of the role assignment to delete. Required. - :type scope: str - :param role_assignment_name: The name of the role assignment to delete. Required. - :type role_assignment_name: str - :return: RoleAssignment - :rtype: ~azure.keyvault.v7_5.models.RoleAssignment + :param key_name: The name of the key to be restored from the user supplied backup. Required. + :type key_name: str + :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous + successful full backup was stored. Is one of the following types: + SelectiveKeyRestoreOperationParameters, JSON, IO[bytes] Required. + :type restore_blob_details: + ~azure.keyvault.administration.models.SelectiveKeyRestoreOperationParameters or JSON or + IO[bytes] + :return: An instance of AsyncLROPoller that returns SelectiveKeyRestoreOperation. The + SelectiveKeyRestoreOperation is compatible with MutableMapping + :rtype: + ~azure.core.polling.AsyncLROPoller[~azure.keyvault.administration.models.SelectiveKeyRestoreOperation] :raises ~azure.core.exceptions.HttpResponseError: """ - error_map = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.RoleAssignment] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.SelectiveKeyRestoreOperation] = kwargs.pop("cls", None) + polling: Union[bool, AsyncPollingMethod] = kwargs.pop("polling", True) + lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) + cont_token: Optional[str] = kwargs.pop("continuation_token", None) + if cont_token is None: + raw_result = await self._selective_key_restore_operation_initial( + key_name=key_name, + restore_blob_details=restore_blob_details, + content_type=content_type, + cls=lambda x, y, z: x, + headers=_headers, + params=_params, + **kwargs + ) + await raw_result.http_response.read() # type: ignore + kwargs.pop("error_map", None) + + def get_long_running_output(pipeline_response): + response_headers = {} + response = pipeline_response.http_response + response_headers["Azure-AsyncOperation"] = self._deserialize( + "str", response.headers.get("Azure-AsyncOperation") + ) + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) + + deserialized = _deserialize(_models.SelectiveKeyRestoreOperation, response.json()) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + return deserialized - _request = build_role_assignments_delete_request( - scope=scope, - role_assignment_name=role_assignment_name, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs + if polling is True: + polling_method: AsyncPollingMethod = cast( + AsyncPollingMethod, + AsyncLROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs), + ) + elif polling is False: + polling_method = cast(AsyncPollingMethod, AsyncNoPolling()) + else: + polling_method = polling + if cont_token: + return AsyncLROPoller[_models.SelectiveKeyRestoreOperation].from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output, + ) + return AsyncLROPoller[_models.SelectiveKeyRestoreOperation]( + self._client, raw_result, get_long_running_output, polling_method # type: ignore ) - response = pipeline_response.http_response - - if response.status_code not in [200]: - if _stream: - await response.read() # Load the body in memory and close the socket - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) - raise HttpResponseError(response=response, model=error) - - deserialized = self._deserialize("RoleAssignment", pipeline_response) - - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore - @overload - async def create( + async def update_setting( self, - vault_base_url: str, - scope: str, - role_assignment_name: str, - parameters: _models.RoleAssignmentCreateParameters, + setting_name: str, + parameters: _models.UpdateSettingRequest, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.RoleAssignment: - """Creates a role assignment. + ) -> _models.Setting: + """Updates key vault account setting, stores it, then returns the setting name and value to the + client. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param scope: The scope of the role assignment to create. Required. - :type scope: str - :param role_assignment_name: The name of the role assignment to create. It can be any valid - GUID. Required. - :type role_assignment_name: str - :param parameters: Parameters for the role assignment. Required. - :type parameters: ~azure.keyvault.v7_5.models.RoleAssignmentCreateParameters + Description of the pool setting to be updated. + + :param setting_name: The name of the account setting. Must be a valid settings option. + Required. + :type setting_name: str + :param parameters: The parameters to update an account setting. Required. + :type parameters: ~azure.keyvault.administration.models.UpdateSettingRequest :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: RoleAssignment - :rtype: ~azure.keyvault.v7_5.models.RoleAssignment + :return: Setting. The Setting is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.Setting :raises ~azure.core.exceptions.HttpResponseError: """ @overload - async def create( - self, - vault_base_url: str, - scope: str, - role_assignment_name: str, - parameters: IO[bytes], - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.RoleAssignment: - """Creates a role assignment. + async def update_setting( + self, setting_name: str, parameters: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.Setting: + """Updates key vault account setting, stores it, then returns the setting name and value to the + client. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param scope: The scope of the role assignment to create. Required. - :type scope: str - :param role_assignment_name: The name of the role assignment to create. It can be any valid - GUID. Required. - :type role_assignment_name: str - :param parameters: Parameters for the role assignment. Required. + Description of the pool setting to be updated. + + :param setting_name: The name of the account setting. Must be a valid settings option. + Required. + :type setting_name: str + :param parameters: The parameters to update an account setting. Required. + :type parameters: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: Setting. The Setting is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.Setting + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + async def update_setting( + self, setting_name: str, parameters: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.Setting: + """Updates key vault account setting, stores it, then returns the setting name and value to the + client. + + Description of the pool setting to be updated. + + :param setting_name: The name of the account setting. Must be a valid settings option. + Required. + :type setting_name: str + :param parameters: The parameters to update an account setting. Required. :type parameters: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: RoleAssignment - :rtype: ~azure.keyvault.v7_5.models.RoleAssignment + :return: Setting. The Setting is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.Setting :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace_async - async def create( - self, - vault_base_url: str, - scope: str, - role_assignment_name: str, - parameters: Union[_models.RoleAssignmentCreateParameters, IO[bytes]], - **kwargs: Any - ) -> _models.RoleAssignment: - """Creates a role assignment. + async def update_setting( + self, setting_name: str, parameters: Union[_models.UpdateSettingRequest, JSON, IO[bytes]], **kwargs: Any + ) -> _models.Setting: + """Updates key vault account setting, stores it, then returns the setting name and value to the + client. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param scope: The scope of the role assignment to create. Required. - :type scope: str - :param role_assignment_name: The name of the role assignment to create. It can be any valid - GUID. Required. - :type role_assignment_name: str - :param parameters: Parameters for the role assignment. Is either a - RoleAssignmentCreateParameters type or a IO[bytes] type. Required. - :type parameters: ~azure.keyvault.v7_5.models.RoleAssignmentCreateParameters or IO[bytes] - :keyword content_type: Body Parameter content-type. Known values are: 'application/json'. - Default value is None. - :paramtype content_type: str - :return: RoleAssignment - :rtype: ~azure.keyvault.v7_5.models.RoleAssignment + Description of the pool setting to be updated. + + :param setting_name: The name of the account setting. Must be a valid settings option. + Required. + :type setting_name: str + :param parameters: The parameters to update an account setting. Is one of the following types: + UpdateSettingRequest, JSON, IO[bytes] Required. + :type parameters: ~azure.keyvault.administration.models.UpdateSettingRequest or JSON or + IO[bytes] + :return: Setting. The Setting is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.Setting :raises ~azure.core.exceptions.HttpResponseError: """ - error_map = { + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, @@ -1635,46 +2269,51 @@ async def create( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.RoleAssignment] = kwargs.pop("cls", None) + cls: ClsType[_models.Setting] = kwargs.pop("cls", None) content_type = content_type or "application/json" - _json = None _content = None if isinstance(parameters, (IOBase, bytes)): _content = parameters else: - _json = self._serialize.body(parameters, "RoleAssignmentCreateParameters") + _content = json.dumps(parameters, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_role_assignments_create_request( - scope=scope, - role_assignment_name=role_assignment_name, + _request = build_key_vault_update_setting_request( + setting_name=setting_name, content_type=content_type, api_version=self._config.api_version, - json=_json, content=_content, headers=_headers, params=_params, ) path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [201]: + if response.status_code not in [200]: if _stream: - await response.read() # Load the body in memory and close the socket + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) raise HttpResponseError(response=response, model=error) - deserialized = self._deserialize("RoleAssignment", pipeline_response) + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize(_models.Setting, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -1682,22 +2321,19 @@ async def create( return deserialized # type: ignore @distributed_trace_async - async def get( - self, vault_base_url: str, scope: str, role_assignment_name: str, **kwargs: Any - ) -> _models.RoleAssignment: - """Get the specified role assignment. + async def get_setting(self, setting_name: str, **kwargs: Any) -> _models.Setting: + """Get specified account setting object. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param scope: The scope of the role assignment. Required. - :type scope: str - :param role_assignment_name: The name of the role assignment to get. Required. - :type role_assignment_name: str - :return: RoleAssignment - :rtype: ~azure.keyvault.v7_5.models.RoleAssignment + Retrieves the setting object of a specified setting name. + + :param setting_name: The name of the account setting. Must be a valid settings option. + Required. + :type setting_name: str + :return: Setting. The Setting is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.Setting :raises ~azure.core.exceptions.HttpResponseError: """ - error_map = { + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, @@ -1708,22 +2344,23 @@ async def get( _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.RoleAssignment] = kwargs.pop("cls", None) + cls: ClsType[_models.Setting] = kwargs.pop("cls", None) - _request = build_role_assignments_get_request( - scope=scope, - role_assignment_name=role_assignment_name, + _request = build_key_vault_get_setting_request( + setting_name=setting_name, api_version=self._config.api_version, headers=_headers, params=_params, ) path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access _request, stream=_stream, **kwargs ) @@ -1731,44 +2368,35 @@ async def get( if response.status_code not in [200]: if _stream: - await response.read() # Load the body in memory and close the socket + try: + await response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) raise HttpResponseError(response=response, model=error) - deserialized = self._deserialize("RoleAssignment", pipeline_response) + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize(_models.Setting, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @distributed_trace - def list_for_scope( - self, vault_base_url: str, scope: str, *, filter: Optional[str] = None, **kwargs: Any - ) -> AsyncIterable["_models.RoleAssignment"]: - """Gets role assignments for a scope. + @distributed_trace_async + async def get_settings(self, **kwargs: Any) -> _models.SettingsListResult: + """List account settings. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param scope: The scope of the role assignments. Required. - :type scope: str - :keyword filter: The filter to apply on the operation. Use $filter=atScope() to return all role - assignments at or above the scope. Use $filter=principalId eq {id} to return all role - assignments at, above or below the scope for the specified principal. Default value is None. - :paramtype filter: str - :return: An iterator like instance of RoleAssignment - :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.keyvault.v7_5.models.RoleAssignment] + Retrieves a list of all the available account settings that can be configured. + + :return: SettingsListResult. The SettingsListResult is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.SettingsListResult :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[_models._models.RoleAssignmentListResult] = kwargs.pop( # pylint: disable=protected-access - "cls", None - ) - - error_map = { + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, @@ -1776,66 +2404,46 @@ def list_for_scope( } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(next_link=None): - if not next_link: - - _request = build_role_assignments_list_for_scope_request( - scope=scope, - filter=filter, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params - ) - path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - return _request + cls: ClsType[_models.SettingsListResult] = kwargs.pop("cls", None) - async def extract_data(pipeline_response): - deserialized = self._deserialize( - _models._models.RoleAssignmentListResult, pipeline_response # pylint: disable=protected-access - ) - list_of_elem = deserialized.value - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.next_link or None, AsyncList(list_of_elem) + _request = build_key_vault_get_settings_request( + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - async def get_next(next_link=None): - _request = prepare_request(next_link) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = await self._client._pipeline.run( # type: ignore # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) - _stream = False - pipeline_response: PipelineResponse = await self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response + response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: + if response.status_code not in [200]: + if _stream: + try: await response.read() # Load the body in memory and close the socket - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) - raise HttpResponseError(response=response, model=error) + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) + raise HttpResponseError(response=response, model=error) - return pipeline_response + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize(_models.SettingsListResult, response.json()) - return AsyncItemPaged(get_next, extract_data) + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/aio/operations/_patch.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/operations/_patch.py similarity index 100% rename from sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/aio/operations/_patch.py rename to sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/aio/operations/_patch.py diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/models/__init__.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/models/__init__.py new file mode 100644 index 000000000000..753cb6201cea --- /dev/null +++ b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/models/__init__.py @@ -0,0 +1,82 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +# pylint: disable=wrong-import-position + +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from ._patch import * # pylint: disable=unused-wildcard-import + + +from ._models import ( # type: ignore + FullBackupOperation, + FullBackupOperationError, + KeyVaultError, + Permission, + PreBackupOperationParameters, + PreRestoreOperationParameters, + RestoreOperation, + RestoreOperationParameters, + RoleAssignment, + RoleAssignmentCreateParameters, + RoleAssignmentProperties, + RoleAssignmentPropertiesWithScope, + RoleDefinition, + RoleDefinitionCreateParameters, + RoleDefinitionProperties, + SASTokenParameter, + SelectiveKeyRestoreOperation, + SelectiveKeyRestoreOperationParameters, + Setting, + SettingsListResult, + UpdateSettingRequest, +) + +from ._enums import ( # type: ignore + DataAction, + OperationStatus, + RoleDefinitionType, + RoleScope, + RoleType, + SettingTypeEnum, +) +from ._patch import __all__ as _patch_all +from ._patch import * +from ._patch import patch_sdk as _patch_sdk + +__all__ = [ + "FullBackupOperation", + "FullBackupOperationError", + "KeyVaultError", + "Permission", + "PreBackupOperationParameters", + "PreRestoreOperationParameters", + "RestoreOperation", + "RestoreOperationParameters", + "RoleAssignment", + "RoleAssignmentCreateParameters", + "RoleAssignmentProperties", + "RoleAssignmentPropertiesWithScope", + "RoleDefinition", + "RoleDefinitionCreateParameters", + "RoleDefinitionProperties", + "SASTokenParameter", + "SelectiveKeyRestoreOperation", + "SelectiveKeyRestoreOperationParameters", + "Setting", + "SettingsListResult", + "UpdateSettingRequest", + "DataAction", + "OperationStatus", + "RoleDefinitionType", + "RoleScope", + "RoleType", + "SettingTypeEnum", +] +__all__.extend([p for p in _patch_all if p not in __all__]) # pyright: ignore +_patch_sdk() diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/models/_enums.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/models/_enums.py similarity index 91% rename from sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/models/_enums.py rename to sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/models/_enums.py index 5c976b985919..4bb8bdeff7b5 100644 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/models/_enums.py +++ b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/models/_enums.py @@ -2,7 +2,7 @@ # -------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for license information. -# Code generated by Microsoft (R) AutoRest Code Generator. +# Code generated by Microsoft (R) Python Code Generator. # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- @@ -83,10 +83,24 @@ class DataAction(str, Enum, metaclass=CaseInsensitiveEnumMeta): """Generate random numbers.""" +class OperationStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta): + """The status of a long-running operation.""" + + IN_PROGRESS = "InProgress" + """The operation is in progress.""" + SUCCEEDED = "Succeeded" + """The operation successfully completed.""" + CANCELED = "Canceled" + """The operation was canceled.""" + FAILED = "Failed" + """The operation failed.""" + + class RoleDefinitionType(str, Enum, metaclass=CaseInsensitiveEnumMeta): """The role definition type.""" MICROSOFT_AUTHORIZATION_ROLE_DEFINITIONS = "Microsoft.Authorization/roleDefinitions" + """Microsoft-defined role definitions.""" class RoleScope(str, Enum, metaclass=CaseInsensitiveEnumMeta): @@ -111,3 +125,4 @@ class SettingTypeEnum(str, Enum, metaclass=CaseInsensitiveEnumMeta): """The type specifier of the value.""" BOOLEAN = "boolean" + """A boolean setting value.""" diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/models/_models.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/models/_models.py new file mode 100644 index 000000000000..d2e7fb38977e --- /dev/null +++ b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/models/_models.py @@ -0,0 +1,833 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +# pylint: disable=useless-super-delegation + +import datetime +from typing import Any, List, Mapping, Optional, TYPE_CHECKING, Union, overload + +from .. import _model_base +from .._model_base import rest_field + +if TYPE_CHECKING: + from .. import models as _models + + +class FullBackupOperation(_model_base.Model): + """Full backup operation. + + :ivar status: Status of the backup operation. Known values are: "InProgress", "Succeeded", + "Canceled", and "Failed". + :vartype status: str or ~azure.keyvault.administration.models.OperationStatus + :ivar status_details: The status details of backup operation. + :vartype status_details: str + :ivar error: Error encountered, if any, during the full backup operation. + :vartype error: ~azure.keyvault.administration.models.FullBackupOperationError + :ivar start_time: The start time of the backup operation in UTC. + :vartype start_time: ~datetime.datetime + :ivar end_time: The end time of the backup operation in UTC. + :vartype end_time: ~datetime.datetime + :ivar job_id: Identifier for the full backup operation. + :vartype job_id: str + :ivar azure_storage_blob_container_uri: The Azure blob storage container Uri which contains the + full backup. + :vartype azure_storage_blob_container_uri: str + """ + + status: Optional[Union[str, "_models.OperationStatus"]] = rest_field() + """Status of the backup operation. Known values are: \"InProgress\", \"Succeeded\", \"Canceled\", + and \"Failed\".""" + status_details: Optional[str] = rest_field(name="statusDetails") + """The status details of backup operation.""" + error: Optional["_models.FullBackupOperationError"] = rest_field() + """Error encountered, if any, during the full backup operation.""" + start_time: Optional[datetime.datetime] = rest_field(name="startTime", format="unix-timestamp") + """The start time of the backup operation in UTC.""" + end_time: Optional[datetime.datetime] = rest_field(name="endTime", format="unix-timestamp") + """The end time of the backup operation in UTC.""" + job_id: Optional[str] = rest_field(name="jobId") + """Identifier for the full backup operation.""" + azure_storage_blob_container_uri: Optional[str] = rest_field(name="azureStorageBlobContainerUri") + """The Azure blob storage container Uri which contains the full backup.""" + + @overload + def __init__( + self, + *, + status: Optional[Union[str, "_models.OperationStatus"]] = None, + status_details: Optional[str] = None, + error: Optional["_models.FullBackupOperationError"] = None, + start_time: Optional[datetime.datetime] = None, + end_time: Optional[datetime.datetime] = None, + job_id: Optional[str] = None, + azure_storage_blob_container_uri: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class FullBackupOperationError(_model_base.Model): + """FullBackupOperationError. + + Readonly variables are only populated by the server, and will be ignored when sending a request. + + :ivar code: The error code. + :vartype code: str + :ivar message: The error message. + :vartype message: str + :ivar inner_error: The key vault server error. + :vartype inner_error: ~azure.keyvault.administration.models.FullBackupOperationError + """ + + code: Optional[str] = rest_field(visibility=["read"]) + """The error code.""" + message: Optional[str] = rest_field(visibility=["read"]) + """The error message.""" + inner_error: Optional["_models.FullBackupOperationError"] = rest_field(name="innererror", visibility=["read"]) + """The key vault server error.""" + + +class KeyVaultError(_model_base.Model): + """The key vault error exception. + + Readonly variables are only populated by the server, and will be ignored when sending a request. + + :ivar error: The key vault server error. + :vartype error: ~azure.keyvault.administration.models.FullBackupOperationError + """ + + error: Optional["_models.FullBackupOperationError"] = rest_field(visibility=["read"]) + """The key vault server error.""" + + +class Permission(_model_base.Model): + """Role definition permissions. + + :ivar actions: Action permissions that are granted. + :vartype actions: list[str] + :ivar not_actions: Action permissions that are excluded but not denied. They may be granted by + other role definitions assigned to a principal. + :vartype not_actions: list[str] + :ivar data_actions: Data action permissions that are granted. + :vartype data_actions: list[str or ~azure.keyvault.administration.models.DataAction] + :ivar not_data_actions: Data action permissions that are excluded but not denied. They may be + granted by other role definitions assigned to a principal. + :vartype not_data_actions: list[str or ~azure.keyvault.administration.models.DataAction] + """ + + actions: Optional[List[str]] = rest_field() + """Action permissions that are granted.""" + not_actions: Optional[List[str]] = rest_field(name="notActions") + """Action permissions that are excluded but not denied. They may be granted by other role + definitions assigned to a principal.""" + data_actions: Optional[List[Union[str, "_models.DataAction"]]] = rest_field(name="dataActions") + """Data action permissions that are granted.""" + not_data_actions: Optional[List[Union[str, "_models.DataAction"]]] = rest_field(name="notDataActions") + """Data action permissions that are excluded but not denied. They may be granted by other role + definitions assigned to a principal.""" + + @overload + def __init__( + self, + *, + actions: Optional[List[str]] = None, + not_actions: Optional[List[str]] = None, + data_actions: Optional[List[Union[str, "_models.DataAction"]]] = None, + not_data_actions: Optional[List[Union[str, "_models.DataAction"]]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class PreBackupOperationParameters(_model_base.Model): + """The authentication method and location for the backup operation. + + :ivar storage_resource_uri: Azure Blob storage container Uri. + :vartype storage_resource_uri: str + :ivar token: The SAS token pointing to an Azure Blob storage container. + :vartype token: str + :ivar use_managed_identity: Indicates which authentication method should be used. If set to + true, Managed HSM will use the configured user-assigned managed identity to authenticate with + Azure Storage. Otherwise, a SAS token has to be specified. + :vartype use_managed_identity: bool + """ + + storage_resource_uri: Optional[str] = rest_field(name="storageResourceUri") + """Azure Blob storage container Uri.""" + token: Optional[str] = rest_field() + """The SAS token pointing to an Azure Blob storage container.""" + use_managed_identity: Optional[bool] = rest_field(name="useManagedIdentity") + """Indicates which authentication method should be used. If set to true, Managed HSM will use the + configured user-assigned managed identity to authenticate with Azure Storage. Otherwise, a SAS + token has to be specified.""" + + @overload + def __init__( + self, + *, + storage_resource_uri: Optional[str] = None, + token: Optional[str] = None, + use_managed_identity: Optional[bool] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class PreRestoreOperationParameters(_model_base.Model): + """The authentication method and location for the restore operation. + + :ivar sas_token_parameters: A user-provided SAS token to an Azure blob storage container. + :vartype sas_token_parameters: ~azure.keyvault.administration.models.SASTokenParameter + :ivar folder_to_restore: The Folder name of the blob where the previous successful full backup + was stored. + :vartype folder_to_restore: str + """ + + sas_token_parameters: Optional["_models.SASTokenParameter"] = rest_field(name="sasTokenParameters") + """A user-provided SAS token to an Azure blob storage container.""" + folder_to_restore: Optional[str] = rest_field(name="folderToRestore") + """The Folder name of the blob where the previous successful full backup was stored.""" + + @overload + def __init__( + self, + *, + sas_token_parameters: Optional["_models.SASTokenParameter"] = None, + folder_to_restore: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RestoreOperation(_model_base.Model): + """Restore operation. + + :ivar status: Status of the restore operation. Known values are: "InProgress", "Succeeded", + "Canceled", and "Failed". + :vartype status: str or ~azure.keyvault.administration.models.OperationStatus + :ivar status_details: The status details of restore operation. + :vartype status_details: str + :ivar error: Error encountered, if any, during the restore operation. + :vartype error: ~azure.keyvault.administration.models.FullBackupOperationError + :ivar job_id: Identifier for the restore operation. + :vartype job_id: str + :ivar start_time: The start time of the restore operation. + :vartype start_time: ~datetime.datetime + :ivar end_time: The end time of the restore operation. + :vartype end_time: ~datetime.datetime + """ + + status: Optional[Union[str, "_models.OperationStatus"]] = rest_field() + """Status of the restore operation. Known values are: \"InProgress\", \"Succeeded\", \"Canceled\", + and \"Failed\".""" + status_details: Optional[str] = rest_field(name="statusDetails") + """The status details of restore operation.""" + error: Optional["_models.FullBackupOperationError"] = rest_field() + """Error encountered, if any, during the restore operation.""" + job_id: Optional[str] = rest_field(name="jobId") + """Identifier for the restore operation.""" + start_time: Optional[datetime.datetime] = rest_field(name="startTime", format="unix-timestamp") + """The start time of the restore operation.""" + end_time: Optional[datetime.datetime] = rest_field(name="endTime", format="unix-timestamp") + """The end time of the restore operation.""" + + @overload + def __init__( + self, + *, + status: Optional[Union[str, "_models.OperationStatus"]] = None, + status_details: Optional[str] = None, + error: Optional["_models.FullBackupOperationError"] = None, + job_id: Optional[str] = None, + start_time: Optional[datetime.datetime] = None, + end_time: Optional[datetime.datetime] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RestoreOperationParameters(_model_base.Model): + """The authentication method and location for the restore operation. + + All required parameters must be populated in order to send to server. + + :ivar sas_token_parameters: A user-provided SAS token to an Azure blob storage container. + Required. + :vartype sas_token_parameters: ~azure.keyvault.administration.models.SASTokenParameter + :ivar folder_to_restore: The Folder name of the blob where the previous successful full backup + was stored. Required. + :vartype folder_to_restore: str + """ + + sas_token_parameters: "_models.SASTokenParameter" = rest_field(name="sasTokenParameters") + """A user-provided SAS token to an Azure blob storage container. Required.""" + folder_to_restore: str = rest_field(name="folderToRestore") + """The Folder name of the blob where the previous successful full backup was stored. Required.""" + + @overload + def __init__( + self, + *, + sas_token_parameters: "_models.SASTokenParameter", + folder_to_restore: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RoleAssignment(_model_base.Model): + """Role Assignments. + + Readonly variables are only populated by the server, and will be ignored when sending a request. + + :ivar id: The role assignment ID. + :vartype id: str + :ivar name: The role assignment name. + :vartype name: str + :ivar type: The role assignment type. + :vartype type: str + :ivar properties: Role assignment properties. + :vartype properties: ~azure.keyvault.administration.models.RoleAssignmentPropertiesWithScope + """ + + id: Optional[str] = rest_field(visibility=["read"]) + """The role assignment ID.""" + name: Optional[str] = rest_field(visibility=["read"]) + """The role assignment name.""" + type: Optional[str] = rest_field(visibility=["read"]) + """The role assignment type.""" + properties: Optional["_models.RoleAssignmentPropertiesWithScope"] = rest_field() + """Role assignment properties.""" + + @overload + def __init__( + self, + *, + properties: Optional["_models.RoleAssignmentPropertiesWithScope"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RoleAssignmentCreateParameters(_model_base.Model): + """Role assignment create parameters. + + All required parameters must be populated in order to send to server. + + :ivar properties: Role assignment properties. Required. + :vartype properties: ~azure.keyvault.administration.models.RoleAssignmentProperties + """ + + properties: "_models.RoleAssignmentProperties" = rest_field() + """Role assignment properties. Required.""" + + @overload + def __init__( + self, + *, + properties: "_models.RoleAssignmentProperties", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RoleAssignmentProperties(_model_base.Model): + """Role assignment properties. + + All required parameters must be populated in order to send to server. + + :ivar role_definition_id: The role definition ID used in the role assignment. Required. + :vartype role_definition_id: str + :ivar principal_id: The principal ID assigned to the role. This maps to the ID inside the + Active Directory. It can point to a user, service principal, or security group. Required. + :vartype principal_id: str + """ + + role_definition_id: str = rest_field(name="roleDefinitionId") + """The role definition ID used in the role assignment. Required.""" + principal_id: str = rest_field(name="principalId") + """The principal ID assigned to the role. This maps to the ID inside the Active Directory. It can + point to a user, service principal, or security group. Required.""" + + @overload + def __init__( + self, + *, + role_definition_id: str, + principal_id: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RoleAssignmentPropertiesWithScope(_model_base.Model): + """Role assignment properties with scope. + + :ivar scope: The role scope. Known values are: "/" and "/keys". + :vartype scope: str or ~azure.keyvault.administration.models.RoleScope + :ivar role_definition_id: The role definition ID. + :vartype role_definition_id: str + :ivar principal_id: The principal ID. + :vartype principal_id: str + """ + + scope: Optional[Union[str, "_models.RoleScope"]] = rest_field() + """The role scope. Known values are: \"/\" and \"/keys\".""" + role_definition_id: Optional[str] = rest_field(name="roleDefinitionId") + """The role definition ID.""" + principal_id: Optional[str] = rest_field(name="principalId") + """The principal ID.""" + + @overload + def __init__( + self, + *, + scope: Optional[Union[str, "_models.RoleScope"]] = None, + role_definition_id: Optional[str] = None, + principal_id: Optional[str] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RoleDefinition(_model_base.Model): + """Role definition. + + Readonly variables are only populated by the server, and will be ignored when sending a request. + + :ivar id: The role definition ID. + :vartype id: str + :ivar name: The role definition name. + :vartype name: str + :ivar type: The role definition type. "Microsoft.Authorization/roleDefinitions" + :vartype type: str or ~azure.keyvault.administration.models.RoleDefinitionType + :ivar properties: Role definition properties. + :vartype properties: ~azure.keyvault.administration.models.RoleDefinitionProperties + """ + + id: Optional[str] = rest_field(visibility=["read"]) + """The role definition ID.""" + name: Optional[str] = rest_field(visibility=["read"]) + """The role definition name.""" + type: Optional[Union[str, "_models.RoleDefinitionType"]] = rest_field(visibility=["read"]) + """The role definition type. \"Microsoft.Authorization/roleDefinitions\"""" + properties: Optional["_models.RoleDefinitionProperties"] = rest_field() + """Role definition properties.""" + + __flattened_items = ["role_name", "description", "role_type", "permissions", "assignable_scopes"] + + @overload + def __init__( + self, + *, + properties: Optional["_models.RoleDefinitionProperties"] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + _flattened_input = {k: kwargs.pop(k) for k in kwargs.keys() & self.__flattened_items} + super().__init__(*args, **kwargs) + for k, v in _flattened_input.items(): + setattr(self, k, v) + + def __getattr__(self, name: str) -> Any: + if name in self.__flattened_items: + if self.properties is None: + return None + return getattr(self.properties, name) + raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'") + + def __setattr__(self, key: str, value: Any) -> None: + if key in self.__flattened_items: + if self.properties is None: + self.properties = self._attr_to_rest_field["properties"]._class_type() + setattr(self.properties, key, value) + else: + super().__setattr__(key, value) + + +class RoleDefinitionCreateParameters(_model_base.Model): + """Role definition create parameters. + + All required parameters must be populated in order to send to server. + + :ivar properties: Role definition properties. Required. + :vartype properties: ~azure.keyvault.administration.models.RoleDefinitionProperties + """ + + properties: "_models.RoleDefinitionProperties" = rest_field() + """Role definition properties. Required.""" + + @overload + def __init__( + self, + *, + properties: "_models.RoleDefinitionProperties", + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class RoleDefinitionProperties(_model_base.Model): + """Role definition properties. + + :ivar role_name: The role name. + :vartype role_name: str + :ivar description: The role definition description. + :vartype description: str + :ivar role_type: The role type. Known values are: "AKVBuiltInRole" and "CustomRole". + :vartype role_type: str or ~azure.keyvault.administration.models.RoleType + :ivar permissions: Role definition permissions. + :vartype permissions: list[~azure.keyvault.administration.models.Permission] + :ivar assignable_scopes: Role definition assignable scopes. + :vartype assignable_scopes: list[str or ~azure.keyvault.administration.models.RoleScope] + """ + + role_name: Optional[str] = rest_field(name="roleName") + """The role name.""" + description: Optional[str] = rest_field() + """The role definition description.""" + role_type: Optional[Union[str, "_models.RoleType"]] = rest_field(name="type") + """The role type. Known values are: \"AKVBuiltInRole\" and \"CustomRole\".""" + permissions: Optional[List["_models.Permission"]] = rest_field() + """Role definition permissions.""" + assignable_scopes: Optional[List[Union[str, "_models.RoleScope"]]] = rest_field(name="assignableScopes") + """Role definition assignable scopes.""" + + @overload + def __init__( + self, + *, + role_name: Optional[str] = None, + description: Optional[str] = None, + role_type: Optional[Union[str, "_models.RoleType"]] = None, + permissions: Optional[List["_models.Permission"]] = None, + assignable_scopes: Optional[List[Union[str, "_models.RoleScope"]]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class SASTokenParameter(_model_base.Model): + """An authentication method and location for the operation. + + All required parameters must be populated in order to send to server. + + :ivar storage_resource_uri: Azure Blob storage container Uri. Required. + :vartype storage_resource_uri: str + :ivar token: The SAS token pointing to an Azure Blob storage container. + :vartype token: str + :ivar use_managed_identity: Indicates which authentication method should be used. If set to + true, Managed HSM will use the configured user-assigned managed identity to authenticate with + Azure Storage. Otherwise, a SAS token has to be specified. + :vartype use_managed_identity: bool + """ + + storage_resource_uri: str = rest_field(name="storageResourceUri") + """Azure Blob storage container Uri. Required.""" + token: Optional[str] = rest_field() + """The SAS token pointing to an Azure Blob storage container.""" + use_managed_identity: Optional[bool] = rest_field(name="useManagedIdentity") + """Indicates which authentication method should be used. If set to true, Managed HSM will use the + configured user-assigned managed identity to authenticate with Azure Storage. Otherwise, a SAS + token has to be specified.""" + + @overload + def __init__( + self, + *, + storage_resource_uri: str, + token: Optional[str] = None, + use_managed_identity: Optional[bool] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class SelectiveKeyRestoreOperation(_model_base.Model): + """Selective Key Restore operation. + + :ivar status: Status of the restore operation. Known values are: "InProgress", "Succeeded", + "Canceled", and "Failed". + :vartype status: str or ~azure.keyvault.administration.models.OperationStatus + :ivar status_details: The status details of restore operation. + :vartype status_details: str + :ivar error: Error encountered, if any, during the selective key restore operation. + :vartype error: ~azure.keyvault.administration.models.FullBackupOperationError + :ivar job_id: Identifier for the selective key restore operation. + :vartype job_id: str + :ivar start_time: The start time of the restore operation. + :vartype start_time: ~datetime.datetime + :ivar end_time: The end time of the restore operation. + :vartype end_time: ~datetime.datetime + """ + + status: Optional[Union[str, "_models.OperationStatus"]] = rest_field() + """Status of the restore operation. Known values are: \"InProgress\", \"Succeeded\", \"Canceled\", + and \"Failed\".""" + status_details: Optional[str] = rest_field(name="statusDetails") + """The status details of restore operation.""" + error: Optional["_models.FullBackupOperationError"] = rest_field() + """Error encountered, if any, during the selective key restore operation.""" + job_id: Optional[str] = rest_field(name="jobId") + """Identifier for the selective key restore operation.""" + start_time: Optional[datetime.datetime] = rest_field(name="startTime", format="unix-timestamp") + """The start time of the restore operation.""" + end_time: Optional[datetime.datetime] = rest_field(name="endTime", format="unix-timestamp") + """The end time of the restore operation.""" + + @overload + def __init__( + self, + *, + status: Optional[Union[str, "_models.OperationStatus"]] = None, + status_details: Optional[str] = None, + error: Optional["_models.FullBackupOperationError"] = None, + job_id: Optional[str] = None, + start_time: Optional[datetime.datetime] = None, + end_time: Optional[datetime.datetime] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class SelectiveKeyRestoreOperationParameters(_model_base.Model): + """The authentication method and location for the selective key restore operation. + + All required parameters must be populated in order to send to server. + + :ivar sas_token_parameters: A user-provided SAS token to an Azure blob storage container. + Required. + :vartype sas_token_parameters: ~azure.keyvault.administration.models.SASTokenParameter + :ivar folder: The Folder name of the blob where the previous successful full backup was stored. + Required. + :vartype folder: str + """ + + sas_token_parameters: "_models.SASTokenParameter" = rest_field(name="sasTokenParameters") + """A user-provided SAS token to an Azure blob storage container. Required.""" + folder: str = rest_field() + """The Folder name of the blob where the previous successful full backup was stored. Required.""" + + @overload + def __init__( + self, + *, + sas_token_parameters: "_models.SASTokenParameter", + folder: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class Setting(_model_base.Model): + """A Key Vault account setting. + + + :ivar name: The account setting to be updated. Required. + :vartype name: str + :ivar value: The value of the pool setting. Required. + :vartype value: str + :ivar type: The type specifier of the value. "boolean" + :vartype type: str or ~azure.keyvault.administration.models.SettingTypeEnum + """ + + name: str = rest_field() + """The account setting to be updated. Required.""" + value: str = rest_field() + """The value of the pool setting. Required.""" + type: Optional[Union[str, "_models.SettingTypeEnum"]] = rest_field() + """The type specifier of the value. \"boolean\"""" + + @overload + def __init__( + self, + *, + name: str, + value: str, + type: Optional[Union[str, "_models.SettingTypeEnum"]] = None, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + +class SettingsListResult(_model_base.Model): + """The settings list result. + + Readonly variables are only populated by the server, and will be ignored when sending a request. + + :ivar settings: A response message containing a list of account settings with their associated + value. + :vartype settings: list[~azure.keyvault.administration.models.Setting] + """ + + settings: Optional[List["_models.Setting"]] = rest_field(visibility=["read"]) + """A response message containing a list of account settings with their associated value.""" + + +class UpdateSettingRequest(_model_base.Model): + """The update settings request object. + + All required parameters must be populated in order to send to server. + + :ivar value: The value of the pool setting. Required. + :vartype value: str + """ + + value: str = rest_field() + """The value of the pool setting. Required.""" + + @overload + def __init__( + self, + *, + value: str, + ) -> None: ... + + @overload + def __init__(self, mapping: Mapping[str, Any]) -> None: + """ + :param mapping: raw JSON to initialize the model. + :type mapping: Mapping[str, Any] + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/models/_patch.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/models/_patch.py similarity index 100% rename from sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/models/_patch.py rename to sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/models/_patch.py diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/operations/__init__.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/operations/__init__.py similarity index 54% rename from sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/operations/__init__.py rename to sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/operations/__init__.py index 523c12525d4f..2318933b2c83 100644 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/operations/__init__.py +++ b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/operations/__init__.py @@ -2,22 +2,28 @@ # -------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for license information. -# Code generated by Microsoft (R) AutoRest Code Generator. +# Code generated by Microsoft (R) Python Code Generator. # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- +# pylint: disable=wrong-import-position -from ._operations import KeyVaultClientOperationsMixin -from ._operations import RoleDefinitionsOperations -from ._operations import RoleAssignmentsOperations +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from ._patch import * # pylint: disable=unused-wildcard-import + +from ._operations import RoleDefinitionsOperations # type: ignore +from ._operations import RoleAssignmentsOperations # type: ignore +from ._operations import KeyVaultClientOperationsMixin # type: ignore from ._patch import __all__ as _patch_all -from ._patch import * # pylint: disable=unused-wildcard-import +from ._patch import * from ._patch import patch_sdk as _patch_sdk __all__ = [ - "KeyVaultClientOperationsMixin", "RoleDefinitionsOperations", "RoleAssignmentsOperations", + "KeyVaultClientOperationsMixin", ] -__all__.extend([p for p in _patch_all if p not in __all__]) +__all__.extend([p for p in _patch_all if p not in __all__]) # pyright: ignore _patch_sdk() diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/operations/_operations.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/operations/_operations.py similarity index 56% rename from sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/operations/_operations.py rename to sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/operations/_operations.py index 5c4f796a6015..a4044f74fb03 100644 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/operations/_operations.py +++ b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/operations/_operations.py @@ -1,21 +1,26 @@ -# pylint: disable=too-many-lines,too-many-statements +# pylint: disable=too-many-lines # coding=utf-8 # -------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for license information. -# Code generated by Microsoft (R) AutoRest Code Generator. +# Code generated by Microsoft (R) Python Code Generator. # Changes may cause incorrect behavior and will be lost if the code is regenerated. # -------------------------------------------------------------------------- from io import IOBase -from typing import Any, Callable, Dict, IO, Iterable, Optional, TypeVar, Union, cast, overload +import json +import sys +from typing import Any, Callable, Dict, IO, Iterable, Iterator, List, Optional, TypeVar, Union, cast, overload import urllib.parse +from azure.core import PipelineClient from azure.core.exceptions import ( ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, ResourceNotModifiedError, + StreamClosedError, + StreamConsumedError, map_error, ) from azure.core.paging import ItemPaged @@ -27,9 +32,17 @@ from azure.core.utils import case_insensitive_dict from .. import models as _models -from .._serialization import Serializer +from .._configuration import KeyVaultClientConfiguration +from .._model_base import SdkJSONEncoder, _deserialize, _failsafe_deserialize +from .._serialization import Deserializer, Serializer +from .._validation import api_version_validation from .._vendor import KeyVaultClientMixinABC +if sys.version_info >= (3, 9): + from collections.abc import MutableMapping +else: + from typing import MutableMapping # type: ignore +JSON = MutableMapping[str, Any] # pylint: disable=unsubscriptable-object T = TypeVar("T") ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] @@ -37,41 +50,46 @@ _SERIALIZER.client_side_validation = False -def build_key_vault_full_backup_request(**kwargs: Any) -> HttpRequest: +def build_role_definitions_delete_request(scope: str, role_definition_name: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.5")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.6-preview.2")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/backup" + _url = "/{scope}/providers/Microsoft.Authorization/roleDefinitions/{roleDefinitionName}" + path_format_arguments = { + "scope": _SERIALIZER.url("scope", scope, "str", skip_quote=True), + "roleDefinitionName": _SERIALIZER.url("role_definition_name", role_definition_name, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="DELETE", url=_url, params=_params, headers=_headers, **kwargs) -def build_key_vault_full_backup_status_request( # pylint: disable=name-too-long - job_id: str, **kwargs: Any +def build_role_definitions_create_or_update_request( # pylint: disable=name-too-long + scope: str, role_definition_name: str, **kwargs: Any ) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.5")) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.6-preview.2")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/backup/{jobId}/pending" + _url = "/{scope}/providers/Microsoft.Authorization/roleDefinitions/{roleDefinitionName}" path_format_arguments = { - "jobId": _SERIALIZER.url("job_id", job_id, "str"), + "scope": _SERIALIZER.url("scope", scope, "str", skip_quote=True), + "roleDefinitionName": _SERIALIZER.url("role_definition_name", role_definition_name, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -80,50 +98,57 @@ def build_key_vault_full_backup_status_request( # pylint: disable=name-too-long _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="PUT", url=_url, params=_params, headers=_headers, **kwargs) -def build_key_vault_full_restore_operation_request(**kwargs: Any) -> HttpRequest: # pylint: disable=name-too-long +def build_role_definitions_get_request(scope: str, role_definition_name: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.5")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.6-preview.2")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/restore" + _url = "/{scope}/providers/Microsoft.Authorization/roleDefinitions/{roleDefinitionName}" + path_format_arguments = { + "scope": _SERIALIZER.url("scope", scope, "str", skip_quote=True), + "roleDefinitionName": _SERIALIZER.url("role_definition_name", role_definition_name, "str"), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="PUT", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_key_vault_restore_status_request(job_id: str, **kwargs: Any) -> HttpRequest: +def build_role_definitions_list_request(scope: str, *, filter: Optional[str] = None, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.5")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.6-preview.2")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/restore/{jobId}/pending" + _url = "/{scope}/providers/Microsoft.Authorization/roleDefinitions" path_format_arguments = { - "jobId": _SERIALIZER.url("job_id", job_id, "str"), + "scope": _SERIALIZER.url("scope", scope, "str", skip_quote=True), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + if filter is not None: + _params["$filter"] = _SERIALIZER.query("filter", filter, "str") # Construct headers _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") @@ -131,20 +156,18 @@ def build_key_vault_restore_status_request(job_id: str, **kwargs: Any) -> HttpRe return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_key_vault_selective_key_restore_operation_request( # pylint: disable=name-too-long - key_name: str, **kwargs: Any -) -> HttpRequest: +def build_role_assignments_delete_request(scope: str, role_assignment_name: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.5")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.6-preview.2")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/keys/{keyName}/restore" + _url = "/{scope}/providers/Microsoft.Authorization/roleAssignments/{roleAssignmentName}" path_format_arguments = { - "keyName": _SERIALIZER.url("key_name", key_name, "str"), + "scope": _SERIALIZER.url("scope", scope, "str", skip_quote=True), + "roleAssignmentName": _SERIALIZER.url("role_assignment_name", role_assignment_name, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -153,25 +176,24 @@ def build_key_vault_selective_key_restore_operation_request( # pylint: disable= _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers - if content_type is not None: - _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="PUT", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="DELETE", url=_url, params=_params, headers=_headers, **kwargs) -def build_key_vault_update_setting_request(setting_name: str, **kwargs: Any) -> HttpRequest: +def build_role_assignments_create_request(scope: str, role_assignment_name: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.5")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.6-preview.2")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/settings/{setting-name}" + _url = "/{scope}/providers/Microsoft.Authorization/roleAssignments/{roleAssignmentName}" path_format_arguments = { - "setting-name": _SERIALIZER.url("setting_name", setting_name, "str"), + "scope": _SERIALIZER.url("scope", scope, "str", skip_quote=True), + "roleAssignmentName": _SERIALIZER.url("role_assignment_name", role_assignment_name, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -184,20 +206,21 @@ def build_key_vault_update_setting_request(setting_name: str, **kwargs: Any) -> _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="PATCH", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="PUT", url=_url, params=_params, headers=_headers, **kwargs) -def build_key_vault_get_setting_request(setting_name: str, **kwargs: Any) -> HttpRequest: +def build_role_assignments_get_request(scope: str, role_assignment_name: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.5")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.6-preview.2")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/settings/{setting-name}" + _url = "/{scope}/providers/Microsoft.Authorization/roleAssignments/{roleAssignmentName}" path_format_arguments = { - "setting-name": _SERIALIZER.url("setting_name", setting_name, "str"), + "scope": _SERIALIZER.url("scope", scope, "str", skip_quote=True), + "roleAssignmentName": _SERIALIZER.url("role_assignment_name", role_assignment_name, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -211,18 +234,27 @@ def build_key_vault_get_setting_request(setting_name: str, **kwargs: Any) -> Htt return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_key_vault_get_settings_request(**kwargs: Any) -> HttpRequest: +def build_role_assignments_list_for_scope_request( # pylint: disable=name-too-long + scope: str, *, filter: Optional[str] = None, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.5")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.6-preview.2")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/settings" + _url = "/{scope}/providers/Microsoft.Authorization/roleAssignments" + path_format_arguments = { + "scope": _SERIALIZER.url("scope", scope, "str", skip_quote=True), + } + + _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + if filter is not None: + _params["$filter"] = _SERIALIZER.query("filter", filter, "str") # Construct headers _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") @@ -230,18 +262,19 @@ def build_key_vault_get_settings_request(**kwargs: Any) -> HttpRequest: return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_role_definitions_delete_request(scope: str, role_definition_name: str, **kwargs: Any) -> HttpRequest: +def build_key_vault_full_backup_status_request( # pylint: disable=name-too-long + job_id: str, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.5")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.6-preview.2")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/{scope}/providers/Microsoft.Authorization/roleDefinitions/{roleDefinitionName}" + _url = "/backup/{jobId}/pending" path_format_arguments = { - "scope": _SERIALIZER.url("scope", scope, "str", skip_quote=True), - "roleDefinitionName": _SERIALIZER.url("role_definition_name", role_definition_name, "str"), + "jobId": _SERIALIZER.url("job_id", job_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -252,27 +285,41 @@ def build_role_definitions_delete_request(scope: str, role_definition_name: str, # Construct headers _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="DELETE", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_role_definitions_create_or_update_request( # pylint: disable=name-too-long - scope: str, role_definition_name: str, **kwargs: Any -) -> HttpRequest: +def build_key_vault_full_backup_request(**kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.5")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.6-preview.2")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/{scope}/providers/Microsoft.Authorization/roleDefinitions/{roleDefinitionName}" - path_format_arguments = { - "scope": _SERIALIZER.url("scope", scope, "str", skip_quote=True), - "roleDefinitionName": _SERIALIZER.url("role_definition_name", role_definition_name, "str"), - } + _url = "/backup" - _url: str = _url.format(**path_format_arguments) # type: ignore + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_key_vault_pre_full_backup_request(**kwargs: Any) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.6-preview.2")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/prebackup" # Construct parameters _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") @@ -282,21 +329,20 @@ def build_role_definitions_create_or_update_request( # pylint: disable=name-too _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="PUT", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="POST", url=_url, params=_params, headers=_headers, **kwargs) -def build_role_definitions_get_request(scope: str, role_definition_name: str, **kwargs: Any) -> HttpRequest: +def build_key_vault_restore_status_request(job_id: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.5")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.6-preview.2")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/{scope}/providers/Microsoft.Authorization/roleDefinitions/{roleDefinitionName}" + _url = "/restore/{jobId}/pending" path_format_arguments = { - "scope": _SERIALIZER.url("scope", scope, "str", skip_quote=True), - "roleDefinitionName": _SERIALIZER.url("role_definition_name", role_definition_name, "str"), + "jobId": _SERIALIZER.url("job_id", job_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -310,44 +356,63 @@ def build_role_definitions_get_request(scope: str, role_definition_name: str, ** return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_role_definitions_list_request(scope: str, *, filter: Optional[str] = None, **kwargs: Any) -> HttpRequest: +def build_key_vault_pre_full_restore_operation_request(**kwargs: Any) -> HttpRequest: # pylint: disable=name-too-long _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.5")) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.6-preview.2")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/{scope}/providers/Microsoft.Authorization/roleDefinitions" - path_format_arguments = { - "scope": _SERIALIZER.url("scope", scope, "str", skip_quote=True), - } + _url = "/prerestore" - _url: str = _url.format(**path_format_arguments) # type: ignore + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") + + # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="PUT", url=_url, params=_params, headers=_headers, **kwargs) + + +def build_key_vault_full_restore_operation_request(**kwargs: Any) -> HttpRequest: # pylint: disable=name-too-long + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.6-preview.2")) + accept = _headers.pop("Accept", "application/json") + + # Construct URL + _url = "/restore" # Construct parameters - if filter is not None: - _params["$filter"] = _SERIALIZER.query("filter", filter, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="PUT", url=_url, params=_params, headers=_headers, **kwargs) -def build_role_assignments_delete_request(scope: str, role_assignment_name: str, **kwargs: Any) -> HttpRequest: +def build_key_vault_selective_key_restore_status_request( # pylint: disable=name-too-long + job_id: str, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.5")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.6-preview.2")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/{scope}/providers/Microsoft.Authorization/roleAssignments/{roleAssignmentName}" + _url = "/restore/{jobId}/pending" path_format_arguments = { - "scope": _SERIALIZER.url("scope", scope, "str", skip_quote=True), - "roleAssignmentName": _SERIALIZER.url("role_assignment_name", role_assignment_name, "str"), + "jobId": _SERIALIZER.url("job_id", job_id, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -358,22 +423,23 @@ def build_role_assignments_delete_request(scope: str, role_assignment_name: str, # Construct headers _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="DELETE", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -def build_role_assignments_create_request(scope: str, role_assignment_name: str, **kwargs: Any) -> HttpRequest: +def build_key_vault_selective_key_restore_operation_request( # pylint: disable=name-too-long + key_name: str, **kwargs: Any +) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.5")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.6-preview.2")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/{scope}/providers/Microsoft.Authorization/roleAssignments/{roleAssignmentName}" + _url = "/keys/{keyName}/restore" path_format_arguments = { - "scope": _SERIALIZER.url("scope", scope, "str", skip_quote=True), - "roleAssignmentName": _SERIALIZER.url("role_assignment_name", role_assignment_name, "str"), + "keyName": _SERIALIZER.url("key_name", key_name, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -389,18 +455,18 @@ def build_role_assignments_create_request(scope: str, role_assignment_name: str, return HttpRequest(method="PUT", url=_url, params=_params, headers=_headers, **kwargs) -def build_role_assignments_get_request(scope: str, role_assignment_name: str, **kwargs: Any) -> HttpRequest: +def build_key_vault_update_setting_request(setting_name: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.5")) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.6-preview.2")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/{scope}/providers/Microsoft.Authorization/roleAssignments/{roleAssignmentName}" + _url = "/settings/{setting-name}" path_format_arguments = { - "scope": _SERIALIZER.url("scope", scope, "str", skip_quote=True), - "roleAssignmentName": _SERIALIZER.url("role_assignment_name", role_assignment_name, "str"), + "setting-name": _SERIALIZER.url("setting_name", setting_name, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore @@ -409,31 +475,29 @@ def build_role_assignments_get_request(scope: str, role_assignment_name: str, ** _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers + if content_type is not None: + _headers["Content-Type"] = _SERIALIZER.header("content_type", content_type, "str") _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") - return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + return HttpRequest(method="PATCH", url=_url, params=_params, headers=_headers, **kwargs) -def build_role_assignments_list_for_scope_request( # pylint: disable=name-too-long - scope: str, *, filter: Optional[str] = None, **kwargs: Any -) -> HttpRequest: +def build_key_vault_get_setting_request(setting_name: str, **kwargs: Any) -> HttpRequest: _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.5")) + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.6-preview.2")) accept = _headers.pop("Accept", "application/json") # Construct URL - _url = "/{scope}/providers/Microsoft.Authorization/roleAssignments" + _url = "/settings/{setting-name}" path_format_arguments = { - "scope": _SERIALIZER.url("scope", scope, "str", skip_quote=True), + "setting-name": _SERIALIZER.url("setting_name", setting_name, "str"), } _url: str = _url.format(**path_format_arguments) # type: ignore # Construct parameters - if filter is not None: - _params["$filter"] = _SERIALIZER.query("filter", filter, "str") _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") # Construct headers @@ -442,227 +506,218 @@ def build_role_assignments_list_for_scope_request( # pylint: disable=name-too-l return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) -class KeyVaultClientOperationsMixin(KeyVaultClientMixinABC): - def _full_backup_initial( - self, - vault_base_url: str, - azure_storage_blob_container_uri: Optional[Union[_models.SASTokenParameter, IO[bytes]]] = None, - **kwargs: Any - ) -> _models.FullBackupOperation: - error_map = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) +def build_key_vault_get_settings_request(**kwargs: Any) -> HttpRequest: + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = case_insensitive_dict(kwargs.pop("params", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} + api_version: str = kwargs.pop("api_version", _params.pop("api-version", "7.6-preview.2")) + accept = _headers.pop("Accept", "application/json") - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.FullBackupOperation] = kwargs.pop("cls", None) + # Construct URL + _url = "/settings" - content_type = content_type or "application/json" - _json = None - _content = None - if isinstance(azure_storage_blob_container_uri, (IOBase, bytes)): - _content = azure_storage_blob_container_uri - else: - if azure_storage_blob_container_uri is not None: - _json = self._serialize.body(azure_storage_blob_container_uri, "SASTokenParameter") - else: - _json = None + # Construct parameters + _params["api-version"] = _SERIALIZER.query("api_version", api_version, "str") - _request = build_key_vault_full_backup_request( - content_type=content_type, - api_version=self._config.api_version, - json=_json, - content=_content, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + # Construct headers + _headers["Accept"] = _SERIALIZER.header("accept", accept, "str") + + return HttpRequest(method="GET", url=_url, params=_params, headers=_headers, **kwargs) + + +class RoleDefinitionsOperations: + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.keyvault.administration.KeyVaultClient`'s + :attr:`role_definitions` attribute. + """ + + def __init__(self, *args, **kwargs): + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: KeyVaultClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace + def delete(self, scope: str, role_definition_name: str, **kwargs: Any) -> _models.RoleDefinition: + """Deletes a custom role definition. + + :param scope: The scope of the role definition to delete. Managed HSM only supports '/'. + Required. + :type scope: str + :param role_definition_name: The name (GUID) of the role definition to delete. Required. + :type role_definition_name: str + :return: RoleDefinition. The RoleDefinition is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RoleDefinition + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.RoleDefinition] = kwargs.pop("cls", None) + + _request = build_role_definitions_delete_request( + scope=scope, + role_definition_name=role_definition_name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [202]: + if response.status_code not in [200]: if _stream: - response.read() # Load the body in memory and close the socket + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) raise HttpResponseError(response=response, model=error) - response_headers = {} - response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) - response_headers["Azure-AsyncOperation"] = self._deserialize( - "str", response.headers.get("Azure-AsyncOperation") - ) - - deserialized = self._deserialize("FullBackupOperation", pipeline_response) + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize(_models.RoleDefinition, response.json()) if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore + return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore @overload - def begin_full_backup( + def create_or_update( self, - vault_base_url: str, - azure_storage_blob_container_uri: Optional[_models.SASTokenParameter] = None, + scope: str, + role_definition_name: str, + parameters: _models.RoleDefinitionCreateParameters, *, content_type: str = "application/json", **kwargs: Any - ) -> LROPoller[_models.FullBackupOperation]: - """Creates a full backup using a user-provided SAS token to an Azure blob storage container. + ) -> _models.RoleDefinition: + """Creates or updates a custom role definition. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param azure_storage_blob_container_uri: Azure blob shared access signature token pointing to a - valid Azure blob container where full backup needs to be stored. This token needs to be valid - for at least next 24 hours from the time of making this call. Default value is None. - :type azure_storage_blob_container_uri: ~azure.keyvault.v7_5.models.SASTokenParameter + :param scope: The scope of the role definition to create or update. Managed HSM only supports + '/'. Required. + :type scope: str + :param role_definition_name: The name of the role definition to create or update. It can be any + valid GUID. Required. + :type role_definition_name: str + :param parameters: Parameters for the role definition. Required. + :type parameters: ~azure.keyvault.administration.models.RoleDefinitionCreateParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: An instance of LROPoller that returns FullBackupOperation - :rtype: ~azure.core.polling.LROPoller[~azure.keyvault.v7_5.models.FullBackupOperation] + :return: RoleDefinition. The RoleDefinition is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RoleDefinition :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def begin_full_backup( + def create_or_update( self, - vault_base_url: str, - azure_storage_blob_container_uri: Optional[IO[bytes]] = None, + scope: str, + role_definition_name: str, + parameters: JSON, *, content_type: str = "application/json", **kwargs: Any - ) -> LROPoller[_models.FullBackupOperation]: - """Creates a full backup using a user-provided SAS token to an Azure blob storage container. + ) -> _models.RoleDefinition: + """Creates or updates a custom role definition. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param azure_storage_blob_container_uri: Azure blob shared access signature token pointing to a - valid Azure blob container where full backup needs to be stored. This token needs to be valid - for at least next 24 hours from the time of making this call. Default value is None. - :type azure_storage_blob_container_uri: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + :param scope: The scope of the role definition to create or update. Managed HSM only supports + '/'. Required. + :type scope: str + :param role_definition_name: The name of the role definition to create or update. It can be any + valid GUID. Required. + :type role_definition_name: str + :param parameters: Parameters for the role definition. Required. + :type parameters: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: An instance of LROPoller that returns FullBackupOperation - :rtype: ~azure.core.polling.LROPoller[~azure.keyvault.v7_5.models.FullBackupOperation] + :return: RoleDefinition. The RoleDefinition is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RoleDefinition :raises ~azure.core.exceptions.HttpResponseError: """ - @distributed_trace - def begin_full_backup( + @overload + def create_or_update( self, - vault_base_url: str, - azure_storage_blob_container_uri: Optional[Union[_models.SASTokenParameter, IO[bytes]]] = None, + scope: str, + role_definition_name: str, + parameters: IO[bytes], + *, + content_type: str = "application/json", **kwargs: Any - ) -> LROPoller[_models.FullBackupOperation]: - """Creates a full backup using a user-provided SAS token to an Azure blob storage container. + ) -> _models.RoleDefinition: + """Creates or updates a custom role definition. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param azure_storage_blob_container_uri: Azure blob shared access signature token pointing to a - valid Azure blob container where full backup needs to be stored. This token needs to be valid - for at least next 24 hours from the time of making this call. Is either a SASTokenParameter - type or a IO[bytes] type. Default value is None. - :type azure_storage_blob_container_uri: ~azure.keyvault.v7_5.models.SASTokenParameter or - IO[bytes] - :keyword content_type: Body Parameter content-type. Known values are: 'application/json'. - Default value is None. + :param scope: The scope of the role definition to create or update. Managed HSM only supports + '/'. Required. + :type scope: str + :param role_definition_name: The name of the role definition to create or update. It can be any + valid GUID. Required. + :type role_definition_name: str + :param parameters: Parameters for the role definition. Required. + :type parameters: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". :paramtype content_type: str - :return: An instance of LROPoller that returns FullBackupOperation - :rtype: ~azure.core.polling.LROPoller[~azure.keyvault.v7_5.models.FullBackupOperation] + :return: RoleDefinition. The RoleDefinition is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RoleDefinition :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} - - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.FullBackupOperation] = kwargs.pop("cls", None) - polling: Union[bool, PollingMethod] = kwargs.pop("polling", True) - lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) - cont_token: Optional[str] = kwargs.pop("continuation_token", None) - if cont_token is None: - raw_result = self._full_backup_initial( - vault_base_url=vault_base_url, - azure_storage_blob_container_uri=azure_storage_blob_container_uri, - content_type=content_type, - cls=lambda x, y, z: x, - headers=_headers, - params=_params, - **kwargs - ) - kwargs.pop("error_map", None) - - def get_long_running_output(pipeline_response): - response_headers = {} - response = pipeline_response.http_response - response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) - response_headers["Azure-AsyncOperation"] = self._deserialize( - "str", response.headers.get("Azure-AsyncOperation") - ) - - deserialized = self._deserialize("FullBackupOperation", pipeline_response) - if cls: - return cls(pipeline_response, deserialized, response_headers) # type: ignore - return deserialized - - path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), - } - - if polling is True: - polling_method: PollingMethod = cast( - PollingMethod, - LROBasePolling( - lro_delay, - lro_options={"final-state-via": "azure-async-operation"}, - path_format_arguments=path_format_arguments, - **kwargs - ), - ) - elif polling is False: - polling_method = cast(PollingMethod, NoPolling()) - else: - polling_method = polling - if cont_token: - return LROPoller[_models.FullBackupOperation].from_continuation_token( - polling_method=polling_method, - continuation_token=cont_token, - client=self._client, - deserialization_callback=get_long_running_output, - ) - return LROPoller[_models.FullBackupOperation]( - self._client, raw_result, get_long_running_output, polling_method # type: ignore - ) @distributed_trace - def full_backup_status(self, vault_base_url: str, job_id: str, **kwargs: Any) -> _models.FullBackupOperation: - """Returns the status of full backup operation. + def create_or_update( + self, + scope: str, + role_definition_name: str, + parameters: Union[_models.RoleDefinitionCreateParameters, JSON, IO[bytes]], + **kwargs: Any + ) -> _models.RoleDefinition: + """Creates or updates a custom role definition. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param job_id: The id returned as part of the backup request. Required. - :type job_id: str - :return: FullBackupOperation - :rtype: ~azure.keyvault.v7_5.models.FullBackupOperation + :param scope: The scope of the role definition to create or update. Managed HSM only supports + '/'. Required. + :type scope: str + :param role_definition_name: The name of the role definition to create or update. It can be any + valid GUID. Required. + :type role_definition_name: str + :param parameters: Parameters for the role definition. Is one of the following types: + RoleDefinitionCreateParameters, JSON, IO[bytes] Required. + :type parameters: ~azure.keyvault.administration.models.RoleDefinitionCreateParameters or JSON + or IO[bytes] + :return: RoleDefinition. The RoleDefinition is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RoleDefinition :raises ~azure.core.exceptions.HttpResponseError: """ - error_map = { + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, @@ -670,50 +725,75 @@ def full_backup_status(self, vault_base_url: str, job_id: str, **kwargs: Any) -> } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.FullBackupOperation] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.RoleDefinition] = kwargs.pop("cls", None) - _request = build_key_vault_full_backup_status_request( - job_id=job_id, + content_type = content_type or "application/json" + _content = None + if isinstance(parameters, (IOBase, bytes)): + _content = parameters + else: + _content = json.dumps(parameters, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_role_definitions_create_or_update_request( + scope=scope, + role_definition_name=role_definition_name, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: + if response.status_code not in [201]: if _stream: - response.read() # Load the body in memory and close the socket + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) raise HttpResponseError(response=response, model=error) - deserialized = self._deserialize("FullBackupOperation", pipeline_response) + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize(_models.RoleDefinition, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - def _full_restore_operation_initial( - self, - vault_base_url: str, - restore_blob_details: Optional[Union[_models.RestoreOperationParameters, IO[bytes]]] = None, - **kwargs: Any - ) -> _models.RestoreOperation: - error_map = { + @distributed_trace + def get(self, scope: str, role_definition_name: str, **kwargs: Any) -> _models.RoleDefinition: + """Get the specified role definition. + + :param scope: The scope of the role definition to get. Managed HSM only supports '/'. Required. + :type scope: str + :param role_definition_name: The name of the role definition to get. Required. + :type role_definition_name: str + :return: RoleDefinition. The RoleDefinition is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RoleDefinition + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, @@ -721,57 +801,680 @@ def _full_restore_operation_initial( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.RestoreOperation] = kwargs.pop("cls", None) - - content_type = content_type or "application/json" - _json = None - _content = None - if isinstance(restore_blob_details, (IOBase, bytes)): - _content = restore_blob_details - else: - if restore_blob_details is not None: - _json = self._serialize.body(restore_blob_details, "RestoreOperationParameters") - else: - _json = None + cls: ClsType[_models.RoleDefinition] = kwargs.pop("cls", None) - _request = build_key_vault_full_restore_operation_request( - content_type=content_type, + _request = build_role_definitions_get_request( + scope=scope, + role_definition_name=role_definition_name, api_version=self._config.api_version, - json=_json, - content=_content, headers=_headers, params=_params, ) path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [202]: + if response.status_code not in [200]: if _stream: - response.read() # Load the body in memory and close the socket + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) raise HttpResponseError(response=response, model=error) - response_headers = {} - response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) - response_headers["Azure-AsyncOperation"] = self._deserialize( - "str", response.headers.get("Azure-AsyncOperation") + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize(_models.RoleDefinition, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list(self, scope: str, *, filter: Optional[str] = None, **kwargs: Any) -> Iterable["_models.RoleDefinition"]: + """Get all role definitions that are applicable at scope and above. + + :param scope: The scope of the role definition. Required. + :type scope: str + :keyword filter: The filter to apply on the operation. Use atScopeAndBelow filter to search + below the given scope as well. Default value is None. + :paramtype filter: str + :return: An iterator like instance of RoleDefinition + :rtype: ~azure.core.paging.ItemPaged[~azure.keyvault.administration.models.RoleDefinition] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.RoleDefinition]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_role_definitions_list_request( + scope=scope, + filter=filter, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params + ) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize(List[_models.RoleDefinition], deserialized["value"]) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, iter(list_of_elem) + + def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + +class RoleAssignmentsOperations: + """ + .. warning:: + **DO NOT** instantiate this class directly. + + Instead, you should access the following operations through + :class:`~azure.keyvault.administration.KeyVaultClient`'s + :attr:`role_assignments` attribute. + """ + + def __init__(self, *args, **kwargs): + input_args = list(args) + self._client: PipelineClient = input_args.pop(0) if input_args else kwargs.pop("client") + self._config: KeyVaultClientConfiguration = input_args.pop(0) if input_args else kwargs.pop("config") + self._serialize: Serializer = input_args.pop(0) if input_args else kwargs.pop("serializer") + self._deserialize: Deserializer = input_args.pop(0) if input_args else kwargs.pop("deserializer") + + @distributed_trace + def delete(self, scope: str, role_assignment_name: str, **kwargs: Any) -> _models.RoleAssignment: + """Deletes a role assignment. + + :param scope: The scope of the role assignment to delete. Required. + :type scope: str + :param role_assignment_name: The name of the role assignment to delete. Required. + :type role_assignment_name: str + :return: RoleAssignment. The RoleAssignment is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RoleAssignment + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.RoleAssignment] = kwargs.pop("cls", None) + + _request = build_role_assignments_delete_request( + scope=scope, + role_assignment_name=role_assignment_name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize(_models.RoleAssignment, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @overload + def create( + self, + scope: str, + role_assignment_name: str, + parameters: _models.RoleAssignmentCreateParameters, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.RoleAssignment: + """Creates a role assignment. + + :param scope: The scope of the role assignment to create. Required. + :type scope: str + :param role_assignment_name: The name of the role assignment to create. It can be any valid + GUID. Required. + :type role_assignment_name: str + :param parameters: Parameters for the role assignment. Required. + :type parameters: ~azure.keyvault.administration.models.RoleAssignmentCreateParameters + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: RoleAssignment. The RoleAssignment is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RoleAssignment + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create( + self, + scope: str, + role_assignment_name: str, + parameters: JSON, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.RoleAssignment: + """Creates a role assignment. + + :param scope: The scope of the role assignment to create. Required. + :type scope: str + :param role_assignment_name: The name of the role assignment to create. It can be any valid + GUID. Required. + :type role_assignment_name: str + :param parameters: Parameters for the role assignment. Required. + :type parameters: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: RoleAssignment. The RoleAssignment is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RoleAssignment + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def create( + self, + scope: str, + role_assignment_name: str, + parameters: IO[bytes], + *, + content_type: str = "application/json", + **kwargs: Any + ) -> _models.RoleAssignment: + """Creates a role assignment. + + :param scope: The scope of the role assignment to create. Required. + :type scope: str + :param role_assignment_name: The name of the role assignment to create. It can be any valid + GUID. Required. + :type role_assignment_name: str + :param parameters: Parameters for the role assignment. Required. + :type parameters: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: RoleAssignment. The RoleAssignment is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RoleAssignment + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @distributed_trace + def create( + self, + scope: str, + role_assignment_name: str, + parameters: Union[_models.RoleAssignmentCreateParameters, JSON, IO[bytes]], + **kwargs: Any + ) -> _models.RoleAssignment: + """Creates a role assignment. + + :param scope: The scope of the role assignment to create. Required. + :type scope: str + :param role_assignment_name: The name of the role assignment to create. It can be any valid + GUID. Required. + :type role_assignment_name: str + :param parameters: Parameters for the role assignment. Is one of the following types: + RoleAssignmentCreateParameters, JSON, IO[bytes] Required. + :type parameters: ~azure.keyvault.administration.models.RoleAssignmentCreateParameters or JSON + or IO[bytes] + :return: RoleAssignment. The RoleAssignment is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RoleAssignment + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.RoleAssignment] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(parameters, (IOBase, bytes)): + _content = parameters + else: + _content = json.dumps(parameters, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_role_assignments_create_request( + scope=scope, + role_assignment_name=role_assignment_name, + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [201]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize(_models.RoleAssignment, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def get(self, scope: str, role_assignment_name: str, **kwargs: Any) -> _models.RoleAssignment: + """Get the specified role assignment. + + :param scope: The scope of the role assignment. Required. + :type scope: str + :param role_assignment_name: The name of the role assignment to get. Required. + :type role_assignment_name: str + :return: RoleAssignment. The RoleAssignment is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RoleAssignment + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.RoleAssignment] = kwargs.pop("cls", None) + + _request = build_role_assignments_get_request( + scope=scope, + role_assignment_name=role_assignment_name, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize(_models.RoleAssignment, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + @distributed_trace + def list_for_scope( + self, scope: str, *, filter: Optional[str] = None, **kwargs: Any + ) -> Iterable["_models.RoleAssignment"]: + """Gets role assignments for a scope. + + :param scope: The scope of the role assignments. Required. + :type scope: str + :keyword filter: The filter to apply on the operation. Use $filter=atScope() to return all role + assignments at or above the scope. Use $filter=principalId eq {id} to return all role + assignments at, above or below the scope for the specified principal. Default value is None. + :paramtype filter: str + :return: An iterator like instance of RoleAssignment + :rtype: ~azure.core.paging.ItemPaged[~azure.keyvault.administration.models.RoleAssignment] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[List[_models.RoleAssignment]] = kwargs.pop("cls", None) + + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + def prepare_request(next_link=None): + if not next_link: + + _request = build_role_assignments_list_for_scope_request( + scope=scope, + filter=filter, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + else: + # make call to next link with the client's api-version + _parsed_next_link = urllib.parse.urlparse(next_link) + _next_request_params = case_insensitive_dict( + { + key: [urllib.parse.quote(v) for v in value] + for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() + } + ) + _next_request_params["api-version"] = self._config.api_version + _request = HttpRequest( + "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params + ) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + return _request + + def extract_data(pipeline_response): + deserialized = pipeline_response.http_response.json() + list_of_elem = _deserialize(List[_models.RoleAssignment], deserialized["value"]) + if cls: + list_of_elem = cls(list_of_elem) # type: ignore + return deserialized.get("nextLink") or None, iter(list_of_elem) + + def get_next(next_link=None): + _request = prepare_request(next_link) + + _stream = False + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) + raise HttpResponseError(response=response, model=error) + + return pipeline_response + + return ItemPaged(get_next, extract_data) + + +class KeyVaultClientOperationsMixin(KeyVaultClientMixinABC): + + @distributed_trace + def full_backup_status(self, job_id: str, **kwargs: Any) -> _models.FullBackupOperation: + """Returns the status of full backup operation. + + :param job_id: The id returned as part of the backup request. Required. + :type job_id: str + :return: FullBackupOperation. The FullBackupOperation is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.FullBackupOperation + :raises ~azure.core.exceptions.HttpResponseError: + """ + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} + + cls: ClsType[_models.FullBackupOperation] = kwargs.pop("cls", None) + + _request = build_key_vault_full_backup_status_request( + job_id=job_id, + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [200]: + if _stream: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) + raise HttpResponseError(response=response, model=error) + + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize(_models.FullBackupOperation, response.json()) + + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore + + def _full_backup_initial( + self, azure_storage_blob_container_uri: Union[_models.SASTokenParameter, JSON, IO[bytes]], **kwargs: Any + ) -> Iterator[bytes]: + error_map: MutableMapping = { + 401: ClientAuthenticationError, + 404: ResourceNotFoundError, + 409: ResourceExistsError, + 304: ResourceNotModifiedError, + } + error_map.update(kwargs.pop("error_map", {}) or {}) + + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) + + content_type = content_type or "application/json" + _content = None + if isinstance(azure_storage_blob_container_uri, (IOBase, bytes)): + _content = azure_storage_blob_container_uri + else: + _content = json.dumps(azure_storage_blob_container_uri, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_key_vault_full_backup_request( + content_type=content_type, + api_version=self._config.api_version, + content=_content, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) + + _stream = True + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) + + response = pipeline_response.http_response + + if response.status_code not in [202]: + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) + raise HttpResponseError(response=response, model=error) + + response_headers = {} + response_headers["Azure-AsyncOperation"] = self._deserialize( + "str", response.headers.get("Azure-AsyncOperation") ) + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) - deserialized = self._deserialize("RestoreOperation", pipeline_response) + deserialized = response.iter_bytes() if cls: return cls(pipeline_response, deserialized, response_headers) # type: ignore @@ -779,205 +1482,155 @@ def _full_restore_operation_initial( return deserialized # type: ignore @overload - def begin_full_restore_operation( + def begin_full_backup( self, - vault_base_url: str, - restore_blob_details: Optional[_models.RestoreOperationParameters] = None, + azure_storage_blob_container_uri: _models.SASTokenParameter, *, content_type: str = "application/json", **kwargs: Any - ) -> LROPoller[_models.RestoreOperation]: - """Restores all key materials using the SAS token pointing to a previously stored Azure Blob - storage backup folder. + ) -> LROPoller[_models.FullBackupOperation]: + """Creates a full backup using a user-provided SAS token to an Azure blob storage container. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous - successful full backup was stored. Default value is None. - :type restore_blob_details: ~azure.keyvault.v7_5.models.RestoreOperationParameters + :param azure_storage_blob_container_uri: Azure blob shared access signature token pointing to a + valid Azure blob container where full backup needs to be stored. This token needs to be valid + for at least next 24 hours from the time of making this call. Required. + :type azure_storage_blob_container_uri: ~azure.keyvault.administration.models.SASTokenParameter :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: An instance of LROPoller that returns RestoreOperation - :rtype: ~azure.core.polling.LROPoller[~azure.keyvault.v7_5.models.RestoreOperation] + :return: An instance of LROPoller that returns FullBackupOperation. The FullBackupOperation is + compatible with MutableMapping + :rtype: + ~azure.core.polling.LROPoller[~azure.keyvault.administration.models.FullBackupOperation] :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def begin_full_restore_operation( - self, - vault_base_url: str, - restore_blob_details: Optional[IO[bytes]] = None, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> LROPoller[_models.RestoreOperation]: - """Restores all key materials using the SAS token pointing to a previously stored Azure Blob - storage backup folder. + def begin_full_backup( + self, azure_storage_blob_container_uri: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> LROPoller[_models.FullBackupOperation]: + """Creates a full backup using a user-provided SAS token to an Azure blob storage container. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous - successful full backup was stored. Default value is None. - :type restore_blob_details: IO[bytes] + :param azure_storage_blob_container_uri: Azure blob shared access signature token pointing to a + valid Azure blob container where full backup needs to be stored. This token needs to be valid + for at least next 24 hours from the time of making this call. Required. + :type azure_storage_blob_container_uri: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of LROPoller that returns FullBackupOperation. The FullBackupOperation is + compatible with MutableMapping + :rtype: + ~azure.core.polling.LROPoller[~azure.keyvault.administration.models.FullBackupOperation] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def begin_full_backup( + self, azure_storage_blob_container_uri: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> LROPoller[_models.FullBackupOperation]: + """Creates a full backup using a user-provided SAS token to an Azure blob storage container. + + :param azure_storage_blob_container_uri: Azure blob shared access signature token pointing to a + valid Azure blob container where full backup needs to be stored. This token needs to be valid + for at least next 24 hours from the time of making this call. Required. + :type azure_storage_blob_container_uri: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: An instance of LROPoller that returns RestoreOperation - :rtype: ~azure.core.polling.LROPoller[~azure.keyvault.v7_5.models.RestoreOperation] + :return: An instance of LROPoller that returns FullBackupOperation. The FullBackupOperation is + compatible with MutableMapping + :rtype: + ~azure.core.polling.LROPoller[~azure.keyvault.administration.models.FullBackupOperation] :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def begin_full_restore_operation( - self, - vault_base_url: str, - restore_blob_details: Optional[Union[_models.RestoreOperationParameters, IO[bytes]]] = None, - **kwargs: Any - ) -> LROPoller[_models.RestoreOperation]: - """Restores all key materials using the SAS token pointing to a previously stored Azure Blob - storage backup folder. + def begin_full_backup( + self, azure_storage_blob_container_uri: Union[_models.SASTokenParameter, JSON, IO[bytes]], **kwargs: Any + ) -> LROPoller[_models.FullBackupOperation]: + """Creates a full backup using a user-provided SAS token to an Azure blob storage container. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous - successful full backup was stored. Is either a RestoreOperationParameters type or a IO[bytes] - type. Default value is None. - :type restore_blob_details: ~azure.keyvault.v7_5.models.RestoreOperationParameters or IO[bytes] - :keyword content_type: Body Parameter content-type. Known values are: 'application/json'. - Default value is None. - :paramtype content_type: str - :return: An instance of LROPoller that returns RestoreOperation - :rtype: ~azure.core.polling.LROPoller[~azure.keyvault.v7_5.models.RestoreOperation] + :param azure_storage_blob_container_uri: Azure blob shared access signature token pointing to a + valid Azure blob container where full backup needs to be stored. This token needs to be valid + for at least next 24 hours from the time of making this call. Is one of the following types: + SASTokenParameter, JSON, IO[bytes] Required. + :type azure_storage_blob_container_uri: ~azure.keyvault.administration.models.SASTokenParameter + or JSON or IO[bytes] + :return: An instance of LROPoller that returns FullBackupOperation. The FullBackupOperation is + compatible with MutableMapping + :rtype: + ~azure.core.polling.LROPoller[~azure.keyvault.administration.models.FullBackupOperation] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.RestoreOperation] = kwargs.pop("cls", None) + cls: ClsType[_models.FullBackupOperation] = kwargs.pop("cls", None) polling: Union[bool, PollingMethod] = kwargs.pop("polling", True) lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) cont_token: Optional[str] = kwargs.pop("continuation_token", None) if cont_token is None: - raw_result = self._full_restore_operation_initial( - vault_base_url=vault_base_url, - restore_blob_details=restore_blob_details, + raw_result = self._full_backup_initial( + azure_storage_blob_container_uri=azure_storage_blob_container_uri, content_type=content_type, cls=lambda x, y, z: x, headers=_headers, params=_params, **kwargs ) + raw_result.http_response.read() # type: ignore kwargs.pop("error_map", None) def get_long_running_output(pipeline_response): response_headers = {} response = pipeline_response.http_response - response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) response_headers["Azure-AsyncOperation"] = self._deserialize( "str", response.headers.get("Azure-AsyncOperation") ) + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) - deserialized = self._deserialize("RestoreOperation", pipeline_response) + deserialized = _deserialize(_models.FullBackupOperation, response.json()) if cls: return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), - } - - if polling is True: - polling_method: PollingMethod = cast( - PollingMethod, - LROBasePolling( - lro_delay, - lro_options={"final-state-via": "azure-async-operation"}, - path_format_arguments=path_format_arguments, - **kwargs - ), - ) - elif polling is False: - polling_method = cast(PollingMethod, NoPolling()) - else: - polling_method = polling - if cont_token: - return LROPoller[_models.RestoreOperation].from_continuation_token( - polling_method=polling_method, - continuation_token=cont_token, - client=self._client, - deserialization_callback=get_long_running_output, - ) - return LROPoller[_models.RestoreOperation]( - self._client, raw_result, get_long_running_output, polling_method # type: ignore - ) - - @distributed_trace - def restore_status(self, vault_base_url: str, job_id: str, **kwargs: Any) -> _models.RestoreOperation: - """Returns the status of restore operation. - - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param job_id: The Job Id returned part of the restore operation. Required. - :type job_id: str - :return: RestoreOperation - :rtype: ~azure.keyvault.v7_5.models.RestoreOperation - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[_models.RestoreOperation] = kwargs.pop("cls", None) - - _request = build_key_vault_restore_status_request( - job_id=job_id, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs + if polling is True: + polling_method: PollingMethod = cast( + PollingMethod, LROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + ) + elif polling is False: + polling_method = cast(PollingMethod, NoPolling()) + else: + polling_method = polling + if cont_token: + return LROPoller[_models.FullBackupOperation].from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output, + ) + return LROPoller[_models.FullBackupOperation]( + self._client, raw_result, get_long_running_output, polling_method # type: ignore ) - response = pipeline_response.http_response - - if response.status_code not in [200]: - if _stream: - response.read() # Load the body in memory and close the socket - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) - raise HttpResponseError(response=response, model=error) - - deserialized = self._deserialize("RestoreOperation", pipeline_response) - - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore - - def _selective_key_restore_operation_initial( + @api_version_validation( + method_added_on="7.6-preview.2", + params_added_on={"7.6-preview.2": ["api_version", "content_type", "accept"]}, + ) + def _pre_full_backup_initial( self, - vault_base_url: str, - key_name: str, - restore_blob_details: Optional[Union[_models.SelectiveKeyRestoreOperationParameters, IO[bytes]]] = None, + pre_backup_operation_parameters: Union[_models.PreBackupOperationParameters, JSON, IO[bytes]], **kwargs: Any - ) -> _models.SelectiveKeyRestoreOperation: - error_map = { + ) -> Iterator[bytes]: + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, @@ -989,34 +1642,30 @@ def _selective_key_restore_operation_initial( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.SelectiveKeyRestoreOperation] = kwargs.pop("cls", None) + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) content_type = content_type or "application/json" - _json = None _content = None - if isinstance(restore_blob_details, (IOBase, bytes)): - _content = restore_blob_details + if isinstance(pre_backup_operation_parameters, (IOBase, bytes)): + _content = pre_backup_operation_parameters else: - if restore_blob_details is not None: - _json = self._serialize.body(restore_blob_details, "SelectiveKeyRestoreOperationParameters") - else: - _json = None + _content = json.dumps(pre_backup_operation_parameters, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_key_vault_selective_key_restore_operation_request( - key_name=key_name, + _request = build_key_vault_pre_full_backup_request( content_type=content_type, api_version=self._config.api_version, - json=_json, content=_content, headers=_headers, params=_params, ) path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _stream = True pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) @@ -1024,19 +1673,21 @@ def _selective_key_restore_operation_initial( response = pipeline_response.http_response if response.status_code not in [202]: - if _stream: + try: response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) raise HttpResponseError(response=response, model=error) response_headers = {} - response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) response_headers["Azure-AsyncOperation"] = self._deserialize( "str", response.headers.get("Azure-AsyncOperation") ) + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) - deserialized = self._deserialize("SelectiveKeyRestoreOperation", pipeline_response) + deserialized = response.iter_bytes() if cls: return cls(pipeline_response, deserialized, response_headers) # type: ignore @@ -1044,312 +1695,159 @@ def _selective_key_restore_operation_initial( return deserialized # type: ignore @overload - def begin_selective_key_restore_operation( + def begin_pre_full_backup( self, - vault_base_url: str, - key_name: str, - restore_blob_details: Optional[_models.SelectiveKeyRestoreOperationParameters] = None, + pre_backup_operation_parameters: _models.PreBackupOperationParameters, *, content_type: str = "application/json", **kwargs: Any - ) -> LROPoller[_models.SelectiveKeyRestoreOperation]: - """Restores all key versions of a given key using user supplied SAS token pointing to a previously - stored Azure Blob storage backup folder. + ) -> LROPoller[_models.FullBackupOperation]: + """Pre-backup operation for checking whether the customer can perform a full backup operation. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param key_name: The name of the key to be restored from the user supplied backup. Required. - :type key_name: str - :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous - successful full backup was stored. Default value is None. - :type restore_blob_details: ~azure.keyvault.v7_5.models.SelectiveKeyRestoreOperationParameters + :param pre_backup_operation_parameters: Optional parameters to validate prior to performing a + full backup operation. Required. + :type pre_backup_operation_parameters: + ~azure.keyvault.administration.models.PreBackupOperationParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: An instance of LROPoller that returns SelectiveKeyRestoreOperation - :rtype: ~azure.core.polling.LROPoller[~azure.keyvault.v7_5.models.SelectiveKeyRestoreOperation] + :return: An instance of LROPoller that returns FullBackupOperation. The FullBackupOperation is + compatible with MutableMapping + :rtype: + ~azure.core.polling.LROPoller[~azure.keyvault.administration.models.FullBackupOperation] :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def begin_selective_key_restore_operation( - self, - vault_base_url: str, - key_name: str, - restore_blob_details: Optional[IO[bytes]] = None, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> LROPoller[_models.SelectiveKeyRestoreOperation]: - """Restores all key versions of a given key using user supplied SAS token pointing to a previously - stored Azure Blob storage backup folder. + def begin_pre_full_backup( + self, pre_backup_operation_parameters: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> LROPoller[_models.FullBackupOperation]: + """Pre-backup operation for checking whether the customer can perform a full backup operation. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param key_name: The name of the key to be restored from the user supplied backup. Required. - :type key_name: str - :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous - successful full backup was stored. Default value is None. - :type restore_blob_details: IO[bytes] + :param pre_backup_operation_parameters: Optional parameters to validate prior to performing a + full backup operation. Required. + :type pre_backup_operation_parameters: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of LROPoller that returns FullBackupOperation. The FullBackupOperation is + compatible with MutableMapping + :rtype: + ~azure.core.polling.LROPoller[~azure.keyvault.administration.models.FullBackupOperation] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def begin_pre_full_backup( + self, pre_backup_operation_parameters: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> LROPoller[_models.FullBackupOperation]: + """Pre-backup operation for checking whether the customer can perform a full backup operation. + + :param pre_backup_operation_parameters: Optional parameters to validate prior to performing a + full backup operation. Required. + :type pre_backup_operation_parameters: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: An instance of LROPoller that returns SelectiveKeyRestoreOperation - :rtype: ~azure.core.polling.LROPoller[~azure.keyvault.v7_5.models.SelectiveKeyRestoreOperation] + :return: An instance of LROPoller that returns FullBackupOperation. The FullBackupOperation is + compatible with MutableMapping + :rtype: + ~azure.core.polling.LROPoller[~azure.keyvault.administration.models.FullBackupOperation] :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def begin_selective_key_restore_operation( + @api_version_validation( + method_added_on="7.6-preview.2", + params_added_on={"7.6-preview.2": ["api_version", "content_type", "accept"]}, + ) + def begin_pre_full_backup( self, - vault_base_url: str, - key_name: str, - restore_blob_details: Optional[Union[_models.SelectiveKeyRestoreOperationParameters, IO[bytes]]] = None, + pre_backup_operation_parameters: Union[_models.PreBackupOperationParameters, JSON, IO[bytes]], **kwargs: Any - ) -> LROPoller[_models.SelectiveKeyRestoreOperation]: - """Restores all key versions of a given key using user supplied SAS token pointing to a previously - stored Azure Blob storage backup folder. - - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param key_name: The name of the key to be restored from the user supplied backup. Required. - :type key_name: str - :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous - successful full backup was stored. Is either a SelectiveKeyRestoreOperationParameters type or a - IO[bytes] type. Default value is None. - :type restore_blob_details: ~azure.keyvault.v7_5.models.SelectiveKeyRestoreOperationParameters - or IO[bytes] - :keyword content_type: Body Parameter content-type. Known values are: 'application/json'. - Default value is None. - :paramtype content_type: str - :return: An instance of LROPoller that returns SelectiveKeyRestoreOperation - :rtype: ~azure.core.polling.LROPoller[~azure.keyvault.v7_5.models.SelectiveKeyRestoreOperation] + ) -> LROPoller[_models.FullBackupOperation]: + """Pre-backup operation for checking whether the customer can perform a full backup operation. + + :param pre_backup_operation_parameters: Optional parameters to validate prior to performing a + full backup operation. Is one of the following types: PreBackupOperationParameters, JSON, + IO[bytes] Required. + :type pre_backup_operation_parameters: + ~azure.keyvault.administration.models.PreBackupOperationParameters or JSON or IO[bytes] + :return: An instance of LROPoller that returns FullBackupOperation. The FullBackupOperation is + compatible with MutableMapping + :rtype: + ~azure.core.polling.LROPoller[~azure.keyvault.administration.models.FullBackupOperation] :raises ~azure.core.exceptions.HttpResponseError: """ _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.SelectiveKeyRestoreOperation] = kwargs.pop("cls", None) + cls: ClsType[_models.FullBackupOperation] = kwargs.pop("cls", None) polling: Union[bool, PollingMethod] = kwargs.pop("polling", True) lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) cont_token: Optional[str] = kwargs.pop("continuation_token", None) if cont_token is None: - raw_result = self._selective_key_restore_operation_initial( - vault_base_url=vault_base_url, - key_name=key_name, - restore_blob_details=restore_blob_details, + raw_result = self._pre_full_backup_initial( + pre_backup_operation_parameters=pre_backup_operation_parameters, content_type=content_type, cls=lambda x, y, z: x, headers=_headers, params=_params, **kwargs ) + raw_result.http_response.read() # type: ignore kwargs.pop("error_map", None) def get_long_running_output(pipeline_response): response_headers = {} response = pipeline_response.http_response - response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) response_headers["Azure-AsyncOperation"] = self._deserialize( "str", response.headers.get("Azure-AsyncOperation") ) + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) - deserialized = self._deserialize("SelectiveKeyRestoreOperation", pipeline_response) + deserialized = _deserialize(_models.FullBackupOperation, response.json()) if cls: return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } if polling is True: polling_method: PollingMethod = cast( - PollingMethod, - LROBasePolling( - lro_delay, - lro_options={"final-state-via": "azure-async-operation"}, - path_format_arguments=path_format_arguments, - **kwargs - ), + PollingMethod, LROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) ) elif polling is False: polling_method = cast(PollingMethod, NoPolling()) else: polling_method = polling if cont_token: - return LROPoller[_models.SelectiveKeyRestoreOperation].from_continuation_token( + return LROPoller[_models.FullBackupOperation].from_continuation_token( polling_method=polling_method, continuation_token=cont_token, client=self._client, deserialization_callback=get_long_running_output, ) - return LROPoller[_models.SelectiveKeyRestoreOperation]( + return LROPoller[_models.FullBackupOperation]( self._client, raw_result, get_long_running_output, polling_method # type: ignore ) - @overload - def update_setting( - self, - vault_base_url: str, - setting_name: str, - parameters: _models.UpdateSettingRequest, - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.Setting: - """Updates key vault account setting, stores it, then returns the setting name and value to the - client. - - Description of the pool setting to be updated. - - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param setting_name: The name of the account setting. Must be a valid settings option. - Required. - :type setting_name: str - :param parameters: The parameters to update an account setting. Required. - :type parameters: ~azure.keyvault.v7_5.models.UpdateSettingRequest - :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. - Default value is "application/json". - :paramtype content_type: str - :return: Setting - :rtype: ~azure.keyvault.v7_5.models.Setting - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @overload - def update_setting( - self, - vault_base_url: str, - setting_name: str, - parameters: IO[bytes], - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.Setting: - """Updates key vault account setting, stores it, then returns the setting name and value to the - client. - - Description of the pool setting to be updated. - - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param setting_name: The name of the account setting. Must be a valid settings option. - Required. - :type setting_name: str - :param parameters: The parameters to update an account setting. Required. - :type parameters: IO[bytes] - :keyword content_type: Body Parameter content-type. Content type parameter for binary body. - Default value is "application/json". - :paramtype content_type: str - :return: Setting - :rtype: ~azure.keyvault.v7_5.models.Setting - :raises ~azure.core.exceptions.HttpResponseError: - """ - - @distributed_trace - def update_setting( - self, - vault_base_url: str, - setting_name: str, - parameters: Union[_models.UpdateSettingRequest, IO[bytes]], - **kwargs: Any - ) -> _models.Setting: - """Updates key vault account setting, stores it, then returns the setting name and value to the - client. - - Description of the pool setting to be updated. - - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param setting_name: The name of the account setting. Must be a valid settings option. - Required. - :type setting_name: str - :param parameters: The parameters to update an account setting. Is either a - UpdateSettingRequest type or a IO[bytes] type. Required. - :type parameters: ~azure.keyvault.v7_5.models.UpdateSettingRequest or IO[bytes] - :keyword content_type: Body Parameter content-type. Known values are: 'application/json'. - Default value is None. - :paramtype content_type: str - :return: Setting - :rtype: ~azure.keyvault.v7_5.models.Setting - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) - _params = kwargs.pop("params", {}) or {} - - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.Setting] = kwargs.pop("cls", None) - - content_type = content_type or "application/json" - _json = None - _content = None - if isinstance(parameters, (IOBase, bytes)): - _content = parameters - else: - _json = self._serialize.body(parameters, "UpdateSettingRequest") - - _request = build_key_vault_update_setting_request( - setting_name=setting_name, - content_type=content_type, - api_version=self._config.api_version, - json=_json, - content=_content, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - - response = pipeline_response.http_response - - if response.status_code not in [200]: - if _stream: - response.read() # Load the body in memory and close the socket - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) - raise HttpResponseError(response=response, model=error) - - deserialized = self._deserialize("Setting", pipeline_response) - - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore - @distributed_trace - def get_setting(self, vault_base_url: str, setting_name: str, **kwargs: Any) -> _models.Setting: - """Get specified account setting object. - - Retrieves the setting object of a specified setting name. + def restore_status(self, job_id: str, **kwargs: Any) -> _models.RestoreOperation: + """Returns the status of restore operation. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param setting_name: The name of the account setting. Must be a valid settings option. - Required. - :type setting_name: str - :return: Setting - :rtype: ~azure.keyvault.v7_5.models.Setting + :param job_id: The Job Id returned part of the restore operation. Required. + :type job_id: str + :return: RestoreOperation. The RestoreOperation is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.RestoreOperation :raises ~azure.core.exceptions.HttpResponseError: """ - error_map = { + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, @@ -1360,20 +1858,22 @@ def get_setting(self, vault_base_url: str, setting_name: str, **kwargs: Any) -> _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.Setting] = kwargs.pop("cls", None) + cls: ClsType[_models.RestoreOperation] = kwargs.pop("cls", None) - _request = build_key_vault_get_setting_request( - setting_name=setting_name, + _request = build_key_vault_restore_status_request( + job_id=job_id, api_version=self._config.api_version, headers=_headers, params=_params, ) path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) @@ -1382,31 +1882,34 @@ def get_setting(self, vault_base_url: str, setting_name: str, **kwargs: Any) -> if response.status_code not in [200]: if _stream: - response.read() # Load the body in memory and close the socket + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) raise HttpResponseError(response=response, model=error) - deserialized = self._deserialize("Setting", pipeline_response) + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize(_models.RestoreOperation, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @distributed_trace - def get_settings(self, vault_base_url: str, **kwargs: Any) -> _models.SettingsListResult: - """List account settings. - - Retrieves a list of all the available account settings that can be configured. - - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :return: SettingsListResult - :rtype: ~azure.keyvault.v7_5.models.SettingsListResult - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map = { + @api_version_validation( + method_added_on="7.6-preview.2", + params_added_on={"7.6-preview.2": ["api_version", "content_type", "accept"]}, + ) + def _pre_full_restore_operation_initial( + self, + pre_restore_operation_parameters: Union[_models.PreRestoreOperationParameters, JSON, IO[bytes]], + **kwargs: Any + ) -> Iterator[bytes]: + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, @@ -1414,80 +1917,205 @@ def get_settings(self, vault_base_url: str, **kwargs: Any) -> _models.SettingsLi } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.SettingsListResult] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - _request = build_key_vault_get_settings_request( + content_type = content_type or "application/json" + _content = None + if isinstance(pre_restore_operation_parameters, (IOBase, bytes)): + _content = pre_restore_operation_parameters + else: + _content = json.dumps(pre_restore_operation_parameters, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_key_vault_pre_full_restore_operation_request( + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _stream = True pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: + if response.status_code not in [202]: + try: response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) raise HttpResponseError(response=response, model=error) - deserialized = self._deserialize("SettingsListResult", pipeline_response) + response_headers = {} + response_headers["Azure-AsyncOperation"] = self._deserialize( + "str", response.headers.get("Azure-AsyncOperation") + ) + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) + + deserialized = response.iter_bytes() if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore + @overload + def begin_pre_full_restore_operation( + self, + pre_restore_operation_parameters: _models.PreRestoreOperationParameters, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> LROPoller[_models.RestoreOperation]: + """Pre-restore operation for checking whether the customer can perform a full restore operation. -class RoleDefinitionsOperations: - """ - .. warning:: - **DO NOT** instantiate this class directly. + :param pre_restore_operation_parameters: Optional pre restore parameters to validate prior to + performing a full restore operation. Required. + :type pre_restore_operation_parameters: + ~azure.keyvault.administration.models.PreRestoreOperationParameters + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of LROPoller that returns RestoreOperation. The RestoreOperation is + compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.keyvault.administration.models.RestoreOperation] + :raises ~azure.core.exceptions.HttpResponseError: + """ - Instead, you should access the following operations through - :class:`~azure.keyvault.v7_5.KeyVaultClient`'s - :attr:`role_definitions` attribute. - """ + @overload + def begin_pre_full_restore_operation( + self, pre_restore_operation_parameters: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> LROPoller[_models.RestoreOperation]: + """Pre-restore operation for checking whether the customer can perform a full restore operation. - models = _models + :param pre_restore_operation_parameters: Optional pre restore parameters to validate prior to + performing a full restore operation. Required. + :type pre_restore_operation_parameters: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of LROPoller that returns RestoreOperation. The RestoreOperation is + compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.keyvault.administration.models.RestoreOperation] + :raises ~azure.core.exceptions.HttpResponseError: + """ - def __init__(self, *args, **kwargs): - input_args = list(args) - self._client = input_args.pop(0) if input_args else kwargs.pop("client") - self._config = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize = input_args.pop(0) if input_args else kwargs.pop("deserializer") + @overload + def begin_pre_full_restore_operation( + self, pre_restore_operation_parameters: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> LROPoller[_models.RestoreOperation]: + """Pre-restore operation for checking whether the customer can perform a full restore operation. - @distributed_trace - def delete( - self, vault_base_url: str, scope: str, role_definition_name: str, **kwargs: Any - ) -> _models.RoleDefinition: - """Deletes a custom role definition. + :param pre_restore_operation_parameters: Optional pre restore parameters to validate prior to + performing a full restore operation. Required. + :type pre_restore_operation_parameters: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of LROPoller that returns RestoreOperation. The RestoreOperation is + compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.keyvault.administration.models.RestoreOperation] + :raises ~azure.core.exceptions.HttpResponseError: + """ - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param scope: The scope of the role definition to delete. Managed HSM only supports '/'. - Required. - :type scope: str - :param role_definition_name: The name (GUID) of the role definition to delete. Required. - :type role_definition_name: str - :return: RoleDefinition - :rtype: ~azure.keyvault.v7_5.models.RoleDefinition + @distributed_trace + @api_version_validation( + method_added_on="7.6-preview.2", + params_added_on={"7.6-preview.2": ["api_version", "content_type", "accept"]}, + ) + def begin_pre_full_restore_operation( + self, + pre_restore_operation_parameters: Union[_models.PreRestoreOperationParameters, JSON, IO[bytes]], + **kwargs: Any + ) -> LROPoller[_models.RestoreOperation]: + """Pre-restore operation for checking whether the customer can perform a full restore operation. + + :param pre_restore_operation_parameters: Optional pre restore parameters to validate prior to + performing a full restore operation. Is one of the following types: + PreRestoreOperationParameters, JSON, IO[bytes] Required. + :type pre_restore_operation_parameters: + ~azure.keyvault.administration.models.PreRestoreOperationParameters or JSON or IO[bytes] + :return: An instance of LROPoller that returns RestoreOperation. The RestoreOperation is + compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.keyvault.administration.models.RestoreOperation] :raises ~azure.core.exceptions.HttpResponseError: """ - error_map = { + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.RestoreOperation] = kwargs.pop("cls", None) + polling: Union[bool, PollingMethod] = kwargs.pop("polling", True) + lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) + cont_token: Optional[str] = kwargs.pop("continuation_token", None) + if cont_token is None: + raw_result = self._pre_full_restore_operation_initial( + pre_restore_operation_parameters=pre_restore_operation_parameters, + content_type=content_type, + cls=lambda x, y, z: x, + headers=_headers, + params=_params, + **kwargs + ) + raw_result.http_response.read() # type: ignore + kwargs.pop("error_map", None) + + def get_long_running_output(pipeline_response): + response_headers = {} + response = pipeline_response.http_response + response_headers["Azure-AsyncOperation"] = self._deserialize( + "str", response.headers.get("Azure-AsyncOperation") + ) + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) + + deserialized = _deserialize(_models.RestoreOperation, response.json()) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + return deserialized + + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + + if polling is True: + polling_method: PollingMethod = cast( + PollingMethod, LROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + ) + elif polling is False: + polling_method = cast(PollingMethod, NoPolling()) + else: + polling_method = polling + if cont_token: + return LROPoller[_models.RestoreOperation].from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output, + ) + return LROPoller[_models.RestoreOperation]( + self._client, raw_result, get_long_running_output, polling_method # type: ignore + ) + + def _full_restore_operation_initial( + self, restore_blob_details: Union[_models.RestoreOperationParameters, JSON, IO[bytes]], **kwargs: Any + ) -> Iterator[bytes]: + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, @@ -1495,136 +2123,210 @@ def delete( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.RoleDefinition] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - _request = build_role_definitions_delete_request( - scope=scope, - role_definition_name=role_definition_name, + content_type = content_type or "application/json" + _content = None + if isinstance(restore_blob_details, (IOBase, bytes)): + _content = restore_blob_details + else: + _content = json.dumps(restore_blob_details, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_key_vault_full_restore_operation_request( + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _stream = True pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: + if response.status_code not in [202]: + try: response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) raise HttpResponseError(response=response, model=error) - deserialized = self._deserialize("RoleDefinition", pipeline_response) + response_headers = {} + response_headers["Azure-AsyncOperation"] = self._deserialize( + "str", response.headers.get("Azure-AsyncOperation") + ) + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) + + deserialized = response.iter_bytes() if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore @overload - def create_or_update( + def begin_full_restore_operation( self, - vault_base_url: str, - scope: str, - role_definition_name: str, - parameters: _models.RoleDefinitionCreateParameters, + restore_blob_details: _models.RestoreOperationParameters, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.RoleDefinition: - """Creates or updates a custom role definition. + ) -> LROPoller[_models.RestoreOperation]: + """Restores all key materials using the SAS token pointing to a previously stored Azure Blob + storage backup folder. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param scope: The scope of the role definition to create or update. Managed HSM only supports - '/'. Required. - :type scope: str - :param role_definition_name: The name of the role definition to create or update. It can be any - valid GUID. Required. - :type role_definition_name: str - :param parameters: Parameters for the role definition. Required. - :type parameters: ~azure.keyvault.v7_5.models.RoleDefinitionCreateParameters + :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous + successful full backup was stored. Required. + :type restore_blob_details: ~azure.keyvault.administration.models.RestoreOperationParameters :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: RoleDefinition - :rtype: ~azure.keyvault.v7_5.models.RoleDefinition + :return: An instance of LROPoller that returns RestoreOperation. The RestoreOperation is + compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.keyvault.administration.models.RestoreOperation] :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def create_or_update( - self, - vault_base_url: str, - scope: str, - role_definition_name: str, - parameters: IO[bytes], - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.RoleDefinition: - """Creates or updates a custom role definition. + def begin_full_restore_operation( + self, restore_blob_details: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> LROPoller[_models.RestoreOperation]: + """Restores all key materials using the SAS token pointing to a previously stored Azure Blob + storage backup folder. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param scope: The scope of the role definition to create or update. Managed HSM only supports - '/'. Required. - :type scope: str - :param role_definition_name: The name of the role definition to create or update. It can be any - valid GUID. Required. - :type role_definition_name: str - :param parameters: Parameters for the role definition. Required. - :type parameters: IO[bytes] + :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous + successful full backup was stored. Required. + :type restore_blob_details: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of LROPoller that returns RestoreOperation. The RestoreOperation is + compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.keyvault.administration.models.RestoreOperation] + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def begin_full_restore_operation( + self, restore_blob_details: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> LROPoller[_models.RestoreOperation]: + """Restores all key materials using the SAS token pointing to a previously stored Azure Blob + storage backup folder. + + :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous + successful full backup was stored. Required. + :type restore_blob_details: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: RoleDefinition - :rtype: ~azure.keyvault.v7_5.models.RoleDefinition + :return: An instance of LROPoller that returns RestoreOperation. The RestoreOperation is + compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.keyvault.administration.models.RestoreOperation] :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def create_or_update( - self, - vault_base_url: str, - scope: str, - role_definition_name: str, - parameters: Union[_models.RoleDefinitionCreateParameters, IO[bytes]], - **kwargs: Any - ) -> _models.RoleDefinition: - """Creates or updates a custom role definition. + def begin_full_restore_operation( + self, restore_blob_details: Union[_models.RestoreOperationParameters, JSON, IO[bytes]], **kwargs: Any + ) -> LROPoller[_models.RestoreOperation]: + """Restores all key materials using the SAS token pointing to a previously stored Azure Blob + storage backup folder. + + :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous + successful full backup was stored. Is one of the following types: RestoreOperationParameters, + JSON, IO[bytes] Required. + :type restore_blob_details: ~azure.keyvault.administration.models.RestoreOperationParameters or + JSON or IO[bytes] + :return: An instance of LROPoller that returns RestoreOperation. The RestoreOperation is + compatible with MutableMapping + :rtype: ~azure.core.polling.LROPoller[~azure.keyvault.administration.models.RestoreOperation] + :raises ~azure.core.exceptions.HttpResponseError: + """ + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _params = kwargs.pop("params", {}) or {} + + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.RestoreOperation] = kwargs.pop("cls", None) + polling: Union[bool, PollingMethod] = kwargs.pop("polling", True) + lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) + cont_token: Optional[str] = kwargs.pop("continuation_token", None) + if cont_token is None: + raw_result = self._full_restore_operation_initial( + restore_blob_details=restore_blob_details, + content_type=content_type, + cls=lambda x, y, z: x, + headers=_headers, + params=_params, + **kwargs + ) + raw_result.http_response.read() # type: ignore + kwargs.pop("error_map", None) + + def get_long_running_output(pipeline_response): + response_headers = {} + response = pipeline_response.http_response + response_headers["Azure-AsyncOperation"] = self._deserialize( + "str", response.headers.get("Azure-AsyncOperation") + ) + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) + + deserialized = _deserialize(_models.RestoreOperation, response.json()) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + return deserialized + + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + + if polling is True: + polling_method: PollingMethod = cast( + PollingMethod, LROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + ) + elif polling is False: + polling_method = cast(PollingMethod, NoPolling()) + else: + polling_method = polling + if cont_token: + return LROPoller[_models.RestoreOperation].from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output, + ) + return LROPoller[_models.RestoreOperation]( + self._client, raw_result, get_long_running_output, polling_method # type: ignore + ) - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param scope: The scope of the role definition to create or update. Managed HSM only supports - '/'. Required. - :type scope: str - :param role_definition_name: The name of the role definition to create or update. It can be any - valid GUID. Required. - :type role_definition_name: str - :param parameters: Parameters for the role definition. Is either a - RoleDefinitionCreateParameters type or a IO[bytes] type. Required. - :type parameters: ~azure.keyvault.v7_5.models.RoleDefinitionCreateParameters or IO[bytes] - :keyword content_type: Body Parameter content-type. Known values are: 'application/json'. - Default value is None. - :paramtype content_type: str - :return: RoleDefinition - :rtype: ~azure.keyvault.v7_5.models.RoleDefinition + @distributed_trace + def selective_key_restore_status(self, job_id: str, **kwargs: Any) -> _models.SelectiveKeyRestoreOperation: + """Returns the status of the selective key restore operation. + + :param job_id: The Job Id returned part of the restore operation. Required. + :type job_id: str + :return: SelectiveKeyRestoreOperation. The SelectiveKeyRestoreOperation is compatible with + MutableMapping + :rtype: ~azure.keyvault.administration.models.SelectiveKeyRestoreOperation :raises ~azure.core.exceptions.HttpResponseError: """ - error_map = { + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, @@ -1632,71 +2334,58 @@ def create_or_update( } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) + _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.RoleDefinition] = kwargs.pop("cls", None) - - content_type = content_type or "application/json" - _json = None - _content = None - if isinstance(parameters, (IOBase, bytes)): - _content = parameters - else: - _json = self._serialize.body(parameters, "RoleDefinitionCreateParameters") + cls: ClsType[_models.SelectiveKeyRestoreOperation] = kwargs.pop("cls", None) - _request = build_role_definitions_create_or_update_request( - scope=scope, - role_definition_name=role_definition_name, - content_type=content_type, + _request = build_key_vault_selective_key_restore_status_request( + job_id=job_id, api_version=self._config.api_version, - json=_json, - content=_content, headers=_headers, params=_params, ) path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [201]: + if response.status_code not in [200]: if _stream: - response.read() # Load the body in memory and close the socket + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) raise HttpResponseError(response=response, model=error) - deserialized = self._deserialize("RoleDefinition", pipeline_response) + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize(_models.SelectiveKeyRestoreOperation, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore return deserialized # type: ignore - @distributed_trace - def get(self, vault_base_url: str, scope: str, role_definition_name: str, **kwargs: Any) -> _models.RoleDefinition: - """Get the specified role definition. - - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param scope: The scope of the role definition to get. Managed HSM only supports '/'. Required. - :type scope: str - :param role_definition_name: The name of the role definition to get. Required. - :type role_definition_name: str - :return: RoleDefinition - :rtype: ~azure.keyvault.v7_5.models.RoleDefinition - :raises ~azure.core.exceptions.HttpResponseError: - """ - error_map = { + def _selective_key_restore_operation_initial( + self, + key_name: str, + restore_blob_details: Union[_models.SelectiveKeyRestoreOperationParameters, JSON, IO[bytes]], + **kwargs: Any + ) -> Iterator[bytes]: + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, @@ -1704,311 +2393,310 @@ def get(self, vault_base_url: str, scope: str, role_definition_name: str, **kwar } error_map.update(kwargs.pop("error_map", {}) or {}) - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.RoleDefinition] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[Iterator[bytes]] = kwargs.pop("cls", None) - _request = build_role_definitions_get_request( - scope=scope, - role_definition_name=role_definition_name, + content_type = content_type or "application/json" + _content = None + if isinstance(restore_blob_details, (IOBase, bytes)): + _content = restore_blob_details + else: + _content = json.dumps(restore_blob_details, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore + + _request = build_key_vault_selective_key_restore_operation_request( + key_name=key_name, + content_type=content_type, api_version=self._config.api_version, + content=_content, headers=_headers, params=_params, ) path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _stream = True pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: + if response.status_code not in [202]: + try: response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) raise HttpResponseError(response=response, model=error) - deserialized = self._deserialize("RoleDefinition", pipeline_response) + response_headers = {} + response_headers["Azure-AsyncOperation"] = self._deserialize( + "str", response.headers.get("Azure-AsyncOperation") + ) + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) + + deserialized = response.iter_bytes() if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore + return cls(pipeline_response, deserialized, response_headers) # type: ignore return deserialized # type: ignore - @distributed_trace - def list( - self, vault_base_url: str, scope: str, *, filter: Optional[str] = None, **kwargs: Any - ) -> Iterable["_models.RoleDefinition"]: - """Get all role definitions that are applicable at scope and above. + @overload + def begin_selective_key_restore_operation( + self, + key_name: str, + restore_blob_details: _models.SelectiveKeyRestoreOperationParameters, + *, + content_type: str = "application/json", + **kwargs: Any + ) -> LROPoller[_models.SelectiveKeyRestoreOperation]: + """Restores all key versions of a given key using user supplied SAS token pointing to a previously + stored Azure Blob storage backup folder. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param scope: The scope of the role definition. Required. - :type scope: str - :keyword filter: The filter to apply on the operation. Use atScopeAndBelow filter to search - below the given scope as well. Default value is None. - :paramtype filter: str - :return: An iterator like instance of RoleDefinition - :rtype: ~azure.core.paging.ItemPaged[~azure.keyvault.v7_5.models.RoleDefinition] + :param key_name: The name of the key to be restored from the user supplied backup. Required. + :type key_name: str + :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous + successful full backup was stored. Required. + :type restore_blob_details: + ~azure.keyvault.administration.models.SelectiveKeyRestoreOperationParameters + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of LROPoller that returns SelectiveKeyRestoreOperation. The + SelectiveKeyRestoreOperation is compatible with MutableMapping + :rtype: + ~azure.core.polling.LROPoller[~azure.keyvault.administration.models.SelectiveKeyRestoreOperation] :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[_models._models.RoleDefinitionListResult] = kwargs.pop( # pylint: disable=protected-access - "cls", None - ) - - error_map = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - def prepare_request(next_link=None): - if not next_link: - - _request = build_role_definitions_list_request( - scope=scope, - filter=filter, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params - ) - path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - return _request - - def extract_data(pipeline_response): - deserialized = self._deserialize( - _models._models.RoleDefinitionListResult, pipeline_response # pylint: disable=protected-access - ) - list_of_elem = deserialized.value - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.next_link or None, iter(list_of_elem) - - def get_next(next_link=None): - _request = prepare_request(next_link) - - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response - - if response.status_code not in [200]: - if _stream: - response.read() # Load the body in memory and close the socket - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) - raise HttpResponseError(response=response, model=error) - - return pipeline_response - - return ItemPaged(get_next, extract_data) - -class RoleAssignmentsOperations: - """ - .. warning:: - **DO NOT** instantiate this class directly. + @overload + def begin_selective_key_restore_operation( + self, key_name: str, restore_blob_details: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> LROPoller[_models.SelectiveKeyRestoreOperation]: + """Restores all key versions of a given key using user supplied SAS token pointing to a previously + stored Azure Blob storage backup folder. - Instead, you should access the following operations through - :class:`~azure.keyvault.v7_5.KeyVaultClient`'s - :attr:`role_assignments` attribute. - """ + :param key_name: The name of the key to be restored from the user supplied backup. Required. + :type key_name: str + :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous + successful full backup was stored. Required. + :type restore_blob_details: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of LROPoller that returns SelectiveKeyRestoreOperation. The + SelectiveKeyRestoreOperation is compatible with MutableMapping + :rtype: + ~azure.core.polling.LROPoller[~azure.keyvault.administration.models.SelectiveKeyRestoreOperation] + :raises ~azure.core.exceptions.HttpResponseError: + """ - models = _models + @overload + def begin_selective_key_restore_operation( + self, key_name: str, restore_blob_details: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> LROPoller[_models.SelectiveKeyRestoreOperation]: + """Restores all key versions of a given key using user supplied SAS token pointing to a previously + stored Azure Blob storage backup folder. - def __init__(self, *args, **kwargs): - input_args = list(args) - self._client = input_args.pop(0) if input_args else kwargs.pop("client") - self._config = input_args.pop(0) if input_args else kwargs.pop("config") - self._serialize = input_args.pop(0) if input_args else kwargs.pop("serializer") - self._deserialize = input_args.pop(0) if input_args else kwargs.pop("deserializer") + :param key_name: The name of the key to be restored from the user supplied backup. Required. + :type key_name: str + :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous + successful full backup was stored. Required. + :type restore_blob_details: IO[bytes] + :keyword content_type: Body Parameter content-type. Content type parameter for binary body. + Default value is "application/json". + :paramtype content_type: str + :return: An instance of LROPoller that returns SelectiveKeyRestoreOperation. The + SelectiveKeyRestoreOperation is compatible with MutableMapping + :rtype: + ~azure.core.polling.LROPoller[~azure.keyvault.administration.models.SelectiveKeyRestoreOperation] + :raises ~azure.core.exceptions.HttpResponseError: + """ @distributed_trace - def delete( - self, vault_base_url: str, scope: str, role_assignment_name: str, **kwargs: Any - ) -> _models.RoleAssignment: - """Deletes a role assignment. + def begin_selective_key_restore_operation( + self, + key_name: str, + restore_blob_details: Union[_models.SelectiveKeyRestoreOperationParameters, JSON, IO[bytes]], + **kwargs: Any + ) -> LROPoller[_models.SelectiveKeyRestoreOperation]: + """Restores all key versions of a given key using user supplied SAS token pointing to a previously + stored Azure Blob storage backup folder. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param scope: The scope of the role assignment to delete. Required. - :type scope: str - :param role_assignment_name: The name of the role assignment to delete. Required. - :type role_assignment_name: str - :return: RoleAssignment - :rtype: ~azure.keyvault.v7_5.models.RoleAssignment + :param key_name: The name of the key to be restored from the user supplied backup. Required. + :type key_name: str + :param restore_blob_details: The Azure blob SAS token pointing to a folder where the previous + successful full backup was stored. Is one of the following types: + SelectiveKeyRestoreOperationParameters, JSON, IO[bytes] Required. + :type restore_blob_details: + ~azure.keyvault.administration.models.SelectiveKeyRestoreOperationParameters or JSON or + IO[bytes] + :return: An instance of LROPoller that returns SelectiveKeyRestoreOperation. The + SelectiveKeyRestoreOperation is compatible with MutableMapping + :rtype: + ~azure.core.polling.LROPoller[~azure.keyvault.administration.models.SelectiveKeyRestoreOperation] :raises ~azure.core.exceptions.HttpResponseError: """ - error_map = { - 401: ClientAuthenticationError, - 404: ResourceNotFoundError, - 409: ResourceExistsError, - 304: ResourceNotModifiedError, - } - error_map.update(kwargs.pop("error_map", {}) or {}) - - _headers = kwargs.pop("headers", {}) or {} + _headers = case_insensitive_dict(kwargs.pop("headers", {}) or {}) _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.RoleAssignment] = kwargs.pop("cls", None) + content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) + cls: ClsType[_models.SelectiveKeyRestoreOperation] = kwargs.pop("cls", None) + polling: Union[bool, PollingMethod] = kwargs.pop("polling", True) + lro_delay = kwargs.pop("polling_interval", self._config.polling_interval) + cont_token: Optional[str] = kwargs.pop("continuation_token", None) + if cont_token is None: + raw_result = self._selective_key_restore_operation_initial( + key_name=key_name, + restore_blob_details=restore_blob_details, + content_type=content_type, + cls=lambda x, y, z: x, + headers=_headers, + params=_params, + **kwargs + ) + raw_result.http_response.read() # type: ignore + kwargs.pop("error_map", None) + + def get_long_running_output(pipeline_response): + response_headers = {} + response = pipeline_response.http_response + response_headers["Azure-AsyncOperation"] = self._deserialize( + "str", response.headers.get("Azure-AsyncOperation") + ) + response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After")) + + deserialized = _deserialize(_models.SelectiveKeyRestoreOperation, response.json()) + if cls: + return cls(pipeline_response, deserialized, response_headers) # type: ignore + return deserialized - _request = build_role_assignments_delete_request( - scope=scope, - role_assignment_name=role_assignment_name, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs + if polling is True: + polling_method: PollingMethod = cast( + PollingMethod, LROBasePolling(lro_delay, path_format_arguments=path_format_arguments, **kwargs) + ) + elif polling is False: + polling_method = cast(PollingMethod, NoPolling()) + else: + polling_method = polling + if cont_token: + return LROPoller[_models.SelectiveKeyRestoreOperation].from_continuation_token( + polling_method=polling_method, + continuation_token=cont_token, + client=self._client, + deserialization_callback=get_long_running_output, + ) + return LROPoller[_models.SelectiveKeyRestoreOperation]( + self._client, raw_result, get_long_running_output, polling_method # type: ignore ) - response = pipeline_response.http_response - - if response.status_code not in [200]: - if _stream: - response.read() # Load the body in memory and close the socket - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) - raise HttpResponseError(response=response, model=error) - - deserialized = self._deserialize("RoleAssignment", pipeline_response) - - if cls: - return cls(pipeline_response, deserialized, {}) # type: ignore - - return deserialized # type: ignore - @overload - def create( + def update_setting( self, - vault_base_url: str, - scope: str, - role_assignment_name: str, - parameters: _models.RoleAssignmentCreateParameters, + setting_name: str, + parameters: _models.UpdateSettingRequest, *, content_type: str = "application/json", **kwargs: Any - ) -> _models.RoleAssignment: - """Creates a role assignment. + ) -> _models.Setting: + """Updates key vault account setting, stores it, then returns the setting name and value to the + client. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param scope: The scope of the role assignment to create. Required. - :type scope: str - :param role_assignment_name: The name of the role assignment to create. It can be any valid - GUID. Required. - :type role_assignment_name: str - :param parameters: Parameters for the role assignment. Required. - :type parameters: ~azure.keyvault.v7_5.models.RoleAssignmentCreateParameters + Description of the pool setting to be updated. + + :param setting_name: The name of the account setting. Must be a valid settings option. + Required. + :type setting_name: str + :param parameters: The parameters to update an account setting. Required. + :type parameters: ~azure.keyvault.administration.models.UpdateSettingRequest :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. Default value is "application/json". :paramtype content_type: str - :return: RoleAssignment - :rtype: ~azure.keyvault.v7_5.models.RoleAssignment + :return: Setting. The Setting is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.Setting :raises ~azure.core.exceptions.HttpResponseError: """ @overload - def create( - self, - vault_base_url: str, - scope: str, - role_assignment_name: str, - parameters: IO[bytes], - *, - content_type: str = "application/json", - **kwargs: Any - ) -> _models.RoleAssignment: - """Creates a role assignment. + def update_setting( + self, setting_name: str, parameters: JSON, *, content_type: str = "application/json", **kwargs: Any + ) -> _models.Setting: + """Updates key vault account setting, stores it, then returns the setting name and value to the + client. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param scope: The scope of the role assignment to create. Required. - :type scope: str - :param role_assignment_name: The name of the role assignment to create. It can be any valid - GUID. Required. - :type role_assignment_name: str - :param parameters: Parameters for the role assignment. Required. + Description of the pool setting to be updated. + + :param setting_name: The name of the account setting. Must be a valid settings option. + Required. + :type setting_name: str + :param parameters: The parameters to update an account setting. Required. + :type parameters: JSON + :keyword content_type: Body Parameter content-type. Content type parameter for JSON body. + Default value is "application/json". + :paramtype content_type: str + :return: Setting. The Setting is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.Setting + :raises ~azure.core.exceptions.HttpResponseError: + """ + + @overload + def update_setting( + self, setting_name: str, parameters: IO[bytes], *, content_type: str = "application/json", **kwargs: Any + ) -> _models.Setting: + """Updates key vault account setting, stores it, then returns the setting name and value to the + client. + + Description of the pool setting to be updated. + + :param setting_name: The name of the account setting. Must be a valid settings option. + Required. + :type setting_name: str + :param parameters: The parameters to update an account setting. Required. :type parameters: IO[bytes] :keyword content_type: Body Parameter content-type. Content type parameter for binary body. Default value is "application/json". :paramtype content_type: str - :return: RoleAssignment - :rtype: ~azure.keyvault.v7_5.models.RoleAssignment + :return: Setting. The Setting is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.Setting :raises ~azure.core.exceptions.HttpResponseError: """ @distributed_trace - def create( - self, - vault_base_url: str, - scope: str, - role_assignment_name: str, - parameters: Union[_models.RoleAssignmentCreateParameters, IO[bytes]], - **kwargs: Any - ) -> _models.RoleAssignment: - """Creates a role assignment. + def update_setting( + self, setting_name: str, parameters: Union[_models.UpdateSettingRequest, JSON, IO[bytes]], **kwargs: Any + ) -> _models.Setting: + """Updates key vault account setting, stores it, then returns the setting name and value to the + client. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param scope: The scope of the role assignment to create. Required. - :type scope: str - :param role_assignment_name: The name of the role assignment to create. It can be any valid - GUID. Required. - :type role_assignment_name: str - :param parameters: Parameters for the role assignment. Is either a - RoleAssignmentCreateParameters type or a IO[bytes] type. Required. - :type parameters: ~azure.keyvault.v7_5.models.RoleAssignmentCreateParameters or IO[bytes] - :keyword content_type: Body Parameter content-type. Known values are: 'application/json'. - Default value is None. - :paramtype content_type: str - :return: RoleAssignment - :rtype: ~azure.keyvault.v7_5.models.RoleAssignment + Description of the pool setting to be updated. + + :param setting_name: The name of the account setting. Must be a valid settings option. + Required. + :type setting_name: str + :param parameters: The parameters to update an account setting. Is one of the following types: + UpdateSettingRequest, JSON, IO[bytes] Required. + :type parameters: ~azure.keyvault.administration.models.UpdateSettingRequest or JSON or + IO[bytes] + :return: Setting. The Setting is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.Setting :raises ~azure.core.exceptions.HttpResponseError: """ - error_map = { + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, @@ -2020,46 +2708,51 @@ def create( _params = kwargs.pop("params", {}) or {} content_type: Optional[str] = kwargs.pop("content_type", _headers.pop("Content-Type", None)) - cls: ClsType[_models.RoleAssignment] = kwargs.pop("cls", None) + cls: ClsType[_models.Setting] = kwargs.pop("cls", None) content_type = content_type or "application/json" - _json = None _content = None if isinstance(parameters, (IOBase, bytes)): _content = parameters else: - _json = self._serialize.body(parameters, "RoleAssignmentCreateParameters") + _content = json.dumps(parameters, cls=SdkJSONEncoder, exclude_readonly=True) # type: ignore - _request = build_role_assignments_create_request( - scope=scope, - role_assignment_name=role_assignment_name, + _request = build_key_vault_update_setting_request( + setting_name=setting_name, content_type=content_type, api_version=self._config.api_version, - json=_json, content=_content, headers=_headers, params=_params, ) path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) response = pipeline_response.http_response - if response.status_code not in [201]: + if response.status_code not in [200]: if _stream: - response.read() # Load the body in memory and close the socket + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) raise HttpResponseError(response=response, model=error) - deserialized = self._deserialize("RoleAssignment", pipeline_response) + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize(_models.Setting, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -2067,20 +2760,19 @@ def create( return deserialized # type: ignore @distributed_trace - def get(self, vault_base_url: str, scope: str, role_assignment_name: str, **kwargs: Any) -> _models.RoleAssignment: - """Get the specified role assignment. + def get_setting(self, setting_name: str, **kwargs: Any) -> _models.Setting: + """Get specified account setting object. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param scope: The scope of the role assignment. Required. - :type scope: str - :param role_assignment_name: The name of the role assignment to get. Required. - :type role_assignment_name: str - :return: RoleAssignment - :rtype: ~azure.keyvault.v7_5.models.RoleAssignment + Retrieves the setting object of a specified setting name. + + :param setting_name: The name of the account setting. Must be a valid settings option. + Required. + :type setting_name: str + :return: Setting. The Setting is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.Setting :raises ~azure.core.exceptions.HttpResponseError: """ - error_map = { + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, @@ -2091,21 +2783,22 @@ def get(self, vault_base_url: str, scope: str, role_assignment_name: str, **kwar _headers = kwargs.pop("headers", {}) or {} _params = kwargs.pop("params", {}) or {} - cls: ClsType[_models.RoleAssignment] = kwargs.pop("cls", None) + cls: ClsType[_models.Setting] = kwargs.pop("cls", None) - _request = build_role_assignments_get_request( - scope=scope, - role_assignment_name=role_assignment_name, + _request = build_key_vault_get_setting_request( + setting_name=setting_name, api_version=self._config.api_version, headers=_headers, params=_params, ) path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), } _request.url = self._client.format_url(_request.url, **path_format_arguments) - _stream = False + _stream = kwargs.pop("stream", False) pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access _request, stream=_stream, **kwargs ) @@ -2114,12 +2807,18 @@ def get(self, vault_base_url: str, scope: str, role_assignment_name: str, **kwar if response.status_code not in [200]: if _stream: - response.read() # Load the body in memory and close the socket + try: + response.read() # Load the body in memory and close the socket + except (StreamConsumedError, StreamClosedError): + pass map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) raise HttpResponseError(response=response, model=error) - deserialized = self._deserialize("RoleAssignment", pipeline_response) + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize(_models.Setting, response.json()) if cls: return cls(pipeline_response, deserialized, {}) # type: ignore @@ -2127,31 +2826,16 @@ def get(self, vault_base_url: str, scope: str, role_assignment_name: str, **kwar return deserialized # type: ignore @distributed_trace - def list_for_scope( - self, vault_base_url: str, scope: str, *, filter: Optional[str] = None, **kwargs: Any - ) -> Iterable["_models.RoleAssignment"]: - """Gets role assignments for a scope. + def get_settings(self, **kwargs: Any) -> _models.SettingsListResult: + """List account settings. - :param vault_base_url: The vault name, for example https://myvault.vault.azure.net. Required. - :type vault_base_url: str - :param scope: The scope of the role assignments. Required. - :type scope: str - :keyword filter: The filter to apply on the operation. Use $filter=atScope() to return all role - assignments at or above the scope. Use $filter=principalId eq {id} to return all role - assignments at, above or below the scope for the specified principal. Default value is None. - :paramtype filter: str - :return: An iterator like instance of RoleAssignment - :rtype: ~azure.core.paging.ItemPaged[~azure.keyvault.v7_5.models.RoleAssignment] + Retrieves a list of all the available account settings that can be configured. + + :return: SettingsListResult. The SettingsListResult is compatible with MutableMapping + :rtype: ~azure.keyvault.administration.models.SettingsListResult :raises ~azure.core.exceptions.HttpResponseError: """ - _headers = kwargs.pop("headers", {}) or {} - _params = kwargs.pop("params", {}) or {} - - cls: ClsType[_models._models.RoleAssignmentListResult] = kwargs.pop( # pylint: disable=protected-access - "cls", None - ) - - error_map = { + error_map: MutableMapping = { 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError, @@ -2159,66 +2843,46 @@ def list_for_scope( } error_map.update(kwargs.pop("error_map", {}) or {}) - def prepare_request(next_link=None): - if not next_link: - - _request = build_role_assignments_list_for_scope_request( - scope=scope, - filter=filter, - api_version=self._config.api_version, - headers=_headers, - params=_params, - ) - path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) - - else: - # make call to next link with the client's api-version - _parsed_next_link = urllib.parse.urlparse(next_link) - _next_request_params = case_insensitive_dict( - { - key: [urllib.parse.quote(v) for v in value] - for key, value in urllib.parse.parse_qs(_parsed_next_link.query).items() - } - ) - _next_request_params["api-version"] = self._config.api_version - _request = HttpRequest( - "GET", urllib.parse.urljoin(next_link, _parsed_next_link.path), params=_next_request_params - ) - path_format_arguments = { - "vaultBaseUrl": self._serialize.url("vault_base_url", vault_base_url, "str", skip_quote=True), - } - _request.url = self._client.format_url(_request.url, **path_format_arguments) + _headers = kwargs.pop("headers", {}) or {} + _params = kwargs.pop("params", {}) or {} - return _request + cls: ClsType[_models.SettingsListResult] = kwargs.pop("cls", None) - def extract_data(pipeline_response): - deserialized = self._deserialize( - _models._models.RoleAssignmentListResult, pipeline_response # pylint: disable=protected-access - ) - list_of_elem = deserialized.value - if cls: - list_of_elem = cls(list_of_elem) # type: ignore - return deserialized.next_link or None, iter(list_of_elem) + _request = build_key_vault_get_settings_request( + api_version=self._config.api_version, + headers=_headers, + params=_params, + ) + path_format_arguments = { + "vaultBaseUrl": self._serialize.url( + "self._config.vault_base_url", self._config.vault_base_url, "str", skip_quote=True + ), + } + _request.url = self._client.format_url(_request.url, **path_format_arguments) - def get_next(next_link=None): - _request = prepare_request(next_link) + _stream = kwargs.pop("stream", False) + pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access + _request, stream=_stream, **kwargs + ) - _stream = False - pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access - _request, stream=_stream, **kwargs - ) - response = pipeline_response.http_response + response = pipeline_response.http_response - if response.status_code not in [200]: - if _stream: + if response.status_code not in [200]: + if _stream: + try: response.read() # Load the body in memory and close the socket - map_error(status_code=response.status_code, response=response, error_map=error_map) - error = self._deserialize.failsafe_deserialize(_models.KeyVaultError, pipeline_response) - raise HttpResponseError(response=response, model=error) + except (StreamConsumedError, StreamClosedError): + pass + map_error(status_code=response.status_code, response=response, error_map=error_map) + error = _failsafe_deserialize(_models.KeyVaultError, response.json()) + raise HttpResponseError(response=response, model=error) - return pipeline_response + if _stream: + deserialized = response.iter_bytes() + else: + deserialized = _deserialize(_models.SettingsListResult, response.json()) - return ItemPaged(get_next, extract_data) + if cls: + return cls(pipeline_response, deserialized, {}) # type: ignore + + return deserialized # type: ignore diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/operations/_patch.py b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/operations/_patch.py similarity index 100% rename from sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/_generated/operations/_patch.py rename to sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/operations/_patch.py diff --git a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/py.typed b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/py.typed index e69de29bb2d1..e5aff4f83af8 100644 --- a/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/py.typed +++ b/sdk/keyvault/azure-keyvault-administration/azure/keyvault/administration/py.typed @@ -0,0 +1 @@ +# Marker file for PEP 561. \ No newline at end of file diff --git a/sdk/keyvault/azure-keyvault-administration/samples/access_control_operations.py b/sdk/keyvault/azure-keyvault-administration/samples/access_control_operations.py index 4a88c14046d9..39d3192ccb73 100644 --- a/sdk/keyvault/azure-keyvault-administration/samples/access_control_operations.py +++ b/sdk/keyvault/azure-keyvault-administration/samples/access_control_operations.py @@ -12,7 +12,7 @@ # # 3. Set environment variable MANAGED_HSM_URL with the URL of your managed HSM and AZURE_CLIENT_ID with the ID of a # service principal -# +# # 4. Set up your environment to use azure-identity's DefaultAzureCredential. For more information about how to configure # the DefaultAzureCredential, refer to https://aka.ms/azsdk/python/identity/docs#azure.identity.DefaultAzureCredential # @@ -79,8 +79,7 @@ # [START update_a_role_definition] new_permissions = [ KeyVaultPermission( - data_actions=[KeyVaultDataAction.READ_HSM_KEY], - not_data_actions=[KeyVaultDataAction.CREATE_HSM_KEY] + data_actions=[KeyVaultDataAction.READ_HSM_KEY], not_data_actions=[KeyVaultDataAction.CREATE_HSM_KEY] ) ] unique_definition_name = role_definition.name diff --git a/sdk/keyvault/azure-keyvault-administration/samples/access_control_operations_async.py b/sdk/keyvault/azure-keyvault-administration/samples/access_control_operations_async.py index 4238ea22245d..48f74e078481 100644 --- a/sdk/keyvault/azure-keyvault-administration/samples/access_control_operations_async.py +++ b/sdk/keyvault/azure-keyvault-administration/samples/access_control_operations_async.py @@ -16,7 +16,7 @@ # 2. azure-keyvault-administration and azure-identity libraries (pip install these) # # 3. Set environment variable MANAGED_HSM_URL with the URL of your managed HSM -# +# # 4. Set up your environment to use azure-identity's DefaultAzureCredential. For more information about how to configure # the DefaultAzureCredential, refer to https://aka.ms/azsdk/python/identity/docs#azure.identity.DefaultAzureCredential # @@ -34,6 +34,7 @@ # 5. Delete a role definition (delete_role_definition) # ---------------------------------------------------------------------------------------------------------- + async def run_sample(): MANAGED_HSM_URL = os.environ["MANAGED_HSM_URL"] @@ -41,7 +42,7 @@ async def run_sample(): # Here we use the DefaultAzureCredential, but any azure-identity credential can be used. credential = DefaultAzureCredential() client = KeyVaultAccessControlClient(vault_url=MANAGED_HSM_URL, credential=credential) - + # Let's first create a custom role definition. This role permits creating keys in a Managed HSM. # We'll provide a friendly role name, and let a unique role definition name (a GUID) be generated for us. print("\n.. Create a role definition") @@ -57,8 +58,7 @@ async def run_sample(): print("\n.. Update a role definition") new_permissions = [ KeyVaultPermission( - data_actions=[KeyVaultDataAction.READ_HSM_KEY], - not_data_actions=[KeyVaultDataAction.CREATE_HSM_KEY] + data_actions=[KeyVaultDataAction.READ_HSM_KEY], not_data_actions=[KeyVaultDataAction.CREATE_HSM_KEY] ) ] unique_definition_name = role_definition.name diff --git a/sdk/keyvault/azure-keyvault-administration/samples/backup_restore_operations.py b/sdk/keyvault/azure-keyvault-administration/samples/backup_restore_operations.py index a36305134280..582b250e5f5f 100644 --- a/sdk/keyvault/azure-keyvault-administration/samples/backup_restore_operations.py +++ b/sdk/keyvault/azure-keyvault-administration/samples/backup_restore_operations.py @@ -17,7 +17,7 @@ # 4. A user-assigned managed identity that has access to your managed HSM. For more information about how to create a # user-assigned managed identity, refer to # https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/overview -# +# # 5. A storage account, that your managed identity has access to, containing a blob storage container # (See https://learn.microsoft.com/azure/storage/blobs/storage-blobs-introduction) # diff --git a/sdk/keyvault/azure-keyvault-administration/samples/backup_restore_operations_async.py b/sdk/keyvault/azure-keyvault-administration/samples/backup_restore_operations_async.py index 1cba4d1b11ae..5d5318769300 100644 --- a/sdk/keyvault/azure-keyvault-administration/samples/backup_restore_operations_async.py +++ b/sdk/keyvault/azure-keyvault-administration/samples/backup_restore_operations_async.py @@ -19,7 +19,7 @@ # 4. A user-assigned managed identity that has access to your managed HSM. For more information about how to create a # user-assigned managed identity, refer to # https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/overview -# +# # 5. A storage account, that your managed identity has access to, containing a blob storage container # (See https://learn.microsoft.com/azure/storage/blobs/storage-blobs-introduction) # @@ -36,6 +36,7 @@ # 2. Perform a full restore (begin_restore) # ---------------------------------------------------------------------------------------------------------- + async def run_sample(): MANAGED_HSM_URL = os.environ["MANAGED_HSM_URL"] CONTAINER_URL = os.environ["CONTAINER_URL"] @@ -45,7 +46,7 @@ async def run_sample(): # Here we use the DefaultAzureCredential, but any azure-identity credential can be used. credential = ManagedIdentityCredential(client_id=MANAGED_IDENTITY_CLIENT_ID) client = KeyVaultBackupClient(vault_url=MANAGED_HSM_URL, credential=credential) - + # Let's back up the vault with begin_backup, which returns a poller. Calling result() on the poller will return # a KeyVaultBackupResult that contains the URL of the backup after the operation completes. Calling wait() on # the poller will wait until the operation is complete. diff --git a/sdk/keyvault/azure-keyvault-administration/samples/settings_operations.py b/sdk/keyvault/azure-keyvault-administration/samples/settings_operations.py index 390e0d7b4e00..e3b134d2b532 100644 --- a/sdk/keyvault/azure-keyvault-administration/samples/settings_operations.py +++ b/sdk/keyvault/azure-keyvault-administration/samples/settings_operations.py @@ -13,7 +13,7 @@ # 2. azure-keyvault-administration and azure-identity libraries (pip install these) # # 3. Set environment variable MANAGED_HSM_URL with the URL of your managed HSM -# +# # 4. Set up your environment to use azure-identity's DefaultAzureCredential. For more information about how to configure # the DefaultAzureCredential, refer to https://aka.ms/azsdk/python/identity/docs#azure.identity.DefaultAzureCredential # diff --git a/sdk/keyvault/azure-keyvault-administration/samples/settings_operations_async.py b/sdk/keyvault/azure-keyvault-administration/samples/settings_operations_async.py index 77a7070a7f44..a7101d5f6bdd 100644 --- a/sdk/keyvault/azure-keyvault-administration/samples/settings_operations_async.py +++ b/sdk/keyvault/azure-keyvault-administration/samples/settings_operations_async.py @@ -16,7 +16,7 @@ # 2. azure-keyvault-administration and azure-identity libraries (pip install these) # # 3. Set environment variable MANAGED_HSM_URL with the URL of your managed HSM -# +# # 4. Set up your environment to use azure-identity's DefaultAzureCredential. For more information about how to configure # the DefaultAzureCredential, refer to https://aka.ms/azsdk/python/identity/docs#azure.identity.DefaultAzureCredential # @@ -28,6 +28,7 @@ # 2. Update a setting (update_setting) # ---------------------------------------------------------------------------------------------------------- + async def run_sample(): MANAGED_HSM_URL = os.environ["MANAGED_HSM_URL"] diff --git a/sdk/keyvault/azure-keyvault-administration/setup.py b/sdk/keyvault/azure-keyvault-administration/setup.py index 5c624c27e20b..cee8f14594ae 100644 --- a/sdk/keyvault/azure-keyvault-administration/setup.py +++ b/sdk/keyvault/azure-keyvault-administration/setup.py @@ -1,51 +1,44 @@ -#!/usr/bin/env python - -# ------------------------------------ -# Copyright (c) Microsoft Corporation. -# Licensed under the MIT License. -# ------------------------------------ -# pylint:disable=missing-docstring +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) Python Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +# coding: utf-8 +import os import re -import os.path -from io import open -from setuptools import find_packages, setup +from setuptools import setup, find_packages + -# Change the PACKAGE_NAME only to change folder and different name PACKAGE_NAME = "azure-keyvault-administration" -PACKAGE_PPRINT_NAME = "Key Vault Administration" +PACKAGE_PPRINT_NAME = "Azure Keyvault Administration" # a-b-c => a/b/c -PACKAGE_FOLDER_PATH = PACKAGE_NAME.replace("-", "/") -# a-b-c => a.b.c -NAMESPACE_NAME = PACKAGE_NAME.replace("-", ".") +package_folder_path = PACKAGE_NAME.replace("-", "/") # Version extraction inspired from 'requests' -with open(os.path.join(PACKAGE_FOLDER_PATH, "_version.py"), "r") as fd: - VERSION = re.search(r'^VERSION\s*=\s*[\'"]([^\'"]*)[\'"]', fd.read(), re.MULTILINE).group(1) # type: ignore +with open(os.path.join(package_folder_path, "_version.py"), "r") as fd: + version = re.search(r'^VERSION\s*=\s*[\'"]([^\'"]*)[\'"]', fd.read(), re.MULTILINE).group(1) -if not VERSION: +if not version: raise RuntimeError("Cannot find version information") -with open("README.md", encoding="utf-8") as f: - README = f.read() -with open("CHANGELOG.md", encoding="utf-8") as f: - CHANGELOG = f.read() setup( name=PACKAGE_NAME, - version=VERSION, - include_package_data=True, - description=f"Microsoft Azure {PACKAGE_PPRINT_NAME} Client Library for Python", - long_description=README + "\n\n" + CHANGELOG, + version=version, + description="Microsoft {} Client Library for Python".format(PACKAGE_PPRINT_NAME), + long_description=open("README.md", "r").read(), long_description_content_type="text/markdown", license="MIT License", author="Microsoft Corporation", - author_email="azurekeyvault@microsoft.com", - url="https://github.com/Azure/azure-sdk-for-python/tree/main/sdk/keyvault/azure-keyvault-administration", + author_email="azpysdkhelp@microsoft.com", + url="https://github.com/Azure/azure-sdk-for-python/tree/main/sdk", keywords="azure, azure sdk", classifiers=[ - "Development Status :: 5 - Production/Stable", + "Development Status :: 4 - Beta", "Programming Language :: Python", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3", @@ -59,17 +52,20 @@ zip_safe=False, packages=find_packages( exclude=[ - "samples", "tests", # Exclude packages that will be covered by PEP420 or nspkg "azure", "azure.keyvault", ] ), - python_requires=">=3.8", + include_package_data=True, + package_data={ + "azure.keyvault.administration": ["py.typed"], + }, install_requires=[ - "azure-core>=1.31.0", "isodate>=0.6.1", - "typing-extensions>=4.0.1", + "azure-core>=1.30.0", + "typing-extensions>=4.6.0", ], + python_requires=">=3.8", ) diff --git a/sdk/keyvault/azure-keyvault-administration/tests/_async_test_case.py b/sdk/keyvault/azure-keyvault-administration/tests/_async_test_case.py index 6ad8ed0388b1..be65a9593f91 100644 --- a/sdk/keyvault/azure-keyvault-administration/tests/_async_test_case.py +++ b/sdk/keyvault/azure-keyvault-administration/tests/_async_test_case.py @@ -25,7 +25,7 @@ def __init__(self, **kwargs) -> None: self.container_uri = f"{storage_url}/{container_name}" self.sas_token = os.environ.get("BLOB_STORAGE_SAS_TOKEN") - + else: self.managed_hsm_url = hsm_playback_url self.container_uri = container_playback_uri @@ -39,7 +39,7 @@ def __init__(self, **kwargs) -> None: # Only set service principal credentials if user-based auth is not requested if use_pwsh == use_cli == use_vscode == use_azd == "false": self._set_mgmt_settings_real_values() - + def _skip_if_not_configured(self, api_version, **kwargs): if self.is_live and api_version != DEFAULT_VERSION: pytest.skip("This test only uses the default API version for live tests") @@ -63,6 +63,7 @@ async def _preparer(test_class, api_version, **kwargs): async with client: await fn(test_class, client, **kwargs) + return _preparer def create_backup_client(self, managed_identity_client_id, **kwargs): @@ -88,6 +89,7 @@ async def _preparer(test_class, api_version, **kwargs): async with client: await fn(test_class, client, **kwargs) + return _preparer def create_backup_client(self, **kwargs): @@ -107,11 +109,11 @@ async def _preparer(test_class, api_version, **kwargs): async with client: await fn(test_class, client, **kwargs) + return _preparer def create_access_control_client(self, **kwargs): - from azure.keyvault.administration.aio import \ - KeyVaultAccessControlClient + from azure.keyvault.administration.aio import KeyVaultAccessControlClient credential = self.get_credential(KeyVaultAccessControlClient, is_async=True) return self.create_client_from_credential( @@ -127,11 +129,11 @@ async def _preparer(test_class, api_version, **kwargs): async with client: await fn(test_class, client, **kwargs) + return _preparer def create_access_control_client(self, **kwargs): - from azure.keyvault.administration.aio import \ - KeyVaultSettingsClient + from azure.keyvault.administration.aio import KeyVaultSettingsClient credential = self.get_credential(KeyVaultSettingsClient, is_async=True) return self.create_client_from_credential( diff --git a/sdk/keyvault/azure-keyvault-administration/tests/_test_case.py b/sdk/keyvault/azure-keyvault-administration/tests/_test_case.py index fe082b88063d..e4b23e6cebed 100644 --- a/sdk/keyvault/azure-keyvault-administration/tests/_test_case.py +++ b/sdk/keyvault/azure-keyvault-administration/tests/_test_case.py @@ -26,7 +26,7 @@ def __init__(self, **kwargs) -> None: self.container_uri = f"{storage_url}/{container_name}" self.sas_token = os.environ.get("BLOB_STORAGE_SAS_TOKEN") - + else: self.managed_hsm_url = hsm_playback_url self.container_uri = container_playback_uri @@ -40,7 +40,7 @@ def __init__(self, **kwargs) -> None: # Only set service principal credentials if user-based auth is not requested if use_pwsh == use_cli == use_vscode == use_azd == "false": self._set_mgmt_settings_real_values() - + def _skip_if_not_configured(self, api_version, **kwargs): if self.is_live and api_version != DEFAULT_VERSION: pytest.skip("This test only uses the default API version for live tests") @@ -56,7 +56,7 @@ def _set_mgmt_settings_real_values(self): class KeyVaultBackupClientPreparer(BaseClientPreparer): def __init__(self, **kwargs) -> None: - super().__init__(**kwargs) + super().__init__(**kwargs) def __call__(self, fn): def _preparer(test_class, api_version, **kwargs): @@ -67,6 +67,7 @@ def _preparer(test_class, api_version, **kwargs): with client: fn(test_class, client, **kwargs) + return _preparer def create_backup_client(self, managed_identity_client_id, **kwargs): @@ -83,7 +84,7 @@ def create_backup_client(self, managed_identity_client_id, **kwargs): class KeyVaultBackupClientSasPreparer(BaseClientPreparer): def __init__(self, **kwargs) -> None: - super().__init__(**kwargs) + super().__init__(**kwargs) def __call__(self, fn): def _preparer(test_class, api_version, **kwargs): @@ -95,6 +96,7 @@ def _preparer(test_class, api_version, **kwargs): with client: fn(test_class, client, **kwargs) + return _preparer def create_backup_client(self, **kwargs): @@ -117,6 +119,7 @@ def _preparer(test_class, api_version, **kwargs): with client: fn(test_class, client, **kwargs) + return _preparer def create_access_control_client(self, **kwargs): @@ -139,6 +142,7 @@ def _preparer(test_class, api_version, **kwargs): with client: fn(test_class, client, **kwargs) + return _preparer def create_settings_client(self, **kwargs): diff --git a/sdk/keyvault/azure-keyvault-administration/tests/conftest.py b/sdk/keyvault/azure-keyvault-administration/tests/conftest.py index 66f14f669a46..872fdb9d38f7 100644 --- a/sdk/keyvault/azure-keyvault-administration/tests/conftest.py +++ b/sdk/keyvault/azure-keyvault-administration/tests/conftest.py @@ -16,7 +16,8 @@ remove_batch_sanitizers, ) -os.environ['PYTHONHASHSEED'] = '0' +os.environ["PYTHONHASHSEED"] = "0" + @pytest.fixture(scope="session", autouse=True) def add_sanitizers(test_proxy): @@ -24,22 +25,22 @@ def add_sanitizers(test_proxy): azure_keyvault_url = azure_keyvault_url.rstrip("/") keyvault_tenant_id = os.getenv("KEYVAULT_TENANT_ID", "keyvault_tenant_id") keyvault_subscription_id = os.getenv("KEYVAULT_SUBSCRIPTION_ID", "keyvault_subscription_id") - azure_managedhsm_url = os.environ.get("AZURE_MANAGEDHSM_URL","https://Sanitized.managedhsm.azure.net") + azure_managedhsm_url = os.environ.get("AZURE_MANAGEDHSM_URL", "https://Sanitized.managedhsm.azure.net") azure_managedhsm_url = azure_managedhsm_url.rstrip("/") - azure_attestation_uri = os.environ.get("AZURE_KEYVAULT_ATTESTATION_URL","https://Sanitized.azurewebsites.net") - azure_attestation_uri = azure_attestation_uri.rstrip('/') + azure_attestation_uri = os.environ.get("AZURE_KEYVAULT_ATTESTATION_URL", "https://Sanitized.azurewebsites.net") + azure_attestation_uri = azure_attestation_uri.rstrip("/") storage_url = os.environ.get("BLOB_STORAGE_URL", "https://Sanitized.blob.core.windows.net") client_id = os.environ.get("KEYVAULT_CLIENT_ID", "service-principal-id") - sas_token = os.environ.get("BLOB_STORAGE_SAS_TOKEN","fake-sas") + sas_token = os.environ.get("BLOB_STORAGE_SAS_TOKEN", "fake-sas") add_general_string_sanitizer(target=azure_keyvault_url, value="https://Sanitized.vault.azure.net") add_general_string_sanitizer(target=keyvault_tenant_id, value="00000000-0000-0000-0000-000000000000") add_general_string_sanitizer(target=keyvault_subscription_id, value="00000000-0000-0000-0000-000000000000") - add_general_string_sanitizer(target=azure_managedhsm_url,value="https://Sanitized.managedhsm.azure.net") - add_general_string_sanitizer(target=azure_attestation_uri,value="https://Sanitized.azurewebsites.net") + add_general_string_sanitizer(target=azure_managedhsm_url, value="https://Sanitized.managedhsm.azure.net") + add_general_string_sanitizer(target=azure_attestation_uri, value="https://Sanitized.azurewebsites.net") add_general_string_sanitizer(target=storage_url, value="https://Sanitized.blob.core.windows.net") add_general_string_sanitizer(target=sas_token, value="fake-sas") - add_general_string_sanitizer(target=client_id, value = "service-principal-id") + add_general_string_sanitizer(target=client_id, value="service-principal-id") # Sanitize API versions of `azure-keyvault-keys` requests add_uri_regex_sanitizer( regex="keys/([^/]*)/create\\?api-version=(\\S*)", value="keys/$1/create?api-version=sanitized" diff --git a/sdk/keyvault/azure-keyvault-administration/tests/perfstress_tests/get_role_definition.py b/sdk/keyvault/azure-keyvault-administration/tests/perfstress_tests/get_role_definition.py index 80730f6ae7d8..dd5dfb5a2add 100644 --- a/sdk/keyvault/azure-keyvault-administration/tests/perfstress_tests/get_role_definition.py +++ b/sdk/keyvault/azure-keyvault-administration/tests/perfstress_tests/get_role_definition.py @@ -8,10 +8,10 @@ from azure.identity import DefaultAzureCredential from azure.identity.aio import DefaultAzureCredential as AsyncDefaultAzureCredential from azure.keyvault.administration import ( - KeyVaultAccessControlClient, + KeyVaultAccessControlClient, KeyVaultDataAction, KeyVaultPermission, - KeyVaultRoleScope, + KeyVaultRoleScope, ) from azure.keyvault.administration.aio import KeyVaultAccessControlClient as AsyncKeyVaultAccessControlClient @@ -32,7 +32,7 @@ def __init__(self, arguments): self.role_name = uuid.uuid4() self.scope = KeyVaultRoleScope.GLOBAL self.permissions = [KeyVaultPermission(data_actions=[KeyVaultDataAction.CREATE_HSM_KEY])] - + async def global_setup(self): """The global setup is run only once.""" await super().global_setup() @@ -42,7 +42,7 @@ async def global_cleanup(self): """The global cleanup is run only once.""" await self.async_client.delete_role_definition(scope=self.scope, name=self.role_name) await super().global_cleanup() - + async def close(self): """This is run after cleanup.""" await self.async_client.close() diff --git a/sdk/keyvault/azure-keyvault-administration/tests/test_access_control.py b/sdk/keyvault/azure-keyvault-administration/tests/test_access_control.py index c14251a13080..89c440d776b0 100644 --- a/sdk/keyvault/azure-keyvault-administration/tests/test_access_control.py +++ b/sdk/keyvault/azure-keyvault-administration/tests/test_access_control.py @@ -43,14 +43,10 @@ def test_role_definitions(self, client, **kwargs): # create custom role definition role_name = self.get_resource_name("role-name") definition_name = self.get_replayable_uuid("definition-name") - add_general_regex_sanitizer(regex=definition_name, value = "definition-name") + add_general_regex_sanitizer(regex=definition_name, value="definition-name") permissions = [KeyVaultPermission(data_actions=[KeyVaultDataAction.READ_HSM_KEY])] created_definition = client.set_role_definition( - scope=scope, - name=definition_name, - role_name=role_name, - description="test", - permissions=permissions + scope=scope, name=definition_name, role_name=role_name, description="test", permissions=permissions ) assert "/" in created_definition.assignable_scopes assert created_definition.role_name == role_name @@ -61,12 +57,8 @@ def test_role_definitions(self, client, **kwargs): assert created_definition.assignable_scopes == [KeyVaultRoleScope.GLOBAL] # update custom role definition - permissions = [ - KeyVaultPermission(data_actions=[], not_data_actions=[KeyVaultDataAction.READ_HSM_KEY]) - ] - updated_definition = client.set_role_definition( - scope=scope, name=definition_name, permissions=permissions - ) + permissions = [KeyVaultPermission(data_actions=[], not_data_actions=[KeyVaultDataAction.READ_HSM_KEY])] + updated_definition = client.set_role_definition(scope=scope, name=definition_name, permissions=permissions) assert updated_definition.role_name == "" assert updated_definition.description == "" assert len(updated_definition.permissions) == 1 @@ -101,18 +93,18 @@ def test_role_assignment(self, client, **kwargs): definition = definitions[0] principal_id = self.get_service_principal_id() name = self.get_replayable_uuid("some-uuid") - add_general_regex_sanitizer(regex=name, value = "some-uuid") + add_general_regex_sanitizer(regex=name, value="some-uuid") created = client.create_role_assignment(scope, definition.id, principal_id, name=name) assert created.name == name - #assert created.properties.principal_id == principal_id + # assert created.properties.principal_id == principal_id assert created.properties.role_definition_id == definition.id assert created.properties.scope == scope # should be able to get the new assignment got = client.get_role_assignment(scope, name) assert got.name == name - #assert got.properties.principal_id == principal_id + # assert got.properties.principal_id == principal_id assert got.properties.role_definition_id == definition.id assert got.properties.scope == scope diff --git a/sdk/keyvault/azure-keyvault-administration/tests/test_access_control_async.py b/sdk/keyvault/azure-keyvault-administration/tests/test_access_control_async.py index db16f213da21..74d961b5b865 100644 --- a/sdk/keyvault/azure-keyvault-administration/tests/test_access_control_async.py +++ b/sdk/keyvault/azure-keyvault-administration/tests/test_access_control_async.py @@ -7,7 +7,7 @@ import uuid import pytest -from azure.keyvault.administration import KeyVaultDataAction, KeyVaultPermission,KeyVaultRoleScope +from azure.keyvault.administration import KeyVaultDataAction, KeyVaultPermission, KeyVaultRoleScope from devtools_testutils import add_general_regex_sanitizer, set_bodiless_matcher from devtools_testutils.aio import recorded_by_proxy_async @@ -31,7 +31,7 @@ def get_service_principal_id(self): value = os.environ["AZURE_CLIENT_ID"] return value return replay_value - + @pytest.mark.asyncio @pytest.mark.parametrize("api_version", all_api_versions) @KeyVaultAccessControlClientPreparer() @@ -48,14 +48,10 @@ async def test_role_definitions(self, client, **kwargs): # create custom role definition role_name = self.get_resource_name("role-name") definition_name = self.get_replayable_uuid("definition-name") - add_general_regex_sanitizer(regex=definition_name, value = "definition-name") + add_general_regex_sanitizer(regex=definition_name, value="definition-name") permissions = [KeyVaultPermission(data_actions=[KeyVaultDataAction.READ_HSM_KEY])] created_definition = await client.set_role_definition( - scope=scope, - name=definition_name, - role_name=role_name, - description="test", - permissions=permissions + scope=scope, name=definition_name, role_name=role_name, description="test", permissions=permissions ) assert "/" in created_definition.assignable_scopes assert created_definition.role_name == role_name @@ -66,9 +62,7 @@ async def test_role_definitions(self, client, **kwargs): assert created_definition.assignable_scopes == [KeyVaultRoleScope.GLOBAL] # update custom role definition - permissions = [ - KeyVaultPermission(data_actions=[], not_data_actions=[KeyVaultDataAction.READ_HSM_KEY]) - ] + permissions = [KeyVaultPermission(data_actions=[], not_data_actions=[KeyVaultDataAction.READ_HSM_KEY])] updated_definition = await client.set_role_definition( scope=scope, name=definition_name, permissions=permissions ) @@ -94,11 +88,10 @@ async def test_role_definitions(self, client, **kwargs): await client.delete_role_definition(scope, definition_name) async for d in client.list_role_definitions(scope): - assert (d.id != definition.id), "the role definition should have been deleted" + assert d.id != definition.id, "the role definition should have been deleted" if self.is_live: await asyncio.sleep(60) # additional waiting to avoid conflicts with resources in other tests - @pytest.mark.asyncio @pytest.mark.parametrize("api_version", all_api_versions) @KeyVaultAccessControlClientPreparer() @@ -114,20 +107,18 @@ async def test_role_assignment(self, client, **kwargs): definition = definitions[0] principal_id = self.get_service_principal_id() name = self.get_replayable_uuid("some-uuid") - add_general_regex_sanitizer(regex=name, value = "some-uuid") - - + add_general_regex_sanitizer(regex=name, value="some-uuid") created = await client.create_role_assignment(scope, definition.id, principal_id, name=name) assert created.name == name - #assert created.properties.principal_id == principal_id + # assert created.properties.principal_id == principal_id assert created.properties.role_definition_id == definition.id assert created.properties.scope == scope # should be able to get the new assignment got = await client.get_role_assignment(scope, name) assert got.name == name - #assert got.properties.principal_id == principal_id + # assert got.properties.principal_id == principal_id assert got.properties.role_definition_id == definition.id assert got.properties.scope == scope diff --git a/sdk/keyvault/azure-keyvault-administration/tests/test_backup_client.py b/sdk/keyvault/azure-keyvault-administration/tests/test_backup_client.py index 1398c6164b12..9d0896a6bf24 100644 --- a/sdk/keyvault/azure-keyvault-administration/tests/test_backup_client.py +++ b/sdk/keyvault/azure-keyvault-administration/tests/test_backup_client.py @@ -22,8 +22,9 @@ class TestBackupClientTests(KeyVaultTestCase): def create_key_client(self, vault_uri, **kwargs): from azure.keyvault.keys import KeyClient + credential = self.get_credential(KeyClient) - return self.create_client_from_credential(KeyClient, credential=credential, vault_url=vault_uri, **kwargs ) + return self.create_client_from_credential(KeyClient, credential=credential, vault_url=vault_uri, **kwargs) @pytest.mark.parametrize("api_version", only_default) @KeyVaultBackupClientPreparer() @@ -86,7 +87,6 @@ def test_selective_key_restore(self, client, **kwargs): key_name = self.get_resource_name("selective-restore-test-key") key_client.create_rsa_key(key_name) - # backup the vault container_uri = kwargs.pop("container_uri") backup_poller = client.begin_backup(container_uri, use_managed_identity=True) diff --git a/sdk/keyvault/azure-keyvault-administration/tests/test_backup_client_async.py b/sdk/keyvault/azure-keyvault-administration/tests/test_backup_client_async.py index 95c675901019..5bd3d48bbea7 100644 --- a/sdk/keyvault/azure-keyvault-administration/tests/test_backup_client_async.py +++ b/sdk/keyvault/azure-keyvault-administration/tests/test_backup_client_async.py @@ -19,9 +19,10 @@ class TestBackupClientTests(KeyVaultTestCase): def create_key_client(self, vault_uri, **kwargs): - from azure.keyvault.keys.aio import KeyClient - credential = self.get_credential(KeyClient, is_async=True) - return self.create_client_from_credential(KeyClient, credential=credential, vault_url=vault_uri, **kwargs ) + from azure.keyvault.keys.aio import KeyClient + + credential = self.get_credential(KeyClient, is_async=True) + return self.create_client_from_credential(KeyClient, credential=credential, vault_url=vault_uri, **kwargs) @pytest.mark.asyncio @pytest.mark.parametrize("api_version", only_default) @@ -114,7 +115,7 @@ async def test_backup_client_polling(self, client, **kwargs): # backup the vault container_uri = kwargs.pop("container_uri") backup_poller = await client.begin_backup(container_uri, use_managed_identity=True) - + # create a new poller from a continuation token token = backup_poller.continuation_token() rehydrated = await client.begin_backup(container_uri, use_managed_identity=True, continuation_token=token) @@ -123,7 +124,7 @@ async def test_backup_client_polling(self, client, **kwargs): if self.is_live: assert backup_poller.status() == "InProgress" assert not backup_poller.done() or backup_poller.polling_method().finished() - #assert rehydrated.status() == "InProgress" + # assert rehydrated.status() == "InProgress" assert not rehydrated.done() or rehydrated.polling_method().finished() backup_operation = await backup_poller.result() @@ -150,7 +151,7 @@ async def test_backup_client_polling(self, client, **kwargs): if self.is_live: assert restore_poller.status() == "InProgress" assert not restore_poller.done() or restore_poller.polling_method().finished() - #assert rehydrated.status() == "InProgress" + # assert rehydrated.status() == "InProgress" assert not rehydrated.done() or rehydrated.polling_method().finished() await rehydrated.wait() diff --git a/sdk/keyvault/azure-keyvault-administration/tests/test_examples_administration.py b/sdk/keyvault/azure-keyvault-administration/tests/test_examples_administration.py index e51d0aa1da6b..8e27b1d71275 100644 --- a/sdk/keyvault/azure-keyvault-administration/tests/test_examples_administration.py +++ b/sdk/keyvault/azure-keyvault-administration/tests/test_examples_administration.py @@ -18,8 +18,9 @@ class TestExamplesTests(KeyVaultTestCase): def create_key_client(self, vault_uri, **kwargs): from azure.keyvault.keys import KeyClient + credential = self.get_credential(KeyClient) - return self.create_client_from_credential(KeyClient, credential=credential, vault_url=vault_uri, **kwargs ) + return self.create_client_from_credential(KeyClient, credential=credential, vault_url=vault_uri, **kwargs) @pytest.mark.parametrize("api_version", only_default) @KeyVaultBackupClientPreparer() @@ -60,7 +61,7 @@ def test_example_backup_and_restore(self, client, **kwargs): @pytest.mark.parametrize("api_version", only_default) @KeyVaultBackupClientPreparer() @recorded_by_proxy - def test_example_selective_key_restore(self, client,**kwargs): + def test_example_selective_key_restore(self, client, **kwargs): set_bodiless_matcher() # create a key to selectively restore managed_hsm_url = kwargs.pop("managed_hsm_url") diff --git a/sdk/keyvault/azure-keyvault-administration/tests/test_examples_administration_async.py b/sdk/keyvault/azure-keyvault-administration/tests/test_examples_administration_async.py index fb5046f8b2a4..d8ee3fde9b9d 100644 --- a/sdk/keyvault/azure-keyvault-administration/tests/test_examples_administration_async.py +++ b/sdk/keyvault/azure-keyvault-administration/tests/test_examples_administration_async.py @@ -19,8 +19,9 @@ class TestExamplesTests(KeyVaultTestCase): def create_key_client(self, vault_uri, **kwargs): from azure.keyvault.keys.aio import KeyClient + credential = self.get_credential(KeyClient, is_async=True) - return self.create_client_from_credential(KeyClient, credential=credential, vault_url=vault_uri, **kwargs ) + return self.create_client_from_credential(KeyClient, credential=credential, vault_url=vault_uri, **kwargs) @pytest.mark.asyncio @pytest.mark.parametrize("api_version", only_default) diff --git a/sdk/keyvault/azure-keyvault-administration/tsp-location.yaml b/sdk/keyvault/azure-keyvault-administration/tsp-location.yaml new file mode 100644 index 000000000000..e70d181e7b9c --- /dev/null +++ b/sdk/keyvault/azure-keyvault-administration/tsp-location.yaml @@ -0,0 +1,8 @@ +directory: specification/keyvault/Security.KeyVault.Administration +commit: 2d9a495c439ab16c8e3b19c67bdf59ab8c4bd1a1 +repo: Azure/azure-rest-api-specs +additionalDirectories: +- specification/keyvault/Security.KeyVault.BackupRestore +- specification/keyvault/Security.KeyVault.Common +- specification/keyvault/Security.KeyVault.RBAC +- specification/keyvault/Security.KeyVault.Settings