@@ -69,7 +69,8 @@ func (i *StrategyDeploymentInstaller) createOrUpdateWebhook(caPEM []byte, desc v
69
69
i .createOrUpdateValidatingWebhook (ogNamespacelabelSelector , caPEM , desc )
70
70
case v1alpha1 .MutatingAdmissionWebhook :
71
71
i .createOrUpdateMutatingWebhook (ogNamespacelabelSelector , caPEM , desc )
72
-
72
+ case v1alpha1 .ConversionWebhook :
73
+ i .createOrUpdateConversionWebhook (caPEM , desc )
73
74
}
74
75
return nil
75
76
}
@@ -102,14 +103,6 @@ func (i *StrategyDeploymentInstaller) createOrUpdateMutatingWebhook(ogNamespacel
102
103
log .Errorf ("Webhooks: Error creating MutatingWebhookConfiguration: %v" , err )
103
104
return err
104
105
}
105
-
106
- // If dealing with a Conversion Webhook, make sure that the operator only supports the AllNamespace installMode.
107
- if len (desc .ConversionCRDs ) != 0 && isSingletonOperator (i ) {
108
- if err := createOrUpdateConversionCRDs (desc , webhook .Webhooks [0 ].ClientConfig , i ); err != nil {
109
- return err
110
- }
111
- }
112
- return nil
113
106
}
114
107
for _ , webhook := range existingWebhooks .Items {
115
108
// Update the list of webhooks
@@ -123,13 +116,6 @@ func (i *StrategyDeploymentInstaller) createOrUpdateMutatingWebhook(ogNamespacel
123
116
log .Warnf ("could not update MutatingWebhookConfiguration %s" , webhook .GetName ())
124
117
return err
125
118
}
126
-
127
- // If dealing with a Conversion Webhook, make sure that the operator only supports the AllNamespace installMode.
128
- if len (desc .ConversionCRDs ) != 0 && isSingletonOperator (i ) {
129
- if err := createOrUpdateConversionCRDs (desc , webhook .Webhooks [0 ].ClientConfig , i ); err != nil {
130
- return err
131
- }
132
- }
133
119
}
134
120
135
121
return nil
@@ -164,13 +150,6 @@ func (i *StrategyDeploymentInstaller) createOrUpdateValidatingWebhook(ogNamespac
164
150
return err
165
151
}
166
152
167
- // If dealing with a Conversion Webhook, make sure that the operator only supports the AllNamespace installMode.
168
- if len (desc .ConversionCRDs ) != 0 && isSingletonOperator (i ) {
169
- if err := createOrUpdateConversionCRDs (desc , webhook .Webhooks [0 ].ClientConfig , i ); err != nil {
170
- return err
171
- }
172
- }
173
-
174
153
return nil
175
154
}
176
155
for _ , webhook := range existingWebhooks .Items {
@@ -185,25 +164,13 @@ func (i *StrategyDeploymentInstaller) createOrUpdateValidatingWebhook(ogNamespac
185
164
log .Warnf ("could not update ValidatingWebhookConfiguration %s" , webhook .GetName ())
186
165
return err
187
166
}
188
-
189
- // If dealing with a Conversion Webhook, make sure that the operator only supports the AllNamespace installMode.
190
- if len (desc .ConversionCRDs ) != 0 && isSingletonOperator (i ) {
191
- if err := createOrUpdateConversionCRDs (desc , webhook .Webhooks [0 ].ClientConfig , i ); err != nil {
192
- return err
193
- }
194
- }
195
167
}
196
168
197
169
return nil
198
170
}
199
171
200
172
// check if csv supports only AllNamespaces install mode
201
- func isSingletonOperator (i * StrategyDeploymentInstaller ) bool {
202
- // get csv
203
- csv , err := i .strategyClient .GetOpLister ().OperatorsV1alpha1 ().ClusterServiceVersionLister ().ClusterServiceVersions (i .owner .GetNamespace ()).Get (i .owner .GetName ())
204
- if err != nil {
205
- log .Infof ("CSV not found, error: %s" , err .Error ())
206
- }
173
+ func isSingletonOperator (csv v1alpha1.ClusterServiceVersion ) bool {
207
174
// check if AllNamespaces is supported and other install modes are not supported
208
175
for _ , installMode := range csv .Spec .InstallModes {
209
176
if installMode .Type == v1alpha1 .InstallModeTypeAllNamespaces && ! installMode .Supported {
@@ -216,34 +183,39 @@ func isSingletonOperator(i *StrategyDeploymentInstaller) bool {
216
183
return true
217
184
}
218
185
219
- func createOrUpdateConversionCRDs ( desc v1alpha1. WebhookDescription , clientConfig admissionregistrationv1. WebhookClientConfig , i * StrategyDeploymentInstaller ) error {
186
+ func ( i * StrategyDeploymentInstaller ) createOrUpdateConversionWebhook ( caPEM [] byte , desc v1alpha1. WebhookDescription ) error {
220
187
// get a list of owned CRDs
221
- csv , err := i .strategyClient .GetOpLister ().OperatorsV1alpha1 ().ClusterServiceVersionLister ().ClusterServiceVersions (i .owner .GetNamespace ()).Get (i .owner .GetName ())
222
- if err != nil {
223
- log .Infof ("CSV not found, error: %s" , err .Error ())
188
+ csv , ok := i .owner .(* v1alpha1.ClusterServiceVersion )
189
+ if ! ok {
190
+ return fmt .Errorf ("ConversionWebhook owner must be a ClusterServiceVersion" )
191
+ }
192
+
193
+ if ! isSingletonOperator (* csv ) {
194
+ return fmt .Errorf ("CSVs with conversion webhooks must support only AllNamespaces" )
195
+ }
196
+
197
+ if len (desc .ConversionCRDs ) == 0 {
198
+ return fmt .Errorf ("Conversion Webhook must have at least one CRD specified" )
224
199
}
225
- ownedCRDs := csv .Spec .CustomResourceDefinitions .Owned
226
200
227
201
// iterate over all the ConversionCRDs
228
- for _ , ConversionCRD := range desc .ConversionCRDs {
229
- // check if CRD exists on cluster
230
- crd , err := i .strategyClient .GetOpClient ().ApiextensionsInterface ().ApiextensionsV1 ().CustomResourceDefinitions ().Get (context .TODO (), ConversionCRD , metav1.GetOptions {})
202
+ for _ , conversionCRD := range desc .ConversionCRDs {
203
+ // Get existing CRD on cluster
204
+ crd , err := i .strategyClient .GetOpClient ().ApiextensionsInterface ().ApiextensionsV1 ().CustomResourceDefinitions ().Get (context .TODO (), conversionCRD , metav1.GetOptions {})
231
205
if err != nil {
232
- log . Infof ( "CRD not found %s, error : %s " , ConversionCRD , err . Error () )
206
+ return fmt . Errorf ( "Unable to get CRD %s specified in Conversion Webhook : %v " , conversionCRD , err )
233
207
}
234
- log .Infof ("Found conversionCRDs %s" , ConversionCRD )
235
208
236
209
// check if this CRD is an owned CRD
237
210
foundCRD := false
238
- for _ , ownedCRD := range ownedCRDs {
239
- if ownedCRD .Name == crd .GetName () {
240
- log .Infof ("CSV %q owns CRD %q" , csv .GetName (), crd .GetName ())
211
+ for _ , ownedCRD := range csv .Spec .CustomResourceDefinitions .Owned {
212
+ if ownedCRD .Name == conversionCRD {
241
213
foundCRD = true
214
+ break
242
215
}
243
216
}
244
217
if ! foundCRD {
245
- log .Infof ("CSV %q does not own CRD %q" , csv .GetName (), crd .GetName ())
246
- return nil
218
+ return fmt .Errorf ("CSV %s does not own CRD %s" , csv .GetName (), conversionCRD )
247
219
}
248
220
249
221
// crd.Spec.Conversion.Strategy specifies how custom resources are converted between versions.
@@ -256,54 +228,41 @@ func createOrUpdateConversionCRDs(desc v1alpha1.WebhookDescription, clientConfig
256
228
// By default the strategy is none
257
229
// Reference:
258
230
// - https://v1-15.docs.kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definition-versioning/#specify-multiple-versions
259
- if crd .Spec .PreserveUnknownFields == true && crd .Spec .Conversion .Strategy == "Webhook" {
260
- log .Infof ("crd.Spec.PreserveUnknownFields must be false to let API Server call webhook to do the conversion." )
261
- return nil
231
+ if crd .Spec .PreserveUnknownFields != false {
232
+ return fmt .Errorf ("crd.Spec.PreserveUnknownFields must be false to let API Server call webhook to do the conversion" )
262
233
}
263
234
264
235
// Conversion WebhookClientConfig should not be set when Strategy is None
265
236
// https://v1-15.docs.kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definition-versioning/#specify-multiple-versions
266
237
// Conversion WebhookClientConfig needs to be set when Strategy is None
267
238
// https://v1-15.docs.kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definition-versioning/#configure-customresourcedefinition-to-use-conversion-webhooks
268
- if crd .Spec .Conversion .Strategy == "Webhook" {
269
- log .Infof ("Updating CRD" )
270
-
271
- // use user defined path for CRD conversion webhook, else set default value
272
- conversionWebhookPath := "/"
273
- if crd .Spec .Conversion .Webhook .ClientConfig .Service .Path != nil {
274
- conversionWebhookPath = * crd .Spec .Conversion .Webhook .ClientConfig .Service .Path
275
- }
276
239
277
- // use user defined port, else set it to admission webhook's port
278
- conversionWebhookPort := * clientConfig . Service . Port
279
- if crd . Spec . Conversion . Webhook . ClientConfig . Service . Port != nil {
280
- conversionWebhookPort = * crd . Spec . Conversion . Webhook . ClientConfig . Service . Port
281
- }
240
+ // use user defined path for CRD conversion webhook, else set default value
241
+ conversionWebhookPath := "/"
242
+ if desc . WebhookPath != nil {
243
+ conversionWebhookPath = * desc . WebhookPath
244
+ }
282
245
283
- // use user defined ConversionReviewVersions
284
- conversionWebhookConversionReviewVersions := crd .Spec .Conversion .Webhook .ConversionReviewVersions
285
-
286
- // Override Name, Namespace, and CABundle
287
- crd .Spec .Conversion = & apiextensionsv1.CustomResourceConversion {
288
- Strategy : "Webhook" ,
289
- Webhook : & apiextensionsv1.WebhookConversion {
290
- ClientConfig : & apiextensionsv1.WebhookClientConfig {
291
- Service : & apiextensionsv1.ServiceReference {
292
- Namespace : clientConfig .Service .Namespace ,
293
- Name : clientConfig .Service .Name ,
294
- Path : & conversionWebhookPath ,
295
- Port : & conversionWebhookPort ,
296
- },
297
- CABundle : clientConfig .CABundle ,
246
+ // Override Name, Namespace, and CABundle
247
+ crd .Spec .Conversion = & apiextensionsv1.CustomResourceConversion {
248
+ Strategy : "Webhook" ,
249
+ Webhook : & apiextensionsv1.WebhookConversion {
250
+ ClientConfig : & apiextensionsv1.WebhookClientConfig {
251
+ Service : & apiextensionsv1.ServiceReference {
252
+ Namespace : i .owner .GetNamespace (),
253
+ Name : desc .DomainName () + "-service" ,
254
+ Path : & conversionWebhookPath ,
255
+ Port : & desc .ContainerPort ,
298
256
},
299
- ConversionReviewVersions : conversionWebhookConversionReviewVersions ,
257
+ CABundle : caPEM ,
300
258
},
301
- }
259
+ ConversionReviewVersions : desc .AdmissionReviewVersions ,
260
+ },
261
+ }
302
262
303
- // update CRD conversion Specs
304
- if _ , err = i .strategyClient .GetOpClient ().ApiextensionsInterface ().ApiextensionsV1 ().CustomResourceDefinitions ().Update (context .TODO (), crd , metav1.UpdateOptions {}); err != nil {
305
- log .Infof ("CRD %s could not be updated, error: %s" , ConversionCRD , err .Error ())
306
- }
263
+ // update CRD conversion Specs
264
+ if _ , err = i .strategyClient .GetOpClient ().ApiextensionsInterface ().ApiextensionsV1 ().CustomResourceDefinitions ().Update (context .TODO (), crd , metav1.UpdateOptions {}); err != nil {
265
+ return fmt .Errorf ("Error updating CRD with Conversion info: %v" , err )
307
266
}
308
267
}
309
268
0 commit comments