Skip to content

Commit 94c7776

Browse files
committed
(rukpak) extend bundle renderer to accept config opts
Pass installNamespace and watchNamespace as config values
1 parent d95f426 commit 94c7776

File tree

9 files changed

+95
-37
lines changed

9 files changed

+95
-37
lines changed

internal/operator-controller/applier/helm.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
ocv1 "github.com/operator-framework/operator-controller/api/v1"
2828
"github.com/operator-framework/operator-controller/internal/operator-controller/authorization"
2929
"github.com/operator-framework/operator-controller/internal/operator-controller/features"
30+
"github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/bundle"
3031
"github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/bundle/source"
3132
"github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/preflights/crdupgradesafety"
3233
"github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/util"
@@ -57,7 +58,7 @@ type Preflight interface {
5758
}
5859

5960
type BundleToHelmChartConverter interface {
60-
ToHelmChart(bundle source.BundleSource, installNamespace string, watchNamespace string) (*chart.Chart, error)
61+
ToHelmChart(bundle source.BundleSource, config map[string]interface{}) (*chart.Chart, error)
6162
}
6263

6364
type Helm struct {
@@ -222,7 +223,10 @@ func (h *Helm) buildHelmChart(bundleFS fs.FS, ext *ocv1.ClusterExtension) (*char
222223
}
223224
}
224225

225-
return h.BundleToHelmChartConverter.ToHelmChart(source.FromFS(bundleFS), ext.Spec.Namespace, watchNamespace)
226+
bundleConfig := map[string]interface{}{}
227+
bundleConfig[bundle.BundleConfigWatchNamespaceKey] = watchNamespace
228+
bundleConfig[bundle.BundleConfigInstallNamespaceKey] = ext.Spec.Namespace
229+
return h.BundleToHelmChartConverter.ToHelmChart(source.FromFS(bundleFS), bundleConfig)
226230
}
227231

