diff --git a/api/v1beta1/metallb_types.go b/api/v1beta1/metallb_types.go index 48e7173df..734c1cc50 100644 --- a/api/v1beta1/metallb_types.go +++ b/api/v1beta1/metallb_types.go @@ -106,6 +106,11 @@ type FRRK8SConfig struct { AlwaysBlock []string `json:"alwaysBlock,omitempty"` // The namespace frr-k8s is running on in case of frr-k8s external mode Namespace string `json:"namespace,omitempty"` + // When set, BGP secret references are passed to frr-k8s without resolving them. + // The secret must exist in the frr-k8s namespace. + // Only valid when frr-k8s runs in external mode. + // +optional + SecretPassthrough bool `json:"secretPassthrough,omitempty"` } type Config struct { diff --git a/bin/metallb-operator.yaml b/bin/metallb-operator.yaml index b417b4043..68ca3d248 100644 --- a/bin/metallb-operator.yaml +++ b/bin/metallb-operator.yaml @@ -3071,6 +3071,12 @@ spec: description: The namespace frr-k8s is running on in case of frr-k8s external mode type: string + secretPassthrough: + description: |- + When set, BGP secret references are passed to frr-k8s without resolving them. + The secret must exist in the frr-k8s namespace. + Only valid when frr-k8s runs in external mode. + type: boolean type: object image: description: Foo is an example field of MetalLB. Edit MetalLB_types.go diff --git a/bundle/manifests/metallb.io_metallbs.yaml b/bundle/manifests/metallb.io_metallbs.yaml index a87206b65..2c42a2b6c 100644 --- a/bundle/manifests/metallb.io_metallbs.yaml +++ b/bundle/manifests/metallb.io_metallbs.yaml @@ -1099,6 +1099,12 @@ spec: description: The namespace frr-k8s is running on in case of frr-k8s external mode type: string + secretPassthrough: + description: |- + When set, BGP secret references are passed to frr-k8s without resolving them. + The secret must exist in the frr-k8s namespace. + Only valid when frr-k8s runs in external mode. + type: boolean type: object image: description: Foo is an example field of MetalLB. Edit MetalLB_types.go diff --git a/config/crd/bases/metallb.io_metallbs.yaml b/config/crd/bases/metallb.io_metallbs.yaml index e764520b2..2b02d89e9 100644 --- a/config/crd/bases/metallb.io_metallbs.yaml +++ b/config/crd/bases/metallb.io_metallbs.yaml @@ -1099,6 +1099,12 @@ spec: description: The namespace frr-k8s is running on in case of frr-k8s external mode type: string + secretPassthrough: + description: |- + When set, BGP secret references are passed to frr-k8s without resolving them. + The secret must exist in the frr-k8s namespace. + Only valid when frr-k8s runs in external mode. + type: boolean type: object image: description: Foo is an example field of MetalLB. Edit MetalLB_types.go diff --git a/manifests/stable/metallb.io_metallbs.yaml b/manifests/stable/metallb.io_metallbs.yaml index 5d90faeba..c5be9c644 100644 --- a/manifests/stable/metallb.io_metallbs.yaml +++ b/manifests/stable/metallb.io_metallbs.yaml @@ -1101,6 +1101,12 @@ spec: description: The namespace frr-k8s is running on in case of frr-k8s external mode type: string + secretPassthrough: + description: |- + When set, BGP secret references are passed to frr-k8s without resolving them. + The secret must exist in the frr-k8s namespace. + Only valid when frr-k8s runs in external mode. + type: boolean type: object image: description: Foo is an example field of MetalLB. Edit MetalLB_types.go diff --git a/pkg/helm/metallb.go b/pkg/helm/metallb.go index 5180ff19a..c2c04abd3 100644 --- a/pkg/helm/metallb.go +++ b/pkg/helm/metallb.go @@ -355,10 +355,15 @@ func metalLBFrrk8sValues(envConfig params.EnvConfig, crdConfig *metallbv1beta1.M if params.BGPType(crdConfig, envConfig) == metallbv1beta1.FRRK8sExternalMode { external = true } + secretPassthrough := false + if crdConfig.Spec.FRRK8SConfig != nil { + secretPassthrough = crdConfig.Spec.FRRK8SConfig.SecretPassthrough + } frrk8sValuesMap := map[string]interface{}{ - "enabled": enabled, - "external": external, - "namespace": frrK8sNamespace, + "enabled": enabled, + "external": external, + "namespace": frrK8sNamespace, + "secretPassthrough": secretPassthrough, } return frrk8sValuesMap } diff --git a/pkg/helm/metallb_test.go b/pkg/helm/metallb_test.go index 320e74ae0..5e9c75ba3 100644 --- a/pkg/helm/metallb_test.go +++ b/pkg/helm/metallb_test.go @@ -228,6 +228,61 @@ func TestParseMetalLBChartWithCustomValues(t *testing.T) { g.Expect(isControllerFound).To(BeTrue()) } +func TestSecretPassthrough(t *testing.T) { + tests := []struct { + name string + secretPassthrough bool + expectFlag bool + }{ + {"enabled", true, true}, + {"disabled", false, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + g := NewGomegaWithT(t) + chart, err := NewMetalLBChart(metalLBChartPath, metalLBChartName, MetalLBTestNameSpace, nil) + g.Expect(err).To(BeNil()) + + metallb := &metallbv1beta1.MetalLB{ + ObjectMeta: metav1.ObjectMeta{ + Name: "metallb", + Namespace: MetalLBTestNameSpace, + }, + Spec: metallbv1beta1.MetalLBSpec{ + BGPBackend: metallbv1beta1.FRRK8sExternalMode, + FRRK8SConfig: &metallbv1beta1.FRRK8SConfig{ + Namespace: "frr-k8s-external-namespace", + SecretPassthrough: tt.secretPassthrough, + }, + }, + } + + objs, err := chart.Objects(defaultEnvConfig, metallb) + g.Expect(err).To(BeNil()) + var speakerFound bool + for _, obj := range objs { + if obj.GetKind() == "DaemonSet" && obj.GetName() == speakerDaemonSet { + speaker := appsv1.DaemonSet{} + err = runtime.DefaultUnstructuredConverter.FromUnstructured(obj.UnstructuredContent(), &speaker) + g.Expect(err).To(BeNil()) + for _, container := range speaker.Spec.Template.Spec.Containers { + if container.Name == "speaker" { + if tt.expectFlag { + g.Expect(container.Args).To(ContainElement("--frrk8s-secret-passthrough")) + } else { + g.Expect(container.Args).NotTo(ContainElement("--frrk8s-secret-passthrough")) + } + g.Expect(container.Args).To(ContainElement("--frrk8s-namespace=frr-k8s-external-namespace")) + speakerFound = true + } + } + } + } + g.Expect(speakerFound).To(BeTrue()) + }) + } +} + func TestParseOCPSecureMetrics(t *testing.T) { g := NewGomegaWithT(t)