diff --git a/pkg/controllers/sync/dispatch/retain.go b/pkg/controllers/sync/dispatch/retain.go index e2c833ee..828b1bba 100644 --- a/pkg/controllers/sync/dispatch/retain.go +++ b/pkg/controllers/sync/dispatch/retain.go @@ -334,6 +334,13 @@ func retainPodFields(desiredObj, clusterObj *unstructured.Unstructured) error { } } + if dnsConfig, exists, err := unstructured.NestedFieldNoCopy(desiredObj.Object, "spec", "dnsConfig"); err == nil && + (!exists || dnsConfig == nil) { + if err := copyUnstructuredField(clusterObj, desiredObj, "spec", "dnsConfig"); err != nil { + return err + } + } + if _, _, exists := findServiceAccountVolume(desiredObj); !exists { if volume, idx, exists := findServiceAccountVolume(clusterObj); exists { // If the service account volume exists in clusterObj but not in the desiredObj, it was injected by the diff --git a/pkg/controllers/sync/dispatch/retain_test.go b/pkg/controllers/sync/dispatch/retain_test.go index 86e322c5..0ab17733 100644 --- a/pkg/controllers/sync/dispatch/retain_test.go +++ b/pkg/controllers/sync/dispatch/retain_test.go @@ -25,8 +25,10 @@ import ( "testing" "github.com/onsi/gomega" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/sets" fedcorev1a1 "github.com/kubewharf/kubeadmiral/pkg/apis/core/v1alpha1" @@ -221,7 +223,8 @@ func Test_retainContainer(t *testing.T) { "resources": map[string]interface{}{ "cpu": "500m", "memory": "512Mi", - }}, + }, + }, clusterContainer: map[string]interface{}{ "name": "container-1", }, @@ -235,10 +238,12 @@ func Test_retainContainer(t *testing.T) { "resources": map[string]interface{}{ "cpu": "500m", "memory": "512Mi", - }}, + }, + }, clusterContainer: map[string]interface{}{ "name": "container-1", - "resources": map[string]interface{}{}}, + "resources": map[string]interface{}{}, + }, }, }, { @@ -249,13 +254,15 @@ func Test_retainContainer(t *testing.T) { "resources": map[string]interface{}{ "cpu": "500m", "memory": "512Mi", - }}, + }, + }, clusterContainer: map[string]interface{}{ "name": "container-1", "resources": map[string]interface{}{ "cpu": "100m", "memory": "100Mi", - }}, + }, + }, }, }, } @@ -270,3 +277,68 @@ func Test_retainContainer(t *testing.T) { }) } } + +func Test_retainPodFields(t *testing.T) { + type args struct { + desiredObj *unstructured.Unstructured + clusterObj *unstructured.Unstructured + } + + noDNSConfigPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-pod", + Namespace: "test-namespace", + }, + } + nilPodUnstructuredMap, _ := runtime.DefaultUnstructuredConverter.ToUnstructured(&noDNSConfigPod) + nilPodUnstructured := &unstructured.Unstructured{ + Object: nilPodUnstructuredMap, + } + + dnsConfigPod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-pod", + Namespace: "test-namespace", + }, + Spec: corev1.PodSpec{ + DNSConfig: &corev1.PodDNSConfig{ + Nameservers: []string{"server1", "server2"}, + }, + }, + } + dnsConfigPodUnstructuredMap, _ := runtime.DefaultUnstructuredConverter.ToUnstructured(&dnsConfigPod) + dnsConfigPodUnstructured := &unstructured.Unstructured{ + Object: dnsConfigPodUnstructuredMap, + } + + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "retain non-empty pod", + args: args{ + desiredObj: nilPodUnstructured, + clusterObj: nilPodUnstructured, + }, + wantErr: false, + }, + { + name: "retain dns config pod", + args: args{ + desiredObj: nilPodUnstructured, + clusterObj: dnsConfigPodUnstructured, + }, + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := retainPodFields(tt.args.desiredObj, tt.args.clusterObj); (err != nil) != tt.wantErr { + t.Errorf("retainPodFields() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +}