Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
03e6359
add support for backup storage redundancy param to create db
xaliciayang Sep 28, 2020
df9d641
add force, warnings, tests
xaliciayang Sep 29, 2020
15f9486
update location check for backup redundancy warnings
xaliciayang Sep 29, 2020
138d559
correct get location function usage
xaliciayang Sep 29, 2020
d7e0b8c
verified behavior
xaliciayang Sep 29, 2020
387da8c
Merge branch 'dev' into dbBackupStorage
xaliciayang Sep 30, 2020
13c076f
Update src/azure-cli/azure/cli/command_modules/sql/_help.py
xaliciayang Sep 30, 2020
479d002
consolidate backup storage redundancy ars
xaliciayang Sep 30, 2020
f0cbc36
test fixes
xaliciayang Sep 30, 2020
40845ba
Merge branch 'dbBackupStorage' of https://github.com/xaliciayang/azur…
xaliciayang Sep 30, 2020
f4b7da3
some updated records
xaliciayang Sep 30, 2020
67c8738
add allowed values for backup storage redundancy back in
xaliciayang Sep 30, 2020
2737eb1
Merge branch 'dev' into dbBackupStorage
xaliciayang Sep 30, 2020
72b052b
updated recordings and ltr restore param
xaliciayang Sep 30, 2020
aad78b6
Merge branch 'dbBackupStorage' of https://github.com/xaliciayang/azur…
xaliciayang Sep 30, 2020
0812359
added recordings
xaliciayang Sep 30, 2020
58a131c
update recording
xaliciayang Sep 30, 2020
6866c57
sensitivity recording
xaliciayang Sep 30, 2020
8a1c63f
add updated sensitivity recording
xaliciayang Oct 5, 2020
dcf4b07
fixed style
xaliciayang Oct 9, 2020
2cca5dc
replace sub
Juliehzl Oct 9, 2020
a05a8f8
Merge branch 'dbBackupStorage' of https://github.com/xaliciayang/azur…
Juliehzl Oct 9, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/azure-cli/azure/cli/command_modules/sql/_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,21 @@ def db_transform(result):
result.edition = result.sku.tier
result.elastic_pool_name = _last_segment(result.elastic_pool_id)

if hasattr(result, 'storage_account_type'):
result.backupStorageRedundancy = _get_external_backup_storage_redundancy(result.storage_account_type)
del result.storage_account_type

return result


def _get_external_backup_storage_redundancy(self):
return {
'lrs': 'Local',
'grs': 'Geo',
'zrs': 'Zone'
}.get(self.lower(), 'Invalid')


#####
# sql db table formatters
#####
Expand Down
13 changes: 12 additions & 1 deletion src/azure-cli/azure/cli/command_modules/sql/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@
text: az sql db copy -g mygroup -s myserver -n originalDb --dest-name newDb --service-objective S0
- name: Create a database with GeneralPurpose edition, Gen4 hardware, and 1 vcore as a copy of an existing GeneralPurpose database.
text: az sql db copy -g mygroup -s myserver -n originalDb --dest-name newDb -f Gen4 -c 1
- name: Create a database with local backup storage redundancy as a copy of an existing database
text: az sql db copy -g mygroup -s myserver -n originalDb --dest-name newDb --backup-storage-redundancy Local

"""

helps['sql db create'] = """
Expand All @@ -75,7 +78,8 @@
text: az sql db create -g mygroup -s myserver -n mydb -e GeneralPurpose -f Gen5 -c 2 --compute-model Serverless --auto-pause-delay 120
- name: Create a Hyperscale Gen5 2 vcore database with 2 read replicas
text: az sql db create -g mygroup -s myserver -n mydb -e Hyperscale -f Gen5 -c 2 --read-replicas 2

