@@ -51,11 +51,6 @@ func (i *OperatorInstall) BindFlags(fs *pflag.FlagSet) {
5151}
5252
5353func (i * OperatorInstall ) Run (ctx context.Context ) (* v1alpha1.ClusterServiceVersion , error ) {
54- og , err := i .getOperatorGroup (ctx )
55- if err != nil {
56- return nil , err
57- }
58-
5954 pm , err := i .getPackageManifest (ctx )
6055 if err != nil {
6156 return nil , fmt .Errorf ("get package manifest: %v" , err )
@@ -65,24 +60,8 @@ func (i *OperatorInstall) Run(ctx context.Context) (*v1alpha1.ClusterServiceVers
6560 if err != nil {
6661 return nil , fmt .Errorf ("get package channel: %v" , err )
6762 }
68- supported := getSupportedInstallModes (pc .CurrentCSVDesc .InstallModes )
69- if ! i .InstallMode .IsEmpty () {
70- supported = supported .Intersection (sets .NewString (string (i .InstallMode .InstallModeType )))
71- if supported .Len () == 0 {
72- return nil , fmt .Errorf ("operator %q does not support install mode %q" , pm .Name , i .InstallMode .InstallModeType )
73- }
74- }
7563
76- if og == nil {
77- if i .CreateOperatorGroup {
78- if og , err = i .createOperatorGroup (ctx , supported ); err != nil {
79- return nil , fmt .Errorf ("create operator group: %v" , err )
80- }
81- log .Printf ("operatorgroup %q created" , og .Name )
82- } else {
83- return nil , fmt .Errorf ("namespace %q has no existing operator group; use --create-operator-group to create one automatically" , i .config .Namespace )
84- }
85- } else if err := i .validateOperatorGroup (* og , supported ); err != nil {
64+ if _ , err := i .ensureOperatorGroup (ctx , pm , pc ); err != nil {
8665 return nil , err
8766 }
8867
@@ -111,6 +90,81 @@ func (i *OperatorInstall) Run(ctx context.Context) (*v1alpha1.ClusterServiceVers
11190 return csv , nil
11291}
11392
93+ func (i * OperatorInstall ) getPackageManifest (ctx context.Context ) (* operatorsv1.PackageManifest , error ) {
94+ pm := & operatorsv1.PackageManifest {}
95+ key := types.NamespacedName {
96+ Namespace : i .config .Namespace ,
97+ Name : i .Package ,
98+ }
99+ if err := i .config .Client .Get (ctx , key , pm ); err != nil {
100+ return nil , err
101+ }
102+ return pm , nil
103+ }
104+
105+ func (i * OperatorInstall ) getPackageChannel (pm * operatorsv1.PackageManifest ) (* operatorsv1.PackageChannel , error ) {
106+ if i .Channel == "" {
107+ i .Channel = pm .Status .DefaultChannel
108+ }
109+ var packageChannel * operatorsv1.PackageChannel
110+ for _ , ch := range pm .Status .Channels {
111+ if ch .Name == i .Channel {
112+ packageChannel = & ch
113+ }
114+ }
115+ if packageChannel == nil {
116+ return nil , fmt .Errorf ("channel %q does not exist for package %q" , i .Channel , i .Package )
117+ }
118+ return packageChannel , nil
119+ }
120+
121+ func (i * OperatorInstall ) ensureOperatorGroup (ctx context.Context , pm * operatorsv1.PackageManifest , pc * operatorsv1.PackageChannel ) (* v1.OperatorGroup , error ) {
122+ og , err := i .getOperatorGroup (ctx )
123+ if err != nil {
124+ return nil , err
125+ }
126+
127+ supported := getSupportedInstallModes (pc .CurrentCSVDesc .InstallModes )
128+ if supported .Len () == 0 {
129+ return nil , fmt .Errorf ("operator %q is not installable: no supported install modes" , pm .Name )
130+ }
131+
132+ if ! i .InstallMode .IsEmpty () {
133+ if i .InstallMode .InstallModeType == v1alpha1 .InstallModeTypeSingleNamespace || i .InstallMode .InstallModeType == v1alpha1 .InstallModeTypeMultiNamespace {
134+ targetNsSet := sets .NewString (i .InstallMode .TargetNamespaces ... )
135+ if ! supported .Has (string (v1alpha1 .InstallModeTypeOwnNamespace )) && targetNsSet .Has (i .config .Namespace ) {
136+ return nil , fmt .Errorf ("cannot watch namespace %q: operator %q does not support install mode %q" , i .config .Namespace , pm .Name , v1alpha1 .InstallModeTypeOwnNamespace )
137+ }
138+ }
139+ if i .InstallMode .InstallModeType == v1alpha1 .InstallModeTypeSingleNamespace && i .InstallMode .TargetNamespaces [0 ] == i .config .Namespace {
140+ return nil , fmt .Errorf ("use install mode %q to watch operator's namespace %q" , v1alpha1 .InstallModeTypeOwnNamespace , i .config .Namespace )
141+ }
142+
143+ supported = supported .Intersection (sets .NewString (string (i .InstallMode .InstallModeType )))
144+ if supported .Len () == 0 {
145+ return nil , fmt .Errorf ("operator %q does not support install mode %q" , pm .Name , i .InstallMode .InstallModeType )
146+ }
147+ }
148+
149+ if og == nil {
150+ if i .CreateOperatorGroup {
151+ targetNamespaces , err := i .getTargetNamespaces (supported )
152+ if err != nil {
153+ return nil , err
154+ }
155+ if og , err = i .createOperatorGroup (ctx , targetNamespaces ); err != nil {
156+ return nil , fmt .Errorf ("create operator group: %v" , err )
157+ }
158+ log .Printf ("operatorgroup %q created" , og .Name )
159+ } else {
160+ return nil , fmt .Errorf ("namespace %q has no existing operator group; use --create-operator-group to create one automatically" , i .config .Namespace )
161+ }
162+ } else if err := i .validateOperatorGroup (* og , supported ); err != nil {
163+ return nil , err
164+ }
165+ return og , nil
166+ }
167+
114168func (i OperatorInstall ) getOperatorGroup (ctx context.Context ) (* v1.OperatorGroup , error ) {
115169 ogs := & v1.OperatorGroupList {}
116170 err := i .config .Client .List (ctx , ogs , client .InNamespace (i .config .Namespace ))
@@ -128,34 +182,43 @@ func (i OperatorInstall) getOperatorGroup(ctx context.Context) (*v1.OperatorGrou
128182 }
129183}
130184
131- func (i * OperatorInstall ) getPackageManifest (ctx context.Context ) (* operatorsv1.PackageManifest , error ) {
132- pm := & operatorsv1.PackageManifest {}
133- key := types.NamespacedName {
134- Namespace : i .config .Namespace ,
135- Name : i .Package ,
136- }
137- if err := i .config .Client .Get (ctx , key , pm ); err != nil {
138- return nil , err
185+ func getSupportedInstallModes (csvInstallModes []v1alpha1.InstallMode ) sets.String {
186+ supported := sets .NewString ()
187+ for _ , im := range csvInstallModes {
188+ if im .Supported {
189+ supported .Insert (string (im .Type ))
190+ }
139191 }
140- return pm , nil
192+ return supported
141193}
142194
143- func (i * OperatorInstall ) createOperatorGroup (ctx context.Context , supported sets.String ) (* v1.OperatorGroup , error ) {
144- og := & v1.OperatorGroup {}
145- og .SetName (i .config .Namespace )
146- og .SetNamespace (i .config .Namespace )
147-
195+ func (i * OperatorInstall ) getTargetNamespaces (supported sets.String ) ([]string , error ) {
148196 switch {
149- case supported .HasAny (
150- string (v1alpha1 .InstallModeTypeAllNamespaces ),
151- string (v1alpha1 .InstallModeTypeSingleNamespace ),
152- string (v1alpha1 .InstallModeTypeMultiNamespace )):
153- og .Spec .TargetNamespaces = i .InstallMode .TargetNamespaces
197+ case supported .Has (string (v1alpha1 .InstallModeTypeAllNamespaces )):
198+ return nil , nil
154199 case supported .Has (string (v1alpha1 .InstallModeTypeOwnNamespace )):
155- og .Spec .TargetNamespaces = []string {i .config .Namespace }
200+ return []string {i .config .Namespace }, nil
201+ case supported .Has (string (v1alpha1 .InstallModeTypeSingleNamespace )):
202+ if len (i .InstallMode .TargetNamespaces ) != 1 {
203+ return nil , fmt .Errorf ("install mode %q requires explicit target namespace" , v1alpha1 .InstallModeTypeSingleNamespace )
204+ }
205+ return i .InstallMode .TargetNamespaces , nil
206+ case supported .Has (string (v1alpha1 .InstallModeTypeMultiNamespace )):
207+ if len (i .InstallMode .TargetNamespaces ) == 0 {
208+ return nil , fmt .Errorf ("install mode %q requires explicit target namespaces" , v1alpha1 .InstallModeTypeMultiNamespace )
209+ }
210+ return i .InstallMode .TargetNamespaces , nil
156211 default :
157212 return nil , fmt .Errorf ("no supported install modes" )
158213 }
214+ }
215+
216+ func (i * OperatorInstall ) createOperatorGroup (ctx context.Context , targetNamespaces []string ) (* v1.OperatorGroup , error ) {
217+ og := & v1.OperatorGroup {}
218+ og .SetName (i .config .Namespace )
219+ og .SetNamespace (i .config .Namespace )
220+ og .Spec .TargetNamespaces = targetNamespaces
221+
159222 if err := i .config .Client .Create (ctx , og ); err != nil {
160223 return nil , err
161224 }
@@ -184,32 +247,6 @@ func (i *OperatorInstall) validateOperatorGroup(og v1.OperatorGroup, supported s
184247 panic (fmt .Sprintf ("unknown install mode %q" , i .InstallMode .InstallModeType ))
185248}
186249
187- func getSupportedInstallModes (csvInstallModes []v1alpha1.InstallMode ) sets.String {
188- supported := sets .NewString ()
189- for _ , im := range csvInstallModes {
190- if im .Supported {
191- supported .Insert (string (im .Type ))
192- }
193- }
194- return supported
195- }
196-
197- func (i * OperatorInstall ) getPackageChannel (pm * operatorsv1.PackageManifest ) (* operatorsv1.PackageChannel , error ) {
198- if i .Channel == "" {
199- i .Channel = pm .Status .DefaultChannel
200- }
201- var packageChannel * operatorsv1.PackageChannel
202- for _ , ch := range pm .Status .Channels {
203- if ch .Name == i .Channel {
204- packageChannel = & ch
205- }
206- }
207- if packageChannel == nil {
208- return nil , fmt .Errorf ("channel %q does not exist for package %q" , i .Channel , i .Package )
209- }
210- return packageChannel , nil
211- }
212-
213250func (i * OperatorInstall ) createSubscription (ctx context.Context , pm * operatorsv1.PackageManifest , pc * operatorsv1.PackageChannel ) (* v1alpha1.Subscription , error ) {
214251 opts := []subscription.Option {
215252 subscription .InstallPlanApproval (i .Approval .Approval ),
0 commit comments