Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -324,5 +324,4 @@ def resource_client_factory(cli_ctx, **_):


def network_client_factory(cli_ctx):
from azure.mgmt.network import NetworkManagementClient
return get_mgmt_service_client(cli_ctx, NetworkManagementClient, api_version="2018-08-01")
return get_mgmt_service_client(cli_ctx, ResourceType.MGMT_NETWORK)
Comment on lines 326 to +327
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually you even don't need to define it here. network module already has the definition and you could just import it.

def network_client_factory(cli_ctx, **kwargs):
from azure.cli.core.profiles import ResourceType
from azure.cli.core.commands.client_factory import get_mgmt_service_client
return get_mgmt_service_client(cli_ctx, ResourceType.MGMT_NETWORK, **kwargs)

Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@

import random
from knack.log import get_logger
from msrest.paging import Paged

from azure.cli.core.commands import LongRunningOperation, _is_poller
from azure.cli.core.util import CLIError
from azure.mgmt.resource.resources.models import ResourceGroup
from ._client_factory import resource_client_factory
from ._client_factory import resource_client_factory, cf_mysql_flexible_location_capabilities, cf_postgres_flexible_location_capabilities

logger = get_logger(__name__)

Expand Down Expand Up @@ -154,6 +156,99 @@ def parse_maintenance_window(maintenance_window_string):
return None, None, None


def get_mysql_versions(sku_info, tier):
return _get_available_values(sku_info, 'versions', tier)


def get_mysql_skus(sku_info, tier):
return _get_available_values(sku_info, 'skus', tier)


def get_mysql_storage_size(sku_info, tier):
return _get_available_values(sku_info, 'storage_sizes', tier)


def get_mysql_backup_retention(sku_info, tier):
return _get_available_values(sku_info, 'backup_retention', tier)


def get_mysql_tiers(sku_info):
return list(sku_info.keys())


def get_postgres_versions(sku_info, tier):
return _get_available_values(sku_info, 'versions', tier)


def get_postgres_skus(sku_info, tier):
return _get_available_values(sku_info, 'skus', tier)


def get_postgres_storage_sizes(sku_info, tier):
return _get_available_values(sku_info, 'storage_sizes', tier)


def get_postgres_tiers(sku_info):
return list(sku_info.keys())


def get_postgres_list_skus_info(cmd, location):
list_skus_client = cf_postgres_flexible_location_capabilities(cmd.cli_ctx, '_')
list_skus_result = list_skus_client.execute(location)
return _parse_list_skus(list_skus_result, 'postgres')


def get_mysql_list_skus_info(cmd, location):
list_skus_client = cf_mysql_flexible_location_capabilities(cmd.cli_ctx, '_')
list_skus_result = list_skus_client.list(location)
return _parse_list_skus(list_skus_result, 'mysql')


def _parse_list_skus(result, database_engine):
result = _get_list_from_paged_response(result)
if not result:
raise CLIError("No available SKUs in this location")

tiers = result[0].supported_flexible_server_editions
tiers_dict = {}
for tier_info in tiers:
tier_name = tier_info.name
tier_dict = {}

skus = set()
versions = set()
for version in tier_info.supported_server_versions:
versions.add(version.name)
for vcores in version.supported_vcores:
skus.add(vcores.name)
tier_dict["skus"] = skus
tier_dict["versions"] = versions

