From 4ee88a5505f55605bf777ae87ccbb05182780c7e Mon Sep 17 00:00:00 2001 From: Jessie Date: Wed, 16 Oct 2024 14:11:53 +1100 Subject: [PATCH] Add yurthub service env updater filter (#2165) Co-authored-by: Jessie Wang --- cmd/yurthub/app/options/filters.go | 5 +- pkg/yurthub/filter/masterservice/filter.go | 1 - .../filter/responsefilter/filter_test.go | 362 ++++++++++++++++++ .../filter/serviceenvupdater/filter.go | 103 +++++ .../filter/serviceenvupdater/filter_test.go | 306 +++++++++++++++ .../v3/deviceservice_client_test.go | 2 - 6 files changed, 775 insertions(+), 4 deletions(-) create mode 100644 pkg/yurthub/filter/serviceenvupdater/filter.go create mode 100644 pkg/yurthub/filter/serviceenvupdater/filter_test.go diff --git a/cmd/yurthub/app/options/filters.go b/cmd/yurthub/app/options/filters.go index b2a93512040..1e344daaa11 100644 --- a/cmd/yurthub/app/options/filters.go +++ b/cmd/yurthub/app/options/filters.go @@ -23,12 +23,13 @@ import ( "github.com/openyurtio/openyurt/pkg/yurthub/filter/inclusterconfig" "github.com/openyurtio/openyurt/pkg/yurthub/filter/masterservice" "github.com/openyurtio/openyurt/pkg/yurthub/filter/nodeportisolation" + "github.com/openyurtio/openyurt/pkg/yurthub/filter/serviceenvupdater" "github.com/openyurtio/openyurt/pkg/yurthub/filter/servicetopology" ) var ( // DisabledInCloudMode contains the filters that should be disabled when yurthub is working in cloud mode. - DisabledInCloudMode = []string{discardcloudservice.FilterName, forwardkubesvctraffic.FilterName} + DisabledInCloudMode = []string{discardcloudservice.FilterName, forwardkubesvctraffic.FilterName, serviceenvupdater.FilterName} // SupportedComponentsForFilter is used for specifying which components are supported by filters as default setting. SupportedComponentsForFilter = map[string]string{ @@ -38,6 +39,7 @@ var ( inclusterconfig.FilterName: "kubelet", nodeportisolation.FilterName: "kube-proxy", forwardkubesvctraffic.FilterName: "kube-proxy", + serviceenvupdater.FilterName: "kubelet", } ) @@ -52,4 +54,5 @@ func RegisterAllFilters(filters *base.Filters) { inclusterconfig.Register(filters) nodeportisolation.Register(filters) forwardkubesvctraffic.Register(filters) + serviceenvupdater.Register(filters) } diff --git a/pkg/yurthub/filter/masterservice/filter.go b/pkg/yurthub/filter/masterservice/filter.go index eab0450f143..1f32ba78dcc 100644 --- a/pkg/yurthub/filter/masterservice/filter.go +++ b/pkg/yurthub/filter/masterservice/filter.go @@ -67,7 +67,6 @@ func (msf *masterServiceFilter) SupportedResourceAndVerbs() map[string]sets.Set[ func (msf *masterServiceFilter) SetMasterServiceHost(host string) error { msf.host = host return nil - } func (msf *masterServiceFilter) SetMasterServicePort(portStr string) error { diff --git a/pkg/yurthub/filter/responsefilter/filter_test.go b/pkg/yurthub/filter/responsefilter/filter_test.go index 02a21df359f..3aab9ccc317 100644 --- a/pkg/yurthub/filter/responsefilter/filter_test.go +++ b/pkg/yurthub/filter/responsefilter/filter_test.go @@ -2220,6 +2220,368 @@ func TestResponseFilterForListRequest(t *testing.T) { }, }, }, + "serviceenvupdater: updates service host and service port env vars in multiple pods": { + masterHost: masterHost, + masterPort: masterPort, + kubeClient: &k8sfake.Clientset{}, + yurtClient: &fake.FakeDynamicClient{}, + poolName: poolName, + group: "", + version: "v1", + resource: "pods", + userAgent: "kubelet", + verb: "GET", + path: "/api/v1/pods", + accept: "application/json", + inputObj: &corev1.PodList{ + TypeMeta: metav1.TypeMeta{ + Kind: "PodList", + APIVersion: "v1", + }, + Items: []corev1.Pod{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "pod1", + Namespace: "kube-system", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test-container", + Env: []corev1.EnvVar{ + {Name: "KUBERNETES_SERVICE_HOST", Value: "192.0.2.1"}, + {Name: "KUBERNETES_SERVICE_PORT", Value: "1234"}, + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + }, + }, + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "pod2", + Namespace: "default", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test-container", + Env: []corev1.EnvVar{ + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + {Name: "KUBERNETES_SERVICE_HOST", Value: "192.0.2.1"}, + {Name: "KUBERNETES_SERVICE_PORT", Value: "1234"}, + }, + }, + }, + }, + }, + }, + }, + expectedObj: &corev1.PodList{ + TypeMeta: metav1.TypeMeta{ + Kind: "PodList", + APIVersion: "v1", + }, + Items: []corev1.Pod{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "pod1", + Namespace: "kube-system", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test-container", + Env: []corev1.EnvVar{ + {Name: "KUBERNETES_SERVICE_HOST", Value: masterHost}, + {Name: "KUBERNETES_SERVICE_PORT", Value: masterPort}, + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + }, + }, + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "pod2", + Namespace: "default", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test-container", + Env: []corev1.EnvVar{ + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + {Name: "KUBERNETES_SERVICE_HOST", Value: masterHost}, + {Name: "KUBERNETES_SERVICE_PORT", Value: masterPort}, + }, + }, + }, + }, + }, + }, + }, + }, + "serviceenvupdater: updates service host and service port env vars in multiple containers per pod": { + masterHost: masterHost, + masterPort: masterPort, + kubeClient: &k8sfake.Clientset{}, + yurtClient: &fake.FakeDynamicClient{}, + poolName: poolName, + group: "", + version: "v1", + resource: "pods", + userAgent: "kubelet", + verb: "GET", + path: "/api/v1/pods", + accept: "application/json", + inputObj: &corev1.PodList{ + TypeMeta: metav1.TypeMeta{ + Kind: "PodList", + APIVersion: "v1", + }, + Items: []corev1.Pod{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "pod1", + Namespace: "kube-system", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test-container", + Env: []corev1.EnvVar{ + {Name: "KUBERNETES_SERVICE_HOST", Value: "192.0.2.1"}, + {Name: "KUBERNETES_SERVICE_PORT", Value: "1234"}, + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + }, + }, + { + Name: "test-container1", + Env: []corev1.EnvVar{ + {Name: "KUBERNETES_SERVICE_HOST", Value: "192.0.2.1"}, + {Name: "KUBERNETES_SERVICE_PORT", Value: "1234"}, + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + }, + }, + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "pod2", + Namespace: "default", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test-container", + Env: []corev1.EnvVar{ + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + {Name: "KUBERNETES_SERVICE_HOST", Value: "192.0.2.1"}, + {Name: "KUBERNETES_SERVICE_PORT", Value: "1234"}, + }, + }, + { + Name: "test-container1", + Env: []corev1.EnvVar{ + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + {Name: "KUBERNETES_SERVICE_HOST", Value: "192.0.2.1"}, + {Name: "KUBERNETES_SERVICE_PORT", Value: "1234"}, + }, + }, + }, + }, + }, + }, + }, + expectedObj: &corev1.PodList{ + TypeMeta: metav1.TypeMeta{ + Kind: "PodList", + APIVersion: "v1", + }, + Items: []corev1.Pod{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "pod1", + Namespace: "kube-system", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test-container", + Env: []corev1.EnvVar{ + {Name: "KUBERNETES_SERVICE_HOST", Value: masterHost}, + {Name: "KUBERNETES_SERVICE_PORT", Value: masterPort}, + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + }, + }, + { + Name: "test-container1", + Env: []corev1.EnvVar{ + {Name: "KUBERNETES_SERVICE_HOST", Value: masterHost}, + {Name: "KUBERNETES_SERVICE_PORT", Value: masterPort}, + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + }, + }, + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "pod2", + Namespace: "default", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test-container", + Env: []corev1.EnvVar{ + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + {Name: "KUBERNETES_SERVICE_HOST", Value: masterHost}, + {Name: "KUBERNETES_SERVICE_PORT", Value: masterPort}, + }, + }, + { + Name: "test-container1", + Env: []corev1.EnvVar{ + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + {Name: "KUBERNETES_SERVICE_HOST", Value: masterHost}, + {Name: "KUBERNETES_SERVICE_PORT", Value: masterPort}, + }, + }, + }, + }, + }, + }, + }, + }, + "serviceenvupdater: updates service host env var - service port env var does not exist": { + masterHost: masterHost, + masterPort: masterPort, + kubeClient: &k8sfake.Clientset{}, + yurtClient: &fake.FakeDynamicClient{}, + poolName: poolName, + group: "", + version: "v1", + resource: "pods", + userAgent: "kubelet", + verb: "GET", + path: "/api/v1/pods", + accept: "application/json", + inputObj: &corev1.PodList{ + TypeMeta: metav1.TypeMeta{ + Kind: "PodList", + APIVersion: "v1", + }, + Items: []corev1.Pod{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "pod1", + Namespace: "kube-system", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test-container", + Env: []corev1.EnvVar{ + {Name: "KUBERNETES_SERVICE_HOST", Value: "192.0.2.1"}, + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + }, + }, + { + Name: "test-container1", + Env: []corev1.EnvVar{ + {Name: "KUBERNETES_SERVICE_HOST", Value: "192.0.2.1"}, + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + }, + }, + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "pod2", + Namespace: "default", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test-container", + Env: []corev1.EnvVar{ + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + {Name: "KUBERNETES_SERVICE_HOST", Value: "192.0.2.1"}, + }, + }, + { + Name: "test-container1", + Env: []corev1.EnvVar{ + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + {Name: "KUBERNETES_SERVICE_HOST", Value: "192.0.2.1"}, + }, + }, + }, + }, + }, + }, + }, + expectedObj: &corev1.PodList{ + TypeMeta: metav1.TypeMeta{ + Kind: "PodList", + APIVersion: "v1", + }, + Items: []corev1.Pod{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "pod1", + Namespace: "kube-system", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test-container", + Env: []corev1.EnvVar{ + {Name: "KUBERNETES_SERVICE_HOST", Value: masterHost}, + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + }, + }, + { + Name: "test-container1", + Env: []corev1.EnvVar{ + {Name: "KUBERNETES_SERVICE_HOST", Value: masterHost}, + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + }, + }, + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "pod2", + Namespace: "default", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test-container", + Env: []corev1.EnvVar{ + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + {Name: "KUBERNETES_SERVICE_HOST", Value: masterHost}, + }, + }, + { + Name: "test-container1", + Env: []corev1.EnvVar{ + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + {Name: "KUBERNETES_SERVICE_HOST", Value: masterHost}, + }, + }, + }, + }, + }, + }, + }, + }, } resolver := newTestRequestInfoResolver() diff --git a/pkg/yurthub/filter/serviceenvupdater/filter.go b/pkg/yurthub/filter/serviceenvupdater/filter.go new file mode 100644 index 00000000000..6ca73517b9a --- /dev/null +++ b/pkg/yurthub/filter/serviceenvupdater/filter.go @@ -0,0 +1,103 @@ +/* +Copyright 2024 The OpenYurt Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package serviceenvupdater + +import ( + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/sets" + + "github.com/openyurtio/openyurt/pkg/yurthub/filter" + "github.com/openyurtio/openyurt/pkg/yurthub/filter/base" +) + +const ( + // FilterName filter is used to mutate the Kubernetes service host and port + // in order for pods on edge nodes to access kube-apiserver via Yurthub proxy + FilterName = "serviceenvupdater" + + envVarServiceHost = "KUBERNETES_SERVICE_HOST" + envVarServicePort = "KUBERNETES_SERVICE_PORT" +) + +// Register registers a filter +func Register(filters *base.Filters) { + filters.Register(FilterName, func() (filter.ObjectFilter, error) { + return NewServiceEnvUpdaterFilter() + }) +} + +type serviceEnvUpdaterFilter struct { + host string + port string +} + +func NewServiceEnvUpdaterFilter() (*serviceEnvUpdaterFilter, error) { + return &serviceEnvUpdaterFilter{}, nil +} + +func (sef *serviceEnvUpdaterFilter) Name() string { + return FilterName +} + +func (sef *serviceEnvUpdaterFilter) SupportedResourceAndVerbs() map[string]sets.Set[string] { + return map[string]sets.Set[string]{ + "pods": sets.New("list", "watch", "get", "patch"), + } +} + +func (sef *serviceEnvUpdaterFilter) SetMasterServiceHost(host string) error { + sef.host = host + return nil +} + +func (sef *serviceEnvUpdaterFilter) SetMasterServicePort(port string) error { + sef.port = port + return nil +} + +func (sef *serviceEnvUpdaterFilter) Filter(obj runtime.Object, _ <-chan struct{}) runtime.Object { + switch v := obj.(type) { + case *corev1.Pod: + return sef.mutatePodEnv(v) + default: + return v + } +} + +func (sef *serviceEnvUpdaterFilter) mutatePodEnv(req *corev1.Pod) *corev1.Pod { + for i := range req.Spec.Containers { + foundHost := false + foundPort := false + + for j, envVar := range req.Spec.Containers[i].Env { + switch envVar.Name { + case envVarServiceHost: + req.Spec.Containers[i].Env[j].Value = sef.host + foundHost = true + case envVarServicePort: + req.Spec.Containers[i].Env[j].Value = sef.port + foundPort = true + } + + if foundHost && foundPort { + break + } + } + } + return req +} diff --git a/pkg/yurthub/filter/serviceenvupdater/filter_test.go b/pkg/yurthub/filter/serviceenvupdater/filter_test.go new file mode 100644 index 00000000000..72c80d189a3 --- /dev/null +++ b/pkg/yurthub/filter/serviceenvupdater/filter_test.go @@ -0,0 +1,306 @@ +/* +Copyright 2024 The OpenYurt Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package serviceenvupdater + +import ( + "reflect" + "testing" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/sets" + + "github.com/openyurtio/openyurt/pkg/util" + "github.com/openyurtio/openyurt/pkg/yurthub/filter/base" +) + +const ( + masterHost = "169.254.2.1" + masterPort = "10261" +) + +func TestRegister(t *testing.T) { + filters := base.NewFilters([]string{}) + Register(filters) + if !filters.Enabled(FilterName) { + t.Errorf("couldn't register %s filter", FilterName) + } +} + +func TestName(t *testing.T) { + nif, _ := NewServiceEnvUpdaterFilter() + if nif.Name() != FilterName { + t.Errorf("expect %s, but got %s", FilterName, nif.Name()) + } +} + +func TestSupportedResourceAndVerbs(t *testing.T) { + nif, _ := NewServiceEnvUpdaterFilter() + rvs := nif.SupportedResourceAndVerbs() + if len(rvs) != 1 { + t.Errorf("supported more than one resources, %v", rvs) + } + for resource, verbs := range rvs { + if resource != "pods" { + t.Errorf("expect resource is pods, but got %s", resource) + } + if !verbs.Equal(sets.New("list", "watch", "get", "patch")) { + t.Errorf("expect verbs are list/watch, but got %v", verbs.UnsortedList()) + } + } +} + +func TestFilterServiceEnvUpdater(t *testing.T) { + tests := []struct { + name string + requestObj runtime.Object + expectedObj runtime.Object + }{ + { + name: "service host and service port set to original value", + requestObj: &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test-container", + Env: []corev1.EnvVar{ + {Name: "KUBERNETES_SERVICE_HOST", Value: "some-host"}, + {Name: "KUBERNETES_SERVICE_PORT", Value: "1234"}, + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + }, + }, + }, + }, + }, + expectedObj: &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test-container", + Env: []corev1.EnvVar{ + {Name: "KUBERNETES_SERVICE_HOST", Value: masterHost}, + {Name: "KUBERNETES_SERVICE_PORT", Value: masterPort}, + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + }, + }, + }, + }, + }, + }, + { + name: "service host and service port set to correct value, should update nothing", + requestObj: &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test-container", + Env: []corev1.EnvVar{ + {Name: "KUBERNETES_SERVICE_HOST", Value: masterHost}, + {Name: "KUBERNETES_SERVICE_PORT", Value: masterPort}, + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + }, + }, + }, + }, + }, + expectedObj: &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test-container", + Env: []corev1.EnvVar{ + {Name: "KUBERNETES_SERVICE_HOST", Value: masterHost}, + {Name: "KUBERNETES_SERVICE_PORT", Value: masterPort}, + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + }, + }, + }, + }, + }, + }, + { + name: "service host and service port does not exist", + requestObj: &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test-container", + Env: []corev1.EnvVar{ + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + }, + }, + }, + }, + }, + expectedObj: &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test-container", + Env: []corev1.EnvVar{ + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + }, + }, + }, + }, + }, + }, + { + name: "service host does not exist", + requestObj: &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test-container", + Env: []corev1.EnvVar{ + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + {Name: "KUBERNETES_SERVICE_PORT", Value: masterPort}, + }, + }, + }, + }, + }, + expectedObj: &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test-container", + Env: []corev1.EnvVar{ + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + {Name: "KUBERNETES_SERVICE_PORT", Value: masterPort}, + }, + }, + }, + }, + }, + }, + { + name: "service port does not exist", + requestObj: &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test-container", + Env: []corev1.EnvVar{ + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + {Name: "KUBERNETES_SERVICE_HOST", Value: masterHost}, + }, + }, + }, + }, + }, + expectedObj: &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test-container", + Env: []corev1.EnvVar{ + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + {Name: "KUBERNETES_SERVICE_HOST", Value: masterHost}, + }, + }, + }, + }, + }, + }, + { + name: "service host and service port updates correctly in multiple containers", + requestObj: &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test-container", + Env: []corev1.EnvVar{ + {Name: "KUBERNETES_SERVICE_HOST", Value: "some-host"}, + {Name: "KUBERNETES_SERVICE_PORT", Value: "1234"}, + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + }, + }, + { + Name: "test-container1", + Env: []corev1.EnvVar{ + {Name: "KUBERNETES_SERVICE_HOST", Value: "some-host"}, + {Name: "KUBERNETES_SERVICE_PORT", Value: "1234"}, + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + }, + }, + }, + }, + }, + expectedObj: &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test-container", + Env: []corev1.EnvVar{ + {Name: "KUBERNETES_SERVICE_HOST", Value: masterHost}, + {Name: "KUBERNETES_SERVICE_PORT", Value: masterPort}, + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + }, + }, + { + Name: "test-container1", + Env: []corev1.EnvVar{ + {Name: "KUBERNETES_SERVICE_HOST", Value: masterHost}, + {Name: "KUBERNETES_SERVICE_PORT", Value: masterPort}, + {Name: "OTHER_ENV_VAR", Value: "some-value"}, + }, + }, + }, + }, + }, + }, + } + stopCh := make(<-chan struct{}) + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + pef, _ := NewServiceEnvUpdaterFilter() + pef.SetMasterServiceHost(masterHost) + pef.SetMasterServicePort(masterPort) + newObj := pef.Filter(tc.requestObj, stopCh) + + if tc.expectedObj == nil { + if !util.IsNil(newObj) { + t.Errorf("RuntimeObjectFilter expect nil obj, but got %v", newObj) + } + } else if !reflect.DeepEqual(newObj, tc.expectedObj) { + t.Errorf("RuntimeObjectFilter got error, expected: \n%v\nbut got: \n%v\n", tc.expectedObj, newObj) + } + }) + } +} + +func TestFilterNonPodReq(t *testing.T) { + serviceReq := &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: "svc1", + Namespace: "default", + }, + Spec: corev1.ServiceSpec{ + ClusterIP: "10.96.105.187", + Type: corev1.ServiceTypeClusterIP, + }, + } + pef, _ := NewServiceEnvUpdaterFilter() + newObj := pef.Filter(serviceReq, make(<-chan struct{})) + + if !reflect.DeepEqual(newObj, serviceReq) { + t.Errorf("RuntimeObjectFilter got error, expected: \n%v\nbut got: \n%v\n", serviceReq, newObj) + } +} diff --git a/pkg/yurtiotdock/clients/edgex-foundry/v3/deviceservice_client_test.go b/pkg/yurtiotdock/clients/edgex-foundry/v3/deviceservice_client_test.go index 0a2a8b7aec4..5c185fa5e68 100644 --- a/pkg/yurtiotdock/clients/edgex-foundry/v3/deviceservice_client_test.go +++ b/pkg/yurtiotdock/clients/edgex-foundry/v3/deviceservice_client_test.go @@ -18,7 +18,6 @@ package v3 import ( "context" "encoding/json" - "fmt" "testing" "github.com/edgexfoundry/go-mod-core-contracts/v3/dtos" @@ -138,7 +137,6 @@ func Test_ConvertServiceSystemEvents(t *testing.T) { service, err := serviceClient.Convert(context.TODO(), dsse, clients.GetOptions{Namespace: "default"}) assert.Nil(t, err) - fmt.Println(service) assert.Equal(t, "device-virtual", service.Name) assert.Equal(t, "http://edgex-device-virtual:59900", service.Spec.BaseAddress) }