From ec527427b44c4d368962627f6c3ad5a7d1620cc5 Mon Sep 17 00:00:00 2001 From: Anson Qian Date: Mon, 22 Jun 2026 12:32:03 -0400 Subject: [PATCH 1/2] fix aks-flex-config release schema compatibility --- docs/usages/aks-flex-config.md | 2 + scripts/aks-flex-config | 3 ++ scripts/aks_flex_config_test.py | 69 +++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 scripts/aks_flex_config_test.py diff --git a/docs/usages/aks-flex-config.md b/docs/usages/aks-flex-config.md index 532842d1..cb7c18f1 100644 --- a/docs/usages/aks-flex-config.md +++ b/docs/usages/aks-flex-config.md @@ -73,6 +73,8 @@ The helper writes `azure.resourceManagerEndpoint` with the public ARM endpoint a Bootstrap-token mode creates a Kubernetes bootstrap token `Secret`, reads the AKS API server and CA data from kubeconfig, and includes those values plus the AKS DNS service IP in the generated config. +The generated config includes legacy field aliases (`kubernetes.version`, `node.kubelet.serverURL`, and `node.kubelet.dnsServiceIP`) so configs produced from `main` remain usable with the latest released `aks-flex-node` binary while the release catches up to the current config schema. + ### Managed Identity ```bash diff --git a/scripts/aks-flex-config b/scripts/aks-flex-config index fe7491d6..c383c2d7 100755 --- a/scripts/aks-flex-config +++ b/scripts/aks-flex-config @@ -174,6 +174,7 @@ def render_config(args: argparse.Namespace, mode: str, metadata: dict[str, str]) "azure": azure, "agent": {"logLevel": "info", "logDir": "/var/log/aks-flex-node"}, "components": {"kubernetes": metadata["kubernetes_version"]}, + "kubernetes": {"version": metadata["kubernetes_version"]}, } if mode == "bootstrap-token": @@ -200,10 +201,12 @@ def render_config(args: argparse.Namespace, mode: str, metadata: dict[str, str]) azure["arc"] = {"enabled": False} kubelet_config = { "clusterFQDN": cluster_fqdn_from_server_url(server_url), + "serverURL": server_url, "caCertData": ca_cert_data, } if metadata["dns_service_ip"]: config["networking"] = {"dnsServiceIP": metadata["dns_service_ip"]} + kubelet_config["dnsServiceIP"] = metadata["dns_service_ip"] config["node"] = {"kubelet": kubelet_config} elif mode == "identity": managed_identity = {} diff --git a/scripts/aks_flex_config_test.py b/scripts/aks_flex_config_test.py new file mode 100644 index 00000000..26ffd3e6 --- /dev/null +++ b/scripts/aks_flex_config_test.py @@ -0,0 +1,69 @@ +import importlib.machinery +import importlib.util +import types +import unittest +from pathlib import Path +from unittest import mock + + +SCRIPT_PATH = Path(__file__).with_name("aks-flex-config") + + +def load_helper(): + loader = importlib.machinery.SourceFileLoader("aks_flex_config", str(SCRIPT_PATH)) + spec = importlib.util.spec_from_loader(loader.name, loader) + module = importlib.util.module_from_spec(spec) + loader.exec_module(module) + return module + + +class RenderConfigTest(unittest.TestCase): + def setUp(self): + self.helper = load_helper() + self.metadata = { + "subscription_id": "00000000-0000-0000-0000-000000000000", + "tenant_id": "11111111-1111-1111-1111-111111111111", + "resource_id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg/providers/Microsoft.ContainerService/managedClusters/aks", + "location": "eastus", + "kubernetes_version": "1.35.5", + "dns_service_ip": "10.42.0.10", + "agent_pool_name": "aksflexnodes", + } + + def test_identity_config_includes_legacy_kubernetes_version_alias(self): + args = types.SimpleNamespace(username="") + + config = self.helper.render_config(args, "identity", self.metadata) + + self.assertEqual(config["components"]["kubernetes"], "1.35.5") + self.assertEqual(config["kubernetes"]["version"], "1.35.5") + + def test_bootstrap_config_includes_current_and_legacy_kubelet_fields(self): + args = types.SimpleNamespace() + server_url = "https://test-cluster-abc123.hcp.eastus.azmk8s.io:443" + + def fake_run(command, *, input_text=None, capture=False): + del input_text, capture + if command[-1] == "jsonpath={.clusters[0].cluster.server}": + return server_url + if command[-1] == "jsonpath={.clusters[0].cluster.certificate-authority-data}": + return "base64-ca-data" + raise AssertionError(f"unexpected command: {command}") + + with mock.patch.object(self.helper, "load_admin_kubeconfig"), mock.patch.object( + self.helper, "generate_bootstrap_token", return_value="abcdef.0123456789abcdef" + ), mock.patch.object(self.helper, "run", side_effect=fake_run): + config = self.helper.render_config(args, "bootstrap-token", self.metadata) + + kubelet = config["node"]["kubelet"] + self.assertEqual(config["components"]["kubernetes"], "1.35.5") + self.assertEqual(config["kubernetes"]["version"], "1.35.5") + self.assertEqual(config["networking"]["dnsServiceIP"], "10.42.0.10") + self.assertEqual(kubelet["clusterFQDN"], "test-cluster-abc123.hcp.eastus.azmk8s.io:443") + self.assertEqual(kubelet["serverURL"], server_url) + self.assertEqual(kubelet["dnsServiceIP"], "10.42.0.10") + self.assertEqual(kubelet["caCertData"], "base64-ca-data") + + +if __name__ == "__main__": + unittest.main() From 6e4472db70ecef992b84d963288eb83435f15b4d Mon Sep 17 00:00:00 2001 From: Anson Qian Date: Mon, 22 Jun 2026 12:34:19 -0400 Subject: [PATCH 2/2] remove notes --- docs/usages/aks-flex-config.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/usages/aks-flex-config.md b/docs/usages/aks-flex-config.md index cb7c18f1..532842d1 100644 --- a/docs/usages/aks-flex-config.md +++ b/docs/usages/aks-flex-config.md @@ -73,8 +73,6 @@ The helper writes `azure.resourceManagerEndpoint` with the public ARM endpoint a Bootstrap-token mode creates a Kubernetes bootstrap token `Secret`, reads the AKS API server and CA data from kubeconfig, and includes those values plus the AKS DNS service IP in the generated config. -The generated config includes legacy field aliases (`kubernetes.version`, `node.kubelet.serverURL`, and `node.kubelet.dnsServiceIP`) so configs produced from `main` remain usable with the latest released `aks-flex-node` binary while the release catches up to the current config schema. - ### Managed Identity ```bash