Skip to content
Merged
2 changes: 2 additions & 0 deletions src/azure-cli/azure/cli/command_modules/sql/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,8 @@
text: az sql mi create -g mygroup -n myinstance -l mylocation -i -u myusername -p mypassword --license-type LicenseIncluded --subnet /subscriptions/{SubID}/resourceGroups/{ResourceGroup}/providers/Microsoft.Network/virtualNetworks/{VNETName}/subnets/{SubnetName} --capacity 8 --storage 32GB --edition GeneralPurpose --family Gen5
- name: Create managed instance with specified parameters and tags
text: az sql mi create -g mygroup -n myinstance -l mylocation -i -u myusername -p mypassword --license-type LicenseIncluded --subnet /subscriptions/{SubID}/resourceGroups/{ResourceGroup}/providers/Microsoft.Network/virtualNetworks/{VNETName}/subnets/{SubnetName} --capacity 8 --storage 32GB --edition GeneralPurpose --family Gen5 --tags tagName1=tagValue1 tagName2=tagValue2
- name: Create managed instance with specified parameters and backup storage redundancy specified
text: az sql mi create -g mygroup -n myinstance -l mylocation -i -u myusername -p mypassword --license-type LicenseIncluded --subnet /subscriptions/{SubID}/resourceGroups/{ResourceGroup}/providers/Microsoft.Network/virtualNetworks/{VNETName}/subnets/{SubnetName} --capacity 8 --storage 32GB --edition GeneralPurpose --family Gen5 --backup-storage-redundancy Local
"""

helps['sql mi delete'] = """
Expand Down
41 changes: 33 additions & 8 deletions src/azure-cli/azure/cli/command_modules/sql/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,15 @@
Database,
ElasticPool,
ElasticPoolPerDatabaseSettings,
ImportExtensionRequest,
ExportRequest,
ImportExistingDatabaseDefinition,
ExportDatabaseDefinition,
InstancePool,
ManagedDatabase,
ManagedInstance,
ManagedInstanceAdministrator,
Server,
ServerAzureADAdministrator,
Sku,
AuthenticationType,
BlobAuditingPolicyState,
CatalogCollationType,
CreateMode,
Expand Down Expand Up @@ -59,12 +58,14 @@
ElasticPoolCapabilitiesAdditionalDetails,
FailoverPolicyType,
SqlServerMinimalTlsVersionType,
SqlManagedInstanceMinimalTlsVersionType
SqlManagedInstanceMinimalTlsVersionType,
AuthenticationType
)

from ._validators import (
create_args_for_complex_type,
validate_managed_instance_storage_size,
validate_managed_instance_backup_storage_redundancy,
validate_subnet
)

Expand Down Expand Up @@ -103,6 +104,13 @@ def __repr__(self):
', '.join(sorted(self.unit_map, key=self.unit_map.__getitem__)))


def get_internal_backup_storage_redundancy(self):
return {
'Local': 'LRS',
'Zone': 'ZRS',
'Geo': 'GRS',
}.get(self, 'Invalid')

#####
# Reusable param type definitions
#####
Expand Down Expand Up @@ -209,6 +217,12 @@ def get_location_type_with_default_from_resource_group(cli_ctx):
help='The storage size. If no unit is specified, defaults to gigabytes (GB).',
validator=validate_managed_instance_storage_size)

backup_storage_redundancy_param_type = CLIArgumentType(
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)

grace_period_param_type = CLIArgumentType(
help='Interval in hours before automatic failover is initiated '
'if an outage occurs on the primary server. '
Expand Down Expand Up @@ -622,9 +636,9 @@ def load_arguments(self, _):
c.argument('max_size_bytes', help='The new maximum size of the database expressed in bytes.')

with self.argument_context('sql db export') as c:
# Create args that will be used to build up the ExportRequest object
# Create args that will be used to build up the ExportDatabaseDefinition object
create_args_for_complex_type(
c, 'parameters', ExportRequest, [
c, 'parameters', ExportDatabaseDefinition, [
'administrator_login',
'administrator_login_password',
'authentication_type',
Expand All @@ -647,8 +661,8 @@ def load_arguments(self, _):
arg_type=get_enum_type(StorageKeyType))

with self.argument_context('sql db import') as c:
# Create args that will be used to build up the ImportExtensionRequest object
create_args_for_complex_type(c, 'parameters', ImportExtensionRequest, [
# Create args that will be used to build up the ImportExistingDatabaseDefinition object
create_args_for_complex_type(c, 'parameters', ImportExistingDatabaseDefinition, [
'administrator_login',
'administrator_login_password',
'authentication_type',
Expand Down Expand Up @@ -1502,6 +1516,8 @@ def _configure_security_policy_storage_params(arg_ctx):
'public_data_endpoint_enabled',
'timezone_id',
'tags',
'storage_account_type',
'yes'
])

# Create args that will be used to build up the Managed Instance's Sku object
Expand Down Expand Up @@ -1538,6 +1554,15 @@ def _configure_security_policy_storage_params(arg_ctx):
help='Generate and assign an Azure Active Directory Identity for this managed instance '
'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')

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

with self.argument_context('sql mi update') as c:
# Create args that will be used to build up the ManagedInstance object
create_args_for_complex_type(
Expand Down
4 changes: 4 additions & 0 deletions src/azure-cli/azure/cli/command_modules/sql/_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ def get_sql_databases_operations(cli_ctx, _):
return get_sql_management_client(cli_ctx).databases


def get_sql_import_export_operations(cli_ctx, _):
return get_sql_management_client(cli_ctx).import_export


def get_sql_database_operations_operations(cli_ctx, _):
return get_sql_management_client(cli_ctx).database_operations

Expand Down
9 changes: 9 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 @@ -124,3 +124,12 @@ def validate_managed_instance_storage_size(namespace):
pass
else:
raise CLIError('incorrect usage: --storage must be specified in increments of 32 GB')


def validate_managed_instance_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')
15 changes: 13 additions & 2 deletions src/azure-cli/azure/cli/command_modules/sql/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@
get_sql_subscription_usages_operations,
get_sql_virtual_clusters_operations,
get_sql_virtual_network_rules_operations,
get_sql_instance_failover_groups_operations
get_sql_instance_failover_groups_operations,
get_sql_import_export_operations
)

from ._validators import (
Expand Down Expand Up @@ -101,6 +102,10 @@ def load_command_table(self, _):
operations_tmpl='azure.mgmt.sql.operations#DatabasesOperations.{}',
client_factory=get_sql_databases_operations)

import_export_operations = CliCommandType(
operations_tmpl='azure.mgmt.sql.operations#ImportExportOperations.{}',
client_factory=get_sql_import_export_operations)

database_lro_transform = LongRunningOperationResultTransform(
self.cli_ctx, db_transform)

Expand Down Expand Up @@ -137,9 +142,15 @@ def load_command_table(self, _):
supports_no_wait=True,
transform=database_lro_transform,
table_transformer=db_table_format)
g.custom_command('import', 'db_import')

g.custom_command('export', 'db_export')

with self.command_group('sql db',
import_export_operations,
client_factory=get_sql_import_export_operations) as g:

g.custom_command('import', 'db_import')

capabilities_operations = CliCommandType(
operations_tmpl='azure.mgmt.sql.operations#CapabilitiesOperations.{}',
client_factory=get_sql_capabilities_operations)
Expand Down
45 changes: 43 additions & 2 deletions src/azure-cli/azure/cli/command_modules/sql/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
CapabilityGroup,
CapabilityStatus,
CreateMode,
DatabaseEdition,
FailoverGroup,
FailoverGroupReadOnlyEndpoint,
FailoverGroupReadWriteEndpoint,
Expand All @@ -45,6 +44,7 @@
)

from knack.log import get_logger
from knack.prompting import prompt_y_n

from ._util import (
get_sql_capabilities_operations,
Expand Down Expand Up @@ -462,6 +462,30 @@ class ComputeModelType(str, Enum):
serverless = "Serverless"


class DatabaseEdition(str, Enum):

web = "Web"
business = "Business"
basic = "Basic"
standard = "Standard"
premium = "Premium"
premium_rs = "PremiumRS"
free = "Free"
stretch = "Stretch"
data_warehouse = "DataWarehouse"
system = "System"
system2 = "System2"
general_purpose = "GeneralPurpose"
business_critical = "BusinessCritical"
hyperscale = "Hyperscale"


class AuthenticationType(str, Enum):

sql = "SQL"
ad_password = "ADPassword"


def _get_server_dns_suffx(cli_ctx):
'''
Gets the DNS suffix for servers in this Azure environment.
Expand Down Expand Up @@ -1188,7 +1212,7 @@ def db_import(
kwargs['storage_key_type'] = storage_key_type
kwargs['storage_key'] = storage_key

return client.create_import_operation(
return client.import_method(
database_name=database_name,
server_name=server_name,
resource_group_name=resource_group_name,
Expand Down Expand Up @@ -2675,6 +2699,23 @@ def managed_instance_create(
kwargs['sku'] = _find_managed_instance_sku_from_capabilities(cmd.cli_ctx, kwargs['location'], sku)
kwargs['subnet_id'] = virtual_network_subnet_id

if not kwargs['yes'] and kwargs['location'].lower() in ['southeastasia', 'brazilsouth', 'eastasia']:
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.
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.
Do you want to proceed?""")
if not confirmation:
return

# Create
return client.create_or_update(
managed_instance_name=managed_instance_name,
Expand Down
Loading