From c603c5fbfa46e46c715a041cdbaea0224203ff27 Mon Sep 17 00:00:00 2001 From: Per Goncalves da Silva Date: Wed, 30 Apr 2025 09:19:41 +0200 Subject: [PATCH] Make targetNamespaces optional Signed-off-by: Per Goncalves da Silva --- .../rukpak/convert/registryv1.go | 2 +- .../rukpak/render/render.go | 21 +++++++++-- .../rukpak/render/render_test.go | 37 ++++++++++++++++--- 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/internal/operator-controller/rukpak/convert/registryv1.go b/internal/operator-controller/rukpak/convert/registryv1.go index 68244d313..1417239fd 100644 --- a/internal/operator-controller/rukpak/convert/registryv1.go +++ b/internal/operator-controller/rukpak/convert/registryv1.go @@ -261,7 +261,7 @@ func (c Converter) Convert(rv1 render.RegistryV1, installNamespace string, targe return nil, fmt.Errorf("webhookDefinitions are not supported") } - objs, err := c.BundleRenderer.Render(rv1, installNamespace, targetNamespaces) + objs, err := c.BundleRenderer.Render(rv1, installNamespace, render.WithTargetNamespaces(targetNamespaces...)) if err != nil { return nil, err } diff --git a/internal/operator-controller/rukpak/render/render.go b/internal/operator-controller/rukpak/render/render.go index af904aec0..279320afc 100644 --- a/internal/operator-controller/rukpak/render/render.go +++ b/internal/operator-controller/rukpak/render/render.go @@ -4,6 +4,7 @@ import ( "errors" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "sigs.k8s.io/controller-runtime/pkg/client" @@ -69,19 +70,33 @@ type Options struct { func (o *Options) apply(opts ...Option) *Options { for _, opt := range opts { - opt(o) + if opt != nil { + opt(o) + } } return o } type Option func(*Options) +func WithTargetNamespaces(namespaces ...string) Option { + return func(o *Options) { + o.TargetNamespaces = namespaces + } +} + +func WithUniqueNameGenerator(generator UniqueNameGenerator) Option { + return func(o *Options) { + o.UniqueNameGenerator = generator + } +} + type BundleRenderer struct { BundleValidator BundleValidator ResourceGenerators []ResourceGenerator } -func (r BundleRenderer) Render(rv1 RegistryV1, installNamespace string, watchNamespaces []string, opts ...Option) ([]client.Object, error) { +func (r BundleRenderer) Render(rv1 RegistryV1, installNamespace string, opts ...Option) ([]client.Object, error) { // validate bundle if err := r.BundleValidator.Validate(&rv1); err != nil { return nil, err @@ -89,7 +104,7 @@ func (r BundleRenderer) Render(rv1 RegistryV1, installNamespace string, watchNam genOpts := (&Options{ InstallNamespace: installNamespace, - TargetNamespaces: watchNamespaces, + TargetNamespaces: []string{metav1.NamespaceAll}, UniqueNameGenerator: DefaultUniqueNameGenerator, }).apply(opts...) diff --git a/internal/operator-controller/rukpak/render/render_test.go b/internal/operator-controller/rukpak/render/render_test.go index ede57ff69..510a62987 100644 --- a/internal/operator-controller/rukpak/render/render_test.go +++ b/internal/operator-controller/rukpak/render/render_test.go @@ -29,7 +29,7 @@ func Test_BundleRenderer_ValidatesBundle(t *testing.T) { }, }, } - objs, err := renderer.Render(render.RegistryV1{}, "", nil) + objs, err := renderer.Render(render.RegistryV1{}, "") require.Nil(t, objs) require.Error(t, err) require.Contains(t, err.Error(), "this bundle is invalid") @@ -37,7 +37,7 @@ func Test_BundleRenderer_ValidatesBundle(t *testing.T) { func Test_BundleRenderer_CreatesCorrectDefaultOptions(t *testing.T) { expectedInstallNamespace := "install-namespace" - expectedTargetNamespaces := []string{"ns-one", "ns-two"} + expectedTargetNamespaces := []string{""} expectedUniqueNameGenerator := render.DefaultUniqueNameGenerator renderer := render.BundleRenderer{ @@ -51,7 +51,34 @@ func Test_BundleRenderer_CreatesCorrectDefaultOptions(t *testing.T) { }, } - _, _ = renderer.Render(render.RegistryV1{}, expectedInstallNamespace, expectedTargetNamespaces) + _, _ = renderer.Render(render.RegistryV1{}, expectedInstallNamespace) +} + +func Test_BundleRenderer_AppliesUserOptions(t *testing.T) { + isOptionApplied := false + _, _ = render.BundleRenderer{}.Render(render.RegistryV1{}, "install-namespace", func(options *render.Options) { + isOptionApplied = true + }) + require.True(t, isOptionApplied) +} + +func Test_WithTargetNamespaces(t *testing.T) { + opts := &render.Options{ + TargetNamespaces: []string{"target-namespace"}, + } + render.WithTargetNamespaces("a", "b", "c")(opts) + require.Equal(t, []string{"a", "b", "c"}, opts.TargetNamespaces) +} + +func Test_WithUniqueNameGenerator(t *testing.T) { + opts := &render.Options{ + UniqueNameGenerator: render.DefaultUniqueNameGenerator, + } + render.WithUniqueNameGenerator(func(s string, i interface{}) (string, error) { + return "a man needs a name", nil + })(opts) + generatedName, _ := opts.UniqueNameGenerator("", nil) + require.Equal(t, "a man needs a name", generatedName) } func Test_BundleRenderer_CallsResourceGenerators(t *testing.T) { @@ -65,7 +92,7 @@ func Test_BundleRenderer_CallsResourceGenerators(t *testing.T) { }, }, } - objs, err := renderer.Render(render.RegistryV1{}, "", nil) + objs, err := renderer.Render(render.RegistryV1{}, "") require.NoError(t, err) require.Equal(t, []client.Object{&corev1.Namespace{}, &corev1.Service{}, &appsv1.Deployment{}}, objs) } @@ -81,7 +108,7 @@ func Test_BundleRenderer_ReturnsResourceGeneratorErrors(t *testing.T) { }, }, } - objs, err := renderer.Render(render.RegistryV1{}, "", nil) + objs, err := renderer.Render(render.RegistryV1{}, "") require.Nil(t, objs) require.Error(t, err) require.Contains(t, err.Error(), "generator error")