@@ -28,7 +28,6 @@ type OperatorInstall struct {
28
28
Version string
29
29
Approval subscription.ApprovalValue
30
30
WatchNamespaces []string
31
- InstallMode operator.InstallMode
32
31
CleanupTimeout time.Duration
33
32
CreateOperatorGroup bool
34
33
@@ -43,13 +42,6 @@ func NewOperatorInstall(cfg *action.Configuration) *OperatorInstall {
43
42
}
44
43
45
44
func (i * OperatorInstall ) Run (ctx context.Context ) (* v1alpha1.ClusterServiceVersion , error ) {
46
- if len (i .WatchNamespaces ) > 0 && ! i .InstallMode .IsEmpty () {
47
- return nil , fmt .Errorf ("WatchNamespaces and InstallMode options are mutually exclusive" )
48
- }
49
- if i .InstallMode .IsEmpty () {
50
- i .configureInstallModeFromWatch ()
51
- }
52
-
53
45
pm , err := i .getPackageManifest (ctx )
54
46
if err != nil {
55
47
return nil , fmt .Errorf ("get package manifest: %v" , err )
@@ -89,19 +81,20 @@ func (i *OperatorInstall) Run(ctx context.Context) (*v1alpha1.ClusterServiceVers
89
81
return csv , nil
90
82
}
91
83
92
- func (i * OperatorInstall ) configureInstallModeFromWatch () {
93
- i .InstallMode .TargetNamespaces = i .WatchNamespaces
94
- switch len (i .InstallMode .TargetNamespaces ) {
84
+ func (i * OperatorInstall ) possibleInstallModes (watchNamespaces []string ) sets.String {
85
+ switch len (watchNamespaces ) {
95
86
case 0 :
96
- i .InstallMode .InstallModeType = v1alpha1 .InstallModeTypeAllNamespaces
87
+ return sets .NewString (
88
+ string (v1alpha1 .InstallModeTypeAllNamespaces ),
89
+ string (v1alpha1 .InstallModeTypeOwnNamespace ),
90
+ )
97
91
case 1 :
98
- if i .InstallMode .TargetNamespaces [0 ] == i .config .Namespace {
99
- i .InstallMode .InstallModeType = v1alpha1 .InstallModeTypeOwnNamespace
100
- } else {
101
- i .InstallMode .InstallModeType = v1alpha1 .InstallModeTypeSingleNamespace
92
+ if watchNamespaces [0 ] == i .config .Namespace {
93
+ return sets .NewString (string (v1alpha1 .InstallModeTypeOwnNamespace ))
102
94
}
95
+ return sets .NewString (string (v1alpha1 .InstallModeTypeSingleNamespace ))
103
96
default :
104
- i . InstallMode . InstallModeType = v1alpha1 .InstallModeTypeMultiNamespace
97
+ return sets . NewString ( string ( v1alpha1 .InstallModeTypeMultiNamespace ))
105
98
}
106
99
}
107
100
@@ -123,47 +116,66 @@ func (i *OperatorInstall) ensureOperatorGroup(ctx context.Context, pm *operator.
123
116
return nil , err
124
117
}
125
118
126
- supported := pc .GetSupportedInstallModes ()
127
- if supported .Len () == 0 {
128
- return nil , fmt .Errorf ("operator %q is not installable: no supported install modes" , pm .Name )
119
+ operatorInstallModes := pc .GetSupportedInstallModes ()
120
+ if operatorInstallModes .Len () == 0 {
121
+ return nil , fmt .Errorf ("operator %q is not installable: operator defined no supported install modes" , pm .Name )
129
122
}
130
123
131
- if ! i .InstallMode .IsEmpty () {
132
- if i .InstallMode .InstallModeType == v1alpha1 .InstallModeTypeSingleNamespace || i .InstallMode .InstallModeType == v1alpha1 .InstallModeTypeMultiNamespace {
133
- targetNsSet := sets .NewString (i .InstallMode .TargetNamespaces ... )
134
- if ! supported .Has (string (v1alpha1 .InstallModeTypeOwnNamespace )) && targetNsSet .Has (i .config .Namespace ) {
135
- return nil , fmt .Errorf ("cannot watch namespace %q: operator %q does not support install mode %q" , i .config .Namespace , pm .Name , v1alpha1 .InstallModeTypeOwnNamespace )
136
- }
137
- }
138
- if i .InstallMode .InstallModeType == v1alpha1 .InstallModeTypeSingleNamespace && i .InstallMode .TargetNamespaces [0 ] == i .config .Namespace {
139
- return nil , fmt .Errorf ("use install mode %q to watch operator's namespace %q" , v1alpha1 .InstallModeTypeOwnNamespace , i .config .Namespace )
140
- }
124
+ desired := i .possibleInstallModes (i .WatchNamespaces )
141
125
142
- supported = supported .Intersection (sets .NewString (string (i .InstallMode .InstallModeType )))
143
- if supported .Len () == 0 {
144
- return nil , fmt .Errorf ("operator %q does not support install mode %q" , pm .Name , i .InstallMode .InstallModeType )
145
- }
126
+ supported := operatorInstallModes .Intersection (desired )
127
+ if supported .Len () == 0 {
128
+ return nil , fmt .Errorf ("operator %q is not installable: install modes supported by operator (%q) not compatible with install modes supported by desired watches (%q)" ,
129
+ pm .Name ,
130
+ strings .Join (operatorInstallModes .List (), "," ),
131
+ strings .Join (desired .List (), "," ),
132
+ )
146
133
}
147
134
148
- if og == nil {
135
+ if og != nil {
136
+ if err := i .validateOperatorGroup (* og , operatorInstallModes , desired ); err != nil {
137
+ return nil , fmt .Errorf ("operator %q not installable: %v" , pm .Name , err )
138
+ }
139
+ } else {
149
140
if i .CreateOperatorGroup {
150
- targetNamespaces , err := i .getTargetNamespaces (supported )
151
- if err != nil {
152
- return nil , err
153
- }
141
+ targetNamespaces := i .getTargetNamespaces (supported )
154
142
if og , err = i .createOperatorGroup (ctx , targetNamespaces ); err != nil {
155
143
return nil , fmt .Errorf ("create operator group: %v" , err )
156
144
}
157
145
i .Logf ("operatorgroup %q created" , og .Name )
158
146
} else {
159
147
return nil , fmt .Errorf ("namespace %q has no existing operator group; use --create-operator-group to create one automatically" , i .config .Namespace )
160
148
}
161
- } else if err := i .validateOperatorGroup (* og , supported ); err != nil {
162
- return nil , err
163
149
}
164
150
return og , nil
165
151
}
166
152
153
+ func (i OperatorInstall ) validateOperatorGroup (og v1.OperatorGroup , operatorInstallModes , desired sets.String ) error {
154
+ ogSupported := i .possibleInstallModes (og .Status .Namespaces )
155
+
156
+ if operatorInstallModes .Intersection (ogSupported ).Len () == 0 {
157
+ return fmt .Errorf ("install modes supported by operator (%q) not compatible with install modes supported by existing operator group (%q)" ,
158
+ strings .Join (operatorInstallModes .List (), "," ),
159
+ strings .Join (ogSupported .List (), "," ),
160
+ )
161
+ }
162
+
163
+ if desired .Intersection (ogSupported ).Len () == 0 {
164
+ return fmt .Errorf ("install modes supported by desired watches (%q) not compatible with install modes supported by existing operator group (%q)" ,
165
+ strings .Join (desired .List (), "," ),
166
+ strings .Join (ogSupported .List (), "," ),
167
+ )
168
+ }
169
+ supported := operatorInstallModes .Intersection (desired )
170
+ if supported .Intersection (ogSupported ).Len () == 0 {
171
+ return fmt .Errorf ("install modes supported by operator and desired watches (%q) not compatible with install modes supported by existing operator group (%q)" ,
172
+ strings .Join (supported .List (), "," ),
173
+ strings .Join (ogSupported .List (), "," ),
174
+ )
175
+ }
176
+ return nil
177
+ }
178
+
167
179
func (i OperatorInstall ) getOperatorGroup (ctx context.Context ) (* v1.OperatorGroup , error ) {
168
180
ogs := & v1.OperatorGroupList {}
169
181
err := i .config .Client .List (ctx , ogs , client .InNamespace (i .config .Namespace ))
@@ -181,24 +193,14 @@ func (i OperatorInstall) getOperatorGroup(ctx context.Context) (*v1.OperatorGrou
181
193
}
182
194
}
183
195
184
- func (i * OperatorInstall ) getTargetNamespaces (supported sets.String ) ( []string , error ) {
196
+ func (i * OperatorInstall ) getTargetNamespaces (supported sets.String ) []string {
185
197
switch {
186
198
case supported .Has (string (v1alpha1 .InstallModeTypeAllNamespaces )):
187
- return nil , nil
199
+ return nil
188
200
case supported .Has (string (v1alpha1 .InstallModeTypeOwnNamespace )):
189
- return []string {i .config .Namespace }, nil
190
- case supported .Has (string (v1alpha1 .InstallModeTypeSingleNamespace )):
191
- if len (i .InstallMode .TargetNamespaces ) != 1 {
192
- return nil , fmt .Errorf ("install mode %q requires explicit target namespace" , v1alpha1 .InstallModeTypeSingleNamespace )
193
- }
194
- return i .InstallMode .TargetNamespaces , nil
195
- case supported .Has (string (v1alpha1 .InstallModeTypeMultiNamespace )):
196
- if len (i .InstallMode .TargetNamespaces ) == 0 {
197
- return nil , fmt .Errorf ("install mode %q requires explicit target namespaces" , v1alpha1 .InstallModeTypeMultiNamespace )
198
- }
199
- return i .InstallMode .TargetNamespaces , nil
201
+ return []string {i .config .Namespace }
200
202
default :
201
- return nil , fmt . Errorf ( "no supported install modes" )
203
+ return i . WatchNamespaces
202
204
}
203
205
}
204
206
@@ -214,28 +216,6 @@ func (i *OperatorInstall) createOperatorGroup(ctx context.Context, targetNamespa
214
216
return og , nil
215
217
}
216
218
217
- func (i * OperatorInstall ) validateOperatorGroup (og v1.OperatorGroup , supported sets.String ) error {
218
- ogTargetNs := sets .NewString (og .Spec .TargetNamespaces ... )
219
- imTargetNs := sets .NewString (i .InstallMode .TargetNamespaces ... )
220
- ownNamespaceNs := sets .NewString (i .config .Namespace )
221
-
222
- if supported .Has (string (v1alpha1 .InstallModeTypeAllNamespaces )) && len (og .Spec .TargetNamespaces ) == 0 ||
223
- supported .Has (string (v1alpha1 .InstallModeTypeOwnNamespace )) && ogTargetNs .Equal (ownNamespaceNs ) ||
224
- supported .Has (string (v1alpha1 .InstallModeTypeSingleNamespace )) && ogTargetNs .Equal (imTargetNs ) ||
225
- supported .Has (string (v1alpha1 .InstallModeTypeMultiNamespace )) && ogTargetNs .Equal (imTargetNs ) {
226
- return nil
227
- }
228
-
229
- switch i .InstallMode .InstallModeType {
230
- case v1alpha1 .InstallModeTypeAllNamespaces , v1alpha1 .InstallModeTypeOwnNamespace ,
231
- v1alpha1 .InstallModeTypeSingleNamespace , v1alpha1 .InstallModeTypeMultiNamespace :
232
- return fmt .Errorf ("existing operatorgroup %q is not compatible with install mode %q" , og .Name , i .InstallMode )
233
- case "" :
234
- return fmt .Errorf ("existing operatorgroup %q is not compatible with any supported package install modes" , og .Name )
235
- }
236
- panic (fmt .Sprintf ("unknown install mode %q" , i .InstallMode .InstallModeType ))
237
- }
238
-
239
219
func (i * OperatorInstall ) createSubscription (ctx context.Context , pm * operator.PackageManifest , pc * operator.PackageChannel ) (* v1alpha1.Subscription , error ) {
240
220
opts := []subscription.Option {
241
221
subscription .InstallPlanApproval (i .Approval .Approval ),
0 commit comments