storage_info = tier_info.supported_storage_editions[0]
if database_engine == 'mysql':
tier_dict["backup_retention"] = (storage_info.min_backup_retention_days, storage_info.max_backup_retention_days)
tier_dict["storage_sizes"] = (int(storage_info.min_storage_size.storage_size_mb) // 1024,
int(storage_info.max_storage_size.storage_size_mb) // 1024)
elif database_engine == 'postgres':
storage_sizes = set()
for size in storage_info.supported_storage_mb:
storage_sizes.add(int(size.storage_size_mb // 1024))
tier_dict["storage_sizes"] = storage_sizes

tiers_dict[tier_name] = tier_dict

return tiers_dict


def _get_available_values(sku_info, argument, tier=None):
result = {key: val[argument] for key, val in sku_info.items()}
return result[tier]


def _get_list_from_paged_response(obj_list):
return list(obj_list) if isinstance(obj_list, Paged) else obj_list


def _update_location(cmd, resource_group_name):
resource_client = resource_client_factory(cmd.cli_ctx)
rg = resource_client.resource_groups.get(resource_group_name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,6 @@
examples:
- name: Delete a flexible server.
text: az mysql flexible-server delete --resource-group testGroup --name testServer
- name: Delete a flexible server without prompt or confirmation.
text: az mysql flexible-server delete --resource-group testGroup --name testServer --force
"""

helps['mysql flexible-server firewall-rule'] = """
Expand Down
55 changes: 25 additions & 30 deletions src/azure-cli/azure/cli/command_modules/rdbms/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
resource_group_name_type,
get_three_state_flag)
from azure.cli.command_modules.rdbms.validators import configuration_value_validator, validate_subnet, \
retention_validator, tls_validator, public_access_validator, pg_storage_validator, mysql_storage_validator, tier_validator, \
pg_sku_name_validator, pg_version_validator, mysql_version_validator, maintenance_window_validator, ip_address_validator
tls_validator, public_access_validator, maintenance_window_validator, ip_address_validator, retention_validator
from azure.cli.core.commands.validators import get_default_location_from_resource_group
from azure.cli.core.local_context import LocalContextAttribute, LocalContextAction

Expand Down Expand Up @@ -229,24 +228,29 @@ def _flexible_server_params(command_group):
with self.argument_context('{} flexible-server create'.format(command_group)) as c:
# Add create mode as a parameter
if command_group == 'postgres':
c.argument('tier', default='GeneralPurpose', options_list=['--tier'], validator=tier_validator,
c.argument('tier', default='GeneralPurpose', options_list=['--tier'],
help='Compute tier of the server. Accepted values: Burstable, GeneralPurpose, Memory Optimized ')
c.argument('sku_name', default='Standard_D2s_v3', options_list=['--sku-name'], validator=pg_sku_name_validator,
c.argument('sku_name', default='Standard_D2s_v3', options_list=['--sku-name'],
help='The name of the compute SKU. Follows the convention Standard_{VM name}. Examples: Standard_D4s_v3 ')
c.argument('storage_mb', default='128', options_list=['--storage-size'], type=int, validator=pg_storage_validator,
c.argument('storage_mb', default='128', options_list=['--storage-size'], type=int,
help='The storage capacity of the server. Minimum is 32 GiB and max is 16 TiB.')
c.argument('version', default='12', options_list=['--version'], validator=pg_version_validator,
c.argument('backup_retention', default=7, type=int, options_list=['--backup-retention'],
help='The number of days a backup is retained. Range of 7 to 35 days. Default is 7 days.',
validator=retention_validator)
c.argument('version', default='12', options_list=['--version'],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quick question: how can user know which kind of version is accepted?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

quick question: how can user know which kind of version is accepted?

Do you mean how they can find out which are the valid versions ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If they pass in a wrong value, they will get a Validation error with the set of acceptable values.

help='Server major version.')
c.argument('zone', options_list=['--zone, -z'],
help='Availability zone into which to provision the resource.')
elif command_group == 'mysql':
c.argument('tier', default='Burstable',
help='Compute tier of the server. Accepted values: Burstable, GeneralPurpose, Memory Optimized ')
c.argument('sku_name', default='Standard_B1ms', options_list=['--sku-name'],
help='The name of the compute SKU. Follows the convention Standard_{VM name}. Examples: Standard_B1ms, Standard_D4s_v3 ')
c.argument('storage_mb', default='10', options_list=['--storage-size'], type=int, validator=mysql_storage_validator,
help='The name of the compute SKU. Follows the convention Standard_{VM name}. Examples: Standard_B1ms, Standard_E16ds_v4 ')
c.argument('storage_mb', default='10', options_list=['--storage-size'], type=int,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
c.argument('storage_mb', default='10', options_list=['--storage-size'], type=int,
c.argument('storage_mb', default=10, options_list=['--storage-size'], type=int,

because it is int type.

help='The storage capacity of the server. Minimum is 5 GiB and increases in 1 GiB increments. Max is 16 TiB.')
c.argument('version', default='5.7', options_list=['--version'], validator=mysql_version_validator,
c.argument('backup_retention', default=7, type=int, options_list=['--backup-retention'],
help='The number of days a backup is retained. Range of 7 to 35 days. Default is 7 days.')
c.argument('version', default='5.7', options_list=['--version'],
help='Server major version.')
c.argument('zone', options_list=['--zone, -z'],
help='Availability zone into which to provision the resource.')
Expand All @@ -263,9 +267,6 @@ def _flexible_server_params(command_group):
c.argument('administrator_login_password', options_list=['--admin-password', '-p'],
help='The password of the administrator. Minimum 8 characters and maximum 128 characters. Password must contain characters from three of the following categories: English uppercase letters, English lowercase letters, numbers, and non-alphanumeric characters.',
arg_group='Authentication')
c.argument('backup_retention', default=7, type=int, options_list=['--backup-retention'],
help='The number of days a backup is retained. Range of 7 to 35 days. Default is 7 days.',
validator=retention_validator)
c.argument('tags', tags_type)
c.argument('public_access', options_list=['--public-access'],
help='Determines the public access. Enter single or range of IP addresses to be included in the allowed list of IPs. IP address ranges must be dash-separated and not contain any spaces. Specifying 0.0.0.0 allows public access from any resources deployed within Azure to access your server. Specifying no IP address sets the server in public access mode but does not create a firewall rule. ',
Expand All @@ -290,8 +291,6 @@ def _flexible_server_params(command_group):

with self.argument_context('{} flexible-server update'.format(command_group)) as c:
c.ignore('assign_identity')
c.argument('backup_retention', type=int, options_list=['--backup-retention'],
help='The number of days a backup is retained. Range of 7 to 35 days. Default is 7 days.', validator=retention_validator)
c.argument('administrator_login_password', options_list=['--admin-password', '-p'],
help='The password of the administrator. Minimum 8 characters and maximum 128 characters. Password must contain characters from three of the following categories: English uppercase letters, English lowercase letters, numbers, and non-alphanumeric characters.',)
c.argument('ha_enabled', options_list=['--high-availability'], arg_type=get_enum_type(['Enabled', 'Disabled']),
Expand All @@ -301,12 +300,13 @@ def _flexible_server_params(command_group):
c.argument('tags', tags_type)
if command_group == 'mysql':
c.argument('tier', options_list=['--tier'],
help='Compute tier of the server. Accepted values: Burstable, GeneralPurpose, Memory Optimized ')
help='Compute tier of the server. Accepted values: Burstable, GeneralPurpose, Memory Optimized')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still prefer getting allowed value from SDK

c.argument('sku_name', options_list=['--sku-name'],
help='The name of the compute SKU. Follows the convention Standard_{VM name}. Examples: Standard_B1ms, Standard_D4s_v3 ')
help='The name of the compute SKU. Follows the convention Standard_{VM name}. Examples: Standard_B1ms, Standard_E16ds_v4 ')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same

c.argument('storage_mb', options_list=['--storage-size'], type=int,
validator=mysql_storage_validator,
help='The storage capacity of the server. Minimum is 5 GiB and increases in 1 GiB increments. Max is 16 TiB.')
c.argument('backup_retention', type=int, options_list=['--backup-retention'],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is to define the retention days but how could I enable/disable delete retention?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It cannot be disabled. By default it is 7 days. But user can pass a value and override the default value.

help='The number of days a backup is retained. Range of 7 to 35 days. Default is 7 days.')
c.argument('auto_grow', arg_type=get_enum_type(['Enabled', 'Disabled']), options_list=['--storage-auto-grow'],
help='Enable or disable autogrow of the storage. Default value is Enabled.')
c.argument('ssl_enforcement', arg_type=get_enum_type(['Enabled', 'Disabled']),
Expand All @@ -317,13 +317,14 @@ def _flexible_server_params(command_group):
c.argument('replication_role', options_list=['--replication-role'],
help='The replication role of the server.')
elif command_group == 'postgres':
c.argument('tier', options_list=['--tier'], validator=tier_validator,
help='Compute tier of the server. Accepted values: Burstable, GeneralPurpose, Memory Optimized ')
c.argument('sku_name', options_list=['--sku-name'], validator=pg_sku_name_validator,
c.argument('tier', options_list=['--tier'],
help='Compute tier of the server. Accepted values: Burstable, GeneralPurpose, Memory Optimized')
c.argument('sku_name', options_list=['--sku-name'],
help='The name of the compute SKU. Follows the convention Standard_{VM name}. Examples: Standard_D4s_v3 ')
c.argument('storage_mb', options_list=['--storage-size'], type=int,
validator=pg_storage_validator,
help='The storage capacity of the server. Minimum is 32 GiB and max is 16 TiB.')
c.argument('backup_retention', type=int, options_list=['--backup-retention'],
help='The number of days a backup is retained. Range of 7 to 35 days. Default is 7 days.', validator=retention_validator)
Comment on lines +320 to +327
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you have so many duplicate arguments. could you use CLIArgumentType to abstract them and reuse these type.


with self.argument_context('{} flexible-server list-skus'.format(command_group)) as c:
c.argument('location', arg_type=get_location_type(self.cli_ctx))
Expand Down Expand Up @@ -412,15 +413,9 @@ def _flexible_server_params(command_group):
with self.argument_context('{} flexible-server replica create'.format(command_group)) as c:
c.argument('source_server', options_list=['--source-server'],
help='The name or resource ID of the source server to restore from.')
if command_group == 'mysql':
c.argument('tier', options_list=['--tier'],
help='Compute tier of the server. Accepted values: Burstable, GeneralPurpose, Memory Optimized ')
c.argument('sku_name', options_list=['--sku-name'],
help='The name of the compute SKU. Follows the convention'
' Standard_{VM name}. Examples: Standard_B1ms, Standard_D4s_v3 ')
if command_group == 'postgres':
c.argument('tier', options_list=['--tier'], validator=tier_validator,
help='Compute tier of the server. Accepted values: Burstable, GeneralPurpose, Memory Optimized ')
c.ignore('location')
c.ignore('sku_name')
c.ignore('tier')
Comment on lines +416 to +418
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The three arguments are totally removed in existing command?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are not using these three args for the command currently


with self.argument_context('{} flexible-server replica stop-replication'.format(command_group)) as c:
c.argument('server_name', options_list=['--name', '-s'], help='Name of the server.')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def table_transform_output_list_sku(result):
for skus in skus_tiers:
tier_name = skus["name"]
try:
keys = skus["supportedServerVersions"][1]["supportedVcores"]
keys = skus["supportedServerVersions"][0]["supportedVcores"]
for key in keys:
new_entry = OrderedDict()
new_entry['SKU'] = key['name']
Expand Down
Loading