diff --git a/src/azure-cli/HISTORY.rst b/src/azure-cli/HISTORY.rst index 7bbafa33310..3253f98884c 100644 --- a/src/azure-cli/HISTORY.rst +++ b/src/azure-cli/HISTORY.rst @@ -172,6 +172,7 @@ Release History **MySQL** * [BREAKING CHANGE] `az mysql flexible-server backup create/restore/geo-restore/replica`: Remove `--storage-redundancy` (#33428) +* Fix #31568: `az mysql flexible-server list-skus`: Fix command returning empty list for all regions **NetAppFiles** diff --git a/src/azure-cli/azure/cli/command_modules/mysql/_transformers.py b/src/azure-cli/azure/cli/command_modules/mysql/_transformers.py index c1c03b7fbc5..7b6c485c2be 100644 --- a/src/azure-cli/azure/cli/command_modules/mysql/_transformers.py +++ b/src/azure-cli/azure/cli/command_modules/mysql/_transformers.py @@ -47,7 +47,7 @@ def table_transform_output_list_servers(result): def mysql_table_transform_output_list_skus(result): table_result = [] - if len(result) > 1: + if isinstance(result, list) and result: skus_tiers = result[0]["supportedFlexibleServerEditions"] for skus in skus_tiers: tier_name = skus["name"] @@ -61,7 +61,7 @@ def mysql_table_transform_output_list_skus(result): new_entry['Memory'] = str(int(key['supportedMemoryPerVCoreMb']) * int(key['vCores']) // 1024) + " GiB" new_entry['Max Disk IOPS'] = key['supportedIops'] table_result.append(new_entry) - except: + except (KeyError, IndexError, TypeError): raise CLIError("There is no sku available for this location.") return table_result diff --git a/src/azure-cli/azure/cli/command_modules/mysql/tests/latest/test_mysql_scenario.py b/src/azure-cli/azure/cli/command_modules/mysql/tests/latest/test_mysql_scenario.py index 312690af6ff..08f921c9e4f 100644 --- a/src/azure-cli/azure/cli/command_modules/mysql/tests/latest/test_mysql_scenario.py +++ b/src/azure-cli/azure/cli/command_modules/mysql/tests/latest/test_mysql_scenario.py @@ -16,6 +16,7 @@ from azure.cli.testsdk.scenario_tests.const import ENV_LIVE_TEST from azure.cli.testsdk.preparers import AbstractPreparer, SingleValueReplacer, StorageAccountPreparer from azure.core.exceptions import HttpResponseError +from knack.util import CLIError from ..._client_factory import cf_mysql_flexible_private_dns_zone_suffix_operations from ..._network import prepare_private_dns_zone from ...custom import DbContext as MysqlDbContext, _determine_iops @@ -224,7 +225,8 @@ def _test_flexible_server_mgmt(self, database_engine, resource_group): self.assertIn('ado.net', connection_string['connectionStrings']) self.cmd('{} flexible-server list-skus -l {}'.format(database_engine, location), - checks=[JMESPathCheck('type(@)', 'array')]) + checks=[JMESPathCheck('type(@)', 'array'), + JMESPathCheck('length(@) > `0`', True)]) self.cmd('{} flexible-server delete -g {} -n {} --yes'.format(database_engine, resource_group, server_name), checks=NoneCheck()) @@ -737,9 +739,21 @@ def _test_flexible_server_byok_mgmt(self, database_engine, resource_group, vault backup_location = DEFAULT_PAIRED_LOCATION replication_role = 'Replica' - user = self.cmd('ad signed-in-user show').get_output_in_json() - - self.cmd('keyvault set-policy --name {} --object-id {} --key-permissions all'.format(vault_name, user['id'])) + try: + # In interactive/delegated auth, `az ad signed-in-user show` returns the signed-in user. + user = self.cmd('ad signed-in-user show').get_output_in_json() + caller_object_id = user['id'] + except CLIError: + # `az ad signed-in-user show` calls Graph /me which is delegated-only. Under + # service-principal/OIDC auth (as used in live-test CI pipelines), the Graph API + # returns an HTTP 400. The role module's graph_err_handler converts the raw + # GraphError into a CLIError, which is what the test SDK re-raises here. + # Fall back to resolving the caller's object ID via `az ad sp show`. + account = self.cmd('account show').get_output_in_json() + sp_client_id = account['user']['name'] + caller_object_id = self.cmd('ad sp show --id {}'.format(sp_client_id)).get_output_in_json()['id'] + + self.cmd('keyvault set-policy --name {} --object-id {} --key-permissions all'.format(vault_name, caller_object_id)) key = self.cmd('keyvault key create --name {} -p software --vault-name {}' .format(key_name, vault_name)).get_output_in_json()