Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
27e6843
first draft
Jun 20, 2025
5c706c2
fixed error
Jun 20, 2025
793d69e
lines too long fix
Jun 20, 2025
49af9a4
linting fixes
Jun 20, 2025
33fbffa
release history
Jun 20, 2025
d6c5548
logic fixes
Jun 20, 2025
cc19cbe
pr feedback
Jun 20, 2025
8abdc40
PR comments
Jun 24, 2025
0abae14
linting fixes
Jun 24, 2025
b29f6e6
fixed the linting issue
Jun 25, 2025
bbae6cb
fixes for PR comments
Jun 25, 2025
6fe79dc
minor changes
Jun 25, 2025
087ebce
adding tests and minor fixes
Jun 26, 2025
3dd272f
Update src/aks-preview/azext_aks_preview/tests/latest/test_aks_comman…
anushkasingh16 Jun 26, 2025
e67b2ac
linting + sytax error
Jun 26, 2025
099c683
Merge branch 'anushkasingh/local-dns-cli-extension' of https://github…
Jun 26, 2025
de8a20c
style fixes
Jun 26, 2025
6115a07
linting
Jun 26, 2025
1061995
passing the file name
Jun 26, 2025
1240e1b
header placement fix
Jun 26, 2025
89f9b32
version should be higher than 1.33
Jun 26, 2025
41e28fa
testing fixes
Jun 26, 2025
54e106a
version
Jun 27, 2025
8621d74
json parsing:
Jun 27, 2025
3b52ffb
spacing fix
Jun 27, 2025
8a19986
json parsing
Jun 27, 2025
b61e90a
parsing
Jun 27, 2025
483ecb3
json parsing fixes
Jun 27, 2025
b988309
test changes
Jun 27, 2025
80b8bb4
test data matching
Jun 27, 2025
e4a026c
testing data
Jun 27, 2025
2e2f161
test logic changes
Jun 27, 2025
a73f8b7
Changed serveStale to immediate for ForceTCP
Jun 27, 2025
947a4e0
Merge branch 'main' into anushkasingh/local-dns-cli-extension
Jul 10, 2025
d35c002
history file fix
Jul 10, 2025
e2b87d8
profile name fixes
Jul 10, 2025
8caf2db
Revert "profile name fixes"
Jul 10, 2025
0bbb49e
parsing fix
Jul 11, 2025
dd8ccd1
syntax
Jul 11, 2025
a0ab576
seralization attempt
Jul 11, 2025
cf1b36d
added logging for testing
Jul 11, 2025
62f4742
model initalization fix
Jul 14, 2025
77adc7f
more pasrsing changes +printing
Jul 14, 2025
2393e59
more parsing
Jul 15, 2025
8161ddd
reattempted
Jul 15, 2025
582935c
Revert "reattempted"
Jul 15, 2025
30b12b7
parsing for update localdns profile
Jul 15, 2025
a2e0f91
syntax fix
Jul 15, 2025
6189a28
update function
Jul 15, 2025
72751ff
moved common logic to _apply_localdns_profile
Jul 15, 2025
65db120
Revert "moved common logic to _apply_localdns_profile"
Jul 15, 2025
e7428a9
duplicated parsing
Jul 15, 2025
e6aab99
Merge branch 'main' into anushkasingh/local-dns-cli-extension
Jul 16, 2025
ea29a7f
removed print statements
Jul 16, 2025
197055e
style fixes
Jul 16, 2025
ad45bfc
recordings latest
Jul 16, 2025
4038391
adding mocks for localdns update command
Jul 17, 2025
86ad9f7
Merge branch 'main' into anushkasingh/local-dns-cli-extension
Jul 17, 2025
6747889
PR comments
Jul 17, 2025
a21d7ea
Update src/aks-preview/HISTORY.rst
anushkasingh16 Jul 18, 2025
a7b4c13
Update src/aks-preview/HISTORY.rst
anushkasingh16 Jul 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/aks-preview/azext_aks_preview/_consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,3 +372,8 @@
CONST_K8S_EXTENSION_NAME = "k8s-extension"
CONST_K8S_EXTENSION_ACTION_MOD_NAME = "azext_k8s_extension.action"
CONST_K8S_EXTENSION_FORMAT_MOD_NAME = "azext_k8s_extension._format"