- name: Create a GeneralPurpose database with locally redundant backup storage
text: az sql db create -g mygroup -s myserver -n mydb -e GeneralPurpose --backup-storage-redundancy Local
"""

helps['sql db delete'] = """
Expand Down Expand Up @@ -267,6 +271,8 @@
text: az sql db replica create -g mygroup -s myserver -n originalDb --partner-server newDb --service-objective S0
- name: Create a database with GeneralPurpose edition, Gen4 hardware, and 1 vcore as a secondary replica of an existing GeneralPurpose database
text: az sql db replica create -g mygroup -s myserver -n originalDb --partner-server newDb -f Gen4 -c 1
- name: Create a database with with zone redundant backup storage as a secondary replica of an existing database.
text: az sql db replica create -g mygroup -s myserver -n originalDb --partner-server newDb --backup-storage-redundancy Zone
"""

helps['sql db replica delete-link'] = """
Expand Down Expand Up @@ -300,6 +306,9 @@
text: |
az sql db restore --dest-name MyDest --edition GeneralPurpose --name MyAzureSQLDatabase --resource-group MyResourceGroup --server myserver --subscription MySubscription --time "2018-05-20T05:34:22"
crafted: true
- name: Create a new database with geo-redundant backup storage by restoring from a backup. (autogenerated)
text: |
az sql db restore --dest-name MyDest --edition GeneralPurpose --name MyAzureSQLDatabase --resource-group MyResourceGroup --server myserver --subscription MySubscription --time "2018-05-20T05:34:22" --backup-storage-redundancy Geo
"""

helps['sql db show'] = """
Expand Down Expand Up @@ -383,6 +392,8 @@
text: az sql db update -g mygroup -s myserver -n mydb -z false
- name: Update database to serverless compute model
text: az sql db update -g mygroup -s myserver -n mydb --edition GeneralPurpose --capacity 2 --family Gen5 --compute-model Serverless
- name: Update database with locally redundant backup storage
text: az sql db update -g mygroup -s myserver -n mydb --backup-storage-redundancy Local

"""

Expand Down
41 changes: 35 additions & 6 deletions src/azure-cli/azure/cli/command_modules/sql/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
from ._validators import (
create_args_for_complex_type,
validate_managed_instance_storage_size,
validate_managed_instance_backup_storage_redundancy,
validate_backup_storage_redundancy,
validate_subnet
)

Expand Down Expand Up @@ -222,7 +222,7 @@ def get_location_type_with_default_from_resource_group(cli_ctx):
options_list=['--backup-storage-redundancy', '--bsr'],
type=get_internal_backup_storage_redundancy,
help='Backup storage redundancy used to store backups. Allowed values include: Local, Zone, Geo.',
validator=validate_managed_instance_backup_storage_redundancy)
validator=validate_backup_storage_redundancy)

grace_period_param_type = CLIArgumentType(
help='Interval in hours before automatic failover is initiated '
Expand Down Expand Up @@ -326,6 +326,9 @@ def _configure_db_dw_params(arg_ctx):
arg_ctx.argument('zone_redundant',
arg_type=zone_redundant_param_type)

arg_ctx.argument('storage_account_type',
arg_type=backup_storage_redundancy_param_type)


def _configure_db_dw_create_params(
arg_ctx,
Expand Down Expand Up @@ -415,7 +418,8 @@ def _configure_db_dw_create_params(
'min_capacity',
'compute_model',
'read_scale',
'read_replica_count'
'read_replica_count',
'storage_account_type'
])

# Create args that will be used to build up the Database's Sku object
Expand Down Expand Up @@ -539,6 +543,13 @@ def load_arguments(self, _):
with self.argument_context('sql db create') as c:
_configure_db_dw_create_params(c, Engine.db, CreateMode.default)

c.argument('storage_account_type',
arg_type=backup_storage_redundancy_param_type)

c.argument('yes',
options_list=['--yes', '-y'],
help='Do not prompt for confirmation.', action='store_true')

with self.argument_context('sql db copy') as c:
_configure_db_dw_create_params(c, Engine.db, CreateMode.copy)

Expand All @@ -555,6 +566,9 @@ def load_arguments(self, _):
help='Name of the server to create the copy in.'
' If unspecified, defaults to the origin server.')

c.argument('storage_account_type',
arg_type=backup_storage_redundancy_param_type)

with self.argument_context('sql db rename') as c:
c.argument('new_name',
help='The new name that the database will be renamed to.')
Expand Down Expand Up @@ -583,6 +597,9 @@ def load_arguments(self, _):
' Either --time or --deleted-time (or both) must be specified. ' +
time_format_help)

c.argument('storage_account_type',
arg_type=backup_storage_redundancy_param_type)

with self.argument_context('sql db show') as c:
# Service tier advisors and transparent data encryption are not included in the first batch
# of GA commands.
Expand Down Expand Up @@ -636,6 +653,9 @@ def load_arguments(self, _):

c.argument('max_size_bytes', help='The new maximum size of the database expressed in bytes.')

c.argument('storage_account_type',
arg_type=backup_storage_redundancy_param_type)

with self.argument_context('sql db export') as c:
# Create args that will be used to build up the ExportDatabaseDefinition object
create_args_for_complex_type(
Expand Down Expand Up @@ -754,6 +774,9 @@ def load_arguments(self, _):
options_list=['--partner-server'],
help='Name of the server to create the new replica in.')

c.argument('storage_account_type',
arg_type=backup_storage_redundancy_param_type)

with self.argument_context('sql db replica set-primary') as c:
c.argument('database_name',
help='Name of the database to fail over.')
Expand All @@ -780,6 +803,7 @@ def load_arguments(self, _):
# sql db audit-policy & threat-policy
#####
def _configure_security_policy_storage_params(arg_ctx):

storage_arg_group = 'Storage'

arg_ctx.argument('storage_account',
Expand Down Expand Up @@ -952,6 +976,10 @@ def _configure_security_policy_storage_params(arg_ctx):
help='The resource id of the long term retention backup to be restored. '
'Use \'az sql db ltr-backup show\' or \'az sql db ltr-backup list\' for backup id.')

c.argument('storage_account_type',
required=False,
arg_type=backup_storage_redundancy_param_type)

###############################################
# sql dw #
###############################################
Expand Down Expand Up @@ -1556,9 +1584,7 @@ def _configure_security_policy_storage_params(arg_ctx):
'for use with key management services like Azure KeyVault.')

c.argument('storage_account_type',
arg_type=backup_storage_redundancy_param_type,
options_list=['--backup-storage-redundancy', '--bsr'],
help='Backup storage redundancy used to store backups')
arg_type=backup_storage_redundancy_param_type)

c.argument('yes',
options_list=['--yes', '-y'],
Expand Down Expand Up @@ -1840,6 +1866,9 @@ def _configure_security_policy_storage_params(arg_ctx):
help='The resource id of the long term retention backup to be restored. '
'Use \'az sql midb ltr-backup show\' or \'az sql midb ltr-backup list\' for backup id.')

c.argument('storage_account_type',
arg_type=backup_storage_redundancy_param_type)

with self.argument_context('sql midb log-replay start') as c:
create_args_for_complex_type(
c, 'parameters', ManagedDatabase, [
Expand Down
13 changes: 13 additions & 0 deletions src/azure-cli/azure/cli/command_modules/sql/_validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,19 @@ def validate_subnet(cmd, namespace):
delattr(namespace, 'vnet_name')


###############################################
# sql db #
###############################################

def validate_backup_storage_redundancy(namespace):
# Validate if entered backup storage redundancy value is within allowed values
if (not namespace.storage_account_type or
(namespace.storage_account_type and namespace.storage_account_type in ['LRS', 'ZRS', 'GRS'])):
pass
else:
raise CLIError('incorrect usage: --backup-storage-redundancy must be either Local, Zone or Geo')


###############################################
# sql managed instance #
###############################################
Expand Down
93 changes: 90 additions & 3 deletions src/azure-cli/azure/cli/command_modules/sql/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -817,18 +817,61 @@ def _db_dw_create(
parameters=kwargs)


def _should_show_backup_storage_redundancy_warnings(target_db_location):
if target_db_location.lower() in ['southeastasia', 'brazilsouth', 'eastasia']:
return True
return False


def _backup_storage_redundancy_specify_geo_warning():
print("""Selected value for backup storage redundancy is geo-redundant storage.
Note that database backups will be geo-replicated to the paired region.
To learn more about Azure Paired Regions visit https://aka.ms/azure-ragrs-regions.""")


