Repository: Azure/AgentBaker
Pull request #6164: Add types and tests for localdns
Author: login: SriHarsha001
Created: 2025-04-08T04:16:46Z | Merged: 2025-04-09T01:52:12Z

**What type of PR is this?**
feature

**What this PR does / why we need it**:
This PR has types and tests for the new feature 'localdns'. 

**Which issue(s) this PR fixes**:
<!-- 
*Automatically closes linked issue when PR is merged.
Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
_If PR is about `failing-tests or flakes`, please post the related issues/tests in a comment and do not use `Fixes`_*
-->
Fixes #

**Requirements**:

- [x] uses [conventional commit messages](https://www.conventionalcommits.org/)
  <!-- Common commit types:
        build: Build 🏭
        chore: Maintenance 🔧
        ci: Continuous Integration 💜
        docs: Documentation 📘
        feat: Features 🌈
        fix: Bug Fixes 🐞
        perf: Performance Improvements 🚀
        refactor: Code Refactoring 💎
        revert: Revert Change ◀️
        style: Code Style 🎶
        security: Security Fix 🛡️
        test: Testing 💚 -->
- [ ] includes documentation
- [x] adds unit tests
- [ ] tested upgrade from previous version

**Special notes for your reviewer**:

**Release note**:

```
none
```



Diff:
diff --git a/pkg/agent/datamodel/types.go b/pkg/agent/datamodel/types.go
index 4f70d1b058f..dfa7450bb99 100644
--- a/pkg/agent/datamodel/types.go
+++ b/pkg/agent/datamodel/types.go
@@ -830,6 +830,7 @@ type AgentPoolProfile struct {
 	CustomKubeletConfig   *CustomKubeletConfig `json:"customKubeletConfig,omitempty"`
 	CustomLinuxOSConfig   *CustomLinuxOSConfig `json:"customLinuxOSConfig,omitempty"`
 	MessageOfTheDay       string               `json:"messageOfTheDay,omitempty"`
+	LocalDNSProfile       *LocalDNSProfile     `json:"localDNSProfile,omitempty"`
 	/* This is a new property and all old agent pools do no have this field. We need to keep the default
 	behavior to reboot Windows node when it is nil. */
 	NotRebootWindowsNode    *bool                    `json:"notRebootWindowsNode,omitempty"`
@@ -2316,3 +2317,116 @@ func (s *SecurityProfile) GetPrivateEgressContainerRegistryServer() string {
 }
 
 // SecurityProfile end.
+
+// ----------------------- Start of changes related to localdns ------------------------------------------.
+// localdns related constants.
+const (
+	// LocalDNSNodeListenerIP sepcifies nodelistener APIPA-IP used in localdns.
+	LocalDNSNodeListenerIP string = "169.254.10.10"
+	// LocalDNSClusterListenerIP sepcifies clusterlistener APIPA-IP used in localdns.
+	LocalDNSClusterListenerIP string = "169.254.10.11"
+	// DefaultLocalDNSServiceIP sepcifies the default coredns service IP.
+	DefaultCoreDNSServiceIP string = "10.0.0.10"
+	// AzureDNSIP is the default Azure DNS IP used in localdns.
+	AzureDNSIP string = "168.63.129.16"
+	// DefaultLocalDNSCPULimitInPercentage sepcifies the default CPU limit used in akslocaldns.
+	DefaultLocalDNSCPULimitInPercentage string = "200.0%"
+	// DefaultLocalDNSMemoryLimitInMB sepcifies the default Memory limit used in akslocaldns.
+	DefaultLocalDNSMemoryLimitInMB string = "128M"
+)
+
+// LocalDNSProfile represents localdns configuration for agentpool nodes.
+type LocalDNSProfile struct {
+	EnableLocalDNS       bool                          `json:"enableLocalDNS,omitempty"`
+	CPULimitInMilliCores *int32                        `json:"cpuLimitInMilliCores,omitempty"`
+	MemoryLimitInMB      *int32                        `json:"memoryLimitInMB,omitempty"`
+	VnetDNSOverrides     map[string]*LocalDNSOverrides `json:"vnetDNSOverrides,omitempty"`
+	KubeDNSOverrides     map[string]*LocalDNSOverrides `json:"kubeDNSOverrides,omitempty"`
+}
+
+type LocalDNSCoreFileData struct {
+	LocalDNSProfile
+	NodeListenerIP    string
+	ClusterListenerIP string
+	CoreDNSServiceIP  string
+	AzureDNSIP        string
+}
+
+// LocalDNSOverrides represents DNS override settings for both VnetDNS and KubeDNS traffic.
+// VnetDNS overrides apply to DNS traffic from pods with dnsPolicy:default or kubelet (referred to as VnetDNS traffic).
+// KubeDNS overrides apply to DNS traffic from pods with dnsPolicy:ClusterFirst (referred to as KubeDNS traffic).
+type LocalDNSOverrides struct {
+	QueryLogging                string `json:"queryLogging,omitempty"`
+	Protocol                    string `json:"protocol,omitempty"`
+	ForwardDestination          string `json:"forwardDestination,omitempty"`
+	ForwardPolicy               string `json:"forwardPolicy,omitempty"`
+	MaxConcurrent               *int32 `json:"maxConcurrent,omitempty"`
+	CacheDurationInSeconds      *int32 `json:"cacheDurationInSeconds,omitempty"`
+	ServeStaleDurationInSeconds *int32 `json:"serveStaleDurationInSeconds,omitempty"`
+	ServeStale                  string `json:"serveStale,omitempty"`
+}
+
+// ShouldEnableLocalDNS returns true if AgentPoolProfile, LocalDNSProfile is not nil and
+// EnableLocaDNS for the Agentpool is true. EnableLocaDNS boolean value is sent by AKS RP.
+// This will tell if localdns should be enabled for the agent pool or not.
+// If this function returns true only then we generate localdns systemd unit and corefile.
+func (a *AgentPoolProfile) ShouldEnableLocalDNS() bool {
+	return a != nil && a.LocalDNSProfile != nil && a.LocalDNSProfile.EnableLocalDNS
+}
+
+// GetLocalDNSNodeListenerIP returns APIPA-IP address that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSNodeListenerIP() string {
+	return LocalDNSNodeListenerIP
+}
+
+// GetLocalDNSClusterListenerIP returns APIPA-IP address that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSClusterListenerIP() string {
+	return LocalDNSClusterListenerIP
+}
+
+// GetAzureDNSIP returns 168.63.129.16 address.
+func (a *AgentPoolProfile) GetAzureDNSIP() string {
+	return AzureDNSIP
+}
+
+// GetLocalDNSCPULimitInPercentage returns CPU limit in percentage unit that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSCPULimitInPercentage() string {
+	if a.LocalDNSProfile.CPULimitInMilliCores != nil {
+		// Convert milli-cores to percentage and return as formatted string.
+		return fmt.Sprintf("%.1f%%", float64(*a.LocalDNSProfile.CPULimitInMilliCores)/10.0)
+	}
+	return DefaultLocalDNSCPULimitInPercentage
+}
+
+// GetLocalDNSMemoryLimitInMB returns memory limit in MB that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSMemoryLimitInMB() string {
+	if a.LocalDNSProfile.MemoryLimitInMB != nil {
+		// Return memory limit as a string with "M" suffix.
+		return fmt.Sprintf("%dM", *a.LocalDNSProfile.MemoryLimitInMB)
+	}
+	return DefaultLocalDNSMemoryLimitInMB
+}
+
+func (a *AgentPoolProfile) GetCoreDNSServiceIP() string {
+	if a.KubernetesConfig != nil && a.KubernetesConfig.DNSServiceIP != "" {
+		return a.KubernetesConfig.DNSServiceIP
+	}
+	return DefaultCoreDNSServiceIP
+}
+
+// GetLocalDNSCoreFileData returns the object that will be used to generate localdns corefile.
+func (a *AgentPoolProfile) GetLocalDNSCoreFileData() LocalDNSCoreFileData {
+	if a.ShouldEnableLocalDNS() {
+		localDNSCoreFileData := LocalDNSCoreFileData{
+			LocalDNSProfile:   *a.LocalDNSProfile,
+			NodeListenerIP:    a.GetLocalDNSNodeListenerIP(),
+			ClusterListenerIP: a.GetLocalDNSClusterListenerIP(),
+			CoreDNSServiceIP:  a.GetCoreDNSServiceIP(),
+			AzureDNSIP:        a.GetAzureDNSIP(),
+		}
+		return localDNSCoreFileData
+	}
+	return LocalDNSCoreFileData{}
+}
+
+// ----------------------- End of changes related to localdns ------------------------------------------.
diff --git a/pkg/agent/datamodel/types_test.go b/pkg/agent/datamodel/types_test.go
index 7d213b3dfba..90338ef0362 100644
--- a/pkg/agent/datamodel/types_test.go
+++ b/pkg/agent/datamodel/types_test.go
@@ -2811,3 +2811,329 @@ func TestSecurityProfileGetPrivateEgressContainerRegistryServer(t *testing.T) {
 		})
 	}
 }
