diff --git a/src/k8s-extension/HISTORY.rst b/src/k8s-extension/HISTORY.rst index dbf39b332fe..02562364f13 100644 --- a/src/k8s-extension/HISTORY.rst +++ b/src/k8s-extension/HISTORY.rst @@ -3,6 +3,12 @@ Release History =============== +0.3.1 +++++++++++++++++++ + +* Add provider registration to check to validations +* Only validate scoring fe settings when inference is enabled in microsoft.azureml.kubernetes + 0.3.0 ++++++++++++++++++ diff --git a/src/k8s-extension/HISTORY_private.rst b/src/k8s-extension/HISTORY_private.rst index 55ac4a68097..0dd9a2d5b7f 100644 --- a/src/k8s-extension/HISTORY_private.rst +++ b/src/k8s-extension/HISTORY_private.rst @@ -3,6 +3,12 @@ Release History =============== +0.3.1-beta.1 +++++++++++++++++++ + +* Add provider registration to check to validations +* Only validate scoring fe settings when inference is enabled in microsoft.azureml.kubernetes + 0.3.0-beta.1 ++++++++++++++++++ * Release customization for microsoft.azureml.kubernetes diff --git a/src/k8s-extension/azext_k8s_extension/_client_factory.py b/src/k8s-extension/azext_k8s_extension/_client_factory.py index 6271246245e..17bb875a38c 100644 --- a/src/k8s-extension/azext_k8s_extension/_client_factory.py +++ b/src/k8s-extension/azext_k8s_extension/_client_factory.py @@ -29,3 +29,8 @@ def cf_resources(cli_ctx, subscription_id=None): def cf_log_analytics(cli_ctx, subscription_id=None): from azure.mgmt.loganalytics import LogAnalyticsManagementClient # pylint: disable=no-name-in-module return get_mgmt_service_client(cli_ctx, LogAnalyticsManagementClient, subscription_id=subscription_id) + + +def _resource_providers_client(cli_ctx): + from azure.mgmt.resource import ResourceManagementClient + return get_mgmt_service_client(cli_ctx, ResourceManagementClient).providers diff --git a/src/k8s-extension/azext_k8s_extension/_validators.py b/src/k8s-extension/azext_k8s_extension/_validators.py new file mode 100644 index 00000000000..ee44f0e68e8 --- /dev/null +++ b/src/k8s-extension/azext_k8s_extension/_validators.py @@ -0,0 +1,26 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +from knack.log import get_logger +from azext_k8s_extension._client_factory import _resource_providers_client +from . import consts + + +logger = get_logger(__name__) + + +# pylint: disable=broad-except +def _validate_cc_registration(cmd): + try: + rp_client = _resource_providers_client(cmd.cli_ctx) + registration_state = rp_client.get(consts.PROVIDER_NAMESPACE).registration_state + + if registration_state != "Registered": + logger.warning("'Extensions' cannot be used because '%s' provider has not been registered." + "More details for registering this provider can be found here - " + "https://aka.ms/RegisterKubernetesConfigurationProvider", consts.PROVIDER_NAMESPACE) + except Exception: + logger.warning("Unable to fetch registration state of '%s' provider. " + "Failed to enable 'extensions' feature...", consts.PROVIDER_NAMESPACE) diff --git a/src/k8s-extension/azext_k8s_extension/consts.py b/src/k8s-extension/azext_k8s_extension/consts.py index 4d09158eacd..2f39b4d7247 100644 --- a/src/k8s-extension/azext_k8s_extension/consts.py +++ b/src/k8s-extension/azext_k8s_extension/consts.py @@ -6,3 +6,4 @@ EXTENSION_NAME = 'k8s-extension' EXTENSION_PACKAGE_NAME = "azext_k8s_extension" +PROVIDER_NAMESPACE = 'Microsoft.KubernetesConfiguration' diff --git a/src/k8s-extension/azext_k8s_extension/custom.py b/src/k8s-extension/azext_k8s_extension/custom.py index 9202f433e1e..c3cb8537cb1 100644 --- a/src/k8s-extension/azext_k8s_extension/custom.py +++ b/src/k8s-extension/azext_k8s_extension/custom.py @@ -13,9 +13,10 @@ from azure.cli.core.azclierror import ResourceNotFoundError, MutuallyExclusiveArgumentError, \ InvalidArgumentValueError, CommandNotFoundError, RequiredArgumentMissingError from azure.cli.core.commands.client_factory import get_subscription_id -from .vendored_sdks.models import ConfigurationIdentity -from .vendored_sdks.models import ErrorResponseException -from .vendored_sdks.models import Scope +from azext_k8s_extension.vendored_sdks.models import ConfigurationIdentity +from azext_k8s_extension.vendored_sdks.models import ErrorResponseException +from azext_k8s_extension.vendored_sdks.models import Scope +from azext_k8s_extension._validators import _validate_cc_registration from .partner_extensions.ContainerInsights import ContainerInsights from .partner_extensions.AzureDefender import AzureDefender @@ -82,9 +83,8 @@ def create_k8s_extension(cmd, client, resource_group_name, cluster_name, name, c """Create a new Extension Instance. """ - extension_type_lower = extension_type.lower() - # Determine ClusterRP + extension_type_lower = extension_type.lower() cluster_rp = __get_cluster_rp(cluster_type) # Configuration Settings & Configuration Protected Settings @@ -139,6 +139,9 @@ def create_k8s_extension(cmd, client, resource_group_name, cluster_name, name, c __validate_version_and_auto_upgrade(extension_instance.version, extension_instance.auto_upgrade_minor_version) __validate_scope_after_customization(extension_instance.scope) + # Check that registration has been done on Microsoft.KubernetesConfiguration for the subscription + _validate_cc_registration(cmd) + # Create identity, if required if create_identity: extension_instance.identity, extension_instance.location = \ 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 34d71beb829..d907e7d3c63 100644 --- a/src/k8s-extension/azext_k8s_extension/partner_extensions/AzureMLKubernetes.py +++ b/src/k8s-extension/azext_k8s_extension/partner_extensions/AzureMLKubernetes.py @@ -167,14 +167,13 @@ def __validate_config(self, configuration_settings, configuration_protected_sett if enable_inference: logger.warning("The installed AzureML extension for AML inference is experimental and not covered by customer support. Please use with discretion.") + self.__validate_scoring_fe_settings(configuration_settings, configuration_protected_settings) elif not (enable_training or enable_inference): raise InvalidArgumentValueError( "Please create Microsoft.AzureML.Kubernetes extension instance either " "for Machine Learning training or inference by specifying " f"'--configuration-settings {self.ENABLE_TRAINING}=true' or '--configuration-settings {self.ENABLE_INFERENCE}=true'") - self.__validate_scoring_fe_settings(configuration_settings, configuration_protected_settings) - configuration_settings[self.ENABLE_TRAINING] = configuration_settings.get(self.ENABLE_TRAINING, enable_training) configuration_settings[self.ENABLE_INFERENCE] = configuration_settings.get( self.ENABLE_INFERENCE, enable_inference) diff --git a/src/k8s-extension/setup.py b/src/k8s-extension/setup.py index 3c9a1882a27..b3512c976db 100644 --- a/src/k8s-extension/setup.py +++ b/src/k8s-extension/setup.py @@ -32,7 +32,7 @@ # TODO: Add any additional SDK dependencies here DEPENDENCIES = [] -VERSION = "0.3.0" +VERSION = "0.3.1" with open('README.rst', 'r', encoding='utf-8') as f: README = f.read() diff --git a/src/k8s-extension/setup_private.py b/src/k8s-extension/setup_private.py index 0a27056e68b..8f31f356fd7 100644 --- a/src/k8s-extension/setup_private.py +++ b/src/k8s-extension/setup_private.py @@ -32,7 +32,7 @@ # TODO: Add any additional SDK dependencies here DEPENDENCIES = [] -VERSION = "0.3.0-beta.1" +VERSION = "0.3.1-beta.1" with open('README.rst', 'r', encoding='utf-8') as f: README = f.read() diff --git a/testing/test/extensions/public/AzureMLKubernetes.Tests.ps1 b/testing/test/extensions/public/AzureMLKubernetes.Tests.ps1 index a434544da12..2bc01244a74 100644 --- a/testing/test/extensions/public/AzureMLKubernetes.Tests.ps1 +++ b/testing/test/extensions/public/AzureMLKubernetes.Tests.ps1 @@ -4,6 +4,7 @@ Describe 'AzureML Kubernetes Testing' { $extensionName = "azureml-kubernetes-connector" $extensionAgentNamespace = "azureml" $relayResourceIDKey = "relayserver.hybridConnectionResourceID" + $serviceBusResourceIDKey = "servicebus.resourceID" . $PSScriptRoot/../../helper/Constants.ps1 . $PSScriptRoot/../../helper/Helper.ps1 @@ -78,6 +79,14 @@ Describe 'AzureML Kubernetes Testing' { } It "Deletes the extension from the cluster" { + # cleanup the relay and servicebus + $relayResourceID = Get-ExtensionConfigurationSettings $extensionName $relayResourceIDKey + $serviceBusResourceID = Get-ExtensionConfigurationSettings $extensionName $serviceBusResourceIDKey + $relayNamespaceName = $relayResourceID.split("/")[8] + $serviceBusNamespaceName = $serviceBusResourceID.split("/")[8] + az relay namespace delete --resource-group $ENVCONFIG.resourceGroup --name $relayNamespaceName + az servicebus namespace delete --resource-group $ENVCONFIG.resourceGroup --name $serviceBusNamespaceName + az k8s-extension delete --cluster-name $ENVCONFIG.arcClusterName -g $ENVCONFIG.resourceGroup --cluster-type connectedClusters --name $extensionName $? | Should -BeTrue