def _confirm_backup_storage_redundancy_take_geo_warning():
# if not storage_account_type:
confirmation = prompt_y_n("""You have not specified the value for backup storage redundancy
which will default to geo-redundant storage. Note that database backups will be geo-replicated
to the paired region. To learn more about Azure Paired Regions visit https://aka.ms/azure-ragrs-regions.
Do you want to proceed?""")
if not confirmation:
return False
return True


def _backup_storage_redundancy_take_source_warning():
print("""You have not specified the value for backup storage redundancy
which will default to source's backup storage redundancy.
To learn more about Azure Paired Regions visit https://aka.ms/azure-ragrs-regions.""")


def db_create(
cmd,
client,
database_name,
server_name,
resource_group_name,
no_wait=False,
yes=None,
**kwargs):
'''
Creates a DB (with 'Default' create mode.)
'''

# Check backup storage redundancy configurations
location = _get_server_location(
cmd.cli_ctx,
server_name=server_name,
resource_group_name=resource_group_name)

if not yes and _should_show_backup_storage_redundancy_warnings(location):
if not kwargs['storage_account_type']:
if not _confirm_backup_storage_redundancy_take_geo_warning():
return None
if kwargs['storage_account_type'] == 'GRS':
_backup_storage_redundancy_specify_geo_warning()

