Skip to content
Open
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
6 changes: 4 additions & 2 deletions src/azure-cli/azure/cli/command_modules/mysql/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from azure.cli.command_modules.mysql._validators import public_access_validator, maintenance_window_validator, ip_address_validator, \
firewall_rule_name_validator, validate_identity, validate_byok_identity, validate_identities, validate_action_name, validate_branch
from azure.cli.core.local_context import LocalContextAttribute, LocalContextAction
from ._util import get_current_time
from ._util import get_current_time, normalize_mysql_tier
from argcomplete.completers import FilesCompleter


Expand Down Expand Up @@ -70,6 +70,7 @@ def load_arguments(self, _): # pylint: disable=too-many-statements, too-many-
)

tier_arg_type = CLIArgumentType(
type=normalize_mysql_tier,
options_list=['--tier'],
help='Compute tier of the server. Accepted values: Burstable, GeneralPurpose, MemoryOptimized '
)
Expand Down Expand Up @@ -119,7 +120,8 @@ def load_arguments(self, _): # pylint: disable=too-many-statements, too-many-
accelerated_logs_arg_type = CLIArgumentType(
arg_type=get_enum_type(['Enabled', 'Disabled']),
options_list=['--accelerated-logs'],
help='Enable or disable accelerated logs. Only support for Business Critical tier. Default value is Enabled.'
help='Enable or disable accelerated logs. Supported for General Purpose and Memory Optimized tiers. '
'For server creation, defaults to Enabled for Memory Optimized and Disabled for General Purpose.'
)
Comment on lines 120 to 125

faster_restore_arg_type = CLIArgumentType(
Expand Down
14 changes: 4 additions & 10 deletions src/azure-cli/azure/cli/command_modules/mysql/_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,10 @@ def get_mysql_tiers(sku_info):
return list(sku_info.keys())


def normalize_mysql_tier(tier):
return 'MemoryOptimized' if tier == 'BusinessCritical' else tier


def get_mysql_list_skus_info(cmd, location, server_name=None):
list_skus_client = cf_mysql_flexible_location_capabilities(cmd.cli_ctx, '_')
params = {'serverName': server_name} if server_name else None
Expand Down Expand Up @@ -477,16 +481,6 @@ def get_user_confirmation(message, yes=False):
'Unable to prompt for confirmation as no tty available. Use --yes.')


def replace_memory_optimized_tier(result):
result = _get_list_from_paged_response(result)
for capability in result:
for edition_idx, edition in enumerate(capability.supported_flexible_server_editions):
if edition.name == 'MemoryOptimized':
capability.supported_flexible_server_editions[edition_idx].name = 'BusinessCritical'

return result


def _is_resource_name(resource):
if len(resource.split('/')) == 1:
return True
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ def mysql_sku_name_validator(sku_name, sku_info, tier, instance):
if sku_name not in skus:
raise CLIError('Incorrect value for --sku-name. The SKU name does not match tier selection. '
'Default value for --tier is Burstable. '
'For Business Critical and General Purpose you need to specify --tier value explicitly. '
'For Memory Optimized and General Purpose you need to specify --tier value explicitly. '
'Allowed values for given tier: {}'.format(skus))