228232
func (h *Helm) renderClientOnlyRelease(ctx context.Context, ext *ocv1.ClusterExtension, chrt *chart.Chart, values chartutil.Values, post postrender.PostRenderer) (*release.Release, error) {

internal/operator-controller/applier/helm_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -559,8 +559,8 @@ func TestApply_InstallationWithSingleOwnNamespaceInstallSupportEnabled(t *testin
559559
},
560560
},
561561
BundleToHelmChartConverter: &fakeBundleToHelmChartConverter{
562-
fn: func(bundle source.BundleSource, installNamespace string, watchNamespace string) (*chart.Chart, error) {
563-
require.Equal(t, expectedWatchNamespace, watchNamespace)
562+
fn: func(bundle source.BundleSource, config map[string]interface{}) (*chart.Chart, error) {
563+
require.Equal(t, expectedWatchNamespace, config["watchNamespace"])
564564
return nil, nil
565565
},
566566
},
@@ -597,8 +597,8 @@ func TestApply_RegistryV1ToChartConverterIntegration(t *testing.T) {
597597
},
598598
},
599599
BundleToHelmChartConverter: &fakeBundleToHelmChartConverter{
600-
fn: func(bundle source.BundleSource, installNamespace string, watchNamespace string) (*chart.Chart, error) {
601-
require.Equal(t, expectedWatchNamespace, watchNamespace)
600+
fn: func(bundle source.BundleSource, config map[string]interface{}) (*chart.Chart, error) {
601+
require.Equal(t, expectedWatchNamespace, config["watchNamespace"])
602602
return nil, nil
603603
},
604604
},
@@ -617,7 +617,7 @@ func TestApply_RegistryV1ToChartConverterIntegration(t *testing.T) {
617617
},
618618
},
619619
BundleToHelmChartConverter: &fakeBundleToHelmChartConverter{
620-
fn: func(bundle source.BundleSource, installNamespace string, watchNamespace string) (*chart.Chart, error) {
620+
fn: func(bundle source.BundleSource, config map[string]interface{}) (*chart.Chart, error) {
621621
return nil, errors.New("some error")
622622
},
623623
},
@@ -629,9 +629,9 @@ func TestApply_RegistryV1ToChartConverterIntegration(t *testing.T) {
629629
}
630630

631631
type fakeBundleToHelmChartConverter struct {
632-
fn func(source.BundleSource, string, string) (*chart.Chart, error)
632+
fn func(source.BundleSource, map[string]interface{}) (*chart.Chart, error)
633633
}
634634

635-
func (f fakeBundleToHelmChartConverter) ToHelmChart(bundle source.BundleSource, installNamespace string, watchNamespace string) (*chart.Chart, error) {
636-
return f.fn(bundle, installNamespace, watchNamespace)
635+
func (f fakeBundleToHelmChartConverter) ToHelmChart(bundle source.BundleSource, config map[string]interface{}) (*chart.Chart, error) {
636+
return f.fn(bundle, config)
637637
}

internal/operator-controller/rukpak/bundle/registryv1.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ import (
77
"github.com/operator-framework/api/pkg/operators/v1alpha1"
88
)
99

10+
const (
11+
BundleConfigWatchNamespaceKey = "watchNamespace"
12+
BundleConfigInstallNamespaceKey = "installNamespace"
13+
)
14+
1015
type RegistryV1 struct {
1116
PackageName string
1217
CSV v1alpha1.ClusterServiceVersion

internal/operator-controller/rukpak/convert/helm.go

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"helm.sh/helm/v3/pkg/chart"
99

10+
bundlepkg "github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/bundle"
1011
"github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/bundle/source"
1112
"github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/render"
1213
)
@@ -17,12 +18,24 @@ type BundleToHelmChartConverter struct {
1718
IsWebhookSupportEnabled bool
1819
}
1920

20-
func (r *BundleToHelmChartConverter) ToHelmChart(bundle source.BundleSource, installNamespace string, watchNamespace string) (*chart.Chart, error) {
21+
func (r *BundleToHelmChartConverter) ToHelmChart(bundle source.BundleSource, config map[string]interface{}) (*chart.Chart, error) {
2122
rv1, err := bundle.GetBundle()
2223
if err != nil {
2324
return nil, err
2425
}
2526

27+
// Convert config map to render options
28+
var opts []render.Option
29+
if config != nil {
30+
if installNs, ok := config[bundlepkg.BundleConfigInstallNamespaceKey].(string); ok {
31+
opts = append(opts, render.WithInstallNamespace(installNs))
32+
}
33+
if watchNs, ok := config[bundlepkg.BundleConfigWatchNamespaceKey].(string); ok {
34+
opts = append(opts, render.WithTargetNamespaces(watchNs))
35+
}
36+
}
37+
opts = append(opts, render.WithCertificateProvider(r.CertificateProvider))
38+
2639
if len(rv1.CSV.Spec.APIServiceDefinitions.Owned) > 0 {
2740
return nil, fmt.Errorf("unsupported bundle: apiServiceDefintions are not supported")
2841
}
@@ -39,11 +52,7 @@ func (r *BundleToHelmChartConverter) ToHelmChart(bundle source.BundleSource, ins
3952
return nil, fmt.Errorf("unsupported bundle: webhookDefinitions are not supported")
4053
}
4154

42-
objs, err := r.BundleRenderer.Render(
43-
rv1, installNamespace,
44-
render.WithTargetNamespaces(watchNamespace),
45-
render.WithCertificateProvider(r.CertificateProvider),
46-
)
55+
objs, err := r.BundleRenderer.Render(rv1, opts...)
4756

4857
if err != nil {
4958
return nil, fmt.Errorf("error rendering bundle: %w", err)

internal/operator-controller/rukpak/convert/helm_test.go

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@ func Test_BundleToHelmChartConverter_ToHelmChart_ReturnsBundleSourceFailures(t *
2424
var failingBundleSource FakeBundleSource = func() (bundle.RegistryV1, error) {
2525
return bundle.RegistryV1{}, errors.New("some error")
2626
}
27-
_, err := converter.ToHelmChart(failingBundleSource, "install-namespace", "watch-namespace")
27+
config := map[string]interface{}{}
28+
config[bundle.BundleConfigInstallNamespaceKey] = "install-namespace"
29+
config[bundle.BundleConfigWatchNamespaceKey] = "watch-namespace"
30+
_, err := converter.ToHelmChart(failingBundleSource, config)
2831
require.Error(t, err)
2932
require.Contains(t, err.Error(), "some error")
3033
}
@@ -46,7 +49,10 @@ func Test_BundleToHelmChartConverter_ToHelmChart_ReturnsBundleRendererFailures(t
4649
},
4750
)
4851

49-
_, err := converter.ToHelmChart(b, "install-namespace", "")
52+
config := map[string]interface{}{}
53+
config[bundle.BundleConfigInstallNamespaceKey] = "install-namespace"
54+
config[bundle.BundleConfigWatchNamespaceKey] = ""
55+
_, err := converter.ToHelmChart(b, config)
5056
require.Error(t, err)
5157
require.Contains(t, err.Error(), "some error")
5258
}
@@ -60,7 +66,10 @@ func Test_BundleToHelmChartConverter_ToHelmChart_NoAPIServiceDefinitions(t *test
6066
},
6167
)
6268

63-
_, err := converter.ToHelmChart(b, "install-namespace", "")
69+
config := map[string]interface{}{}
70+
config["installNamespace"] = "install-namespace"
71+
config["watchNamespace"] = ""
72+
_, err := converter.ToHelmChart(b, config)
6473
require.Error(t, err)
6574
require.Contains(t, err.Error(), "unsupported bundle: apiServiceDefintions are not supported")
6675
}
@@ -76,7 +85,10 @@ func Test_BundleToHelmChartConverter_ToHelmChart_NoWebhooksWithoutCertProvider(t
7685
},
7786
)
7887

