diff --git a/src/aks-preview/HISTORY.rst b/src/aks-preview/HISTORY.rst index b9d347eb549..f32354c84ce 100644 --- a/src/aks-preview/HISTORY.rst +++ b/src/aks-preview/HISTORY.rst @@ -14,6 +14,8 @@ Pending * `az aks create` and `az aks nodepool add`: Add `--enable-osdisk-full-caching` (preview) to enable the full-cache ephemeral OS disk feature for a node pool. Requires AFEC registration `Microsoft.ContainerService/FullCachePreview`. Property is immutable after node pool creation. * Clean up unused disk driver version constants and remove obsolete CSI driver v2 tests following the removal of `--disk-driver-version` in 21.0.0b1. +* `az aks create/update`: Add `--enable-fips` (preview) to enable FIPS mode at the cluster level and `az aks update --disable-fips` to disable it. Requires Kubernetes version 1.34 or later and AFEC registration `Microsoft.ContainerService/EnableFIPSPreview`. + 21.0.0b1 ++++++ * [BREAKING CHANGE] `az aks create/update`: Remove `--disk-driver-version` option as the `version` field has been removed from the API spec for `ManagedClusterStorageProfileDiskCSIDriver`. diff --git a/src/aks-preview/azext_aks_preview/_help.py b/src/aks-preview/azext_aks_preview/_help.py index 0450cd679f2..2bb0410ceca 100644 --- a/src/aks-preview/azext_aks_preview/_help.py +++ b/src/aks-preview/azext_aks_preview/_help.py @@ -291,6 +291,20 @@ - name: --enable-fips-image type: bool short-summary: Use FIPS-enabled OS on agent nodes. + - name: --enable-fips + type: bool + short-summary: Enable FIPS mode at the cluster level. + long-summary: |- + Enables FIPS compliance for all AKS-managed components, such as the node + operating system, addons, and managed containerized components + (https://aka.ms/aks/components/docs). See Enable cluster-wide FIPS + (https://aka.ms/aks/fips) for more details. + Requires Kubernetes version 1.34 or later and the + Microsoft.ContainerService/EnableFIPSPreview feature to be registered + on the subscription. All node pools must be FIPS-enabled; this command + enables FIPS on the default node pool during cluster creation. Some + addons and extensions aren't supported with cluster-wide FIPS. Verify + addon and extension compatibility before enabling this preview feature. - name: --workspace-resource-id type: string short-summary: The resource ID of an existing Log Analytics Workspace to use for storing monitoring data. If not specified, uses the default Log Analytics Workspace if it exists, otherwise creates one. @@ -1251,6 +1265,27 @@ - name: --disable-image-integrity type: bool short-summary: Disable ImageIntegrity Service. + - name: --enable-fips + type: bool + short-summary: Enable FIPS mode at the cluster level. + long-summary: |- + Enables FIPS compliance for all AKS-managed components, such as the node + operating system, addons, and managed containerized components + (https://aka.ms/aks/components/docs). See Enable cluster-wide FIPS + (https://aka.ms/aks/fips) for more details. + Requires Kubernetes version 1.34 or later and the + Microsoft.ContainerService/EnableFIPSPreview feature to be registered + on the subscription. Existing node pools must already be FIPS-enabled + before enabling this cluster-level setting, and future node pools must + also be created with FIPS enabled. Some addons and extensions aren't + supported with cluster-wide FIPS. Verify addon and extension + compatibility before enabling this preview feature. + - name: --disable-fips + type: bool + short-summary: Disable FIPS mode at the cluster level. + long-summary: |- + Disables cluster-wide FIPS enforcement for AKS-managed components. + This doesn't disable FIPS on existing node pools. - name: --enable-service-account-image-pull type: bool short-summary: Enable service account based image pull. For more information, see https://aka.ms/aks/identity-binding/acr-image-pull/docs. @@ -1505,6 +1540,8 @@ text: az aks update --enable-cluster-autoscaler --min-count 1 --max-count 5 -g MyResourceGroup -n MyManagedCluster - name: Disable cluster-autoscaler for an existing cluster text: az aks update --disable-cluster-autoscaler -g MyResourceGroup -n MyManagedCluster + - name: Disable FIPS mode at the cluster level. + text: az aks update -g MyResourceGroup -n MyManagedCluster --disable-fips - name: Update min-count or max-count for cluster autoscaler. text: az aks update --update-cluster-autoscaler --min-count 1 --max-count 10 -g MyResourceGroup -n MyManagedCluster - name: Upgrade load balancer sku to standard diff --git a/src/aks-preview/azext_aks_preview/_params.py b/src/aks-preview/azext_aks_preview/_params.py index f4deb15bca9..d74870bc010 100644 --- a/src/aks-preview/azext_aks_preview/_params.py +++ b/src/aks-preview/azext_aks_preview/_params.py @@ -921,6 +921,7 @@ def load_arguments(self, _): c.argument("enable_encryption_at_host", action="store_true") c.argument("enable_ultra_ssd", action="store_true") c.argument("enable_fips_image", action="store_true") + c.argument("enable_fips", action="store_true", is_preview=True) c.argument("kubelet_config") c.argument("linux_os_config") c.argument("host_group_id", validator=validate_host_group_id) @@ -1549,6 +1550,8 @@ def load_arguments(self, _): ) c.argument("image_cleaner_interval_hours", type=int) c.argument("disable_image_integrity", action="store_true", is_preview=True) + c.argument("enable_fips", action="store_true", is_preview=True) + c.argument("disable_fips", action="store_true", is_preview=True) c.argument("enable_service_account_image_pull", action="store_true", is_preview=True) c.argument("disable_service_account_image_pull", action="store_true", is_preview=True) c.argument("service_account_image_pull_default_managed_identity_id", is_preview=True) diff --git a/src/aks-preview/azext_aks_preview/custom.py b/src/aks-preview/azext_aks_preview/custom.py index 77ab483c1ad..7d6aa23c1ab 100644 --- a/src/aks-preview/azext_aks_preview/custom.py +++ b/src/aks-preview/azext_aks_preview/custom.py @@ -1073,6 +1073,7 @@ def aks_create( enable_encryption_at_host=False, enable_ultra_ssd=False, enable_fips_image=False, + enable_fips=False, kubelet_config=None, linux_os_config=None, host_group_id=None, @@ -1343,6 +1344,8 @@ def aks_update( image_cleaner_interval_hours=None, enable_image_integrity=False, disable_image_integrity=False, + enable_fips=False, + disable_fips=False, enable_service_account_image_pull=False, disable_service_account_image_pull=False, service_account_image_pull_default_managed_identity_id=None, diff --git a/src/aks-preview/azext_aks_preview/managed_cluster_decorator.py b/src/aks-preview/azext_aks_preview/managed_cluster_decorator.py index 60f22700aaa..74b15c06ae2 100644 --- a/src/aks-preview/azext_aks_preview/managed_cluster_decorator.py +++ b/src/aks-preview/azext_aks_preview/managed_cluster_decorator.py @@ -1821,6 +1821,61 @@ def get_kubernetes_version(self) -> str: """ return self._get_kubernetes_version(read_only=False) + def _validate_enable_fips_kubernetes_version(self) -> None: + kubernetes_version = self._get_kubernetes_version(read_only=True) + if not kubernetes_version: + return + + version_parts = str(kubernetes_version).lstrip("v").split(".") + if len(version_parts) < 2: + return + try: + major = int(version_parts[0]) + minor = int(version_parts[1].split("-")[0]) + except ValueError: + return + if (major, minor) < (1, 34): + raise InvalidArgumentValueError("--enable-fips requires Kubernetes version 1.34 or later.") + + def _get_enable_fips_from_mc(self) -> Optional[bool]: + if not self.mc: + return None + if hasattr(self.mc, "enable_fips") and self.mc.enable_fips is not None: + return self.mc.enable_fips + properties = getattr(self.mc, "properties", None) + if properties is not None: + return properties.get("enableFIPS") + return None + + def get_enable_fips(self) -> bool: + """Obtain the value of enable_fips. + :return: bool + """ + enable_fips = self.raw_param.get("enable_fips", False) + if enable_fips and self.get_disable_fips(): + raise MutuallyExclusiveArgumentError( + "Cannot specify --enable-fips and --disable-fips at the same time." + ) + if self.decorator_mode == DecoratorMode.CREATE: + value_obtained_from_mc = self._get_enable_fips_from_mc() + if value_obtained_from_mc is not None: + enable_fips = value_obtained_from_mc + + if enable_fips: + self._validate_enable_fips_kubernetes_version() + return bool(enable_fips) + + def get_disable_fips(self) -> bool: + """Obtain the value of disable_fips. + :return: bool + """ + disable_fips = self.raw_param.get("disable_fips", False) + if disable_fips and self.raw_param.get("enable_fips", False): + raise MutuallyExclusiveArgumentError( + "Cannot specify --enable-fips and --disable-fips at the same time." + ) + return bool(disable_fips) + def get_disk_driver(self) -> Optional[ManagedClusterStorageProfileDiskCSIDriver]: """Obtain the value of storage_profile.disk_csi_driver @@ -4282,6 +4337,17 @@ def set_up_image_integrity(self, mc: ManagedCluster) -> ManagedCluster: return mc + def set_up_enable_fips(self, mc: ManagedCluster) -> ManagedCluster: + """Set up FIPS mode at the cluster level for the ManagedCluster object.""" + self._ensure_mc(mc) + + if self.context.get_enable_fips(): + mc.enable_fips = True + if mc.agent_pool_profiles: + for agentpool in mc.agent_pool_profiles: + agentpool.enable_fips = True + return mc + def set_up_service_account_image_pull(self, mc: ManagedCluster) -> ManagedCluster: """Set up security profile serviceAccountImagePullProfile for the ManagedCluster object. @@ -5174,6 +5240,8 @@ def construct_mc_profile_preview(self, bypass_restore_defaults: bool = False) -> mc = self.set_up_image_cleaner(mc) # set up image integrity mc = self.set_up_image_integrity(mc) + # set up FIPS mode at the cluster level + mc = self.set_up_enable_fips(mc) # set up service account image pull mc = self.set_up_service_account_image_pull(mc) # set up KMS infrastructure encryption @@ -6684,6 +6752,31 @@ def update_image_integrity(self, mc: ManagedCluster) -> ManagedCluster: return mc + def update_enable_fips(self, mc: ManagedCluster) -> ManagedCluster: + """Update FIPS mode at the cluster level for the ManagedCluster object.""" + self._ensure_mc(mc) + + if self.context.get_disable_fips(): + mc.enable_fips = False + return mc + + if not self.context.get_enable_fips(): + return mc + + non_fips_nodepools = [ + agentpool.name + for agentpool in (mc.agent_pool_profiles or []) + if agentpool.enable_fips is not True + ] + if non_fips_nodepools: + raise InvalidArgumentValueError( + "--enable-fips requires all node pools in the cluster to be FIPS-enabled. " + "Enable FIPS on these node pools first: {}.".format(", ".join(non_fips_nodepools)) + ) + + mc.enable_fips = True + return mc + def update_service_account_image_pull(self, mc: ManagedCluster) -> ManagedCluster: """Update security profile serviceAccountImagePullProfile for the ManagedCluster object. @@ -8091,6 +8184,8 @@ def update_mc_profile_preview(self) -> ManagedCluster: mc = self.update_image_cleaner(mc) # update image integrity mc = self.update_image_integrity(mc) + # update FIPS mode at the cluster level + mc = self.update_enable_fips(mc) # update service account image pull mc = self.update_service_account_image_pull(mc) # update KMS infrastructure encryption diff --git a/src/aks-preview/azext_aks_preview/tests/latest/test_aks_commands.py b/src/aks-preview/azext_aks_preview/tests/latest/test_aks_commands.py index 46769d53699..58ad76248ed 100644 --- a/src/aks-preview/azext_aks_preview/tests/latest/test_aks_commands.py +++ b/src/aks-preview/azext_aks_preview/tests/latest/test_aks_commands.py @@ -7140,6 +7140,97 @@ def test_aks_create_with_fips(self, resource_group, resource_group_location): checks=[self.is_empty()], ) + # FIPS mode at the cluster level is gated by EnableFIPSPreview AFEC and requires K8s 1.34+, + # so this scenario is live-only until the preview is broadly available. + @live_only() + @AllowLargeResponse() + @AKSCustomResourceGroupPreparer( + random_name_length=17, name_prefix="clitest", location="eastus2euap" + ) + def test_aks_create_with_cluster_fips( + self, resource_group, resource_group_location + ): + self.test_resources_count = 0 + aks_name = self.create_random_name("cliakstest", 16) + self.kwargs.update( + { + "resource_group": resource_group, + "name": aks_name, + "location": resource_group_location, + "ssh_key_value": self.generate_ssh_keys(), + } + ) + + self.cmd( + "aks create --resource-group={resource_group} --name={name} " + "--location={location} --kubernetes-version 1.34 " + "--enable-fips --ssh-key-value={ssh_key_value}", + checks=[ + self.check("provisioningState", "Succeeded"), + self.check("enableFips", True), + self.check("agentPoolProfiles[0].enableFips", True), + ], + ) + + self.cmd( + "aks delete -g {resource_group} -n {name} --yes --no-wait", + checks=[self.is_empty()], + ) + + @live_only() + @AllowLargeResponse() + @AKSCustomResourceGroupPreparer( + random_name_length=17, name_prefix="clitest", location="eastus2euap" + ) + def test_aks_update_with_cluster_fips( + self, resource_group, resource_group_location + ): + self.test_resources_count = 0 + aks_name = self.create_random_name("cliakstest", 16) + self.kwargs.update( + { + "resource_group": resource_group, + "name": aks_name, + "location": resource_group_location, + "ssh_key_value": self.generate_ssh_keys(), + } + ) + + self.cmd( + "aks create --resource-group={resource_group} --name={name} " + "--location={location} --kubernetes-version 1.34 " + "--enable-fips-image --ssh-key-value={ssh_key_value}", + checks=[ + self.check("provisioningState", "Succeeded"), + self.check("agentPoolProfiles[0].enableFips", True), + ], + ) + + self.cmd( + "aks update --resource-group={resource_group} --name={name} " + "--enable-fips", + checks=[ + self.check("provisioningState", "Succeeded"), + self.check("enableFips", True), + self.check("agentPoolProfiles[0].enableFips", True), + ], + ) + + self.cmd( + "aks update --resource-group={resource_group} --name={name} " + "--disable-fips", + checks=[ + self.check("provisioningState", "Succeeded"), + self.check("enableFips", False), + self.check("agentPoolProfiles[0].enableFips", True), + ], + ) + + self.cmd( + "aks delete -g {resource_group} -n {name} --yes --no-wait", + checks=[self.is_empty()], + ) + # the availability of features is controlled by a toggle and cannot be fully tested yet, # however, existing test results show that the client side works as expected, so exclude it at this moment @live_only() diff --git a/src/aks-preview/azext_aks_preview/tests/latest/test_managed_cluster_decorator.py b/src/aks-preview/azext_aks_preview/tests/latest/test_managed_cluster_decorator.py index fcf4fff548c..f7a49d405b7 100644 --- a/src/aks-preview/azext_aks_preview/tests/latest/test_managed_cluster_decorator.py +++ b/src/aks-preview/azext_aks_preview/tests/latest/test_managed_cluster_decorator.py @@ -97,6 +97,8 @@ UnknownError, CLIError, ) +from azure.cli.core.commands import AzCliCommandInvoker +from azure.cli.core.util import todict from azure.cli.command_modules.acs._consts import ( CONST_OUTBOUND_TYPE_LOAD_BALANCER, CONST_OUTBOUND_TYPE_MANAGED_NAT_GATEWAY, @@ -3123,6 +3125,83 @@ def test_get_kubernetes_version(self): ctx_5.get_kubernetes_version(), "custom_kubernetes_version" ) + def test_get_enable_fips(self): + # default + ctx_1 = AKSPreviewManagedClusterContext( + self.cmd, + AKSManagedClusterParamDict({}), + self.models, + DecoratorMode.CREATE, + ) + self.assertEqual(ctx_1.get_enable_fips(), False) + + # custom value with supported Kubernetes version + ctx_2 = AKSPreviewManagedClusterContext( + self.cmd, + AKSManagedClusterParamDict( + { + "enable_fips": True, + "kubernetes_version": "1.34.0", + } + ), + self.models, + DecoratorMode.CREATE, + ) + self.assertEqual(ctx_2.get_enable_fips(), True) + + # custom value with unsupported Kubernetes version + ctx_3 = AKSPreviewManagedClusterContext( + self.cmd, + AKSManagedClusterParamDict( + { + "enable_fips": True, + "kubernetes_version": "1.33.9", + } + ), + self.models, + DecoratorMode.CREATE, + ) + with self.assertRaises(InvalidArgumentValueError): + ctx_3.get_enable_fips() + + # CREATE: value on attached mc overrides raw parameter default + ctx_4 = AKSPreviewManagedClusterContext( + self.cmd, + AKSManagedClusterParamDict({"enable_fips": False}), + self.models, + DecoratorMode.CREATE, + ) + mc_4 = self.models.ManagedCluster( + location="test_location", + kubernetes_version="1.34.0", + ) + mc_4.properties["enableFIPS"] = True + ctx_4.attach_mc(mc_4) + self.assertEqual(ctx_4.get_enable_fips(), True) + + ctx_5 = AKSPreviewManagedClusterContext( + self.cmd, + AKSManagedClusterParamDict({"disable_fips": True}), + self.models, + DecoratorMode.UPDATE, + ) + self.assertEqual(ctx_5.get_disable_fips(), True) + + ctx_6 = AKSPreviewManagedClusterContext( + self.cmd, + AKSManagedClusterParamDict( + { + "enable_fips": True, + "disable_fips": True, + "kubernetes_version": "1.34.0", + } + ), + self.models, + DecoratorMode.UPDATE, + ) + with self.assertRaises(MutuallyExclusiveArgumentError): + ctx_6.get_enable_fips() + def test_get_disk_driver(self): ctx_1 = AKSPreviewManagedClusterContext( self.cmd, @@ -7589,6 +7668,72 @@ def test_set_up_bootstrap_profile(self): with self.assertRaises(MutuallyExclusiveArgumentError): dec_mc_4 = dec_4.set_up_bootstrap_profile(mc_4) + def test_set_up_enable_fips(self): + dec_1 = AKSPreviewManagedClusterCreateDecorator( + self.cmd, + self.client, + {}, + CUSTOM_MGMT_AKS_PREVIEW, + ) + mc_1 = self.models.ManagedCluster(location="test_location") + dec_1.context.attach_mc(mc_1) + dec_mc_1 = dec_1.set_up_enable_fips(mc_1) + ground_truth_mc_1 = self.models.ManagedCluster(location="test_location") + self.assertEqual(dec_mc_1, ground_truth_mc_1) + + dec_2 = AKSPreviewManagedClusterCreateDecorator( + self.cmd, + self.client, + { + "enable_fips": True, + "kubernetes_version": "1.34.0", + }, + CUSTOM_MGMT_AKS_PREVIEW, + ) + agentpool_profile = self.models.ManagedClusterAgentPoolProfile( + name="nodepool1", + enable_fips=False, + ) + mc_2 = self.models.ManagedCluster( + location="test_location", + kubernetes_version="1.34.0", + agent_pool_profiles=[agentpool_profile], + ) + dec_2.context.attach_mc(mc_2) + dec_mc_2 = dec_2.set_up_enable_fips(mc_2) + ground_truth_agentpool_profile = self.models.ManagedClusterAgentPoolProfile( + name="nodepool1", + enable_fips=True, + ) + ground_truth_mc_2 = self.models.ManagedCluster( + location="test_location", + kubernetes_version="1.34.0", + agent_pool_profiles=[ground_truth_agentpool_profile], + ) + ground_truth_mc_2.enable_fips = True + self.assertEqual(dec_mc_2, ground_truth_mc_2) + self.assertEqual( + todict(dec_mc_2, AzCliCommandInvoker.remove_additional_prop_layer).get("enableFips"), + True, + ) + + dec_3 = AKSPreviewManagedClusterCreateDecorator( + self.cmd, + self.client, + { + "enable_fips": True, + "kubernetes_version": "1.33.9", + }, + CUSTOM_MGMT_AKS_PREVIEW, + ) + mc_3 = self.models.ManagedCluster( + location="test_location", + kubernetes_version="1.33.9", + ) + dec_3.context.attach_mc(mc_3) + with self.assertRaises(InvalidArgumentValueError): + dec_3.set_up_enable_fips(mc_3) + def test_set_up_static_egress_gateway(self): dec_0 = AKSPreviewManagedClusterCreateDecorator( self.cmd, @@ -13873,6 +14018,130 @@ def test_update_supportPlan(self): normalClusterCalculated = noopDecorator3.update_k8s_support_plan(normalCluster) self.assertEqual(normalClusterCalculated, normalCluster) + def test_update_enable_fips(self): + dec_1 = AKSPreviewManagedClusterUpdateDecorator( + self.cmd, + self.client, + {}, + CUSTOM_MGMT_AKS_PREVIEW, + ) + mc_1 = self.models.ManagedCluster( + location="test_location", + kubernetes_version="1.34.0", + ) + dec_1.context.attach_mc(mc_1) + dec_mc_1 = dec_1.update_enable_fips(mc_1) + self.assertEqual(dec_mc_1, mc_1) + + dec_2 = AKSPreviewManagedClusterUpdateDecorator( + self.cmd, + self.client, + {"enable_fips": True}, + CUSTOM_MGMT_AKS_PREVIEW, + ) + agentpool_profile = self.models.ManagedClusterAgentPoolProfile( + name="nodepool1", + enable_fips=True, + ) + mc_2 = self.models.ManagedCluster( + location="test_location", + kubernetes_version="1.34.0", + agent_pool_profiles=[agentpool_profile], + ) + dec_2.context.attach_mc(mc_2) + dec_mc_2 = dec_2.update_enable_fips(mc_2) + ground_truth_mc_2 = self.models.ManagedCluster( + location="test_location", + kubernetes_version="1.34.0", + agent_pool_profiles=[agentpool_profile], + ) + ground_truth_mc_2.enable_fips = True + self.assertEqual(dec_mc_2, ground_truth_mc_2) + self.assertEqual( + todict(dec_mc_2, AzCliCommandInvoker.remove_additional_prop_layer).get("enableFips"), + True, + ) + + dec_3 = AKSPreviewManagedClusterUpdateDecorator( + self.cmd, + self.client, + {"enable_fips": True}, + CUSTOM_MGMT_AKS_PREVIEW, + ) + non_fips_agentpool_profile = self.models.ManagedClusterAgentPoolProfile( + name="nodepool2", + enable_fips=False, + ) + mc_3 = self.models.ManagedCluster( + location="test_location", + kubernetes_version="1.34.0", + agent_pool_profiles=[non_fips_agentpool_profile], + ) + dec_3.context.attach_mc(mc_3) + with self.assertRaises(InvalidArgumentValueError): + dec_3.update_enable_fips(mc_3) + + dec_4 = AKSPreviewManagedClusterUpdateDecorator( + self.cmd, + self.client, + {"enable_fips": True}, + CUSTOM_MGMT_AKS_PREVIEW, + ) + mc_4 = self.models.ManagedCluster( + location="test_location", + kubernetes_version="1.33.9", + ) + dec_4.context.attach_mc(mc_4) + with self.assertRaises(InvalidArgumentValueError): + dec_4.update_enable_fips(mc_4) + + dec_5 = AKSPreviewManagedClusterUpdateDecorator( + self.cmd, + self.client, + {"disable_fips": True}, + CUSTOM_MGMT_AKS_PREVIEW, + ) + agentpool_profile_5 = self.models.ManagedClusterAgentPoolProfile( + name="nodepool1", + enable_fips=True, + ) + mc_5 = self.models.ManagedCluster( + location="test_location", + kubernetes_version="1.34.0", + agent_pool_profiles=[agentpool_profile_5], + ) + mc_5.properties["enableFIPS"] = True + dec_5.context.attach_mc(mc_5) + dec_mc_5 = dec_5.update_enable_fips(mc_5) + ground_truth_mc_5 = self.models.ManagedCluster( + location="test_location", + kubernetes_version="1.34.0", + agent_pool_profiles=[agentpool_profile_5], + ) + ground_truth_mc_5.enable_fips = False + self.assertEqual(dec_mc_5, ground_truth_mc_5) + self.assertEqual( + todict(dec_mc_5, AzCliCommandInvoker.remove_additional_prop_layer).get("enableFips"), + False, + ) + + dec_6 = AKSPreviewManagedClusterUpdateDecorator( + self.cmd, + self.client, + { + "enable_fips": True, + "disable_fips": True, + }, + CUSTOM_MGMT_AKS_PREVIEW, + ) + mc_6 = self.models.ManagedCluster( + location="test_location", + kubernetes_version="1.34.0", + ) + dec_6.context.attach_mc(mc_6) + with self.assertRaises(MutuallyExclusiveArgumentError): + dec_6.update_enable_fips(mc_6) + def test_mc_get_node_init_taints(self): # Default, not set. ctx_1 = AKSPreviewManagedClusterContext(