Skip to content

Commit 43c3a1f

Browse files
committed
Fix addon and msi auth bug
1 parent d7110d8 commit 43c3a1f

2 files changed

Lines changed: 160 additions & 8 deletions

File tree

src/aks-preview/azext_aks_preview/managed_cluster_decorator.py

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,24 @@ def get_enable_msi_auth_for_monitoring(self) -> Union[bool, None]:
389389
elif enable_azure_monitor_logs:
390390
result = True
391391
elif enable_msi_auth_for_monitoring is False:
392-
result = False
392+
# The base class returns False when service_principal_profile.client_id is not None,
393+
# but MSI-based clusters set client_id to "msi". Check if the monitoring addon
394+
# already has useAADAuth=true, which indicates MSI auth is actually in use.
395+
addon_consts = self.get_addon_consts()
396+
CONST_MONITORING_ADDON_NAME = addon_consts.get("CONST_MONITORING_ADDON_NAME")
397+
CONST_MONITORING_USING_AAD_MSI_AUTH = addon_consts.get("CONST_MONITORING_USING_AAD_MSI_AUTH")
398+
if self.mc and self.mc.addon_profiles:
399+
monitoring_profile = (
400+
self.mc.addon_profiles.get(CONST_MONITORING_ADDON_NAME) or
401+
self.mc.addon_profiles.get(CONST_MONITORING_ADDON_NAME_CAMELCASE)
402+
)
403+
if (monitoring_profile and monitoring_profile.config and
404+
str(monitoring_profile.config.get(CONST_MONITORING_USING_AAD_MSI_AUTH, "")).lower() == "true"):
405+
result = True
406+
else:
407+
result = False
408+
else:
409+
result = False
393410
elif enable_msi_auth_for_monitoring is None and not disable_msi_auth and not enable_msi_auth:
394411
result = True
395412
else:
@@ -5109,9 +5126,14 @@ def postprocessing_after_mc_created(self, cluster: ManagedCluster) -> None:
51095126
)
51105127
addon_consts = self.context.get_addon_consts()
51115128
CONST_MONITORING_ADDON_NAME = addon_consts.get("CONST_MONITORING_ADDON_NAME")
5129+
# The API response may return the addon key as either "omsagent" or "omsAgent"
5130+
monitoring_addon_key = CONST_MONITORING_ADDON_NAME
5131+
if CONST_MONITORING_ADDON_NAME not in cluster.addon_profiles and \
5132+
CONST_MONITORING_ADDON_NAME_CAMELCASE in cluster.addon_profiles:
5133+
monitoring_addon_key = CONST_MONITORING_ADDON_NAME_CAMELCASE
51125134
self.context.external_functions.ensure_container_insights_for_monitoring(
51135135
self.cmd,
5114-
cluster.addon_profiles[CONST_MONITORING_ADDON_NAME],
5136+
cluster.addon_profiles[monitoring_addon_key],
51155137
self.context.get_subscription_id(),
51165138
self.context.get_resource_group_name(),
51175139
self.context.get_name(),
@@ -7733,14 +7755,21 @@ def postprocessing_after_mc_created(self, cluster: ManagedCluster) -> None:
77337755
CONST_MONITORING_ADDON_NAME = addon_consts.get("CONST_MONITORING_ADDON_NAME")
77347756
CONST_MONITORING_USING_AAD_MSI_AUTH = addon_consts.get("CONST_MONITORING_USING_AAD_MSI_AUTH")
77357757

7736-
if (cluster.addon_profiles and
7737-
CONST_MONITORING_ADDON_NAME in cluster.addon_profiles and
7738-
cluster.addon_profiles[CONST_MONITORING_ADDON_NAME].enabled):
7758+
# The API response may return the addon key as either "omsagent" or "omsAgent"
7759+
monitoring_addon_key = None
7760+
if cluster.addon_profiles:
7761+
if CONST_MONITORING_ADDON_NAME in cluster.addon_profiles:
7762+
monitoring_addon_key = CONST_MONITORING_ADDON_NAME
7763+
elif CONST_MONITORING_ADDON_NAME_CAMELCASE in cluster.addon_profiles:
7764+
monitoring_addon_key = CONST_MONITORING_ADDON_NAME_CAMELCASE
7765+
7766+
if (monitoring_addon_key and
7767+
cluster.addon_profiles[monitoring_addon_key].enabled):
77397768

77407769
# Check if MSI auth is enabled
77417770
if (CONST_MONITORING_USING_AAD_MSI_AUTH in
7742-
cluster.addon_profiles[CONST_MONITORING_ADDON_NAME].config and
7743-
str(cluster.addon_profiles[CONST_MONITORING_ADDON_NAME].config[
7771+
cluster.addon_profiles[monitoring_addon_key].config and
7772+
str(cluster.addon_profiles[monitoring_addon_key].config[
77447773
CONST_MONITORING_USING_AAD_MSI_AUTH]).lower() == "true"):
77457774

77467775
# Check parameter sizes to identify what might be causing large headers
@@ -7755,7 +7784,7 @@ def postprocessing_after_mc_created(self, cluster: ManagedCluster) -> None:
77557784

77567785
self.context.external_functions.ensure_container_insights_for_monitoring(
77577786
self.cmd,
7758-
cluster.addon_profiles[CONST_MONITORING_ADDON_NAME],
7787+
cluster.addon_profiles[monitoring_addon_key],
77597788
self.context.get_subscription_id(),
77607789
self.context.get_resource_group_name(),
77617790
self.context.get_name(),

src/aks-preview/azext_aks_preview/tests/latest/test_managed_cluster_decorator.py

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
CONST_MANAGED_GATEWAY_INSTALLATION_DISABLED,
4242
CONST_MANAGED_GATEWAY_INSTALLATION_STANDARD,
4343
CONST_MONITORING_ADDON_NAME,
44+
CONST_MONITORING_ADDON_NAME_CAMELCASE,
4445
CONST_MONITORING_LOG_ANALYTICS_WORKSPACE_RESOURCE_ID,
4546
CONST_MONITORING_USING_AAD_MSI_AUTH,
4647
CONST_NODEPOOL_MODE_SYSTEM,
@@ -5137,6 +5138,36 @@ def test_get_enable_high_log_scale_mode_update_monitoring_camelcase_key(self):
51375138
result = ctx.get_enable_high_log_scale_mode()
51385139
self.assertTrue(result)
51395140

5141+
def test_get_enable_msi_auth_for_monitoring_with_msi_service_principal(self):
5142+
"""Test that MSI auth is correctly detected when service_principal_profile.client_id='msi'.
5143+
5144+
The base class returns False when client_id is not None, but MSI-based clusters set
5145+
client_id to 'msi'. The preview override should check the addon config for useAADAuth.
5146+
"""
5147+
ctx = AKSPreviewManagedClusterContext(
5148+
self.cmd,
5149+
AKSManagedClusterParamDict({}),
5150+
self.models,
5151+
decorator_mode=DecoratorMode.UPDATE,
5152+
)
5153+
mc = self.models.ManagedCluster(
5154+
location="test_location",
5155+
service_principal_profile=self.models.ManagedClusterServicePrincipalProfile(
5156+
client_id="msi",
5157+
),
5158+
addon_profiles={
5159+
"omsagent": self.models.ManagedClusterAddonProfile(
5160+
enabled=True,
5161+
config={
5162+
CONST_MONITORING_USING_AAD_MSI_AUTH: "true",
5163+
}
5164+
)
5165+
},
5166+
)
5167+
ctx.attach_mc(mc)
5168+
result = ctx.get_enable_msi_auth_for_monitoring()
5169+
self.assertTrue(result)
5170+
51405171
def test_get_enable_default_domain(self):
51415172
# default value
51425173
ctx_1 = AKSPreviewManagedClusterContext(
@@ -7967,6 +7998,33 @@ def test_postprocessing_create_dcr_true_when_cnl_and_hlsm_both_set(self):
79677998
_, kwargs = mock_ecifm.call_args
79687999
self.assertTrue(kwargs["create_dcr"])
79698000

8001+
def test_postprocessing_create_dcr_true_with_camelcase_addon_key(self):
8002+
"""create_dcr=True when the API response uses the camelCase 'omsAgent' addon key.
8003+
8004+
The API may return 'omsAgent' instead of 'omsagent'. The postprocessing must
8005+
handle both key variants to ensure the DCR is updated.
8006+
"""
8007+
dec = self._make_postprocessing_decorator(
8008+
{"enable_container_network_logs": True, "enable_high_log_scale_mode": True}
8009+
)
8010+
# Build cluster with camelCase addon key (as the API might return)
8011+
cluster = self.models.ManagedCluster(
8012+
location="test_location",
8013+
addon_profiles={
8014+
CONST_MONITORING_ADDON_NAME_CAMELCASE: self.models.ManagedClusterAddonProfile(enabled=True)
8015+
},
8016+
)
8017+
external_functions = dec.context.external_functions
8018+
with patch.object(
8019+
external_functions, "ensure_container_insights_for_monitoring", return_value=None
8020+
) as mock_ecifm, patch.object(
8021+
dec.context, "get_enable_high_log_scale_mode", return_value=True
8022+
):
8023+
dec.postprocessing_after_mc_created(cluster)
8024+
mock_ecifm.assert_called_once()
8025+
_, kwargs = mock_ecifm.call_args
8026+
self.assertTrue(kwargs["create_dcr"])
8027+
79708028

79718029
def test_set_up_health_monitor_profile(self):
79728030
# no flag - no change
@@ -13738,6 +13796,71 @@ def test_update_disable_hlsm_standalone_no_postprocessing(self):
1373813796
dec.context.get_intermediate("monitoring_addon_postprocessing_required", default_value=False)
1373913797
)
1374013798

13799+
def test_update_postprocessing_with_camelcase_addon_key(self):
13800+
"""Test that update postprocessing works when the API response uses 'omsAgent' (camelCase).
13801+
13802+
The API may return the monitoring addon as 'omsAgent' instead of 'omsagent'.
13803+
The postprocessing must handle both key variants so the DCR gets updated.
13804+
"""
13805+
dec = AKSPreviewManagedClusterUpdateDecorator(
13806+
self.cmd,
13807+
self.client,
13808+
{
13809+
"enable_container_network_logs": True,
13810+
"enable_high_log_scale_mode": True,
13811+
"name": "test_name",
13812+
"resource_group_name": "test_rg_name",
13813+
"location": "test_location",
13814+
"enable_msi_auth_for_monitoring": True,
13815+
"enable_syslog": False,
13816+
"data_collection_settings": None,
13817+
},
13818+
CUSTOM_MGMT_AKS_PREVIEW,
13819+
)
13820+
mc = self.models.ManagedCluster(
13821+
location="test_location",
13822+
network_profile=self.models.ContainerServiceNetworkProfile(
13823+
advanced_networking=self.models.AdvancedNetworking(
13824+
enabled=True,
13825+
),
13826+
),
13827+
addon_profiles={
13828+
"omsagent": self.models.ManagedClusterAddonProfile(
13829+
enabled=True,
13830+
config={
13831+
CONST_MONITORING_USING_AAD_MSI_AUTH: "true",
13832+
}
13833+
)
13834+
},
13835+
)
13836+
dec.context.attach_mc(mc)
13837+
dec.context.set_intermediate("subscription_id", "test_subscription_id")
13838+
# Simulate profile update setting the postprocessing flag
13839+
dec.update_monitoring_profile_flow_logs(mc)
13840+
self.assertTrue(dec.context.get_intermediate("monitoring_addon_postprocessing_required"))
13841+
13842+
# Build API response cluster with camelCase addon key
13843+
cluster = self.models.ManagedCluster(
13844+
location="test_location",
13845+
addon_profiles={
13846+
CONST_MONITORING_ADDON_NAME_CAMELCASE: self.models.ManagedClusterAddonProfile(
13847+
enabled=True,
13848+
config={
13849+
CONST_MONITORING_USING_AAD_MSI_AUTH: "true",
13850+
}
13851+
)
13852+
},
13853+
)
13854+
external_functions = dec.context.external_functions
13855+
with patch.object(
13856+
external_functions, "ensure_container_insights_for_monitoring", return_value=None
13857+
) as mock_ecifm:
13858+
dec.postprocessing_after_mc_created(cluster)
13859+
mock_ecifm.assert_called_once()
13860+
_, kwargs = mock_ecifm.call_args
13861+
self.assertTrue(kwargs["create_dcr"])
13862+
self.assertTrue(kwargs["enable_high_log_scale_mode"])
13863+
1374113864
def test_update_node_provisioning_profile(self):
1374213865
dec_0 = AKSPreviewManagedClusterUpdateDecorator(
1374313866
self.cmd,

0 commit comments

Comments
 (0)