79-
_, err := converter.ToHelmChart(b, "install-namespace", "")
88+
config := map[string]interface{}{}
89+
config[bundle.BundleConfigInstallNamespaceKey] = "install-namespace"
90+
config[bundle.BundleConfigWatchNamespaceKey] = ""
91+
_, err := converter.ToHelmChart(b, config)
8092
require.Error(t, err)
8193
require.Contains(t, err.Error(), "webhookDefinitions are not supported")
8294
}
@@ -92,7 +104,10 @@ func Test_BundleToHelmChartConverter_ToHelmChart_WebhooksSupportDisabled(t *test
92104
},
93105
)
94106

95-
_, err := converter.ToHelmChart(b, "install-namespace", "")
107+
config := map[string]interface{}{}
108+
config[bundle.BundleConfigInstallNamespaceKey] = "install-namespace"
109+
config[bundle.BundleConfigWatchNamespaceKey] = ""
110+
_, err := converter.ToHelmChart(b, config)
96111
require.Error(t, err)
97112
require.Contains(t, err.Error(), "webhookDefinitions are not supported")
98113
}
@@ -112,7 +127,10 @@ func Test_BundleToHelmChartConverter_ToHelmChart_WebhooksWithCertProvider(t *tes
112127
},
113128
)
114129

115-
_, err := converter.ToHelmChart(b, "install-namespace", "")
130+
config := map[string]interface{}{}
131+
config[bundle.BundleConfigInstallNamespaceKey] = "install-namespace"
132+
config[bundle.BundleConfigWatchNamespaceKey] = ""
133+
_, err := converter.ToHelmChart(b, config)
116134
require.NoError(t, err)
117135
}
118136

@@ -142,7 +160,10 @@ func Test_BundleToHelmChartConverter_ToHelmChart_BundleRendererIntegration(t *te
142160
},
143161
)
144162

145-
_, err := converter.ToHelmChart(b, expectedInstallNamespace, expectedWatchNamespace)
163+
config := map[string]interface{}{}
164+
config[bundle.BundleConfigInstallNamespaceKey] = expectedInstallNamespace
165+
config[bundle.BundleConfigWatchNamespaceKey] = expectedWatchNamespace
166+
_, err := converter.ToHelmChart(b, config)
146167
require.NoError(t, err)
147168
}
148169

@@ -181,7 +202,10 @@ func Test_BundleToHelmChartConverter_ToHelmChart_Success(t *testing.T) {
181202
},
182203
)
183204

184-
chart, err := converter.ToHelmChart(b, "install-namespace", "")
205+
config := map[string]interface{}{}
206+
config[bundle.BundleConfigWatchNamespaceKey] = ""
207+
config[bundle.BundleConfigInstallNamespaceKey] = "install-namespace"
208+
chart, err := converter.ToHelmChart(b, config)
185209
require.NoError(t, err)
186210
require.NotNil(t, chart)
187211
require.NotNil(t, chart.Metadata)