return _db_dw_create(
cmd.cli_ctx,
client,
Expand Down Expand Up @@ -885,6 +928,16 @@ def db_copy(
resource_group_name,
kwargs)

# Check backup storage redundancy configurations
location = _get_server_location(cmd.cli_ctx,
server_name=dest_server_name,
resource_group_name=dest_resource_group_name)
if _should_show_backup_storage_redundancy_warnings(location):
if not kwargs['storage_account_type']:
_backup_storage_redundancy_take_source_warning()
if kwargs['storage_account_type'] == 'GRS':
_backup_storage_redundancy_specify_geo_warning()

return _db_dw_create(
cmd.cli_ctx,
client,
Expand Down Expand Up @@ -927,6 +980,16 @@ def db_create_replica(
resource_group_name,
kwargs)

# Check backup storage redundancy configurations
location = _get_server_location(cmd.cli_ctx,
server_name=partner_server_name,
resource_group_name=partner_resource_group_name)
if _should_show_backup_storage_redundancy_warnings(location):
if not kwargs['storage_account_type']:
_backup_storage_redundancy_take_source_warning()
if kwargs['storage_account_type'] == 'GRS':
_backup_storage_redundancy_specify_geo_warning()

# Replica must have the same database name as the source db
return _db_dw_create(
cmd.cli_ctx,
Expand Down Expand Up @@ -994,6 +1057,14 @@ def db_restore(
kwargs['source_database_deletion_date'] = source_database_deletion_date
kwargs['create_mode'] = CreateMode.restore.value if is_deleted else CreateMode.point_in_time_restore.value

# Check backup storage redundancy configurations
location = _get_server_location(cmd.cli_ctx, server_name=server_name, resource_group_name=resource_group_name)
if _should_show_backup_storage_redundancy_warnings(location):
if not kwargs['storage_account_type']:
_backup_storage_redundancy_take_source_warning()
if kwargs['storage_account_type'] == 'GRS':
_backup_storage_redundancy_specify_geo_warning()

return _db_dw_create(
cmd.cli_ctx,
client,
Expand Down Expand Up @@ -1271,7 +1342,8 @@ def db_update(
read_replica_count=None,
min_capacity=None,
auto_pause_delay=None,
compute_model=None):
compute_model=None,
storage_account_type=None):
'''
Applies requested parameters to a db resource instance for a DB update.
'''
Expand All @@ -1280,6 +1352,12 @@ def db_update(
raise CLIError('Azure SQL Data Warehouse can be updated with the command'
' `az sql dw update`.')

# Check backup storage redundancy configuration
location = _get_server_location(cmd.cli_ctx, server_name=server_name, resource_group_name=resource_group_name)
if _should_show_backup_storage_redundancy_warnings(location):
if storage_account_type == 'GRS':
_backup_storage_redundancy_specify_geo_warning()

#####
# Set sku-related properties
#####
Expand Down Expand Up @@ -1768,6 +1846,7 @@ def restore_long_term_retention_backup(
target_database_name,
target_server_name,
target_resource_group_name,
storage_account_type,
**kwargs):
'''
Restores an existing database (i.e. create with 'RestoreLongTermRetentionBackup' create mode.)
Expand All @@ -1788,6 +1867,14 @@ def restore_long_term_retention_backup(

kwargs['create_mode'] = CreateMode.restore_long_term_retention_backup.value
kwargs['long_term_retention_backup_resource_id'] = long_term_retention_backup_resource_id
kwargs['storage_account_type'] = storage_account_type

# Check backup storage redundancy configurations
if _should_show_backup_storage_redundancy_warnings(kwargs['location']):
if not kwargs['storage_account_type']:
_backup_storage_redundancy_take_source_warning()
if kwargs['storage_account_type'] == 'GRS':
_backup_storage_redundancy_specify_geo_warning()

return client.create_or_update(
database_name=target_database_name,
Expand Down Expand Up @@ -2703,15 +2790,15 @@ def managed_instance_create(
if kwargs['storage_account_type'] == 'GRS':
confirmation = prompt_y_n("""Selected value for backup storage redundancy is geo-redundant storage.
Note that database backups will be geo-replicated to the paired region.
To learn more about Azure Paired Regions visit https://aka.ms/micreate-ragrs-regions.
To learn more about Azure Paired Regions visit https://aka.ms/azure-ragrs-regions.
Do you want to proceed?""")
if not confirmation:
return

if not kwargs['storage_account_type']:
confirmation = prompt_y_n("""You have not specified the value for backup storage redundancy
which will default to geo-redundant storage. Note that database backups will be geo-replicated
to the paired region. To learn more about Azure Paired Regions visit https://aka.ms/micreate-ragrs-regions.
to the paired region. To learn more about Azure Paired Regions visit https://aka.ms/azure-ragrs-regions.
Do you want to proceed?""")
if not confirmation:
return
Expand Down
Loading