Expand Down
14 changes: 2 additions & 12 deletions src/azure-cli/azure/cli/command_modules/mysql/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
cf_mysql_flexible_servers, cf_mysql_flexible_replica, cf_mysql_flexible_adadmin, cf_mysql_flexible_private_dns_zone_suffix_operations, cf_mysql_servers, \
cf_mysql_firewall_rules, get_mysql_flexible_management_client_by_sub
from ._util import resolve_poller, generate_missing_parameters, get_mysql_list_skus_info, generate_password, parse_maintenance_window, \
replace_memory_optimized_tier, build_identity_and_data_encryption, get_identity_and_data_encryption, get_tenant_id, run_subprocess, \
_get_list_from_paged_response, build_identity_and_data_encryption, get_identity_and_data_encryption, get_tenant_id, run_subprocess, \
fill_action_template, get_git_root_dir, get_single_to_flex_sku_mapping, get_firewall_rules_from_paged_response, \
ImportFromStorageProgressHook, OperationProgressBar, GITHUB_ACTION_PATH
from ._network import prepare_mysql_exist_private_dns_zone, prepare_mysql_exist_private_network, prepare_private_network, prepare_private_dns_zone, prepare_public_network
Expand Down Expand Up @@ -360,9 +360,6 @@ def flexible_server_create(cmd, client,
# Process parameters
server_name = server_name.lower()

# MySQL chnged MemoryOptimized tier to BusinessCritical (only in client tool not in list-skus return)
if tier == 'BusinessCritical':
tier = 'MemoryOptimized'
mysql_arguments_validator(db_context,
server_name=server_name,
location=location,
Expand Down Expand Up @@ -567,9 +564,6 @@ def flexible_server_import_create(cmd, client,
# Process parameters
server_name = server_name.lower()

# MySQL changed MemoryOptimized tier to BusinessCritical (only in client tool not in list-skus return)
if tier == 'BusinessCritical':
tier = 'MemoryOptimized'
mysql_arguments_validator(db_context,
data_source_type=data_source_type,
mode=mode,
Expand Down Expand Up @@ -1016,9 +1010,6 @@ def flexible_server_update_custom_func(cmd, client, instance, sku_name=None, tie
cf_availability_without_location=cf_mysql_check_resource_availability_without_location,
logging_name='MySQL', command_group='mysql', server_client=client, location=instance.location)

# MySQL chnged MemoryOptimized tier to BusinessCritical (only in client tool not in list-skus return)
if tier == 'BusinessCritical':
tier = 'MemoryOptimized'
mysql_arguments_validator(db_context,
location=location,
tier=tier,
Expand Down Expand Up @@ -1467,8 +1458,7 @@ def flexible_server_mysql_get(cmd, resource_group_name, server_name):


def flexible_list_skus(cmd, client, location):
result = client.list(location)
result = replace_memory_optimized_tier(result)
result = _get_list_from_paged_response(client.list(location))
logger.warning('For prices please refer to https://aka.ms/mysql-pricing')
return result

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
import unittest
from unittest.mock import patch
from unittest.mock import MagicMock, patch

from ... import custom
from ..._params import load_arguments
from ..._util import normalize_mysql_tier


class MysqlFlexibleServerFirewallRuleCustomTest(unittest.TestCase):
Expand Down Expand Up @@ -34,6 +36,71 @@ def test_firewall_rule_create_uses_properties_payload(self):
}, client.parameters.as_dict())


class MysqlAcceleratedLogsCustomTest(unittest.TestCase):

def test_accelerated_logs_tier_behavior(self):
self.assertEqual(
'Enabled',
custom._determine_acceleratedLogs('Enabled', 'GeneralPurpose'))
self.assertEqual(
'Disabled',
custom._determine_acceleratedLogs(None, 'GeneralPurpose'))
self.assertEqual(
'Enabled',
custom._determine_acceleratedLogs(None, 'MemoryOptimized'))
self.assertEqual(
'Disabled',
custom._determine_acceleratedLogs('Enabled', 'Burstable'))


class MysqlTierNormalizationTest(unittest.TestCase):

def test_business_critical_is_normalized_as_legacy_alias(self):
self.assertEqual('MemoryOptimized', normalize_mysql_tier('BusinessCritical'))
self.assertEqual('MemoryOptimized', normalize_mysql_tier('MemoryOptimized'))
self.assertIsNone(normalize_mysql_tier(None))

def test_all_tier_arguments_use_legacy_alias_normalizer(self):
registrations = []
loader = MagicMock()
loader.argument_context.side_effect = \
lambda command_name: _FakeArgumentContext(command_name, registrations)

load_arguments(loader, None)

tier_arg_types = {
command_name: settings['arg_type']
for command_name, argument_name, settings in registrations
if argument_name == 'tier'
}
self.assertEqual({
'mysql flexible-server create',
'mysql flexible-server geo-restore',
'mysql flexible-server import create',
'mysql flexible-server replica create',
'mysql flexible-server restore',
'mysql flexible-server update'
}, set(tier_arg_types))
for command_name, arg_type in tier_arg_types.items():
with self.subTest(command_name=command_name):
self.assertIs(normalize_mysql_tier, arg_type.settings['type'])


class MysqlFlexibleServerListSkusCustomTest(unittest.TestCase):

def test_list_skus_preserves_memory_optimized_tier(self):
capabilities = [_FakeCapability('MemoryOptimized')]
client = _FakeLocationCapabilitiesClient(capabilities)

result = custom.flexible_list_skus(cmd=None, client=client, location='eastus')

self.assertIs(capabilities, result)
self.assertEqual('eastus', client.location)
self.assertEqual(
'MemoryOptimized',
result[0].supported_flexible_server_editions[0].name)


class _FakeFirewallRulesClient:

def begin_create_or_update(self, resource_group_name, server_name, firewall_rule_name, parameters):
Expand All @@ -44,5 +111,46 @@ def begin_create_or_update(self, resource_group_name, server_name, firewall_rule
return parameters


class _FakeCapability:

def __init__(self, tier_name):
self.supported_flexible_server_editions = [_FakeEdition(tier_name)]


class _FakeEdition:

def __init__(self, name):
self.name = name


class _FakeLocationCapabilitiesClient:

def __init__(self, result):
self.result = result
self.location = None

def list(self, location):
self.location = location
return self.result


class _FakeArgumentContext:

def __init__(self, command_name, registrations):
self.command_name = command_name
self.registrations = registrations

def __enter__(self):
return self

def __exit__(self, *args):
return False

def argument(self, argument_name, *args, **settings):
if args:
settings['arg_type'] = args[0]
self.registrations.append((self.command_name, argument_name, settings))


if __name__ == '__main__':
unittest.main()
Loading