diff --git a/src/k8s-extension/HISTORY.rst b/src/k8s-extension/HISTORY.rst index 4b40bd2fbd4..f48c9059b08 100644 --- a/src/k8s-extension/HISTORY.rst +++ b/src/k8s-extension/HISTORY.rst @@ -3,6 +3,12 @@ Release History =============== +1.3.1 +++++++++++++++++++ +* microsoft.azureml.kubernetes: Always show TSG link for AzureMLKubernetes extension at the head. +* microsoft.azuremonitor.containers: add omsagent rename changes +* microsoft.azuremonitor.containers: fix script to support provisionedClusters + 1.3.0 ++++++++++++++++++ * Add support for provisionedClusters diff --git a/src/k8s-extension/azext_k8s_extension/partner_extensions/AzureMLKubernetes.py b/src/k8s-extension/azext_k8s_extension/partner_extensions/AzureMLKubernetes.py index a260580cf8d..a3ddb6ebe33 100644 --- a/src/k8s-extension/azext_k8s_extension/partner_extensions/AzureMLKubernetes.py +++ b/src/k8s-extension/azext_k8s_extension/partner_extensions/AzureMLKubernetes.py @@ -46,6 +46,9 @@ # pylint: disable=too-many-instance-attributes class AzureMLKubernetes(DefaultExtension): def __init__(self): + # tsg link + self.TSG_LINK = 'https://aka.ms/arcmltsg' + # constants for configuration settings. self.DEFAULT_RELEASE_NAMESPACE = 'azureml' self.RELAY_CONNECTION_STRING_KEY = 'relayserver.relayConnectionString' @@ -112,10 +115,13 @@ def Create(self, cmd, client, resource_group_name, cluster_name, name, cluster_t extension_type, scope, auto_upgrade_minor_version, release_train, version, target_namespace, release_namespace, configuration_settings, configuration_protected_settings, configuration_settings_file, configuration_protected_settings_file): + + logger.warning("Troubleshooting: {}".format(self.TSG_LINK)) + if scope == 'namespace': raise InvalidArgumentValueError("Invalid scope '{}'. This extension can't be installed " "only at 'cluster' scope. " - "Check https://aka.ms/arcmltsg for more information.".format(scope)) + "Check {} for more information.".format(scope, self.TSG_LINK)) # set release name explicitly to azureml release_namespace = self.DEFAULT_RELEASE_NAMESPACE scope_cluster = ScopeCluster(release_namespace=release_namespace) @@ -217,10 +223,14 @@ def Create(self, cmd, client, resource_group_name, cluster_name, name, cluster_t return extension, name, create_identity def Delete(self, cmd, client, resource_group_name, cluster_name, name, cluster_type, cluster_rp, yes): + logger.warning("Troubleshooting: {}".format(self.TSG_LINK)) user_confirmation_factory(cmd, yes) def Update(self, cmd, resource_group_name, cluster_name, auto_upgrade_minor_version, release_train, version, configuration_settings, configuration_protected_settings, original_extension, yes=False): + + logger.warning("Troubleshooting: {}".format(self.TSG_LINK)) + input_configuration_settings = copy.deepcopy(configuration_settings) input_configuration_protected_settings = copy.deepcopy(configuration_protected_settings) # configuration_settings and configuration_protected_settings can be none, so need to set them to empty dict @@ -335,9 +345,9 @@ def Update(self, cmd, resource_group_name, cluster_name, auto_upgrade_minor_vers except azure.mgmt.relay.models.ErrorResponseException as ex: if ex.response.status_code == 404: raise ResourceNotFoundError("Relay server not found. " - "Check https://aka.ms/arcmltsg for more information.") from ex + "Check {} for more information.".format(self.TSG_LINK)) from ex raise AzureResponseError("Failed to get relay connection string." - "Check https://aka.ms/arcmltsg for more information.") from ex + "Check {} for more information.".format(self.TSG_LINK)) from ex if original_extension_config_settings.get(self.SERVICE_BUS_ENABLED).lower() != 'false' \ and self.SERVICE_BUS_CONNECTION_STRING not in configuration_protected_settings: @@ -349,9 +359,9 @@ def Update(self, cmd, resource_group_name, cluster_name, auto_upgrade_minor_vers except azure.core.exceptions.HttpResponseError as ex: if ex.response.status_code == 404: raise ResourceNotFoundError("Service bus not found." - "Check https://aka.ms/arcmltsg for more information.") from ex + "Check {} for more information.".format(self.TSG_LINK)) from ex raise AzureResponseError("Failed to get service bus connection string." - "Check https://aka.ms/arcmltsg for more information.") from ex + "Check {} for more information.".format(self.TSG_LINK)) from ex configuration_protected_settings = _dereference(self.reference_mapping, configuration_protected_settings) @@ -384,7 +394,7 @@ def __normalize_config(self, configuration_settings, configuration_protected_set if not _is_valid_service_type(inferenceRouterServiceType): raise InvalidArgumentValueError( "inferenceRouterServiceType only supports NodePort or LoadBalancer or ClusterIP." - "Check https://aka.ms/arcmltsg for more information.") + "Check {} for more information.".format(self.TSG_LINK)) feIsNodePort = str(inferenceRouterServiceType).lower() == 'nodeport' configuration_settings['scoringFe.serviceType.nodePort'] = feIsNodePort @@ -407,7 +417,7 @@ def __validate_config(self, configuration_settings, configuration_protected_sett logger.warning( 'Duplicate keys found in both configuration settings and configuration protected setttings: %s', key) raise InvalidArgumentValueError("Duplicate keys found." - "Check https://aka.ms/arcmltsg for more information.") + "Check {} for more information.".format(self.TSG_LINK)) enable_training = _get_value_from_config_protected_config( self.ENABLE_TRAINING, configuration_settings, configuration_protected_settings) @@ -425,7 +435,7 @@ def __validate_config(self, configuration_settings, configuration_protected_sett "To create Microsoft.AzureML.Kubernetes extension, either " "enable Machine Learning training or inference by specifying " f"'--configuration-settings {self.ENABLE_TRAINING}=true' or '--configuration-settings {self.ENABLE_INFERENCE}=true'." - "Please check https://aka.ms/arcmltsg for more information.") + "Please check {} for more information.".format(self.TSG_LINK)) configuration_settings[self.ENABLE_TRAINING] = configuration_settings.get(self.ENABLE_TRAINING, enable_training) configuration_settings[self.ENABLE_INFERENCE] = configuration_settings.get( @@ -461,7 +471,7 @@ def __validate_scoring_fe_settings(self, configuration_settings, configuration_p if not sslCname: raise InvalidArgumentValueError( "To enable HTTPs endpoint, " - "please specify sslCname parameter in --configuration-settings. Check https://aka.ms/arcmltsg for more information.") + "please specify sslCname parameter in --configuration-settings. Check {} for more information.".format(self.TSG_LINK)) inferenceRouterServiceType = _get_value_from_config_protected_config( self.inferenceRouterServiceType, configuration_settings, configuration_protected_settings) @@ -469,7 +479,7 @@ def __validate_scoring_fe_settings(self, configuration_settings, configuration_p raise InvalidArgumentValueError( "To use inference, " "please specify inferenceRouterServiceType=ClusterIP or inferenceRouterServiceType=NodePort or inferenceRouterServiceType=LoadBalancer in --configuration-settings and also set internalLoadBalancerProvider=azure if your aks only supports internal load balancer." - "Check https://aka.ms/arcmltsg for more information.") + "Check {} for more information.".format(self.TSG_LINK)) feIsNodePort = str(inferenceRouterServiceType).lower() == 'nodeport' internalLoadBalancerProvider = _get_value_from_config_protected_config( @@ -479,7 +489,7 @@ def __validate_scoring_fe_settings(self, configuration_settings, configuration_p if feIsNodePort and feIsInternalLoadBalancer: raise MutuallyExclusiveArgumentError( "When using nodePort as inferenceRouterServiceType, no need to specify internalLoadBalancerProvider." - "Check https://aka.ms/arcmltsg for more information.") + "Check {} for more information.".format(self.TSG_LINK)) if feIsNodePort: configuration_settings['scoringFe.serviceType.nodePort'] = feIsNodePort elif feIsInternalLoadBalancer: diff --git a/src/k8s-extension/azext_k8s_extension/partner_extensions/ContainerInsights.py b/src/k8s-extension/azext_k8s_extension/partner_extensions/ContainerInsights.py index 3908ee54d26..d2e5ba2491c 100644 --- a/src/k8s-extension/azext_k8s_extension/partner_extensions/ContainerInsights.py +++ b/src/k8s-extension/azext_k8s_extension/partner_extensions/ContainerInsights.py @@ -87,10 +87,15 @@ def Delete(self, cmd, client, resource_group_name, cluster_name, name, cluster_t cluster_resource_id = '/subscriptions/{0}/resourceGroups/{1}/providers/{2}/{3}/{4}'.format(subscription_id, resource_group_name, cluster_rp, cluster_type, cluster_name) if (extension is not None) and (extension.configuration_settings is not None): configSettings = extension.configuration_settings + # omsagent is being renamed to ama-logs. Check for both for compatibility if 'omsagent.useAADAuth' in configSettings: useAADAuthSetting = configSettings['omsagent.useAADAuth'] if (isinstance(useAADAuthSetting, str) and str(useAADAuthSetting).lower() == "true") or (isinstance(useAADAuthSetting, bool) and useAADAuthSetting): useAADAuth = True + elif 'amalogs.useAADAuth' in configSettings: + useAADAuthSetting = configSettings['amalogs.useAADAuth'] + if (isinstance(useAADAuthSetting, str) and str(useAADAuthSetting).lower() == "true") or (isinstance(useAADAuthSetting, bool) and useAADAuthSetting): + useAADAuth = True if useAADAuth: association_url = cmd.cli_ctx.cloud.endpoints.resource_manager + f"{cluster_resource_id}/providers/Microsoft.Insights/dataCollectionRuleAssociations/ContainerInsightsExtension?api-version=2021-04-01" for _ in range(3): @@ -236,10 +241,10 @@ def _ensure_default_log_analytics_workspace_for_monitoring(cmd, subscription_id, cluster_location = '' resources = cf_resources(cmd.cli_ctx, subscription_id) - cluster_resource_id = '/subscriptions/{0}/resourceGroups/{1}/providers//{2}/{3}/{4}'.format( + cluster_resource_id = '/subscriptions/{0}/resourceGroups/{1}/providers/{2}/{3}/{4}'.format( subscription_id, cluster_resource_group_name, cluster_rp, cluster_type, cluster_name) try: - resource = resources.get_by_id(cluster_resource_id, '2020-01-01-preview') + resource = resources.get_by_id(cluster_resource_id, '2022-05-01-preview') cluster_location = resource.location.lower() except HttpResponseError as ex: raise ex @@ -453,11 +458,17 @@ def _get_container_insights_settings(cmd, cluster_resource_group_name, cluster_r if 'logAnalyticsWorkspaceResourceID' in configuration_settings: workspace_resource_id = configuration_settings['logAnalyticsWorkspaceResourceID'] + # omsagent is being renamed to ama-logs. Check for both for compatibility if 'omsagent.useAADAuth' in configuration_settings: useAADAuthSetting = configuration_settings['omsagent.useAADAuth'] logger.info("provided useAADAuth flag is : %s", useAADAuthSetting) if (isinstance(useAADAuthSetting, str) and str(useAADAuthSetting).lower() == "true") or (isinstance(useAADAuthSetting, bool) and useAADAuthSetting): useAADAuth = True + elif 'amalogs.useAADAuth' in configuration_settings: + useAADAuthSetting = configuration_settings['amalogs.useAADAuth'] + logger.info("provided useAADAuth flag is : %s", useAADAuthSetting) + if (isinstance(useAADAuthSetting, str) and str(useAADAuthSetting).lower() == "true") or (isinstance(useAADAuthSetting, bool) and useAADAuthSetting): + useAADAuth = True workspace_resource_id = workspace_resource_id.strip() @@ -473,7 +484,9 @@ def _get_container_insights_settings(cmd, cluster_resource_group_name, cluster_r 'proxyEndpoint url should in this format http(s)://:@:' ) logger.info("successfully validated proxyEndpoint url hence passing proxy endpoint to extension") + # omsagent is being renamed to ama-logs. Set for both for compatibility configuration_protected_settings['omsagent.proxy'] = configuration_protected_settings['proxyEndpoint'] + configuration_protected_settings['amalogs.proxy'] = configuration_protected_settings['proxyEndpoint'] if not workspace_resource_id: workspace_resource_id = _ensure_default_log_analytics_workspace_for_monitoring( @@ -509,20 +522,28 @@ def _get_container_insights_settings(cmd, cluster_resource_group_name, cluster_r if not shared_keys: raise InvalidArgumentValueError('Failed to retrieve shared key for workspace {}'.format( log_analytics_workspace)) + # omsagent is being renamed to ama-logs. Set for both for compatibility configuration_protected_settings['omsagent.secret.key'] = shared_keys.primary_shared_key + configuration_protected_settings['amalogs.secret.key'] = shared_keys.primary_shared_key + # omsagent is being renamed to ama-logs. Set for both for compatibility configuration_protected_settings['omsagent.secret.wsid'] = log_analytics_workspace.customer_id + configuration_protected_settings['amalogs.secret.wsid'] = log_analytics_workspace.customer_id configuration_settings['logAnalyticsWorkspaceResourceID'] = workspace_resource_id # set the domain for the ci agent for non azure public clouds cloud_name = cmd.cli_ctx.cloud.name if cloud_name.lower() == 'azurechinacloud': configuration_settings['omsagent.domain'] = 'opinsights.azure.cn' + configuration_settings['amalogs.domain'] = 'opinsights.azure.cn' elif cloud_name.lower() == 'azureusgovernment': configuration_settings['omsagent.domain'] = 'opinsights.azure.us' + configuration_settings['amalogs.domain'] = 'opinsights.azure.us' elif cloud_name.lower() == 'usnat': configuration_settings['omsagent.domain'] = 'opinsights.azure.eaglex.ic.gov' + configuration_settings['amalogs.domain'] = 'opinsights.azure.eaglex.ic.gov' elif cloud_name.lower() == 'ussec': configuration_settings['omsagent.domain'] = 'opinsights.azure.microsoft.scloud' + configuration_settings['amalogs.domain'] = 'opinsights.azure.microsoft.scloud' def get_existing_container_insights_extension_dcr_tags(cmd, dcr_url): @@ -553,7 +574,7 @@ def _ensure_container_insights_dcr_for_monitoring(cmd, subscription_id, cluster_ cluster_resource_id = '/subscriptions/{0}/resourceGroups/{1}/providers/{2}/{3}/{4}'.format( subscription_id, cluster_resource_group_name, cluster_rp, cluster_type, cluster_name) try: - resource = resources.get_by_id(cluster_resource_id, '2020-01-01-preview') + resource = resources.get_by_id(cluster_resource_id, '2022-05-01-preview') cluster_region = resource.location.lower() except HttpResponseError as ex: raise ex diff --git a/src/k8s-extension/setup.py b/src/k8s-extension/setup.py index be009d730cb..85d18cd327c 100644 --- a/src/k8s-extension/setup.py +++ b/src/k8s-extension/setup.py @@ -33,7 +33,7 @@ # TODO: Add any additional SDK dependencies here DEPENDENCIES = [] -VERSION = "1.3.0" +VERSION = "1.3.1" with open("README.rst", "r", encoding="utf-8") as f: README = f.read()