diff --git a/linter_exclusions.yml b/linter_exclusions.yml index 14b0d35dd6f..3f125447613 100644 --- a/linter_exclusions.yml +++ b/linter_exclusions.yml @@ -1248,6 +1248,9 @@ cloud register: endpoint_active_directory_resource_id: rule_exclusions: - option_length_too_long + endpoint_microsoft_graph_resource_id: + rule_exclusions: + - option_length_too_long endpoint_resource_manager: rule_exclusions: - option_length_too_long @@ -1257,6 +1260,9 @@ cloud register: endpoint_vm_image_alias_doc: rule_exclusions: - option_length_too_long + skip_endpoint_discovery: + rule_exclusions: + - option_length_too_long suffix_acr_login_server_endpoint: rule_exclusions: - option_length_too_long @@ -1289,6 +1295,9 @@ cloud update: endpoint_active_directory_resource_id: rule_exclusions: - option_length_too_long + endpoint_microsoft_graph_resource_id: + rule_exclusions: + - option_length_too_long endpoint_resource_manager: rule_exclusions: - option_length_too_long @@ -1298,6 +1307,9 @@ cloud update: endpoint_vm_image_alias_doc: rule_exclusions: - option_length_too_long + skip_endpoint_discovery: + rule_exclusions: + - option_length_too_long suffix_acr_login_server_endpoint: rule_exclusions: - option_length_too_long diff --git a/src/azure-cli/azure/cli/command_modules/cloud/__init__.py b/src/azure-cli/azure/cli/command_modules/cloud/__init__.py index f7982d19fac..3ccaa9a2a29 100644 --- a/src/azure-cli/azure/cli/command_modules/cloud/__init__.py +++ b/src/azure-cli/azure/cli/command_modules/cloud/__init__.py @@ -42,6 +42,7 @@ def load_arguments(self, command): c.argument('cloud_name', options_list=('--name', '-n'), help='Name of a registered cloud', completer=get_cloud_name_completion_list) c.argument('profile', help='Profile to use for this cloud. The azure stack profiles `2017-03-09-profile` `2018-03-01-hybrid` `2019-03-01-hybrid` and `2020-09-01-hybrid` have been deprecated and removed. To continue using Azure Stack, please install the Azure CLI `2.66.*` (LTS) version. For more details, refer to: https://learn.microsoft.com/en-us/cli/azure/whats-new-overview#important-notice-for-azure-stack-hub-customers', choices=list(API_PROFILES)) c.argument('cloud_config', options_list=('--cloud-config',), help='JSON encoded cloud configuration. Use @{file} to load from a file.', type=shell_safe_json_parse) + c.argument('skip_endpoint_discovery', action='store_true', help="If specified, the cloud endpoints' auto discovery will be skipped") c.argument('endpoint_management', help='The management service endpoint') c.argument('endpoint_resource_manager', help='The resource management endpoint') c.argument('endpoint_sql_management', help='The sql server management endpoint') @@ -49,6 +50,7 @@ def load_arguments(self, command): c.argument('endpoint_active_directory', help='The Active Directory login endpoint') c.argument('endpoint_active_directory_resource_id', help='The resource ID to obtain AD tokens for') c.argument('endpoint_active_directory_graph_resource_id', help='The Active Directory resource ID') + c.argument('endpoint_microsoft_graph_resource_id', help='The Microsoft Graph resource ID') c.argument('endpoint_active_directory_data_lake_resource_id', help='The Active Directory resource ID for data lake services') c.argument('endpoint_vm_image_alias_doc', help='The uri of the document which caches commonly used virtual machine images') c.argument('suffix_sql_server_hostname', help='The dns suffix for sql servers') diff --git a/src/azure-cli/azure/cli/command_modules/cloud/custom.py b/src/azure-cli/azure/cli/command_modules/cloud/custom.py index 86f699a0bae..eadbc89af37 100644 --- a/src/azure-cli/azure/cli/command_modules/cloud/custom.py +++ b/src/azure-cli/azure/cli/command_modules/cloud/custom.py @@ -58,18 +58,21 @@ def _populate_from_metadata_endpoint(arm_endpoint, session=None): raise CLIError(error_msg_fmt.format(msg)) -def _build_cloud(cli_ctx, cloud_name, cloud_config=None, cloud_args=None): +def _build_cloud(cli_ctx, cloud_name, skip_endpoint_discovery=False, cloud_config=None, cloud_args=None): if cloud_config: # Using JSON format so convert the keys to snake case cloud_args = {to_snake_case(k): v for k, v in cloud_config.items()} - arm_endpoint = None - if 'endpoints' in cloud_args: - arm_endpoint = (cloud_args['endpoints'].get('resource_manager', None) or - cloud_args['endpoints'].get('resourceManager', None)) - if 'endpoint_resource_manager' in cloud_args: - arm_endpoint = cloud_args['endpoint_resource_manager'] - c = _populate_from_metadata_endpoint(arm_endpoint) - c.name = cloud_name + if skip_endpoint_discovery: + c = Cloud(cloud_name) + else: + arm_endpoint = None + if 'endpoints' in cloud_args: + arm_endpoint = (cloud_args['endpoints'].get('resource_manager', None) or + cloud_args['endpoints'].get('resourceManager', None)) + if 'endpoint_resource_manager' in cloud_args: + arm_endpoint = cloud_args['endpoint_resource_manager'] + c = _populate_from_metadata_endpoint(arm_endpoint) + c.name = cloud_name c.profile = cloud_args.get('profile', None) try: endpoints = cloud_args['endpoints'] @@ -92,8 +95,7 @@ def _build_cloud(cli_ctx, cloud_name, cloud_config=None, cloud_args=None): required_endpoints = {'resource_manager': '--endpoint-resource-manager', 'active_directory': '--endpoint-active-directory', - 'active_directory_resource_id': '--endpoint-active-directory-resource-id', - 'active_directory_graph_resource_id': '--endpoint-active-directory-graph-resource-id'} + 'active_directory_resource_id': '--endpoint-active-directory-resource-id'} missing_endpoints = [e_param for e_name, e_param in required_endpoints.items() if not c.endpoints.has_endpoint_set(e_name)] if missing_endpoints and not cloud_is_registered(cli_ctx, cloud_name): @@ -108,6 +110,7 @@ def register_cloud(cmd, cloud_name, cloud_config=None, profile=None, + skip_endpoint_discovery=False, endpoint_management=None, endpoint_resource_manager=None, endpoint_sql_management=None, @@ -115,6 +118,7 @@ def register_cloud(cmd, endpoint_active_directory=None, endpoint_active_directory_resource_id=None, endpoint_active_directory_graph_resource_id=None, + endpoint_microsoft_graph_resource_id=None, endpoint_active_directory_data_lake_resource_id=None, endpoint_vm_image_alias_doc=None, suffix_sql_server_hostname=None, @@ -123,8 +127,8 @@ def register_cloud(cmd, suffix_azure_datalake_store_file_system_endpoint=None, suffix_azure_datalake_analytics_catalog_and_job_endpoint=None, suffix_acr_login_server_endpoint=None): - c = _build_cloud(cmd.cli_ctx, cloud_name, cloud_config=cloud_config, - cloud_args=locals()) + c = _build_cloud(cmd.cli_ctx, cloud_name, skip_endpoint_discovery=skip_endpoint_discovery, + cloud_config=cloud_config, cloud_args=locals()) try: add_cloud(cmd.cli_ctx, c) except CloudAlreadyRegisteredException as e: @@ -135,6 +139,7 @@ def modify_cloud(cmd, cloud_name=None, cloud_config=None, profile=None, + skip_endpoint_discovery=False, endpoint_management=None, endpoint_resource_manager=None, endpoint_sql_management=None, @@ -142,6 +147,7 @@ def modify_cloud(cmd, endpoint_active_directory=None, endpoint_active_directory_resource_id=None, endpoint_active_directory_graph_resource_id=None, + endpoint_microsoft_graph_resource_id=None, endpoint_active_directory_data_lake_resource_id=None, endpoint_vm_image_alias_doc=None, suffix_sql_server_hostname=None, @@ -152,8 +158,8 @@ def modify_cloud(cmd, suffix_acr_login_server_endpoint=None): if not cloud_name: cloud_name = cmd.cli_ctx.cloud.name - c = _build_cloud(cmd.cli_ctx, cloud_name, cloud_config=cloud_config, - cloud_args=locals()) + c = _build_cloud(cmd.cli_ctx, cloud_name, skip_endpoint_discovery=skip_endpoint_discovery, + cloud_config=cloud_config, cloud_args=locals()) try: update_cloud(cmd.cli_ctx, c) except CloudNotRegisteredException as e: diff --git a/src/azure-cli/azure/cli/command_modules/cloud/tests/latest/test_cloud.py b/src/azure-cli/azure/cli/command_modules/cloud/tests/latest/test_cloud.py index ee07d54690c..e49921a1832 100644 --- a/src/azure-cli/azure/cli/command_modules/cloud/tests/latest/test_cloud.py +++ b/src/azure-cli/azure/cli/command_modules/cloud/tests/latest/test_cloud.py @@ -102,6 +102,11 @@ def test_cloud_scenario(self): assert result['endpoints']['activeDirectory'] == 'https://login.myendpoint.com/' assert result['endpoints']['management'] == 'https://management.myendpoint.com/' + # Skip cloud discovery + self.cmd('cloud update --name {name} --endpoint-resource-manager https://foo.example.com --skip-endpoint-discovery') + result = self.cmd('cloud show --name {name}').get_output_in_json() + assert result['endpoints']['resourceManager'] == 'https://foo.example.com' + # TODO: Test all arguments of `az cloud update` self.cmd('cloud set --name {name} --profile latest')