diff --git a/src/aks-preview/azext_aks_preview/_consts.py b/src/aks-preview/azext_aks_preview/_consts.py index ab9a16d2e78..351a016a31a 100644 --- a/src/aks-preview/azext_aks_preview/_consts.py +++ b/src/aks-preview/azext_aks_preview/_consts.py @@ -332,3 +332,11 @@ # GPU Driver Type Consts CONST_GPU_DRIVER_TYPE_CUDA = "CUDA" CONST_GPU_DRIVER_TYPE_GRID = "GRID" + +# aks extension constants +CONST_K8S_EXTENSION_CUSTOM_MOD_NAME = "azext_k8s_extension.custom" +CONST_K8S_EXTENSION_CLIENT_FACTORY_MOD_NAME = "azext_k8s_extension._client_factory" +CONST_K8S_EXTENSION_TYPE_CLIENT_FACTORY_MOD_NAME = "azext_k8s_extension_types._client_factory" +CONST_K8S_EXTENSION_NAME = "k8s-extension" +CONST_K8S_EXTENSION_ACTION_MOD_NAME = "azext_k8s_extension.action" +CONST_K8S_EXTENSION_FORMAT_MOD_NAME = "azext_k8s_extension._format" diff --git a/src/aks-preview/azext_aks_preview/_format.py b/src/aks-preview/azext_aks_preview/_format.py index b0b0ced6caa..c7323eb6118 100644 --- a/src/aks-preview/azext_aks_preview/_format.py +++ b/src/aks-preview/azext_aks_preview/_format.py @@ -373,3 +373,76 @@ def _format_mesh_revision_entry(revision): } flattened.append(item) return flattened + + +def aks_extension_list_table_format(results): + """Format a list of K8s extensions as summary results for display with "-o table". """ + return [_get_table_row(result) for result in results] + + +def aks_extension_show_table_format(result): + """Format a K8s extension as summary results for display with "-o table". """ + return _get_table_row(result) + + +def _get_table_row(result): + return OrderedDict([ + ('name', result['name']), + ('extensionType', result.get('extensionType', '')), + ('version', result.get('version', '')), + ('provisioningState', result.get('provisioningState', '')), + ('lastModifiedAt', result.get('systemData', {}).get('lastModifiedAt', '')), + ('isSystemExtension', result.get('isSystemExtension', '')), + ]) + + +def aks_extension_types_list_table_format(results): + """Format a list of K8s extension types as summary results for display with "-o table". """ + return [_get_extension_type_table_row(result) for result in results] + + +def aks_extension_type_show_table_format(result): + """Format a K8s extension type as summary results for display with "-o table". """ + return _get_extension_type_table_row(result) + + +def _get_extension_type_table_row(result): + # Populate the values to be returned if they are not undefined + clusterTypes = '' + if result['properties']['supportedClusterTypes'] is not None: + clusterTypes = ', '.join(result['properties']['supportedClusterTypes']) + + name = result['name'] + defaultScope, allowMultInstances, defaultReleaseNamespace = '', '', '' + if result['properties']['supportedScopes']: + defaultScope = result['properties']['supportedScopes']['defaultScope'] + if result['properties']['supportedScopes']['clusterScopeSettings'] is not None: + clusterScopeSettings = result['properties']['supportedScopes']['clusterScopeSettings'] + allowMultInstances = clusterScopeSettings['allowMultipleInstances'] + defaultReleaseNamespace = clusterScopeSettings['defaultReleaseNamespace'] + + retVal = OrderedDict([ + ('name', name), + ('defaultScope', defaultScope), + ('clusterTypes', clusterTypes), + ('allowMultipleInstances', allowMultInstances), + ('defaultReleaseNamespace', defaultReleaseNamespace) + ]) + + return retVal + + +def aks_extension_type_versions_list_table_format(results): + """Format a list of K8s extension type versions as summary results for display with "-o table". """ + return [_get_extension_type_versions_table_row(result) for result in results] + + +def aks_extension_type_version_show_table_format(results): + """Format a K8s extension type version as summary results for display with "-o table". """ + return _get_extension_type_versions_table_row(results) + + +def _get_extension_type_versions_table_row(result): + return OrderedDict([ + ('versions', result['properties']['version']) + ]) diff --git a/src/aks-preview/azext_aks_preview/_help.py b/src/aks-preview/azext_aks_preview/_help.py index bf66c4fb016..40993059ed5 100644 --- a/src/aks-preview/azext_aks_preview/_help.py +++ b/src/aks-preview/azext_aks_preview/_help.py @@ -3301,6 +3301,107 @@ short-summary: Additional endpoint(s) to perform the connectivity check, separated by comma. """ +helps['aks extension'] = """ + type: group + short-summary: Commands to manage extensions in Kubernetes cluster +""" + +helps['aks extension create'] = """ + type: command + short-summary: Creates the Kubernetes extension instance on the managed cluster. Please refer to the example at the end to see how to create a k8s extension + long-summary: Create a Kubernetes Extension. \ +The output includes secrets that you must protect. Be sure that you do not include these secrets in your \ + source control. Also verify that no secrets are present in the logs of your command or script. \ + For additional information, see http://aka.ms/clisecrets. + parameters: + - name: --extension-type -t + type: string + short-summary: Name of the extension type + - name: --cluster-name -c + type: string + short-summary: Name of the AKS cluster + - name: --name -n + type: string + short-summary: Name of the extension instance + - name: --scope + type: string + short-summary: specify scope of the extension type, takes in name or cluster as the scope + - name: --release-train + type: string + short-summary: specify the release train for the extension type + examples: + - name: Install K8s extension on AKS cluster + text: az aks extension create --resource-group my-resource-group \ +--cluster-name mycluster --name myextension --extension-type microsoft.openservicemesh \ +--scope cluster --release-train stable +""" + +helps['aks extension update'] = """ + type: command + short-summary: Update mutable properties of a Kubernetes Extension. + long-summary: For update to ConfigSettings and ConfigProtectedSettings, please \ +refer to documentation of the cluster extension service to check update to these \ +properties is supported before updating these properties. \ +The output includes secrets that you must protect. Be sure that you do not include these secrets in your \ + source control. Also verify that no secrets are present in the logs of your command or script. \ + For additional information, see http://aka.ms/clisecrets. + parameters: + - name: --cluster-name -c + type: string + short-summary: Name of the AKS cluster + - name: --name -n + type: string + short-summary: Name of the extension instance + - name: --release-train + type: string + short-summary: specify the release train for the extension type + - name: --version + type: string + short-summary: Specify the version to install for the extension instance if --auto-upgrade-minor-version is not enabled. + examples: + - name: Update K8s extension on AKS cluster + text: az aks extension update --resource-group my-resource-group \ +--cluster-name mycluster --name myextension --auto-upgrade true/false \ +--version extension-version --release-train stable \ +--configuration-settings settings-key=settings-value \ +--config-protected-settings protected-settings-key=protected-value \ +--config-settings-file=config-settings-file \ +--config-protected-file=protected-settings-file +""" + +helps['aks extension delete'] = """ + type: command + short-summary: Delete a Kubernetes Extension. + parameters: + - name: --cluster-name -c + type: string + short-summary: Name of the AKS cluster + - name: --name -n + type: string + short-summary: Name of the extension instance + examples: + - name: Delete an existing Kubernetes extension on AKS cluster + text: az aks extension delete --resource-group resource-group --cluster-name cluster --name ext +""" + +helps['aks extension show'] = """ + type: command + short-summary: Show a Kubernetes Extension + long-summary: Show a Kubernetes Extension including its properties. \ +The output includes secrets that you must protect. Be sure that you do not include these secrets in your \ + source control. Also verify that no secrets are present in the logs of your command or script. \ + For additional information, see http://aka.ms/clisecrets. + parameters: + - name: --cluster-name -c + type: string + short-summary: Name of the AKS cluster + - name: --name -n + type: string + short-summary: Name of the extension instance + examples: + - name: Show details of a Kubernetes Extension + text: az aks extension show --resource-group my-resource-group \ +--cluster-name mycluster --name myextension helps['aks loadbalancer'] = """ type: group short-summary: Commands to manage load balancer configurations in a managed Kubernetes cluster. diff --git a/src/aks-preview/azext_aks_preview/_helpers.py b/src/aks-preview/azext_aks_preview/_helpers.py index e952f238318..2880c6ae4c9 100644 --- a/src/aks-preview/azext_aks_preview/_helpers.py +++ b/src/aks-preview/azext_aks_preview/_helpers.py @@ -19,7 +19,8 @@ from azext_aks_preview._consts import ( ADDONS, - CONST_MONITORING_ADDON_NAME + CONST_MONITORING_ADDON_NAME, + CONST_K8S_EXTENSION_NAME, ) from azure.cli.command_modules.acs._helpers import map_azure_error_to_cli_error @@ -28,6 +29,7 @@ FileOperationError, InvalidArgumentValueError, ResourceNotFoundError, + UnknownError, ) from azure.core.exceptions import AzureError from knack.log import get_logger @@ -395,3 +397,24 @@ def filter_hard_taints(node_initialization_taints: List[str]) -> List[str]: # If the taint doesn't have a recognizable format, keep it, if it's incorrect - AKS-RP will return an error filtered_taints.append(taint) return filtered_taints + + +def get_k8s_extension_module(module_name): + try: + # adding the installed extension in the path + from azure.cli.core.extension.operations import add_extension_to_path + add_extension_to_path(CONST_K8S_EXTENSION_NAME) + # import the extension module + from importlib import import_module + azext_custom = import_module(module_name) + return azext_custom + except ImportError: + raise UnknownError( # pylint: disable=raise-missing-from + "Please add CLI extension `k8s-extension` for performing K8s extension operations.\n" + "Run command `az extension add --name k8s-extension`" + ) + + +def check_if_extension_type_is_in_allow_list(extension_type_name): + allowedListOfExtensions = ["microsoft.dataprotection.kubernetes", "microsoft.flux"] + return extension_type_name.lower() in allowedListOfExtensions diff --git a/src/aks-preview/azext_aks_preview/_params.py b/src/aks-preview/azext_aks_preview/_params.py index b78881df786..363286b981d 100644 --- a/src/aks-preview/azext_aks_preview/_params.py +++ b/src/aks-preview/azext_aks_preview/_params.py @@ -33,6 +33,7 @@ tags_type, zones_type, ) +from azure.cli.core.commands.validators import get_default_location_from_resource_group from azext_aks_preview._client_factory import CUSTOM_MGMT_AKS_PREVIEW from azext_aks_preview._completers import ( get_k8s_upgrades_completion_list, @@ -131,6 +132,7 @@ CONST_GPU_DRIVER_TYPE_CUDA, CONST_GPU_DRIVER_TYPE_GRID, ) + from azext_aks_preview._validators import ( validate_acr, validate_addon, @@ -218,6 +220,12 @@ CONST_STORAGE_POOL_OPTION_NVME, CONST_STORAGE_POOL_OPTION_SSD, ) + +from .action import ( + AddConfigurationSettings, + AddConfigurationProtectedSettings, +) + from knack.arguments import CLIArgumentType # candidates for enumeration @@ -2325,6 +2333,105 @@ def load_arguments(self, _): help='Space-separated additional endpoint(s) to perform the connectivity check.', validator=validate_custom_endpoints) + # Reference: https://learn.microsoft.com/en-us/cli/azure/k8s-extension?view=azure-cli-latest + with self.argument_context('aks extension') as c: + c.argument('resource_group_name', + options_list=['--resource-group', '-g'], + help='Name of resource group.') + c.argument('location', + validator=get_default_location_from_resource_group) + c.argument('name', + options_list=['--name', '-n'], + help='Name of the extension instance') + c.argument('extension_type', + options_list=['--extension-type', '-t'], + help='Name of the extension type.') + c.argument('cluster_name', + options_list=['--cluster-name', '-c'], + help='Name of the Kubernetes cluster') + c.argument('scope', + arg_type=get_enum_type(['cluster', 'namespace']), + help='Specify the extension scope.') + c.argument('auto_upgrade_minor_version', + arg_group="Version", + options_list=['--auto-upgrade-minor-version', '--auto-upgrade'], + arg_type=get_three_state_flag(), + help='Automatically upgrade minor version of the extension instance.') + c.argument('version', + arg_group="Version", + help='Specify the version to install for the extension instance if' + ' --auto-upgrade-minor-version is not enabled.') + c.argument('release_train', + arg_group="Version", + help='Specify the release train for the extension type.') + c.argument('configuration_settings', + arg_group="Configuration", + options_list=['--configuration-settings', '--config'], + action=AddConfigurationSettings, + nargs='+', + help='Configuration Settings as key=value pair.' + + 'Repeat parameter for each setting.' + + 'Do not use this for secrets, as this value is returned in response.') + c.argument('configuration_protected_settings', + arg_group="Configuration", + options_list=['--config-protected-settings', '--config-protected'], + action=AddConfigurationProtectedSettings, + nargs='+', + help='Configuration Protected Settings as key=value pair.' + + 'Repeat parameter for each setting. Only the key is returned in response, the value is not.') + c.argument('configuration_settings_file', + arg_group="Configuration", + options_list=['--config-settings-file', '--config-file'], + help='JSON file path for configuration-settings') + c.argument('configuration_protected_settings_file', + arg_group="Configuration", + options_list=['--config-protected-settings-file', '--config-protected-file'], + help='JSON file path for configuration-protected-settings') + c.argument('release_namespace', + help='Specify the namespace to install the extension release.') + c.argument('target_namespace', + help='Specify the target namespace to install to for the extension instance. This' + ' parameter is required if extension scope is set to \'namespace\'') + + with self.argument_context("aks extension update") as c: + c.argument('yes', + options_list=['--yes', '-y'], + help='Ignore confirmation prompts') + + with self.argument_context("aks extension delete") as c: + c.argument('yes', + options_list=['--yes', '-y'], + help='Ignore confirmation prompts') + c.argument('force', + help='Specify whether to force delete the extension from the cluster.') + + # Reference: https://learn.microsoft.com/en-us/cli/azure/k8s-extension/extension-types?view=azure-cli-latest + with self.argument_context("aks extension-type") as c: + c.argument('resource_group_name', + options_list=['--resource-group', '-g'], + help='Name of resource group.') + c.argument('cluster_name', + options_list=['--cluster-name', '-c'], + help='Name of the Kubernetes cluster') + c.argument('extension_type', + options_list=['--extension-type', '-t'], + help='Name of the extension type.') + c.argument('location', + validator=get_default_location_from_resource_group, + help='Name of the location. Values from: `az account list-locations`') + c.argument('version', + help='Version for the extension type.') + c.argument('major_version', + help='Filter results by only the major version of an extension type.' + + 'For example if 1 is specified, all versions with major version 1 (1.1, 1.1.2) will be shown.' + + 'The default value is None') + c.argument('release_train', + arg_group="Version", + help='Specify the release train for the extension type.') + c.argument('show_latest', + arg_type=get_three_state_flag(), + help='Filter results by only the latest version.' + + 'For example, if this flag is used the latest version of the extensionType will be shown.') # AKS loadbalancer command parameter configuration with self.argument_context("aks loadbalancer add") as c: c.argument( diff --git a/src/aks-preview/azext_aks_preview/action.py b/src/aks-preview/azext_aks_preview/action.py new file mode 100644 index 00000000000..73fd3dfefde --- /dev/null +++ b/src/aks-preview/azext_aks_preview/action.py @@ -0,0 +1,41 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +import argparse +from azure.cli.core.azclierror import ArgumentUsageError + +# pylint: disable=protected-access, too-few-public-methods + +# Reference: https://github.com/Azure/azure-cli-extensions/blob/main/src/k8s-extension/azext_k8s_extension/action.py +# TODO: Update this file if there are changes to this class in the k8s-extensions folder + + +class AddConfigurationSettings(argparse._AppendAction): + + def __call__(self, parser, namespace, values, option_string=None): + settings = {} + for item in values: + try: + key, value = item.split('=', 1) + settings[key] = value + except ValueError as ex: + raise ArgumentUsageError('Usage error: {} configuration_setting_key=configuration_setting_value'. + format(option_string)) from ex + super().__call__(parser, namespace, settings, option_string) + + +# pylint: disable=protected-access, too-few-public-methods +class AddConfigurationProtectedSettings(argparse._AppendAction): + + def __call__(self, parser, namespace, values, option_string=None): + prot_settings = {} + for item in values: + try: + key, value = item.split('=', 1) + prot_settings[key] = value + except ValueError as ex: + raise ArgumentUsageError('Usage error: {} configuration_protected_setting_key=' + 'configuration_protected_setting_value'.format(option_string)) from ex + super().__call__(parser, namespace, prot_settings, option_string) diff --git a/src/aks-preview/azext_aks_preview/commands.py b/src/aks-preview/azext_aks_preview/commands.py index 877639bdf92..26e5a144f4e 100644 --- a/src/aks-preview/azext_aks_preview/commands.py +++ b/src/aks-preview/azext_aks_preview/commands.py @@ -17,6 +17,7 @@ cf_operations, cf_load_balancers, ) + from azext_aks_preview._format import ( aks_addon_list_available_table_format, aks_addon_list_table_format, @@ -38,7 +39,14 @@ aks_versions_table_format, aks_mesh_revisions_table_format, aks_mesh_upgrades_table_format, + aks_extension_list_table_format, + aks_extension_show_table_format, + aks_extension_types_list_table_format, + aks_extension_type_show_table_format, + aks_extension_type_versions_list_table_format, + aks_extension_type_version_show_table_format, ) + from knack.log import get_logger logger = get_logger(__name__) @@ -466,3 +474,65 @@ def load_command_table(self, _): "aks check-network", managed_clusters_sdk, client_factory=cf_managed_clusters ) as g: g.custom_command("outbound", "aks_check_network_outbound") + + with self.command_group( + "aks extension", managed_clusters_sdk, client_factory=cf_managed_clusters + ) as g: + g.custom_command('create', 'create_k8s_extension', supports_no_wait=True) + g.custom_command('delete', 'delete_k8s_extension', supports_no_wait=True) + g.custom_command( + 'list', + 'list_k8s_extension', + table_transformer=aks_extension_list_table_format + ) + g.custom_show_command( + 'show', + 'show_k8s_extension', + table_transformer=aks_extension_show_table_format + ) + g.custom_command('update', 'update_k8s_extension', supports_no_wait=True) + + with self.command_group( + "aks extension-type", managed_clusters_sdk, client_factory=cf_managed_clusters + ) as g: + g.custom_command( + 'list-by-location', + 'list_k8s_extension_types_by_location', + table_transformer=aks_extension_types_list_table_format + ) + g.custom_command( + 'show-by-location', + 'show_k8s_extension_type_by_location', + table_transformer=aks_extension_type_show_table_format + ) + g.custom_command( + 'list-versions-by-location', + 'list_k8s_extension_type_versions_by_location', + table_transformer=aks_extension_type_versions_list_table_format + ) + g.custom_command( + 'show-version-by-location', + 'show_k8s_extension_type_version_by_location', + table_transformer=aks_extension_type_version_show_table_format + ) + + g.custom_command( + 'list-by-cluster', + 'list_k8s_extension_types_by_cluster', + table_transformer=aks_extension_types_list_table_format + ) + g.custom_command( + 'show-by-cluster', + 'show_k8s_extension_type_by_cluster', + table_transformer=aks_extension_type_show_table_format + ) + g.custom_command( + 'list-versions-by-cluster', + 'list_k8s_extension_type_versions_by_cluster', + table_transformer=aks_extension_type_versions_list_table_format + ) + g.custom_command( + 'show-version-by-cluster', + 'show_k8s_extension_type_version_by_cluster', + table_transformer=aks_extension_type_version_show_table_format + ) diff --git a/src/aks-preview/azext_aks_preview/custom.py b/src/aks-preview/azext_aks_preview/custom.py index 85170afc006..3263f0827e0 100644 --- a/src/aks-preview/azext_aks_preview/custom.py +++ b/src/aks-preview/azext_aks_preview/custom.py @@ -3,7 +3,7 @@ # Licensed under the MIT License. See License.txt in the project root for license information. # -------------------------------------------------------------------------------------------- -# pylint: disable=too-many-lines +# pylint: disable=too-many-lines, disable=broad-except import datetime import json import os @@ -57,14 +57,18 @@ CONST_AVAILABILITY_SET, CONST_MIN_NODE_IMAGE_VERSION, CONST_ARTIFACT_SOURCE_DIRECT, + CONST_K8S_EXTENSION_CUSTOM_MOD_NAME, + CONST_K8S_EXTENSION_CLIENT_FACTORY_MOD_NAME, ) from azext_aks_preview._helpers import ( check_is_private_link_cluster, get_cluster_snapshot_by_snapshot_id, + get_k8s_extension_module, get_nodepool_snapshot_by_snapshot_id, print_or_merge_credentials, process_message_for_run_command, check_is_monitoring_addon_enabled, + check_if_extension_type_is_in_allow_list, ) from azext_aks_preview._podidentity import ( _ensure_managed_identity_operator_permission, @@ -3706,6 +3710,375 @@ def aks_check_network_outbound( custom_endpoints) +def create_k8s_extension( + cmd, + client, + resource_group_name, + cluster_name, + name, + extension_type, + scope=None, + auto_upgrade_minor_version=None, + release_train=None, + version=None, + target_namespace=None, + release_namespace=None, + configuration_settings=None, + configuration_protected_settings=None, + configuration_settings_file=None, + configuration_protected_settings_file=None, + no_wait=False, +): + if not check_if_extension_type_is_in_allow_list(extension_type.lower()): + raise ValidationError(f"Failed to install {extension_type.lower()} " + + "as it is not in allowed list of extension types") + + k8s_extension_custom_mod = get_k8s_extension_module(CONST_K8S_EXTENSION_CUSTOM_MOD_NAME) + client_factory = get_k8s_extension_module(CONST_K8S_EXTENSION_CLIENT_FACTORY_MOD_NAME) + client = client_factory.cf_k8s_extension_operation(cmd.cli_ctx) + + try: + result = k8s_extension_custom_mod.create_k8s_extension( + cmd, + client, + resource_group_name, + cluster_name, + name=name, + cluster_type="managedClusters", + extension_type=extension_type, + auto_upgrade_minor_version=auto_upgrade_minor_version, + release_train=release_train, + scope=scope, + version=version, + target_namespace=target_namespace, + release_namespace=release_namespace, + configuration_settings=configuration_settings, + configuration_protected_settings=configuration_protected_settings, + configuration_settings_file=configuration_settings_file, + configuration_protected_settings_file=configuration_protected_settings_file, + no_wait=no_wait, + ) + return result + except Exception as ex: + logger.error("K8s extension failed to install.\nError: %s", ex) + + +def list_k8s_extension( + cmd, + client, + resource_group_name, + cluster_name +): + k8s_extension_custom_mod = get_k8s_extension_module(CONST_K8S_EXTENSION_CUSTOM_MOD_NAME) + client_factory = get_k8s_extension_module(CONST_K8S_EXTENSION_CLIENT_FACTORY_MOD_NAME) + client = client_factory.cf_k8s_extension_operation(cmd.cli_ctx) + + try: + result = k8s_extension_custom_mod.list_k8s_extension( + client, + resource_group_name, + cluster_name, + cluster_type="managedClusters", + ) + return result + except Exception as ex: + logger.error("Failed to list the K8s extension.\nError: %s", ex) + + +def update_k8s_extension( + cmd, + client, + resource_group_name, + cluster_name, + name, + auto_upgrade_minor_version=None, + release_train=None, + version=None, + configuration_settings=None, + configuration_protected_settings=None, + configuration_settings_file=None, + configuration_protected_settings_file=None, + no_wait=False, + yes=False, +): + k8s_extension_custom_mod = get_k8s_extension_module(CONST_K8S_EXTENSION_CUSTOM_MOD_NAME) + client_factory = get_k8s_extension_module(CONST_K8S_EXTENSION_CLIENT_FACTORY_MOD_NAME) + client = client_factory.cf_k8s_extension_operation(cmd.cli_ctx) + + try: + result = k8s_extension_custom_mod.update_k8s_extension( + cmd, + client, + resource_group_name, + cluster_name, + name, + "managedClusters", + auto_upgrade_minor_version=auto_upgrade_minor_version, + release_train=release_train, + version=version, + configuration_settings=configuration_settings, + configuration_protected_settings=configuration_protected_settings, + configuration_settings_file=configuration_settings_file, + configuration_protected_settings_file=configuration_protected_settings_file, + no_wait=no_wait, + yes=yes, + ) + return result + except Exception as ex: + logger.error("K8s extension failed to patch.\nError: %s", ex) + + +def delete_k8s_extension( + cmd, + client, + resource_group_name, + cluster_name, + name, + no_wait=False, + yes=False, + force=False, +): + k8s_extension_custom_mod = get_k8s_extension_module(CONST_K8S_EXTENSION_CUSTOM_MOD_NAME) + client_factory = get_k8s_extension_module(CONST_K8S_EXTENSION_CLIENT_FACTORY_MOD_NAME) + client = client_factory.cf_k8s_extension_operation(cmd.cli_ctx) + + try: + result = k8s_extension_custom_mod.delete_k8s_extension( + cmd, + client, + resource_group_name, + cluster_name, + name, + "managedClusters", + no_wait=no_wait, + yes=yes, + force=force, + ) + return result + except Exception as ex: + logger.error("Failed to delete K8s extension.\nError: %s", ex) + + +def show_k8s_extension(cmd, client, resource_group_name, cluster_name, name): + k8s_extension_custom_mod = get_k8s_extension_module(CONST_K8S_EXTENSION_CUSTOM_MOD_NAME) + client_factory = get_k8s_extension_module(CONST_K8S_EXTENSION_CLIENT_FACTORY_MOD_NAME) + client = client_factory.cf_k8s_extension_operation(cmd.cli_ctx) + + try: + result = k8s_extension_custom_mod.show_k8s_extension( + client, + resource_group_name, + cluster_name, + name, + "managedClusters", + ) + return result + except Exception as ex: + logger.error("Failed to get K8s extension.\nError: %s", ex) + + +def list_k8s_extension_types_by_location(cmd, client, location): + k8s_extension_custom_mod = get_k8s_extension_module(CONST_K8S_EXTENSION_CUSTOM_MOD_NAME) + client_factory = get_k8s_extension_module(CONST_K8S_EXTENSION_CLIENT_FACTORY_MOD_NAME) + client = client_factory.cf_k8s_extension_types(cmd.cli_ctx) + try: + result = k8s_extension_custom_mod.list_extension_types_by_location( + client, + location, + ) + return result + except Exception as ex: + logger.error("Failed to list K8s extension types by location.\nError: %s", ex) + + +# get by location +def show_k8s_extension_type_by_location(cmd, client, location, extension_type): + if not check_if_extension_type_is_in_allow_list(extension_type.lower()): + raise ValidationError(f"Failed to get extension type {extension_type.lower()} by location " + + "as it is not in allowed list of extension types") + k8s_extension_custom_mod = get_k8s_extension_module(CONST_K8S_EXTENSION_CUSTOM_MOD_NAME) + client_factory = get_k8s_extension_module(CONST_K8S_EXTENSION_CLIENT_FACTORY_MOD_NAME) + client = client_factory.cf_k8s_extension_types(cmd.cli_ctx) + try: + result = k8s_extension_custom_mod.show_extension_type_by_location( + client, + location, + extension_type, + ) + return result + except Exception as ex: + logger.error("Failed to get K8s extension types by location.\nError: %s", ex) + + +# list version by location +def list_k8s_extension_type_versions_by_location( + cmd, + client, + location, + extension_type, + release_train=None, + major_version=None, + show_latest=False +): + if not check_if_extension_type_is_in_allow_list(extension_type.lower()): + raise ValidationError(f"Failed to list extension type versions by location for {extension_type.lower()} " + + "as it is not in allowed list of extension types") + k8s_extension_custom_mod = get_k8s_extension_module(CONST_K8S_EXTENSION_CUSTOM_MOD_NAME) + client_factory = get_k8s_extension_module(CONST_K8S_EXTENSION_CLIENT_FACTORY_MOD_NAME) + client = client_factory.cf_k8s_extension_types(cmd.cli_ctx) + try: + result = k8s_extension_custom_mod.list_extension_type_versions_by_location( + client, + location, + extension_type, + release_train=release_train, + cluster_type="managedClusters", + major_version=major_version, + show_latest=show_latest, + ) + return result + except Exception as ex: + logger.error("Failed to list K8s extension type versions by location.\nError: %s", ex) + + +# show version by location +def show_k8s_extension_type_version_by_location( + cmd, + client, + location, + extension_type, + version +): + if not check_if_extension_type_is_in_allow_list(extension_type.lower()): + raise ValidationError(f"Failed to get extension type version by location for {extension_type.lower()} " + + "as it is not in allowed list of extension types") + k8s_extension_custom_mod = get_k8s_extension_module(CONST_K8S_EXTENSION_CUSTOM_MOD_NAME) + client_factory = get_k8s_extension_module(CONST_K8S_EXTENSION_CLIENT_FACTORY_MOD_NAME) + client = client_factory.cf_k8s_extension_types(cmd.cli_ctx) + try: + result = k8s_extension_custom_mod.show_extension_type_version_by_location( + client, + location, + extension_type, + version, + ) + return result + except Exception as ex: + logger.error("Failed to get K8s extension type versions by location.\nError: %s", ex) + + +def list_k8s_extension_types_by_cluster( + cmd, + client, + resource_group_name, + cluster_name, + release_train=None +): + k8s_extension_custom_mod = get_k8s_extension_module(CONST_K8S_EXTENSION_CUSTOM_MOD_NAME) + client_factory = get_k8s_extension_module(CONST_K8S_EXTENSION_CLIENT_FACTORY_MOD_NAME) + client = client_factory.cf_k8s_extension_types(cmd.cli_ctx) + try: + result = k8s_extension_custom_mod.list_extension_types_by_cluster( + client, + resource_group_name, + cluster_name, + "managedClusters", + release_train=release_train, + ) + return result + except Exception as ex: + logger.error("Failed to list K8s extension type versions by cluster.\nError: %s", ex) + + +# get by cluster +def show_k8s_extension_type_by_cluster( + cmd, + client, + resource_group_name, + cluster_name, + extension_type +): + if not check_if_extension_type_is_in_allow_list(extension_type.lower()): + raise ValidationError(f"Failed to get extension type {extension_type.lower()} by cluster " + + "as it is not in allowed list of extension types") + k8s_extension_custom_mod = get_k8s_extension_module(CONST_K8S_EXTENSION_CUSTOM_MOD_NAME) + client_factory = get_k8s_extension_module(CONST_K8S_EXTENSION_CLIENT_FACTORY_MOD_NAME) + client = client_factory.cf_k8s_extension_types(cmd.cli_ctx) + try: + result = k8s_extension_custom_mod.show_extension_type_by_cluster( + client, + resource_group_name, + cluster_name, + "managedClusters", + extension_type, + ) + return result + except Exception as ex: + logger.error("Failed to get K8s extension type by cluster.\nError: %s", ex) + + +# list version by cluster +def list_k8s_extension_type_versions_by_cluster( + cmd, + client, + resource_group_name, + cluster_name, + extension_type, + release_train=None, + major_version=None, + show_latest=False +): + if not check_if_extension_type_is_in_allow_list(extension_type.lower()): + raise ValidationError(f"Failed to list extension type versions by cluster for {extension_type.lower()} " + + "as it is not in allowed list of extension types") + k8s_extension_custom_mod = get_k8s_extension_module(CONST_K8S_EXTENSION_CUSTOM_MOD_NAME) + client_factory = get_k8s_extension_module(CONST_K8S_EXTENSION_CLIENT_FACTORY_MOD_NAME) + client = client_factory.cf_k8s_extension_types(cmd.cli_ctx) + try: + result = k8s_extension_custom_mod.list_extension_type_versions_by_cluster( + client, + resource_group_name, + "managedClusters", + cluster_name, + extension_type, + release_train=release_train, + major_version=major_version, + show_latest=show_latest, + ) + return result + except Exception as ex: + logger.error("Failed to list K8s extension type versions by cluster.\nError: %s", ex) + + +# show version by cluster +def show_k8s_extension_type_version_by_cluster( + cmd, + client, + resource_group_name, + cluster_name, + extension_type, + version +): + if not check_if_extension_type_is_in_allow_list(extension_type.lower()): + raise ValidationError(f"Failed to get extension type version by cluster for {extension_type.lower()} " + + "as it is not in allowed list of extension types") + k8s_extension_custom_mod = get_k8s_extension_module(CONST_K8S_EXTENSION_CUSTOM_MOD_NAME) + client_factory = get_k8s_extension_module(CONST_K8S_EXTENSION_CLIENT_FACTORY_MOD_NAME) + client = client_factory.cf_k8s_extension_types(cmd.cli_ctx) + try: + result = k8s_extension_custom_mod.show_extension_type_version_by_cluster( + client, + resource_group_name, + "managedClusters", + cluster_name, + extension_type, + version + ) + return result + except Exception as ex: + logger.error("Failed to get K8s extension type versions by cluster.\nError: %s", ex) + + # pylint: disable=unused-argument def aks_loadbalancer_add( cmd,