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 f1da31dbd2a..7c338c137e3 100644 --- a/src/azure-cli/azure/cli/command_modules/cloud/custom.py +++ b/src/azure-cli/azure/cli/command_modules/cloud/custom.py @@ -34,8 +34,40 @@ def show_cloud(cmd, cloud_name=None): raise CLIError(e) +def _populate_from_metadata_endpoint(cloud, arm_endpoint, session=None): + endpoints_in_metadata = ['active_directory_graph_resource_id', + 'active_directory_resource_id', 'active_directory'] + METADATA_ENDPOINT_SUFFIX = '/metadata/endpoints?api-version=2015-01-01' + if not arm_endpoint or all([cloud.endpoints.has_endpoint_set(n) for n in endpoints_in_metadata]): # pylint: disable=use-a-generator + return + import requests + error_msg_fmt = "Unable to get endpoints from the cloud.\n{}" + try: + session = requests.Session() if session is None else session + metadata_endpoint = arm_endpoint + METADATA_ENDPOINT_SUFFIX + response = session.get(metadata_endpoint) + if response.status_code == 200: + metadata = response.json() + if not cloud.endpoints.has_endpoint_set('gallery'): + setattr(cloud.endpoints, 'gallery', metadata.get('galleryEndpoint')) + if not cloud.endpoints.has_endpoint_set('active_directory_graph_resource_id'): + setattr(cloud.endpoints, 'active_directory_graph_resource_id', metadata.get('graphEndpoint')) + if not cloud.endpoints.has_endpoint_set('active_directory'): + setattr(cloud.endpoints, 'active_directory', metadata['authentication'].get('loginEndpoint')) + if not cloud.endpoints.has_endpoint_set('active_directory_resource_id'): + setattr(cloud.endpoints, 'active_directory_resource_id', metadata['authentication']['audiences'][0]) + else: + msg = 'Server returned status code {} for {}'.format(response.status_code, metadata_endpoint) + raise CLIError(error_msg_fmt.format(msg)) + except (requests.exceptions.ConnectionError, requests.exceptions.HTTPError) as err: + msg = 'Please ensure you have network connection. Error detail: {}'.format(str(err)) + raise CLIError(error_msg_fmt.format(msg)) + except ValueError as err: + msg = 'Response body does not contain valid json. Error detail: {}'.format(str(err)) + raise CLIError(error_msg_fmt.format(msg)) + + def _build_cloud(cli_ctx, cloud_name, cloud_config=None, cloud_args=None): - from msrestazure.azure_cloud import _populate_from_metadata_endpoint, MetadataEndpointError from azure.cli.core.cloud import CloudEndpointNotSetException if cloud_config: # Using JSON format so convert the keys to snake case @@ -65,10 +97,8 @@ def _build_cloud(cli_ctx, cloud_name, cloud_config=None, cloud_args=None): arm_endpoint = c.endpoints.resource_manager except CloudEndpointNotSetException: arm_endpoint = None - try: - _populate_from_metadata_endpoint(c, arm_endpoint) - except MetadataEndpointError as err: - raise CLIError(err) + + _populate_from_metadata_endpoint(c, arm_endpoint) required_endpoints = {'resource_manager': '--endpoint-resource-manager', 'active_directory': '--endpoint-active-directory', 'active_directory_resource_id': '--endpoint-active-directory-resource-id',