Skip to content

Commit 0155fc6

Browse files
williexuderekbekoe
authored andcommitted
Storage soft-delete feature (#5515)
* rebased soft-delete work with latest cli and sdk updates * tests and history * re-recorded storage tests, fixes due to service changes, version, history * review feedback, remove test version constraint * re-recorded tests with new shell * new recording for blob incremental copy
1 parent 68b4d77 commit 0155fc6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+4329
-3740
lines changed

src/azure-cli-core/HISTORY.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ Release History
66
++++++
77
* auth: key on both subscription id and name on msi login
88
* Add events module in core for EVENT_INVOKER_PRE_CMD_TBL_TRUNCATE
9-
* Minor fixes
109

1110
2.0.26
1211
++++++

src/azure-cli-core/azure/cli/core/profiles/_shared.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def __init__(self, default_api_version, profile=None):
7979
ResourceType.MGMT_RESOURCE_POLICY: '2017-06-01-preview',
8080
ResourceType.MGMT_RESOURCE_RESOURCES: '2017-05-10',
8181
ResourceType.MGMT_RESOURCE_SUBSCRIPTIONS: '2016-06-01',
82-
ResourceType.DATA_STORAGE: '2017-04-17',
82+
ResourceType.DATA_STORAGE: '2017-07-29',
8383
ResourceType.DATA_COSMOS_TABLE: '2017-04-17'
8484
},
8585
'2017-03-09-profile': {

src/command_modules/azure-cli-storage/HISTORY.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Release History
55

66
2.0.25
77
++++++
8-
* Minor fixes.
8+
* Added `storage blob service-properties delete-policy` and `storage blob undelete` commands to enable soft-delete.
99

1010
2.0.24
1111
++++++

src/command_modules/azure-cli-storage/azure/cli/command_modules/storage/_help.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,7 @@
196196
short-summary: List blobs in a given container.
197197
parameters:
198198
- name: --include
199-
short-summary: 'Specifies additional datasets to include: (c)opy-info, (m)etadata, (s)napshots. Can be
200-
combined.'
199+
short-summary: 'Specifies additional datasets to include: (c)opy-info, (m)etadata, (s)napshots, (d)eleted-soft. Can be combined.'
201200
"""
202201

203202
helps['storage blob copy'] = """
@@ -225,6 +224,19 @@
225224
short-summary: Manage storage blob service properties.
226225
"""
227226

227+
helps['storage blob service-properties delete-policy'] = """
228+
type: group
229+
short-summary: Manage storage blob delete-policy service properties.
230+
"""
231+
helps['storage blob service-properties delete-policy show'] = """
232+
type: command
233+
short-summary: Show the storage blob delete-policy.
234+
"""
235+
helps['storage blob service-properties delete-policy update'] = """
236+
type: command
237+
short-summary: Update the storage blob delete-policy.
238+
"""
239+
228240
helps['storage blob set-tier'] = """
229241
type: command
230242
short-summary: Set the block or page tiers on the blob.

src/command_modules/azure-cli-storage/azure/cli/command_modules/storage/_params.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,11 @@ def load_arguments(self, _): # pylint: disable=too-many-locals, too-many-statem
220220
c.argument('tier', validator=blob_tier_validator)
221221
c.argument('timeout', type=int)
222222

223+
with self.argument_context('storage blob service-properties delete-policy update') as c:
224+
c.argument('enable', arg_type=get_enum_type(['true', 'false']), help='Enables/disables soft-delete.')
225+
c.argument('days_retained', type=int,
226+
help='Number of days that soft-deleted blob will be retained. Must be in range [1,365].')
227+
223228
with self.argument_context('storage blob upload') as c:
224229
from ._validators import page_blob_tier_validator
225230
from .sdkutil import get_blob_types, get_blob_tier_names

src/command_modules/azure-cli-storage/azure/cli/command_modules/storage/_validators.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -468,11 +468,11 @@ def validator(namespace):
468468
def validate_included_datasets(cmd, namespace):
469469
if namespace.include:
470470
include = namespace.include
471-
if set(include) - set('cms'):
472-
help_string = '(c)opy-info (m)etadata (s)napshots'
471+
if set(include) - set('cmsd'):
472+
help_string = '(c)opy-info (m)etadata (s)napshots (d)eleted'
473473
raise ValueError('valid values are {} or a combination thereof.'.format(help_string))
474474
t_blob_include = cmd.get_models('blob#Include')
475-
namespace.include = t_blob_include('s' in include, 'm' in include, False, 'c' in include)
475+
namespace.include = t_blob_include('s' in include, 'm' in include, False, 'c' in include, 'd' in include)
476476

477477

478478
def validate_key(namespace):

src/command_modules/azure-cli-storage/azure/cli/command_modules/storage/commands.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ def get_custom_sdk(custom_module, client_factory, resource_type=ResourceType.DAT
104104
g.storage_command('exists', 'exists', transform=create_boolean_result_output_transformer('exists'))
105105
g.storage_command('delete', 'delete_blob', transform=create_boolean_result_output_transformer('deleted'),
106106
table_transformer=transform_boolean_for_table)
107+
g.storage_command('undelete', 'undelete_blob', transform=create_boolean_result_output_transformer('undeleted'),
108+
table_transformer=transform_boolean_for_table, min_api='2017-07-29')
107109

108110
g.storage_custom_command('set-tier', 'set_blob_tier')
109111
g.storage_custom_command('upload', 'upload_blob',
@@ -139,6 +141,14 @@ def get_custom_sdk(custom_module, client_factory, resource_type=ResourceType.DAT
139141
min_api='2016-05-31') as g:
140142
g.storage_command('cancel', 'abort_copy_blob')
141143

144+
with self.command_group('storage blob service-properties delete-policy', command_type=base_blob_sdk,
145+
min_api='2017-07-29',
146+
custom_command_type=get_custom_sdk('blob', blob_data_service_factory)) as g:
147+
g.storage_command('show', 'get_blob_service_properties',
148+
transform=lambda x: getattr(x, 'delete_retention_policy', x),
149+
exception_handler=g.get_handler_suppress_404())
150+
g.storage_custom_command('update', 'set_delete_policy')
151+
142152
with self.command_group('storage blob service-properties', command_type=base_blob_sdk) as g:
143153
g.storage_command('show', 'get_blob_service_properties', exception_handler=g.get_handler_suppress_404())
144154

src/command_modules/azure-cli-storage/azure/cli/command_modules/storage/operations/blob.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,22 @@ def set_blob_tier(client, container_name, blob_name, tier, blob_type='block', ti
2727
raise ValueError('Blob tier is only applicable to block or page blob.')
2828

2929

30+
def set_delete_policy(client, enable=None, days_retained=None):
31+
policy = client.get_blob_service_properties().delete_retention_policy
32+
33+
if enable is not None:
34+
policy.enabled = enable == 'true'
35+
if days_retained is not None:
36+
policy.days = days_retained
37+
38+
if policy.enabled and not policy.days:
39+
from knack.util import CLIError
40+
raise CLIError("must specify days-retained")
41+
42+
client.set_blob_service_properties(delete_retention_policy=policy)
43+
return client.get_blob_service_properties().delete_retention_policy
44+
45+
3046
def storage_blob_copy_batch(cmd, client, source_client,
3147
destination_container=None, source_container=None, source_share=None,
3248
source_sas=None, pattern=None, dryrun=False):

src/command_modules/azure-cli-storage/azure/cli/command_modules/storage/tests/latest/recordings/test_create_account_sas.yaml

Lines changed: 50 additions & 51 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)