# Local DNS profile modes
CONST_LOCAL_DNS_MODE_REQUIRED = "required"
CONST_LOCAL_DNS_MODE_PREFERRED = "preferred"
CONST_LOCAL_DNS_MODE_DISABLED = "disabled"
26 changes: 26 additions & 0 deletions src/aks-preview/azext_aks_preview/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@
CONST_GPU_INSTANCE_PROFILE_MIG7_G,
CONST_LOAD_BALANCER_SKU_BASIC,
CONST_LOAD_BALANCER_SKU_STANDARD,
CONST_LOCAL_DNS_MODE_REQUIRED,
CONST_LOCAL_DNS_MODE_PREFERRED,
CONST_LOCAL_DNS_MODE_DISABLED,
CONST_MANAGED_CLUSTER_SKU_TIER_FREE,
CONST_MANAGED_CLUSTER_SKU_TIER_STANDARD,
CONST_MANAGED_CLUSTER_SKU_TIER_PREMIUM,
Expand Down Expand Up @@ -1823,6 +1826,29 @@ def load_arguments(self, _):
arg_type=get_enum_type(node_os_skus_update),
validator=validate_os_sku,
)
# local dns
c.argument(
"set_localdns",
options_list=["--set-localdns"],
action="store_true",
help="Enable or update the local DNS profile for this nodepool. Must be used with --localdns-mode or --localdns-config."
)
c.argument(
"localdns_config",
options_list=["--localdns-config"],
type=file_type,
help="Path to a JSON file with the local DNS profile configuration. Must be used with --set-localdns."
)
c.argument(
"localdns_mode",
options_list=["--localdns-mode"],
arg_type=get_enum_type([
CONST_LOCAL_DNS_MODE_REQUIRED,
CONST_LOCAL_DNS_MODE_PREFERRED,
CONST_LOCAL_DNS_MODE_DISABLED
]),
help="The mode for the local DNS profile. Must be used with --set-localdns."
)
# In update scenario, use emtpy str as default.
c.argument('ssh_access', arg_type=get_enum_type(ssh_accesses), is_preview=True)
c.argument('yes', options_list=['--yes', '-y'], help='Do not prompt for confirmation.', action='store_true')
Expand Down
51 changes: 51 additions & 0 deletions src/aks-preview/azext_aks_preview/agentpool_decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,12 @@
CONST_DEFAULT_WINDOWS_VMS_VM_SIZE,
CONST_SSH_ACCESS_LOCALUSER,
CONST_GPU_DRIVER_NONE,
CONST_LOCAL_DNS_MODE_REQUIRED,
CONST_LOCAL_DNS_MODE_PREFERRED,
CONST_LOCAL_DNS_MODE_DISABLED,
)
import json