internal/operator-controller/rukpak/render/registryv1/registryv1_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ func Test_Renderer_Success(t *testing.T) {
8181
},
8282
}
8383

84-
objs, err := registryv1.Renderer.Render(bundle, "install-namespace")
84+
objs, err := registryv1.Renderer.Render(bundle, render.WithInstallNamespace("install-namespace"))
8585
t.Log("Check renderer returns objects and no errors")
8686
require.NoError(t, err)
8787
require.NotEmpty(t, objs)
@@ -115,7 +115,7 @@ func Test_Renderer_Failure_UnsupportedKind(t *testing.T) {
115115
},
116116
}
117117

118-
objs, err := registryv1.Renderer.Render(bundle, "install-namespace")
118+
objs, err := registryv1.Renderer.Render(bundle, render.WithInstallNamespace("install-namespace"))
119119
t.Log("Check renderer returns objects and no errors")
120120
require.Error(t, err)
121121
require.Contains(t, err.Error(), "unsupported resource")

internal/operator-controller/rukpak/render/render.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ func (o *Options) apply(opts ...Option) *Options {
7474

7575
func (o *Options) validate(rv1 *bundle.RegistryV1) (*Options, []error) {
7676
var errs []error
77+
if o.InstallNamespace == "" {
78+
errs = append(errs, errors.New("install namespace must be specified"))
79+
}
7780
if len(o.TargetNamespaces) == 0 {
7881
errs = append(errs, errors.New("at least one target namespace must be specified"))
7982
}
@@ -88,6 +91,12 @@ func (o *Options) validate(rv1 *bundle.RegistryV1) (*Options, []error) {
8891

8992
type Option func(*Options)
9093

94+
func WithInstallNamespace(namespace string) Option {
95+
return func(o *Options) {
96+
o.InstallNamespace = namespace
97+
}
98+
}
99+
91100
func WithTargetNamespaces(namespaces ...string) Option {
92101
return func(o *Options) {
93102
o.TargetNamespaces = namespaces
@@ -111,7 +120,7 @@ type BundleRenderer struct {
111120
ResourceGenerators []ResourceGenerator
112121
}
113122

114-
func (r BundleRenderer) Render(rv1 bundle.RegistryV1, installNamespace string, opts ...Option) ([]client.Object, error) {
123+
func (r BundleRenderer) Render(rv1 bundle.RegistryV1, opts ...Option) ([]client.Object, error) {
115124
// validate bundle
116125
if err := r.BundleValidator.Validate(&rv1); err != nil {
117126
return nil, err
@@ -120,7 +129,6 @@ func (r BundleRenderer) Render(rv1 bundle.RegistryV1, installNamespace string, o
120129
// generate bundle objects
121130
genOpts, errs := (&Options{
122131
// default options
123-
InstallNamespace: installNamespace,
124132
TargetNamespaces: []string{metav1.NamespaceAll},
125133
UniqueNameGenerator: DefaultUniqueNameGenerator,
126134
CertificateProvider: nil,

internal/operator-controller/rukpak/render/render_test.go

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func Test_BundleRenderer_NoConfig(t *testing.T) {
2323
objs, err := renderer.Render(
2424
bundle.RegistryV1{
2525
CSV: MakeCSV(WithInstallModeSupportFor(v1alpha1.InstallModeTypeAllNamespaces)),
26-
}, "", nil)
26+
}, render.WithInstallNamespace("test-namespace"))
2727
require.NoError(t, err)
2828
require.Empty(t, objs)
2929
}
@@ -36,7 +36,7 @@ func Test_BundleRenderer_ValidatesBundle(t *testing.T) {
3636
},
3737
},
3838
}
39-
objs, err := renderer.Render(bundle.RegistryV1{}, "")
39+
objs, err := renderer.Render(bundle.RegistryV1{}, render.WithInstallNamespace("test-namespace"))
4040
require.Nil(t, objs)
4141
require.Error(t, err)
4242
require.Contains(t, err.Error(), "this bundle is invalid")
@@ -58,7 +58,7 @@ func Test_BundleRenderer_CreatesCorrectDefaultOptions(t *testing.T) {
5858
},
5959
}
6060

61-
_, _ = renderer.Render(bundle.RegistryV1{}, expectedInstallNamespace)
61+
_, _ = renderer.Render(bundle.RegistryV1{}, render.WithInstallNamespace(expectedInstallNamespace))
6262
}
6363

6464
func Test_BundleRenderer_ValidatesRenderOptions(t *testing.T) {
@@ -70,6 +70,14 @@ func Test_BundleRenderer_ValidatesRenderOptions(t *testing.T) {
7070
err error
7171
}{
7272
{
73+
name: "rejects empty install namespace",
74+
installNamespace: "",
75+
csv: MakeCSV(WithInstallModeSupportFor(v1alpha1.InstallModeTypeAllNamespaces)),
76+
opts: []render.Option{
77+
render.WithTargetNamespaces("some-namespace"),
78+
},
79+
err: errors.New("invalid option(s): install namespace must be specified"),
80+
}, {
7381
name: "rejects empty targetNamespaces",
7482
installNamespace: "install-namespace",
7583
csv: MakeCSV(WithInstallModeSupportFor(v1alpha1.InstallModeTypeAllNamespaces)),
@@ -164,10 +172,10 @@ func Test_BundleRenderer_ValidatesRenderOptions(t *testing.T) {
164172
} {
165173
t.Run(tc.name, func(t *testing.T) {
166174
renderer := render.BundleRenderer{}
175+
opts := append([]render.Option{render.WithInstallNamespace(tc.installNamespace)}, tc.opts...)
167176
_, err := renderer.Render(
168177
bundle.RegistryV1{CSV: tc.csv},
169-
tc.installNamespace,
170-
tc.opts...,
178+
opts...,
171179
)
172180
if tc.err == nil {
173181
require.NoError(t, err)
@@ -181,7 +189,7 @@ func Test_BundleRenderer_ValidatesRenderOptions(t *testing.T) {
181189

182190
func Test_BundleRenderer_AppliesUserOptions(t *testing.T) {
183191
isOptionApplied := false
184-
_, _ = render.BundleRenderer{}.Render(bundle.RegistryV1{}, "install-namespace", func(options *render.Options) {
192+
_, _ = render.BundleRenderer{}.Render(bundle.RegistryV1{}, render.WithInstallNamespace("install-namespace"), func(options *render.Options) {
185193
isOptionApplied = true
186194
})
187195
require.True(t, isOptionApplied)
@@ -227,7 +235,7 @@ func Test_BundleRenderer_CallsResourceGenerators(t *testing.T) {
227235
objs, err := renderer.Render(
228236
bundle.RegistryV1{
229237
CSV: MakeCSV(WithInstallModeSupportFor(v1alpha1.InstallModeTypeAllNamespaces)),
230-
}, "")
238+
}, render.WithInstallNamespace("test-namespace"))
231239
require.NoError(t, err)
232240
require.Equal(t, []client.Object{&corev1.Namespace{}, &corev1.Service{}, &appsv1.Deployment{}}, objs)
233241
}
@@ -246,7 +254,7 @@ func Test_BundleRenderer_ReturnsResourceGeneratorErrors(t *testing.T) {
246254
objs, err := renderer.Render(
247255
bundle.RegistryV1{
248256
CSV: MakeCSV(WithInstallModeSupportFor(v1alpha1.InstallModeTypeAllNamespaces)),
249-
}, "")
257+
}, render.WithInstallNamespace("test-namespace"))
250258
require.Nil(t, objs)
251259
require.Error(t, err)
252260
require.Contains(t, err.Error(), "generator error")

test/regression/convert/generate-manifests.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ func generateManifests(outputPath, bundleDir, installNamespace, watchNamespace s
9797
}
9898

9999
// Convert RegistryV1 to plain manifests
100-
objs, err := registryv1.Renderer.Render(regv1, installNamespace, render.WithTargetNamespaces(watchNamespace))
100+
objs, err := registryv1.Renderer.Render(regv1, render.WithInstallNamespace(installNamespace), render.WithTargetNamespaces(watchNamespace))
101101
if err != nil {
102102
return fmt.Errorf("error converting registry+v1 bundle: %w", err)
103103
}

0 commit comments

Comments
 (0)