From 30532b77155ff1e5580bc8722ff1d3844043b9d7 Mon Sep 17 00:00:00 2001 From: david kydd Date: Thu, 7 May 2026 19:51:29 +1200 Subject: [PATCH 1/9] [AKS] aks-preview: add --enable/--disable-control-plane-metrics Surface the new first-class API property azureMonitorProfile.metrics.controlPlane.enabled (API version 2026-02-02-preview) so users can opt in/out of Azure Monitor managed Prometheus control plane metrics (kube-apiserver, etcd, etc.) without relying on the AFEC-gated preview. - Add --enable-control-plane-metrics on `az aks create` and `az aks update`, plus --disable-control-plane-metrics on `az aks update`. - Validate that --enable-control-plane-metrics requires Azure Monitor metrics to be enabled (either already on the cluster or via --enable-azure-monitor-metrics in the same command), and that enable and disable cannot be combined. - Wire the flags into the create (set_up_azure_monitor_profile) and update (update_azure_monitor_profile) decorator paths. - Bump extension to 20.0.0b7 and add HISTORY entry. --- src/aks-preview/HISTORY.rst | 4 + src/aks-preview/azext_aks_preview/_help.py | 9 ++ src/aks-preview/azext_aks_preview/_params.py | 3 + src/aks-preview/azext_aks_preview/custom.py | 3 + .../managed_cluster_decorator.py | 109 ++++++++++++++++++ src/aks-preview/setup.py | 2 +- 6 files changed, 129 insertions(+), 1 deletion(-) diff --git a/src/aks-preview/HISTORY.rst b/src/aks-preview/HISTORY.rst index 33ca380a7d8..204d5b93614 100644 --- a/src/aks-preview/HISTORY.rst +++ b/src/aks-preview/HISTORY.rst @@ -14,6 +14,10 @@ Pending * Update the minimum required cli core version to `2.76.0` (actually since `20.0.0b3`). * `az aks upgrade`: Add `--k8s-support-plan` and `--tier` flag support to allow cluster support plan and tier configuration during cluster upgrade. +20.0.0b7 +++++++ +* `az aks create / update`: Add `--enable-control-plane-metrics` and `az aks update`: `--disable-control-plane-metrics` flags to opt clusters into Azure Monitor managed Prometheus control plane metrics (kube-apiserver, etcd, etc.) via the first-class API property in API version `2026-02-02-preview` (replaces the AFEC-gated preview). + 20.0.0b6 ++++++ * `az aks loadbalancer update`: Allow updating `--primary-agent-pool-name` for load balancer configurations. diff --git a/src/aks-preview/azext_aks_preview/_help.py b/src/aks-preview/azext_aks_preview/_help.py index c33f774bd21..99587c37868 100644 --- a/src/aks-preview/azext_aks_preview/_help.py +++ b/src/aks-preview/azext_aks_preview/_help.py @@ -583,6 +583,9 @@ - name: --enable-azure-monitor-metrics type: bool short-summary: Enable Azure Monitor Metrics Profile + - name: --enable-control-plane-metrics + type: bool + short-summary: Enable collection of Azure Monitor managed Prometheus control plane metrics for managed cluster components (kube-apiserver, etcd, etc). Requires --enable-azure-monitor-metrics. See aka.ms/aks/controlplane-metrics. - name: --azure-monitor-workspace-resource-id type: string short-summary: Resource ID of the Azure Monitor Workspace @@ -1291,6 +1294,9 @@ - name: --enable-azure-monitor-metrics type: bool short-summary: Enable Azure Monitor Metrics Profile + - name: --enable-control-plane-metrics + type: bool + short-summary: Enable collection of Azure Monitor managed Prometheus control plane metrics for managed cluster components (kube-apiserver, etcd, etc). Requires --enable-azure-monitor-metrics. See aka.ms/aks/controlplane-metrics. - name: --azure-monitor-workspace-resource-id type: string short-summary: Resource ID of the Azure Monitor Workspace @@ -1312,6 +1318,9 @@ - name: --disable-azure-monitor-metrics type: bool short-summary: Disable Azure Monitor Metrics Profile. This will delete all DCRA's associated with the cluster, any linked DCRs with the data stream = prometheus-stream and the recording rule groups created by the addon for this AKS cluster. + - name: --disable-control-plane-metrics + type: bool + short-summary: Disable collection of Azure Monitor managed Prometheus control plane metrics. Leaves Azure Monitor metrics enabled. See aka.ms/aks/controlplane-metrics. - name: --enable-azure-monitor-app-monitoring type: bool short-summary: Enable Azure Monitor Application Monitoring diff --git a/src/aks-preview/azext_aks_preview/_params.py b/src/aks-preview/azext_aks_preview/_params.py index 84146eb6610..228f65eb5b9 100644 --- a/src/aks-preview/azext_aks_preview/_params.py +++ b/src/aks-preview/azext_aks_preview/_params.py @@ -1106,6 +1106,7 @@ def load_arguments(self, _): c.argument("ksm_metric_annotations_allow_list") c.argument("grafana_resource_id", validator=validate_grafanaresourceid) c.argument("enable_windows_recording_rules", action="store_true") + c.argument("enable_control_plane_metrics", action="store_true") c.argument("enable_azure_monitor_app_monitoring", is_preview=True, action="store_true" @@ -1601,6 +1602,8 @@ def load_arguments(self, _): hide=True, ), ) + c.argument("enable_control_plane_metrics", action="store_true") + c.argument("disable_control_plane_metrics", action="store_true") c.argument("enable_azure_monitor_app_monitoring", action="store_true", is_preview=True diff --git a/src/aks-preview/azext_aks_preview/custom.py b/src/aks-preview/azext_aks_preview/custom.py index b512cf0338e..3f7625df531 100644 --- a/src/aks-preview/azext_aks_preview/custom.py +++ b/src/aks-preview/azext_aks_preview/custom.py @@ -1137,6 +1137,7 @@ def aks_create( ksm_metric_annotations_allow_list=None, grafana_resource_id=None, enable_windows_recording_rules=False, + enable_control_plane_metrics=False, # azure monitor profile - app monitoring enable_azure_monitor_app_monitoring=False, # opentelemetry parameters @@ -1363,6 +1364,8 @@ def aks_update( enable_windows_recording_rules=False, disable_azuremonitormetrics=False, disable_azure_monitor_metrics=False, + enable_control_plane_metrics=False, + disable_control_plane_metrics=False, # azure monitor profile - app monitoring enable_azure_monitor_app_monitoring=False, disable_azure_monitor_app_monitoring=False, 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 17ac59ea25f..21b845923b3 100644 --- a/src/aks-preview/azext_aks_preview/managed_cluster_decorator.py +++ b/src/aks-preview/azext_aks_preview/managed_cluster_decorator.py @@ -2611,6 +2611,84 @@ def get_disable_azure_monitor_metrics(self) -> bool: """ return self._get_disable_azure_monitor_metrics(enable_validation=True) + def _get_enable_control_plane_metrics(self, enable_validation: bool = False) -> bool: + """Internal function to obtain the value of enable_control_plane_metrics. + This function supports the option of enable_validation. When enabled, if both + enable_control_plane_metrics and disable_control_plane_metrics are specified, raise a + MutuallyExclusiveArgumentError. Additionally, --enable-control-plane-metrics requires Azure + Monitor metrics to either already be enabled on the cluster or to be enabled in the same + command via --enable-azure-monitor-metrics. + + :return: bool + """ + # Read the original value passed by the command. + enable_control_plane_metrics = self.raw_param.get("enable_control_plane_metrics") + # In create mode, try to read the property value corresponding to the parameter from the `mc` object. + if self.decorator_mode == DecoratorMode.CREATE: + if ( + self.mc and + self.mc.azure_monitor_profile and + self.mc.azure_monitor_profile.metrics and + self.mc.azure_monitor_profile.metrics.control_plane + ): + enable_control_plane_metrics = self.mc.azure_monitor_profile.metrics.control_plane.enabled + # This parameter does not need dynamic completion. + if enable_validation: + if enable_control_plane_metrics and self._get_disable_control_plane_metrics(False): + raise MutuallyExclusiveArgumentError( + "Cannot specify --enable-control-plane-metrics and --disable-control-plane-metrics " + "at the same time." + ) + if enable_control_plane_metrics: + # Must have Azure Monitor metrics enabled (either already or in this command). + already_enabled = ( + self.mc and + self.mc.azure_monitor_profile and + self.mc.azure_monitor_profile.metrics and + self.mc.azure_monitor_profile.metrics.enabled + ) + enabling_now = self._get_enable_azure_monitor_metrics(False) + if not already_enabled and not enabling_now: + raise RequiredArgumentMissingError( + "--enable-control-plane-metrics requires Azure Monitor metrics to be enabled. " + "Specify --enable-azure-monitor-metrics or run on a cluster that already has " + "Azure Monitor metrics enabled." + ) + return enable_control_plane_metrics + + def get_enable_control_plane_metrics(self) -> bool: + """Obtain the value of enable_control_plane_metrics. + This function will verify the parameter by default. If both enable_control_plane_metrics and + disable_control_plane_metrics are specified, raise a MutuallyExclusiveArgumentError. + :return: bool + """ + return self._get_enable_control_plane_metrics(enable_validation=True) + + def _get_disable_control_plane_metrics(self, enable_validation: bool = False) -> bool: + """Internal function to obtain the value of disable_control_plane_metrics. + This function supports the option of enable_validation. When enabled, if both + enable_control_plane_metrics and disable_control_plane_metrics are specified, raise a + MutuallyExclusiveArgumentError. + :return: bool + """ + # Read the original value passed by the command. + disable_control_plane_metrics = self.raw_param.get("disable_control_plane_metrics") + if enable_validation: + if disable_control_plane_metrics and self._get_enable_control_plane_metrics(False): + raise MutuallyExclusiveArgumentError( + "Cannot specify --enable-control-plane-metrics and --disable-control-plane-metrics " + "at the same time." + ) + return disable_control_plane_metrics + + def get_disable_control_plane_metrics(self) -> bool: + """Obtain the value of disable_control_plane_metrics. + This function will verify the parameter by default. If both enable_control_plane_metrics and + disable_control_plane_metrics are specified, raise a MutuallyExclusiveArgumentError. + :return: bool + """ + return self._get_disable_control_plane_metrics(enable_validation=True) + def _get_enable_azure_monitor_app_monitoring(self, enable_validation=True) -> bool: """Internal function to obtain the value of enable_azure_monitor_app_monitoring. This function supports the option of enable_validation. When enabled, if both @@ -4637,6 +4715,13 @@ def _setup_azure_monitor_metrics(self, mc: ManagedCluster) -> None: metric_annotations_allow_list=str(ksm_metric_annotations_allow_list) )) mc.azure_monitor_profile.metrics.kube_state_metrics = kube_state_metrics + + # Enable control plane metrics if requested. + if self.context.get_enable_control_plane_metrics(): + mc.azure_monitor_profile.metrics.control_plane = ( + self.models.ManagedClusterAzureMonitorProfileMetricsControlPlane(enabled=True) + ) + self.context.set_intermediate("azuremonitormetrics_addon_enabled", True, overwrite_exists=True) def _setup_azure_monitor_app_monitoring(self, mc: ManagedCluster) -> None: @@ -6923,6 +7008,30 @@ def update_azure_monitor_profile(self, mc: ManagedCluster) -> ManagedCluster: if self.context.get_disable_azure_monitor_metrics(): self._disable_azure_monitor_metrics(mc) + # Handle enable / disable of control plane metrics independently of the parent metrics flag, + # so users can toggle control plane metrics on a cluster that already has metrics enabled. + if self.context.get_enable_control_plane_metrics(): + if mc.azure_monitor_profile is None: + mc.azure_monitor_profile = self.models.ManagedClusterAzureMonitorProfile() # pylint: disable=no-member + if mc.azure_monitor_profile.metrics is None: + # Should not normally happen — validation requires metrics to be enabled — but guard + # against partially-populated profiles to avoid AttributeError. + mc.azure_monitor_profile.metrics = ( + self.models.ManagedClusterAzureMonitorProfileMetrics(enabled=True) # pylint: disable=no-member + ) + mc.azure_monitor_profile.metrics.control_plane = ( + self.models.ManagedClusterAzureMonitorProfileMetricsControlPlane(enabled=True) # pylint: disable=no-member + ) + + if self.context.get_disable_control_plane_metrics(): + if ( + mc.azure_monitor_profile and + mc.azure_monitor_profile.metrics + ): + mc.azure_monitor_profile.metrics.control_plane = ( + self.models.ManagedClusterAzureMonitorProfileMetricsControlPlane(enabled=False) # pylint: disable=no-member + ) + if self.context.get_enable_azure_monitor_app_monitoring(): if mc.azure_monitor_profile is None: mc.azure_monitor_profile = self.models.ManagedClusterAzureMonitorProfile() diff --git a/src/aks-preview/setup.py b/src/aks-preview/setup.py index eb271541186..3c3f3b698b9 100644 --- a/src/aks-preview/setup.py +++ b/src/aks-preview/setup.py @@ -9,7 +9,7 @@ from setuptools import find_packages, setup -VERSION = "20.0.0b6" +VERSION = "20.0.0b7" CLASSIFIERS = [ "Development Status :: 4 - Beta", From e3c6dffe77139aaa00513b4e237f5d8756053b10 Mon Sep 17 00:00:00 2001 From: david kydd Date: Tue, 12 May 2026 16:38:13 +1200 Subject: [PATCH 2/9] fix(aks-preview): reject --enable-control-plane-metrics with --disable-azure-monitor-metrics Combining the two flags in the same command produced an inconsistent payload (azureMonitorProfile.metrics.enabled=False AND metrics.controlPlane.enabled=True). Validator now raises MutuallyExclusiveArgumentError up-front. Addresses Copilot review feedback on PR #9855. --- .../azext_aks_preview/managed_cluster_decorator.py | 7 +++++++ 1 file changed, 7 insertions(+) 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 21b845923b3..fed7d63420f 100644 --- a/src/aks-preview/azext_aks_preview/managed_cluster_decorator.py +++ b/src/aks-preview/azext_aks_preview/managed_cluster_decorator.py @@ -2640,6 +2640,13 @@ def _get_enable_control_plane_metrics(self, enable_validation: bool = False) -> "at the same time." ) if enable_control_plane_metrics: + # Reject combining enable-control-plane-metrics with disable-azure-monitor-metrics + # in the same command — the resulting payload would be inconsistent. + if self._get_disable_azure_monitor_metrics(False): + raise MutuallyExclusiveArgumentError( + "Cannot specify --enable-control-plane-metrics together with " + "--disable-azure-monitor-metrics." + ) # Must have Azure Monitor metrics enabled (either already or in this command). already_enabled = ( self.mc and From a7b923cb9b03fdd80bd37ceeb702a1a75163372b Mon Sep 17 00:00:00 2001 From: david kydd Date: Tue, 12 May 2026 16:38:36 +1200 Subject: [PATCH 3/9] fix(aks-preview): trigger control-plane-metrics validation on create even without parent flag set_up_azure_monitor_profile now invokes get_enable_control_plane_metrics() unconditionally so passing --enable-control-plane-metrics without --enable-azure-monitor-metrics raises RequiredArgumentMissingError instead of being silently ignored when _setup_azure_monitor_metrics is skipped. Addresses Copilot review feedback on PR #9855. --- .../azext_aks_preview/managed_cluster_decorator.py | 5 +++++ 1 file changed, 5 insertions(+) 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 fed7d63420f..daf3089d271 100644 --- a/src/aks-preview/azext_aks_preview/managed_cluster_decorator.py +++ b/src/aks-preview/azext_aks_preview/managed_cluster_decorator.py @@ -4848,6 +4848,11 @@ def set_up_azure_monitor_profile(self, mc: ManagedCluster) -> ManagedCluster: """ self._ensure_mc(mc) + # Trigger control-plane-metrics validation even if the parent metrics flag was + # not specified, so users get a clear error instead of silent ignore when they + # pass --enable-control-plane-metrics on its own. + self.context.get_enable_control_plane_metrics() + if self.context.get_enable_azure_monitor_metrics(): self._setup_azure_monitor_metrics(mc) From 9cda233232727afc8f779125eb2e4800b5800e5b Mon Sep 17 00:00:00 2001 From: david kydd Date: Tue, 12 May 2026 16:38:51 +1200 Subject: [PATCH 4/9] docs(aks-preview): clarify --enable-control-plane-metrics prerequisite wording Previous wording "Requires --enable-azure-monitor-metrics" was misleading on update for clusters that already have Azure Monitor metrics enabled. Updated to "Requires Azure Monitor metrics to be enabled (already enabled or via --enable-azure-monitor-metrics)" for both 'aks create' and 'aks update'. Addresses Copilot review feedback on PR #9855. --- src/aks-preview/azext_aks_preview/_help.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/aks-preview/azext_aks_preview/_help.py b/src/aks-preview/azext_aks_preview/_help.py index 99587c37868..9d2f04518ca 100644 --- a/src/aks-preview/azext_aks_preview/_help.py +++ b/src/aks-preview/azext_aks_preview/_help.py @@ -585,7 +585,7 @@ short-summary: Enable Azure Monitor Metrics Profile - name: --enable-control-plane-metrics type: bool - short-summary: Enable collection of Azure Monitor managed Prometheus control plane metrics for managed cluster components (kube-apiserver, etcd, etc). Requires --enable-azure-monitor-metrics. See aka.ms/aks/controlplane-metrics. + short-summary: Enable collection of Azure Monitor managed Prometheus control plane metrics for managed cluster components (kube-apiserver, etcd, etc). Requires Azure Monitor metrics to be enabled (already enabled or via --enable-azure-monitor-metrics). See aka.ms/aks/controlplane-metrics. - name: --azure-monitor-workspace-resource-id type: string short-summary: Resource ID of the Azure Monitor Workspace @@ -1296,7 +1296,7 @@ short-summary: Enable Azure Monitor Metrics Profile - name: --enable-control-plane-metrics type: bool - short-summary: Enable collection of Azure Monitor managed Prometheus control plane metrics for managed cluster components (kube-apiserver, etcd, etc). Requires --enable-azure-monitor-metrics. See aka.ms/aks/controlplane-metrics. + short-summary: Enable collection of Azure Monitor managed Prometheus control plane metrics for managed cluster components (kube-apiserver, etcd, etc). Requires Azure Monitor metrics to be enabled (already enabled or via --enable-azure-monitor-metrics). See aka.ms/aks/controlplane-metrics. - name: --azure-monitor-workspace-resource-id type: string short-summary: Resource ID of the Azure Monitor Workspace From 6101e7634357a1af2ab70e400a938bfa63fe15a5 Mon Sep 17 00:00:00 2001 From: david kydd Date: Tue, 12 May 2026 16:38:51 +1200 Subject: [PATCH 5/9] docs(aks-preview): move Pending bullets into 20.0.0b7 release section The two unreleased bullets under Pending (cli core minimum bump, --k8s-support-plan/--tier on upgrade) are part of 20.0.0b7. Moved into the 20.0.0b7 section so the changelog reflects the actual shipping version. Addresses Copilot review feedback on PR #9855. --- src/aks-preview/HISTORY.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/aks-preview/HISTORY.rst b/src/aks-preview/HISTORY.rst index 204d5b93614..5c1864fd7d7 100644 --- a/src/aks-preview/HISTORY.rst +++ b/src/aks-preview/HISTORY.rst @@ -11,12 +11,12 @@ To release a new version, please select a new version number (usually plus 1 to Pending +++++++ -* Update the minimum required cli core version to `2.76.0` (actually since `20.0.0b3`). -* `az aks upgrade`: Add `--k8s-support-plan` and `--tier` flag support to allow cluster support plan and tier configuration during cluster upgrade. 20.0.0b7 ++++++ * `az aks create / update`: Add `--enable-control-plane-metrics` and `az aks update`: `--disable-control-plane-metrics` flags to opt clusters into Azure Monitor managed Prometheus control plane metrics (kube-apiserver, etcd, etc.) via the first-class API property in API version `2026-02-02-preview` (replaces the AFEC-gated preview). +* Update the minimum required cli core version to `2.76.0` (actually since `20.0.0b3`). +* `az aks upgrade`: Add `--k8s-support-plan` and `--tier` flag support to allow cluster support plan and tier configuration during cluster upgrade. 20.0.0b6 ++++++ From 3f343fe59e0ae66945c6d76740ae3a3dcc8ad5cc Mon Sep 17 00:00:00 2001 From: david kydd Date: Tue, 12 May 2026 16:38:56 +1200 Subject: [PATCH 6/9] test(aks-preview): add control-plane metrics validation/update coverage Adds 5 update-decorator tests covering the new validation branches and update path: - enable-control-plane-metrics without parent flag raises - enable-control-plane-metrics succeeds when AM metrics already on cluster - enable-control-plane-metrics + disable-azure-monitor-metrics raises - enable + disable control-plane-metrics together raises - disable-control-plane-metrics writes control_plane.enabled=False Addresses Copilot review feedback on PR #9855. --- .../latest/test_managed_cluster_decorator.py | 146 ++++++++++++++++++ 1 file changed, 146 insertions(+) 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 39f53f81e3e..59002a2a914 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 @@ -12284,6 +12284,152 @@ def test_update_disable_azure_monitor_metrics(self): dec_mc_3.azure_monitor_profile.app_monitoring.open_telemetry_metrics ) + def test_update_enable_control_plane_metrics_requires_parent_metrics(self): + # Update path: --enable-control-plane-metrics on a cluster that has neither + # Azure Monitor metrics already enabled nor --enable-azure-monitor-metrics in + # the same command must raise RequiredArgumentMissingError. + dec = AKSPreviewManagedClusterUpdateDecorator( + self.cmd, + self.client, + { + "enable_control_plane_metrics": True, + }, + CUSTOM_MGMT_AKS_PREVIEW, + ) + mc = self.models.ManagedCluster( + location="test_location", + identity=self.models.ManagedClusterIdentity(type="SystemAssigned"), + ) + dec.context.attach_mc(mc) + + with self.assertRaises(RequiredArgumentMissingError): + dec.context.get_enable_control_plane_metrics() + + def test_update_enable_control_plane_metrics_already_enabled_cluster_succeeds(self): + # Update path: --enable-control-plane-metrics on a cluster that already has + # Azure Monitor metrics enabled should succeed without requiring + # --enable-azure-monitor-metrics. + dec = AKSPreviewManagedClusterUpdateDecorator( + self.cmd, + self.client, + { + "enable_control_plane_metrics": True, + }, + CUSTOM_MGMT_AKS_PREVIEW, + ) + mc = self.models.ManagedCluster( + location="test_location", + identity=self.models.ManagedClusterIdentity(type="SystemAssigned"), + azure_monitor_profile=self.models.ManagedClusterAzureMonitorProfile( + metrics=self.models.ManagedClusterAzureMonitorProfileMetrics(enabled=True) + ), + ) + dec.context.attach_mc(mc) + + self.assertTrue(dec.context.get_enable_control_plane_metrics()) + + with patch( + "azext_aks_preview.managed_cluster_decorator.ensure_azure_monitor_profile_prerequisites" + ), patch.object( + dec.context, "get_subscription_id", return_value="test-subscription-id" + ), patch.object( + dec.context, "get_resource_group_name", return_value="test-rg" + ), patch.object( + dec.context, "get_name", return_value="test-cluster" + ): + dec_mc = dec.update_azure_monitor_profile(mc) + + self.assertIsNotNone(dec_mc.azure_monitor_profile.metrics.control_plane) + self.assertTrue(dec_mc.azure_monitor_profile.metrics.control_plane.enabled) + + def test_update_enable_control_plane_metrics_with_disable_metrics_raises(self): + # Update path: --enable-control-plane-metrics combined with + # --disable-azure-monitor-metrics in the same command must be rejected to + # avoid producing an inconsistent payload. + dec = AKSPreviewManagedClusterUpdateDecorator( + self.cmd, + self.client, + { + "enable_control_plane_metrics": True, + "disable_azure_monitor_metrics": True, + }, + CUSTOM_MGMT_AKS_PREVIEW, + ) + mc = self.models.ManagedCluster( + location="test_location", + identity=self.models.ManagedClusterIdentity(type="SystemAssigned"), + azure_monitor_profile=self.models.ManagedClusterAzureMonitorProfile( + metrics=self.models.ManagedClusterAzureMonitorProfileMetrics(enabled=True) + ), + ) + dec.context.attach_mc(mc) + + with self.assertRaises(MutuallyExclusiveArgumentError): + dec.context.get_enable_control_plane_metrics() + + def test_update_enable_control_plane_metrics_with_disable_control_plane_raises(self): + # --enable-control-plane-metrics together with --disable-control-plane-metrics + # in the same command must raise MutuallyExclusiveArgumentError. + dec = AKSPreviewManagedClusterUpdateDecorator( + self.cmd, + self.client, + { + "enable_control_plane_metrics": True, + "disable_control_plane_metrics": True, + }, + CUSTOM_MGMT_AKS_PREVIEW, + ) + mc = self.models.ManagedCluster( + location="test_location", + identity=self.models.ManagedClusterIdentity(type="SystemAssigned"), + azure_monitor_profile=self.models.ManagedClusterAzureMonitorProfile( + metrics=self.models.ManagedClusterAzureMonitorProfileMetrics(enabled=True) + ), + ) + dec.context.attach_mc(mc) + + with self.assertRaises(MutuallyExclusiveArgumentError): + dec.context.get_enable_control_plane_metrics() + + def test_update_disable_control_plane_metrics_sets_enabled_false(self): + # --disable-control-plane-metrics on a cluster that has it enabled should + # produce a payload with control_plane.enabled=False. + dec = AKSPreviewManagedClusterUpdateDecorator( + self.cmd, + self.client, + { + "disable_control_plane_metrics": True, + }, + CUSTOM_MGMT_AKS_PREVIEW, + ) + mc = self.models.ManagedCluster( + location="test_location", + identity=self.models.ManagedClusterIdentity(type="SystemAssigned"), + azure_monitor_profile=self.models.ManagedClusterAzureMonitorProfile( + metrics=self.models.ManagedClusterAzureMonitorProfileMetrics( + enabled=True, + control_plane=self.models.ManagedClusterAzureMonitorProfileMetricsControlPlane( + enabled=True + ), + ) + ), + ) + dec.context.attach_mc(mc) + + with patch( + "azext_aks_preview.managed_cluster_decorator.ensure_azure_monitor_profile_prerequisites" + ), patch.object( + dec.context, "get_subscription_id", return_value="test-subscription-id" + ), patch.object( + dec.context, "get_resource_group_name", return_value="test-rg" + ), patch.object( + dec.context, "get_name", return_value="test-cluster" + ): + dec_mc = dec.update_azure_monitor_profile(mc) + + self.assertIsNotNone(dec_mc.azure_monitor_profile.metrics.control_plane) + self.assertFalse(dec_mc.azure_monitor_profile.metrics.control_plane.enabled) + def test_setup_azure_monitor_logs_with_omsagent_camelcase(self): # Test that _setup_azure_monitor_logs handles existing omsAgent (camelCase) correctly # This simulates what Azure API returns From 552ef2c086d147a1b7695a919e5857665ff43e5b Mon Sep 17 00:00:00 2001 From: david kydd Date: Tue, 12 May 2026 22:35:18 +1200 Subject: [PATCH 7/9] fix(aks-preview): add short aliases for control-plane-metrics flags Linter (option_length_too_long, threshold 22) flagged --enable-control-plane-metrics (31) and --disable-control-plane-metrics (32) as too long. Adds --enable-cp-metrics and --disable-cp-metrics short aliases on both 'aks create' and 'aks update'. Canonical long names retained for backward compatibility. --- src/aks-preview/azext_aks_preview/_params.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/aks-preview/azext_aks_preview/_params.py b/src/aks-preview/azext_aks_preview/_params.py index 228f65eb5b9..2e1c94c68f8 100644 --- a/src/aks-preview/azext_aks_preview/_params.py +++ b/src/aks-preview/azext_aks_preview/_params.py @@ -1106,7 +1106,11 @@ def load_arguments(self, _): c.argument("ksm_metric_annotations_allow_list") c.argument("grafana_resource_id", validator=validate_grafanaresourceid) c.argument("enable_windows_recording_rules", action="store_true") - c.argument("enable_control_plane_metrics", action="store_true") + c.argument( + "enable_control_plane_metrics", + options_list=["--enable-control-plane-metrics", "--enable-cp-metrics"], + action="store_true", + ) c.argument("enable_azure_monitor_app_monitoring", is_preview=True, action="store_true" @@ -1602,8 +1606,16 @@ def load_arguments(self, _): hide=True, ), ) - c.argument("enable_control_plane_metrics", action="store_true") - c.argument("disable_control_plane_metrics", action="store_true") + c.argument( + "enable_control_plane_metrics", + options_list=["--enable-control-plane-metrics", "--enable-cp-metrics"], + action="store_true", + ) + c.argument( + "disable_control_plane_metrics", + options_list=["--disable-control-plane-metrics", "--disable-cp-metrics"], + action="store_true", + ) c.argument("enable_azure_monitor_app_monitoring", action="store_true", is_preview=True From 620006abea1921bd52955d80f99da3b186cee10c Mon Sep 17 00:00:00 2001 From: david kydd Date: Tue, 12 May 2026 22:56:39 +1200 Subject: [PATCH 8/9] fix(aks-preview): add inline help= for control-plane-metrics flags Linter (missing_parameter_help) requires inline help text on c.argument when options_list is set, since the YAML help block in _help.py is not matched once the canonical option name is one of several. Adds inline help= mirroring the YAML wording on all three argument definitions. --- src/aks-preview/azext_aks_preview/_params.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/aks-preview/azext_aks_preview/_params.py b/src/aks-preview/azext_aks_preview/_params.py index 2e1c94c68f8..96b6fc353f6 100644 --- a/src/aks-preview/azext_aks_preview/_params.py +++ b/src/aks-preview/azext_aks_preview/_params.py @@ -1110,6 +1110,7 @@ def load_arguments(self, _): "enable_control_plane_metrics", options_list=["--enable-control-plane-metrics", "--enable-cp-metrics"], action="store_true", + help="Enable collection of Azure Monitor managed Prometheus control plane metrics for managed cluster components (kube-apiserver, etcd, etc). Requires Azure Monitor metrics to be enabled (already enabled or via --enable-azure-monitor-metrics). See aka.ms/aks/controlplane-metrics.", ) c.argument("enable_azure_monitor_app_monitoring", is_preview=True, @@ -1610,11 +1611,13 @@ def load_arguments(self, _): "enable_control_plane_metrics", options_list=["--enable-control-plane-metrics", "--enable-cp-metrics"], action="store_true", + help="Enable collection of Azure Monitor managed Prometheus control plane metrics for managed cluster components (kube-apiserver, etcd, etc). Requires Azure Monitor metrics to be enabled (already enabled or via --enable-azure-monitor-metrics). See aka.ms/aks/controlplane-metrics.", ) c.argument( "disable_control_plane_metrics", options_list=["--disable-control-plane-metrics", "--disable-cp-metrics"], action="store_true", + help="Disable collection of Azure Monitor managed Prometheus control plane metrics. Sets azureMonitorProfile.metrics.controlPlane.enabled=false on the cluster.", ) c.argument("enable_azure_monitor_app_monitoring", action="store_true", From 88a3e2ec0bdc6b6adad7afda48ce1823a2807ba5 Mon Sep 17 00:00:00 2001 From: david kydd Date: Wed, 13 May 2026 12:44:08 +1200 Subject: [PATCH 9/9] fix(aks-preview): wrap long help= and add aliases to help entries - Wrap inline help= strings in _params.py to satisfy line-too-long (C0301). - Update _help.py entries to include the alias forms (--enable-cp-metrics, --disable-cp-metrics) so the linter's unrecognized_help_parameter_rule recognizes the canonical option list. --- src/aks-preview/azext_aks_preview/_help.py | 6 +++--- src/aks-preview/azext_aks_preview/_params.py | 17 ++++++++++++++--- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/aks-preview/azext_aks_preview/_help.py b/src/aks-preview/azext_aks_preview/_help.py index 9d2f04518ca..5c28e01f7b1 100644 --- a/src/aks-preview/azext_aks_preview/_help.py +++ b/src/aks-preview/azext_aks_preview/_help.py @@ -583,7 +583,7 @@ - name: --enable-azure-monitor-metrics type: bool short-summary: Enable Azure Monitor Metrics Profile - - name: --enable-control-plane-metrics + - name: --enable-control-plane-metrics --enable-cp-metrics type: bool short-summary: Enable collection of Azure Monitor managed Prometheus control plane metrics for managed cluster components (kube-apiserver, etcd, etc). Requires Azure Monitor metrics to be enabled (already enabled or via --enable-azure-monitor-metrics). See aka.ms/aks/controlplane-metrics. - name: --azure-monitor-workspace-resource-id @@ -1294,7 +1294,7 @@ - name: --enable-azure-monitor-metrics type: bool short-summary: Enable Azure Monitor Metrics Profile - - name: --enable-control-plane-metrics + - name: --enable-control-plane-metrics --enable-cp-metrics type: bool short-summary: Enable collection of Azure Monitor managed Prometheus control plane metrics for managed cluster components (kube-apiserver, etcd, etc). Requires Azure Monitor metrics to be enabled (already enabled or via --enable-azure-monitor-metrics). See aka.ms/aks/controlplane-metrics. - name: --azure-monitor-workspace-resource-id @@ -1318,7 +1318,7 @@ - name: --disable-azure-monitor-metrics type: bool short-summary: Disable Azure Monitor Metrics Profile. This will delete all DCRA's associated with the cluster, any linked DCRs with the data stream = prometheus-stream and the recording rule groups created by the addon for this AKS cluster. - - name: --disable-control-plane-metrics + - name: --disable-control-plane-metrics --disable-cp-metrics type: bool short-summary: Disable collection of Azure Monitor managed Prometheus control plane metrics. Leaves Azure Monitor metrics enabled. See aka.ms/aks/controlplane-metrics. - name: --enable-azure-monitor-app-monitoring diff --git a/src/aks-preview/azext_aks_preview/_params.py b/src/aks-preview/azext_aks_preview/_params.py index 96b6fc353f6..fc8ff8133d2 100644 --- a/src/aks-preview/azext_aks_preview/_params.py +++ b/src/aks-preview/azext_aks_preview/_params.py @@ -1110,7 +1110,11 @@ def load_arguments(self, _): "enable_control_plane_metrics", options_list=["--enable-control-plane-metrics", "--enable-cp-metrics"], action="store_true", - help="Enable collection of Azure Monitor managed Prometheus control plane metrics for managed cluster components (kube-apiserver, etcd, etc). Requires Azure Monitor metrics to be enabled (already enabled or via --enable-azure-monitor-metrics). See aka.ms/aks/controlplane-metrics.", + help=( + "Enable collection of Azure Monitor managed Prometheus control plane metrics for managed " + "cluster components (kube-apiserver, etcd, etc). Requires Azure Monitor metrics to be enabled " + "(already enabled or via --enable-azure-monitor-metrics). See aka.ms/aks/controlplane-metrics." + ), ) c.argument("enable_azure_monitor_app_monitoring", is_preview=True, @@ -1611,13 +1615,20 @@ def load_arguments(self, _): "enable_control_plane_metrics", options_list=["--enable-control-plane-metrics", "--enable-cp-metrics"], action="store_true", - help="Enable collection of Azure Monitor managed Prometheus control plane metrics for managed cluster components (kube-apiserver, etcd, etc). Requires Azure Monitor metrics to be enabled (already enabled or via --enable-azure-monitor-metrics). See aka.ms/aks/controlplane-metrics.", + help=( + "Enable collection of Azure Monitor managed Prometheus control plane metrics for managed " + "cluster components (kube-apiserver, etcd, etc). Requires Azure Monitor metrics to be enabled " + "(already enabled or via --enable-azure-monitor-metrics). See aka.ms/aks/controlplane-metrics." + ), ) c.argument( "disable_control_plane_metrics", options_list=["--disable-control-plane-metrics", "--disable-cp-metrics"], action="store_true", - help="Disable collection of Azure Monitor managed Prometheus control plane metrics. Sets azureMonitorProfile.metrics.controlPlane.enabled=false on the cluster.", + help=( + "Disable collection of Azure Monitor managed Prometheus control plane metrics. " + "Sets azureMonitorProfile.metrics.controlPlane.enabled=false on the cluster." + ), ) c.argument("enable_azure_monitor_app_monitoring", action="store_true",