7
7
8
8
"helm.sh/helm/v3/pkg/chart"
9
9
10
+ "github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/bundle"
10
11
"github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/bundle/source"
11
12
"github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/render"
12
13
)
@@ -18,11 +19,27 @@ type BundleToHelmChartConverter struct {
18
19
}
19
20
20
21
func (r * BundleToHelmChartConverter ) ToHelmChart (bundle source.BundleSource , installNamespace string , watchNamespace string ) (* chart.Chart , error ) {
22
+ config := make (map [string ]interface {})
23
+
24
+ if watchNamespace != "" {
25
+ config ["watchNamespace" ] = watchNamespace
26
+ }
27
+
21
28
rv1 , err := bundle .GetBundle ()
22
29
if err != nil {
23
30
return nil , err
24
31
}
25
32
33
+ if _ , present := config ["watchNamespace" ]; ! present {
34
+ config ["watchNamespace" ] = r .deriveDefaultWatchNamespace (& rv1 , installNamespace )
35
+ }
36
+
37
+ // Derive target namespaces from watchNamespace
38
+ targetNamespaces , err := r .deriveTargetNamespaces (config )
39
+ if err != nil {
40
+ return nil , fmt .Errorf ("error deriving target namespaces: %w" , err )
41
+ }
42
+
26
43
if len (rv1 .CSV .Spec .APIServiceDefinitions .Owned ) > 0 {
27
44
return nil , fmt .Errorf ("unsupported bundle: apiServiceDefintions are not supported" )
28
45
}
@@ -41,7 +58,7 @@ func (r *BundleToHelmChartConverter) ToHelmChart(bundle source.BundleSource, ins
41
58
42
59
objs , err := r .BundleRenderer .Render (
43
60
rv1 , installNamespace ,
44
- render .WithTargetNamespaces (watchNamespace ),
61
+ render .WithTargetNamespaces (targetNamespaces ... ),
45
62
render .WithCertificateProvider (r .CertificateProvider ),
46
63
)
47
64
@@ -77,3 +94,55 @@ func (r *BundleToHelmChartConverter) ToHelmChart(bundle source.BundleSource, ins
77
94
78
95
return chrt , nil
79
96
}
97
+
98
+ // deriveDefaultWatchNamespace determines the default watch namespace based on bundle's supported install modes
99
+ func (r * BundleToHelmChartConverter ) deriveDefaultWatchNamespace (rv1 * bundle.RegistryV1 , installNamespace string ) string {
100
+ // Check what install modes the bundle supports
101
+ supportedModes := make (map [string ]bool )
102
+ for _ , installMode := range rv1 .CSV .Spec .InstallModes {
103
+ if installMode .Supported {
104
+ supportedModes [string (installMode .Type )] = true
105
+ }
106
+ }
107
+
108
+ // Priority order for defaults:
109
+ // 1. If supports AllNamespaces -> "" (AllNamespaces)
110
+ // 2. If supports OwnNamespace -> installNamespace (OwnNamespace)
111
+ // 3. If supports SingleNamespace -> installNamespace (treat as OwnNamespace since we can't know the target)
112
+ // 4. Fallback -> "" (AllNamespaces)
113
+
114
+ if supportedModes ["AllNamespaces" ] {
115
+ return "" // Empty string means AllNamespaces
116
+ }
117
+ if supportedModes ["OwnNamespace" ] {
118
+ return installNamespace // OwnNamespace
119
+ }
120
+ if supportedModes ["SingleNamespace" ] {
121
+ return installNamespace // Treat as OwnNamespace since we don't know the target namespace
122
+ }
123
+
124
+ // Fallback to AllNamespaces
125
+ return ""
126
+ }
127
+
128
+ // deriveTargetNamespaces converts config.watchNamespace to the target namespaces for the renderer
129
+ func (r * BundleToHelmChartConverter ) deriveTargetNamespaces (cfg map [string ]interface {}) ([]string , error ) {
130
+ watchNsRaw , exists := cfg ["watchNamespace" ]
131
+ if ! exists {
132
+ // No configuration provided, default to AllNamespaces
133
+ return []string {"" }, nil
134
+ }
135
+
136
+ watchNs , ok := watchNsRaw .(string )
137
+ if ! ok {
138
+ return nil , fmt .Errorf ("watchNamespace must be a string, got %T" , watchNsRaw )
139
+ }
140
+
141
+ if watchNs == "" {
142
+ // Empty string means AllNamespaces
143
+ return []string {"" }, nil
144
+ } else {
145
+ // Non-empty string means SingleNamespace (or OwnNamespace if it equals installNamespace)
146
+ return []string {watchNs }, nil
147
+ }
148
+ }
0 commit comments