+
+// ----------------------- Start of changes related to localdns ------------------------------------------.
+func TestShouldEnableLocalDNS(t *testing.T) {
+	tests := []struct {
+		name             string
+		agentPoolProfile *AgentPoolProfile
+		expectedData     bool
+	}{
+		{
+			name:             "ShouldEnableLocalDNS - AgentPoolProfile nil",
+			agentPoolProfile: nil,
+			expectedData:     false,
+		},
+		{
+			name: "ShouldEnableLocalDNS - LocalDNSProfile nil",
+			agentPoolProfile: &AgentPoolProfile{
+				LocalDNSProfile: nil,
+			},
+			expectedData: false,
+		},
+		{
+			name: "ShouldEnableLocalDNS - LocalDNSProfile disabled",
+			agentPoolProfile: &AgentPoolProfile{
+				LocalDNSProfile: &LocalDNSProfile{
+					EnableLocalDNS: false,
+				},
+			},
+			expectedData: false,
+		},
+		{
+			name: "ShouldEnableLocalDNS - LocalDNSProfile enabled",
+			agentPoolProfile: &AgentPoolProfile{
+				LocalDNSProfile: &LocalDNSProfile{
+					EnableLocalDNS: true,
+				},
+			},
+			expectedData: true,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			actualData := false
+			if tt.agentPoolProfile != nil {
+				actualData = tt.agentPoolProfile.ShouldEnableLocalDNS()
+			}
+			assert.Equal(t, tt.expectedData, actualData)
+		})
+	}
+}
+
+func TestLocalDNSProfileMethods(t *testing.T) {
+	tests := []struct {
+		name             string
+		agentPoolProfile *AgentPoolProfile
+		expectedData     interface{}
+		expectedError    bool
+	}{
+		{
+			name: "GetLocalDNSNodeListenerIP",
+			agentPoolProfile: &AgentPoolProfile{
+				LocalDNSProfile: &LocalDNSProfile{},
+			},
+			expectedData: LocalDNSNodeListenerIP,
+		},
+		{
+			name: "GetLocalDNSClusterListenerIP",
+			agentPoolProfile: &AgentPoolProfile{
+				LocalDNSProfile: &LocalDNSProfile{},
+			},
+			expectedData: LocalDNSClusterListenerIP,
+		},
+		{
+			name: "GetAzureDNSIP",
+			agentPoolProfile: &AgentPoolProfile{
+				LocalDNSProfile: &LocalDNSProfile{},
+			},
+			expectedData: AzureDNSIP,
+		},
+		{
+			name: "GetLocalDNSCPULimitInPercentage - CPU limit nil",
+			agentPoolProfile: &AgentPoolProfile{
+				LocalDNSProfile: &LocalDNSProfile{},
+			},
+			expectedData: DefaultLocalDNSCPULimitInPercentage,
+		},
+		{
+			name: "GetLocalDNSCPULimitInPercentage - CPU limit set",
+			agentPoolProfile: &AgentPoolProfile{
+				LocalDNSProfile: &LocalDNSProfile{
+					CPULimitInMilliCores: to.Int32Ptr(1000),
+				},
+			},
+			expectedData: "100.0%",
+		},
+		{
+			name: "GetLocalDNSMemoryLimitInMB - Memory limit nil",
+			agentPoolProfile: &AgentPoolProfile{
+				LocalDNSProfile: &LocalDNSProfile{},
+			},
+			expectedData: DefaultLocalDNSMemoryLimitInMB,
+		},
+		{
+			name: "GetLocalDNSMemoryLimitInMB - Memory limit set",
+			agentPoolProfile: &AgentPoolProfile{
+				LocalDNSProfile: &LocalDNSProfile{
+					MemoryLimitInMB: to.Int32Ptr(4096),
+				},
+			},
+			expectedData: "4096M",
+		},
+		{
+			name: "GetCoreDNSServiceIP - DNSServiceIP in KubernetesConfig",
+			agentPoolProfile: &AgentPoolProfile{
+				KubernetesConfig: &KubernetesConfig{
+					DNSServiceIP: "10.0.0.53",
+				},
+			},
+			expectedData: "10.0.0.53",
+		},
+		{
+			name: "GetCoreDNSServiceIP - DNSServiceIP not set",
+			agentPoolProfile: &AgentPoolProfile{
+				KubernetesConfig: &KubernetesConfig{},
+			},
+			expectedData: DefaultCoreDNSServiceIP,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			switch tt.name {
+			case "GetCoreDNSServiceIP - DNSServiceIP in KubernetesConfig":
+				assert.Equal(t, tt.expectedData, tt.agentPoolProfile.GetCoreDNSServiceIP())
+			case "GetCoreDNSServiceIP - DNSServiceIP not set":
+				assert.Equal(t, tt.expectedData, tt.agentPoolProfile.GetCoreDNSServiceIP())
+			case "GetLocalDNSNodeListenerIP":
+				assert.Equal(t, tt.expectedData, tt.agentPoolProfile.GetLocalDNSNodeListenerIP())
+			case "GetLocalDNSClusterListenerIP":
+				assert.Equal(t, tt.expectedData, tt.agentPoolProfile.GetLocalDNSClusterListenerIP())
+			case "GetAzureDNSIP":
+				assert.Equal(t, tt.expectedData, tt.agentPoolProfile.GetAzureDNSIP())
+			case "GetLocalDNSCPULimitInPercentage - CPU limit set":
+				assert.Equal(t, tt.expectedData, tt.agentPoolProfile.GetLocalDNSCPULimitInPercentage())
+			case "GetLocalDNSCPULimitInPercentage - CPU limit nil":
+				assert.Equal(t, tt.expectedData, tt.agentPoolProfile.GetLocalDNSCPULimitInPercentage())
+			case "GetLocalDNSMemoryLimitInMB - Memory limit set":
+				assert.Equal(t, tt.expectedData, tt.agentPoolProfile.GetLocalDNSMemoryLimitInMB())
+			case "GetLocalDNSMemoryLimitInMB - Memory limit nil":
+				assert.Equal(t, tt.expectedData, tt.agentPoolProfile.GetLocalDNSMemoryLimitInMB())
+			}
+		})
+	}
+}
+
+func TestGetLocalDNSCoreFileData(t *testing.T) {
+	tests := []struct {
+		name             string
+		agentPoolProfile *AgentPoolProfile
+		expectedData     LocalDNSCoreFileData
+		expectError      bool
+	}{
+		{
+			name:             "AgentPoolProfile nil",
+			agentPoolProfile: nil,
+		},
+		{
+			name: "LocalDNSProfile nil",
+			agentPoolProfile: &AgentPoolProfile{
+				LocalDNSProfile: nil,
+			},
+		},
+		{
+			name: "LocalDNSProfile disabled",
+			agentPoolProfile: &AgentPoolProfile{
+				LocalDNSProfile: &LocalDNSProfile{
+					EnableLocalDNS: false,
+				},
+			},
+		},
+		{
+			name: "LocalDNSProfile disabled but has data",
+			agentPoolProfile: &AgentPoolProfile{
+				LocalDNSProfile: &LocalDNSProfile{
+					EnableLocalDNS:       false,
+					CPULimitInMilliCores: to.Int32Ptr(1000),
+					MemoryLimitInMB:      to.Int32Ptr(1024),
+				},
+			},
+			expectedData: LocalDNSCoreFileData{
+				LocalDNSProfile: LocalDNSProfile{
+					EnableLocalDNS:       false,
+					CPULimitInMilliCores: nil,
+					MemoryLimitInMB:      nil,
+					VnetDNSOverrides:     nil,
+					KubeDNSOverrides:     nil,
+				},
+				NodeListenerIP:    "",
+				ClusterListenerIP: "",
+				CoreDNSServiceIP:  "",
+				AzureDNSIP:        "",
+			},
+		},
+		{
+			name: "LocalDNSProfile enabled",
+			agentPoolProfile: &AgentPoolProfile{
+				LocalDNSProfile: &LocalDNSProfile{
+					EnableLocalDNS:       true,
+					CPULimitInMilliCores: to.Int32Ptr(2000),
+					MemoryLimitInMB:      to.Int32Ptr(4096),
+					VnetDNSOverrides: map[string]*LocalDNSOverrides{
+						".": {
+							QueryLogging:                "Log",
+							Protocol:                    "PreferUDP",
+							ForwardDestination:          "VnetDNS",
+							ForwardPolicy:               "Sequential",
+							MaxConcurrent:               to.Int32Ptr(1000),
+							CacheDurationInSeconds:      to.Int32Ptr(3600),
+							ServeStaleDurationInSeconds: to.Int32Ptr(3600),
+							ServeStale:                  "Verify",
+						},
+						"cluster.local": {
+							QueryLogging:                "Error",
+							Protocol:                    "ForceTCP",
+							ForwardDestination:          "ClusterCoreDNS",
+							ForwardPolicy:               "Sequential",
+							MaxConcurrent:               to.Int32Ptr(1000),
+							CacheDurationInSeconds:      to.Int32Ptr(3600),
+							ServeStaleDurationInSeconds: to.Int32Ptr(3600),
+							ServeStale:                  "Disable",
+						},
+					},
+					KubeDNSOverrides: map[string]*LocalDNSOverrides{
+						".": {
+							QueryLogging:                "Error",
+							Protocol:                    "PreferUDP",
+							ForwardDestination:          "ClusterCoreDNS",
+							ForwardPolicy:               "Sequential",
+							MaxConcurrent:               to.Int32Ptr(1000),
+							CacheDurationInSeconds:      to.Int32Ptr(3600),
+							ServeStaleDurationInSeconds: to.Int32Ptr(3600),
+							ServeStale:                  "Verify",
+						},
+						"cluster.local": {
+							QueryLogging:                "Log",
+							Protocol:                    "ForceTCP",
+							ForwardDestination:          "ClusterCoreDNS",
+							ForwardPolicy:               "RoundRobin",
+							MaxConcurrent:               to.Int32Ptr(1000),
+							CacheDurationInSeconds:      to.Int32Ptr(3600),
+							ServeStaleDurationInSeconds: to.Int32Ptr(3600),
+							ServeStale:                  "Disable",
+						},
+					},
+				},
+			},
+			expectedData: LocalDNSCoreFileData{
+				LocalDNSProfile: LocalDNSProfile{
+					EnableLocalDNS:       true,
+					CPULimitInMilliCores: to.Int32Ptr(2000),
+					MemoryLimitInMB:      to.Int32Ptr(4096),
+					VnetDNSOverrides: map[string]*LocalDNSOverrides{
+						".": {
+							QueryLogging:                "Log",
+							Protocol:                    "PreferUDP",
+							ForwardDestination:          "VnetDNS",
+							ForwardPolicy:               "Sequential",
+							MaxConcurrent:               to.Int32Ptr(1000),
+							CacheDurationInSeconds:      to.Int32Ptr(3600),
+							ServeStaleDurationInSeconds: to.Int32Ptr(3600),
+							ServeStale:                  "Verify",
+						},
+						"cluster.local": {
+							QueryLogging:                "Error",
+							Protocol:                    "ForceTCP",
+							ForwardDestination:          "ClusterCoreDNS",
+							ForwardPolicy:               "Sequential",
+							MaxConcurrent:               to.Int32Ptr(1000),
+							CacheDurationInSeconds:      to.Int32Ptr(3600),
+							ServeStaleDurationInSeconds: to.Int32Ptr(3600),
+							ServeStale:                  "Disable",
+						},
+					},
+					KubeDNSOverrides: map[string]*LocalDNSOverrides{
+						".": {
+							QueryLogging:                "Error",
+							Protocol:                    "PreferUDP",
+							ForwardDestination:          "ClusterCoreDNS",
+							ForwardPolicy:               "Sequential",
+							MaxConcurrent:               to.Int32Ptr(1000),
+							CacheDurationInSeconds:      to.Int32Ptr(3600),
+							ServeStaleDurationInSeconds: to.Int32Ptr(3600),
+							ServeStale:                  "Verify",
+						},
+						"cluster.local": {
+							QueryLogging:                "Log",
+							Protocol:                    "ForceTCP",
+							ForwardDestination:          "ClusterCoreDNS",
+							ForwardPolicy:               "RoundRobin",
+							MaxConcurrent:               to.Int32Ptr(1000),
+							CacheDurationInSeconds:      to.Int32Ptr(3600),
+							ServeStaleDurationInSeconds: to.Int32Ptr(3600),
+							ServeStale:                  "Disable",
+						},
+					},
+				},
+				NodeListenerIP:    LocalDNSNodeListenerIP,
+				ClusterListenerIP: LocalDNSClusterListenerIP,
+				CoreDNSServiceIP:  DefaultCoreDNSServiceIP,
+				AzureDNSIP:        AzureDNSIP,
+			},
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			var actualData LocalDNSCoreFileData
+			if tt.agentPoolProfile != nil {
+				actualData = tt.agentPoolProfile.GetLocalDNSCoreFileData()
+			}
+			assert.Equal(t, tt.expectedData, actualData)
+		})
+	}
+}
+
+// ----------------------- End of changes related to localdns ------------------------------------------.


Reviews:
user: login: Devinwong
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-08T18:59:17Z
user: login: Devinwong
body: approve with a suggestion
state: DISMISSED
author_association: COLLABORATOR
submitted_at: 2025-04-08T19:00:13Z
user: login: SriHarsha001
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-08T19:09:53Z
user: login: Devinwong
state: DISMISSED
author_association: COLLABORATOR
submitted_at: 2025-04-08T19:11:31Z
user: login: yewmsft
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-08T22:24:25Z
user: login: yewmsft
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-08T22:25:31Z
user: login: yewmsft
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-08T22:34:07Z
user: login: cameronmeissner
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-08T22:40:30Z
user: login: SriHarsha001
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-08T22:41:57Z
user: login: SriHarsha001
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-08T22:42:03Z
user: login: yewmsft
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-08T22:46:39Z
user: login: SriHarsha001
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-08T22:50:58Z
user: login: yewmsft
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-08T22:51:18Z
user: login: yewmsft
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-08T23:02:29Z
user: login: yewmsft
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-08T23:03:27Z
user: login: SriHarsha001
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-09T01:18:23Z
user: login: SriHarsha001
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-09T01:19:14Z
user: login: SriHarsha001
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-09T01:21:43Z
user: login: yewmsft
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-09T01:32:30Z
user: login: yewmsft
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-09T01:32:46Z
user: login: yewmsft
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-09T01:37:02Z
user: login: SriHarsha001
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-09T01:44:36Z
user: login: SriHarsha001
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-09T01:44:52Z
user: login: yewmsft
state: APPROVED
author_association: MEMBER
submitted_at: 2025-04-09T01:45:18Z
user: login: anujmaheshwari1
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-09T01:52:01Z

Review comments:
diff_hunk: @@ -2316,3 +2317,116 @@ func (s *SecurityProfile) GetPrivateEgressContainerRegistryServer() string {
 }
 
 // SecurityProfile end.
