Skip to content

Commit

Permalink
Option to disable reflection of specific labels and annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
fra98 authored and adamjensenbot committed Aug 3, 2023
1 parent b7e707e commit a0e3f1b
Show file tree
Hide file tree
Showing 51 changed files with 400 additions and 139 deletions.
32 changes: 19 additions & 13 deletions cmd/liqo-controller-manager/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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)")

Expand All @@ -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()
Expand Down
3 changes: 3 additions & 0 deletions cmd/virtual-kubelet/root/flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
6 changes: 6 additions & 0 deletions cmd/virtual-kubelet/root/opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
3 changes: 3 additions & 0 deletions cmd/virtual-kubelet/root/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
2 changes: 2 additions & 0 deletions deployments/liqo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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. |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand Down
11 changes: 11 additions & 0 deletions deployments/liqo/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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
Expand Down Expand Up @@ -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))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down Expand Up @@ -269,6 +271,7 @@ var _ = Describe("Test Storage Provisioner", func() {
var (
remotePersistentVolumeClaims corev1listers.PersistentVolumeClaimNamespaceLister
remotePersistentVolumesClaimsClient corev1clients.PersistentVolumeClaimInterface
forgingOpts *forge.ForgingOpts
)

BeforeEach(func() {
Expand All @@ -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()

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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))
})

})
Expand Down
4 changes: 4 additions & 0 deletions pkg/utils/testutil/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down
9 changes: 9 additions & 0 deletions pkg/utils/testutil/liqo.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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},
}
}
6 changes: 3 additions & 3 deletions pkg/virtualKubelet/forge/configmaps.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
16 changes: 11 additions & 5 deletions pkg/virtualKubelet/forge/configmaps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")))
Expand All @@ -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() {
Expand Down
10 changes: 6 additions & 4 deletions pkg/virtualKubelet/forge/endpointslices.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
}
Expand Down
16 changes: 11 additions & 5 deletions pkg/virtualKubelet/forge/endpointslices_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down Expand Up @@ -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() {
Expand All @@ -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)))
Expand Down
Loading

0 comments on commit a0e3f1b

Please sign in to comment.