diff --git a/cmd/liqo-controller-manager/main.go b/cmd/liqo-controller-manager/main.go index 9060c2d178..6e71833626 100644 --- a/cmd/liqo-controller-manager/main.go +++ b/cmd/liqo-controller-manager/main.go @@ -106,6 +106,8 @@ func main() { var kubeletRAMRequests, kubeletRAMLimits argsutils.Quantity var kubeletMetricsAddress string var kubeletMetricsEnabled bool + var labelsNotReflected argsutils.StringList + var annotationsNotReflected argsutils.StringList webhookPort := flag.Uint("webhook-port", 9443, "The port the webhook server binds to") metricsAddr := flag.String("metrics-address", ":8080", "The address the metric endpoint binds to") @@ -166,6 +168,8 @@ func main() { flag.BoolVar(&kubeletMetricsEnabled, "kubelet-metrics-enabled", false, "Enable the kubelet metrics endpoint") flag.Var(&nodeExtraAnnotations, "node-extra-annotations", "Extra annotations to add to the Virtual Node") flag.Var(&nodeExtraLabels, "node-extra-labels", "Extra labels to add to the Virtual Node") + flag.Var(&labelsNotReflected, "labels-not-reflected", "List of labels (key) that must not be reflected") + flag.Var(&annotationsNotReflected, "annotations-not-reflected", "List of annotations (key) that must not be reflected") kubeletIpamServer := flag.String("kubelet-ipam-server", "", "The address of the IPAM server to use for the virtual kubelet (set to empty string to disable IPAM)") @@ -187,19 +191,21 @@ func main() { // Options for the virtual kubelet. virtualKubeletOpts := &forge.VirtualKubeletOpts{ - ContainerImage: *kubeletImage, - ExtraAnnotations: kubeletExtraAnnotations.StringMap, - ExtraLabels: kubeletExtraLabels.StringMap, - ExtraArgs: kubeletExtraArgs.StringList, - NodeExtraAnnotations: nodeExtraAnnotations, - NodeExtraLabels: nodeExtraLabels, - RequestsCPU: kubeletCPURequests.Quantity, - RequestsRAM: kubeletRAMRequests.Quantity, - LimitsCPU: kubeletCPULimits.Quantity, - LimitsRAM: kubeletRAMLimits.Quantity, - IpamEndpoint: *kubeletIpamServer, - MetricsAddress: kubeletMetricsAddress, - MetricsEnabled: kubeletMetricsEnabled, + ContainerImage: *kubeletImage, + ExtraAnnotations: kubeletExtraAnnotations.StringMap, + ExtraLabels: kubeletExtraLabels.StringMap, + ExtraArgs: kubeletExtraArgs.StringList, + NodeExtraAnnotations: nodeExtraAnnotations, + NodeExtraLabels: nodeExtraLabels, + RequestsCPU: kubeletCPURequests.Quantity, + RequestsRAM: kubeletRAMRequests.Quantity, + LimitsCPU: kubeletCPULimits.Quantity, + LimitsRAM: kubeletRAMLimits.Quantity, + IpamEndpoint: *kubeletIpamServer, + MetricsAddress: kubeletMetricsAddress, + MetricsEnabled: kubeletMetricsEnabled, + LabelsNotReflected: labelsNotReflected.StringList, + AnnotationsNotReflected: annotationsNotReflected.StringList, } clusterIdentity := clusterIdentityFlags.ReadOrDie() diff --git a/cmd/virtual-kubelet/root/flag.go b/cmd/virtual-kubelet/root/flag.go index 3fd18a7095..f8ae197b05 100644 --- a/cmd/virtual-kubelet/root/flag.go +++ b/cmd/virtual-kubelet/root/flag.go @@ -71,6 +71,9 @@ func InstallFlags(flags *pflag.FlagSet, o *Opts) { flags.Var(&o.NodeExtraAnnotations, "node-extra-annotations", "Extra annotations to add to the Virtual Node") flags.Var(&o.NodeExtraLabels, "node-extra-labels", "Extra labels to add to the Virtual Node") + flags.Var(&o.LabelsNotReflected, "labels-not-reflected", "List of labels (key) that must not be reflected") + flags.Var(&o.AnnotationsNotReflected, "annotations-not-reflected", "List of annotations (key) that must not be reflected") + flags.BoolVar(&o.EnableAPIServerSupport, "enable-apiserver-support", false, "Enable offloaded pods to interact back with the local Kubernetes API server") flags.BoolVar(&o.EnableStorage, "enable-storage", false, "Enable the Liqo storage reflection") diff --git a/cmd/virtual-kubelet/root/opts.go b/cmd/virtual-kubelet/root/opts.go index fa6746b576..1a67a67715 100644 --- a/cmd/virtual-kubelet/root/opts.go +++ b/cmd/virtual-kubelet/root/opts.go @@ -89,6 +89,9 @@ type Opts struct { PersistentVolumeClaimWorkers uint EventWorkers uint + LabelsNotReflected argsutils.StringList + AnnotationsNotReflected argsutils.StringList + NodeLeaseDuration time.Duration NodePingInterval time.Duration NodePingTimeout time.Duration @@ -140,6 +143,9 @@ func NewOpts() *Opts { PersistentVolumeClaimWorkers: DefaultPersistenVolumeClaimWorkers, EventWorkers: DefaultEventWorkers, + LabelsNotReflected: argsutils.StringList{}, + AnnotationsNotReflected: argsutils.StringList{}, + NodeLeaseDuration: node.DefaultLeaseDuration * time.Second, NodePingInterval: node.DefaultPingInterval, NodePingTimeout: DefaultNodePingTimeout, diff --git a/cmd/virtual-kubelet/root/root.go b/cmd/virtual-kubelet/root/root.go index c6d087a43d..ecbf5e18b6 100644 --- a/cmd/virtual-kubelet/root/root.go +++ b/cmd/virtual-kubelet/root/root.go @@ -128,6 +128,9 @@ func runRootCommand(ctx context.Context, c *Opts) error { HomeAPIServerHost: c.HomeAPIServerHost, HomeAPIServerPort: c.HomeAPIServerPort, + + LabelsNotReflected: c.LabelsNotReflected.StringList, + AnnotationsNotReflected: c.AnnotationsNotReflected.StringList, } eb := record.NewBroadcaster() diff --git a/deployments/liqo/README.md b/deployments/liqo/README.md index cc18549b65..fc018b2acb 100644 --- a/deployments/liqo/README.md +++ b/deployments/liqo/README.md @@ -115,6 +115,8 @@ | proxy.service.annotations | object | `{}` | | | proxy.service.type | string | `"ClusterIP"` | | | pullPolicy | string | `"IfNotPresent"` | The pullPolicy for liqo pods. | +| reflection.skip.annotations | list | `["metallb.universe.tf/ip-allocated-from-pool","metallb.universe.tf/loadBalancerIPs","metallb.universe.tf/address-pool"]` | List of annotations that must not be reflected on remote clusters. | +| reflection.skip.labels | list | `[]` | List of labels that must not be reflected on remote clusters. | | route.imageName | string | `"ghcr.io/liqotech/liqonet"` | Image repository for the route pod. | | route.pod.annotations | object | `{}` | Annotations for the route pod. | | route.pod.extraArgs | list | `[]` | Extra arguments for the route pod. | diff --git a/deployments/liqo/templates/liqo-controller-manager-deployment.yaml b/deployments/liqo/templates/liqo-controller-manager-deployment.yaml index d7ea368ff9..ac8c3e1dec 100644 --- a/deployments/liqo/templates/liqo-controller-manager-deployment.yaml +++ b/deployments/liqo/templates/liqo-controller-manager-deployment.yaml @@ -77,6 +77,14 @@ spec: - --liqo-namespace=$(POD_NAMESPACE) - --enable-incoming-peering={{ .Values.discovery.config.incomingPeeringEnabled }} - --resource-sharing-percentage={{ .Values.controllerManager.config.resourceSharingPercentage }} + {{- if .Values.reflection.skip.labels }} + {{- $d := dict "commandName" "--labels-not-reflected" "list" .Values.reflection.skip.labels }} + {{- include "liqo.concatenateList" $d | nindent 10 }} + {{- end }} + {{- if .Values.reflection.skip.annotations }} + {{- $d := dict "commandName" "--annotations-not-reflected" "list" .Values.reflection.skip.annotations }} + {{- include "liqo.concatenateList" $d | nindent 10 }} + {{- end }} - --kubelet-image={{ .Values.virtualKubelet.imageName }}{{ include "liqo.suffix" $ctrlManagerConfig }}:{{ include "liqo.version" $ctrlManagerConfig }} {{- if .Values.virtualKubelet.metrics.enabled }} - --kubelet-metrics-address=:{{ .Values.virtualKubelet.metrics.port }} diff --git a/deployments/liqo/values.yaml b/deployments/liqo/values.yaml index d27cc89d7d..32604b81b1 100644 --- a/deployments/liqo/values.yaml +++ b/deployments/liqo/values.yaml @@ -18,6 +18,17 @@ networking: # -- Reflect pod IPs and EnpointSlices to the remote clusters. reflectIPs: true +reflection: + skip: + # -- List of labels that must not be reflected on remote clusters. + labels: [] + # -- List of annotations that must not be reflected on remote clusters. + annotations: [ + metallb.universe.tf/ip-allocated-from-pool, + metallb.universe.tf/loadBalancerIPs, + metallb.universe.tf/address-pool, + ] + controllerManager: # -- The number of controller-manager instances to run, which can be increased for active/passive high availability. replicas: 1 diff --git a/pkg/liqo-controller-manager/storageprovisioner/remoteprovisioner.go b/pkg/liqo-controller-manager/storageprovisioner/remoteprovisioner.go index 24b46b6b54..472529800c 100644 --- a/pkg/liqo-controller-manager/storageprovisioner/remoteprovisioner.go +++ b/pkg/liqo-controller-manager/storageprovisioner/remoteprovisioner.go @@ -36,7 +36,8 @@ func ProvisionRemotePVC(ctx context.Context, options controller.ProvisionOptions, remoteNamespace, remoteRealStorageClass string, remotePvcLister corev1listers.PersistentVolumeClaimNamespaceLister, - remotePvcClient corev1clients.PersistentVolumeClaimInterface) (*corev1.PersistentVolume, controller.ProvisioningState, error) { + remotePvcClient corev1clients.PersistentVolumeClaimInterface, + forgingOpts *forge.ForgingOpts) (*corev1.PersistentVolume, controller.ProvisioningState, error) { virtualPvc := options.PVC labels := options.SelectedNode.GetLabels() @@ -62,7 +63,7 @@ func ProvisionRemotePVC(ctx context.Context, default: } - mutation := remotePersistentVolumeClaim(virtualPvc, remoteStorageClass, remoteNamespace) + mutation := remotePersistentVolumeClaim(virtualPvc, remoteStorageClass, remoteNamespace, forgingOpts) _, err = remotePvcClient.Apply(ctx, mutation, forge.ApplyOptions()) if err != nil { return nil, controller.ProvisioningInBackground, err @@ -110,11 +111,11 @@ func ProvisionRemotePVC(ctx context.Context, // remotePersistentVolumeClaim forges the apply patch for the reflected PersistentVolumeClaim, given the local one. func remotePersistentVolumeClaim(virtualPvc *corev1.PersistentVolumeClaim, - storageClass, namespace string) *v1apply.PersistentVolumeClaimApplyConfiguration { + storageClass, namespace string, forgingOpts *forge.ForgingOpts) *v1apply.PersistentVolumeClaimApplyConfiguration { return v1apply.PersistentVolumeClaim(virtualPvc.Name, namespace). - WithLabels(virtualPvc.GetLabels()). + WithLabels(forge.FilterNotReflected(virtualPvc.GetLabels(), forgingOpts.LabelsNotReflected)). WithLabels(forge.ReflectionLabels()). - WithAnnotations(filterAnnotations(virtualPvc.GetAnnotations())). + WithAnnotations(forge.FilterNotReflected(filterAnnotations(virtualPvc.GetAnnotations()), forgingOpts.AnnotationsNotReflected)). WithSpec(remotePersistentVolumeClaimSpec(virtualPvc, storageClass)) } diff --git a/pkg/liqo-controller-manager/storageprovisioner/storageprovisioner_test.go b/pkg/liqo-controller-manager/storageprovisioner/storageprovisioner_test.go index 3949cc425b..01e217743c 100644 --- a/pkg/liqo-controller-manager/storageprovisioner/storageprovisioner_test.go +++ b/pkg/liqo-controller-manager/storageprovisioner/storageprovisioner_test.go @@ -38,6 +38,8 @@ import ( "sigs.k8s.io/sig-storage-lib-external-provisioner/v7/controller" liqoconst "github.com/liqotech/liqo/pkg/consts" + "github.com/liqotech/liqo/pkg/utils/testutil" + "github.com/liqotech/liqo/pkg/virtualKubelet/forge" ) const ( @@ -269,6 +271,7 @@ var _ = Describe("Test Storage Provisioner", func() { var ( remotePersistentVolumeClaims corev1listers.PersistentVolumeClaimNamespaceLister remotePersistentVolumesClaimsClient corev1clients.PersistentVolumeClaimInterface + forgingOpts *forge.ForgingOpts ) BeforeEach(func() { @@ -281,6 +284,8 @@ var _ = Describe("Test Storage Provisioner", func() { Expect(err).ToNot(HaveOccurred()) } + forgingOpts = testutil.FakeForgingOpts() + factory := informers.NewSharedInformerFactory(testEnvClient, 10*time.Hour) remote := factory.Core().V1().PersistentVolumeClaims() @@ -330,7 +335,7 @@ var _ = Describe("Test Storage Provisioner", func() { return &policy }(), }, - }, RemoteNamespace, storageClass, remotePersistentVolumeClaims, remotePersistentVolumesClaimsClient) + }, RemoteNamespace, storageClass, remotePersistentVolumeClaims, remotePersistentVolumesClaimsClient, forgingOpts) if err != nil { return err @@ -364,6 +369,8 @@ var _ = Describe("Test Storage Provisioner", func() { realPvc, err := testEnvClient.CoreV1().PersistentVolumeClaims(RemoteNamespace).Get(ctx, pvcName, metav1.GetOptions{}) Expect(err).ToNot(HaveOccurred()) Expect(realPvc.Spec.StorageClassName).To(PointTo(Equal(realStorageClassName))) + Expect(realPvc.Labels).ToNot(HaveKey(testutil.FakeNotReflectedLabelKey)) + Expect(realPvc.Annotations).ToNot(HaveKey(testutil.FakeNotReflectedAnnotKey)) }) }) diff --git a/pkg/utils/testutil/consts.go b/pkg/utils/testutil/consts.go index 08612185b4..13eb558e86 100644 --- a/pkg/utils/testutil/consts.go +++ b/pkg/utils/testutil/consts.go @@ -35,6 +35,10 @@ const ( VPNGatewayPort = 32406 // AuthenticationPort is the port of the liqo-auth service used for testing. AuthenticationPort = 32407 + // FakeNotReflectedLabelKey is the key of the fake not reflected label used for testing. + FakeNotReflectedLabelKey = "not-reflected-label" + // FakeNotReflectedAnnotKey is the key of the fake not reflected annotation used for testing. + FakeNotReflectedAnnotKey = "not-reflected-annot" ) var ( diff --git a/pkg/utils/testutil/liqo.go b/pkg/utils/testutil/liqo.go index 6bf24e7255..8eb4d86720 100644 --- a/pkg/utils/testutil/liqo.go +++ b/pkg/utils/testutil/liqo.go @@ -27,6 +27,7 @@ import ( netv1alpha1 "github.com/liqotech/liqo/apis/net/v1alpha1" sharingv1alpha1 "github.com/liqotech/liqo/apis/sharing/v1alpha1" liqoconsts "github.com/liqotech/liqo/pkg/consts" + "github.com/liqotech/liqo/pkg/virtualKubelet/forge" ) // FakeLiqoAuthService returns a fake liqo-auth service. @@ -248,3 +249,11 @@ func FakeNetworkConfig(local bool, clusterName, tenantNamespace, }, } } + +// FakeForgingOpts returns a fake ForgingOpts. +func FakeForgingOpts() *forge.ForgingOpts { + return &forge.ForgingOpts{ + LabelsNotReflected: []string{FakeNotReflectedLabelKey}, + AnnotationsNotReflected: []string{FakeNotReflectedAnnotKey}, + } +} diff --git a/pkg/virtualKubelet/forge/configmaps.go b/pkg/virtualKubelet/forge/configmaps.go index e1d75d5869..ad7b54e4a4 100644 --- a/pkg/virtualKubelet/forge/configmaps.go +++ b/pkg/virtualKubelet/forge/configmaps.go @@ -23,10 +23,10 @@ import ( const RootCAConfigMapName = "kube-root-ca.crt" // RemoteConfigMap forges the apply patch for the reflected configmap, given the local one. -func RemoteConfigMap(local *corev1.ConfigMap, targetNamespace string) *corev1apply.ConfigMapApplyConfiguration { +func RemoteConfigMap(local *corev1.ConfigMap, targetNamespace string, forgingOpts *ForgingOpts) *corev1apply.ConfigMapApplyConfiguration { applyConfig := corev1apply.ConfigMap(RemoteConfigMapName(local.GetName()), targetNamespace). - WithLabels(local.GetLabels()).WithLabels(ReflectionLabels()). - WithAnnotations(local.GetAnnotations()). + WithLabels(FilterNotReflected(local.GetLabels(), forgingOpts.LabelsNotReflected)).WithLabels(ReflectionLabels()). + WithAnnotations(FilterNotReflected(local.GetAnnotations(), forgingOpts.AnnotationsNotReflected)). WithBinaryData(local.BinaryData). WithData(local.Data) diff --git a/pkg/virtualKubelet/forge/configmaps_test.go b/pkg/virtualKubelet/forge/configmaps_test.go index b93797b37f..bbd98f1895 100644 --- a/pkg/virtualKubelet/forge/configmaps_test.go +++ b/pkg/virtualKubelet/forge/configmaps_test.go @@ -23,30 +23,34 @@ import ( corev1apply "k8s.io/client-go/applyconfigurations/core/v1" "k8s.io/utils/pointer" + "github.com/liqotech/liqo/pkg/utils/testutil" "github.com/liqotech/liqo/pkg/virtualKubelet/forge" ) var _ = Describe("ConfigMaps Forging", func() { Describe("the RemoteConfigMap function", func() { var ( - input *corev1.ConfigMap - output *corev1apply.ConfigMapApplyConfiguration + input *corev1.ConfigMap + output *corev1apply.ConfigMapApplyConfiguration + forgingOpts *forge.ForgingOpts ) BeforeEach(func() { input = &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: "name", Namespace: "original", - Labels: map[string]string{"foo": "bar"}, - Annotations: map[string]string{"bar": "baz"}, + Labels: map[string]string{"foo": "bar", testutil.FakeNotReflectedLabelKey: "true"}, + Annotations: map[string]string{"bar": "baz", testutil.FakeNotReflectedAnnotKey: "true"}, }, Data: map[string]string{"data-key": "data value"}, BinaryData: map[string][]byte{"binary-data-key": []byte("ABC")}, Immutable: pointer.Bool(true), } + + forgingOpts = testutil.FakeForgingOpts() }) - JustBeforeEach(func() { output = forge.RemoteConfigMap(input, "reflected") }) + JustBeforeEach(func() { output = forge.RemoteConfigMap(input, "reflected", forgingOpts) }) It("should correctly set the name and namespace", func() { Expect(output.Name).To(PointTo(Equal("name"))) @@ -57,10 +61,12 @@ var _ = Describe("ConfigMaps Forging", func() { Expect(output.Labels).To(HaveKeyWithValue("foo", "bar")) Expect(output.Labels).To(HaveKeyWithValue(forge.LiqoOriginClusterIDKey, LocalClusterID)) Expect(output.Labels).To(HaveKeyWithValue(forge.LiqoDestinationClusterIDKey, RemoteClusterID)) + Expect(output.Labels).ToNot(HaveKey(testutil.FakeNotReflectedLabelKey)) }) It("should correctly set the annotations", func() { Expect(output.Annotations).To(HaveKeyWithValue("bar", "baz")) + Expect(output.Annotations).ToNot(HaveKey(testutil.FakeNotReflectedAnnotKey)) }) It("should correctly set the data", func() { diff --git a/pkg/virtualKubelet/forge/endpointslices.go b/pkg/virtualKubelet/forge/endpointslices.go index db64d9b1f1..e109574049 100644 --- a/pkg/virtualKubelet/forge/endpointslices.go +++ b/pkg/virtualKubelet/forge/endpointslices.go @@ -74,15 +74,15 @@ func EndpointToBeReflected(endpoint *discoveryv1.Endpoint, localNodeClient corev // RemoteShadowEndpointSlice forges the remote shadowendpointslice, given the local endpointslice. func RemoteShadowEndpointSlice(local *discoveryv1.EndpointSlice, remote *vkv1alpha1.ShadowEndpointSlice, - localNodeClient corev1listers.NodeLister, targetNamespace string, - translator EndpointTranslator) *vkv1alpha1.ShadowEndpointSlice { + localNodeClient corev1listers.NodeLister, targetNamespace string, translator EndpointTranslator, + forgingOpts *ForgingOpts) *vkv1alpha1.ShadowEndpointSlice { if remote == nil { // The remote is nil if not already created. remote = &vkv1alpha1.ShadowEndpointSlice{ObjectMeta: metav1.ObjectMeta{Name: local.GetName(), Namespace: targetNamespace}} } return &vkv1alpha1.ShadowEndpointSlice{ - ObjectMeta: RemoteEndpointSliceObjectMeta(&local.ObjectMeta, &remote.ObjectMeta), + ObjectMeta: RemoteEndpointSliceObjectMeta(&local.ObjectMeta, &remote.ObjectMeta, forgingOpts), Spec: vkv1alpha1.ShadowEndpointSliceSpec{ Template: vkv1alpha1.EndpointSliceTemplate{ AddressType: local.AddressType, @@ -94,9 +94,11 @@ func RemoteShadowEndpointSlice(local *discoveryv1.EndpointSlice, remote *vkv1alp } // RemoteEndpointSliceObjectMeta forges the objectMeta of the reflected endpointslice, given the local one. -func RemoteEndpointSliceObjectMeta(local, remote *metav1.ObjectMeta) metav1.ObjectMeta { +func RemoteEndpointSliceObjectMeta(local, remote *metav1.ObjectMeta, forgingOpts *ForgingOpts) metav1.ObjectMeta { objectMeta := RemoteObjectMeta(local, remote) objectMeta.SetLabels(labels.Merge(objectMeta.Labels, EndpointSliceLabels())) + objectMeta.SetLabels(FilterNotReflected(objectMeta.Labels, forgingOpts.LabelsNotReflected)) + objectMeta.SetAnnotations(FilterNotReflected(objectMeta.Annotations, forgingOpts.AnnotationsNotReflected)) return objectMeta } diff --git a/pkg/virtualKubelet/forge/endpointslices_test.go b/pkg/virtualKubelet/forge/endpointslices_test.go index ce451faa6d..22bcff565c 100644 --- a/pkg/virtualKubelet/forge/endpointslices_test.go +++ b/pkg/virtualKubelet/forge/endpointslices_test.go @@ -27,6 +27,7 @@ import ( vkv1alpha1 "github.com/liqotech/liqo/apis/virtualkubelet/v1alpha1" "github.com/liqotech/liqo/pkg/consts" + "github.com/liqotech/liqo/pkg/utils/testutil" "github.com/liqotech/liqo/pkg/virtualKubelet/forge" ) @@ -63,24 +64,27 @@ var _ = Describe("EndpointSlices Forging", func() { Describe("the RemoteEndpointSlice function", func() { var ( - input *discoveryv1.EndpointSlice - output *vkv1alpha1.ShadowEndpointSlice + input *discoveryv1.EndpointSlice + output *vkv1alpha1.ShadowEndpointSlice + forgingOpts *forge.ForgingOpts ) BeforeEach(func() { input = &discoveryv1.EndpointSlice{ ObjectMeta: metav1.ObjectMeta{ Name: "name", Namespace: "original", - Labels: map[string]string{"foo": "bar"}, - Annotations: map[string]string{"bar": "baz"}, + Labels: map[string]string{"foo": "bar", testutil.FakeNotReflectedLabelKey: "true"}, + Annotations: map[string]string{"bar": "baz", testutil.FakeNotReflectedAnnotKey: "true"}, }, AddressType: discoveryv1.AddressTypeFQDN, Endpoints: []discoveryv1.Endpoint{{Hostname: pointer.String("Test")}}, Ports: []discoveryv1.EndpointPort{{Name: pointer.String("HTTPS")}}, } + forgingOpts = testutil.FakeForgingOpts() + JustBeforeEach(func() { - output = forge.RemoteShadowEndpointSlice(input, output, &FakeNodeLister{}, "reflected", Translator) + output = forge.RemoteShadowEndpointSlice(input, output, &FakeNodeLister{}, "reflected", Translator, forgingOpts) }) It("should correctly set the name and namespace", func() { @@ -93,9 +97,11 @@ var _ = Describe("EndpointSlices Forging", func() { Expect(output.Labels).To(HaveKeyWithValue(forge.LiqoOriginClusterIDKey, LocalClusterID)) Expect(output.Labels).To(HaveKeyWithValue(forge.LiqoDestinationClusterIDKey, RemoteClusterID)) Expect(output.Labels).To(HaveKeyWithValue(discoveryv1.LabelManagedBy, forge.EndpointSliceManagedBy)) + Expect(output.Labels).ToNot(HaveKey(testutil.FakeNotReflectedLabelKey)) }) It("should correctly set the annotations", func() { Expect(output.Annotations).To(HaveKeyWithValue("bar", "baz")) + Expect(output.Annotations).ToNot(HaveKey(testutil.FakeNotReflectedAnnotKey)) }) It("should correctly set the address type", func() { Expect(output.Spec.Template.AddressType).To(PointTo(Equal(discoveryv1.AddressTypeFQDN))) diff --git a/pkg/virtualKubelet/forge/forge.go b/pkg/virtualKubelet/forge/forge.go index 6af5435a3e..16a34514c3 100644 --- a/pkg/virtualKubelet/forge/forge.go +++ b/pkg/virtualKubelet/forge/forge.go @@ -67,3 +67,17 @@ func ApplyOptions() metav1.ApplyOptions { FieldManager: ReflectionFieldManager, } } + +// ForgingOpts contains options to forge the reflected resources. +type ForgingOpts struct { + LabelsNotReflected []string + AnnotationsNotReflected []string +} + +// NewForgingOpts returns a new ForgingOpts instance. +func NewForgingOpts(labelsNotReflected, annotationsNotReflected []string) ForgingOpts { + return ForgingOpts{ + LabelsNotReflected: labelsNotReflected, + AnnotationsNotReflected: annotationsNotReflected, + } +} diff --git a/pkg/virtualKubelet/forge/ingresses.go b/pkg/virtualKubelet/forge/ingresses.go index 45f972b299..4269d33216 100644 --- a/pkg/virtualKubelet/forge/ingresses.go +++ b/pkg/virtualKubelet/forge/ingresses.go @@ -22,10 +22,10 @@ import ( ) // RemoteIngress forges the apply patch for the reflected ingress, given the local one. -func RemoteIngress(local *netv1.Ingress, targetNamespace string) *netv1apply.IngressApplyConfiguration { +func RemoteIngress(local *netv1.Ingress, targetNamespace string, forgingOpts *ForgingOpts) *netv1apply.IngressApplyConfiguration { return netv1apply.Ingress(local.GetName(), targetNamespace). - WithLabels(local.GetLabels()).WithLabels(ReflectionLabels()). - WithAnnotations(FilterIngressAnnotations(local.GetAnnotations())). + WithLabels(FilterNotReflected(local.GetLabels(), forgingOpts.LabelsNotReflected)).WithLabels(ReflectionLabels()). + WithAnnotations(FilterNotReflected(FilterIngressAnnotations(local.GetAnnotations()), forgingOpts.AnnotationsNotReflected)). WithSpec(RemoteIngressSpec(local.Spec.DeepCopy())) } diff --git a/pkg/virtualKubelet/forge/ingresses_test.go b/pkg/virtualKubelet/forge/ingresses_test.go index d94a7224e9..8f27338560 100644 --- a/pkg/virtualKubelet/forge/ingresses_test.go +++ b/pkg/virtualKubelet/forge/ingresses_test.go @@ -23,6 +23,7 @@ import ( netv1apply "k8s.io/client-go/applyconfigurations/networking/v1" "k8s.io/utils/pointer" + "github.com/liqotech/liqo/pkg/utils/testutil" "github.com/liqotech/liqo/pkg/virtualKubelet/forge" ) @@ -74,8 +75,9 @@ var _ = Describe("Ingresses Forging", func() { Describe("the RemoteIngress function", func() { var ( - input *netv1.Ingress - output *netv1apply.IngressApplyConfiguration + input *netv1.Ingress + output *netv1apply.IngressApplyConfiguration + forgingOpts *forge.ForgingOpts ) BeforeEach(func() { @@ -86,10 +88,11 @@ var _ = Describe("Ingresses Forging", func() { Annotations: map[string]string{"bar": "baz", "kubernetes.io/ingress.class": "nginx"}, }, } + forgingOpts = testutil.FakeForgingOpts() ForgeIngressSpec(input) }) - JustBeforeEach(func() { output = forge.RemoteIngress(input, "reflected") }) + JustBeforeEach(func() { output = forge.RemoteIngress(input, "reflected", forgingOpts) }) It("should correctly set the name and namespace", func() { Expect(output.Name).To(PointTo(Equal("name"))) @@ -100,10 +103,12 @@ var _ = Describe("Ingresses Forging", func() { Expect(output.Labels).To(HaveKeyWithValue("foo", "bar")) Expect(output.Labels).To(HaveKeyWithValue(forge.LiqoOriginClusterIDKey, LocalClusterID)) Expect(output.Labels).To(HaveKeyWithValue(forge.LiqoDestinationClusterIDKey, RemoteClusterID)) + Expect(output.Labels).ToNot(HaveKey(testutil.FakeNotReflectedLabelKey)) }) It("should correctly set the annotations", func() { Expect(output.Annotations).To(HaveKeyWithValue("bar", "baz")) Expect(output.Annotations).ToNot(HaveKey("kubernetes.io/ingress.class")) + Expect(output.Annotations).ToNot(HaveKey(testutil.FakeNotReflectedAnnotKey)) }) It("should correctly set the spec", func() { Expect(output.Spec.DefaultBackend).To(PointTo(Equal(netv1apply.IngressBackendApplyConfiguration{ diff --git a/pkg/virtualKubelet/forge/meta.go b/pkg/virtualKubelet/forge/meta.go index 19195100c5..66d5287a89 100644 --- a/pkg/virtualKubelet/forge/meta.go +++ b/pkg/virtualKubelet/forge/meta.go @@ -19,6 +19,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" corev1apply "k8s.io/client-go/applyconfigurations/core/v1" + + "github.com/liqotech/liqo/pkg/utils/maps" ) const ( @@ -91,3 +93,9 @@ func RemoteTypedLocalObjectReference(local *corev1.TypedLocalObjectReference) *c func RemoteKind(kind string) string { return "Remote" + kind } + +// FilterNotReflected returns a map filtering out entries that match the given keys. +func FilterNotReflected(m map[string]string, blackListedKeys []string) map[string]string { + filter := maps.FilterBlacklist(blackListedKeys...) + return maps.Filter(m, filter) +} diff --git a/pkg/virtualKubelet/forge/pods.go b/pkg/virtualKubelet/forge/pods.go index 734918556e..7899e5fc86 100644 --- a/pkg/virtualKubelet/forge/pods.go +++ b/pkg/virtualKubelet/forge/pods.go @@ -147,7 +147,7 @@ func LocalRejectedPodStatus(local *corev1.PodStatus, phase corev1.PodPhase, reas // RemoteShadowPod forges the reflected shadowpod, given the local one. func RemoteShadowPod(local *corev1.Pod, remote *vkv1alpha1.ShadowPod, - targetNamespace string, mutators ...RemotePodSpecMutator) *vkv1alpha1.ShadowPod { + targetNamespace string, forgingOpts *ForgingOpts, mutators ...RemotePodSpecMutator) *vkv1alpha1.ShadowPod { var creation bool if remote == nil { // The remote is nil if not already created. @@ -160,6 +160,10 @@ func RemoteShadowPod(local *corev1.Pod, remote *vkv1alpha1.ShadowPod, delete(localMetaFiltered.GetLabels(), liqoconst.LocalPodLabelKey) localMetaFiltered.GetLabels()[LiqoOriginClusterNodeName] = LiqoNodeName + // Filter out the labels and annotations not to be reflected. + localMetaFiltered.SetLabels(FilterNotReflected(localMetaFiltered.GetLabels(), forgingOpts.LabelsNotReflected)) + localMetaFiltered.SetAnnotations(FilterNotReflected(localMetaFiltered.GetAnnotations(), forgingOpts.AnnotationsNotReflected)) + // Initialize the appropriate anti-affinity mutator if the corresponding annotation is present. switch local.Annotations[liqoconst.PodAntiAffinityPresetKey] { case liqoconst.PodAntiAffinityPresetValuePropagate: diff --git a/pkg/virtualKubelet/forge/pods_test.go b/pkg/virtualKubelet/forge/pods_test.go index 2bdda1dd9c..24235d34ce 100644 --- a/pkg/virtualKubelet/forge/pods_test.go +++ b/pkg/virtualKubelet/forge/pods_test.go @@ -31,6 +31,7 @@ import ( vkv1alpha1 "github.com/liqotech/liqo/apis/virtualkubelet/v1alpha1" "github.com/liqotech/liqo/pkg/consts" + "github.com/liqotech/liqo/pkg/utils/testutil" "github.com/liqotech/liqo/pkg/virtualKubelet/forge" ) @@ -139,32 +140,45 @@ var _ = Describe("Pod forging", func() { var ( local *corev1.Pod remote, output *vkv1alpha1.ShadowPod + forgingOpts *forge.ForgingOpts ) Mutator := func(remote *corev1.PodSpec) { - remote.ActiveDeadlineSeconds = pointer.Int64Ptr(99) + remote.ActiveDeadlineSeconds = pointer.Int64(99) } BeforeEach(func() { local = &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{Name: "local-name", Namespace: "local-namespace", - Labels: map[string]string{"foo": "bar", consts.LocalPodLabelKey: consts.LocalPodLabelValue}}, + Labels: map[string]string{ + "foo": "bar", + consts.LocalPodLabelKey: consts.LocalPodLabelValue, + testutil.FakeNotReflectedLabelKey: "true", + }, + Annotations: map[string]string{ + testutil.FakeNotReflectedAnnotKey: "true", + }, + }, Spec: corev1.PodSpec{TerminationGracePeriodSeconds: pointer.Int64(15)}, } + + forgingOpts = testutil.FakeForgingOpts() }) JustBeforeEach(func() { - output = forge.RemoteShadowPod(local, remote, "remote-namespace", Mutator) + output = forge.RemoteShadowPod(local, remote, "remote-namespace", forgingOpts, Mutator) }) Context("the remote pod does not exist", func() { It("should correctly forge the object meta", func() { Expect(output.GetName()).To(Equal("local-name")) Expect(output.GetNamespace()).To(Equal("remote-namespace")) - Expect(output.GetLabels()).To(HaveKeyWithValue("foo", "bar")) - Expect(output.GetLabels()).ToNot(HaveKeyWithValue(consts.LocalPodLabelKey, consts.LocalPodLabelValue)) + Expect(output.Labels).To(HaveKeyWithValue("foo", "bar")) + Expect(output.Labels).ToNot(HaveKeyWithValue(consts.LocalPodLabelKey, consts.LocalPodLabelValue)) Expect(output.Labels).To(HaveKeyWithValue(forge.LiqoOriginClusterIDKey, LocalClusterID)) Expect(output.Labels).To(HaveKeyWithValue(forge.LiqoDestinationClusterIDKey, RemoteClusterID)) + Expect(output.Labels).ToNot(HaveKey(testutil.FakeNotReflectedLabelKey)) + Expect(output.Annotations).ToNot(HaveKey(testutil.FakeNotReflectedAnnotKey)) }) It("should correctly reflect the pod spec", func() { @@ -187,8 +201,10 @@ var _ = Describe("Pod forging", func() { Expect(output.GetName()).To(Equal("remote-name")) Expect(output.GetNamespace()).To(Equal("remote-namespace")) Expect(output.UID).To(BeEquivalentTo("remote-uid")) - Expect(output.GetLabels()).To(HaveKeyWithValue("foo", "bar")) - Expect(output.GetLabels()).ToNot(HaveKeyWithValue(consts.LocalPodLabelKey, consts.LocalPodLabelValue)) + Expect(output.Labels).To(HaveKeyWithValue("foo", "bar")) + Expect(output.Labels).ToNot(HaveKeyWithValue(consts.LocalPodLabelKey, consts.LocalPodLabelValue)) + Expect(output.Labels).ToNot(HaveKey(testutil.FakeNotReflectedLabelKey)) + Expect(output.Annotations).ToNot(HaveKey(testutil.FakeNotReflectedAnnotKey)) }) It("should not update the pod spec", func() { diff --git a/pkg/virtualKubelet/forge/secrets.go b/pkg/virtualKubelet/forge/secrets.go index ec0ad466c8..ca5ff060c5 100644 --- a/pkg/virtualKubelet/forge/secrets.go +++ b/pkg/virtualKubelet/forge/secrets.go @@ -61,10 +61,10 @@ func IsServiceAccountSecret(obj metav1.Object) bool { } // RemoteSecret forges the apply patch for the reflected secret, given the local one. -func RemoteSecret(local *corev1.Secret, targetNamespace string) *corev1apply.SecretApplyConfiguration { +func RemoteSecret(local *corev1.Secret, targetNamespace string, forgingOpts *ForgingOpts) *corev1apply.SecretApplyConfiguration { applyConfig := corev1apply.Secret(local.GetName(), targetNamespace). - WithLabels(local.GetLabels()).WithLabels(ReflectionLabels()). - WithAnnotations(local.GetAnnotations()). + WithLabels(FilterNotReflected(local.GetLabels(), forgingOpts.LabelsNotReflected)).WithLabels(ReflectionLabels()). + WithAnnotations(FilterNotReflected(local.GetAnnotations(), forgingOpts.AnnotationsNotReflected)). WithData(local.Data). WithType(local.Type) diff --git a/pkg/virtualKubelet/forge/secrets_test.go b/pkg/virtualKubelet/forge/secrets_test.go index 7840f1601c..6d6325ae47 100644 --- a/pkg/virtualKubelet/forge/secrets_test.go +++ b/pkg/virtualKubelet/forge/secrets_test.go @@ -27,30 +27,34 @@ import ( corev1apply "k8s.io/client-go/applyconfigurations/core/v1" "k8s.io/utils/pointer" + "github.com/liqotech/liqo/pkg/utils/testutil" "github.com/liqotech/liqo/pkg/virtualKubelet/forge" ) var _ = Describe("Secrets Forging", func() { Describe("the RemoteSecret function", func() { var ( - input *corev1.Secret - output *corev1apply.SecretApplyConfiguration + input *corev1.Secret + output *corev1apply.SecretApplyConfiguration + forgingOpts *forge.ForgingOpts ) BeforeEach(func() { input = &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "name", Namespace: "original", - Labels: map[string]string{"foo": "bar"}, - Annotations: map[string]string{"bar": "baz"}, + Labels: map[string]string{"foo": "bar", testutil.FakeNotReflectedLabelKey: "true"}, + Annotations: map[string]string{"bar": "baz", testutil.FakeNotReflectedAnnotKey: "true"}, }, Data: map[string][]byte{"data-key": []byte("ABC")}, Type: corev1.SecretTypeBasicAuth, Immutable: pointer.Bool(true), } + + forgingOpts = testutil.FakeForgingOpts() }) - JustBeforeEach(func() { output = forge.RemoteSecret(input, "reflected") }) + JustBeforeEach(func() { output = forge.RemoteSecret(input, "reflected", forgingOpts) }) It("should correctly set the name and namespace", func() { Expect(output.Name).To(PointTo(Equal("name"))) @@ -61,10 +65,12 @@ var _ = Describe("Secrets Forging", func() { Expect(output.Labels).To(HaveKeyWithValue("foo", "bar")) Expect(output.Labels).To(HaveKeyWithValue(forge.LiqoOriginClusterIDKey, LocalClusterID)) Expect(output.Labels).To(HaveKeyWithValue(forge.LiqoDestinationClusterIDKey, RemoteClusterID)) + Expect(output.Labels).ToNot(HaveKey(testutil.FakeNotReflectedLabelKey)) }) It("should correctly set the annotations", func() { Expect(output.Annotations).To(HaveKeyWithValue("bar", "baz")) + Expect(output.Annotations).ToNot(HaveKey(testutil.FakeNotReflectedAnnotKey)) }) It("should correctly set the data", func() { diff --git a/pkg/virtualKubelet/forge/services.go b/pkg/virtualKubelet/forge/services.go index 42023d0a07..e75ff85b29 100644 --- a/pkg/virtualKubelet/forge/services.go +++ b/pkg/virtualKubelet/forge/services.go @@ -26,10 +26,10 @@ import ( const nodePortUnset = 0 // RemoteService forges the apply patch for the reflected service, given the local one. -func RemoteService(local *corev1.Service, targetNamespace string) *corev1apply.ServiceApplyConfiguration { +func RemoteService(local *corev1.Service, targetNamespace string, forgingOpts *ForgingOpts) *corev1apply.ServiceApplyConfiguration { return corev1apply.Service(local.GetName(), targetNamespace). - WithLabels(local.GetLabels()).WithLabels(ReflectionLabels()). - WithAnnotations(local.GetAnnotations()). + WithLabels(FilterNotReflected(local.GetLabels(), forgingOpts.LabelsNotReflected)).WithLabels(ReflectionLabels()). + WithAnnotations(FilterNotReflected(local.GetAnnotations(), forgingOpts.AnnotationsNotReflected)). WithSpec(RemoteServiceSpec(local.Spec.DeepCopy(), getForceRemoteNodePort(local))) } diff --git a/pkg/virtualKubelet/forge/services_test.go b/pkg/virtualKubelet/forge/services_test.go index fcb3dafecd..453cf794c0 100644 --- a/pkg/virtualKubelet/forge/services_test.go +++ b/pkg/virtualKubelet/forge/services_test.go @@ -24,27 +24,31 @@ import ( corev1apply "k8s.io/client-go/applyconfigurations/core/v1" "k8s.io/utils/pointer" + "github.com/liqotech/liqo/pkg/utils/testutil" "github.com/liqotech/liqo/pkg/virtualKubelet/forge" ) var _ = Describe("Services Forging", func() { Describe("the RemoteService function", func() { var ( - input *corev1.Service - output *corev1apply.ServiceApplyConfiguration + input *corev1.Service + output *corev1apply.ServiceApplyConfiguration + forgingOpts *forge.ForgingOpts ) BeforeEach(func() { input = &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: "name", Namespace: "original", - Labels: map[string]string{"foo": "bar"}, - Annotations: map[string]string{"bar": "baz"}, + Labels: map[string]string{"foo": "bar", testutil.FakeNotReflectedLabelKey: "true"}, + Annotations: map[string]string{"bar": "baz", testutil.FakeNotReflectedAnnotKey: "true"}, }, Spec: corev1.ServiceSpec{Type: corev1.ServiceTypeNodePort}, } - JustBeforeEach(func() { output = forge.RemoteService(input, "reflected") }) + forgingOpts = testutil.FakeForgingOpts() + + JustBeforeEach(func() { output = forge.RemoteService(input, "reflected", forgingOpts) }) It("should correctly set the name and namespace", func() { Expect(output.Name).To(PointTo(Equal("name"))) @@ -55,9 +59,11 @@ var _ = Describe("Services Forging", func() { Expect(output.Labels).To(HaveKeyWithValue("foo", "bar")) Expect(output.Labels).To(HaveKeyWithValue(forge.LiqoOriginClusterIDKey, LocalClusterID)) Expect(output.Labels).To(HaveKeyWithValue(forge.LiqoDestinationClusterIDKey, RemoteClusterID)) + Expect(output.Labels).ToNot(HaveKey(testutil.FakeNotReflectedLabelKey)) }) It("should correctly set the annotations", func() { Expect(output.Annotations).To(HaveKeyWithValue("bar", "baz")) + Expect(output.Annotations).ToNot(HaveKey(testutil.FakeNotReflectedAnnotKey)) }) It("should correctly set the spec", func() { Expect(output.Spec.Type).To(PointTo(Equal(corev1.ServiceTypeNodePort))) diff --git a/pkg/virtualKubelet/provider/provider.go b/pkg/virtualKubelet/provider/provider.go index fee7e4897d..aaf164436a 100644 --- a/pkg/virtualKubelet/provider/provider.go +++ b/pkg/virtualKubelet/provider/provider.go @@ -81,6 +81,9 @@ type InitConfig struct { HomeAPIServerHost string HomeAPIServerPort string + + LabelsNotReflected []string + AnnotationsNotReflected []string } // LiqoProvider implements the virtual-kubelet provider interface and stores pods in memory. @@ -133,7 +136,8 @@ func NewLiqoProvider(ctx context.Context, cfg *InitConfig, eb record.EventBroadc } podreflector := workload.NewPodReflector(cfg.RemoteConfig, remoteMetricsClient, ipamClient, &podReflectorConfig, cfg.PodWorkers) - reflectionManager := manager.New(localClient, remoteClient, localLiqoClient, remoteLiqoClient, cfg.InformerResyncPeriod, eb). + reflectionManager := manager.New(localClient, remoteClient, localLiqoClient, remoteLiqoClient, + cfg.InformerResyncPeriod, eb, cfg.LabelsNotReflected, cfg.AnnotationsNotReflected). With(podreflector). With(exposition.NewServiceReflector(cfg.ServiceWorkers)). With(exposition.NewIngressReflector(cfg.IngressWorkers)). diff --git a/pkg/virtualKubelet/reflection/configuration/configmap.go b/pkg/virtualKubelet/reflection/configuration/configmap.go index ae3d10470f..cadfd2c981 100644 --- a/pkg/virtualKubelet/reflection/configuration/configmap.go +++ b/pkg/virtualKubelet/reflection/configuration/configmap.go @@ -134,7 +134,7 @@ func (ncr *NamespacedConfigMapReflector) Handle(ctx context.Context, name string } // Forge the mutation to be applied to the remote cluster. - mutation := forge.RemoteConfigMap(local, ncr.RemoteNamespace()) + mutation := forge.RemoteConfigMap(local, ncr.RemoteNamespace(), ncr.ForgingOpts) tracer.Step("Remote mutation created") defer tracer.Step("Enforced the correctness of the remote object") diff --git a/pkg/virtualKubelet/reflection/configuration/configmap_test.go b/pkg/virtualKubelet/reflection/configuration/configmap_test.go index 081e73daa1..95f2d305e5 100644 --- a/pkg/virtualKubelet/reflection/configuration/configmap_test.go +++ b/pkg/virtualKubelet/reflection/configuration/configmap_test.go @@ -22,6 +22,7 @@ import ( corev1 "k8s.io/api/core/v1" kerrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/informers" "k8s.io/client-go/tools/record" "k8s.io/utils/trace" @@ -100,7 +101,8 @@ var _ = Describe("ConfigMap Reflection", func() { WithLocal(LocalNamespace, client, factory). WithRemote(RemoteNamespace, client, factory). WithHandlerFactory(FakeEventHandler). - WithEventBroadcaster(record.NewBroadcaster())) + WithEventBroadcaster(record.NewBroadcaster()). + WithForgingOpts(FakeForgingOpts())) factory.Start(ctx.Done()) factory.WaitForCacheSync(ctx.Done()) @@ -115,8 +117,8 @@ var _ = Describe("ConfigMap Reflection", func() { When("the local object does exists", func() { BeforeEach(func() { - local.SetLabels(map[string]string{"foo": "bar"}) - local.SetAnnotations(map[string]string{"bar": "baz"}) + local.SetLabels(map[string]string{"foo": "bar", FakeNotReflectedLabelKey: "true"}) + local.SetAnnotations(map[string]string{"bar": "baz", FakeNotReflectedAnnotKey: "true"}) local.Data = map[string]string{"data-key": "some config data"} CreateConfigMap(&local) }) @@ -129,7 +131,10 @@ var _ = Describe("ConfigMap Reflection", func() { Expect(remoteAfter.Labels).To(HaveKeyWithValue(forge.LiqoOriginClusterIDKey, LocalClusterID)) Expect(remoteAfter.Labels).To(HaveKeyWithValue(forge.LiqoDestinationClusterIDKey, RemoteClusterID)) Expect(remoteAfter.Labels).To(HaveKeyWithValue("foo", "bar")) + Expect(remoteAfter.Labels).ToNot(HaveKey(FakeNotReflectedLabelKey)) Expect(remoteAfter.Annotations).To(HaveKeyWithValue("bar", "baz")) + Expect(remoteAfter.Annotations).ToNot(HaveKey(FakeNotReflectedAnnotKey)) + }) It("the spec should have been correctly replicated to the remote object", func() { @@ -141,8 +146,8 @@ var _ = Describe("ConfigMap Reflection", func() { When("the remote object already exists", func() { BeforeEach(func() { - remote.SetLabels(forge.ReflectionLabels()) - remote.SetAnnotations(map[string]string{"bar": "previous", "existing": "existing"}) + remote.SetLabels(labels.Merge(forge.ReflectionLabels(), map[string]string{FakeNotReflectedLabelKey: "true"})) + remote.SetAnnotations(map[string]string{"bar": "previous", "existing": "existing", FakeNotReflectedAnnotKey: "true"}) remote.Data = map[string]string{"data-key": "some remote config data"} CreateConfigMap(&remote) }) @@ -154,8 +159,10 @@ var _ = Describe("ConfigMap Reflection", func() { Expect(remoteAfter.Labels).To(HaveKeyWithValue(forge.LiqoOriginClusterIDKey, LocalClusterID)) Expect(remoteAfter.Labels).To(HaveKeyWithValue(forge.LiqoDestinationClusterIDKey, RemoteClusterID)) Expect(remoteAfter.Labels).To(HaveKeyWithValue("foo", "bar")) + Expect(remoteAfter.Labels).To(HaveKey(FakeNotReflectedLabelKey)) Expect(remoteAfter.Annotations).To(HaveKeyWithValue("bar", "baz")) Expect(remoteAfter.Annotations).To(HaveKeyWithValue("existing", "existing")) + Expect(remoteAfter.Annotations).To(HaveKey(FakeNotReflectedAnnotKey)) }) It("the spec should have been correctly replicated to the remote object", func() { diff --git a/pkg/virtualKubelet/reflection/configuration/secret.go b/pkg/virtualKubelet/reflection/configuration/secret.go index 31fd69584d..732c10cb21 100644 --- a/pkg/virtualKubelet/reflection/configuration/secret.go +++ b/pkg/virtualKubelet/reflection/configuration/secret.go @@ -137,7 +137,7 @@ func (nsr *NamespacedSecretReflector) Handle(ctx context.Context, name string) e } // Forge the mutation to be applied to the remote cluster. - mutation := forge.RemoteSecret(local, nsr.RemoteNamespace()) + mutation := forge.RemoteSecret(local, nsr.RemoteNamespace(), nsr.ForgingOpts) tracer.Step("Remote mutation created") defer tracer.Step("Enforced the correctness of the remote object") diff --git a/pkg/virtualKubelet/reflection/configuration/secret_test.go b/pkg/virtualKubelet/reflection/configuration/secret_test.go index d3cce0d2e5..9bc0e4f727 100644 --- a/pkg/virtualKubelet/reflection/configuration/secret_test.go +++ b/pkg/virtualKubelet/reflection/configuration/secret_test.go @@ -103,7 +103,8 @@ var _ = Describe("Secret Reflection", func() { WithLocal(LocalNamespace, client, factory). WithRemote(RemoteNamespace, client, factory). WithHandlerFactory(FakeEventHandler). - WithEventBroadcaster(record.NewBroadcaster())) + WithEventBroadcaster(record.NewBroadcaster()). + WithForgingOpts(FakeForgingOpts())) factory.Start(ctx.Done()) factory.WaitForCacheSync(ctx.Done()) @@ -118,8 +119,8 @@ var _ = Describe("Secret Reflection", func() { When("the local object does exists", func() { BeforeEach(func() { - local.SetLabels(map[string]string{"foo": "bar"}) - local.SetAnnotations(map[string]string{"bar": "baz"}) + local.SetLabels(map[string]string{"foo": "bar", FakeNotReflectedLabelKey: "true"}) + local.SetAnnotations(map[string]string{"bar": "baz", FakeNotReflectedAnnotKey: "true"}) local.Data = map[string][]byte{"data-key": []byte("some secret data")} CreateSecret(&local) }) @@ -132,7 +133,9 @@ var _ = Describe("Secret Reflection", func() { Expect(remoteAfter.Labels).To(HaveKeyWithValue(forge.LiqoOriginClusterIDKey, LocalClusterID)) Expect(remoteAfter.Labels).To(HaveKeyWithValue(forge.LiqoDestinationClusterIDKey, RemoteClusterID)) Expect(remoteAfter.Labels).To(HaveKeyWithValue("foo", "bar")) + Expect(remoteAfter.Labels).ToNot(HaveKey(FakeNotReflectedLabelKey)) Expect(remoteAfter.Annotations).To(HaveKeyWithValue("bar", "baz")) + Expect(remoteAfter.Annotations).ToNot(HaveKey(FakeNotReflectedAnnotKey)) }) It("the spec should have been correctly replicated to the remote object", func() { @@ -144,8 +147,8 @@ var _ = Describe("Secret Reflection", func() { When("the remote object already exists", func() { BeforeEach(func() { - remote.SetLabels(forge.ReflectionLabels()) - remote.SetAnnotations(map[string]string{"bar": "previous", "existing": "existing"}) + remote.SetLabels(labels.Merge(forge.ReflectionLabels(), map[string]string{FakeNotReflectedLabelKey: "true"})) + remote.SetAnnotations(map[string]string{"bar": "previous", "existing": "existing", FakeNotReflectedAnnotKey: "true"}) remote.Data = map[string][]byte{"data-key": []byte("some secret data")} CreateSecret(&remote) }) @@ -157,8 +160,10 @@ var _ = Describe("Secret Reflection", func() { Expect(remoteAfter.Labels).To(HaveKeyWithValue(forge.LiqoOriginClusterIDKey, LocalClusterID)) Expect(remoteAfter.Labels).To(HaveKeyWithValue(forge.LiqoDestinationClusterIDKey, RemoteClusterID)) Expect(remoteAfter.Labels).To(HaveKeyWithValue("foo", "bar")) + Expect(remoteAfter.Labels).To(HaveKey(FakeNotReflectedLabelKey)) Expect(remoteAfter.Annotations).To(HaveKeyWithValue("bar", "baz")) Expect(remoteAfter.Annotations).To(HaveKeyWithValue("existing", "existing")) + Expect(remoteAfter.Annotations).To(HaveKey(FakeNotReflectedAnnotKey)) }) It("the spec should have been correctly replicated to the remote object", func() { diff --git a/pkg/virtualKubelet/reflection/event/event.go b/pkg/virtualKubelet/reflection/event/event.go index 64a8f97ddb..de31eb8509 100644 --- a/pkg/virtualKubelet/reflection/event/event.go +++ b/pkg/virtualKubelet/reflection/event/event.go @@ -170,8 +170,8 @@ func (ner *NamespacedEventReflector) Handle(ctx context.Context, name string) er ObjectMeta: metav1.ObjectMeta{ Name: remote.Name, Namespace: ner.LocalNamespace(), - Labels: labels.Merge(remote.GetLabels(), forge.ReflectionLabels()), - Annotations: remote.GetAnnotations(), + Labels: labels.Merge(forge.FilterNotReflected(remote.GetLabels(), ner.ForgingOpts.LabelsNotReflected), forge.ReflectionLabels()), + Annotations: forge.FilterNotReflected(remote.GetAnnotations(), ner.ForgingOpts.AnnotationsNotReflected), }, InvolvedObject: corev1.ObjectReference{ APIVersion: remote.InvolvedObject.APIVersion, diff --git a/pkg/virtualKubelet/reflection/event/event_test.go b/pkg/virtualKubelet/reflection/event/event_test.go index f6b57d4c18..5371fb8a04 100644 --- a/pkg/virtualKubelet/reflection/event/event_test.go +++ b/pkg/virtualKubelet/reflection/event/event_test.go @@ -166,7 +166,8 @@ var _ = Describe("Event Reflection Tests", func() { WithLocal(LocalNamespace, client, factory). WithRemote(RemoteNamespace, client, factory). WithHandlerFactory(FakeEventHandler). - WithEventBroadcaster(record.NewBroadcaster())) + WithEventBroadcaster(record.NewBroadcaster()). + WithForgingOpts(FakeForgingOpts())) factory.Start(ctx.Done()) factory.WaitForCacheSync(ctx.Done()) @@ -181,8 +182,8 @@ var _ = Describe("Event Reflection Tests", func() { When("the remote object does exist", func() { BeforeEach(func() { - remote.SetLabels(map[string]string{"foo": "bar"}) - remote.SetAnnotations(map[string]string{"bar": "baz"}) + remote.SetLabels(map[string]string{"foo": "bar", FakeNotReflectedLabelKey: "true"}) + remote.SetAnnotations(map[string]string{"bar": "baz", FakeNotReflectedAnnotKey: "true"}) ForgeEvent(&remote, true) CreateEvent(&remote) }) @@ -194,7 +195,9 @@ var _ = Describe("Event Reflection Tests", func() { Expect(localAfter.Labels).To(HaveKeyWithValue(forge.LiqoOriginClusterIDKey, LocalClusterID)) Expect(localAfter.Labels).To(HaveKeyWithValue(forge.LiqoDestinationClusterIDKey, RemoteClusterID)) Expect(localAfter.Labels).To(HaveKeyWithValue("foo", "bar")) + Expect(localAfter.Labels).ToNot(HaveKey(FakeNotReflectedLabelKey)) Expect(localAfter.Annotations).To(HaveKeyWithValue("bar", "baz")) + Expect(localAfter.Annotations).ToNot(HaveKey(FakeNotReflectedAnnotKey)) }) It("the spec should have been correctly replicated to the local object", func() { localAfter := GetEvent(LocalNamespace) diff --git a/pkg/virtualKubelet/reflection/exposition/endpointslice.go b/pkg/virtualKubelet/reflection/exposition/endpointslice.go index 752fcddc7e..c3e80d0eb8 100644 --- a/pkg/virtualKubelet/reflection/exposition/endpointslice.go +++ b/pkg/virtualKubelet/reflection/exposition/endpointslice.go @@ -181,7 +181,7 @@ func (ner *NamespacedEndpointSliceReflector) Handle(ctx context.Context, name st return translations } - target := forge.RemoteShadowEndpointSlice(local, remote, ner.localNodeClient, ner.RemoteNamespace(), translator) + target := forge.RemoteShadowEndpointSlice(local, remote, ner.localNodeClient, ner.RemoteNamespace(), translator, ner.ForgingOpts) if terr != nil { klog.Errorf("Reflection of local EndpointSlice %q to %q failed: %v", ner.LocalRef(name), ner.RemoteRef(name), terr) ner.Event(local, corev1.EventTypeWarning, forge.EventFailedReflection, forge.EventFailedReflectionMsg(terr)) diff --git a/pkg/virtualKubelet/reflection/exposition/endpointslice_test.go b/pkg/virtualKubelet/reflection/exposition/endpointslice_test.go index 345c01b27b..dea4fb31ca 100644 --- a/pkg/virtualKubelet/reflection/exposition/endpointslice_test.go +++ b/pkg/virtualKubelet/reflection/exposition/endpointslice_test.go @@ -132,7 +132,8 @@ var _ = Describe("EndpointSlice Reflection Tests", func() { WithRemote(RemoteNamespace, client, factory). WithLiqoRemote(liqoClient, liqoFactory). WithHandlerFactory(FakeEventHandler). - WithEventBroadcaster(record.NewBroadcaster())) + WithEventBroadcaster(record.NewBroadcaster()). + WithForgingOpts(FakeForgingOpts())) factory.Start(ctx.Done()) liqoFactory.Start(ctx.Done()) @@ -152,8 +153,8 @@ var _ = Describe("EndpointSlice Reflection Tests", func() { When("the local object does exist", func() { BeforeEach(func() { - local.SetLabels(map[string]string{"foo": "bar"}) - local.SetAnnotations(map[string]string{"bar": "baz"}) + local.SetLabels(map[string]string{"foo": "bar", FakeNotReflectedLabelKey: "true"}) + local.SetAnnotations(map[string]string{"bar": "baz", FakeNotReflectedAnnotKey: "true"}) local.AddressType = discoveryv1.AddressTypeIPv4 local.Endpoints = []discoveryv1.Endpoint{{ NodeName: pointer.String(LocalClusterNodeName), @@ -170,7 +171,9 @@ var _ = Describe("EndpointSlice Reflection Tests", func() { Expect(remoteAfter.Labels).To(HaveKeyWithValue(forge.LiqoDestinationClusterIDKey, RemoteClusterID)) Expect(remoteAfter.Labels).To(HaveKeyWithValue(discoveryv1.LabelManagedBy, forge.EndpointSliceManagedBy)) Expect(remoteAfter.Labels).To(HaveKeyWithValue("foo", "bar")) + Expect(remoteAfter.Labels).ToNot(HaveKey(FakeNotReflectedLabelKey)) Expect(remoteAfter.Annotations).To(HaveKeyWithValue("bar", "baz")) + Expect(remoteAfter.Annotations).ToNot(HaveKey(FakeNotReflectedAnnotKey)) }) It("the spec should have been correctly replicated to the remote object", func() { remoteAfter := GetShadowEndpointSlice(RemoteNamespace) @@ -185,7 +188,8 @@ var _ = Describe("EndpointSlice Reflection Tests", func() { BeforeEach(func() { remote.SetLabels(labels.Merge(forge.ReflectionLabels(), forge.EndpointSliceLabels())) remote.SetLabels(labels.Merge(remote.GetLabels(), map[string]string{"foo": "previous", "existing": "existing"})) - remote.SetAnnotations(map[string]string{"bar": "previous", "existing": "existing"}) + remote.SetLabels(labels.Merge(remote.GetLabels(), map[string]string{FakeNotReflectedLabelKey: "true"})) + remote.SetAnnotations(map[string]string{"bar": "previous", "existing": "existing", FakeNotReflectedAnnotKey: "true"}) remote.Spec.Template.AddressType = discoveryv1.AddressTypeIPv4 CreateShadowEndpointSlice(&remote) }) @@ -198,8 +202,10 @@ var _ = Describe("EndpointSlice Reflection Tests", func() { Expect(remoteAfter.Labels).To(HaveKeyWithValue(discoveryv1.LabelManagedBy, forge.EndpointSliceManagedBy)) Expect(remoteAfter.Labels).To(HaveKeyWithValue("foo", "bar")) Expect(remoteAfter.Labels).ToNot(HaveKey("existing")) + Expect(remoteAfter.Labels).ToNot(HaveKey(FakeNotReflectedLabelKey)) Expect(remoteAfter.Annotations).To(HaveKeyWithValue("bar", "baz")) Expect(remoteAfter.Annotations).ToNot(HaveKey("existing")) + Expect(remoteAfter.Annotations).ToNot(HaveKey(FakeNotReflectedAnnotKey)) }) It("the spec should have been correctly replicated to the remote object", func() { remoteAfter := GetShadowEndpointSlice(RemoteNamespace) diff --git a/pkg/virtualKubelet/reflection/exposition/ingress.go b/pkg/virtualKubelet/reflection/exposition/ingress.go index 69b81d3730..7cbbc2d123 100644 --- a/pkg/virtualKubelet/reflection/exposition/ingress.go +++ b/pkg/virtualKubelet/reflection/exposition/ingress.go @@ -121,7 +121,7 @@ func (nir *NamespacedIngressReflector) Handle(ctx context.Context, name string) } // Forge the mutation to be applied to the remote cluster. - mutation := forge.RemoteIngress(local, nir.RemoteNamespace()) + mutation := forge.RemoteIngress(local, nir.RemoteNamespace(), nir.ForgingOpts) tracer.Step("Remote mutation created") defer tracer.Step("Enforced the correctness of the remote object") diff --git a/pkg/virtualKubelet/reflection/exposition/ingress_test.go b/pkg/virtualKubelet/reflection/exposition/ingress_test.go index 242c6a6826..0b0cf8ac5f 100644 --- a/pkg/virtualKubelet/reflection/exposition/ingress_test.go +++ b/pkg/virtualKubelet/reflection/exposition/ingress_test.go @@ -22,6 +22,7 @@ import ( netv1 "k8s.io/api/networking/v1" kerrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/informers" "k8s.io/client-go/tools/record" "k8s.io/utils/trace" @@ -112,7 +113,8 @@ var _ = Describe("Ingress Reflection Tests", func() { WithLocal(LocalNamespace, client, factory). WithRemote(RemoteNamespace, client, factory). WithHandlerFactory(FakeEventHandler). - WithEventBroadcaster(record.NewBroadcaster())) + WithEventBroadcaster(record.NewBroadcaster()). + WithForgingOpts(FakeForgingOpts())) factory.Start(ctx.Done()) factory.WaitForCacheSync(ctx.Done()) @@ -127,8 +129,8 @@ var _ = Describe("Ingress Reflection Tests", func() { When("the local object does exist", func() { BeforeEach(func() { - local.SetLabels(map[string]string{"foo": "bar"}) - local.SetAnnotations(map[string]string{"bar": "baz"}) + local.SetLabels(map[string]string{"foo": "bar", FakeNotReflectedLabelKey: "true"}) + local.SetAnnotations(map[string]string{"bar": "baz", FakeNotReflectedAnnotKey: "true"}) ForgeIngressSpec(&local) CreateIngress(&local) }) @@ -140,7 +142,9 @@ var _ = Describe("Ingress Reflection Tests", func() { Expect(remoteAfter.Labels).To(HaveKeyWithValue(forge.LiqoOriginClusterIDKey, LocalClusterID)) Expect(remoteAfter.Labels).To(HaveKeyWithValue(forge.LiqoDestinationClusterIDKey, RemoteClusterID)) Expect(remoteAfter.Labels).To(HaveKeyWithValue("foo", "bar")) + Expect(remoteAfter.Labels).ToNot(HaveKey(FakeNotReflectedLabelKey)) Expect(remoteAfter.Annotations).To(HaveKeyWithValue("bar", "baz")) + Expect(remoteAfter.Annotations).ToNot(HaveKey(FakeNotReflectedAnnotKey)) }) It("the spec should have been correctly replicated to the remote object", func() { remoteAfter := GetIngress(RemoteNamespace) @@ -151,8 +155,8 @@ var _ = Describe("Ingress Reflection Tests", func() { When("the remote object already exists", func() { BeforeEach(func() { - remote.SetLabels(forge.ReflectionLabels()) - remote.SetAnnotations(map[string]string{"bar": "previous", "existing": "existing"}) + remote.SetLabels(labels.Merge(forge.ReflectionLabels(), map[string]string{FakeNotReflectedLabelKey: "true"})) + remote.SetAnnotations(map[string]string{"bar": "previous", "existing": "existing", FakeNotReflectedAnnotKey: "true"}) ForgeIngressSpec(&remote) CreateIngress(&remote) }) @@ -163,8 +167,10 @@ var _ = Describe("Ingress Reflection Tests", func() { Expect(remoteAfter.Labels).To(HaveKeyWithValue(forge.LiqoOriginClusterIDKey, LocalClusterID)) Expect(remoteAfter.Labels).To(HaveKeyWithValue(forge.LiqoDestinationClusterIDKey, RemoteClusterID)) Expect(remoteAfter.Labels).To(HaveKeyWithValue("foo", "bar")) + Expect(remoteAfter.Labels).To(HaveKey(FakeNotReflectedLabelKey)) Expect(remoteAfter.Annotations).To(HaveKeyWithValue("bar", "baz")) Expect(remoteAfter.Annotations).To(HaveKeyWithValue("existing", "existing")) + Expect(remoteAfter.Annotations).To(HaveKey(FakeNotReflectedAnnotKey)) }) It("the spec should have been correctly replicated to the remote object", func() { remoteAfter := GetIngress(RemoteNamespace) diff --git a/pkg/virtualKubelet/reflection/exposition/service.go b/pkg/virtualKubelet/reflection/exposition/service.go index d57ecb5327..9fe0ce692f 100644 --- a/pkg/virtualKubelet/reflection/exposition/service.go +++ b/pkg/virtualKubelet/reflection/exposition/service.go @@ -129,7 +129,7 @@ func (nsr *NamespacedServiceReflector) Handle(ctx context.Context, name string) } // Forge the mutation to be applied to the remote cluster. - mutation := forge.RemoteService(local, nsr.RemoteNamespace()) + mutation := forge.RemoteService(local, nsr.RemoteNamespace(), nsr.ForgingOpts) tracer.Step("Remote mutation created") defer tracer.Step("Enforced the correctness of the remote object") diff --git a/pkg/virtualKubelet/reflection/exposition/service_test.go b/pkg/virtualKubelet/reflection/exposition/service_test.go index d136a8543c..b1365d0dad 100644 --- a/pkg/virtualKubelet/reflection/exposition/service_test.go +++ b/pkg/virtualKubelet/reflection/exposition/service_test.go @@ -22,6 +22,7 @@ import ( corev1 "k8s.io/api/core/v1" kerrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/client-go/informers" "k8s.io/client-go/tools/record" @@ -100,7 +101,8 @@ var _ = Describe("Service Reflection Tests", func() { WithLocal(LocalNamespace, client, factory). WithRemote(RemoteNamespace, client, factory). WithHandlerFactory(FakeEventHandler). - WithEventBroadcaster(record.NewBroadcaster())) + WithEventBroadcaster(record.NewBroadcaster()). + WithForgingOpts(FakeForgingOpts())) factory.Start(ctx.Done()) factory.WaitForCacheSync(ctx.Done()) @@ -115,8 +117,8 @@ var _ = Describe("Service Reflection Tests", func() { When("the local object does exist", func() { BeforeEach(func() { - local.SetLabels(map[string]string{"foo": "bar"}) - local.SetAnnotations(map[string]string{"bar": "baz"}) + local.SetLabels(map[string]string{"foo": "bar", FakeNotReflectedLabelKey: "true"}) + local.SetAnnotations(map[string]string{"bar": "baz", FakeNotReflectedAnnotKey: "true"}) local.Spec = corev1.ServiceSpec{ Type: corev1.ServiceTypeLoadBalancer, Ports: []corev1.ServicePort{{Name: "http", Port: 80, TargetPort: intstr.FromInt(8080)}}, @@ -131,7 +133,9 @@ var _ = Describe("Service Reflection Tests", func() { Expect(remoteAfter.Labels).To(HaveKeyWithValue(forge.LiqoOriginClusterIDKey, LocalClusterID)) Expect(remoteAfter.Labels).To(HaveKeyWithValue(forge.LiqoDestinationClusterIDKey, RemoteClusterID)) Expect(remoteAfter.Labels).To(HaveKeyWithValue("foo", "bar")) + Expect(remoteAfter.Labels).ToNot(HaveKey(FakeNotReflectedLabelKey)) Expect(remoteAfter.Annotations).To(HaveKeyWithValue("bar", "baz")) + Expect(remoteAfter.Annotations).ToNot(HaveKey(FakeNotReflectedAnnotKey)) }) It("the spec should have been correctly replicated to the remote object", func() { remoteAfter := GetService(RemoteNamespace) @@ -142,8 +146,8 @@ var _ = Describe("Service Reflection Tests", func() { When("the remote object already exists", func() { BeforeEach(func() { - remote.SetLabels(forge.ReflectionLabels()) - remote.SetAnnotations(map[string]string{"bar": "previous", "existing": "existing"}) + remote.SetLabels(labels.Merge(forge.ReflectionLabels(), map[string]string{FakeNotReflectedLabelKey: "true"})) + remote.SetAnnotations(map[string]string{"bar": "previous", "existing": "existing", FakeNotReflectedAnnotKey: "true"}) remote.Spec.Ports = []corev1.ServicePort{{Name: "http", Port: 80, TargetPort: intstr.FromInt(8080)}} CreateService(&remote) }) @@ -154,8 +158,10 @@ var _ = Describe("Service Reflection Tests", func() { Expect(remoteAfter.Labels).To(HaveKeyWithValue(forge.LiqoOriginClusterIDKey, LocalClusterID)) Expect(remoteAfter.Labels).To(HaveKeyWithValue(forge.LiqoDestinationClusterIDKey, RemoteClusterID)) Expect(remoteAfter.Labels).To(HaveKeyWithValue("foo", "bar")) + Expect(remoteAfter.Labels).To(HaveKey(FakeNotReflectedLabelKey)) Expect(remoteAfter.Annotations).To(HaveKeyWithValue("bar", "baz")) Expect(remoteAfter.Annotations).To(HaveKeyWithValue("existing", "existing")) + Expect(remoteAfter.Annotations).To(HaveKey(FakeNotReflectedAnnotKey)) }) It("the spec should have been correctly replicated to the remote object", func() { remoteAfter := GetService(RemoteNamespace) diff --git a/pkg/virtualKubelet/reflection/generic/namespaced.go b/pkg/virtualKubelet/reflection/generic/namespaced.go index e0bcfbef11..ad7898e6a2 100644 --- a/pkg/virtualKubelet/reflection/generic/namespaced.go +++ b/pkg/virtualKubelet/reflection/generic/namespaced.go @@ -27,6 +27,7 @@ import ( "k8s.io/klog/v2" "github.com/liqotech/liqo/pkg/consts" + "github.com/liqotech/liqo/pkg/virtualKubelet/forge" "github.com/liqotech/liqo/pkg/virtualKubelet/reflection/options" ) @@ -38,6 +39,8 @@ type NamespacedReflector struct { local string remote string + + ForgingOpts *forge.ForgingOpts } // ResourceDeleter know how to delete a Kubernetes object with the given name. @@ -49,7 +52,7 @@ type ResourceDeleter interface { func NewNamespacedReflector(opts *options.NamespacedOpts, name string) NamespacedReflector { return NamespacedReflector{ EventRecorder: opts.EventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: "liqo-" + strings.ToLower(name) + "-reflection"}), - local: opts.LocalNamespace, remote: opts.RemoteNamespace, ready: opts.Ready, + local: opts.LocalNamespace, remote: opts.RemoteNamespace, ready: opts.Ready, ForgingOpts: opts.ForgingOpts, } } diff --git a/pkg/virtualKubelet/reflection/generic/namespaced_test.go b/pkg/virtualKubelet/reflection/generic/namespaced_test.go index 1993248a19..d57c939559 100644 --- a/pkg/virtualKubelet/reflection/generic/namespaced_test.go +++ b/pkg/virtualKubelet/reflection/generic/namespaced_test.go @@ -28,6 +28,7 @@ import ( "k8s.io/klog/v2" . "github.com/liqotech/liqo/pkg/utils/testutil" + "github.com/liqotech/liqo/pkg/virtualKubelet/forge" "github.com/liqotech/liqo/pkg/virtualKubelet/reflection/options" ) @@ -40,15 +41,21 @@ var _ = Describe("NamespacedReflector tests", func() { Context("the NewNamespacedReflector function", func() { var ( - nsrfl NamespacedReflector - ready bool + nsrfl NamespacedReflector + ready bool + forgingOpts *forge.ForgingOpts ) - BeforeEach(func() { ready = false }) + BeforeEach(func() { + ready = false + forgingOpts = &forge.ForgingOpts{} + }) + JustBeforeEach(func() { opts := options.NamespacedOpts{ LocalNamespace: localNamespace, RemoteNamespace: remoteNamespace, Ready: func() bool { return ready }, EventBroadcaster: record.NewBroadcaster(), + ForgingOpts: forgingOpts, } nsrfl = NewNamespacedReflector(&opts, name) }) @@ -58,6 +65,7 @@ var _ = Describe("NamespacedReflector tests", func() { Expect(nsrfl.local).To(BeIdenticalTo(localNamespace)) Expect(nsrfl.remote).To(BeIdenticalTo(remoteNamespace)) Expect(nsrfl.ready).ToNot(BeNil()) + Expect(nsrfl.ForgingOpts).To(BeIdenticalTo(forgingOpts)) }) Context("the readiness property", func() { diff --git a/pkg/virtualKubelet/reflection/manager/manager.go b/pkg/virtualKubelet/reflection/manager/manager.go index 85b070b764..9460161419 100644 --- a/pkg/virtualKubelet/reflection/manager/manager.go +++ b/pkg/virtualKubelet/reflection/manager/manager.go @@ -55,11 +55,13 @@ type manager struct { started bool stop map[string]context.CancelFunc + + forgingOpts forge.ForgingOpts } // New returns a new manager to start the reflection towards a remote cluster. func New(local, remote kubernetes.Interface, localLiqo, remoteLiqo liqoclient.Interface, resync time.Duration, - eb record.EventBroadcaster) Manager { + eb record.EventBroadcaster, labelsNotReflected, annotationsNotReflected []string) Manager { // Configure the field selector to retrieve only the pods scheduled on the current virtual node. localPodTweakListOptions := func(opts *metav1.ListOptions) { opts.FieldSelector = fields.OneTermEqualSelector("spec.nodeName", forge.LiqoNodeName).String() @@ -79,6 +81,8 @@ func New(local, remote kubernetes.Interface, localLiqo, remoteLiqo liqoclient.In started: false, stop: make(map[string]context.CancelFunc), + + forgingOpts: forge.NewForgingOpts(labelsNotReflected, annotationsNotReflected), } } @@ -172,7 +176,8 @@ func (m *manager) StartNamespace(local, remote string) { opts := options.NewNamespaced(). WithLocal(local, m.local, localFactory).WithLiqoLocal(m.localLiqo, localLiqoFactory). WithRemote(remote, m.remote, remoteFactory).WithLiqoRemote(m.remoteLiqo, remoteLiqoFactory). - WithReadinessFunc(func() bool { return ready }).WithEventBroadcaster(m.eventBroadcaster) + WithReadinessFunc(func() bool { return ready }).WithEventBroadcaster(m.eventBroadcaster). + WithForgingOpts(&m.forgingOpts) reflector.StartNamespace(opts) } diff --git a/pkg/virtualKubelet/reflection/manager/manager_test.go b/pkg/virtualKubelet/reflection/manager/manager_test.go index c9bb110f16..79038de0eb 100644 --- a/pkg/virtualKubelet/reflection/manager/manager_test.go +++ b/pkg/virtualKubelet/reflection/manager/manager_test.go @@ -36,12 +36,14 @@ var _ = Describe("Manager tests", func() { ) var ( - mgr Manager - localClient kubernetes.Interface - remoteClient kubernetes.Interface - localLiqoClient liqoclient.Interface - remoteLiqoClient liqoclient.Interface - broadcaster record.EventBroadcaster + mgr Manager + localClient kubernetes.Interface + remoteClient kubernetes.Interface + localLiqoClient liqoclient.Interface + remoteLiqoClient liqoclient.Interface + broadcaster record.EventBroadcaster + labelsNotReflected []string + annotationsNotReflected []string ctx context.Context cancel context.CancelFunc @@ -58,7 +60,7 @@ var _ = Describe("Manager tests", func() { AfterEach(func() { cancel() }) JustBeforeEach(func() { - mgr = New(localClient, remoteClient, localLiqoClient, remoteLiqoClient, 1*time.Hour, broadcaster) + mgr = New(localClient, remoteClient, localLiqoClient, remoteLiqoClient, 1*time.Hour, broadcaster, labelsNotReflected, annotationsNotReflected) }) Context("a new manager is created", func() { @@ -78,6 +80,8 @@ var _ = Describe("Manager tests", func() { Expect(mgr.(*manager).started).To(BeFalse()) Expect(mgr.(*manager).stop).ToNot(BeNil()) + + Expect(mgr.(*manager).forgingOpts).ToNot(BeNil()) }) Context("a NamespaceMapEventHandler is registered", func() { @@ -153,6 +157,7 @@ var _ = Describe("Manager tests", func() { Expect(opts.EventBroadcaster).To(Equal(broadcaster)) Expect(opts.Ready).ToNot(BeNil()) Expect(opts.HandlerFactory).To(BeNil()) + Expect(opts.ForgingOpts).ToNot(BeNil()) }) It("should eventually mark the namespace as ready", func() { Eventually(reflector.NamespaceStarted[localNamespace].Ready).Should(BeTrue()) diff --git a/pkg/virtualKubelet/reflection/options/options.go b/pkg/virtualKubelet/reflection/options/options.go index f8b1b67813..da87812852 100644 --- a/pkg/virtualKubelet/reflection/options/options.go +++ b/pkg/virtualKubelet/reflection/options/options.go @@ -26,6 +26,7 @@ import ( liqoclient "github.com/liqotech/liqo/pkg/client/clientset/versioned" liqoinformers "github.com/liqotech/liqo/pkg/client/informers/externalversions" + "github.com/liqotech/liqo/pkg/virtualKubelet/forge" ) // Keyer retrieves a set of NamespacedNames referring to the reconciliation targets from the object metadata. @@ -87,6 +88,8 @@ type NamespacedOpts struct { Ready func() bool HandlerFactory func(Keyer, ...EventFilter) cache.ResourceEventHandler + + ForgingOpts *forge.ForgingOpts } // NewNamespaced returns a new NamespacedOpts object. @@ -142,6 +145,12 @@ func (ro *NamespacedOpts) WithEventBroadcaster(broadcaster record.EventBroadcast return ro } +// WithForgingOpts configures the reflection options of the NamespacedOpts. +func (ro *NamespacedOpts) WithForgingOpts(opts *forge.ForgingOpts) *NamespacedOpts { + ro.ForgingOpts = opts + return ro +} + // EventFilterCreate ignores events of type create. func EventFilterCreate(et watch.EventType) bool { return et == watch.Added } diff --git a/pkg/virtualKubelet/reflection/options/options_test.go b/pkg/virtualKubelet/reflection/options/options_test.go index 65b369b0c8..9daab7bc51 100644 --- a/pkg/virtualKubelet/reflection/options/options_test.go +++ b/pkg/virtualKubelet/reflection/options/options_test.go @@ -29,6 +29,7 @@ import ( liqoclient "github.com/liqotech/liqo/pkg/client/clientset/versioned" liqoclientfake "github.com/liqotech/liqo/pkg/client/clientset/versioned/fake" liqoinformers "github.com/liqotech/liqo/pkg/client/informers/externalversions" + "github.com/liqotech/liqo/pkg/virtualKubelet/forge" "github.com/liqotech/liqo/pkg/virtualKubelet/reflection/options" ) @@ -115,6 +116,7 @@ var _ = Describe("Options", func() { Expect(opts.EventBroadcaster).To(BeNil()) Expect(opts.HandlerFactory).To(BeNil()) Expect(opts.Ready).To(BeNil()) + Expect(opts.ForgingOpts).To(BeNil()) }) }) @@ -129,6 +131,7 @@ var _ = Describe("Options", func() { factory informers.SharedInformerFactory liqoFactory liqoinformers.SharedInformerFactory broadcaster record.EventBroadcaster + forgingOpts *forge.ForgingOpts ) BeforeEach(func() { @@ -137,6 +140,7 @@ var _ = Describe("Options", func() { factory = informers.NewSharedInformerFactory(client, 10*time.Hour) liqoFactory = liqoinformers.NewSharedInformerFactory(liqoClient, 10*time.Hour) broadcaster = record.NewBroadcaster() + forgingOpts = &forge.ForgingOpts{} }) JustBeforeEach(func() { original = options.NewNamespaced() }) @@ -160,6 +164,7 @@ var _ = Describe("Options", func() { Expect(opts.EventBroadcaster).To(BeNil()) Expect(opts.HandlerFactory).To(BeNil()) Expect(opts.Ready).To(BeNil()) + Expect(opts.ForgingOpts).To(BeNil()) }) }) @@ -182,6 +187,7 @@ var _ = Describe("Options", func() { Expect(opts.EventBroadcaster).To(BeNil()) Expect(opts.HandlerFactory).To(BeNil()) Expect(opts.Ready).To(BeNil()) + Expect(opts.ForgingOpts).To(BeNil()) }) }) @@ -204,6 +210,7 @@ var _ = Describe("Options", func() { Expect(opts.EventBroadcaster).To(BeNil()) Expect(opts.HandlerFactory).To(BeNil()) Expect(opts.Ready).To(BeNil()) + Expect(opts.ForgingOpts).To(BeNil()) }) }) @@ -226,6 +233,7 @@ var _ = Describe("Options", func() { Expect(opts.EventBroadcaster).To(BeNil()) Expect(opts.HandlerFactory).To(BeNil()) Expect(opts.Ready).To(BeNil()) + Expect(opts.ForgingOpts).To(BeNil()) }) }) @@ -251,6 +259,7 @@ var _ = Describe("Options", func() { Expect(opts.RemoteLiqoFactory).To(BeNil()) Expect(opts.EventBroadcaster).To(BeNil()) Expect(opts.Ready).To(BeNil()) + Expect(opts.ForgingOpts).To(BeNil()) }) }) @@ -275,6 +284,7 @@ var _ = Describe("Options", func() { Expect(opts.RemoteLiqoFactory).To(BeNil()) Expect(opts.EventBroadcaster).To(BeNil()) Expect(opts.HandlerFactory).To(BeNil()) + Expect(opts.ForgingOpts).To(BeNil()) }) }) @@ -297,6 +307,30 @@ var _ = Describe("Options", func() { Expect(opts.RemoteLiqoFactory).To(BeNil()) Expect(opts.HandlerFactory).To(BeNil()) Expect(opts.Ready).To(BeNil()) + Expect(opts.ForgingOpts).To(BeNil()) + }) + }) + + Describe("The WithForgingOpts function", func() { + JustBeforeEach(func() { opts = original.WithForgingOpts(forgingOpts) }) + + It("should return a non-nil pointer", func() { Expect(opts).ToNot(BeNil()) }) + It("should return the same pointer of the receiver", func() { Expect(opts).To(BeIdenticalTo(original)) }) + It("should correctly set the forging options value", func() { Expect(opts.ForgingOpts).To(BeIdenticalTo(forgingOpts)) }) + It("should leave the other fields unset", func() { + Expect(opts.LocalNamespace).To(BeEmpty()) + Expect(opts.RemoteNamespace).To(BeEmpty()) + Expect(opts.LocalClient).To(BeNil()) + Expect(opts.LocalFactory).To(BeNil()) + Expect(opts.LocalLiqoClient).To(BeNil()) + Expect(opts.LocalFactory).To(BeNil()) + Expect(opts.RemoteClient).To(BeNil()) + Expect(opts.RemoteLiqoClient).To(BeNil()) + Expect(opts.RemoteFactory).To(BeNil()) + Expect(opts.RemoteLiqoFactory).To(BeNil()) + Expect(opts.HandlerFactory).To(BeNil()) + Expect(opts.Ready).To(BeNil()) + Expect(opts.EventBroadcaster).To(BeNil()) }) }) }) diff --git a/pkg/virtualKubelet/reflection/storage/persistentvolumeclaim.go b/pkg/virtualKubelet/reflection/storage/persistentvolumeclaim.go index 20a9f0f7b1..d17ffca2a6 100644 --- a/pkg/virtualKubelet/reflection/storage/persistentvolumeclaim.go +++ b/pkg/virtualKubelet/reflection/storage/persistentvolumeclaim.go @@ -181,7 +181,8 @@ func (npvcr *NamespacedPersistentVolumeClaimReflector) Handle(ctx context.Contex pv, state, err := liqostorageprovisioner.ProvisionRemotePVC(ctx, options, npvcr.RemoteNamespace(), npvcr.remoteRealStorageClassName, - npvcr.remotePersistentVolumeClaims, npvcr.remotePersistentVolumesClaimsClient) + npvcr.remotePersistentVolumeClaims, npvcr.remotePersistentVolumesClaimsClient, + npvcr.ForgingOpts) if err == nil && state == controller.ProvisioningFinished { local.Spec.VolumeName = options.PVName } diff --git a/pkg/virtualKubelet/reflection/storage/persistentvolumeclaim_test.go b/pkg/virtualKubelet/reflection/storage/persistentvolumeclaim_test.go index a0de760b2f..0f90c38252 100644 --- a/pkg/virtualKubelet/reflection/storage/persistentvolumeclaim_test.go +++ b/pkg/virtualKubelet/reflection/storage/persistentvolumeclaim_test.go @@ -83,6 +83,9 @@ var _ = Describe("reflector methods", func() { Expect(err).ToNot(HaveOccurred()) Expect(offloadedPvc).ToNot(BeNil()) + Expect(offloadedPvc.Labels).ToNot(HaveKey(FakeNotReflectedLabelKey)) + Expect(offloadedPvc.Annotations).ToNot(HaveKey(FakeNotReflectedAnnotKey)) + Expect(offloadedPvc.Spec.StorageClassName).To(PointTo(Equal(RealRemoteStorageClassName))) }) diff --git a/pkg/virtualKubelet/reflection/storage/storage_suite_test.go b/pkg/virtualKubelet/reflection/storage/storage_suite_test.go index 55a0f08ab2..1739c1bb8b 100644 --- a/pkg/virtualKubelet/reflection/storage/storage_suite_test.go +++ b/pkg/virtualKubelet/reflection/storage/storage_suite_test.go @@ -154,9 +154,13 @@ var _ = BeforeEach(func() { ObjectMeta: metav1.ObjectMeta{ Name: localPvcName, Namespace: LocalNamespace, + Labels: map[string]string{ + testutil.FakeNotReflectedLabelKey: "true", + }, Annotations: map[string]string{ - annStorageProvisioner: consts.StorageProvisionerName, - annSelectedNode: RealNodeName, + annStorageProvisioner: consts.StorageProvisionerName, + annSelectedNode: RealNodeName, + testutil.FakeNotReflectedAnnotKey: "true", }, }, Spec: corev1.PersistentVolumeClaimSpec{ @@ -218,7 +222,8 @@ var _ = JustBeforeEach(func() { options := options.NewNamespaced(). WithLocal(LocalNamespace, k8sClient, factory). WithRemote(RemoteNamespace, k8sClient, factory). - WithHandlerFactory(FakeEventHandler).WithEventBroadcaster(record.NewBroadcaster()) + WithHandlerFactory(FakeEventHandler).WithEventBroadcaster(record.NewBroadcaster()). + WithForgingOpts(testutil.FakeForgingOpts()) reflector = reflectorBuilder(options).(*NamespacedPersistentVolumeClaimReflector) Expect(reflector).ToNot(BeNil()) diff --git a/pkg/virtualKubelet/reflection/workload/podns.go b/pkg/virtualKubelet/reflection/workload/podns.go index 2851f7e8e2..a53073e76f 100644 --- a/pkg/virtualKubelet/reflection/workload/podns.go +++ b/pkg/virtualKubelet/reflection/workload/podns.go @@ -217,7 +217,7 @@ func (npr *NamespacedPodReflector) Handle(ctx context.Context, name string) erro info.PreventCreationUntilSeen = false // The local pod is currently running, and it is necessary to enforce its presence in the remote cluster. - target, terr := npr.ForgeShadowPod(ctx, local, shadow, info) + target, terr := npr.ForgeShadowPod(ctx, local, shadow, info, npr.ForgingOpts) if terr != nil { klog.Errorf("Reflection of local pod %q to %q failed: %v", npr.LocalRef(local.GetName()), npr.RemoteRef(local.GetName()), terr) npr.Event(local, corev1.EventTypeWarning, forge.EventFailedReflection, forge.EventFailedReflectionMsg(terr)) @@ -298,7 +298,7 @@ func (npr *NamespacedPodReflector) HandleLabels(ctx context.Context, local *core // ForgeShadowPod forges the ShadowPod object to be enforced by the reflection process. func (npr *NamespacedPodReflector) ForgeShadowPod(ctx context.Context, local *corev1.Pod, - shadow *vkv1alpha1.ShadowPod, info *PodInfo) (*vkv1alpha1.ShadowPod, error) { + shadow *vkv1alpha1.ShadowPod, info *PodInfo, forgingOpts *forge.ForgingOpts) (*vkv1alpha1.ShadowPod, error) { var saerr, kserr error // Wrap the secret name retrieval from the service account, so that we do not have to handle errors in the forge logic. @@ -325,7 +325,7 @@ func (npr *NamespacedPodReflector) ForgeShadowPod(ctx context.Context, local *co } // Forge the target shadowpod object. - target := forge.RemoteShadowPod(local, shadow, npr.RemoteNamespace(), + target := forge.RemoteShadowPod(local, shadow, npr.RemoteNamespace(), forgingOpts, forge.APIServerSupportMutator(npr.config.APIServerSupport, local.Annotations, pod.ServiceAccountName(local), saSecretRetriever, ipGetter, npr.config.HomeAPIServerHost, npr.config.HomeAPIServerPort), forge.ServiceAccountMutator(npr.config.APIServerSupport, local.Annotations)) diff --git a/pkg/virtualKubelet/reflection/workload/podns_test.go b/pkg/virtualKubelet/reflection/workload/podns_test.go index 874027a344..aca9f19d49 100644 --- a/pkg/virtualKubelet/reflection/workload/podns_test.go +++ b/pkg/virtualKubelet/reflection/workload/podns_test.go @@ -77,7 +77,7 @@ var _ = Describe("Namespaced Pod Reflection Tests", func() { reflector = rfl.NewNamespaced(options.NewNamespaced(). WithLocal(LocalNamespace, client, factory).WithLiqoLocal(liqoClient, liqoFactory). WithRemote(RemoteNamespace, client, factory).WithLiqoRemote(liqoClient, liqoFactory). - WithHandlerFactory(FakeEventHandler).WithEventBroadcaster(broadcaster)) + WithHandlerFactory(FakeEventHandler).WithEventBroadcaster(broadcaster).WithForgingOpts(FakeForgingOpts())) factory.Start(ctx.Done()) liqoFactory.Start(ctx.Done()) @@ -148,8 +148,8 @@ var _ = Describe("Namespaced Pod Reflection Tests", func() { BeforeEach(func() { shouldDenyPodPatches = false - local.SetLabels(map[string]string{"foo": "bar"}) - local.SetAnnotations(map[string]string{"bar": "baz"}) + local.SetLabels(map[string]string{"foo": "bar", FakeNotReflectedLabelKey: "true"}) + local.SetAnnotations(map[string]string{"bar": "baz", FakeNotReflectedAnnotKey: "true"}) local.Spec.Containers = []corev1.Container{{Name: "bar", Image: "foo"}} CreatePod(client, &local) @@ -183,7 +183,9 @@ var _ = Describe("Namespaced Pod Reflection Tests", func() { Expect(shadowAfter.Labels).To(HaveKeyWithValue(forge.LiqoOriginClusterIDKey, LocalClusterID)) Expect(shadowAfter.Labels).To(HaveKeyWithValue(forge.LiqoDestinationClusterIDKey, RemoteClusterID)) Expect(shadowAfter.Labels).To(HaveKeyWithValue("foo", "bar")) + Expect(shadowAfter.Labels).ToNot(HaveKey(FakeNotReflectedLabelKey)) Expect(shadowAfter.Annotations).To(HaveKeyWithValue("bar", "baz")) + Expect(shadowAfter.Annotations).ToNot(HaveKey(FakeNotReflectedAnnotKey)) }) It("the spec should have been correctly replicated to the remote object", func() { shadowAfter := GetShadowPod(liqoClient, RemoteNamespace, PodName) @@ -196,8 +198,8 @@ var _ = Describe("Namespaced Pod Reflection Tests", func() { When("the remote object already exists and needs to be updated", func() { BeforeEach(func() { - shadow.SetLabels(forge.ReflectionLabels()) - shadow.SetAnnotations(map[string]string{"bar": "previous", "existing": "existing"}) + shadow.SetLabels(labels.Merge(forge.ReflectionLabels(), map[string]string{FakeNotReflectedLabelKey: "true"})) + shadow.SetAnnotations(map[string]string{"bar": "previous", "existing": "existing", FakeNotReflectedAnnotKey: "true"}) CreateShadowPod(liqoClient, &shadow) }) @@ -207,8 +209,10 @@ var _ = Describe("Namespaced Pod Reflection Tests", func() { Expect(shadowAfter.Labels).To(HaveKeyWithValue(forge.LiqoOriginClusterIDKey, LocalClusterID)) Expect(shadowAfter.Labels).To(HaveKeyWithValue(forge.LiqoDestinationClusterIDKey, RemoteClusterID)) Expect(shadowAfter.Labels).To(HaveKeyWithValue("foo", "bar")) + Expect(shadowAfter.Labels).ToNot(HaveKey(FakeNotReflectedLabelKey)) Expect(shadowAfter.Annotations).To(HaveKeyWithValue("bar", "baz")) Expect(shadowAfter.Annotations).NotTo(HaveKeyWithValue("existing", "existing")) + Expect(shadowAfter.Annotations).ToNot(HaveKey(FakeNotReflectedAnnotKey)) }) It("the spec should not have been replicated to the remote object, to prevent possible issues", func() { shadowAfter := GetShadowPod(liqoClient, RemoteNamespace, PodName) diff --git a/pkg/vkMachinery/forge/forge.go b/pkg/vkMachinery/forge/forge.go index f57ea9770c..1ac84e7265 100644 --- a/pkg/vkMachinery/forge/forge.go +++ b/pkg/vkMachinery/forge/forge.go @@ -64,6 +64,14 @@ func forgeVKContainers( getDefaultStorageClass(storageClasses).StorageClassName)) } + if len(opts.LabelsNotReflected) > 0 { + args = append(args, stringifyArgument(string(LabelsNotReflected), strings.Join(opts.LabelsNotReflected, ","))) + } + + if len(opts.AnnotationsNotReflected) > 0 { + args = append(args, stringifyArgument(string(AnnotationsNotReflected), strings.Join(opts.AnnotationsNotReflected, ","))) + } + if extraAnnotations := opts.NodeExtraAnnotations.StringMap; len(extraAnnotations) != 0 { args = append(args, stringifyArgument(string(NodeExtraAnnotations), opts.NodeExtraAnnotations.String())) } diff --git a/pkg/vkMachinery/forge/type.go b/pkg/vkMachinery/forge/type.go index 98dd4e3751..fd4f5c09ab 100644 --- a/pkg/vkMachinery/forge/type.go +++ b/pkg/vkMachinery/forge/type.go @@ -23,19 +23,21 @@ import ( // VirtualKubeletOpts defines the custom options associated with the virtual kubelet deployment forging. type VirtualKubeletOpts struct { // ContainerImage contains the virtual kubelet image name and tag. - ContainerImage string - ExtraAnnotations map[string]string - ExtraLabels map[string]string - ExtraArgs []string - NodeExtraAnnotations argsutils.StringMap - NodeExtraLabels argsutils.StringMap - RequestsCPU resource.Quantity - LimitsCPU resource.Quantity - RequestsRAM resource.Quantity - LimitsRAM resource.Quantity - IpamEndpoint string - MetricsEnabled bool - MetricsAddress string + ContainerImage string + ExtraAnnotations map[string]string + ExtraLabels map[string]string + ExtraArgs []string + NodeExtraAnnotations argsutils.StringMap + NodeExtraLabels argsutils.StringMap + RequestsCPU resource.Quantity + LimitsCPU resource.Quantity + RequestsRAM resource.Quantity + LimitsRAM resource.Quantity + IpamEndpoint string + MetricsEnabled bool + MetricsAddress string + LabelsNotReflected []string + AnnotationsNotReflected []string } // VirtualKubeletOptsFlag defines the custom options flags associated with the virtual kubelet deployment forging. @@ -75,4 +77,8 @@ const ( MetricsAddress VirtualKubeletOptsFlag = "--metrics-address" // CreateNode is the flag used to specify if the node must be created. CreateNode VirtualKubeletOptsFlag = "--create-node" + // LabelsNotReflected is the flag used to specify the labels not reflected. + LabelsNotReflected VirtualKubeletOptsFlag = "--labels-not-reflected" + // AnnotationsNotReflected is the flag used to specify the annotations not reflected. + AnnotationsNotReflected VirtualKubeletOptsFlag = "--annotations-not-reflected" )