+
+// ----------------------- Start of Changed related to localdns ------------------------------------------.
+// localdns related constants.
+const (
+	// LocalDNSEnabled is a string constant for 'Enabled'.
+	LocalDNSEnabled string = "Enabled"
+	// LocalDNSNodeListenerIP sepcifies nodelistener APIPA-IP used in localdns.
+	LocalDNSNodeListenerIP string = "169.254.10.10"
+	// LocalDNSClusterListenerIP sepcifies clusterlistener APIPA-IP used in localdns.
+	LocalDNSClusterListenerIP string = "169.254.10.11"
+	// DefaultLocalDNSCPULimitInPercentage sepcifies the default CPU limit used in akslocaldns.
+	DefaultLocalDNSCPULimitInPercentage string = "200.0%"
+	// DefaultLocalDNSMemoryLimitInMB sepcifies the default Memory limit used in akslocaldns.
+	DefaultLocalDNSMemoryLimitInMB string = "128M"
+	// DefaultLocalDNSServiceIP sepcifies the default coredns service IP.
+	DefaultCoreDNSServiceIP string = "10.0.0.10"
+	// AzureDNSIP is the default Azure DNS IP used in localdns.
+	AzureDNSIP string = "168.63.129.16"
+)
+
+// LocalDNSProfile represents localdns configuration for agentpool nodes.
+type LocalDNSProfile struct {
+	State                string                        `json:"state,omitempty"`
+	CPULimitInMilliCores *int32                        `json:"cpuLimitInMilliCores,omitempty"`
+	MemoryLimitInMB      *int32                        `json:"memoryLimitInMB,omitempty"`
+	VnetDNSOverrides     map[string]*LocalDNSOverrides `json:"vnetDNSOverrides,omitempty"`
+	KubeDNSOverrides     map[string]*LocalDNSOverrides `json:"kubeDNSOverrides,omitempty"`
+}
+
+type LocalDNSCoreFileData struct {
+	LocalDNSProfile
+	NodeListenerIP    string
+	ClusterListenerIP string
+	CoreDNSServiceIP  string
+	AzureDNSIP        string
+}
+
+// LocalDNSOverrides represents DNS override settings for both VnetDNS and KubeDNS traffic.
+// VnetDNS overrides apply to DNS traffic from pods with dnsPolicy:default or kubelet (referred to as VnetDNS traffic).
+// KubeDNS overrides apply to DNS traffic from pods with dnsPolicy:ClusterFirst (referred to as KubeDNS traffic).
+type LocalDNSOverrides struct {
+	QueryLogging                string `json:"queryLogging,omitempty"`
+	Protocol                    string `json:"protocol,omitempty"`
+	ForwardDestination          string `json:"forwardDestination,omitempty"`
+	ForwardPolicy               string `json:"forwardPolicy,omitempty"`
+	MaxConcurrent               *int32 `json:"maxConcurrent,omitempty"`
+	CacheDurationInSeconds      *int32 `json:"cacheDurationInSeconds,omitempty"`
+	ServeStaleDurationInSeconds *int32 `json:"serveStaleDurationInSeconds,omitempty"`
+	ServeStale                  string `json:"serveStale,omitempty"`
+}
+
+// ShouldEnableLocalDNS returns true if LocalDNSProfile is not nil and GoalState is 'Enable'.
+func (a *AgentPoolProfile) ShouldEnableLocalDNS() bool {
+	return a != nil && a.LocalDNSProfile != nil &&
+		strings.EqualFold(a.LocalDNSProfile.State, LocalDNSEnabled)
+}
+
+// GetLocalDNSNodeListenerIP returns APIPA-IP address that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSNodeListenerIP() string {
+	return LocalDNSNodeListenerIP
+}
+
+// GetLocalDNSClusterListenerIP returns APIPA-IP address that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSClusterListenerIP() string {
+	return LocalDNSClusterListenerIP
+}
+
+// GetAzureDNSIP returns 168.63.129.16 address.
+func (a *AgentPoolProfile) GetAzureDNSIP() string {
+	return AzureDNSIP
+}
+
+// GetLocalDNSCPULimitInPercentage returns CPU limit in percentage unit that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSCPULimitInPercentage() string {
+	if a.ShouldEnableLocalDNS() && a.LocalDNSProfile.CPULimitInMilliCores != nil {
+		// Convert milli-cores to percentage and return as formatted string
+		return fmt.Sprintf("%.1f%%", float64(*a.LocalDNSProfile.CPULimitInMilliCores)/10.0)
+	}
+	return DefaultLocalDNSCPULimitInPercentage
+}
+
+// GetLocalDNSMemoryLimitInMB returns memory limit in MB that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSMemoryLimitInMB() string {
+	if a.ShouldEnableLocalDNS() && a.LocalDNSProfile.MemoryLimitInMB != nil {
+		// Return memory limit as a string with "M" suffix
+		return fmt.Sprintf("%dM", *a.LocalDNSProfile.MemoryLimitInMB)
+	}
+	return DefaultLocalDNSMemoryLimitInMB
+}
+
+func (a *AgentPoolProfile) GetCoreDNSServiceIP() string {
+	if a.ShouldEnableLocalDNS() && a.KubernetesConfig != nil && a.KubernetesConfig.DNSServiceIP != "" {
+		return a.KubernetesConfig.DNSServiceIP
+	}
+	return DefaultCoreDNSServiceIP
+}
+
+// GetLocalDNSCoreFileData returns the object that will be used to generate localdns corefile.
+func (a *AgentPoolProfile) GetLocalDNSCoreFileData() LocalDNSCoreFileData {
+	if a.ShouldEnableLocalDNS() {
+		localdnsCoreFileData := LocalDNSCoreFileData{
path: pkg/agent/datamodel/types.go
user: login: Devinwong
body: The upper/lower case seems not consistent.
(IMO) If the type is `LocalDNSCoreFileData`, then the variable should be `localDNSCoreFileData` for consistency.
created_at: 2025-04-08T18:59:17Z
author_association: COLLABORATOR
diff_hunk: @@ -2316,3 +2317,116 @@ func (s *SecurityProfile) GetPrivateEgressContainerRegistryServer() string {
 }
 
 // SecurityProfile end.
+
+// ----------------------- Start of Changed related to localdns ------------------------------------------.
+// localdns related constants.
+const (
+	// LocalDNSEnabled is a string constant for 'Enabled'.
+	LocalDNSEnabled string = "Enabled"
+	// LocalDNSNodeListenerIP sepcifies nodelistener APIPA-IP used in localdns.
+	LocalDNSNodeListenerIP string = "169.254.10.10"
+	// LocalDNSClusterListenerIP sepcifies clusterlistener APIPA-IP used in localdns.
+	LocalDNSClusterListenerIP string = "169.254.10.11"
+	// DefaultLocalDNSCPULimitInPercentage sepcifies the default CPU limit used in akslocaldns.
+	DefaultLocalDNSCPULimitInPercentage string = "200.0%"
+	// DefaultLocalDNSMemoryLimitInMB sepcifies the default Memory limit used in akslocaldns.
+	DefaultLocalDNSMemoryLimitInMB string = "128M"
+	// DefaultLocalDNSServiceIP sepcifies the default coredns service IP.
+	DefaultCoreDNSServiceIP string = "10.0.0.10"
+	// AzureDNSIP is the default Azure DNS IP used in localdns.
+	AzureDNSIP string = "168.63.129.16"
+)
+
+// LocalDNSProfile represents localdns configuration for agentpool nodes.
+type LocalDNSProfile struct {
+	State                string                        `json:"state,omitempty"`
+	CPULimitInMilliCores *int32                        `json:"cpuLimitInMilliCores,omitempty"`
+	MemoryLimitInMB      *int32                        `json:"memoryLimitInMB,omitempty"`
+	VnetDNSOverrides     map[string]*LocalDNSOverrides `json:"vnetDNSOverrides,omitempty"`
+	KubeDNSOverrides     map[string]*LocalDNSOverrides `json:"kubeDNSOverrides,omitempty"`
+}
+
+type LocalDNSCoreFileData struct {
+	LocalDNSProfile
+	NodeListenerIP    string
+	ClusterListenerIP string
+	CoreDNSServiceIP  string
+	AzureDNSIP        string
+}
+
+// LocalDNSOverrides represents DNS override settings for both VnetDNS and KubeDNS traffic.
+// VnetDNS overrides apply to DNS traffic from pods with dnsPolicy:default or kubelet (referred to as VnetDNS traffic).
+// KubeDNS overrides apply to DNS traffic from pods with dnsPolicy:ClusterFirst (referred to as KubeDNS traffic).
+type LocalDNSOverrides struct {
+	QueryLogging                string `json:"queryLogging,omitempty"`
+	Protocol                    string `json:"protocol,omitempty"`
+	ForwardDestination          string `json:"forwardDestination,omitempty"`
+	ForwardPolicy               string `json:"forwardPolicy,omitempty"`
+	MaxConcurrent               *int32 `json:"maxConcurrent,omitempty"`
+	CacheDurationInSeconds      *int32 `json:"cacheDurationInSeconds,omitempty"`
+	ServeStaleDurationInSeconds *int32 `json:"serveStaleDurationInSeconds,omitempty"`
+	ServeStale                  string `json:"serveStale,omitempty"`
+}
+
+// ShouldEnableLocalDNS returns true if LocalDNSProfile is not nil and GoalState is 'Enable'.
+func (a *AgentPoolProfile) ShouldEnableLocalDNS() bool {
+	return a != nil && a.LocalDNSProfile != nil &&
+		strings.EqualFold(a.LocalDNSProfile.State, LocalDNSEnabled)
+}
+
+// GetLocalDNSNodeListenerIP returns APIPA-IP address that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSNodeListenerIP() string {
+	return LocalDNSNodeListenerIP
+}
+
+// GetLocalDNSClusterListenerIP returns APIPA-IP address that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSClusterListenerIP() string {
+	return LocalDNSClusterListenerIP
+}
+
+// GetAzureDNSIP returns 168.63.129.16 address.
+func (a *AgentPoolProfile) GetAzureDNSIP() string {
+	return AzureDNSIP
+}
+
+// GetLocalDNSCPULimitInPercentage returns CPU limit in percentage unit that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSCPULimitInPercentage() string {
+	if a.ShouldEnableLocalDNS() && a.LocalDNSProfile.CPULimitInMilliCores != nil {
+		// Convert milli-cores to percentage and return as formatted string
+		return fmt.Sprintf("%.1f%%", float64(*a.LocalDNSProfile.CPULimitInMilliCores)/10.0)
+	}
+	return DefaultLocalDNSCPULimitInPercentage
+}
+
+// GetLocalDNSMemoryLimitInMB returns memory limit in MB that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSMemoryLimitInMB() string {
+	if a.ShouldEnableLocalDNS() && a.LocalDNSProfile.MemoryLimitInMB != nil {
+		// Return memory limit as a string with "M" suffix
+		return fmt.Sprintf("%dM", *a.LocalDNSProfile.MemoryLimitInMB)
+	}
+	return DefaultLocalDNSMemoryLimitInMB
+}
+
+func (a *AgentPoolProfile) GetCoreDNSServiceIP() string {
+	if a.ShouldEnableLocalDNS() && a.KubernetesConfig != nil && a.KubernetesConfig.DNSServiceIP != "" {
+		return a.KubernetesConfig.DNSServiceIP
+	}
+	return DefaultCoreDNSServiceIP
+}
+
+// GetLocalDNSCoreFileData returns the object that will be used to generate localdns corefile.
+func (a *AgentPoolProfile) GetLocalDNSCoreFileData() LocalDNSCoreFileData {
+	if a.ShouldEnableLocalDNS() {
+		localdnsCoreFileData := LocalDNSCoreFileData{
path: pkg/agent/datamodel/types.go
user: login: SriHarsha001
body: Ah good catch. I have made the change. 
created_at: 2025-04-08T19:09:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2316,3 +2317,116 @@ func (s *SecurityProfile) GetPrivateEgressContainerRegistryServer() string {
 }
 
 // SecurityProfile end.
+
+// ----------------------- Start of Changed related to localdns ------------------------------------------.
+// localdns related constants.
+const (
+	// LocalDNSEnabled is a string constant for 'Enabled'.
+	LocalDNSEnabled string = "Enabled"
+	// LocalDNSNodeListenerIP sepcifies nodelistener APIPA-IP used in localdns.
+	LocalDNSNodeListenerIP string = "169.254.10.10"
+	// LocalDNSClusterListenerIP sepcifies clusterlistener APIPA-IP used in localdns.
+	LocalDNSClusterListenerIP string = "169.254.10.11"
+	// DefaultLocalDNSCPULimitInPercentage sepcifies the default CPU limit used in akslocaldns.
+	DefaultLocalDNSCPULimitInPercentage string = "200.0%"
+	// DefaultLocalDNSMemoryLimitInMB sepcifies the default Memory limit used in akslocaldns.
+	DefaultLocalDNSMemoryLimitInMB string = "128M"
+	// DefaultLocalDNSServiceIP sepcifies the default coredns service IP.
+	DefaultCoreDNSServiceIP string = "10.0.0.10"
+	// AzureDNSIP is the default Azure DNS IP used in localdns.
+	AzureDNSIP string = "168.63.129.16"
+)
+
+// LocalDNSProfile represents localdns configuration for agentpool nodes.
+type LocalDNSProfile struct {
+	State                string                        `json:"state,omitempty"`
+	CPULimitInMilliCores *int32                        `json:"cpuLimitInMilliCores,omitempty"`
+	MemoryLimitInMB      *int32                        `json:"memoryLimitInMB,omitempty"`
+	VnetDNSOverrides     map[string]*LocalDNSOverrides `json:"vnetDNSOverrides,omitempty"`
+	KubeDNSOverrides     map[string]*LocalDNSOverrides `json:"kubeDNSOverrides,omitempty"`
+}
+
+type LocalDNSCoreFileData struct {
+	LocalDNSProfile
+	NodeListenerIP    string
+	ClusterListenerIP string
+	CoreDNSServiceIP  string
+	AzureDNSIP        string
+}
+
+// LocalDNSOverrides represents DNS override settings for both VnetDNS and KubeDNS traffic.
+// VnetDNS overrides apply to DNS traffic from pods with dnsPolicy:default or kubelet (referred to as VnetDNS traffic).
+// KubeDNS overrides apply to DNS traffic from pods with dnsPolicy:ClusterFirst (referred to as KubeDNS traffic).
+type LocalDNSOverrides struct {
+	QueryLogging                string `json:"queryLogging,omitempty"`
+	Protocol                    string `json:"protocol,omitempty"`
+	ForwardDestination          string `json:"forwardDestination,omitempty"`
+	ForwardPolicy               string `json:"forwardPolicy,omitempty"`
+	MaxConcurrent               *int32 `json:"maxConcurrent,omitempty"`
+	CacheDurationInSeconds      *int32 `json:"cacheDurationInSeconds,omitempty"`
+	ServeStaleDurationInSeconds *int32 `json:"serveStaleDurationInSeconds,omitempty"`
+	ServeStale                  string `json:"serveStale,omitempty"`
+}
+
+// ShouldEnableLocalDNS returns true if LocalDNSProfile is not nil and GoalState is 'Enable'.
+func (a *AgentPoolProfile) ShouldEnableLocalDNS() bool {
+	return a != nil && a.LocalDNSProfile != nil &&
+		strings.EqualFold(a.LocalDNSProfile.State, LocalDNSEnabled)
path: pkg/agent/datamodel/types.go
user: login: yewmsft
body: This should be mode, right? State should only be set after localdns being enabled or disabled
created_at: 2025-04-08T22:24:24Z
author_association: MEMBER
diff_hunk: @@ -2316,3 +2317,116 @@ func (s *SecurityProfile) GetPrivateEgressContainerRegistryServer() string {
 }
 
 // SecurityProfile end.
+
+// ----------------------- Start of Changed related to localdns ------------------------------------------.
+// localdns related constants.
+const (
+	// LocalDNSEnabled is a string constant for 'Enabled'.
+	LocalDNSEnabled string = "Enabled"
+	// LocalDNSNodeListenerIP sepcifies nodelistener APIPA-IP used in localdns.
+	LocalDNSNodeListenerIP string = "169.254.10.10"
+	// LocalDNSClusterListenerIP sepcifies clusterlistener APIPA-IP used in localdns.
+	LocalDNSClusterListenerIP string = "169.254.10.11"
+	// DefaultLocalDNSCPULimitInPercentage sepcifies the default CPU limit used in akslocaldns.
+	DefaultLocalDNSCPULimitInPercentage string = "200.0%"
+	// DefaultLocalDNSMemoryLimitInMB sepcifies the default Memory limit used in akslocaldns.
+	DefaultLocalDNSMemoryLimitInMB string = "128M"
+	// DefaultLocalDNSServiceIP sepcifies the default coredns service IP.
+	DefaultCoreDNSServiceIP string = "10.0.0.10"
+	// AzureDNSIP is the default Azure DNS IP used in localdns.
+	AzureDNSIP string = "168.63.129.16"
+)
+
+// LocalDNSProfile represents localdns configuration for agentpool nodes.
+type LocalDNSProfile struct {
+	State                string                        `json:"state,omitempty"`
path: pkg/agent/datamodel/types.go
user: login: yewmsft
body: I think we should pass in mode here. Preferred, Required, Disabled
created_at: 2025-04-08T22:25:30Z
author_association: MEMBER
diff_hunk: @@ -2316,3 +2317,116 @@ func (s *SecurityProfile) GetPrivateEgressContainerRegistryServer() string {
 }
 
 // SecurityProfile end.
+
+// ----------------------- Start of Changed related to localdns ------------------------------------------.
+// localdns related constants.
+const (
+	// LocalDNSEnabled is a string constant for 'Enabled'.
+	LocalDNSEnabled string = "Enabled"
+	// LocalDNSNodeListenerIP sepcifies nodelistener APIPA-IP used in localdns.
+	LocalDNSNodeListenerIP string = "169.254.10.10"
+	// LocalDNSClusterListenerIP sepcifies clusterlistener APIPA-IP used in localdns.
+	LocalDNSClusterListenerIP string = "169.254.10.11"
+	// DefaultLocalDNSCPULimitInPercentage sepcifies the default CPU limit used in akslocaldns.
+	DefaultLocalDNSCPULimitInPercentage string = "200.0%"
+	// DefaultLocalDNSMemoryLimitInMB sepcifies the default Memory limit used in akslocaldns.
+	DefaultLocalDNSMemoryLimitInMB string = "128M"
+	// DefaultLocalDNSServiceIP sepcifies the default coredns service IP.
+	DefaultCoreDNSServiceIP string = "10.0.0.10"
+	// AzureDNSIP is the default Azure DNS IP used in localdns.
+	AzureDNSIP string = "168.63.129.16"
+)
+
+// LocalDNSProfile represents localdns configuration for agentpool nodes.
+type LocalDNSProfile struct {
+	State                string                        `json:"state,omitempty"`
+	CPULimitInMilliCores *int32                        `json:"cpuLimitInMilliCores,omitempty"`
+	MemoryLimitInMB      *int32                        `json:"memoryLimitInMB,omitempty"`
+	VnetDNSOverrides     map[string]*LocalDNSOverrides `json:"vnetDNSOverrides,omitempty"`
+	KubeDNSOverrides     map[string]*LocalDNSOverrides `json:"kubeDNSOverrides,omitempty"`
+}
+
+type LocalDNSCoreFileData struct {
+	LocalDNSProfile
+	NodeListenerIP    string
+	ClusterListenerIP string
+	CoreDNSServiceIP  string
+	AzureDNSIP        string
+}
+
+// LocalDNSOverrides represents DNS override settings for both VnetDNS and KubeDNS traffic.
+// VnetDNS overrides apply to DNS traffic from pods with dnsPolicy:default or kubelet (referred to as VnetDNS traffic).
+// KubeDNS overrides apply to DNS traffic from pods with dnsPolicy:ClusterFirst (referred to as KubeDNS traffic).
+type LocalDNSOverrides struct {
+	QueryLogging                string `json:"queryLogging,omitempty"`
+	Protocol                    string `json:"protocol,omitempty"`
+	ForwardDestination          string `json:"forwardDestination,omitempty"`
+	ForwardPolicy               string `json:"forwardPolicy,omitempty"`
+	MaxConcurrent               *int32 `json:"maxConcurrent,omitempty"`
+	CacheDurationInSeconds      *int32 `json:"cacheDurationInSeconds,omitempty"`
+	ServeStaleDurationInSeconds *int32 `json:"serveStaleDurationInSeconds,omitempty"`
+	ServeStale                  string `json:"serveStale,omitempty"`
+}
+
+// ShouldEnableLocalDNS returns true if LocalDNSProfile is not nil and GoalState is 'Enable'.
+func (a *AgentPoolProfile) ShouldEnableLocalDNS() bool {
+	return a != nil && a.LocalDNSProfile != nil &&
+		strings.EqualFold(a.LocalDNSProfile.State, LocalDNSEnabled)
+}
+
+// GetLocalDNSNodeListenerIP returns APIPA-IP address that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSNodeListenerIP() string {
+	return LocalDNSNodeListenerIP
+}
+
+// GetLocalDNSClusterListenerIP returns APIPA-IP address that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSClusterListenerIP() string {
+	return LocalDNSClusterListenerIP
+}
+
+// GetAzureDNSIP returns 168.63.129.16 address.
+func (a *AgentPoolProfile) GetAzureDNSIP() string {
+	return AzureDNSIP
+}
+
+// GetLocalDNSCPULimitInPercentage returns CPU limit in percentage unit that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSCPULimitInPercentage() string {
+	if a.ShouldEnableLocalDNS() && a.LocalDNSProfile.CPULimitInMilliCores != nil {
+		// Convert milli-cores to percentage and return as formatted string
+		return fmt.Sprintf("%.1f%%", float64(*a.LocalDNSProfile.CPULimitInMilliCores)/10.0)
+	}
+	return DefaultLocalDNSCPULimitInPercentage
path: pkg/agent/datamodel/types.go
user: login: yewmsft
body: why returning default value when a.ShouldEnableLocalDNS() is false?
created_at: 2025-04-08T22:34:07Z
author_association: MEMBER
diff_hunk: @@ -2316,3 +2317,116 @@ func (s *SecurityProfile) GetPrivateEgressContainerRegistryServer() string {
 }
 
 // SecurityProfile end.
+
+// ----------------------- Start of Changed related to localdns ------------------------------------------.
path: pkg/agent/datamodel/types.go
user: login: cameronmeissner
body: typo: changes
created_at: 2025-04-08T22:40:30Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2316,3 +2317,116 @@ func (s *SecurityProfile) GetPrivateEgressContainerRegistryServer() string {
 }
 
 // SecurityProfile end.
+
+// ----------------------- Start of Changed related to localdns ------------------------------------------.
+// localdns related constants.
+const (
+	// LocalDNSEnabled is a string constant for 'Enabled'.
+	LocalDNSEnabled string = "Enabled"
+	// LocalDNSNodeListenerIP sepcifies nodelistener APIPA-IP used in localdns.
+	LocalDNSNodeListenerIP string = "169.254.10.10"
+	// LocalDNSClusterListenerIP sepcifies clusterlistener APIPA-IP used in localdns.
+	LocalDNSClusterListenerIP string = "169.254.10.11"
+	// DefaultLocalDNSCPULimitInPercentage sepcifies the default CPU limit used in akslocaldns.
+	DefaultLocalDNSCPULimitInPercentage string = "200.0%"
+	// DefaultLocalDNSMemoryLimitInMB sepcifies the default Memory limit used in akslocaldns.
+	DefaultLocalDNSMemoryLimitInMB string = "128M"
+	// DefaultLocalDNSServiceIP sepcifies the default coredns service IP.
+	DefaultCoreDNSServiceIP string = "10.0.0.10"
+	// AzureDNSIP is the default Azure DNS IP used in localdns.
+	AzureDNSIP string = "168.63.129.16"
+)
+
+// LocalDNSProfile represents localdns configuration for agentpool nodes.
+type LocalDNSProfile struct {
+	State                string                        `json:"state,omitempty"`
+	CPULimitInMilliCores *int32                        `json:"cpuLimitInMilliCores,omitempty"`
+	MemoryLimitInMB      *int32                        `json:"memoryLimitInMB,omitempty"`
+	VnetDNSOverrides     map[string]*LocalDNSOverrides `json:"vnetDNSOverrides,omitempty"`
+	KubeDNSOverrides     map[string]*LocalDNSOverrides `json:"kubeDNSOverrides,omitempty"`
+}
+
+type LocalDNSCoreFileData struct {
+	LocalDNSProfile
+	NodeListenerIP    string
+	ClusterListenerIP string
+	CoreDNSServiceIP  string
+	AzureDNSIP        string
+}
+
+// LocalDNSOverrides represents DNS override settings for both VnetDNS and KubeDNS traffic.
+// VnetDNS overrides apply to DNS traffic from pods with dnsPolicy:default or kubelet (referred to as VnetDNS traffic).
+// KubeDNS overrides apply to DNS traffic from pods with dnsPolicy:ClusterFirst (referred to as KubeDNS traffic).
+type LocalDNSOverrides struct {
+	QueryLogging                string `json:"queryLogging,omitempty"`
+	Protocol                    string `json:"protocol,omitempty"`
+	ForwardDestination          string `json:"forwardDestination,omitempty"`
+	ForwardPolicy               string `json:"forwardPolicy,omitempty"`
+	MaxConcurrent               *int32 `json:"maxConcurrent,omitempty"`
+	CacheDurationInSeconds      *int32 `json:"cacheDurationInSeconds,omitempty"`
+	ServeStaleDurationInSeconds *int32 `json:"serveStaleDurationInSeconds,omitempty"`
+	ServeStale                  string `json:"serveStale,omitempty"`
+}
+
+// ShouldEnableLocalDNS returns true if LocalDNSProfile is not nil and GoalState is 'Enable'.
+func (a *AgentPoolProfile) ShouldEnableLocalDNS() bool {
+	return a != nil && a.LocalDNSProfile != nil &&
+		strings.EqualFold(a.LocalDNSProfile.State, LocalDNSEnabled)
path: pkg/agent/datamodel/types.go
user: login: SriHarsha001
body: Mode is what we get an an input from user. In AKS RP, we will decide if we can enable localdns on the nodepool and set the State to either Enabled or Disabled and send it to AgentBaker via NBC. 
created_at: 2025-04-08T22:41:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2316,3 +2317,116 @@ func (s *SecurityProfile) GetPrivateEgressContainerRegistryServer() string {
 }
 
 // SecurityProfile end.
+
+// ----------------------- Start of Changed related to localdns ------------------------------------------.
+// localdns related constants.
+const (
+	// LocalDNSEnabled is a string constant for 'Enabled'.
+	LocalDNSEnabled string = "Enabled"
+	// LocalDNSNodeListenerIP sepcifies nodelistener APIPA-IP used in localdns.
+	LocalDNSNodeListenerIP string = "169.254.10.10"
+	// LocalDNSClusterListenerIP sepcifies clusterlistener APIPA-IP used in localdns.
+	LocalDNSClusterListenerIP string = "169.254.10.11"
+	// DefaultLocalDNSCPULimitInPercentage sepcifies the default CPU limit used in akslocaldns.
+	DefaultLocalDNSCPULimitInPercentage string = "200.0%"
+	// DefaultLocalDNSMemoryLimitInMB sepcifies the default Memory limit used in akslocaldns.
+	DefaultLocalDNSMemoryLimitInMB string = "128M"
+	// DefaultLocalDNSServiceIP sepcifies the default coredns service IP.
+	DefaultCoreDNSServiceIP string = "10.0.0.10"
+	// AzureDNSIP is the default Azure DNS IP used in localdns.
+	AzureDNSIP string = "168.63.129.16"
+)
+
+// LocalDNSProfile represents localdns configuration for agentpool nodes.
+type LocalDNSProfile struct {
+	State                string                        `json:"state,omitempty"`
path: pkg/agent/datamodel/types.go
user: login: SriHarsha001
body: Mode is what we get an an input from user. In AKS RP, we will decide if we can enable localdns on the nodepool and set the State to either Enabled or Disabled and send it to AgentBaker via NBC. 
created_at: 2025-04-08T22:42:03Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2316,3 +2317,116 @@ func (s *SecurityProfile) GetPrivateEgressContainerRegistryServer() string {
 }
 
 // SecurityProfile end.
+
+// ----------------------- Start of Changed related to localdns ------------------------------------------.
+// localdns related constants.
+const (
+	// LocalDNSEnabled is a string constant for 'Enabled'.
+	LocalDNSEnabled string = "Enabled"
+	// LocalDNSNodeListenerIP sepcifies nodelistener APIPA-IP used in localdns.
+	LocalDNSNodeListenerIP string = "169.254.10.10"
+	// LocalDNSClusterListenerIP sepcifies clusterlistener APIPA-IP used in localdns.
+	LocalDNSClusterListenerIP string = "169.254.10.11"
+	// DefaultLocalDNSCPULimitInPercentage sepcifies the default CPU limit used in akslocaldns.
+	DefaultLocalDNSCPULimitInPercentage string = "200.0%"
+	// DefaultLocalDNSMemoryLimitInMB sepcifies the default Memory limit used in akslocaldns.
+	DefaultLocalDNSMemoryLimitInMB string = "128M"
+	// DefaultLocalDNSServiceIP sepcifies the default coredns service IP.
+	DefaultCoreDNSServiceIP string = "10.0.0.10"
+	// AzureDNSIP is the default Azure DNS IP used in localdns.
+	AzureDNSIP string = "168.63.129.16"
+)
+
+// LocalDNSProfile represents localdns configuration for agentpool nodes.
+type LocalDNSProfile struct {
+	State                string                        `json:"state,omitempty"`
path: pkg/agent/datamodel/types.go
user: login: yewmsft
body: I would use a different name for this. It would be very confusing since there is a property in RP API called state.
created_at: 2025-04-08T22:46:39Z
author_association: MEMBER
diff_hunk: @@ -2316,3 +2317,116 @@ func (s *SecurityProfile) GetPrivateEgressContainerRegistryServer() string {
 }
 
 // SecurityProfile end.
+
+// ----------------------- Start of Changed related to localdns ------------------------------------------.
path: pkg/agent/datamodel/types.go
user: login: SriHarsha001
body: thank you. Fixed the comment. 
created_at: 2025-04-08T22:50:58Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2316,3 +2317,116 @@ func (s *SecurityProfile) GetPrivateEgressContainerRegistryServer() string {
 }
 
 // SecurityProfile end.
+
+// ----------------------- Start of Changed related to localdns ------------------------------------------.
+// localdns related constants.
+const (
+	// LocalDNSEnabled is a string constant for 'Enabled'.
+	LocalDNSEnabled string = "Enabled"
+	// LocalDNSNodeListenerIP sepcifies nodelistener APIPA-IP used in localdns.
+	LocalDNSNodeListenerIP string = "169.254.10.10"
+	// LocalDNSClusterListenerIP sepcifies clusterlistener APIPA-IP used in localdns.
+	LocalDNSClusterListenerIP string = "169.254.10.11"
+	// DefaultLocalDNSCPULimitInPercentage sepcifies the default CPU limit used in akslocaldns.
+	DefaultLocalDNSCPULimitInPercentage string = "200.0%"
+	// DefaultLocalDNSMemoryLimitInMB sepcifies the default Memory limit used in akslocaldns.
+	DefaultLocalDNSMemoryLimitInMB string = "128M"
+	// DefaultLocalDNSServiceIP sepcifies the default coredns service IP.
+	DefaultCoreDNSServiceIP string = "10.0.0.10"
+	// AzureDNSIP is the default Azure DNS IP used in localdns.
+	AzureDNSIP string = "168.63.129.16"
+)
+
+// LocalDNSProfile represents localdns configuration for agentpool nodes.
+type LocalDNSProfile struct {
+	State                string                        `json:"state,omitempty"`
+	CPULimitInMilliCores *int32                        `json:"cpuLimitInMilliCores,omitempty"`
+	MemoryLimitInMB      *int32                        `json:"memoryLimitInMB,omitempty"`
+	VnetDNSOverrides     map[string]*LocalDNSOverrides `json:"vnetDNSOverrides,omitempty"`
+	KubeDNSOverrides     map[string]*LocalDNSOverrides `json:"kubeDNSOverrides,omitempty"`
+}
+
+type LocalDNSCoreFileData struct {
+	LocalDNSProfile
+	NodeListenerIP    string
+	ClusterListenerIP string
+	CoreDNSServiceIP  string
+	AzureDNSIP        string
+}
+
+// LocalDNSOverrides represents DNS override settings for both VnetDNS and KubeDNS traffic.
+// VnetDNS overrides apply to DNS traffic from pods with dnsPolicy:default or kubelet (referred to as VnetDNS traffic).
+// KubeDNS overrides apply to DNS traffic from pods with dnsPolicy:ClusterFirst (referred to as KubeDNS traffic).
+type LocalDNSOverrides struct {
+	QueryLogging                string `json:"queryLogging,omitempty"`
+	Protocol                    string `json:"protocol,omitempty"`
+	ForwardDestination          string `json:"forwardDestination,omitempty"`
+	ForwardPolicy               string `json:"forwardPolicy,omitempty"`
+	MaxConcurrent               *int32 `json:"maxConcurrent,omitempty"`
+	CacheDurationInSeconds      *int32 `json:"cacheDurationInSeconds,omitempty"`
+	ServeStaleDurationInSeconds *int32 `json:"serveStaleDurationInSeconds,omitempty"`
+	ServeStale                  string `json:"serveStale,omitempty"`
+}
+
+// ShouldEnableLocalDNS returns true if LocalDNSProfile is not nil and GoalState is 'Enable'.
+func (a *AgentPoolProfile) ShouldEnableLocalDNS() bool {
+	return a != nil && a.LocalDNSProfile != nil &&
+		strings.EqualFold(a.LocalDNSProfile.State, LocalDNSEnabled)
path: pkg/agent/datamodel/types.go
user: login: yewmsft
body: consider using Enable bool. Enable == true -> should enable. Enable == false --> should disable. 
created_at: 2025-04-08T22:51:18Z
author_association: MEMBER
diff_hunk: @@ -2316,3 +2317,116 @@ func (s *SecurityProfile) GetPrivateEgressContainerRegistryServer() string {
 }
 
 // SecurityProfile end.
+
+// ----------------------- Start of Changed related to localdns ------------------------------------------.
+// localdns related constants.
+const (
+	// LocalDNSEnabled is a string constant for 'Enabled'.
+	LocalDNSEnabled string = "Enabled"
+	// LocalDNSNodeListenerIP sepcifies nodelistener APIPA-IP used in localdns.
+	LocalDNSNodeListenerIP string = "169.254.10.10"
+	// LocalDNSClusterListenerIP sepcifies clusterlistener APIPA-IP used in localdns.
+	LocalDNSClusterListenerIP string = "169.254.10.11"
+	// DefaultLocalDNSCPULimitInPercentage sepcifies the default CPU limit used in akslocaldns.
+	DefaultLocalDNSCPULimitInPercentage string = "200.0%"
+	// DefaultLocalDNSMemoryLimitInMB sepcifies the default Memory limit used in akslocaldns.
+	DefaultLocalDNSMemoryLimitInMB string = "128M"
+	// DefaultLocalDNSServiceIP sepcifies the default coredns service IP.
+	DefaultCoreDNSServiceIP string = "10.0.0.10"
+	// AzureDNSIP is the default Azure DNS IP used in localdns.
+	AzureDNSIP string = "168.63.129.16"
+)
+
+// LocalDNSProfile represents localdns configuration for agentpool nodes.
+type LocalDNSProfile struct {
+	State                string                        `json:"state,omitempty"`
+	CPULimitInMilliCores *int32                        `json:"cpuLimitInMilliCores,omitempty"`
+	MemoryLimitInMB      *int32                        `json:"memoryLimitInMB,omitempty"`
+	VnetDNSOverrides     map[string]*LocalDNSOverrides `json:"vnetDNSOverrides,omitempty"`
+	KubeDNSOverrides     map[string]*LocalDNSOverrides `json:"kubeDNSOverrides,omitempty"`
+}
+
+type LocalDNSCoreFileData struct {
+	LocalDNSProfile
+	NodeListenerIP    string
+	ClusterListenerIP string
+	CoreDNSServiceIP  string
+	AzureDNSIP        string
+}
+
+// LocalDNSOverrides represents DNS override settings for both VnetDNS and KubeDNS traffic.
+// VnetDNS overrides apply to DNS traffic from pods with dnsPolicy:default or kubelet (referred to as VnetDNS traffic).
+// KubeDNS overrides apply to DNS traffic from pods with dnsPolicy:ClusterFirst (referred to as KubeDNS traffic).
+type LocalDNSOverrides struct {
+	QueryLogging                string `json:"queryLogging,omitempty"`
+	Protocol                    string `json:"protocol,omitempty"`
+	ForwardDestination          string `json:"forwardDestination,omitempty"`
+	ForwardPolicy               string `json:"forwardPolicy,omitempty"`
+	MaxConcurrent               *int32 `json:"maxConcurrent,omitempty"`
+	CacheDurationInSeconds      *int32 `json:"cacheDurationInSeconds,omitempty"`
+	ServeStaleDurationInSeconds *int32 `json:"serveStaleDurationInSeconds,omitempty"`
+	ServeStale                  string `json:"serveStale,omitempty"`
+}
+
+// ShouldEnableLocalDNS returns true if LocalDNSProfile is not nil and GoalState is 'Enable'.
+func (a *AgentPoolProfile) ShouldEnableLocalDNS() bool {
+	return a != nil && a.LocalDNSProfile != nil &&
+		strings.EqualFold(a.LocalDNSProfile.State, LocalDNSEnabled)
path: pkg/agent/datamodel/types.go
user: login: yewmsft
body: and using state = enabled / disabled on RP side to denote the result of the enablement. 
created_at: 2025-04-08T23:02:29Z
author_association: MEMBER
diff_hunk: @@ -2316,3 +2317,116 @@ func (s *SecurityProfile) GetPrivateEgressContainerRegistryServer() string {
 }
 
 // SecurityProfile end.
+
+// ----------------------- Start of Changed related to localdns ------------------------------------------.
+// localdns related constants.
+const (
+	// LocalDNSEnabled is a string constant for 'Enabled'.
+	LocalDNSEnabled string = "Enabled"
+	// LocalDNSNodeListenerIP sepcifies nodelistener APIPA-IP used in localdns.
+	LocalDNSNodeListenerIP string = "169.254.10.10"
+	// LocalDNSClusterListenerIP sepcifies clusterlistener APIPA-IP used in localdns.
+	LocalDNSClusterListenerIP string = "169.254.10.11"
+	// DefaultLocalDNSCPULimitInPercentage sepcifies the default CPU limit used in akslocaldns.
+	DefaultLocalDNSCPULimitInPercentage string = "200.0%"
+	// DefaultLocalDNSMemoryLimitInMB sepcifies the default Memory limit used in akslocaldns.
+	DefaultLocalDNSMemoryLimitInMB string = "128M"
+	// DefaultLocalDNSServiceIP sepcifies the default coredns service IP.
+	DefaultCoreDNSServiceIP string = "10.0.0.10"
+	// AzureDNSIP is the default Azure DNS IP used in localdns.
+	AzureDNSIP string = "168.63.129.16"
+)
+
+// LocalDNSProfile represents localdns configuration for agentpool nodes.
+type LocalDNSProfile struct {
+	State                string                        `json:"state,omitempty"`
+	CPULimitInMilliCores *int32                        `json:"cpuLimitInMilliCores,omitempty"`
+	MemoryLimitInMB      *int32                        `json:"memoryLimitInMB,omitempty"`
+	VnetDNSOverrides     map[string]*LocalDNSOverrides `json:"vnetDNSOverrides,omitempty"`
+	KubeDNSOverrides     map[string]*LocalDNSOverrides `json:"kubeDNSOverrides,omitempty"`
+}
+
+type LocalDNSCoreFileData struct {
+	LocalDNSProfile
+	NodeListenerIP    string
+	ClusterListenerIP string
+	CoreDNSServiceIP  string
+	AzureDNSIP        string
+}
+
+// LocalDNSOverrides represents DNS override settings for both VnetDNS and KubeDNS traffic.
+// VnetDNS overrides apply to DNS traffic from pods with dnsPolicy:default or kubelet (referred to as VnetDNS traffic).
+// KubeDNS overrides apply to DNS traffic from pods with dnsPolicy:ClusterFirst (referred to as KubeDNS traffic).
+type LocalDNSOverrides struct {
+	QueryLogging                string `json:"queryLogging,omitempty"`
+	Protocol                    string `json:"protocol,omitempty"`
+	ForwardDestination          string `json:"forwardDestination,omitempty"`
+	ForwardPolicy               string `json:"forwardPolicy,omitempty"`
+	MaxConcurrent               *int32 `json:"maxConcurrent,omitempty"`
+	CacheDurationInSeconds      *int32 `json:"cacheDurationInSeconds,omitempty"`
+	ServeStaleDurationInSeconds *int32 `json:"serveStaleDurationInSeconds,omitempty"`
+	ServeStale                  string `json:"serveStale,omitempty"`
+}
+
+// ShouldEnableLocalDNS returns true if LocalDNSProfile is not nil and GoalState is 'Enable'.
+func (a *AgentPoolProfile) ShouldEnableLocalDNS() bool {
+	return a != nil && a.LocalDNSProfile != nil &&
+		strings.EqualFold(a.LocalDNSProfile.State, LocalDNSEnabled)
path: pkg/agent/datamodel/types.go
user: login: yewmsft
body: Becaue, you can have Enable == true, but enabling operation failed, so on RP side, state should still be Disabled. 
created_at: 2025-04-08T23:03:27Z
author_association: MEMBER
diff_hunk: @@ -2316,3 +2317,116 @@ func (s *SecurityProfile) GetPrivateEgressContainerRegistryServer() string {
 }
 
 // SecurityProfile end.
+
+// ----------------------- Start of Changed related to localdns ------------------------------------------.
+// localdns related constants.
+const (
+	// LocalDNSEnabled is a string constant for 'Enabled'.
+	LocalDNSEnabled string = "Enabled"
+	// LocalDNSNodeListenerIP sepcifies nodelistener APIPA-IP used in localdns.
+	LocalDNSNodeListenerIP string = "169.254.10.10"
+	// LocalDNSClusterListenerIP sepcifies clusterlistener APIPA-IP used in localdns.
+	LocalDNSClusterListenerIP string = "169.254.10.11"
+	// DefaultLocalDNSCPULimitInPercentage sepcifies the default CPU limit used in akslocaldns.
+	DefaultLocalDNSCPULimitInPercentage string = "200.0%"
+	// DefaultLocalDNSMemoryLimitInMB sepcifies the default Memory limit used in akslocaldns.
+	DefaultLocalDNSMemoryLimitInMB string = "128M"
+	// DefaultLocalDNSServiceIP sepcifies the default coredns service IP.
+	DefaultCoreDNSServiceIP string = "10.0.0.10"
+	// AzureDNSIP is the default Azure DNS IP used in localdns.
+	AzureDNSIP string = "168.63.129.16"
+)
+
+// LocalDNSProfile represents localdns configuration for agentpool nodes.
+type LocalDNSProfile struct {
+	State                string                        `json:"state,omitempty"`
+	CPULimitInMilliCores *int32                        `json:"cpuLimitInMilliCores,omitempty"`
+	MemoryLimitInMB      *int32                        `json:"memoryLimitInMB,omitempty"`
+	VnetDNSOverrides     map[string]*LocalDNSOverrides `json:"vnetDNSOverrides,omitempty"`
+	KubeDNSOverrides     map[string]*LocalDNSOverrides `json:"kubeDNSOverrides,omitempty"`
+}
+
+type LocalDNSCoreFileData struct {
+	LocalDNSProfile
+	NodeListenerIP    string
+	ClusterListenerIP string
+	CoreDNSServiceIP  string
+	AzureDNSIP        string
+}
+
+// LocalDNSOverrides represents DNS override settings for both VnetDNS and KubeDNS traffic.
+// VnetDNS overrides apply to DNS traffic from pods with dnsPolicy:default or kubelet (referred to as VnetDNS traffic).
+// KubeDNS overrides apply to DNS traffic from pods with dnsPolicy:ClusterFirst (referred to as KubeDNS traffic).
+type LocalDNSOverrides struct {
+	QueryLogging                string `json:"queryLogging,omitempty"`
+	Protocol                    string `json:"protocol,omitempty"`
+	ForwardDestination          string `json:"forwardDestination,omitempty"`
+	ForwardPolicy               string `json:"forwardPolicy,omitempty"`
+	MaxConcurrent               *int32 `json:"maxConcurrent,omitempty"`
+	CacheDurationInSeconds      *int32 `json:"cacheDurationInSeconds,omitempty"`
+	ServeStaleDurationInSeconds *int32 `json:"serveStaleDurationInSeconds,omitempty"`
+	ServeStale                  string `json:"serveStale,omitempty"`
+}
+
+// ShouldEnableLocalDNS returns true if LocalDNSProfile is not nil and GoalState is 'Enable'.
+func (a *AgentPoolProfile) ShouldEnableLocalDNS() bool {
+	return a != nil && a.LocalDNSProfile != nil &&
+		strings.EqualFold(a.LocalDNSProfile.State, LocalDNSEnabled)
path: pkg/agent/datamodel/types.go
user: login: SriHarsha001
body: Using EnableLocalDNS as a bool and made the changes. 
created_at: 2025-04-09T01:18:23Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2316,3 +2317,116 @@ func (s *SecurityProfile) GetPrivateEgressContainerRegistryServer() string {
 }
 
 // SecurityProfile end.
+
+// ----------------------- Start of Changed related to localdns ------------------------------------------.
+// localdns related constants.
+const (
+	// LocalDNSEnabled is a string constant for 'Enabled'.
+	LocalDNSEnabled string = "Enabled"
+	// LocalDNSNodeListenerIP sepcifies nodelistener APIPA-IP used in localdns.
+	LocalDNSNodeListenerIP string = "169.254.10.10"
+	// LocalDNSClusterListenerIP sepcifies clusterlistener APIPA-IP used in localdns.
+	LocalDNSClusterListenerIP string = "169.254.10.11"
+	// DefaultLocalDNSCPULimitInPercentage sepcifies the default CPU limit used in akslocaldns.
+	DefaultLocalDNSCPULimitInPercentage string = "200.0%"
+	// DefaultLocalDNSMemoryLimitInMB sepcifies the default Memory limit used in akslocaldns.
+	DefaultLocalDNSMemoryLimitInMB string = "128M"
+	// DefaultLocalDNSServiceIP sepcifies the default coredns service IP.
+	DefaultCoreDNSServiceIP string = "10.0.0.10"
+	// AzureDNSIP is the default Azure DNS IP used in localdns.
+	AzureDNSIP string = "168.63.129.16"
+)
+
+// LocalDNSProfile represents localdns configuration for agentpool nodes.
+type LocalDNSProfile struct {
+	State                string                        `json:"state,omitempty"`
+	CPULimitInMilliCores *int32                        `json:"cpuLimitInMilliCores,omitempty"`
+	MemoryLimitInMB      *int32                        `json:"memoryLimitInMB,omitempty"`
+	VnetDNSOverrides     map[string]*LocalDNSOverrides `json:"vnetDNSOverrides,omitempty"`
+	KubeDNSOverrides     map[string]*LocalDNSOverrides `json:"kubeDNSOverrides,omitempty"`
+}
+
+type LocalDNSCoreFileData struct {
+	LocalDNSProfile
+	NodeListenerIP    string
+	ClusterListenerIP string
+	CoreDNSServiceIP  string
+	AzureDNSIP        string
+}
+
+// LocalDNSOverrides represents DNS override settings for both VnetDNS and KubeDNS traffic.
+// VnetDNS overrides apply to DNS traffic from pods with dnsPolicy:default or kubelet (referred to as VnetDNS traffic).
+// KubeDNS overrides apply to DNS traffic from pods with dnsPolicy:ClusterFirst (referred to as KubeDNS traffic).
+type LocalDNSOverrides struct {
+	QueryLogging                string `json:"queryLogging,omitempty"`
+	Protocol                    string `json:"protocol,omitempty"`
+	ForwardDestination          string `json:"forwardDestination,omitempty"`
+	ForwardPolicy               string `json:"forwardPolicy,omitempty"`
+	MaxConcurrent               *int32 `json:"maxConcurrent,omitempty"`
+	CacheDurationInSeconds      *int32 `json:"cacheDurationInSeconds,omitempty"`
+	ServeStaleDurationInSeconds *int32 `json:"serveStaleDurationInSeconds,omitempty"`
+	ServeStale                  string `json:"serveStale,omitempty"`
+}
+
+// ShouldEnableLocalDNS returns true if LocalDNSProfile is not nil and GoalState is 'Enable'.
+func (a *AgentPoolProfile) ShouldEnableLocalDNS() bool {
+	return a != nil && a.LocalDNSProfile != nil &&
+		strings.EqualFold(a.LocalDNSProfile.State, LocalDNSEnabled)
+}
+
+// GetLocalDNSNodeListenerIP returns APIPA-IP address that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSNodeListenerIP() string {
+	return LocalDNSNodeListenerIP
+}
+
+// GetLocalDNSClusterListenerIP returns APIPA-IP address that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSClusterListenerIP() string {
+	return LocalDNSClusterListenerIP
+}
+
+// GetAzureDNSIP returns 168.63.129.16 address.
+func (a *AgentPoolProfile) GetAzureDNSIP() string {
+	return AzureDNSIP
+}
+
+// GetLocalDNSCPULimitInPercentage returns CPU limit in percentage unit that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSCPULimitInPercentage() string {
+	if a.ShouldEnableLocalDNS() && a.LocalDNSProfile.CPULimitInMilliCores != nil {
+		// Convert milli-cores to percentage and return as formatted string
+		return fmt.Sprintf("%.1f%%", float64(*a.LocalDNSProfile.CPULimitInMilliCores)/10.0)
+	}
+	return DefaultLocalDNSCPULimitInPercentage
path: pkg/agent/datamodel/types.go
user: login: SriHarsha001
body: ok, made the changes and added tests. 
created_at: 2025-04-09T01:19:14Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2316,3 +2317,116 @@ func (s *SecurityProfile) GetPrivateEgressContainerRegistryServer() string {
 }
 
 // SecurityProfile end.
+
+// ----------------------- Start of Changed related to localdns ------------------------------------------.
+// localdns related constants.
+const (
+	// LocalDNSEnabled is a string constant for 'Enabled'.
+	LocalDNSEnabled string = "Enabled"
+	// LocalDNSNodeListenerIP sepcifies nodelistener APIPA-IP used in localdns.
+	LocalDNSNodeListenerIP string = "169.254.10.10"
+	// LocalDNSClusterListenerIP sepcifies clusterlistener APIPA-IP used in localdns.
+	LocalDNSClusterListenerIP string = "169.254.10.11"
+	// DefaultLocalDNSCPULimitInPercentage sepcifies the default CPU limit used in akslocaldns.
+	DefaultLocalDNSCPULimitInPercentage string = "200.0%"
+	// DefaultLocalDNSMemoryLimitInMB sepcifies the default Memory limit used in akslocaldns.
+	DefaultLocalDNSMemoryLimitInMB string = "128M"
+	// DefaultLocalDNSServiceIP sepcifies the default coredns service IP.
+	DefaultCoreDNSServiceIP string = "10.0.0.10"
+	// AzureDNSIP is the default Azure DNS IP used in localdns.
+	AzureDNSIP string = "168.63.129.16"
+)
+
+// LocalDNSProfile represents localdns configuration for agentpool nodes.
+type LocalDNSProfile struct {
+	State                string                        `json:"state,omitempty"`
path: pkg/agent/datamodel/types.go
user: login: SriHarsha001
body: Using EnableLocalDNS as a bool and made the changes.
created_at: 2025-04-09T01:21:42Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2316,3 +2317,112 @@ func (s *SecurityProfile) GetPrivateEgressContainerRegistryServer() string {
 }
 
 // SecurityProfile end.
+
+// ----------------------- Start of changes related to localdns ------------------------------------------.
+// localdns related constants.
+const (
+	// LocalDNSNodeListenerIP sepcifies nodelistener APIPA-IP used in localdns.
+	LocalDNSNodeListenerIP string = "169.254.10.10"
+	// LocalDNSClusterListenerIP sepcifies clusterlistener APIPA-IP used in localdns.
+	LocalDNSClusterListenerIP string = "169.254.10.11"
+	// DefaultLocalDNSServiceIP sepcifies the default coredns service IP.
+	DefaultCoreDNSServiceIP string = "10.0.0.10"
+	// AzureDNSIP is the default Azure DNS IP used in localdns.
+	AzureDNSIP string = "168.63.129.16"
+)
+
+// LocalDNSProfile represents localdns configuration for agentpool nodes.
+type LocalDNSProfile struct {
+	EnableLocalDNS       bool                          `json:"enableLocalDNS,omitempty"`
+	CPULimitInMilliCores *int32                        `json:"cpuLimitInMilliCores,omitempty"`
+	MemoryLimitInMB      *int32                        `json:"memoryLimitInMB,omitempty"`
+	VnetDNSOverrides     map[string]*LocalDNSOverrides `json:"vnetDNSOverrides,omitempty"`
+	KubeDNSOverrides     map[string]*LocalDNSOverrides `json:"kubeDNSOverrides,omitempty"`
+}
+
+type LocalDNSCoreFileData struct {
+	LocalDNSProfile
+	NodeListenerIP    string
+	ClusterListenerIP string
+	CoreDNSServiceIP  string
+	AzureDNSIP        string
+}
+
+// LocalDNSOverrides represents DNS override settings for both VnetDNS and KubeDNS traffic.
+// VnetDNS overrides apply to DNS traffic from pods with dnsPolicy:default or kubelet (referred to as VnetDNS traffic).
+// KubeDNS overrides apply to DNS traffic from pods with dnsPolicy:ClusterFirst (referred to as KubeDNS traffic).
+type LocalDNSOverrides struct {
+	QueryLogging                string `json:"queryLogging,omitempty"`
+	Protocol                    string `json:"protocol,omitempty"`
+	ForwardDestination          string `json:"forwardDestination,omitempty"`
+	ForwardPolicy               string `json:"forwardPolicy,omitempty"`
+	MaxConcurrent               *int32 `json:"maxConcurrent,omitempty"`
+	CacheDurationInSeconds      *int32 `json:"cacheDurationInSeconds,omitempty"`
+	ServeStaleDurationInSeconds *int32 `json:"serveStaleDurationInSeconds,omitempty"`
+	ServeStale                  string `json:"serveStale,omitempty"`
+}
+
+// ShouldEnableLocalDNS returns true if AgentPoolProfile, LocalDNSProfile is not nil and
+// EnableLocaDNS for the Agentpool is true. EnableLocaDNS boolean value is sent by AKS RP.
+// This will tell if localdns should be enabled for the agent pool or not.
+// If this function returns true only then we generate localdns systemd unit and corefile.
+func (a *AgentPoolProfile) ShouldEnableLocalDNS() bool {
+	return a != nil && a.LocalDNSProfile != nil && a.LocalDNSProfile.EnableLocalDNS
+}
+
+// GetLocalDNSNodeListenerIP returns APIPA-IP address that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSNodeListenerIP() string {
+	return LocalDNSNodeListenerIP
+}
+
+// GetLocalDNSClusterListenerIP returns APIPA-IP address that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSClusterListenerIP() string {
+	return LocalDNSClusterListenerIP
+}
+
+// GetAzureDNSIP returns 168.63.129.16 address.
+func (a *AgentPoolProfile) GetAzureDNSIP() string {
+	return AzureDNSIP
+}
+
+// GetLocalDNSCPULimitInPercentage returns CPU limit in percentage unit that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSCPULimitInPercentage() string {
+	if a.LocalDNSProfile.CPULimitInMilliCores != nil {
+		// Convert milli-cores to percentage and return as formatted string.
+		return fmt.Sprintf("%.1f%%", float64(*a.LocalDNSProfile.CPULimitInMilliCores)/10.0)
+	}
+	return ""
path: pkg/agent/datamodel/types.go
user: login: yewmsft
body: return default here？
created_at: 2025-04-09T01:32:30Z
author_association: MEMBER
diff_hunk: @@ -2316,3 +2317,112 @@ func (s *SecurityProfile) GetPrivateEgressContainerRegistryServer() string {
 }
 
 // SecurityProfile end.
+
+// ----------------------- Start of changes related to localdns ------------------------------------------.
+// localdns related constants.
+const (
+	// LocalDNSNodeListenerIP sepcifies nodelistener APIPA-IP used in localdns.
+	LocalDNSNodeListenerIP string = "169.254.10.10"
+	// LocalDNSClusterListenerIP sepcifies clusterlistener APIPA-IP used in localdns.
+	LocalDNSClusterListenerIP string = "169.254.10.11"
+	// DefaultLocalDNSServiceIP sepcifies the default coredns service IP.
+	DefaultCoreDNSServiceIP string = "10.0.0.10"
+	// AzureDNSIP is the default Azure DNS IP used in localdns.
+	AzureDNSIP string = "168.63.129.16"
+)
+
+// LocalDNSProfile represents localdns configuration for agentpool nodes.
+type LocalDNSProfile struct {
+	EnableLocalDNS       bool                          `json:"enableLocalDNS,omitempty"`
+	CPULimitInMilliCores *int32                        `json:"cpuLimitInMilliCores,omitempty"`
+	MemoryLimitInMB      *int32                        `json:"memoryLimitInMB,omitempty"`
+	VnetDNSOverrides     map[string]*LocalDNSOverrides `json:"vnetDNSOverrides,omitempty"`
+	KubeDNSOverrides     map[string]*LocalDNSOverrides `json:"kubeDNSOverrides,omitempty"`
+}
+
+type LocalDNSCoreFileData struct {
+	LocalDNSProfile
+	NodeListenerIP    string
+	ClusterListenerIP string
+	CoreDNSServiceIP  string
+	AzureDNSIP        string
+}
+
+// LocalDNSOverrides represents DNS override settings for both VnetDNS and KubeDNS traffic.
+// VnetDNS overrides apply to DNS traffic from pods with dnsPolicy:default or kubelet (referred to as VnetDNS traffic).
+// KubeDNS overrides apply to DNS traffic from pods with dnsPolicy:ClusterFirst (referred to as KubeDNS traffic).
+type LocalDNSOverrides struct {
+	QueryLogging                string `json:"queryLogging,omitempty"`
+	Protocol                    string `json:"protocol,omitempty"`
+	ForwardDestination          string `json:"forwardDestination,omitempty"`
+	ForwardPolicy               string `json:"forwardPolicy,omitempty"`
+	MaxConcurrent               *int32 `json:"maxConcurrent,omitempty"`
+	CacheDurationInSeconds      *int32 `json:"cacheDurationInSeconds,omitempty"`
+	ServeStaleDurationInSeconds *int32 `json:"serveStaleDurationInSeconds,omitempty"`
+	ServeStale                  string `json:"serveStale,omitempty"`
+}
+
+// ShouldEnableLocalDNS returns true if AgentPoolProfile, LocalDNSProfile is not nil and
+// EnableLocaDNS for the Agentpool is true. EnableLocaDNS boolean value is sent by AKS RP.
+// This will tell if localdns should be enabled for the agent pool or not.
+// If this function returns true only then we generate localdns systemd unit and corefile.
+func (a *AgentPoolProfile) ShouldEnableLocalDNS() bool {
+	return a != nil && a.LocalDNSProfile != nil && a.LocalDNSProfile.EnableLocalDNS
+}
+
+// GetLocalDNSNodeListenerIP returns APIPA-IP address that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSNodeListenerIP() string {
+	return LocalDNSNodeListenerIP
+}
+
+// GetLocalDNSClusterListenerIP returns APIPA-IP address that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSClusterListenerIP() string {
+	return LocalDNSClusterListenerIP
+}
+
+// GetAzureDNSIP returns 168.63.129.16 address.
+func (a *AgentPoolProfile) GetAzureDNSIP() string {
+	return AzureDNSIP
+}
+
+// GetLocalDNSCPULimitInPercentage returns CPU limit in percentage unit that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSCPULimitInPercentage() string {
+	if a.LocalDNSProfile.CPULimitInMilliCores != nil {
+		// Convert milli-cores to percentage and return as formatted string.
+		return fmt.Sprintf("%.1f%%", float64(*a.LocalDNSProfile.CPULimitInMilliCores)/10.0)
+	}
+	return ""
+}
+
+// GetLocalDNSMemoryLimitInMB returns memory limit in MB that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSMemoryLimitInMB() string {
+	if a.LocalDNSProfile.MemoryLimitInMB != nil {
+		// Return memory limit as a string with "M" suffix.
+		return fmt.Sprintf("%dM", *a.LocalDNSProfile.MemoryLimitInMB)
+	}
+	return ""
path: pkg/agent/datamodel/types.go
user: login: yewmsft
body: same
created_at: 2025-04-09T01:32:46Z
author_association: MEMBER
diff_hunk: @@ -2316,3 +2317,112 @@ func (s *SecurityProfile) GetPrivateEgressContainerRegistryServer() string {
 }
 
 // SecurityProfile end.
+
+// ----------------------- Start of changes related to localdns ------------------------------------------.
+// localdns related constants.
+const (
+	// LocalDNSNodeListenerIP sepcifies nodelistener APIPA-IP used in localdns.
+	LocalDNSNodeListenerIP string = "169.254.10.10"
+	// LocalDNSClusterListenerIP sepcifies clusterlistener APIPA-IP used in localdns.
+	LocalDNSClusterListenerIP string = "169.254.10.11"
+	// DefaultLocalDNSServiceIP sepcifies the default coredns service IP.
+	DefaultCoreDNSServiceIP string = "10.0.0.10"
+	// AzureDNSIP is the default Azure DNS IP used in localdns.
+	AzureDNSIP string = "168.63.129.16"
+)
+
+// LocalDNSProfile represents localdns configuration for agentpool nodes.
+type LocalDNSProfile struct {
+	EnableLocalDNS       bool                          `json:"enableLocalDNS,omitempty"`
+	CPULimitInMilliCores *int32                        `json:"cpuLimitInMilliCores,omitempty"`
+	MemoryLimitInMB      *int32                        `json:"memoryLimitInMB,omitempty"`
+	VnetDNSOverrides     map[string]*LocalDNSOverrides `json:"vnetDNSOverrides,omitempty"`
+	KubeDNSOverrides     map[string]*LocalDNSOverrides `json:"kubeDNSOverrides,omitempty"`
+}
+
+type LocalDNSCoreFileData struct {
+	LocalDNSProfile
+	NodeListenerIP    string
+	ClusterListenerIP string
+	CoreDNSServiceIP  string
+	AzureDNSIP        string
+}
+
+// LocalDNSOverrides represents DNS override settings for both VnetDNS and KubeDNS traffic.
+// VnetDNS overrides apply to DNS traffic from pods with dnsPolicy:default or kubelet (referred to as VnetDNS traffic).
+// KubeDNS overrides apply to DNS traffic from pods with dnsPolicy:ClusterFirst (referred to as KubeDNS traffic).
+type LocalDNSOverrides struct {
+	QueryLogging                string `json:"queryLogging,omitempty"`
+	Protocol                    string `json:"protocol,omitempty"`
+	ForwardDestination          string `json:"forwardDestination,omitempty"`
+	ForwardPolicy               string `json:"forwardPolicy,omitempty"`
+	MaxConcurrent               *int32 `json:"maxConcurrent,omitempty"`
+	CacheDurationInSeconds      *int32 `json:"cacheDurationInSeconds,omitempty"`
+	ServeStaleDurationInSeconds *int32 `json:"serveStaleDurationInSeconds,omitempty"`
+	ServeStale                  string `json:"serveStale,omitempty"`
+}
+
+// ShouldEnableLocalDNS returns true if AgentPoolProfile, LocalDNSProfile is not nil and
+// EnableLocaDNS for the Agentpool is true. EnableLocaDNS boolean value is sent by AKS RP.
+// This will tell if localdns should be enabled for the agent pool or not.
+// If this function returns true only then we generate localdns systemd unit and corefile.
+func (a *AgentPoolProfile) ShouldEnableLocalDNS() bool {
+	return a != nil && a.LocalDNSProfile != nil && a.LocalDNSProfile.EnableLocalDNS
+}
+
+// GetLocalDNSNodeListenerIP returns APIPA-IP address that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSNodeListenerIP() string {
+	return LocalDNSNodeListenerIP
+}
+
+// GetLocalDNSClusterListenerIP returns APIPA-IP address that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSClusterListenerIP() string {
+	return LocalDNSClusterListenerIP
+}
+
+// GetAzureDNSIP returns 168.63.129.16 address.
+func (a *AgentPoolProfile) GetAzureDNSIP() string {
+	return AzureDNSIP
+}
+
+// GetLocalDNSCPULimitInPercentage returns CPU limit in percentage unit that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSCPULimitInPercentage() string {
+	if a.LocalDNSProfile.CPULimitInMilliCores != nil {
+		// Convert milli-cores to percentage and return as formatted string.
+		return fmt.Sprintf("%.1f%%", float64(*a.LocalDNSProfile.CPULimitInMilliCores)/10.0)
+	}
+	return ""
path: pkg/agent/datamodel/types.go
user: login: yewmsft
body: or, will localdns systemd fail if you pass in empty to the core file？
created_at: 2025-04-09T01:37:02Z
author_association: MEMBER
diff_hunk: @@ -2316,3 +2317,112 @@ func (s *SecurityProfile) GetPrivateEgressContainerRegistryServer() string {
 }
 
 // SecurityProfile end.
+
+// ----------------------- Start of changes related to localdns ------------------------------------------.
+// localdns related constants.
+const (
+	// LocalDNSNodeListenerIP sepcifies nodelistener APIPA-IP used in localdns.
+	LocalDNSNodeListenerIP string = "169.254.10.10"
+	// LocalDNSClusterListenerIP sepcifies clusterlistener APIPA-IP used in localdns.
+	LocalDNSClusterListenerIP string = "169.254.10.11"
+	// DefaultLocalDNSServiceIP sepcifies the default coredns service IP.
+	DefaultCoreDNSServiceIP string = "10.0.0.10"
+	// AzureDNSIP is the default Azure DNS IP used in localdns.
+	AzureDNSIP string = "168.63.129.16"
+)
+
+// LocalDNSProfile represents localdns configuration for agentpool nodes.
+type LocalDNSProfile struct {
+	EnableLocalDNS       bool                          `json:"enableLocalDNS,omitempty"`
+	CPULimitInMilliCores *int32                        `json:"cpuLimitInMilliCores,omitempty"`
+	MemoryLimitInMB      *int32                        `json:"memoryLimitInMB,omitempty"`
+	VnetDNSOverrides     map[string]*LocalDNSOverrides `json:"vnetDNSOverrides,omitempty"`
+	KubeDNSOverrides     map[string]*LocalDNSOverrides `json:"kubeDNSOverrides,omitempty"`
+}
+
+type LocalDNSCoreFileData struct {
+	LocalDNSProfile
+	NodeListenerIP    string
+	ClusterListenerIP string
+	CoreDNSServiceIP  string
+	AzureDNSIP        string
+}
+
+// LocalDNSOverrides represents DNS override settings for both VnetDNS and KubeDNS traffic.
+// VnetDNS overrides apply to DNS traffic from pods with dnsPolicy:default or kubelet (referred to as VnetDNS traffic).
+// KubeDNS overrides apply to DNS traffic from pods with dnsPolicy:ClusterFirst (referred to as KubeDNS traffic).
+type LocalDNSOverrides struct {
+	QueryLogging                string `json:"queryLogging,omitempty"`
+	Protocol                    string `json:"protocol,omitempty"`
+	ForwardDestination          string `json:"forwardDestination,omitempty"`
+	ForwardPolicy               string `json:"forwardPolicy,omitempty"`
+	MaxConcurrent               *int32 `json:"maxConcurrent,omitempty"`
+	CacheDurationInSeconds      *int32 `json:"cacheDurationInSeconds,omitempty"`
+	ServeStaleDurationInSeconds *int32 `json:"serveStaleDurationInSeconds,omitempty"`
+	ServeStale                  string `json:"serveStale,omitempty"`
+}
+
+// ShouldEnableLocalDNS returns true if AgentPoolProfile, LocalDNSProfile is not nil and
+// EnableLocaDNS for the Agentpool is true. EnableLocaDNS boolean value is sent by AKS RP.
+// This will tell if localdns should be enabled for the agent pool or not.
+// If this function returns true only then we generate localdns systemd unit and corefile.
+func (a *AgentPoolProfile) ShouldEnableLocalDNS() bool {
+	return a != nil && a.LocalDNSProfile != nil && a.LocalDNSProfile.EnableLocalDNS
+}
+
+// GetLocalDNSNodeListenerIP returns APIPA-IP address that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSNodeListenerIP() string {
+	return LocalDNSNodeListenerIP
+}
+
+// GetLocalDNSClusterListenerIP returns APIPA-IP address that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSClusterListenerIP() string {
+	return LocalDNSClusterListenerIP
+}
+
+// GetAzureDNSIP returns 168.63.129.16 address.
+func (a *AgentPoolProfile) GetAzureDNSIP() string {
+	return AzureDNSIP
+}
+
+// GetLocalDNSCPULimitInPercentage returns CPU limit in percentage unit that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSCPULimitInPercentage() string {
+	if a.LocalDNSProfile.CPULimitInMilliCores != nil {
+		// Convert milli-cores to percentage and return as formatted string.
+		return fmt.Sprintf("%.1f%%", float64(*a.LocalDNSProfile.CPULimitInMilliCores)/10.0)
+	}
+	return ""
path: pkg/agent/datamodel/types.go
user: login: SriHarsha001
body: I think I mis-understood the suggestions earlier. Made the change. 
created_at: 2025-04-09T01:44:35Z
author_association: CONTRIBUTOR
diff_hunk: @@ -2316,3 +2317,112 @@ func (s *SecurityProfile) GetPrivateEgressContainerRegistryServer() string {
 }
 
 // SecurityProfile end.
