From 9294d573f098f63f5e265a39390da50d78a719ce Mon Sep 17 00:00:00 2001 From: Fuming Zhang Date: Tue, 19 Oct 2021 17:55:10 +0800 Subject: [PATCH 01/10] update --- .../azext_aks_preview/decorator.py | 92 ++++++++++++++++++- .../tests/latest/test_decorator.py | 9 ++ 2 files changed, 100 insertions(+), 1 deletion(-) diff --git a/src/aks-preview/azext_aks_preview/decorator.py b/src/aks-preview/azext_aks_preview/decorator.py index 21695b2a8d7..ea6eb9d6b43 100644 --- a/src/aks-preview/azext_aks_preview/decorator.py +++ b/src/aks-preview/azext_aks_preview/decorator.py @@ -4,7 +4,7 @@ # -------------------------------------------------------------------------------------------- import os -from typing import Dict, TypeVar, Union +from typing import Dict, TypeVar, Union, List from azure.cli.command_modules.acs._consts import DecoratorMode from azure.cli.command_modules.acs.decorator import ( @@ -24,6 +24,14 @@ from azure.cli.core.commands import AzCliCommand from azure.cli.core.profiles import ResourceType from azure.cli.core.util import get_file_json +# TODO: change to import from azure.cli.command_modules.acs._consts +from azext_aks_preview._consts import ( + ADDONS, + CONST_INGRESS_APPGW_ADDON_NAME, + CONST_INGRESS_APPGW_SUBNET_CIDR, + CONST_MONITORING_ADDON_NAME, + CONST_MONITORING_USING_AAD_MSI_AUTH +) from knack.log import get_logger from azext_aks_preview._natgateway import create_nat_gateway_profile @@ -496,6 +504,88 @@ def get_enable_pod_identity_with_kubenet(self) -> bool: """ return self._get_enable_pod_identity_with_kubenet(enable_validation=True) + # pylint: disable=unused-argument + def _get_enable_addons(self, enable_validation: bool = False, **kwargs) -> List[str]: + print("Hello World!") + print(ADDONS) + return super()._get_enable_addons(enable_validation, ADDONS=ADDONS) + + def get_appgw_subnet_prefix(self) -> Union[str, None]: + """Obtain the value of appgw_subnet_prefix. + + [Deprecated] Note: this parameter is depracated and replaced by appgw_subnet_cidr. + + :return: string or None + """ + # read the original value passed by the command + appgw_subnet_prefix = self.raw_param.get("appgw_subnet_prefix") + # try to read the property value corresponding to the parameter from the `mc` object + if ( + self.mc and + self.mc.addon_profiles and + CONST_INGRESS_APPGW_ADDON_NAME in self.mc.addon_profiles and + self.mc.addon_profiles.get( + CONST_INGRESS_APPGW_ADDON_NAME + ).config.get(CONST_INGRESS_APPGW_SUBNET_CIDR) is not None + ): + appgw_subnet_prefix = self.mc.addon_profiles.get( + CONST_INGRESS_APPGW_ADDON_NAME + ).config.get(CONST_INGRESS_APPGW_SUBNET_CIDR) + + # this parameter does not need dynamic completion + # this parameter does not need validation + return appgw_subnet_prefix + + def get_enable_msi_auth_for_monitoring(self) -> Union[bool, None]: + """Obtain the value of enable_msi_auth_for_monitoring. + + Note: The arg type of this parameter supports three states (True, False or None), but the corresponding default + value in entry function is not None. + + :return: bool or None + """ + # read the original value passed by the command + enable_msi_auth_for_monitoring = self.raw_param.get("enable_msi_auth_for_monitoring") + # try to read the property value corresponding to the parameter from the `mc` object + if ( + self.mc and + self.mc.addon_profiles and + CONST_MONITORING_ADDON_NAME in self.mc.addon_profiles and + self.mc.addon_profiles.get( + CONST_MONITORING_ADDON_NAME + ).config.get(CONST_MONITORING_USING_AAD_MSI_AUTH) is not None + ): + enable_msi_auth_for_monitoring = self.mc.addon_profiles.get( + CONST_MONITORING_ADDON_NAME + ).config.get(CONST_MONITORING_USING_AAD_MSI_AUTH) + + # this parameter does not need dynamic completion + # this parameter does not need validation + return enable_msi_auth_for_monitoring + + # def get_enable_secret_rotation(self) -> bool: + # """Obtain the value of enable_secret_rotation. + + # :return: bool + # """ + # # read the original value passed by the command + # enable_secret_rotation = self.raw_param.get("enable_secret_rotation") + # # try to read the property value corresponding to the parameter from the `mc` object + # if ( + # self.mc and + # self.mc.addon_profiles and + # CONST_MONITORING_ADDON_NAME in self.mc.addon_profiles and + # self.mc.addon_profiles.get( + # CONST_MONITORING_ADDON_NAME + # ).config.get(CONST_MONITORING_USING_AAD_MSI_AUTH) is not None + # ): + # enable_msi_auth_for_monitoring = self.mc.addon_profiles.get( + # CONST_MONITORING_ADDON_NAME + # ).config.get(CONST_MONITORING_USING_AAD_MSI_AUTH) + + # # this parameter does not need dynamic completion + # # this parameter does not need validation + # return enable_msi_auth_for_monitoring class AKSPreviewCreateDecorator(AKSCreateDecorator): # pylint: disable=super-init-not-called diff --git a/src/aks-preview/azext_aks_preview/tests/latest/test_decorator.py b/src/aks-preview/azext_aks_preview/tests/latest/test_decorator.py index 1f24ba88a2c..e3697f2b535 100644 --- a/src/aks-preview/azext_aks_preview/tests/latest/test_decorator.py +++ b/src/aks-preview/azext_aks_preview/tests/latest/test_decorator.py @@ -464,6 +464,15 @@ def test_get_enable_pod_identity_with_kubenet(self): ctx_2.get_enable_pod_identity_with_kubenet(), False ) + def test_get_appgw_subnet_prefix(self): + ctx_1 = AKSPreviewContext( + self.cmd, + {"enable_addons": "monitoring,gitops"}, + self.models, + decorator_mode=DecoratorMode.CREATE, + ) + print(ctx_1.get_enable_addons()) + class AKSPreviewCreateDecoratorTestCase(unittest.TestCase): def setUp(self): From 194b0c9e416f12fedb5fe043f7f660ee9af85cd4 Mon Sep 17 00:00:00 2001 From: Fuming Zhang Date: Wed, 20 Oct 2021 15:35:26 +0800 Subject: [PATCH 02/10] overwriate _get_addon_consts --- .../azext_aks_preview/decorator.py | 67 ++++++++++++------- .../tests/latest/test_decorator.py | 14 ++-- 2 files changed, 51 insertions(+), 30 deletions(-) diff --git a/src/aks-preview/azext_aks_preview/decorator.py b/src/aks-preview/azext_aks_preview/decorator.py index ea6eb9d6b43..5aa23487db8 100644 --- a/src/aks-preview/azext_aks_preview/decorator.py +++ b/src/aks-preview/azext_aks_preview/decorator.py @@ -24,14 +24,6 @@ from azure.cli.core.commands import AzCliCommand from azure.cli.core.profiles import ResourceType from azure.cli.core.util import get_file_json -# TODO: change to import from azure.cli.command_modules.acs._consts -from azext_aks_preview._consts import ( - ADDONS, - CONST_INGRESS_APPGW_ADDON_NAME, - CONST_INGRESS_APPGW_SUBNET_CIDR, - CONST_MONITORING_ADDON_NAME, - CONST_MONITORING_USING_AAD_MSI_AUTH -) from knack.log import get_logger from azext_aks_preview._natgateway import create_nat_gateway_profile @@ -504,11 +496,30 @@ def get_enable_pod_identity_with_kubenet(self) -> bool: """ return self._get_enable_pod_identity_with_kubenet(enable_validation=True) - # pylint: disable=unused-argument - def _get_enable_addons(self, enable_validation: bool = False, **kwargs) -> List[str]: - print("Hello World!") - print(ADDONS) - return super()._get_enable_addons(enable_validation, ADDONS=ADDONS) + def _get_addon_consts(self) -> Dict[str, str]: + """Helper function to obtain the constants used by addons. + + Note: This is not a parameter of aks commands. + + :return: dict + """ + from azext_aks_preview._consts import ( + ADDONS, + CONST_GITOPS_ADDON_NAME, + CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME, + CONST_SECRET_ROTATION_ENABLED, + ) + + addon_consts = super()._get_addon_consts() + addon_consts["ADDONS"] = ADDONS + addon_consts["CONST_GITOPS_ADDON_NAME"] = CONST_GITOPS_ADDON_NAME + addon_consts[ + "CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME" + ] = CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME + addon_consts[ + "CONST_SECRET_ROTATION_ENABLED" + ] = CONST_SECRET_ROTATION_ENABLED + return addon_consts def get_appgw_subnet_prefix(self) -> Union[str, None]: """Obtain the value of appgw_subnet_prefix. @@ -517,20 +528,25 @@ def get_appgw_subnet_prefix(self) -> Union[str, None]: :return: string or None """ + # determine the value of constants + addon_consts = self._get_addon_consts() + ingress_appgw_addon_name = addon_consts.get("CONST_INGRESS_APPGW_ADDON_NAME") + ingress_appgw_subnet_cidr = addon_consts.get("CONST_INGRESS_APPGW_SUBNET_CIDR") + # read the original value passed by the command appgw_subnet_prefix = self.raw_param.get("appgw_subnet_prefix") # try to read the property value corresponding to the parameter from the `mc` object if ( self.mc and self.mc.addon_profiles and - CONST_INGRESS_APPGW_ADDON_NAME in self.mc.addon_profiles and + ingress_appgw_addon_name in self.mc.addon_profiles and self.mc.addon_profiles.get( - CONST_INGRESS_APPGW_ADDON_NAME - ).config.get(CONST_INGRESS_APPGW_SUBNET_CIDR) is not None + ingress_appgw_addon_name + ).config.get(ingress_appgw_subnet_cidr) is not None ): appgw_subnet_prefix = self.mc.addon_profiles.get( - CONST_INGRESS_APPGW_ADDON_NAME - ).config.get(CONST_INGRESS_APPGW_SUBNET_CIDR) + ingress_appgw_addon_name + ).config.get(ingress_appgw_subnet_cidr) # this parameter does not need dynamic completion # this parameter does not need validation @@ -544,20 +560,25 @@ def get_enable_msi_auth_for_monitoring(self) -> Union[bool, None]: :return: bool or None """ + # determine the value of constants + addon_consts = self._get_addon_consts() + monitoring_addon_name = addon_consts.get("CONST_MONITORING_ADDON_NAME") + monitoring_using_aad_msi_auth = addon_consts.get("CONST_MONITORING_USING_AAD_MSI_AUTH") + # read the original value passed by the command enable_msi_auth_for_monitoring = self.raw_param.get("enable_msi_auth_for_monitoring") # try to read the property value corresponding to the parameter from the `mc` object if ( self.mc and self.mc.addon_profiles and - CONST_MONITORING_ADDON_NAME in self.mc.addon_profiles and + monitoring_addon_name in self.mc.addon_profiles and self.mc.addon_profiles.get( - CONST_MONITORING_ADDON_NAME - ).config.get(CONST_MONITORING_USING_AAD_MSI_AUTH) is not None + monitoring_addon_name + ).config.get(monitoring_using_aad_msi_auth) is not None ): enable_msi_auth_for_monitoring = self.mc.addon_profiles.get( - CONST_MONITORING_ADDON_NAME - ).config.get(CONST_MONITORING_USING_AAD_MSI_AUTH) + monitoring_addon_name + ).config.get(monitoring_using_aad_msi_auth) # this parameter does not need dynamic completion # this parameter does not need validation diff --git a/src/aks-preview/azext_aks_preview/tests/latest/test_decorator.py b/src/aks-preview/azext_aks_preview/tests/latest/test_decorator.py index e3697f2b535..c8082728306 100644 --- a/src/aks-preview/azext_aks_preview/tests/latest/test_decorator.py +++ b/src/aks-preview/azext_aks_preview/tests/latest/test_decorator.py @@ -465,13 +465,13 @@ def test_get_enable_pod_identity_with_kubenet(self): ) def test_get_appgw_subnet_prefix(self): - ctx_1 = AKSPreviewContext( - self.cmd, - {"enable_addons": "monitoring,gitops"}, - self.models, - decorator_mode=DecoratorMode.CREATE, - ) - print(ctx_1.get_enable_addons()) + pass + + def test_get_enable_msi_auth_for_monitoring(self): + pass + + def test_get_enable_secret_rotation(self): + pass class AKSPreviewCreateDecoratorTestCase(unittest.TestCase): From 8adb24bc0ff2efa4c01ef33a23818c21f28f5c87 Mon Sep 17 00:00:00 2001 From: Fuming Zhang Date: Wed, 20 Oct 2021 17:45:54 +0800 Subject: [PATCH 03/10] refactor set up addon profiles --- .../azext_aks_preview/decorator.py | 159 +++++++++++++----- 1 file changed, 119 insertions(+), 40 deletions(-) diff --git a/src/aks-preview/azext_aks_preview/decorator.py b/src/aks-preview/azext_aks_preview/decorator.py index 5aa23487db8..8af2928cb38 100644 --- a/src/aks-preview/azext_aks_preview/decorator.py +++ b/src/aks-preview/azext_aks_preview/decorator.py @@ -4,7 +4,7 @@ # -------------------------------------------------------------------------------------------- import os -from typing import Dict, TypeVar, Union, List +from typing import Dict, List, Optional, TypeVar, Union from azure.cli.command_modules.acs._consts import DecoratorMode from azure.cli.command_modules.acs.decorator import ( @@ -27,6 +27,7 @@ from knack.log import get_logger from azext_aks_preview._natgateway import create_nat_gateway_profile +from azext_aks_preview.addonconfiguration import ensure_container_insights_for_monitoring logger = get_logger(__name__) @@ -530,8 +531,8 @@ def get_appgw_subnet_prefix(self) -> Union[str, None]: """ # determine the value of constants addon_consts = self._get_addon_consts() - ingress_appgw_addon_name = addon_consts.get("CONST_INGRESS_APPGW_ADDON_NAME") - ingress_appgw_subnet_cidr = addon_consts.get("CONST_INGRESS_APPGW_SUBNET_CIDR") + CONST_INGRESS_APPGW_ADDON_NAME = addon_consts.get("CONST_INGRESS_APPGW_ADDON_NAME") + CONST_INGRESS_APPGW_SUBNET_CIDR = addon_consts.get("CONST_INGRESS_APPGW_SUBNET_CIDR") # read the original value passed by the command appgw_subnet_prefix = self.raw_param.get("appgw_subnet_prefix") @@ -539,14 +540,14 @@ def get_appgw_subnet_prefix(self) -> Union[str, None]: if ( self.mc and self.mc.addon_profiles and - ingress_appgw_addon_name in self.mc.addon_profiles and + CONST_INGRESS_APPGW_ADDON_NAME in self.mc.addon_profiles and self.mc.addon_profiles.get( - ingress_appgw_addon_name - ).config.get(ingress_appgw_subnet_cidr) is not None + CONST_INGRESS_APPGW_ADDON_NAME + ).config.get(CONST_INGRESS_APPGW_SUBNET_CIDR) is not None ): appgw_subnet_prefix = self.mc.addon_profiles.get( - ingress_appgw_addon_name - ).config.get(ingress_appgw_subnet_cidr) + CONST_INGRESS_APPGW_ADDON_NAME + ).config.get(CONST_INGRESS_APPGW_SUBNET_CIDR) # this parameter does not need dynamic completion # this parameter does not need validation @@ -562,8 +563,8 @@ def get_enable_msi_auth_for_monitoring(self) -> Union[bool, None]: """ # determine the value of constants addon_consts = self._get_addon_consts() - monitoring_addon_name = addon_consts.get("CONST_MONITORING_ADDON_NAME") - monitoring_using_aad_msi_auth = addon_consts.get("CONST_MONITORING_USING_AAD_MSI_AUTH") + CONST_MONITORING_ADDON_NAME = addon_consts.get("CONST_MONITORING_ADDON_NAME") + CONST_MONITORING_USING_AAD_MSI_AUTH = addon_consts.get("CONST_MONITORING_USING_AAD_MSI_AUTH") # read the original value passed by the command enable_msi_auth_for_monitoring = self.raw_param.get("enable_msi_auth_for_monitoring") @@ -571,42 +572,51 @@ def get_enable_msi_auth_for_monitoring(self) -> Union[bool, None]: if ( self.mc and self.mc.addon_profiles and - monitoring_addon_name in self.mc.addon_profiles and + CONST_MONITORING_ADDON_NAME in self.mc.addon_profiles and self.mc.addon_profiles.get( - monitoring_addon_name - ).config.get(monitoring_using_aad_msi_auth) is not None + CONST_MONITORING_ADDON_NAME + ).config.get(CONST_MONITORING_USING_AAD_MSI_AUTH) is not None ): enable_msi_auth_for_monitoring = self.mc.addon_profiles.get( - monitoring_addon_name - ).config.get(monitoring_using_aad_msi_auth) + CONST_MONITORING_ADDON_NAME + ).config.get(CONST_MONITORING_USING_AAD_MSI_AUTH) # this parameter does not need dynamic completion # this parameter does not need validation return enable_msi_auth_for_monitoring - # def get_enable_secret_rotation(self) -> bool: - # """Obtain the value of enable_secret_rotation. - - # :return: bool - # """ - # # read the original value passed by the command - # enable_secret_rotation = self.raw_param.get("enable_secret_rotation") - # # try to read the property value corresponding to the parameter from the `mc` object - # if ( - # self.mc and - # self.mc.addon_profiles and - # CONST_MONITORING_ADDON_NAME in self.mc.addon_profiles and - # self.mc.addon_profiles.get( - # CONST_MONITORING_ADDON_NAME - # ).config.get(CONST_MONITORING_USING_AAD_MSI_AUTH) is not None - # ): - # enable_msi_auth_for_monitoring = self.mc.addon_profiles.get( - # CONST_MONITORING_ADDON_NAME - # ).config.get(CONST_MONITORING_USING_AAD_MSI_AUTH) - - # # this parameter does not need dynamic completion - # # this parameter does not need validation - # return enable_msi_auth_for_monitoring + def get_enable_secret_rotation(self) -> bool: + """Obtain the value of enable_secret_rotation. + + :return: bool + """ + # determine the value of constants + addon_consts = self._get_addon_consts() + CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME = addon_consts.get( + "CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME" + ) + CONST_SECRET_ROTATION_ENABLED = addon_consts.get( + "CONST_SECRET_ROTATION_ENABLED" + ) + + # read the original value passed by the command + enable_secret_rotation = self.raw_param.get("enable_secret_rotation") + # try to read the property value corresponding to the parameter from the `mc` object + if ( + self.mc and + self.mc.addon_profiles and + CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME in self.mc.addon_profiles and + self.mc.addon_profiles.get( + CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME + ).config.get(CONST_SECRET_ROTATION_ENABLED) is not None + ): + enable_secret_rotation = self.mc.addon_profiles.get( + CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME + ).config.get(CONST_SECRET_ROTATION_ENABLED) + + # this parameter does not need dynamic completion + # this parameter does not need validation + return enable_secret_rotation class AKSPreviewCreateDecorator(AKSCreateDecorator): # pylint: disable=super-init-not-called @@ -640,7 +650,7 @@ def set_up_agent_pool_profiles(self, mc: ManagedCluster) -> ManagedCluster: """Set up agent pool profiles for the ManagedCluster object. Call the method of the same name in the parent class to set up agent_pool_profiles, and then set some additional - properties on this basis. + properties. :return: the ManagedCluster object """ @@ -690,7 +700,7 @@ def set_up_network_profile(self, mc: ManagedCluster) -> ManagedCluster: """Set up network profile for the ManagedCluster object. Call the method of the same name in the parent class to set up network_profile, and then set the - nat_gateway_profile on this basis. + nat_gateway_profile. :return: the ManagedCluster object """ @@ -746,6 +756,75 @@ def set_up_pod_identity_profile(self, mc: ManagedCluster) -> ManagedCluster: mc.pod_identity_profile = pod_identity_profile return mc + def set_up_addon_profiles(self, mc: ManagedCluster, skip_addons: Optional[List[str]] = None) -> ManagedCluster: + """Set up addon profiles for the ManagedCluster object. + + Call the method of the same name in the parent class to set up addon_profiles, and then set some extra addons + and overwrite the process of setting the monitoring addon. + + :return: the ManagedCluster object + """ + # replace empty default value + if skip_addons is None: + skip_addons = [] + addon_consts = self.context._get_addon_consts() + CONST_MONITORING_ADDON_NAME = addon_consts.get( + "CONST_MONITORING_ADDON_NAME" + ) + CONST_MONITORING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID = addon_consts.get( + "CONST_MONITORING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID" + ) + CONST_MONITORING_USING_AAD_MSI_AUTH = addon_consts.get( + "CONST_MONITORING_USING_AAD_MSI_AUTH" + ) + CONST_SECRET_ROTATION_ENABLED = addon_consts.get( + "CONST_SECRET_ROTATION_ENABLED" + ) + CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME = addon_consts.get( + "CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME" + ) + + mc = super().set_up_addon_profiles(mc, skip_addons=["monitoring"]) + ManagedClusterAddonProfile = self.models.ManagedClusterAddonProfile + addon_profiles = mc.addon_profiles + addons = self.context.get_enable_addons() + if "monitoring" in addons: + workspace_resource_id = self.context.get_workspace_resource_id() + enable_msi_auth_for_monitoring = ( + self.context.get_enable_msi_auth_for_monitoring() + ) + addon_profiles[ + CONST_MONITORING_ADDON_NAME + ] = ManagedClusterAddonProfile( + enabled=True, + config={ + CONST_MONITORING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID: workspace_resource_id, + CONST_MONITORING_USING_AAD_MSI_AUTH: enable_msi_auth_for_monitoring, + }, + ) + # post-process, create a deployment + # TODO: fix signature + ensure_container_insights_for_monitoring( + self.cmd, addon_profiles[CONST_MONITORING_ADDON_NAME] + ) + # set intermediate + self.context.set_intermediate( + "monitoring", True, overwrite_exists=True + ) + if "azure-keyvault-secrets-provider" in addons: + addon_profile = ManagedClusterAddonProfile( + enabled=True, config={CONST_SECRET_ROTATION_ENABLED: "false"} + ) + if self.context.get_enable_secret_rotation(): + addon_profile.config[CONST_SECRET_ROTATION_ENABLED] = "true" + addon_profiles[ + CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME + ] = addon_profile + if "gitops" in addons: + addon_profiles["gitops"] = ManagedClusterAddonProfile(enabled=True) + mc.addon_profiles = addon_profiles + return mc + def construct_preview_mc_profile(self) -> ManagedCluster: """The overall controller used to construct the preview ManagedCluster profile. From d38577becadf3c048967a22f3fa66d7cd13e39db Mon Sep 17 00:00:00 2001 From: Fuming Zhang Date: Thu, 21 Oct 2021 09:54:31 +0800 Subject: [PATCH 04/10] fix lint --- src/aks-preview/azext_aks_preview/decorator.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/aks-preview/azext_aks_preview/decorator.py b/src/aks-preview/azext_aks_preview/decorator.py index 8af2928cb38..31fcb6e7a5b 100644 --- a/src/aks-preview/azext_aks_preview/decorator.py +++ b/src/aks-preview/azext_aks_preview/decorator.py @@ -497,7 +497,7 @@ def get_enable_pod_identity_with_kubenet(self) -> bool: """ return self._get_enable_pod_identity_with_kubenet(enable_validation=True) - def _get_addon_consts(self) -> Dict[str, str]: + def get_addon_consts(self) -> Dict[str, str]: """Helper function to obtain the constants used by addons. Note: This is not a parameter of aks commands. @@ -511,7 +511,7 @@ def _get_addon_consts(self) -> Dict[str, str]: CONST_SECRET_ROTATION_ENABLED, ) - addon_consts = super()._get_addon_consts() + addon_consts = super().get_addon_consts() addon_consts["ADDONS"] = ADDONS addon_consts["CONST_GITOPS_ADDON_NAME"] = CONST_GITOPS_ADDON_NAME addon_consts[ @@ -530,7 +530,7 @@ def get_appgw_subnet_prefix(self) -> Union[str, None]: :return: string or None """ # determine the value of constants - addon_consts = self._get_addon_consts() + addon_consts = self.get_addon_consts() CONST_INGRESS_APPGW_ADDON_NAME = addon_consts.get("CONST_INGRESS_APPGW_ADDON_NAME") CONST_INGRESS_APPGW_SUBNET_CIDR = addon_consts.get("CONST_INGRESS_APPGW_SUBNET_CIDR") @@ -562,7 +562,7 @@ def get_enable_msi_auth_for_monitoring(self) -> Union[bool, None]: :return: bool or None """ # determine the value of constants - addon_consts = self._get_addon_consts() + addon_consts = self.get_addon_consts() CONST_MONITORING_ADDON_NAME = addon_consts.get("CONST_MONITORING_ADDON_NAME") CONST_MONITORING_USING_AAD_MSI_AUTH = addon_consts.get("CONST_MONITORING_USING_AAD_MSI_AUTH") @@ -591,7 +591,7 @@ def get_enable_secret_rotation(self) -> bool: :return: bool """ # determine the value of constants - addon_consts = self._get_addon_consts() + addon_consts = self.get_addon_consts() CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME = addon_consts.get( "CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME" ) @@ -767,7 +767,7 @@ def set_up_addon_profiles(self, mc: ManagedCluster, skip_addons: Optional[List[s # replace empty default value if skip_addons is None: skip_addons = [] - addon_consts = self.context._get_addon_consts() + addon_consts = self.context.get_addon_consts() CONST_MONITORING_ADDON_NAME = addon_consts.get( "CONST_MONITORING_ADDON_NAME" ) From e28d384d527de3596d0ae1b3d3816d76511ab047 Mon Sep 17 00:00:00 2001 From: Fuming Zhang Date: Thu, 21 Oct 2021 14:33:27 +0800 Subject: [PATCH 05/10] fix monitoring addon --- .../azext_aks_preview/decorator.py | 93 +++++++++++++++++-- 1 file changed, 84 insertions(+), 9 deletions(-) diff --git a/src/aks-preview/azext_aks_preview/decorator.py b/src/aks-preview/azext_aks_preview/decorator.py index 31fcb6e7a5b..5b16b9e6582 100644 --- a/src/aks-preview/azext_aks_preview/decorator.py +++ b/src/aks-preview/azext_aks_preview/decorator.py @@ -4,6 +4,7 @@ # -------------------------------------------------------------------------------------------- import os +import time from typing import Dict, List, Optional, TypeVar, Union from azure.cli.command_modules.acs._consts import DecoratorMode @@ -25,9 +26,12 @@ from azure.cli.core.profiles import ResourceType from azure.cli.core.util import get_file_json from knack.log import get_logger +from msrestazure.azure_exceptions import CloudError from azext_aks_preview._natgateway import create_nat_gateway_profile -from azext_aks_preview.addonconfiguration import ensure_container_insights_for_monitoring +from azext_aks_preview.addonconfiguration import ( + ensure_container_insights_for_monitoring, +) logger = get_logger(__name__) @@ -391,7 +395,7 @@ def _get_enable_managed_identity( ) -> bool: """Internal function to obtain the value of enable_pod_identity. - Inherited and extended to perform additional validation. + Note: Inherited and extended in aks-preview to perform additional validation. This function supports the option of enable_validation. When enabled, if enable_managed_identity is not specified but enable_pod_identity is, raise a RequiredArgumentMissingError. @@ -500,16 +504,15 @@ def get_enable_pod_identity_with_kubenet(self) -> bool: def get_addon_consts(self) -> Dict[str, str]: """Helper function to obtain the constants used by addons. + Note: Inherited and extended in aks-preview to replace and add a few values. + Note: This is not a parameter of aks commands. :return: dict """ from azext_aks_preview._consts import ( - ADDONS, - CONST_GITOPS_ADDON_NAME, - CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME, - CONST_SECRET_ROTATION_ENABLED, - ) + ADDONS, CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME, + CONST_GITOPS_ADDON_NAME, CONST_SECRET_ROTATION_ENABLED) addon_consts = super().get_addon_consts() addon_consts["ADDONS"] = ADDONS @@ -585,6 +588,27 @@ def get_enable_msi_auth_for_monitoring(self) -> Union[bool, None]: # this parameter does not need validation return enable_msi_auth_for_monitoring + + def get_no_wait(self) -> bool: + """Obtain the value of no_wait. + + Note: Inherited and extended in aks-preview to replace the set value when enable_msi_auth_for_monitoring is + specified. + + Note: no_wait will not be decorated into the `mc` object. + + :return: bool + """ + no_wait = super().get_no_wait() + + if self.get_intermediate("monitoring") and self.get_enable_msi_auth_for_monitoring(): + logger.warning("Enabling msi auth for monitoring addon requires waiting for cluster creation to complete") + if no_wait: + logger.warning("The set option --no-wait has been ignored") + no_wait = False + return no_wait + + def get_enable_secret_rotation(self) -> bool: """Obtain the value of enable_secret_rotation. @@ -618,6 +642,7 @@ def get_enable_secret_rotation(self) -> bool: # this parameter does not need validation return enable_secret_rotation + class AKSPreviewCreateDecorator(AKSCreateDecorator): # pylint: disable=super-init-not-called def __init__( @@ -803,9 +828,17 @@ def set_up_addon_profiles(self, mc: ManagedCluster, skip_addons: Optional[List[s }, ) # post-process, create a deployment - # TODO: fix signature ensure_container_insights_for_monitoring( - self.cmd, addon_profiles[CONST_MONITORING_ADDON_NAME] + self.cmd, + addon_profiles[CONST_MONITORING_ADDON_NAME], + self.context.get_subscription_id(), + self.context.get_resource_group_name(), + self.context.get_name(), + self.context.get_location(), + remove_monitoring=False, + aad_route=enable_msi_auth_for_monitoring, + create_dcr=True, + create_dcra=False, ) # set intermediate self.context.set_intermediate( @@ -845,6 +878,48 @@ def construct_preview_mc_profile(self) -> ManagedCluster: mc = self.set_up_pod_identity_profile(mc) return mc + def create_mc(self, mc: ManagedCluster) -> ManagedCluster: + """Send request to create a real managed cluster. + + Note: Inherited and extended in aks-preview to create dcr association for monitoring addon if + enable_msi_auth_for_monitoring is specified after cluster is created. + + :return: the ManagedCluster object + """ + created_cluster = super().create_mc(mc) + + # determine the value of constants + addon_consts = self.context.get_addon_consts() + CONST_MONITORING_ADDON_NAME = addon_consts.get("CONST_MONITORING_ADDON_NAME") + + # Due to SPN replication latency, we do a few retries here + max_retry = 30 + retry_exception = Exception(None) + for _ in range(0, max_retry): + try: + if self.context.get_intermediate("monitoring") and self.context.get_enable_msi_auth_for_monitoring(): + # Create the DCR Association here + ensure_container_insights_for_monitoring( + self.cmd, + mc.addon_profiles[CONST_MONITORING_ADDON_NAME], + self.context.get_subscription_id(), + self.context.get_resource_group_name(), + self.context.get_name(), + self.context.get_location(), + remove_monitoring=False, + aad_route=self.context.get_enable_msi_auth_for_monitoring(), + create_dcr=False, + create_dcra=True, + ) + return created_cluster + except CloudError as ex: + retry_exception = ex + if 'not found in Active Directory tenant' in ex.message: + time.sleep(3) + else: + raise ex + raise retry_exception + class AKSPreviewUpdateDecorator(AKSUpdateDecorator): # pylint: disable=super-init-not-called From 07be45b449df17dc5362b0707b565361df89e40f Mon Sep 17 00:00:00 2001 From: Fuming Zhang Date: Thu, 21 Oct 2021 15:12:44 +0800 Subject: [PATCH 06/10] update set up monitoring addon profile --- .../azext_aks_preview/decorator.py | 83 +++++++++---------- 1 file changed, 37 insertions(+), 46 deletions(-) diff --git a/src/aks-preview/azext_aks_preview/decorator.py b/src/aks-preview/azext_aks_preview/decorator.py index 5b16b9e6582..4b018d19d5a 100644 --- a/src/aks-preview/azext_aks_preview/decorator.py +++ b/src/aks-preview/azext_aks_preview/decorator.py @@ -5,7 +5,7 @@ import os import time -from typing import Dict, List, Optional, TypeVar, Union +from typing import Dict, TypeVar, Union from azure.cli.command_modules.acs._consts import DecoratorMode from azure.cli.command_modules.acs.decorator import ( @@ -781,7 +781,41 @@ def set_up_pod_identity_profile(self, mc: ManagedCluster) -> ManagedCluster: mc.pod_identity_profile = pod_identity_profile return mc - def set_up_addon_profiles(self, mc: ManagedCluster, skip_addons: Optional[List[str]] = None) -> ManagedCluster: + def set_up_monitoring_addon_profile(self): + # determine the value of constants + addon_consts = self.context.get_addon_consts() + CONST_MONITORING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID = addon_consts.get( + "CONST_MONITORING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID" + ) + CONST_MONITORING_USING_AAD_MSI_AUTH = addon_consts.get( + "CONST_MONITORING_USING_AAD_MSI_AUTH" + ) + + monitoring_addon_profile = self.models.ManagedClusterAddonProfile( + enabled=True, + config={ + CONST_MONITORING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID: self.context.get_workspace_resource_id(), + CONST_MONITORING_USING_AAD_MSI_AUTH: self.context.get_enable_msi_auth_for_monitoring(), + }, + ) + # post-process, create a deployment + ensure_container_insights_for_monitoring( + self.cmd, + monitoring_addon_profile, + self.context.get_subscription_id(), + self.context.get_resource_group_name(), + self.context.get_name(), + self.context.get_location(), + remove_monitoring=False, + aad_route=self.context.get_enable_msi_auth_for_monitoring(), + create_dcr=True, + create_dcra=False, + ) + # set intermediate + self.context.set_intermediate("monitoring", True, overwrite_exists=True) + return monitoring_addon_profile + + def set_up_addon_profiles(self, mc: ManagedCluster) -> ManagedCluster: """Set up addon profiles for the ManagedCluster object. Call the method of the same name in the parent class to set up addon_profiles, and then set some extra addons @@ -789,19 +823,7 @@ def set_up_addon_profiles(self, mc: ManagedCluster, skip_addons: Optional[List[s :return: the ManagedCluster object """ - # replace empty default value - if skip_addons is None: - skip_addons = [] addon_consts = self.context.get_addon_consts() - CONST_MONITORING_ADDON_NAME = addon_consts.get( - "CONST_MONITORING_ADDON_NAME" - ) - CONST_MONITORING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID = addon_consts.get( - "CONST_MONITORING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID" - ) - CONST_MONITORING_USING_AAD_MSI_AUTH = addon_consts.get( - "CONST_MONITORING_USING_AAD_MSI_AUTH" - ) CONST_SECRET_ROTATION_ENABLED = addon_consts.get( "CONST_SECRET_ROTATION_ENABLED" ) @@ -809,41 +831,10 @@ def set_up_addon_profiles(self, mc: ManagedCluster, skip_addons: Optional[List[s "CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME" ) - mc = super().set_up_addon_profiles(mc, skip_addons=["monitoring"]) + mc = super().set_up_addon_profiles(mc) ManagedClusterAddonProfile = self.models.ManagedClusterAddonProfile addon_profiles = mc.addon_profiles addons = self.context.get_enable_addons() - if "monitoring" in addons: - workspace_resource_id = self.context.get_workspace_resource_id() - enable_msi_auth_for_monitoring = ( - self.context.get_enable_msi_auth_for_monitoring() - ) - addon_profiles[ - CONST_MONITORING_ADDON_NAME - ] = ManagedClusterAddonProfile( - enabled=True, - config={ - CONST_MONITORING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID: workspace_resource_id, - CONST_MONITORING_USING_AAD_MSI_AUTH: enable_msi_auth_for_monitoring, - }, - ) - # post-process, create a deployment - ensure_container_insights_for_monitoring( - self.cmd, - addon_profiles[CONST_MONITORING_ADDON_NAME], - self.context.get_subscription_id(), - self.context.get_resource_group_name(), - self.context.get_name(), - self.context.get_location(), - remove_monitoring=False, - aad_route=enable_msi_auth_for_monitoring, - create_dcr=True, - create_dcra=False, - ) - # set intermediate - self.context.set_intermediate( - "monitoring", True, overwrite_exists=True - ) if "azure-keyvault-secrets-provider" in addons: addon_profile = ManagedClusterAddonProfile( enabled=True, config={CONST_SECRET_ROTATION_ENABLED: "false"} From 09fe85a6d3615003df74f122d9e63e6b1c7ee9e2 Mon Sep 17 00:00:00 2001 From: Fuming Zhang Date: Thu, 21 Oct 2021 17:36:24 +0800 Subject: [PATCH 07/10] add unit tests --- .../azext_aks_preview/decorator.py | 104 +++++-- .../tests/latest/test_decorator.py | 266 +++++++++++++++++- 2 files changed, 334 insertions(+), 36 deletions(-) diff --git a/src/aks-preview/azext_aks_preview/decorator.py b/src/aks-preview/azext_aks_preview/decorator.py index 4b018d19d5a..38eb0af2a27 100644 --- a/src/aks-preview/azext_aks_preview/decorator.py +++ b/src/aks-preview/azext_aks_preview/decorator.py @@ -45,6 +45,7 @@ LinuxOSConfig = TypeVar("LinuxOSConfig") ManagedClusterHTTPProxyConfig = TypeVar("ManagedClusterHTTPProxyConfig") ContainerServiceNetworkProfile = TypeVar("ContainerServiceNetworkProfile") +ManagedClusterAddonProfile = TypeVar("ManagedClusterAddonProfile") # pylint: disable=too-many-instance-attributes,too-few-public-methods @@ -511,8 +512,12 @@ def get_addon_consts(self) -> Dict[str, str]: :return: dict """ from azext_aks_preview._consts import ( - ADDONS, CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME, - CONST_GITOPS_ADDON_NAME, CONST_SECRET_ROTATION_ENABLED) + ADDONS, + CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME, + CONST_GITOPS_ADDON_NAME, + CONST_SECRET_ROTATION_ENABLED, + CONST_MONITORING_USING_AAD_MSI_AUTH, + ) addon_consts = super().get_addon_consts() addon_consts["ADDONS"] = ADDONS @@ -523,6 +528,9 @@ def get_addon_consts(self) -> Dict[str, str]: addon_consts[ "CONST_SECRET_ROTATION_ENABLED" ] = CONST_SECRET_ROTATION_ENABLED + addon_consts[ + "CONST_MONITORING_USING_AAD_MSI_AUTH" + ] = CONST_MONITORING_USING_AAD_MSI_AUTH return addon_consts def get_appgw_subnet_prefix(self) -> Union[str, None]: @@ -588,7 +596,6 @@ def get_enable_msi_auth_for_monitoring(self) -> Union[bool, None]: # this parameter does not need validation return enable_msi_auth_for_monitoring - def get_no_wait(self) -> bool: """Obtain the value of no_wait. @@ -604,11 +611,10 @@ def get_no_wait(self) -> bool: if self.get_intermediate("monitoring") and self.get_enable_msi_auth_for_monitoring(): logger.warning("Enabling msi auth for monitoring addon requires waiting for cluster creation to complete") if no_wait: - logger.warning("The set option --no-wait has been ignored") + logger.warning("The set option '--no-wait' has been ignored") no_wait = False return no_wait - def get_enable_secret_rotation(self) -> bool: """Obtain the value of enable_secret_rotation. @@ -636,7 +642,7 @@ def get_enable_secret_rotation(self) -> bool: ): enable_secret_rotation = self.mc.addon_profiles.get( CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME - ).config.get(CONST_SECRET_ROTATION_ENABLED) + ).config.get(CONST_SECRET_ROTATION_ENABLED) == "true" # this parameter does not need dynamic completion # this parameter does not need validation @@ -674,8 +680,7 @@ def __init__( def set_up_agent_pool_profiles(self, mc: ManagedCluster) -> ManagedCluster: """Set up agent pool profiles for the ManagedCluster object. - Call the method of the same name in the parent class to set up agent_pool_profiles, and then set some additional - properties. + Note: Inherited and extended in aks-preview to set some additional properties. :return: the ManagedCluster object """ @@ -724,8 +729,7 @@ def set_up_node_resource_group(self, mc: ManagedCluster) -> ManagedCluster: def set_up_network_profile(self, mc: ManagedCluster) -> ManagedCluster: """Set up network profile for the ManagedCluster object. - Call the method of the same name in the parent class to set up network_profile, and then set the - nat_gateway_profile. + Note: Inherited and extended in aks-preview to set the nat_gateway_profile. :return: the ManagedCluster object """ @@ -781,7 +785,13 @@ def set_up_pod_identity_profile(self, mc: ManagedCluster) -> ManagedCluster: mc.pod_identity_profile = pod_identity_profile return mc - def set_up_monitoring_addon_profile(self): + def set_up_monitoring_addon_profile(self) -> ManagedClusterAddonProfile: + """Set up monitoring addon profile. + + Note: Overwritten in aks-preview. + + :return: a ManagedClusterAddonProfile object + """ # determine the value of constants addon_consts = self.context.get_addon_consts() CONST_MONITORING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID = addon_consts.get( @@ -815,37 +825,83 @@ def set_up_monitoring_addon_profile(self): self.context.set_intermediate("monitoring", True, overwrite_exists=True) return monitoring_addon_profile - def set_up_addon_profiles(self, mc: ManagedCluster) -> ManagedCluster: - """Set up addon profiles for the ManagedCluster object. + def set_up_ingress_appgw_addon_profile(self) -> ManagedClusterAddonProfile: + """Set up ingress appgw addon profile. - Call the method of the same name in the parent class to set up addon_profiles, and then set some extra addons - and overwrite the process of setting the monitoring addon. + Note: Inherited and extended in aks-preview to support option appgw_subnet_prefix. - :return: the ManagedCluster object + :return: a ManagedClusterAddonProfile object """ + # determine the value of constants + addon_consts = self.context.get_addon_consts() + CONST_INGRESS_APPGW_SUBNET_CIDR = addon_consts.get( + "CONST_INGRESS_APPGW_SUBNET_CIDR" + ) + + ingress_appgw_addon_profile = super().set_up_ingress_appgw_addon_profile() + appgw_subnet_prefix = self.context.get_appgw_subnet_prefix() + if ( + appgw_subnet_prefix is not None and + ingress_appgw_addon_profile.config.get( + CONST_INGRESS_APPGW_SUBNET_CIDR + ) + is None + ): + ingress_appgw_addon_profile.config[CONST_INGRESS_APPGW_SUBNET_CIDR] = appgw_subnet_prefix + return ingress_appgw_addon_profile + + def set_up_azure_keyvault_secrets_provider_addon_profile(self) -> ManagedClusterAddonProfile: + """Set up azure keyvault secrets provider addon profile. + + :return: a ManagedClusterAddonProfile object + """ + # determine the value of constants addon_consts = self.context.get_addon_consts() CONST_SECRET_ROTATION_ENABLED = addon_consts.get( "CONST_SECRET_ROTATION_ENABLED" ) + + azure_keyvault_secrets_provider_addon_profile = self.models.ManagedClusterAddonProfile( + enabled=True, config={CONST_SECRET_ROTATION_ENABLED: "false"} + ) + if self.context.get_enable_secret_rotation(): + azure_keyvault_secrets_provider_addon_profile.config[CONST_SECRET_ROTATION_ENABLED] = "true" + return azure_keyvault_secrets_provider_addon_profile + + def set_up_gitops_addon_profile(self) -> ManagedClusterAddonProfile: + """Set up gitops addon profile. + + :return: a ManagedClusterAddonProfile object + """ + gitops_addon_profile = self.models.ManagedClusterAddonProfile( + enabled=True, + ) + return gitops_addon_profile + + def set_up_addon_profiles(self, mc: ManagedCluster) -> ManagedCluster: + """Set up addon profiles for the ManagedCluster object. + + Note: Inherited and extended in aks-preview to set some extra addons. + + :return: the ManagedCluster object + """ + addon_consts = self.context.get_addon_consts() CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME = addon_consts.get( "CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME" ) + CONST_GITOPS_ADDON_NAME = addon_consts.get("CONST_GITOPS_ADDON_NAME") mc = super().set_up_addon_profiles(mc) - ManagedClusterAddonProfile = self.models.ManagedClusterAddonProfile addon_profiles = mc.addon_profiles addons = self.context.get_enable_addons() if "azure-keyvault-secrets-provider" in addons: - addon_profile = ManagedClusterAddonProfile( - enabled=True, config={CONST_SECRET_ROTATION_ENABLED: "false"} - ) - if self.context.get_enable_secret_rotation(): - addon_profile.config[CONST_SECRET_ROTATION_ENABLED] = "true" addon_profiles[ CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME - ] = addon_profile + ] = self.set_up_azure_keyvault_secrets_provider_addon_profile() if "gitops" in addons: - addon_profiles["gitops"] = ManagedClusterAddonProfile(enabled=True) + addon_profiles[ + CONST_GITOPS_ADDON_NAME + ] = self.set_up_gitops_addon_profile() mc.addon_profiles = addon_profiles return mc diff --git a/src/aks-preview/azext_aks_preview/tests/latest/test_decorator.py b/src/aks-preview/azext_aks_preview/tests/latest/test_decorator.py index c8082728306..8b9b34c20e5 100644 --- a/src/aks-preview/azext_aks_preview/tests/latest/test_decorator.py +++ b/src/aks-preview/azext_aks_preview/tests/latest/test_decorator.py @@ -5,6 +5,7 @@ import importlib import unittest +from unittest.mock import patch from azext_aks_preview.__init__ import register_aks_preview_resource_type from azext_aks_preview._client_factory import CUSTOM_MGMT_AKS_PREVIEW @@ -26,6 +27,29 @@ RequiredArgumentMissingError, UnknownError, ) +from azext_aks_preview._consts import ( + ADDONS, + CONST_ACC_SGX_QUOTE_HELPER_ENABLED, + CONST_AZURE_POLICY_ADDON_NAME, + CONST_CONFCOM_ADDON_NAME, + CONST_HTTP_APPLICATION_ROUTING_ADDON_NAME, + CONST_INGRESS_APPGW_ADDON_NAME, + CONST_INGRESS_APPGW_APPLICATION_GATEWAY_ID, + CONST_INGRESS_APPGW_APPLICATION_GATEWAY_NAME, + CONST_INGRESS_APPGW_SUBNET_CIDR, + CONST_INGRESS_APPGW_SUBNET_ID, + CONST_INGRESS_APPGW_WATCH_NAMESPACE, + CONST_KUBE_DASHBOARD_ADDON_NAME, + CONST_MONITORING_ADDON_NAME, + CONST_MONITORING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID, + CONST_OPEN_SERVICE_MESH_ADDON_NAME, + CONST_VIRTUAL_NODE_ADDON_NAME, + CONST_VIRTUAL_NODE_SUBNET_NAME, + CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME, + CONST_GITOPS_ADDON_NAME, + CONST_SECRET_ROTATION_ENABLED, + CONST_MONITORING_USING_AAD_MSI_AUTH, +) class AKSPreviewModelsTestCase(unittest.TestCase): @@ -464,14 +488,126 @@ def test_get_enable_pod_identity_with_kubenet(self): ctx_2.get_enable_pod_identity_with_kubenet(), False ) + def test_get_addon_consts(self): + # default + ctx_1 = AKSPreviewContext( + self.cmd, + {}, + self.models, + decorator_mode=DecoratorMode.CREATE, + ) + addon_consts = ctx_1.get_addon_consts() + ground_truth_addon_consts = { + "ADDONS": ADDONS, + "CONST_ACC_SGX_QUOTE_HELPER_ENABLED": CONST_ACC_SGX_QUOTE_HELPER_ENABLED, + "CONST_AZURE_POLICY_ADDON_NAME": CONST_AZURE_POLICY_ADDON_NAME, + "CONST_CONFCOM_ADDON_NAME": CONST_CONFCOM_ADDON_NAME, + "CONST_HTTP_APPLICATION_ROUTING_ADDON_NAME": CONST_HTTP_APPLICATION_ROUTING_ADDON_NAME, + "CONST_INGRESS_APPGW_ADDON_NAME": CONST_INGRESS_APPGW_ADDON_NAME, + "CONST_INGRESS_APPGW_APPLICATION_GATEWAY_ID": CONST_INGRESS_APPGW_APPLICATION_GATEWAY_ID, + "CONST_INGRESS_APPGW_APPLICATION_GATEWAY_NAME": CONST_INGRESS_APPGW_APPLICATION_GATEWAY_NAME, + "CONST_INGRESS_APPGW_SUBNET_CIDR": CONST_INGRESS_APPGW_SUBNET_CIDR, + "CONST_INGRESS_APPGW_SUBNET_ID": CONST_INGRESS_APPGW_SUBNET_ID, + "CONST_INGRESS_APPGW_WATCH_NAMESPACE": CONST_INGRESS_APPGW_WATCH_NAMESPACE, + "CONST_KUBE_DASHBOARD_ADDON_NAME": CONST_KUBE_DASHBOARD_ADDON_NAME, + "CONST_MONITORING_ADDON_NAME": CONST_MONITORING_ADDON_NAME, + "CONST_MONITORING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID": CONST_MONITORING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID, + "CONST_OPEN_SERVICE_MESH_ADDON_NAME": CONST_OPEN_SERVICE_MESH_ADDON_NAME, + "CONST_VIRTUAL_NODE_ADDON_NAME": CONST_VIRTUAL_NODE_ADDON_NAME, + "CONST_VIRTUAL_NODE_SUBNET_NAME": CONST_VIRTUAL_NODE_SUBNET_NAME, + "CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME": CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME, + "CONST_GITOPS_ADDON_NAME": CONST_GITOPS_ADDON_NAME, + "CONST_SECRET_ROTATION_ENABLED": CONST_SECRET_ROTATION_ENABLED, + "CONST_MONITORING_USING_AAD_MSI_AUTH": CONST_MONITORING_USING_AAD_MSI_AUTH, + } + self.assertEqual(addon_consts, ground_truth_addon_consts) + def test_get_appgw_subnet_prefix(self): - pass + # default + ctx_1 = AKSPreviewContext( + self.cmd, + { + "appgw_subnet_prefix": None, + }, + self.models, + decorator_mode=DecoratorMode.CREATE, + ) + self.assertEqual(ctx_1.get_appgw_subnet_prefix(), None) + addon_profiles_1 = { + CONST_INGRESS_APPGW_ADDON_NAME: self.models.ManagedClusterAddonProfile( + enabled=True, + config={ + CONST_INGRESS_APPGW_SUBNET_CIDR: "test_appgw_subnet_prefix" + }, + ) + } + mc = self.models.ManagedCluster( + location="test_location", addon_profiles=addon_profiles_1 + ) + ctx_1.attach_mc(mc) + self.assertEqual( + ctx_1.get_appgw_subnet_prefix(), "test_appgw_subnet_prefix" + ) def test_get_enable_msi_auth_for_monitoring(self): - pass + # default + ctx_1 = AKSPreviewContext( + self.cmd, + { + "enable_msi_auth_for_monitoring": False, + }, + self.models, + decorator_mode=DecoratorMode.CREATE, + ) + self.assertEqual(ctx_1.get_enable_msi_auth_for_monitoring(), False) + addon_profiles_1 = { + CONST_MONITORING_ADDON_NAME: self.models.ManagedClusterAddonProfile( + enabled=True, + config={CONST_MONITORING_USING_AAD_MSI_AUTH: True}, + ) + } + mc = self.models.ManagedCluster( + location="test_location", addon_profiles=addon_profiles_1 + ) + ctx_1.attach_mc(mc) + self.assertEqual(ctx_1.get_enable_msi_auth_for_monitoring(), True) + + def test_get_no_wait(self): + # custom value + ctx_1 = AKSPreviewContext( + self.cmd, + { + "no_wait": True, + "enable_msi_auth_for_monitoring": True, + }, + self.models, + decorator_mode=DecoratorMode.CREATE, + ) + ctx_1.set_intermediate("monitoring", True, overwrite_exists=True) + self.assertEqual(ctx_1.get_no_wait(), False) def test_get_enable_secret_rotation(self): - pass + # default + ctx_1 = AKSPreviewContext( + self.cmd, + { + "enable_secret_rotation": False, + }, + self.models, + decorator_mode=DecoratorMode.CREATE, + ) + self.assertEqual(ctx_1.get_enable_secret_rotation(), False) + addon_profiles_1 = { + CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME: self.models.ManagedClusterAddonProfile( + enabled=True, + config={CONST_SECRET_ROTATION_ENABLED: "true"}, + ) + } + mc = self.models.ManagedCluster( + location="test_location", addon_profiles=addon_profiles_1 + ) + ctx_1.attach_mc(mc) + self.assertEqual(ctx_1.get_enable_secret_rotation(), True) class AKSPreviewCreateDecoratorTestCase(unittest.TestCase): @@ -882,22 +1018,128 @@ def test_set_up_pod_identity_profile(self): location="test_location", network_profile=network_profile_2 ) dec_mc_2 = dec_2.set_up_pod_identity_profile(mc_2) - ground_truth_network_profile_2 = ( - self.models.ContainerServiceNetworkProfile(network_plugin="kubenet") + network_profile_2 = self.models.ContainerServiceNetworkProfile( + network_plugin="kubenet" ) - ground_truth_pod_identity_profile_2 = ( - self.models.ManagedClusterPodIdentityProfile( - enabled=True, - allow_network_plugin_kubenet=True, - ) + pod_identity_profile_2 = self.models.ManagedClusterPodIdentityProfile( + enabled=True, + allow_network_plugin_kubenet=True, ) ground_truth_mc_2 = self.models.ManagedCluster( location="test_location", - network_profile=ground_truth_network_profile_2, - pod_identity_profile=ground_truth_pod_identity_profile_2, + network_profile=network_profile_2, + pod_identity_profile=pod_identity_profile_2, ) self.assertEqual(dec_mc_2, ground_truth_mc_2) + def test_set_up_addon_profiles(self): + # default value in `aks_create` + dec_1 = AKSPreviewCreateDecorator( + self.cmd, + self.client, + { + "enable_addons": None, + "workspace_resource_id": None, + "aci_subnet_name": None, + "appgw_name": None, + "appgw_subnet_cidr": None, + "appgw_id": None, + "appgw_subnet_id": None, + "appgw_watch_namespace": None, + "enable_sgxquotehelper": False, + "appgw_subnet_prefix": None, + "enable_msi_auth_for_monitoring": False, + "enable_secret_rotation": False, + }, + CUSTOM_MGMT_AKS_PREVIEW, + ) + + mc_1 = self.models.ManagedCluster(location="test_location") + # fail on passing the wrong mc object + with self.assertRaises(CLIInternalError): + dec_1.set_up_addon_profiles(None) + dec_mc_1 = dec_1.set_up_addon_profiles(mc_1) + ground_truth_mc_1 = self.models.ManagedCluster( + location="test_location", addon_profiles={} + ) + self.assertEqual(dec_mc_1, ground_truth_mc_1) + self.assertEqual(dec_1.context.get_intermediate("monitoring"), None) + self.assertEqual( + dec_1.context.get_intermediate("enable_virtual_node"), None + ) + self.assertEqual( + dec_1.context.get_intermediate("ingress_appgw_addon_enabled"), None + ) + + # custom value + dec_2 = AKSPreviewCreateDecorator( + self.cmd, + self.client, + { + "name": "test_name", + "resource_group_name": "test_rg_name", + "location": "test_location", + "vnet_subnet_id": "test_vnet_subnet_id", + "enable_addons": "monitoring,ingress-appgw,gitops,azure-keyvault-secrets-provider", + "workspace_resource_id": "test_workspace_resource_id", + "enable_msi_auth_for_monitoring": True, + "appgw_name": "test_appgw_name", + "appgw_subnet_prefix": "test_appgw_subnet_prefix", + "appgw_id": "test_appgw_id", + "appgw_subnet_id": "test_appgw_subnet_id", + "appgw_watch_namespace": "test_appgw_watch_namespace", + "enable_secret_rotation": True, + }, + CUSTOM_MGMT_AKS_PREVIEW, + ) + dec_2.context.set_intermediate( + "subscription_id", "test_subscription_id" + ) + mc_2 = self.models.ManagedCluster(location="test_location") + with patch( + "azext_aks_preview.decorator.ensure_container_insights_for_monitoring", + return_value=None, + ): + dec_mc_2 = dec_2.set_up_addon_profiles(mc_2) + + addon_profiles_2 = { + CONST_MONITORING_ADDON_NAME: self.models.ManagedClusterAddonProfile( + enabled=True, + config={ + CONST_MONITORING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID: "/test_workspace_resource_id", + CONST_MONITORING_USING_AAD_MSI_AUTH: True, + }, + ), + CONST_INGRESS_APPGW_ADDON_NAME: self.models.ManagedClusterAddonProfile( + enabled=True, + config={ + CONST_INGRESS_APPGW_APPLICATION_GATEWAY_NAME: "test_appgw_name", + CONST_INGRESS_APPGW_APPLICATION_GATEWAY_ID: "test_appgw_id", + CONST_INGRESS_APPGW_SUBNET_ID: "test_appgw_subnet_id", + CONST_INGRESS_APPGW_SUBNET_CIDR: "test_appgw_subnet_prefix", + CONST_INGRESS_APPGW_WATCH_NAMESPACE: "test_appgw_watch_namespace", + }, + ), + CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME: self.models.ManagedClusterAddonProfile( + enabled=True, + config={CONST_SECRET_ROTATION_ENABLED: "true"}, + ), + CONST_GITOPS_ADDON_NAME: self.models.ManagedClusterAddonProfile( + enabled=True, + ), + } + ground_truth_mc_2 = self.models.ManagedCluster( + location="test_location", addon_profiles=addon_profiles_2 + ) + self.assertEqual(dec_mc_2, ground_truth_mc_2) + self.assertEqual(dec_2.context.get_intermediate("monitoring"), True) + self.assertEqual( + dec_2.context.get_intermediate("enable_virtual_node"), None + ) + self.assertEqual( + dec_2.context.get_intermediate("ingress_appgw_addon_enabled"), True + ) + def test_construct_preview_mc_profile(self): pass From d93ca1d9365d85a4cb425ae07b07fdb3fdea4cd3 Mon Sep 17 00:00:00 2001 From: Fuming Zhang Date: Thu, 21 Oct 2021 17:46:45 +0800 Subject: [PATCH 08/10] fix lint --- src/aks-preview/azext_aks_preview/decorator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/aks-preview/azext_aks_preview/decorator.py b/src/aks-preview/azext_aks_preview/decorator.py index 38eb0af2a27..803917f16f5 100644 --- a/src/aks-preview/azext_aks_preview/decorator.py +++ b/src/aks-preview/azext_aks_preview/decorator.py @@ -862,8 +862,8 @@ def set_up_azure_keyvault_secrets_provider_addon_profile(self) -> ManagedCluster ) azure_keyvault_secrets_provider_addon_profile = self.models.ManagedClusterAddonProfile( - enabled=True, config={CONST_SECRET_ROTATION_ENABLED: "false"} - ) + enabled=True, config={CONST_SECRET_ROTATION_ENABLED: "false"} + ) if self.context.get_enable_secret_rotation(): azure_keyvault_secrets_provider_addon_profile.config[CONST_SECRET_ROTATION_ENABLED] = "true" return azure_keyvault_secrets_provider_addon_profile From a055accffd00bef068ea570ba9989e1cf56ca144 Mon Sep 17 00:00:00 2001 From: Fuming Zhang Date: Mon, 25 Oct 2021 16:48:30 +0800 Subject: [PATCH 09/10] update addon & add tests --- .../azext_aks_preview/decorator.py | 22 +- .../tests/latest/test_decorator.py | 225 ++++++++++++++++++ 2 files changed, 236 insertions(+), 11 deletions(-) diff --git a/src/aks-preview/azext_aks_preview/decorator.py b/src/aks-preview/azext_aks_preview/decorator.py index 803917f16f5..6fd41cdb82f 100644 --- a/src/aks-preview/azext_aks_preview/decorator.py +++ b/src/aks-preview/azext_aks_preview/decorator.py @@ -785,8 +785,8 @@ def set_up_pod_identity_profile(self, mc: ManagedCluster) -> ManagedCluster: mc.pod_identity_profile = pod_identity_profile return mc - def set_up_monitoring_addon_profile(self) -> ManagedClusterAddonProfile: - """Set up monitoring addon profile. + def build_monitoring_addon_profile(self) -> ManagedClusterAddonProfile: + """Build monitoring addon profile. Note: Overwritten in aks-preview. @@ -825,8 +825,8 @@ def set_up_monitoring_addon_profile(self) -> ManagedClusterAddonProfile: self.context.set_intermediate("monitoring", True, overwrite_exists=True) return monitoring_addon_profile - def set_up_ingress_appgw_addon_profile(self) -> ManagedClusterAddonProfile: - """Set up ingress appgw addon profile. + def build_ingress_appgw_addon_profile(self) -> ManagedClusterAddonProfile: + """Build ingress appgw addon profile. Note: Inherited and extended in aks-preview to support option appgw_subnet_prefix. @@ -838,7 +838,7 @@ def set_up_ingress_appgw_addon_profile(self) -> ManagedClusterAddonProfile: "CONST_INGRESS_APPGW_SUBNET_CIDR" ) - ingress_appgw_addon_profile = super().set_up_ingress_appgw_addon_profile() + ingress_appgw_addon_profile = super().build_ingress_appgw_addon_profile() appgw_subnet_prefix = self.context.get_appgw_subnet_prefix() if ( appgw_subnet_prefix is not None and @@ -850,8 +850,8 @@ def set_up_ingress_appgw_addon_profile(self) -> ManagedClusterAddonProfile: ingress_appgw_addon_profile.config[CONST_INGRESS_APPGW_SUBNET_CIDR] = appgw_subnet_prefix return ingress_appgw_addon_profile - def set_up_azure_keyvault_secrets_provider_addon_profile(self) -> ManagedClusterAddonProfile: - """Set up azure keyvault secrets provider addon profile. + def build_azure_keyvault_secrets_provider_addon_profile(self) -> ManagedClusterAddonProfile: + """Build azure keyvault secrets provider addon profile. :return: a ManagedClusterAddonProfile object """ @@ -868,8 +868,8 @@ def set_up_azure_keyvault_secrets_provider_addon_profile(self) -> ManagedCluster azure_keyvault_secrets_provider_addon_profile.config[CONST_SECRET_ROTATION_ENABLED] = "true" return azure_keyvault_secrets_provider_addon_profile - def set_up_gitops_addon_profile(self) -> ManagedClusterAddonProfile: - """Set up gitops addon profile. + def build_gitops_addon_profile(self) -> ManagedClusterAddonProfile: + """Build gitops addon profile. :return: a ManagedClusterAddonProfile object """ @@ -897,11 +897,11 @@ def set_up_addon_profiles(self, mc: ManagedCluster) -> ManagedCluster: if "azure-keyvault-secrets-provider" in addons: addon_profiles[ CONST_AZURE_KEYVAULT_SECRETS_PROVIDER_ADDON_NAME - ] = self.set_up_azure_keyvault_secrets_provider_addon_profile() + ] = self.build_azure_keyvault_secrets_provider_addon_profile() if "gitops" in addons: addon_profiles[ CONST_GITOPS_ADDON_NAME - ] = self.set_up_gitops_addon_profile() + ] = self.build_gitops_addon_profile() mc.addon_profiles = addon_profiles return mc diff --git a/src/aks-preview/azext_aks_preview/tests/latest/test_decorator.py b/src/aks-preview/azext_aks_preview/tests/latest/test_decorator.py index 8b9b34c20e5..7665b2b9b34 100644 --- a/src/aks-preview/azext_aks_preview/tests/latest/test_decorator.py +++ b/src/aks-preview/azext_aks_preview/tests/latest/test_decorator.py @@ -1032,6 +1032,231 @@ def test_set_up_pod_identity_profile(self): ) self.assertEqual(dec_mc_2, ground_truth_mc_2) + def test_build_monitoring_addon_profile(self): + # default + dec_1 = AKSPreviewCreateDecorator( + self.cmd, + self.client, + { + "resource_group_name": "test_rg_name", + "name": "test_name", + "location": "test_location", + "enable_addons": "monitoring", + "workspace_resource_id": "test_workspace_resource_id", + "enable_msi_auth_for_monitoring": False, + }, + CUSTOM_MGMT_AKS_PREVIEW, + ) + + with patch( + "azext_aks_preview.decorator.ensure_container_insights_for_monitoring", + return_value=None, + ): + self.assertEqual(dec_1.context.get_intermediate("monitoring"), None) + monitoring_addon_profile = dec_1.build_monitoring_addon_profile() + ground_truth_monitoring_addon_profile = self.models.ManagedClusterAddonProfile( + enabled=True, + config={ + CONST_MONITORING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID: "/test_workspace_resource_id", + CONST_MONITORING_USING_AAD_MSI_AUTH: False, + }, + ) + self.assertEqual( + monitoring_addon_profile, ground_truth_monitoring_addon_profile + ) + self.assertEqual(dec_1.context.get_intermediate("monitoring"), True) + + # custom value + dec_2 = AKSPreviewCreateDecorator( + self.cmd, + self.client, + { + "resource_group_name": "test_rg_name", + "name": "test_name", + "location": "test_location", + "enable_addons": "monitoring", + "workspace_resource_id": "test_workspace_resource_id", + "enable_msi_auth_for_monitoring": True, + }, + CUSTOM_MGMT_AKS_PREVIEW, + ) + + with patch( + "azext_aks_preview.decorator.ensure_container_insights_for_monitoring", + return_value=None, + ): + self.assertEqual(dec_2.context.get_intermediate("monitoring"), None) + monitoring_addon_profile = dec_2.build_monitoring_addon_profile() + ground_truth_monitoring_addon_profile = self.models.ManagedClusterAddonProfile( + enabled=True, + config={ + CONST_MONITORING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID: "/test_workspace_resource_id", + CONST_MONITORING_USING_AAD_MSI_AUTH: True, + }, + ) + self.assertEqual( + monitoring_addon_profile, ground_truth_monitoring_addon_profile + ) + self.assertEqual(dec_2.context.get_intermediate("monitoring"), True) + + def test_build_ingress_appgw_addon_profile(self): + # default + dec_1 = AKSPreviewCreateDecorator( + self.cmd, + self.client, + {}, + CUSTOM_MGMT_AKS_PREVIEW, + ) + + self.assertEqual( + dec_1.context.get_intermediate("ingress_appgw_addon_enabled"), None + ) + ingress_appgw_addon_profile = dec_1.build_ingress_appgw_addon_profile() + ground_truth_ingress_appgw_addon_profile = ( + self.models.ManagedClusterAddonProfile( + enabled=True, + config={}, + ) + ) + self.assertEqual( + ingress_appgw_addon_profile, + ground_truth_ingress_appgw_addon_profile, + ) + self.assertEqual( + dec_1.context.get_intermediate("ingress_appgw_addon_enabled"), True + ) + + # custom value + dec_2 = AKSPreviewCreateDecorator( + self.cmd, + self.client, + { + "appgw_name": "test_appgw_name", + "appgw_subnet_prefix": "test_appgw_subnet_prefix", + "appgw_id": "test_appgw_id", + "appgw_subnet_id": "test_appgw_subnet_id", + "appgw_watch_namespace": "test_appgw_watch_namespace", + }, + CUSTOM_MGMT_AKS_PREVIEW, + ) + + self.assertEqual( + dec_2.context.get_intermediate("ingress_appgw_addon_enabled"), None + ) + ingress_appgw_addon_profile = dec_2.build_ingress_appgw_addon_profile() + ground_truth_ingress_appgw_addon_profile = self.models.ManagedClusterAddonProfile( + enabled=True, + config={ + CONST_INGRESS_APPGW_APPLICATION_GATEWAY_NAME: "test_appgw_name", + CONST_INGRESS_APPGW_SUBNET_CIDR: "test_appgw_subnet_prefix", + CONST_INGRESS_APPGW_APPLICATION_GATEWAY_ID: "test_appgw_id", + CONST_INGRESS_APPGW_SUBNET_ID: "test_appgw_subnet_id", + CONST_INGRESS_APPGW_WATCH_NAMESPACE: "test_appgw_watch_namespace", + }, + ) + self.assertEqual( + ingress_appgw_addon_profile, + ground_truth_ingress_appgw_addon_profile, + ) + self.assertEqual( + dec_2.context.get_intermediate("ingress_appgw_addon_enabled"), True + ) + + # custom value + dec_3 = AKSPreviewCreateDecorator( + self.cmd, + self.client, + { + "appgw_name": "test_appgw_name", + "appgw_subnet_prefix": "test_appgw_subnet_prefix", + "appgw_subnet_cidr": "test_appgw_subnet_cidr", + "appgw_id": "test_appgw_id", + "appgw_subnet_id": "test_appgw_subnet_id", + "appgw_watch_namespace": "test_appgw_watch_namespace", + }, + CUSTOM_MGMT_AKS_PREVIEW, + ) + + self.assertEqual( + dec_3.context.get_intermediate("ingress_appgw_addon_enabled"), None + ) + ingress_appgw_addon_profile = dec_3.build_ingress_appgw_addon_profile() + ground_truth_ingress_appgw_addon_profile = self.models.ManagedClusterAddonProfile( + enabled=True, + config={ + CONST_INGRESS_APPGW_APPLICATION_GATEWAY_NAME: "test_appgw_name", + CONST_INGRESS_APPGW_SUBNET_CIDR: "test_appgw_subnet_cidr", + CONST_INGRESS_APPGW_APPLICATION_GATEWAY_ID: "test_appgw_id", + CONST_INGRESS_APPGW_SUBNET_ID: "test_appgw_subnet_id", + CONST_INGRESS_APPGW_WATCH_NAMESPACE: "test_appgw_watch_namespace", + }, + ) + self.assertEqual( + ingress_appgw_addon_profile, + ground_truth_ingress_appgw_addon_profile, + ) + self.assertEqual( + dec_3.context.get_intermediate("ingress_appgw_addon_enabled"), True + ) + + def test_build_azure_keyvault_secrets_provider_addon_profile(self): + # default + dec_1 = AKSPreviewCreateDecorator( + self.cmd, + self.client, + {"enable_secret_rotation": False}, + CUSTOM_MGMT_AKS_PREVIEW, + ) + + azure_keyvault_secrets_provider_addon_profile = dec_1.build_azure_keyvault_secrets_provider_addon_profile() + ground_truth_azure_keyvault_secrets_provider_addon_profile = ( + self.models.ManagedClusterAddonProfile( + enabled=True, + config={CONST_SECRET_ROTATION_ENABLED: "false"} + ) + ) + self.assertEqual( + azure_keyvault_secrets_provider_addon_profile, ground_truth_azure_keyvault_secrets_provider_addon_profile + ) + + # custom value + dec_2 = AKSPreviewCreateDecorator( + self.cmd, + self.client, + {"enable_secret_rotation": True}, + CUSTOM_MGMT_AKS_PREVIEW, + ) + + azure_keyvault_secrets_provider_addon_profile = dec_2.build_azure_keyvault_secrets_provider_addon_profile() + ground_truth_azure_keyvault_secrets_provider_addon_profile = ( + self.models.ManagedClusterAddonProfile( + enabled=True, + config={CONST_SECRET_ROTATION_ENABLED: "true"} + ) + ) + self.assertEqual( + azure_keyvault_secrets_provider_addon_profile, ground_truth_azure_keyvault_secrets_provider_addon_profile + ) + + def test_build_gitops_addon_profile(self): + # default + dec_1 = AKSPreviewCreateDecorator( + self.cmd, + self.client, + {}, + CUSTOM_MGMT_AKS_PREVIEW, + ) + + gitops_addon_profile = dec_1.build_gitops_addon_profile() + ground_truth_gitops_addon_profile = ( + self.models.ManagedClusterAddonProfile( + enabled=True, + ) + ) + self.assertEqual( + gitops_addon_profile, ground_truth_gitops_addon_profile + ) + def test_set_up_addon_profiles(self): # default value in `aks_create` dec_1 = AKSPreviewCreateDecorator( From e4367c63583f64ee199461cb532f8720c9b115ee Mon Sep 17 00:00:00 2001 From: Fuming Zhang Date: Mon, 25 Oct 2021 17:09:08 +0800 Subject: [PATCH 10/10] fix test --- .../azext_aks_preview/tests/latest/test_decorator.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/aks-preview/azext_aks_preview/tests/latest/test_decorator.py b/src/aks-preview/azext_aks_preview/tests/latest/test_decorator.py index 7665b2b9b34..a97d31361a2 100644 --- a/src/aks-preview/azext_aks_preview/tests/latest/test_decorator.py +++ b/src/aks-preview/azext_aks_preview/tests/latest/test_decorator.py @@ -1047,6 +1047,9 @@ def test_build_monitoring_addon_profile(self): }, CUSTOM_MGMT_AKS_PREVIEW, ) + dec_1.context.set_intermediate( + "subscription_id", "test_subscription_id" + ) with patch( "azext_aks_preview.decorator.ensure_container_insights_for_monitoring", @@ -1080,6 +1083,9 @@ def test_build_monitoring_addon_profile(self): }, CUSTOM_MGMT_AKS_PREVIEW, ) + dec_2.context.set_intermediate( + "subscription_id", "test_subscription_id" + ) with patch( "azext_aks_preview.decorator.ensure_container_insights_for_monitoring",