From 6ef33a9e518e2d7966d9b39e83382b1be8c12395 Mon Sep 17 00:00:00 2001 From: Jiashuo Li <4003950+jiasli@users.noreply.github.com> Date: Thu, 19 Dec 2024 16:53:23 +0800 Subject: [PATCH 01/13] {LTS} Backport #30289, #30313 (#30541) --- ...functionapp_access_restriction_commands.py | 8 ++++ .../tests/latest/test_functionapp_commands.py | 47 ++++++++++++++++++- .../tests/latest/test_webapp_commands.py | 1 + 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/test_functionapp_access_restriction_commands.py b/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/test_functionapp_access_restriction_commands.py index 3560ae6a0f1..c8c0388ca9a 100644 --- a/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/test_functionapp_access_restriction_commands.py +++ b/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/test_functionapp_access_restriction_commands.py @@ -24,6 +24,7 @@ class FunctionAppAccessRestrictionScenarioTest(ScenarioTest): + @unittest.skip("To be fixed") @ResourceGroupPreparer(parameter_name_for_location='location', location=WINDOWS_ASP_LOCATION_WEBAPP) @StorageAccountPreparer(location=WINDOWS_ASP_LOCATION_WEBAPP) def test_functionapp_access_restriction_show(self, resource_group, location): @@ -49,6 +50,7 @@ def test_functionapp_access_restriction_show(self, resource_group, location): JMESPathCheck('scmIpSecurityRestrictionsDefaultAction', None) ]) + @unittest.skip("To be fixed") @ResourceGroupPreparer(parameter_name_for_location='location', location=WINDOWS_ASP_LOCATION_WEBAPP) @StorageAccountPreparer(location=WINDOWS_ASP_LOCATION_WEBAPP) def test_functionapp_access_restriction_set_simple(self, resource_group, location): @@ -80,6 +82,7 @@ def test_functionapp_access_restriction_set_simple(self, resource_group, locatio JMESPathCheck('scmIpSecurityRestrictionsDefaultAction', 'Deny') ]) + @unittest.skip("To be fixed") @ResourceGroupPreparer(parameter_name_for_location='location', location=WINDOWS_ASP_LOCATION_WEBAPP) @StorageAccountPreparer(location=WINDOWS_ASP_LOCATION_WEBAPP) def test_functionapp_access_restriction_set_complex(self, resource_group, location): @@ -100,6 +103,7 @@ def test_functionapp_access_restriction_set_complex(self, resource_group, locati JMESPathCheck('scmIpSecurityRestrictionsUseMain', False) ]) + @unittest.skip("To be fixed") @ResourceGroupPreparer(random_name_length=17, parameter_name_for_location='location', location=WINDOWS_ASP_LOCATION_WEBAPP) # random_name_length is temporary until the bug fix in the API is deployed successfully & then should be removed. @StorageAccountPreparer(location=WINDOWS_ASP_LOCATION_WEBAPP) @@ -121,6 +125,7 @@ def test_functionapp_access_restriction_add(self, resource_group, location): JMESPathCheck('[1].action', 'Deny') ]) + @unittest.skip("To be fixed") @ResourceGroupPreparer(parameter_name_for_location='location', location=WINDOWS_ASP_LOCATION_WEBAPP) @StorageAccountPreparer(location=WINDOWS_ASP_LOCATION_WEBAPP) def test_functionapp_access_restriction_add_ip_address_validation(self, resource_group, location): @@ -176,6 +181,7 @@ def test_functionapp_access_restriction_add_service_endpoint(self, resource_grou JMESPathCheck('[1].action', 'Deny') ]) + @unittest.skip("To be fixed") @ResourceGroupPreparer(parameter_name_for_location='location', location=WINDOWS_ASP_LOCATION_WEBAPP) @StorageAccountPreparer(location=WINDOWS_ASP_LOCATION_WEBAPP) def test_functionapp_access_restriction_remove(self, resource_group, location): @@ -202,6 +208,7 @@ def test_functionapp_access_restriction_remove(self, resource_group, location): JMESPathCheck('[0].action', 'Allow') ]) + @unittest.skip("To be fixed") @ResourceGroupPreparer(parameter_name_for_location='location', location=WINDOWS_ASP_LOCATION_WEBAPP) @StorageAccountPreparer(location=WINDOWS_ASP_LOCATION_WEBAPP) def test_functionapp_access_restriction_add_scm(self, resource_group, location): @@ -222,6 +229,7 @@ def test_functionapp_access_restriction_add_scm(self, resource_group, location): JMESPathCheck('[1].action', 'Deny') ]) + @unittest.skip("To be fixed") @ResourceGroupPreparer(parameter_name_for_location='location', location=WINDOWS_ASP_LOCATION_WEBAPP) @StorageAccountPreparer(location=WINDOWS_ASP_LOCATION_WEBAPP) def test_functionapp_access_restriction_remove_scm(self, resource_group, location): diff --git a/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/test_functionapp_commands.py b/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/test_functionapp_commands.py index 6dc81edcbd1..0c4852dc6a8 100644 --- a/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/test_functionapp_commands.py +++ b/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/test_functionapp_commands.py @@ -169,6 +169,7 @@ def test_acr_deployment_function_app(self, resource_group, storage_account): class FunctionAppReservedInstanceTest(ScenarioTest): + @live_only() # TODO to be fixed @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() def test_functionapp_reserved_instance(self, resource_group, storage_account): @@ -191,6 +192,7 @@ def test_functionapp_reserved_instance(self, resource_group, storage_account): class FunctionAppHttpsOnlyTest(ScenarioTest): + @live_only() # TODO to be fixed @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() def test_functionapp_https_only(self, resource_group, storage_account): @@ -210,6 +212,7 @@ def test_functionapp_https_only(self, resource_group, storage_account): class FunctionAppWithPlanE2ETest(ScenarioTest): + @live_only() # TODO to be fixed @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @ResourceGroupPreparer(parameter_name='resource_group2', location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) def test_functionapp_e2e(self, resource_group, resource_group2): @@ -286,6 +289,7 @@ def test_functionapp_on_linux_app_service_java_with_runtime_version(self, resour self.cmd('functionapp config show -g {} -n {}'.format(resource_group, functionapp), checks=[ JMESPathCheck('linuxFxVersion', 'Java|11')]) + @live_only() # TODO: to be fixed @ResourceGroupPreparer(location=LINUX_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() def test_functionapp_on_linux_app_service_powershell(self, resource_group, storage_account): @@ -311,6 +315,7 @@ def test_functionapp_on_linux_app_service_powershell(self, resource_group, stora self.cmd('functionapp config show -g {} -n {}'.format(resource_group, functionapp), checks=[ JMESPathCheck('linuxFxVersion', 'PowerShell|7.2')]) + @live_only() # TODO: to be fixed @ResourceGroupPreparer(location=LINUX_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() def test_functionapp_on_linux_app_service_powershell_with_runtime_version(self, resource_group, storage_account): @@ -362,6 +367,7 @@ def test_functionapp_on_linux_app_service_dotnet_with_runtime_version(self, reso class FunctionUpdatePlan(ScenarioTest): + @live_only() # TODO to be fixed @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() def test_move_plan_to_elastic(self, resource_group, storage_account): @@ -429,6 +435,7 @@ def test_functionapp_update_slot(self, resource_group, storage_account): class FunctionAppWithConsumptionPlanE2ETest(ScenarioTest): + @live_only() # TODO to be fixed @ResourceGroupPreparer(name_prefix='azurecli-functionapp-c-e2e', location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() def test_functionapp_consumption_e2e(self, resource_group, storage_account): @@ -457,6 +464,7 @@ def test_functionapp_consumption_e2e(self, resource_group, storage_account): self.cmd( 'functionapp delete -g {} -n {}'.format(resource_group, functionapp_name)) + @live_only() # TODO to be fixed @ResourceGroupPreparer(name_prefix='azurecli-functionapp-c-e2e-ragrs', location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer(sku='Standard_RAGRS') def test_functionapp_consumption_ragrs_storage_e2e(self, resource_group, storage_account): @@ -594,6 +602,7 @@ def test_functionapp_consumption_linux_java(self, resource_group, storage_accoun self.cmd('functionapp config appsettings list -g {} -n {}'.format(resource_group, functionapp_name), checks=[ JMESPathCheck("[?name=='FUNCTIONS_WORKER_RUNTIME'].value|[0]", 'java')]) + @live_only() # TODO: to be fixed @ResourceGroupPreparer(name_prefix='azurecli-functionapp-linux', location=LINUX_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() def test_functionapp_consumption_linux_powershell(self, resource_group, storage_account): @@ -635,6 +644,7 @@ def test_functionapp_consumption_linux_dotnet_isolated(self, resource_group, sto class FunctionappDaprConfig(ScenarioTest): + @live_only() # TODO to be fixed @ResourceGroupPreparer(location='northeurope') @StorageAccountPreparer() def test_functionapp_enable_dapr(self, resource_group, storage_account): @@ -979,6 +989,7 @@ def __init__(self, method_name, config_file=None, recording_name=None, recording super().__init__(method_name, config_file, recording_name, recording_processors, replay_processors, recording_patches, replay_patches, random_config_dir) self.cmd('extension add -n application-insights') + @live_only() # TODO to be fixed @ResourceGroupPreparer(location='westeurope') @StorageAccountPreparer() def test_functionapp_create_with_appcontainer_managed_environment(self, resource_group, storage_account): @@ -1003,6 +1014,7 @@ def test_functionapp_create_with_appcontainer_managed_environment(self, resource self.assertTrue('ftpPublishingUrl' not in r) + @live_only() # TODO to be fixed @ResourceGroupPreparer(location='eastus') @StorageAccountPreparer() def test_functionapp_create_with_appcontainer_managed_environment_existing_app_insights(self, resource_group, storage_account): @@ -1066,7 +1078,8 @@ def test_functionapp_create_with_appcontainer_managed_environment_vnet_config_er with self.assertRaises(ArgumentUsageError): self.cmd('functionapp create -g {} -n {} -s {} --vnet {} --subnet {} --environment {} --runtime dotnet --functions-version 4' .format(resource_group, functionapp_name, storage_account, vnet_name, subnet_name, managed_environment_name)) - + + @live_only() # TODO to be fixed @ResourceGroupPreparer(location='westeurope') @StorageAccountPreparer() def test_functionapp_create_with_appcontainer_managed_environment_add_vnet_error(self, resource_group, storage_account): @@ -1095,6 +1108,7 @@ def test_functionapp_create_with_appcontainer_managed_environment_add_vnet_error self.cmd('functionapp vnet-integration add -g {} -n {} --vnet {} --subnet {}' .format(resource_group, functionapp_name, vnet_name, subnet_name)) + @live_only() # TODO to be fixed @ResourceGroupPreparer(location='southcentralus') @StorageAccountPreparer() def test_functionapp_create_with_appcontainer_managed_environment_remove_vnet_error(self, resource_group, storage_account): @@ -1120,6 +1134,7 @@ def test_functionapp_create_with_appcontainer_managed_environment_remove_vnet_er with self.assertRaises(ValidationError): self.cmd('functionapp vnet-integration remove -g {} -n {}'.format(resource_group, functionapp_name)) + @live_only() # TODO to be fixed @ResourceGroupPreparer(location='westeurope') @StorageAccountPreparer() def test_functionapp_create_with_appcontainer_managed_environment_list_vnet_error(self, resource_group, storage_account): @@ -1144,7 +1159,8 @@ def test_functionapp_create_with_appcontainer_managed_environment_list_vnet_erro JMESPathPatternCheck('hostNames[0]', functionapp_name + ".+" + 'azurecontainerapps.io')]) with self.assertRaises(ValidationError): self.cmd('functionapp vnet-integration list -g {} -n {}'.format(resource_group, functionapp_name)) - + + @live_only() # TODO to be fixed @ResourceGroupPreparer(location='northeurope') @StorageAccountPreparer() def test_functionapp_delete_functions(self, resource_group, storage_account): @@ -1193,6 +1209,7 @@ def test_functionapp_create_with_appcontainer_managed_environment_plan_error(sel self.cmd('functionapp create -g {} -n {} -p {} -s {} --environment {} --runtime dotnet --functions-version 4' .format(resource_group, functionapp_name, plan_name, storage_account, managed_environment_name)) + @live_only() # TODO to be fixed @ResourceGroupPreparer(location='northeurope') @StorageAccountPreparer() def test_functionapp_config_with_appcontainer_managed_environment_error(self, resource_group, storage_account): @@ -1219,6 +1236,7 @@ def test_functionapp_config_with_appcontainer_managed_environment_error(self, re self.cmd('functionapp config show -g {} -n {}' .format(resource_group, functionapp_name)) + @live_only() # TODO to be fixed @ResourceGroupPreparer(location='eastus') @StorageAccountPreparer() def test_functionapp_create_with_replicas(self, resource_group, storage_account): @@ -1258,6 +1276,7 @@ def test_functionapp_create_with_min_replicas_error(self, resource_group, storag self.cmd('functionapp create -g {} -n {} -p {} -s {} --runtime dotnet --functions-version 4 --min-replicas 1' .format(resource_group, functionapp_name, plan_name, storage_account)) + @live_only() # TODO to be fixed @ResourceGroupPreparer(location='eastus') @StorageAccountPreparer() def test_functionapp_container_config_set_replicas(self, resource_group, storage_account): @@ -1415,6 +1434,7 @@ def test_functionapp_windows_runtime_java(self, resource_group, storage_account) self.cmd('functionapp config show -g {} -n {}'.format(resource_group, functionapp_name), checks=[ JMESPathCheck('javaVersion', '17')]) + @live_only() # TODO: to be fixed @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() def test_functionapp_windows_runtime_powershell(self, resource_group, storage_account): @@ -1507,6 +1527,7 @@ def test_functionapp_windows_runtime_custom_handler(self, resource_group, storag class FunctionAppOnWindowsWithoutRuntime(ScenarioTest): + @live_only() # TODO to be fixed @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() def test_functionapp_windows_without_runtime(self, resource_group, storage_account): @@ -1525,6 +1546,7 @@ def test_functionapp_windows_without_runtime(self, resource_group, storage_accou class FunctionAppWithAppInsightsKey(ScenarioTest): + @live_only() # TODO to be fixed @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() def test_functionapp_with_app_insights_key(self, resource_group, storage_account): @@ -1556,6 +1578,7 @@ def __init__(self, method_name, config_file=None, recording_name=None, recording super().__init__(method_name, config_file, recording_name, recording_processors, replay_processors, recording_patches, replay_patches, random_config_dir) self.cmd('extension add -n application-insights') + @live_only() # TODO to be fixed @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() def test_functionapp_with_app_insights_conn_string(self, resource_group, storage_account): @@ -1631,6 +1654,7 @@ def test_functionapp_without_default_distributed_tracing(self, resource_group, s class FunctionAppWithAppInsightsDefault(ScenarioTest): + @live_only() # TODO to be fixed @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() def test_functionapp_with_default_app_insights(self, resource_group, storage_account): @@ -1653,6 +1677,7 @@ def test_functionapp_with_default_app_insights(self, resource_group, storage_acc self.assertTrue('AzureWebJobsDashboard' not in [ kp['name'] for kp in app_set]) + @live_only() # TODO to be fixed @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() def test_functionapp_with_no_default_app_insights(self, resource_group, storage_account): @@ -1681,6 +1706,7 @@ def __init__(self, method_name, config_file=None, recording_name=None, recording super().__init__(method_name, config_file, recording_name, recording_processors, replay_processors, recording_patches, replay_patches, random_config_dir) self.cmd('extension add -n application-insights') + @live_only() # TODO to be fixed @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() def test_functionapp_create_default_rg_and_workspace(self, resource_group, storage_account): @@ -1698,6 +1724,7 @@ def test_functionapp_create_default_rg_and_workspace(self, resource_group, stora self.check('workspaceResourceId', workspace_id) ]) + @live_only() # TODO to be fixed @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() def test_functionapp_existing_workspace(self, resource_group, storage_account): @@ -1709,6 +1736,7 @@ def test_functionapp_existing_workspace(self, resource_group, storage_account): self.check('workspaceResourceId', workspace['id']) ]) + @live_only() # TODO to be fixed @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() def test_functionapp_existing_default_rg(self, resource_group, storage_account): @@ -1880,6 +1908,7 @@ def test_functionapp_on_linux_functions_version_consumption(self, resource_group "[?name=='FUNCTIONS_EXTENSION_VERSION'].value|[0]", '~4') ]) + @live_only() # TODO to be fixed @ResourceGroupPreparer(location=LINUX_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() def test_functionapp_on_linux_dotnet_consumption(self, resource_group, storage_account): @@ -2034,6 +2063,7 @@ def test_functionapp_slot_swap(self, resource_group, storage_account): class FunctionAppKeysTests(ScenarioTest): + @live_only() # TODO to be fixed @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() def test_functionapp_keys_set(self, resource_group, storage_account): @@ -2061,6 +2091,7 @@ def test_functionapp_keys_set(self, resource_group, storage_account): JMESPathCheck('type', 'Microsoft.Web/sites/host/functionKeys'), JMESPathCheck('value', None)]) + @live_only() # TODO to be fixed @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() def test_functionapp_keys_list(self, resource_group, storage_account): @@ -2085,6 +2116,7 @@ def test_functionapp_keys_list(self, resource_group, storage_account): .format(resource_group, functionapp_name)).assert_with_checks([ JMESPathCheck('functionKeys.{}'.format(key_name), key_value)]) + @live_only() # TODO to be fixed @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() def test_functionapp_keys_delete(self, resource_group, storage_account): @@ -2112,6 +2144,7 @@ def test_functionapp_keys_delete(self, resource_group, storage_account): .format(resource_group, functionapp_name)).assert_with_checks([ JMESPathCheck('functionKeys.{}'.format(key_name), None)]) + @live_only() # TODO to be fixed @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() def test_functionapp_keys_set_slot(self, resource_group, storage_account): @@ -2519,6 +2552,7 @@ def test_functionapp_list_deployment_logs(self, resource_group, storage_account) class FunctionappLocalContextScenarioTest(LocalContextScenarioTest): + @live_only() # TODO to be fixed @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() def test_functionapp_local_context(self, resource_group, storage_account): @@ -2575,6 +2609,7 @@ def test_functionapp_assign_system_identity(self, resource_group, storage_accoun self.cmd('functionapp identity show -g {} -n {}'.format(resource_group, functionapp_name), checks=self.is_empty()) + @live_only() # TODO to be fixed @AllowLargeResponse(8192) @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() @@ -2607,6 +2642,7 @@ def test_functionapp_assign_user_identity(self, resource_group, storage_account) self.check('userAssignedIdentities', None), ]) + @live_only() # TODO to be fixed @AllowLargeResponse(8192) @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() @@ -2651,6 +2687,7 @@ def test_functionapp_remove_identity(self, resource_group, storage_account): class FunctionappCorsTest(ScenarioTest): + @live_only() # TODO to be fixed @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() def test_functionapp_cors_credentials(self, resource_group, storage_account): @@ -2667,6 +2704,7 @@ def test_functionapp_cors_credentials(self, resource_group, storage_account): class FunctionappNetworkConnectionTests(ScenarioTest): + @live_only() # TODO to be fixed @AllowLargeResponse() @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() @@ -2709,6 +2747,7 @@ def test_functionapp_vnetE2E(self, resource_group, storage_account): JMESPathCheck('length(@)', 0) ]) + @live_only() # TODO to be fixed @AllowLargeResponse() @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() @@ -2741,6 +2780,7 @@ def test_functionapp_create_with_vnet_consumption_plan(self, resource_group, sto self.cmd( 'functionapp create -g {} -n {} -s {} --consumption-plan-location {} --vnet {} --subnet {} --functions-version 4'.format(resource_group, functionapp_name, storage_account, WINDOWS_ASP_LOCATION_FUNCTIONAPP, vnet_name, subnet_name)) + @live_only() # TODO to be fixed @AllowLargeResponse() @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() @@ -2763,6 +2803,7 @@ def test_functionapp_vnet_basic_sku_E2E(self, resource_group, storage_account): JMESPathCheck('[0].name', subnet_name) ]) + @live_only() # TODO to be fixed @AllowLargeResponse() @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() @@ -2785,6 +2826,7 @@ def test_functionapp_vnet_EP_sku_E2E(self, resource_group, storage_account): JMESPathCheck('[0].name', subnet_name) ]) + @live_only() # TODO to be fixed @AllowLargeResponse() @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP, parameter_name="rg2") @@ -2998,6 +3040,7 @@ def test_functionapp_create_with_vnet_no_subnet(self, resource_group, storage_ac subnet_name, storage_account), expect_failure=True) class FunctionAppConfigTest(ScenarioTest): + @live_only() # TODO: to be fixed @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_FUNCTIONAPP) @StorageAccountPreparer() def test_functionapp_powershell_version(self, resource_group, storage_account): diff --git a/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/test_webapp_commands.py b/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/test_webapp_commands.py index 71cd5bd815b..5ee73cce36a 100644 --- a/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/test_webapp_commands.py +++ b/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/test_webapp_commands.py @@ -1576,6 +1576,7 @@ def test_webapp_cors(self, resource_group): self.cmd('webapp cors show -g {rg} -n {web} --slot {slot}', checks=self.check('allowedOrigins', [])) + @live_only() # TODO to be fixed @ResourceGroupPreparer(location=WINDOWS_ASP_LOCATION_WEBAPP) @StorageAccountPreparer() def test_functionapp_cors(self, resource_group, storage_account): From dac0ad4aaab0c3a090ae3975ffa460530250d790 Mon Sep 17 00:00:00 2001 From: Jiashuo Li <4003950+jiasli@users.noreply.github.com> Date: Tue, 24 Dec 2024 18:00:58 +0800 Subject: [PATCH 02/13] [LTS] Backport #30092 (#30540) --- .../azure/cli/core/auth/identity.py | 22 ++++------------- .../cli/core/auth/tests/test_identity.py | 16 +++---------- .../azure/cli/core/auth/util.py | 24 +++++++++++++------ .../cli/command_modules/profile/_help.py | 4 ++-- .../cli/command_modules/profile/custom.py | 2 +- 5 files changed, 28 insertions(+), 40 deletions(-) diff --git a/src/azure-cli-core/azure/cli/core/auth/identity.py b/src/azure-cli-core/azure/cli/core/auth/identity.py index d9f4e5a2027..69f853a4a36 100644 --- a/src/azure-cli-core/azure/cli/core/auth/identity.py +++ b/src/azure-cli-core/azure/cli/core/auth/identity.py @@ -37,10 +37,6 @@ "Select the account you want to log in with. " "For more information on login with Azure CLI, see https://go.microsoft.com/fwlink/?linkid=2271136") -PASSWORD_CERTIFICATE_WARNING = ( - "Passing the service principal certificate with `--password` is deprecated and will be removed " - "by version 2.74. Please use `--certificate` instead.") - logger = get_logger(__name__) @@ -196,7 +192,7 @@ def login_with_service_principal(self, client_id, credential, scopes): """ sp_auth = ServicePrincipalAuth.build_from_credential(self.tenant_id, client_id, credential) client_credential = sp_auth.get_msal_client_credential() - cca = ConfidentialClientApplication(client_id, client_credential, **self._msal_app_kwargs) + cca = ConfidentialClientApplication(client_id, client_credential=client_credential, **self._msal_app_kwargs) result = cca.acquire_token_for_client(scopes) check_result(result) @@ -307,7 +303,7 @@ def build_from_credential(cls, tenant_id, client_id, credential): return ServicePrincipalAuth(entry) @classmethod - def build_credential(cls, secret_or_certificate=None, + def build_credential(cls, client_secret=None, certificate=None, use_cert_sn_issuer=None, client_assertion=None): """Build credential from user input. The credential looks like below, but only one key can exist. @@ -318,20 +314,12 @@ def build_credential(cls, secret_or_certificate=None, } """ entry = {} - if certificate: + if client_secret: + entry[_CLIENT_SECRET] = client_secret + elif certificate: entry[_CERTIFICATE] = os.path.expanduser(certificate) if use_cert_sn_issuer: entry[_USE_CERT_SN_ISSUER] = use_cert_sn_issuer - elif secret_or_certificate: - # TODO: Make secret_or_certificate secret only - user_expanded = os.path.expanduser(secret_or_certificate) - if os.path.isfile(user_expanded): - logger.warning(PASSWORD_CERTIFICATE_WARNING) - entry[_CERTIFICATE] = user_expanded - if use_cert_sn_issuer: - entry[_USE_CERT_SN_ISSUER] = use_cert_sn_issuer - else: - entry[_CLIENT_SECRET] = secret_or_certificate elif client_assertion: entry[_CLIENT_ASSERTION] = client_assertion return entry diff --git a/src/azure-cli-core/azure/cli/core/auth/tests/test_identity.py b/src/azure-cli-core/azure/cli/core/auth/tests/test_identity.py index 677de98ef29..993039faca3 100644 --- a/src/azure-cli-core/azure/cli/core/auth/tests/test_identity.py +++ b/src/azure-cli-core/azure/cli/core/auth/tests/test_identity.py @@ -264,20 +264,10 @@ def test_service_principal_auth_client_assertion(self): assert client_credential == {'client_assertion': 'test_jwt'} def test_build_credential(self): - # secret - cred = ServicePrincipalAuth.build_credential(secret_or_certificate="test_secret") + # client_secret + cred = ServicePrincipalAuth.build_credential(client_secret="test_secret") assert cred == {"client_secret": "test_secret"} - # secret with '~', which is preserved as-is - cred = ServicePrincipalAuth.build_credential(secret_or_certificate="~test_secret") - assert cred == {"client_secret": "~test_secret"} - - # certificate as password (deprecated) - current_dir = os.path.dirname(os.path.realpath(__file__)) - test_cert_file = os.path.join(current_dir, 'sp_cert.pem') - cred = ServicePrincipalAuth.build_credential(secret_or_certificate=test_cert_file) - assert cred == {'certificate': test_cert_file} - # certificate current_dir = os.path.dirname(os.path.realpath(__file__)) test_cert_file = os.path.join(current_dir, 'sp_cert.pem') @@ -297,7 +287,7 @@ def test_build_credential(self): cred = ServicePrincipalAuth.build_credential(certificate=test_cert_file, use_cert_sn_issuer=True) assert cred == {'certificate': test_cert_file, 'use_cert_sn_issuer': True} - # client assertion + # client_assertion cred = ServicePrincipalAuth.build_credential(client_assertion="test_jwt") assert cred == {"client_assertion": "test_jwt"} diff --git a/src/azure-cli-core/azure/cli/core/auth/util.py b/src/azure-cli-core/azure/cli/core/auth/util.py index 61e91b27ca1..a89500ef9ce 100644 --- a/src/azure-cli-core/azure/cli/core/auth/util.py +++ b/src/azure-cli-core/azure/cli/core/auth/util.py @@ -14,6 +14,12 @@ AccessToken = namedtuple("AccessToken", ["token", "expires_on"]) +PASSWORD_CERTIFICATE_WARNING = ( + "The error may be caused by passing a service principal certificate with --password. " + "Please note that --password no longer accepts a service principal certificate. " + "To pass a service principal certificate, use --certificate instead.") + + def aad_error_handler(error, **kwargs): """ Handle the error from AAD server returned by ADAL or MSAL. """ @@ -30,17 +36,21 @@ def aad_error_handler(error, **kwargs): "below, please mention the hostname '%s'", socket.gethostname()) error_description = error.get('error_description') + error_codes = error.get('error_codes') # Build recommendation message - login_command = _generate_login_command(**kwargs) - login_message = ( - # Cloud Shell uses IMDS-like interface for implicit login. If getting token/cert failed, - # we let the user explicitly log in to AAD with MSAL. - "Please explicitly log in with:\n{}" if error.get('error') == 'broker_error' - else "Interactive authentication is needed. Please run:\n{}").format(login_command) + if error_codes and 7000215 in error_codes: + recommendation = PASSWORD_CERTIFICATE_WARNING + else: + login_command = _generate_login_command(**kwargs) + recommendation = ( + # Cloud Shell uses IMDS-like interface for implicit login. If getting token/cert failed, + # we let the user explicitly log in to AAD with MSAL. + "Please explicitly log in with:\n{}" if error.get('error') == 'broker_error' + else "Interactive authentication is needed. Please run:\n{}").format(login_command) from azure.cli.core.azclierror import AuthenticationError - raise AuthenticationError(error_description, msal_error=error, recommendation=login_message) + raise AuthenticationError(error_description, msal_error=error, recommendation=recommendation) def _generate_login_command(scopes=None, claims=None): diff --git a/src/azure-cli/azure/cli/command_modules/profile/_help.py b/src/azure-cli/azure/cli/command_modules/profile/_help.py index 0b71bac93b6..d3f5c3b9abe 100644 --- a/src/azure-cli/azure/cli/command_modules/profile/_help.py +++ b/src/azure-cli/azure/cli/command_modules/profile/_help.py @@ -21,8 +21,8 @@ For more details, see https://go.microsoft.com/fwlink/?linkid=2276314 - [WARNING] Passing the service principal certificate with `--password` is deprecated and will be removed - by version 2.74. Please use `--certificate` instead. + [WARNING] `--password` no longer accepts a service principal certificate. + Use `--certificate` to pass a service principal certificate. To log in with a service principal, specify --service-principal. diff --git a/src/azure-cli/azure/cli/command_modules/profile/custom.py b/src/azure-cli/azure/cli/command_modules/profile/custom.py index 07db5ac2d04..89416732a73 100644 --- a/src/azure-cli/azure/cli/command_modules/profile/custom.py +++ b/src/azure-cli/azure/cli/command_modules/profile/custom.py @@ -159,7 +159,7 @@ def login(cmd, username=None, password=None, tenant=None, scopes=None, allow_no_ if service_principal: from azure.cli.core.auth.identity import ServicePrincipalAuth password = ServicePrincipalAuth.build_credential( - secret_or_certificate=password, + client_secret=password, certificate=certificate, use_cert_sn_issuer=use_cert_sn_issuer, client_assertion=client_assertion) From 00d0cb23a8a785cfadb57d0fdbc6cd23bcab1eb7 Mon Sep 17 00:00:00 2001 From: Hang Date: Wed, 25 Dec 2024 10:32:45 +0800 Subject: [PATCH 03/13] [LTS] Backport #30533 (#30567) --- build_scripts/windows/scripts/build.cmd | 2 +- scripts/release/debian/build.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build_scripts/windows/scripts/build.cmd b/build_scripts/windows/scripts/build.cmd index 96599d31a85..14d8e9d5179 100644 --- a/build_scripts/windows/scripts/build.cmd +++ b/build_scripts/windows/scripts/build.cmd @@ -30,7 +30,7 @@ if "%ARCH%"=="x86" ( echo Please set ARCH to "x86" or "x64" goto ERROR ) -set PYTHON_VERSION=3.12.7 +set PYTHON_VERSION=3.12.8 set WIX_DOWNLOAD_URL="https://azurecliprod.blob.core.windows.net/msi/wix310-binaries-mirror.zip" set PYTHON_DOWNLOAD_URL="https://www.python.org/ftp/python/%PYTHON_VERSION%/python-%PYTHON_VERSION%-embed-%PYTHON_ARCH%.zip" diff --git a/scripts/release/debian/build.sh b/scripts/release/debian/build.sh index c5625bb9aef..6be2708a91d 100755 --- a/scripts/release/debian/build.sh +++ b/scripts/release/debian/build.sh @@ -15,7 +15,7 @@ set -exv ls -Rl /mnt/artifacts WORKDIR=`cd $(dirname $0); cd ../../../; pwd` -PYTHON_VERSION="3.12.7" +PYTHON_VERSION="3.12.8" SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" # Update APT packages From 43526699f2597e7aea790b693cb5678cbd1d50d5 Mon Sep 17 00:00:00 2001 From: Hang Date: Thu, 13 Feb 2025 17:03:58 +0800 Subject: [PATCH 04/13] {LTS} Backport #30554 (#30557) --- azure-pipelines.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 192acd09785..f28ed32f93d 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -7,7 +7,7 @@ trigger: include: - '*' exclude: - - 'release' + - 'release*' pr: branches: @@ -208,7 +208,7 @@ jobs: artifactName: metadata - task: PipAuthenticate@1 - condition: eq(variables['Build.SourceBranch'], 'refs/heads/release') + condition: startsWith(variables['Build.SourceBranch'], 'refs/heads/release') displayName: 'Pip Authenticate' inputs: artifactFeeds: $(AZURE_ARTIFACTS_FEEDS) @@ -252,7 +252,7 @@ jobs: artifactName: metadata - task: PipAuthenticate@1 - condition: eq(variables['Build.SourceBranch'], 'refs/heads/release') + condition: startsWith(variables['Build.SourceBranch'], 'refs/heads/release') displayName: 'Pip Authenticate' inputs: artifactFeeds: $(AZURE_ARTIFACTS_FEEDS) @@ -442,7 +442,7 @@ jobs: versionSpec: 3.12 - task: PipAuthenticate@1 - condition: eq(variables['Build.SourceBranch'], 'refs/heads/release') + condition: startsWith(variables['Build.SourceBranch'], 'refs/heads/release') displayName: 'Pip Authenticate' inputs: artifactFeeds: $(AZURE_ARTIFACTS_FEEDS) @@ -730,7 +730,7 @@ jobs: displayName: Install Docker - task: PipAuthenticate@1 - condition: eq(variables['Build.SourceBranch'], 'refs/heads/release') + condition: startsWith(variables['Build.SourceBranch'], 'refs/heads/release') displayName: 'Pip Authenticate' inputs: artifactFeeds: $(AZURE_ARTIFACTS_FEEDS) @@ -826,7 +826,7 @@ jobs: - bash: ./scripts/ci/install_docker.sh displayName: Install Docker - task: PipAuthenticate@1 - condition: eq(variables['Build.SourceBranch'], 'refs/heads/release') + condition: startsWith(variables['Build.SourceBranch'], 'refs/heads/release') displayName: 'Pip Authenticate' inputs: artifactFeeds: $(AZURE_ARTIFACTS_FEEDS) @@ -948,7 +948,7 @@ jobs: - bash: ./scripts/ci/install_docker.sh displayName: Install Docker - task: PipAuthenticate@1 - condition: eq(variables['Build.SourceBranch'], 'refs/heads/release') + condition: startsWith(variables['Build.SourceBranch'], 'refs/heads/release') displayName: 'Pip Authenticate' inputs: artifactFeeds: $(AZURE_ARTIFACTS_FEEDS) From 79a8e4c262e58b79d3a15050c254db7ea8a5221d Mon Sep 17 00:00:00 2001 From: Hang Date: Fri, 14 Feb 2025 11:26:22 +0800 Subject: [PATCH 05/13] [LTS] Backport #30816 (#30819) --- src/azure-cli/requirements.py3.Darwin.txt | 4 ++-- src/azure-cli/requirements.py3.Linux.txt | 4 ++-- src/azure-cli/requirements.py3.windows.txt | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/azure-cli/requirements.py3.Darwin.txt b/src/azure-cli/requirements.py3.Darwin.txt index b50f8c3eef7..fbab4603d67 100644 --- a/src/azure-cli/requirements.py3.Darwin.txt +++ b/src/azure-cli/requirements.py3.Darwin.txt @@ -93,7 +93,7 @@ certifi==2024.7.4 cffi==1.16.0 chardet==5.2.0 colorama==0.4.6 -cryptography==43.0.1 +cryptography==44.0.1 fabric==3.2.2 humanfriendly==10.0 idna==3.7 @@ -118,7 +118,7 @@ pycomposefile==0.0.30 PyGithub==1.55 PyJWT==2.4.0 PyNaCl==1.5.0 -pyOpenSSL==24.2.1 +pyOpenSSL==25.0.0 python-dateutil==2.8.0 requests-oauthlib==1.2.0 requests[socks]==2.32.3 diff --git a/src/azure-cli/requirements.py3.Linux.txt b/src/azure-cli/requirements.py3.Linux.txt index cf6dc20769c..4a13f6e6fc1 100644 --- a/src/azure-cli/requirements.py3.Linux.txt +++ b/src/azure-cli/requirements.py3.Linux.txt @@ -93,7 +93,7 @@ certifi==2024.7.4 cffi==1.16.0 chardet==5.2.0 colorama==0.4.6 -cryptography==43.0.1 +cryptography==44.0.1 distro==1.6.0 fabric==3.2.2 humanfriendly==10.0 @@ -119,7 +119,7 @@ pycomposefile==0.0.30 PyGithub==1.55 PyJWT==2.4.0 PyNaCl==1.5.0 -pyOpenSSL==24.2.1 +pyOpenSSL==25.0.0 python-dateutil==2.8.0 requests-oauthlib==1.2.0 requests[socks]==2.32.3 diff --git a/src/azure-cli/requirements.py3.windows.txt b/src/azure-cli/requirements.py3.windows.txt index 1c556bbaa23..5dfa21e44a3 100644 --- a/src/azure-cli/requirements.py3.windows.txt +++ b/src/azure-cli/requirements.py3.windows.txt @@ -93,7 +93,7 @@ certifi==2024.7.4 cffi==1.16.0 chardet==5.2.0 colorama==0.4.6 -cryptography==43.0.1 +cryptography==44.0.1 fabric==3.2.2 humanfriendly==10.0 idna==3.7 @@ -119,7 +119,7 @@ PyGithub==1.55 PyJWT==2.4.0 pymsalruntime==0.16.2 PyNaCl==1.5.0 -pyOpenSSL==24.2.1 +pyOpenSSL==25.0.0 python-dateutil==2.8.0 pywin32==306 requests-oauthlib==1.2.0 From 540af6123d13367a77ac6858111f40f98450fbfd Mon Sep 17 00:00:00 2001 From: Azure CLI Bot Date: Mon, 24 Feb 2025 14:49:58 +0800 Subject: [PATCH 06/13] {Release} Upgrade to Azure CLI 2.66.1 (#30848) --- azure-pipelines.yml | 1 + src/azure-cli-core/azure/cli/core/__init__.py | 2 +- src/azure-cli-core/setup.py | 2 +- src/azure-cli/azure/cli/__main__.py | 2 +- src/azure-cli/requirements.py3.Darwin.txt | 4 ++-- src/azure-cli/requirements.py3.Linux.txt | 4 ++-- src/azure-cli/requirements.py3.windows.txt | 4 ++-- src/azure-cli/setup.py | 2 +- 8 files changed, 11 insertions(+), 10 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index f28ed32f93d..3e7b6a8aeed 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1054,6 +1054,7 @@ jobs: - job: CheckHeaders displayName: "Check License, History, and DocMap" + condition: and(not(contains(variables['Build.SourceBranch'], 'lts')), not(contains(variables['System.PullRequest.TargetBranch'], 'lts'))) pool: name: ${{ variables.ubuntu_pool }} diff --git a/src/azure-cli-core/azure/cli/core/__init__.py b/src/azure-cli-core/azure/cli/core/__init__.py index 44e0fc318d1..9de5d62ba2c 100644 --- a/src/azure-cli-core/azure/cli/core/__init__.py +++ b/src/azure-cli-core/azure/cli/core/__init__.py @@ -4,7 +4,7 @@ # -------------------------------------------------------------------------------------------- # pylint: disable=line-too-long -__version__ = "2.66.0" +__version__ = "2.66.1" import os import sys diff --git a/src/azure-cli-core/setup.py b/src/azure-cli-core/setup.py index 084eab31df2..7ad4f62e63f 100644 --- a/src/azure-cli-core/setup.py +++ b/src/azure-cli-core/setup.py @@ -8,7 +8,7 @@ from codecs import open from setuptools import setup, find_packages -VERSION = "2.66.0" +VERSION = "2.66.1" # If we have source, validate that our version numbers match # This should prevent uploading releases with mismatched versions. diff --git a/src/azure-cli/azure/cli/__main__.py b/src/azure-cli/azure/cli/__main__.py index 9bf05456c50..13ac83cc472 100644 --- a/src/azure-cli/azure/cli/__main__.py +++ b/src/azure-cli/azure/cli/__main__.py @@ -17,7 +17,7 @@ from knack.log import get_logger __author__ = "Microsoft Corporation " -__version__ = "2.66.0" +__version__ = "2.66.1" logger = get_logger(__name__) diff --git a/src/azure-cli/requirements.py3.Darwin.txt b/src/azure-cli/requirements.py3.Darwin.txt index fbab4603d67..4d1d5b1be14 100644 --- a/src/azure-cli/requirements.py3.Darwin.txt +++ b/src/azure-cli/requirements.py3.Darwin.txt @@ -4,9 +4,9 @@ argcomplete==3.3.0 asn1crypto==0.24.0 azure-appconfiguration==1.7.0 azure-batch==14.2.0 -azure-cli-core==2.66.0 +azure-cli-core==2.66.1 azure-cli-telemetry==1.1.0 -azure-cli==2.66.0 +azure-cli==2.66.1 azure-common==1.1.22 azure-core==1.31.0 azure-cosmos==3.2.0 diff --git a/src/azure-cli/requirements.py3.Linux.txt b/src/azure-cli/requirements.py3.Linux.txt index 4a13f6e6fc1..bd81c456aed 100644 --- a/src/azure-cli/requirements.py3.Linux.txt +++ b/src/azure-cli/requirements.py3.Linux.txt @@ -4,9 +4,9 @@ argcomplete==3.3.0 asn1crypto==0.24.0 azure-appconfiguration==1.7.0 azure-batch==14.2.0 -azure-cli-core==2.66.0 +azure-cli-core==2.66.1 azure-cli-telemetry==1.1.0 -azure-cli==2.66.0 +azure-cli==2.66.1 azure-common==1.1.22 azure-core==1.31.0 azure-cosmos==3.2.0 diff --git a/src/azure-cli/requirements.py3.windows.txt b/src/azure-cli/requirements.py3.windows.txt index 5dfa21e44a3..51104b7e356 100644 --- a/src/azure-cli/requirements.py3.windows.txt +++ b/src/azure-cli/requirements.py3.windows.txt @@ -4,9 +4,9 @@ argcomplete==3.3.0 asn1crypto==0.24.0 azure-appconfiguration==1.7.0 azure-batch==14.2.0 -azure-cli-core==2.66.0 +azure-cli-core==2.66.1 azure-cli-telemetry==1.1.0 -azure-cli==2.66.0 +azure-cli==2.66.1 azure-common==1.1.22 azure-core==1.31.0 azure-cosmos==3.2.0 diff --git a/src/azure-cli/setup.py b/src/azure-cli/setup.py index 6439c937e7b..485a8cfc68b 100644 --- a/src/azure-cli/setup.py +++ b/src/azure-cli/setup.py @@ -17,7 +17,7 @@ logging.warning("Wheel is not available, disabling bdist_wheel hook") cmdclass = {} -VERSION = "2.66.0" +VERSION = "2.66.1" # If we have source, validate that our version numbers match # This should prevent uploading releases with mismatched versions. try: From ec3172dd54637aadb24ab78cdfb7c7b956d26cd2 Mon Sep 17 00:00:00 2001 From: Hang Date: Wed, 26 Feb 2025 14:59:12 +0800 Subject: [PATCH 07/13] {CI} Pin azdev to 0.1.90 (#30874) --- .azure-pipelines/templates/azdev_setup.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure-pipelines/templates/azdev_setup.yml b/.azure-pipelines/templates/azdev_setup.yml index b39abaf187c..055a8d2cf70 100644 --- a/.azure-pipelines/templates/azdev_setup.yml +++ b/.azure-pipelines/templates/azdev_setup.yml @@ -16,7 +16,7 @@ steps: chmod +x env/bin/activate . env/bin/activate python -m pip install -U pip - pip install azdev + pip install azdev==0.1.90 azdev --version if [ -z "$CLI_EXT_REPO_PATH" ]; then From 37327c821579a3c64080b6307e59a713028373b1 Mon Sep 17 00:00:00 2001 From: Jiashuo Li <4003950+jiasli@users.noreply.github.com> Date: Mon, 3 Mar 2025 15:19:07 +0800 Subject: [PATCH 08/13] {LTS} Backport #30759 (#30912) --- src/azure-cli/azure/cli/command_modules/eventgrid/custom.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/azure-cli/azure/cli/command_modules/eventgrid/custom.py b/src/azure-cli/azure/cli/command_modules/eventgrid/custom.py index 26fd4e7e270..7b2de70575d 100644 --- a/src/azure-cli/azure/cli/command_modules/eventgrid/custom.py +++ b/src/azure-cli/azure/cli/command_modules/eventgrid/custom.py @@ -715,7 +715,7 @@ def cli_domain_topic_event_subscription_delete( domain_topic_name, event_subscription_name): - client.begin_delete( + return client.begin_delete( resource_group_name=resource_group_name, domain_name=domain_name, topic_name=domain_topic_name, From bcb416611863a549963d4f77de8945bcb33023fd Mon Sep 17 00:00:00 2001 From: Jiashuo Li <4003950+jiasli@users.noreply.github.com> Date: Mon, 3 Mar 2025 15:23:32 +0800 Subject: [PATCH 09/13] {LTS} Do not add `post` suffix for branches starting with `release` (#30905) --- scripts/release/pypi/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/release/pypi/build.sh b/scripts/release/pypi/build.sh index 7d8447554ec..d4818fb9c60 100755 --- a/scripts/release/pypi/build.sh +++ b/scripts/release/pypi/build.sh @@ -22,7 +22,7 @@ pip list script_dir=`cd $(dirname $BASH_SOURCE[0]); pwd` -if [[ "$branch" != "release" ]]; then +if [[ ! $branch =~ ^release ]]; then . $script_dir/../../ci/version.sh post`date -u '+%Y%m%d%H%M%S'` fi From a3d6a5f7c1b0dccbf687dfce445984a55a7463f6 Mon Sep 17 00:00:00 2001 From: Hang Date: Fri, 9 May 2025 13:13:55 +0800 Subject: [PATCH 10/13] {LTS} Backport #30993 (#31367) --- .../azure/cli/core/tests/test_credential_helper.py | 4 ++-- src/azure-cli-core/setup.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/azure-cli-core/azure/cli/core/tests/test_credential_helper.py b/src/azure-cli-core/azure/cli/core/tests/test_credential_helper.py index 9a566c7fd7d..dd7d3ccb3b7 100644 --- a/src/azure-cli-core/azure/cli/core/tests/test_credential_helper.py +++ b/src/azure-cli-core/azure/cli/core/tests/test_credential_helper.py @@ -12,7 +12,7 @@ class TestCredentialHelper(unittest.TestCase): def _get_test_secret_masker(self): from microsoft_security_utilities_secret_masker import SecretMasker, load_regex_pattern_from_json email_address_json = { - "Pattern": r"(?[\w.%#+-]+)(%40|@)([a-z0-9.-]*.[a-z]{2,})", + "Pattern": r"(?P[\w.%#+-]+)(%40|@)([a-z0-9.-]*.[a-z]{2,})", "Id": "001", "Name": "EmailAddress", "Signatures": [ @@ -22,7 +22,7 @@ def _get_test_secret_masker(self): "DetectionMetadata": "HighConfidence" } guid_json = { - "Pattern": r"(?[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12})", + "Pattern": r"(?P[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12})", "Id": "002", "Name": "GUID", "DetectionMetadata": "LowConfidence" diff --git a/src/azure-cli-core/setup.py b/src/azure-cli-core/setup.py index 7ad4f62e63f..da6b832c581 100644 --- a/src/azure-cli-core/setup.py +++ b/src/azure-cli-core/setup.py @@ -53,6 +53,7 @@ 'humanfriendly~=10.0', 'jmespath', 'knack~=0.11.0', + 'microsoft-security-utilities-secret-masker~=1.0.0b4', 'msal-extensions==1.2.0', 'msal[broker]==1.31.0', 'msrestazure~=0.6.4', @@ -63,7 +64,6 @@ 'PyJWT>=2.1.0', 'pyopenssl>=17.1.0', # https://github.com/pyca/pyopenssl/pull/612 'requests[socks]', - 'microsoft-security-utilities-secret-masker~=1.0.0b2', ] with open('README.rst', 'r', encoding='utf-8') as f: From 0066c06c08b1ff749e8a8f1e2c37f203fbd66a2a Mon Sep 17 00:00:00 2001 From: Hang Date: Fri, 9 May 2025 13:14:23 +0800 Subject: [PATCH 11/13] {LTS} Backport #31159 (#31368) --- .../network/azure_stack/zone_file/parse_zone_file.py | 2 -- .../cli/command_modules/network/zone_file/parse_zone_file.py | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/network/azure_stack/zone_file/parse_zone_file.py b/src/azure-cli/azure/cli/command_modules/network/azure_stack/zone_file/parse_zone_file.py index 77c17bb2c5b..a77ed05d246 100644 --- a/src/azure-cli/azure/cli/command_modules/network/azure_stack/zone_file/parse_zone_file.py +++ b/src/azure-cli/azure/cli/command_modules/network/azure_stack/zone_file/parse_zone_file.py @@ -288,8 +288,6 @@ def _add_record_names(text): Go through each line of the text and ensure that a name is defined. Use previous record name if there is none. """ - global SUPPORTED_RECORDS - lines = text.split("\n") ret = [] previous_record_name = None diff --git a/src/azure-cli/azure/cli/command_modules/network/zone_file/parse_zone_file.py b/src/azure-cli/azure/cli/command_modules/network/zone_file/parse_zone_file.py index 5a358b19067..830be1d52b9 100644 --- a/src/azure-cli/azure/cli/command_modules/network/zone_file/parse_zone_file.py +++ b/src/azure-cli/azure/cli/command_modules/network/zone_file/parse_zone_file.py @@ -290,8 +290,6 @@ def _add_record_names(text): Go through each line of the text and ensure that a name is defined. Use previous record name if there is none. """ - global SUPPORTED_RECORDS - lines = text.split("\n") ret = [] previous_record_name = None From b63ab72298ae87e19a59878c71c59d120986ed20 Mon Sep 17 00:00:00 2001 From: Hang Date: Wed, 4 Jun 2025 15:14:44 +0800 Subject: [PATCH 12/13] [LTS] Backport #31208 (#31361) --- azure-pipelines.yml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 3e7b6a8aeed..b83ba490988 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -911,12 +911,6 @@ jobs: matrix: ${{ each arch in parameters.architectures }}: # https://wiki.ubuntu.com/Releases - Focal ${{ arch.name }}: - # 20.04 - deb_system: ubuntu - distro: focal - arch: ${{ arch.value }} - pool: ${{ arch.pool }} Jammy ${{ arch.name }}: # 22.04 deb_system: ubuntu @@ -980,11 +974,6 @@ jobs: strategy: matrix: ${{ each arch in parameters.architectures }}: - Focal ${{ arch.name }}: - deb_system: ubuntu - distro: focal - arch: ${{ arch.value }} - pool: ${{ arch.pool }} Jammy ${{ arch.name }}: deb_system: ubuntu distro: jammy From 849b8836085c76a475d9d8fae64bab1d42aada69 Mon Sep 17 00:00:00 2001 From: kai ru <69238381+kairu-ms@users.noreply.github.com> Date: Wed, 29 Jan 2025 08:13:42 +0800 Subject: [PATCH 13/13] {core} Fixed generic update issue. (#30703) * {core} --set: Minor fix * add test (cherry picked from commit 05a5d8fa878d8ae4d2ee8a1294feedc8af83fedb) --- .../azure/cli/core/commands/arm.py | 12 ++++++------ .../azure/cli/core/tests/test_util.py | 18 ++++++++++++++++++ src/azure-cli-core/azure/cli/core/util.py | 14 ++++++++++++++ 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/azure-cli-core/azure/cli/core/commands/arm.py b/src/azure-cli-core/azure/cli/core/commands/arm.py index 28d1e0f5c68..e953b26a548 100644 --- a/src/azure-cli-core/azure/cli/core/commands/arm.py +++ b/src/azure-cli-core/azure/cli/core/commands/arm.py @@ -15,7 +15,7 @@ from azure.cli.core.commands.client_factory import get_mgmt_service_client from azure.cli.core.commands.events import EVENT_INVOKER_PRE_LOAD_ARGUMENTS from azure.cli.core.commands.validators import IterateValue -from azure.cli.core.util import shell_safe_json_parse, get_command_type_kwarg +from azure.cli.core.util import shell_safe_json_parse, get_command_type_kwarg, getprop from azure.cli.core.profiles import ResourceType, get_sdk from knack.arguments import CLICommandArgument, ignore_type @@ -600,7 +600,7 @@ def remove_properties(instance, argument_values): def throw_and_show_options(instance, part, path): from msrest.serialization import Model options = instance.__dict__ if hasattr(instance, '__dict__') else instance - if isinstance(instance, Model) and isinstance(getattr(instance, 'additional_properties', None), dict): + if isinstance(instance, Model) and isinstance(getprop(instance, 'additional_properties', None), dict): options.update(options.pop('additional_properties')) parent = '.'.join(path[:-1]).replace('.[', '[') error_message = "Couldn't find '{}' in '{}'.".format(part, parent) @@ -673,7 +673,7 @@ def _update_instance(instance, part, path): # pylint: disable=too-many-return-s matches.append(x) elif not isinstance(x, dict): snake_key = make_snake_case(key) - if hasattr(x, snake_key) and getattr(x, snake_key, None) == value: + if hasattr(x, snake_key) and getprop(x, snake_key, None) == value: matches.append(x) if len(matches) == 1: @@ -681,7 +681,7 @@ def _update_instance(instance, part, path): # pylint: disable=too-many-return-s if len(matches) > 1: raise CLIError("non-unique key '{}' found multiple matches on {}. Key must be unique." .format(key, path[-2])) - if key in getattr(instance, 'additional_properties', {}): + if key in getprop(instance, 'additional_properties', {}): instance.enable_additional_properties_sending() return instance.additional_properties[key] raise CLIError("item with value '{}' doesn\'t exist for key '{}' on {}".format(value, key, path[-2])) @@ -697,8 +697,8 @@ def _update_instance(instance, part, path): # pylint: disable=too-many-return-s return instance[part] if hasattr(instance, make_snake_case(part)): - return getattr(instance, make_snake_case(part), None) - if part in getattr(instance, 'additional_properties', {}): + return getprop(instance, make_snake_case(part), None) + if part in getprop(instance, 'additional_properties', {}): instance.enable_additional_properties_sending() return instance.additional_properties[part] raise AttributeError() diff --git a/src/azure-cli-core/azure/cli/core/tests/test_util.py b/src/azure-cli-core/azure/cli/core/tests/test_util.py index 2e5f8ee9f29..abff11b948f 100644 --- a/src/azure-cli-core/azure/cli/core/tests/test_util.py +++ b/src/azure-cli-core/azure/cli/core/tests/test_util.py @@ -463,6 +463,24 @@ def test_b64_to_hex_type(self): self.assertIsInstance(b64_to_hex(self.base64), str) +class TestGetProperty(unittest.TestCase): + + def test_getprop(self): + from azure.cli.core.util import getprop + with self.assertRaises(AttributeError): + getprop(self, '__class__') + with self.assertRaises(AttributeError): + getprop(self, '__init__') + with self.assertRaises(AttributeError): + getprop(self, 'assertRaises') + with self.assertRaises(AttributeError): + getprop(self, '_diffThreshold') + with self.assertRaises(AttributeError): + getprop(self, 'new_props') + self.assertEqual(getprop(self, 'maxDiff'), self.maxDiff) + self.assertEqual(getprop(self, 'new_props', "new_props"), "new_props") + + class TestHandleException(unittest.TestCase): @mock.patch('azure.cli.core.azclierror.logger.error', autospec=True) diff --git a/src/azure-cli-core/azure/cli/core/util.py b/src/azure-cli-core/azure/cli/core/util.py index 8abc77884a7..66c803e6c60 100644 --- a/src/azure-cli-core/azure/cli/core/util.py +++ b/src/azure-cli-core/azure/cli/core/util.py @@ -1392,3 +1392,17 @@ def run_az_cmd(args, out_file=None): cli = get_default_cli() cli.invoke(args, out_file=out_file) return cli.result + + +def getprop(o, name, *default): + """ This function is used to get the property of the object. + It will raise an error if the property is a private property or a method. + """ + if name.startswith('_'): + # avoid to access the private properties or methods + raise AttributeError(name) + v = getattr(o, name, *default) + if callable(v): + # avoid to access the methods + raise AttributeError(name) + return v