+
+// ----------------------- Start of changes related to localdns ------------------------------------------.
+// localdns related constants.
+const (
+	// LocalDNSNodeListenerIP sepcifies nodelistener APIPA-IP used in localdns.
+	LocalDNSNodeListenerIP string = "169.254.10.10"
+	// LocalDNSClusterListenerIP sepcifies clusterlistener APIPA-IP used in localdns.
+	LocalDNSClusterListenerIP string = "169.254.10.11"
+	// DefaultLocalDNSServiceIP sepcifies the default coredns service IP.
+	DefaultCoreDNSServiceIP string = "10.0.0.10"
+	// AzureDNSIP is the default Azure DNS IP used in localdns.
+	AzureDNSIP string = "168.63.129.16"
+)
+
+// LocalDNSProfile represents localdns configuration for agentpool nodes.
+type LocalDNSProfile struct {
+	EnableLocalDNS       bool                          `json:"enableLocalDNS,omitempty"`
+	CPULimitInMilliCores *int32                        `json:"cpuLimitInMilliCores,omitempty"`
+	MemoryLimitInMB      *int32                        `json:"memoryLimitInMB,omitempty"`
+	VnetDNSOverrides     map[string]*LocalDNSOverrides `json:"vnetDNSOverrides,omitempty"`
+	KubeDNSOverrides     map[string]*LocalDNSOverrides `json:"kubeDNSOverrides,omitempty"`
+}
+
+type LocalDNSCoreFileData struct {
+	LocalDNSProfile
+	NodeListenerIP    string
+	ClusterListenerIP string
+	CoreDNSServiceIP  string
+	AzureDNSIP        string
+}
+
+// LocalDNSOverrides represents DNS override settings for both VnetDNS and KubeDNS traffic.
+// VnetDNS overrides apply to DNS traffic from pods with dnsPolicy:default or kubelet (referred to as VnetDNS traffic).
+// KubeDNS overrides apply to DNS traffic from pods with dnsPolicy:ClusterFirst (referred to as KubeDNS traffic).
+type LocalDNSOverrides struct {
+	QueryLogging                string `json:"queryLogging,omitempty"`
+	Protocol                    string `json:"protocol,omitempty"`
+	ForwardDestination          string `json:"forwardDestination,omitempty"`
+	ForwardPolicy               string `json:"forwardPolicy,omitempty"`
+	MaxConcurrent               *int32 `json:"maxConcurrent,omitempty"`
+	CacheDurationInSeconds      *int32 `json:"cacheDurationInSeconds,omitempty"`
+	ServeStaleDurationInSeconds *int32 `json:"serveStaleDurationInSeconds,omitempty"`
+	ServeStale                  string `json:"serveStale,omitempty"`
+}
+
+// ShouldEnableLocalDNS returns true if AgentPoolProfile, LocalDNSProfile is not nil and
+// EnableLocaDNS for the Agentpool is true. EnableLocaDNS boolean value is sent by AKS RP.
+// This will tell if localdns should be enabled for the agent pool or not.
+// If this function returns true only then we generate localdns systemd unit and corefile.
+func (a *AgentPoolProfile) ShouldEnableLocalDNS() bool {
+	return a != nil && a.LocalDNSProfile != nil && a.LocalDNSProfile.EnableLocalDNS
+}
+
+// GetLocalDNSNodeListenerIP returns APIPA-IP address that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSNodeListenerIP() string {
+	return LocalDNSNodeListenerIP
+}
+
+// GetLocalDNSClusterListenerIP returns APIPA-IP address that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSClusterListenerIP() string {
+	return LocalDNSClusterListenerIP
+}
+
+// GetAzureDNSIP returns 168.63.129.16 address.
+func (a *AgentPoolProfile) GetAzureDNSIP() string {
+	return AzureDNSIP
+}
+
+// GetLocalDNSCPULimitInPercentage returns CPU limit in percentage unit that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSCPULimitInPercentage() string {
+	if a.LocalDNSProfile.CPULimitInMilliCores != nil {
+		// Convert milli-cores to percentage and return as formatted string.
+		return fmt.Sprintf("%.1f%%", float64(*a.LocalDNSProfile.CPULimitInMilliCores)/10.0)
+	}
+	return ""
+}
+
+// GetLocalDNSMemoryLimitInMB returns memory limit in MB that will be used in localdns systemd unit.
+func (a *AgentPoolProfile) GetLocalDNSMemoryLimitInMB() string {
+	if a.LocalDNSProfile.MemoryLimitInMB != nil {
+		// Return memory limit as a string with "M" suffix.
+		return fmt.Sprintf("%dM", *a.LocalDNSProfile.MemoryLimitInMB)
+	}
+	return ""
path: pkg/agent/datamodel/types.go
user: login: SriHarsha001
body: I think I mis-understood the suggestions earlier. Made the change. 
created_at: 2025-04-09T01:44:52Z
author_association: CONTRIBUTOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-04-09T01:44:38Z
body: No changes to cached containers or packages on Windows VHDs

<!-- thollander/actions-comment-pull-request "WINDOWS_VHD_CONTENT_DIFF" -->
author_association: CONTRIBUTOR