from azext_aks_preview._helpers import (
get_nodepool_snapshot_by_snapshot_id,
filter_hard_taints,
Expand Down Expand Up @@ -808,6 +813,49 @@ def get_disable_fips_image(self) -> bool:
# read the original value passed by the command
return self.raw_param.get("disable_fips_image")

def get_set_localdns(self) -> bool:
return self.raw_param.get("set_localdns", False)

def get_localdns_config(self):
return self.raw_param.get("localdns_config")

def get_localdns_mode(self):
return self.raw_param.get("localdns_mode")

def get_localdns_profile(self):
"""
Returns the local DNS profile dict if set, or None.
Handles validation and file loading.
"""
set_localdns = self.get_set_localdns()
config = self.get_localdns_config()
mode = self.get_localdns_mode()
if not set_localdns and (config or mode):
raise InvalidArgumentValueError("--set-localdns must be specified when using --localdns-config or --localdns-mode.")
if set_localdns:
if not (config or mode):
raise InvalidArgumentValueError("--set-localdns requires either --localdns-config or --localdns-mode.")
if config and mode:
raise MutuallyExclusiveArgumentError("Cannot specify both --localdns-config and --localdns-mode.")
if config:
# Load and validate JSON file
try:
if isinstance(config, str):
with open(config, "r") as f:
profile = json.load(f)
else:
# If already file-like (from CLI file_type)
profile = json.load(config)
except Exception as ex:
raise InvalidArgumentValueError(f"Failed to load local DNS config file: {ex}")
return profile
if mode:
if mode not in [CONST_LOCAL_DNS_MODE_REQUIRED, CONST_LOCAL_DNS_MODE_PREFERRED, CONST_LOCAL_DNS_MODE_DISABLED]:
raise InvalidArgumentValueError(f"Invalid local DNS mode: {mode}")
# Return a minimal profile dict with just the mode
return {"mode": mode}
return None


class AKSPreviewAgentPoolAddDecorator(AKSAgentPoolAddDecorator):
def __init__(
Expand Down Expand Up @@ -1342,6 +1390,9 @@ def update_agentpool_profile_preview(self, agentpools: List[AgentPool] = None) -
# update ssh access
agentpool = self.update_ssh_access(agentpool)

# update locald DNS profile
localdns_profile = self.context.get_localdns_profile()

return agentpool

def update_upgrade_settings(self, agentpool: AgentPool) -> AgentPool:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
import unittest
from unittest.mock import Mock
from azext_aks_preview.agentpool_decorator import AKSPreviewAgentPoolContext, AKSPreviewAgentPoolModels, AKSPreviewAgentPoolUpdateDecorator
from azure.cli.command_modules.acs.agentpool_decorator import AKSAgentPoolParamDict
from azure.cli.command_modules.acs._consts import AgentPoolDecoratorMode, DecoratorMode
from azure.cli.core.azclierror import InvalidArgumentValueError, MutuallyExclusiveArgumentError
from types import SimpleNamespace
import tempfile
import json

class TestLocalDNSProfile(unittest.TestCase):
def setUp(self):
self.cmd = Mock()
self.models = Mock()
self.models.AgentPoolLocalDNSProfile = lambda **kwargs: SimpleNamespace(**kwargs)
self.agentpool_decorator_mode = AgentPoolDecoratorMode.STANDALONE

def test_localdns_mode(self):
ctx = AKSPreviewAgentPoolContext(
self.cmd,
AKSAgentPoolParamDict({
"set_localdns": True,
"localdns_mode": "preferred",
"localdns_config": None
}),
self.models,
DecoratorMode.UPDATE,
self.agentpool_decorator_mode,
)
profile = ctx.get_localdns_profile()
self.assertEqual(profile, {"mode": "preferred"})

def test_localdns_config(self):
config = {"mode": "required", "custom": "foo"}
with tempfile.NamedTemporaryFile(mode="w+", delete=False) as f:
json.dump(config, f)
f.flush()
ctx = AKSPreviewAgentPoolContext(
self.cmd,
AKSAgentPoolParamDict({
"set_localdns": True,
"localdns_mode": None,
"localdns_config": f.name
}),
self.models,
DecoratorMode.UPDATE,
self.agentpool_decorator_mode,
)
profile = ctx.get_localdns_profile()
self.assertEqual(profile, config)

def test_localdns_validation(self):
# Missing --set-localdns
ctx = AKSPreviewAgentPoolContext(
self.cmd,
AKSAgentPoolParamDict({
"set_localdns": False,
"localdns_mode": "preferred",
"localdns_config": None
}),
self.models,
DecoratorMode.UPDATE,
self.agentpool_decorator_mode,
)
with self.assertRaises(InvalidArgumentValueError):
ctx.get_localdns_profile()
# Both config and mode
ctx = AKSPreviewAgentPoolContext(
self.cmd,
AKSAgentPoolParamDict({
"set_localdns": True,
"localdns_mode": "preferred",
"localdns_config": "foo.json"
}),
self.models,
DecoratorMode.UPDATE,
self.agentpool_decorator_mode,
)
with self.assertRaises(MutuallyExclusiveArgumentError):
ctx.get_localdns_profile()
# Neither config nor mode
ctx = AKSPreviewAgentPoolContext(
self.cmd,
AKSAgentPoolParamDict({
"set_localdns": True,
"localdns_mode": None,
"localdns_config": None
}),
self.models,
DecoratorMode.UPDATE,
self.agentpool_decorator_mode,
)
with self.assertRaises(InvalidArgumentValueError):
ctx.get_localdns_profile()

if __name__ == "__main__":
unittest.main()
Loading