22# Copyright (c) Microsoft Corporation.
33# Licensed under the MIT License.
44# ------------------------------------
5+ import base64
56import functools
7+ import pickle
68from typing import TYPE_CHECKING
79
8- from azure .core .polling .base_polling import LROBasePolling
10+ from six import raise_from
11+ from six .moves .urllib_parse import urlparse
912
1013from ._models import KeyVaultBackupOperation
1114from ._internal import KeyVaultClientBase , parse_folder_url
12- from ._internal .polling import KeyVaultBackupClientPolling
15+ from ._internal .polling import KeyVaultBackupClientPolling , KeyVaultBackupClientPollingMethod
1316
1417if TYPE_CHECKING :
1518 # pylint:disable=unused-import
1619 from typing import Any
1720 from azure .core .polling import LROPoller
1821
1922
23+ def _parse_status_url (url ):
24+ parsed = urlparse (url )
25+ job_id = parsed .path .split ("/" )[2 ]
26+ return job_id
27+
28+
2029class KeyVaultBackupClient (KeyVaultClientBase ):
2130 """Performs Key Vault backup and restore operations.
2231
@@ -37,15 +46,48 @@ def begin_backup(self, blob_storage_url, sas_token, **kwargs):
3746 :returns: An :class:`~azure.core.polling.LROPoller` instance. Call `result()` on this object to wait for the
3847 operation to complete and get a :class:`KeyVaultBackupOperation`.
3948 :rtype: ~azure.core.polling.LROPoller[~azure.keyvault.administration.KeyVaultBackupOperation]
49+
50+ Example:
51+ .. literalinclude:: ../tests/test_examples_administration.py
52+ :start-after: [START begin_backup]
53+ :end-before: [END begin_backup]
54+ :language: python
55+ :caption: Create a vault backup
56+ :dedent: 8
4057 """
4158 polling_interval = kwargs .pop ("_polling_interval" , 5 )
4259 sas_parameter = self ._models .SASTokenParameter (storage_resource_uri = blob_storage_url , token = sas_token )
60+
61+ continuation_token = kwargs .pop ("continuation_token" , None )
62+ status_response = None
63+ if continuation_token :
64+ status_url = base64 .b64decode (continuation_token .encode ()).decode ("ascii" )
65+ try :
66+ job_id = _parse_status_url (status_url )
67+ except Exception as ex : # pylint: disable=broad-except
68+ raise_from (
69+ ValueError (
70+ "The provided continuation_token is malformed. A valid token can be obtained from the "
71+ + "operation poller's continuation_token() method"
72+ ),
73+ ex ,
74+ )
75+
76+ pipeline_response = self ._client .full_backup_status (
77+ vault_base_url = self ._vault_url , job_id = job_id , cls = lambda pipeline_response , _ , __ : pipeline_response
78+ )
79+ if "azure-asyncoperation" not in pipeline_response .http_response .headers :
80+ pipeline_response .http_response .headers ["azure-asyncoperation" ] = status_url
81+ status_response = base64 .b64encode (pickle .dumps (pipeline_response )).decode ("ascii" )
82+
4383 return self ._client .begin_full_backup (
4484 vault_base_url = self ._vault_url ,
4585 azure_storage_blob_container_uri = sas_parameter ,
4686 cls = KeyVaultBackupOperation ._from_generated ,
47- continuation_token = kwargs .pop ("continuation_token" , None ),
48- polling = LROBasePolling (lro_algorithms = [KeyVaultBackupClientPolling ()], timeout = polling_interval , ** kwargs ),
87+ continuation_token = status_response ,
88+ polling = KeyVaultBackupClientPollingMethod (
89+ lro_algorithms = [KeyVaultBackupClientPolling ()], timeout = polling_interval , ** kwargs
90+ ),
4991 ** kwargs
5092 )
5193
@@ -62,14 +104,50 @@ def begin_restore(self, folder_url, sas_token, **kwargs):
62104 :keyword str continuation_token: a continuation token to restart polling from a saved state
63105 :keyword str key_name: name of a single key in the backup. When set, only this key will be restored.
64106 :rtype: ~azure.core.polling.LROPoller
107+
108+ Examples:
109+ .. literalinclude:: ../tests/test_examples_administration.py
110+ :start-after: [START begin_restore]
111+ :end-before: [END begin_restore]
112+ :language: python
113+ :caption: Restore a vault backup
114+ :dedent: 8
115+
116+ .. literalinclude:: ../tests/test_examples_administration.py
117+ :start-after: [START begin_selective_restore]
118+ :end-before: [END begin_selective_restore]
119+ :language: python
120+ :caption: Restore a single key
121+ :dedent: 8
65122 """
66123 # LROBasePolling passes its kwargs to pipeline.run(), so we remove unexpected args before constructing it
67124 continuation_token = kwargs .pop ("continuation_token" , None )
68125 key_name = kwargs .pop ("key_name" , None )
69126
127+ status_response = None
128+ if continuation_token :
129+ status_url = base64 .b64decode (continuation_token .encode ()).decode ("ascii" )
130+ try :
131+ job_id = _parse_status_url (status_url )
132+ except Exception as ex : # pylint: disable=broad-except
133+ raise_from (
134+ ValueError (
135+ "The provided continuation_token is malformed. A valid token can be obtained from the "
136+ + "operation poller's continuation_token() method"
137+ ),
138+ ex ,
139+ )
140+
141+ pipeline_response = self ._client .restore_status (
142+ vault_base_url = self ._vault_url , job_id = job_id , cls = lambda pipeline_response , _ , __ : pipeline_response
143+ )
144+ if "azure-asyncoperation" not in pipeline_response .http_response .headers :
145+ pipeline_response .http_response .headers ["azure-asyncoperation" ] = status_url
146+ status_response = base64 .b64encode (pickle .dumps (pipeline_response )).decode ("ascii" )
147+
70148 container_url , folder_name = parse_folder_url (folder_url )
71149 sas_parameter = self ._models .SASTokenParameter (storage_resource_uri = container_url , token = sas_token )
72- polling = LROBasePolling (
150+ polling = KeyVaultBackupClientPollingMethod (
73151 lro_algorithms = [KeyVaultBackupClientPolling ()], timeout = kwargs .pop ("_polling_interval" , 5 ), ** kwargs
74152 )
75153
@@ -88,7 +166,7 @@ def begin_restore(self, folder_url, sas_token, **kwargs):
88166 vault_base_url = self ._vault_url ,
89167 restore_blob_details = restore_details ,
90168 cls = lambda * _ : None , # poller.result() returns None
91- continuation_token = continuation_token ,
169+ continuation_token = status_response ,
92170 polling = polling ,
93171 ** kwargs
94172 )
0 commit comments