Skip to content

Commit 29a27ad

Browse files
committed
Immutable ltr backup
1 parent 4bc92d3 commit 29a27ad

File tree

6 files changed

+2453
-1883
lines changed

6 files changed

+2453
-1883
lines changed

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

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,7 +1313,8 @@ def _configure_security_policy_storage_params(arg_ctx):
13131313
'monthly_retention',
13141314
'yearly_retention',
13151315
'week_of_year',
1316-
'make_backups_immutable'])
1316+
'time_based_immutability',
1317+
'time_based_immutability_mode'])
13171318

13181319
c.argument('weekly_retention',
13191320
help='Retention for the weekly backup. '
@@ -1333,9 +1334,19 @@ def _configure_security_policy_storage_params(arg_ctx):
13331334
c.argument('week_of_year',
13341335
help='The Week of Year, 1 to 52, in which to take the yearly LTR backup.')
13351336

1336-
c.argument('make_backups_immutable',
1337-
help='Whether to make the LTR backups immutable.',
1338-
arg_type=get_three_state_flag())
1337+
c.argument('time_based_immutability',
1338+
help='Whether to make the LTR backups immutable.'
1339+
'Possible values are: \'Enabled\', \'Disabled\'.',
1340+
is_preview=True)
1341+
1342+
c.argument('time_based_immutability_mode',
1343+
help='The mode of time based immutability to be set on the LTR backups. '
1344+
'Possible values are: \'Locked\', \'Unlocked\'.',
1345+
is_preview=True)
1346+
1347+
c.argument('yes',
1348+
options_list=['--yes', '-y'],
1349+
help='Do not prompt for confirmation.', action='store_true')
13391350

13401351
with self.argument_context('sql db ltr-backup') as c:
13411352
c.argument('location_name',
@@ -1357,7 +1368,7 @@ def _configure_security_policy_storage_params(arg_ctx):
13571368
options_list=['--database', '-d'],
13581369
help='Name of the Azure SQL Database. '
13591370
'If specified (along with server name), retrieves all requested backups under this database.')
1360-
1371+
13611372
with self.argument_context('sql db ltr-backup list') as c:
13621373
c.argument('database_state',
13631374
required=False,
@@ -1408,7 +1419,7 @@ def _configure_security_policy_storage_params(arg_ctx):
14081419

14091420
c.argument('federated_client_id',
14101421
arg_type=database_federated_client_id_param_type)
1411-
1422+
14121423
###############################################
14131424
# sql db geo-backup #
14141425
###############################################

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,10 @@ def load_command_table(self, _):
348348
g.show_command('show', 'get')
349349
g.custom_command('list', 'list_long_term_retention_backups')
350350
g.command('delete', 'begin_delete', confirmation=True)
351+
g.custom_command('remove-time-based-immutability', 'remove_time_based_immutability', confirmation = "Removing the time-based immutability has the effect of removing the immutability on the backup. The backup will continue to be available for the remainder of the configured duration as usual, without immutability. Are you sure you want to disable time-based immutability for the backup?", is_preview=True)
352+
g.custom_command('lock-time-based-immutability', 'lock_time_based_immutability', confirmation = "Locking the time-based immutability enforces immutability for the duration of the configured retention. This action cannot be reversed. Are you sure you want to lock time-based immutability for the backup?", is_preview=True)
353+
g.custom_command('enable-legal-hold-immutability', 'set_legal_hold_immutability', confirmation = "When you enable Legal hold immutability on the backup, the backup will not be deleted until the legal hold is removed, even if the retention for the backup expires. Are you sure you want to enable legal hold for the backup?", is_preview=True)
354+
g.custom_command('disable-legal-hold-immutability', 'remove_legal_hold_immutability', confirmation = "Are you sure you want to disable legal hold for the backup?", is_preview=True)
351355

352356
with self.command_group('sql db ltr-backup',
353357
database_operations,

src/azure-cli/azure/cli/command_modules/sql/custom.py

Lines changed: 238 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66
# pylint: disable=C0302
77
from enum import Enum
88
import calendar
9+
import argparse
910
from datetime import datetime
11+
import re
12+
from warnings import catch_warnings
1013
from dateutil.parser import parse
1114

1215
from azure.cli.core.util import (
@@ -3104,7 +3107,9 @@ def update_long_term_retention(
31043107
monthly_retention=None,
31053108
yearly_retention=None,
31063109
week_of_year=None,
3107-
make_backups_immutable=None,
3110+
time_based_immutability=None,
3111+
time_based_immutability_mode=None,
3112+
yes=None,
31083113
**kwargs):
31093114
'''
31103115
Updates long term retention for managed database
@@ -3115,12 +3120,21 @@ def update_long_term_retention(
31153120
if yearly_retention and not week_of_year:
31163121
raise CLIError('Please specify week of year for yearly retention.')
31173122

3118-
if make_backups_immutable:
3119-
confirmation = prompt_y_n("""Immutable LTR backups can't be changed or deleted.
3120-
You'll be charged for LTR backups for the full retention period.
3121-
Do you want to proceed?""")
3122-
if not confirmation:
3123-
return
3123+
if time_based_immutability and time_based_immutability.lower() == "enabled":
3124+
if not yes:
3125+
confirmation = prompt_y_n("""Immutable LTR backups can't be changed or deleted.
3126+
You'll be charged for LTR backups for the full retention period.
3127+
Do you want to proceed?""")
3128+
if not confirmation:
3129+
return
3130+
3131+
if time_based_immutability_mode:
3132+
if not time_based_immutability or time_based_immutability.lower() != "enabled":
3133+
raise CLIError('Time-based immutability mode can only be set if time-based immutability is enabled.')
3134+
if time_based_immutability_mode.lower() not in ['unlocked', 'locked']:
3135+
raise CLIError('Invalid value for time-based immutability mode. '
3136+
'Valid values are "unlocked" or "locked".')
3137+
31243138

31253139
kwargs['weekly_retention'] = weekly_retention
31263140

@@ -3130,7 +3144,8 @@ def update_long_term_retention(
31303144

31313145
kwargs['week_of_year'] = week_of_year
31323146

3133-
kwargs['make_backups_immutable'] = make_backups_immutable
3147+
kwargs['time_based_immutability'] = time_based_immutability
3148+
kwargs['time_based_immutability_mode'] = time_based_immutability_mode
31343149

31353150
policy = client.begin_create_or_update(
31363151
database_name=database_name,
@@ -3326,6 +3341,221 @@ def list_long_term_retention_backups(
33263341
return backups
33273342

33283343

3344+
def remove_time_based_immutability(
3345+
client,
3346+
location_name: str,
3347+
long_term_retention_server_name: str,
3348+
long_term_retention_database_name: str,
3349+
backup_name: str,
3350+
resource_group_name=None,
3351+
**kwargs):
3352+
'''
3353+
Removes time-based immutability for long term retention backups.
3354+
'''
3355+
3356+
if not long_term_retention_server_name or not long_term_retention_database_name or not backup_name:
3357+
raise CLIError('Please specify all required parameters: '
3358+
'location_name, long_term_retention_server_name, '
3359+
'long_term_retention_database_name, and backup_name.')
3360+
if resource_group_name:
3361+
try:
3362+
client.begin_remove_time_based_immutability_by_resource_group(
3363+
resource_group_name,
3364+
location_name,
3365+
long_term_retention_server_name,
3366+
long_term_retention_database_name,
3367+
backup_name,
3368+
**kwargs).wait()
3369+
except Exception as ex:
3370+
raise ex
3371+
return client.list_by_resource_group_database(
3372+
resource_group_name,
3373+
location_name,
3374+
long_term_retention_server_name,
3375+
long_term_retention_database_name,
3376+
backup_name,
3377+
**kwargs)
3378+
else:
3379+
try:
3380+
client.begin_remove_time_based_immutability(
3381+
location_name,
3382+
long_term_retention_server_name,
3383+
long_term_retention_database_name,
3384+
backup_name,
3385+
**kwargs).wait()
3386+
except Exception as ex:
3387+
raise ex
3388+
3389+
return client.get(
3390+
location_name,
3391+
long_term_retention_server_name,
3392+
long_term_retention_database_name,
3393+
backup_name,
3394+
**kwargs)
3395+
3396+
3397+
def lock_time_based_immutability(
3398+
client,
3399+
location_name: str,
3400+
long_term_retention_server_name: str,
3401+
long_term_retention_database_name: str,
3402+
backup_name: str,
3403+
resource_group_name=None,
3404+
**kwargs):
3405+
'''
3406+
Locks time-based immutability for long term retention backups.
3407+
'''
3408+
3409+
if not long_term_retention_server_name or not long_term_retention_database_name or not backup_name:
3410+
raise CLIError('Please specify all required parameters: '
3411+
'location_name, long_term_retention_server_name, '
3412+
'long_term_retention_database_name, and backup_name.')
3413+
3414+
if resource_group_name:
3415+
try:
3416+
client.begin_lock_time_based_immutability_by_resource_group(
3417+
resource_group_name,
3418+
location_name,
3419+
long_term_retention_server_name,
3420+
long_term_retention_database_name,
3421+
backup_name,
3422+
**kwargs).wait()
3423+
except Exception as ex:
3424+
raise ex
3425+
3426+
return client.list_by_resource_group_database(
3427+
resource_group_name,
3428+
location_name,
3429+
long_term_retention_server_name,
3430+
long_term_retention_database_name,
3431+
backup_name,
3432+
**kwargs)
3433+
else:
3434+
try:
3435+
client.begin_lock_time_based_immutability(
3436+
location_name,
3437+
long_term_retention_server_name,
3438+
long_term_retention_database_name,
3439+
backup_name,
3440+
**kwargs).wait()
3441+
except Exception as ex:
3442+
raise ex
3443+
3444+
return client.get(
3445+
location_name,
3446+
long_term_retention_server_name,
3447+
long_term_retention_database_name,
3448+
backup_name,
3449+
**kwargs)
3450+
3451+
3452+
def set_legal_hold_immutability(
3453+
client,
3454+
location_name: str,
3455+
long_term_retention_server_name: str,
3456+
long_term_retention_database_name: str,
3457+
backup_name: str,
3458+
resource_group_name=None,
3459+
**kwargs):
3460+
'''
3461+
Sets legal hold immutability for long term retention backups.
3462+
'''
3463+
3464+
if not long_term_retention_server_name or not long_term_retention_database_name or not backup_name:
3465+
raise CLIError('Please specify all required parameters: '
3466+
'location_name, long_term_retention_server_name, '
3467+
'long_term_retention_database_name, and backup_name.')
3468+
if resource_group_name:
3469+
try:
3470+
client.begin_set_legal_hold_immutability_by_resource_group(
3471+
resource_group_name,
3472+
location_name,
3473+
long_term_retention_server_name,
3474+
long_term_retention_database_name,
3475+
backup_name,
3476+
**kwargs).wait()
3477+
except Exception as ex:
3478+
raise ex
3479+
3480+
return client.list_by_resource_group_database(
3481+
resource_group_name,
3482+
location_name,
3483+
long_term_retention_server_name,
3484+
long_term_retention_database_name,
3485+
backup_name,
3486+
**kwargs)
3487+
else:
3488+
try:
3489+
client.begin_set_legal_hold_immutability(
3490+
location_name,
3491+
long_term_retention_server_name,
3492+
long_term_retention_database_name,
3493+
backup_name,
3494+
**kwargs).wait()
3495+
except Exception as ex:
3496+
raise ex
3497+
3498+
return client.get(
3499+
location_name,
3500+
long_term_retention_server_name,
3501+
long_term_retention_database_name,
3502+
backup_name,
3503+
**kwargs)
3504+
3505+
3506+
def remove_legal_hold_immutability(
3507+
client,
3508+
location_name: str,
3509+
long_term_retention_server_name: str,
3510+
long_term_retention_database_name: str,
3511+
backup_name: str,
3512+
resource_group_name=None,
3513+
**kwargs):
3514+
'''
3515+
Removes legal hold immutability for long term retention backups.
3516+
'''
3517+
3518+
if not long_term_retention_server_name or not long_term_retention_database_name or not backup_name:
3519+
raise CLIError('Please specify all required parameters: '
3520+
'location_name, long_term_retention_server_name, '
3521+
'long_term_retention_database_name, and backup_name.')
3522+
if resource_group_name:
3523+
try:
3524+
client.begin_remove_legal_hold_immutability_by_resource_group(
3525+
resource_group_name,
3526+
location_name,
3527+
long_term_retention_server_name,
3528+
long_term_retention_database_name,
3529+
backup_name,
3530+
**kwargs).wait()
3531+
except Exception as ex:
3532+
raise ex
3533+
return client.list_by_resource_group_database(
3534+
resource_group_name,
3535+
location_name,
3536+
long_term_retention_server_name,
3537+
long_term_retention_database_name,
3538+
backup_name,
3539+
**kwargs)
3540+
3541+
else:
3542+
try:
3543+
client.begin_remove_legal_hold_immutability(
3544+
location_name,
3545+
long_term_retention_server_name,
3546+
long_term_retention_database_name,
3547+
backup_name,
3548+
**kwargs).wait()
3549+
except Exception as ex:
3550+
raise ex
3551+
return client.get(
3552+
location_name,
3553+
long_term_retention_server_name,
3554+
long_term_retention_database_name,
3555+
backup_name,
3556+
**kwargs)
3557+
3558+
33293559
def restore_long_term_retention_backup(
33303560
cmd,
33313561
client,

0 commit comments

Comments
 (0)