@@ -21,6 +21,8 @@ const (
21
21
defaultCaPath = "/etc/certs/ca.crt"
22
22
webhookServiceName = "devbox-server"
23
23
devContainerWebhookCfgName = "devcontainer-mutate-webhooks"
24
+ imageManagerWebhookCfgName = "imagemanager-mutate-webhooks"
25
+ imageManagerWebhookPrefix = "imagemanager-webhook"
24
26
mutatingWebhookNamePrefix = "devcontainer-webhook"
25
27
helmRelease = "meta.helm.sh/release-name"
26
28
helmReleaseNamespace = "meta.helm.sh/release-namespace"
31
33
webhookServiceNamespace = & constants .Namespace
32
34
webhookPath = "/webhook/devcontainer"
33
35
WebhookPort int32 = 8083
36
+
37
+ imageManagerWebhookPath = "/webhook/imagemanager"
34
38
// WebhookServerListenAddress = webhookServiceName + ":" + strconv.Itoa(int(WebhookPort))
35
39
36
40
// codecs is the codec factory used by the deserialzer
@@ -202,7 +206,150 @@ func (wh *Webhook) DeleteDevContainerMutatingWebhook() error {
202
206
return nil
203
207
}
204
208
209
+ func (wh * Webhook ) CreateOrUpdateImageManagerMutatingWebhook () error {
210
+ failurePolicy := admissionregv1 .Fail
211
+ matchPolicy := admissionregv1 .Exact
212
+ webhookTimeout := int32 (30 )
213
+
214
+ caBundle , err := os .ReadFile (defaultCaPath )
215
+ if err != nil {
216
+ return err
217
+ }
218
+
219
+ mwhLabels := map [string ]string {"velero.io/exclude-from-backup" : "true" }
220
+ mwh := admissionregv1.MutatingWebhookConfiguration {
221
+ ObjectMeta : metav1.ObjectMeta {
222
+ Name : imageManagerWebhookCfgName ,
223
+ Labels : mwhLabels ,
224
+ },
225
+ Webhooks : []admissionregv1.MutatingWebhook {},
226
+ }
227
+ imwh := admissionregv1.MutatingWebhook {
228
+ Name : imageManagerWebhookName (),
229
+ ClientConfig : admissionregv1.WebhookClientConfig {
230
+ CABundle : caBundle ,
231
+ Service : & admissionregv1.ServiceReference {
232
+ Namespace : * webhookServiceNamespace ,
233
+ Name : webhookServiceName ,
234
+ Path : & imageManagerWebhookPath ,
235
+ Port : & WebhookPort ,
236
+ },
237
+ },
238
+ FailurePolicy : & failurePolicy ,
239
+ MatchPolicy : & matchPolicy ,
240
+ Rules : []admissionregv1.RuleWithOperations {
241
+ {
242
+ Operations : []admissionregv1.OperationType {admissionregv1 .Create },
243
+ Rule : admissionregv1.Rule {
244
+ APIGroups : []string {"app.bytetrade.io" },
245
+ APIVersions : []string {"*" },
246
+ Resources : []string {"imagemanagers" },
247
+ },
248
+ },
249
+ },
250
+ ObjectSelector : & metav1.LabelSelector {
251
+ MatchExpressions : []metav1.LabelSelectorRequirement {
252
+ {
253
+ Key : constants .DevOwnerLabel ,
254
+ Operator : metav1 .LabelSelectorOpIn ,
255
+ Values : []string {constants .Owner },
256
+ },
257
+ },
258
+ },
259
+ SideEffects : func () * admissionregv1.SideEffectClass {
260
+ sideEffect := admissionregv1 .SideEffectClassNoneOnDryRun
261
+ return & sideEffect
262
+ }(),
263
+ TimeoutSeconds : & webhookTimeout ,
264
+ AdmissionReviewVersions : []string {"v1" },
265
+ }
266
+ mwh .Webhooks = append (mwh .Webhooks , imwh )
267
+ if _ , err = wh .KubeClient .AdmissionregistrationV1 ().MutatingWebhookConfigurations ().Create (context .TODO (), & mwh , metav1.CreateOptions {}); err != nil {
268
+ if apierrors .IsAlreadyExists (err ) {
269
+ err = retry .RetryOnConflict (retry .DefaultRetry , func () error {
270
+ existing , err := wh .KubeClient .AdmissionregistrationV1 ().MutatingWebhookConfigurations ().Get (context .TODO (), mwh .Name , metav1.GetOptions {})
271
+ if err != nil {
272
+ klog .Error ("Error getting MutatingWebhookConfiguration " , err )
273
+ return err
274
+ }
275
+ found := false
276
+ for i , w := range existing .Webhooks {
277
+ if w .Name == imwh .Name {
278
+ found = true
279
+ existing .Webhooks [i ] = imwh
280
+ break
281
+ }
282
+ }
283
+ if ! found {
284
+ existing .Webhooks = append (existing .Webhooks , imwh )
285
+ }
286
+ _ , err = wh .KubeClient .AdmissionregistrationV1 ().MutatingWebhookConfigurations ().Update (context .TODO (), existing , metav1.UpdateOptions {})
287
+ if err != nil && ! apierrors .IsConflict (err ) {
288
+ klog .Error ("Error updating MutatingWebhookConfiguration " , err )
289
+ }
290
+ return err
291
+ })
292
+ if err != nil {
293
+ klog .Error ("Error updating MutatingWebhookConfiguration " , err )
294
+ return err
295
+ }
296
+ } else {
297
+ klog .Error ("Error creating MutatingWebhookConfiguration " , err )
298
+ return err
299
+ }
300
+ }
301
+ klog .Infof ("Finished creating MutatingWebhookConfiguration %s" , imageManagerWebhookCfgName )
302
+ return nil
303
+ }
304
+
305
+ func (wh * Webhook ) DeleteImageManagerMutatingWebhook () error {
306
+ imwhName := imageManagerWebhookName ()
307
+ existing , err := wh .KubeClient .AdmissionregistrationV1 ().MutatingWebhookConfigurations ().Get (context .TODO (), imageManagerWebhookCfgName , metav1.GetOptions {})
308
+ if err != nil {
309
+ if apierrors .IsNotFound (err ) {
310
+ klog .Info ("webhook configuration not found, " , imageManagerWebhookCfgName )
311
+ return nil
312
+ }
313
+ return err
314
+ }
315
+ for i , w := range existing .Webhooks {
316
+ if w .Name == imwhName {
317
+ if len (existing .Webhooks ) == 1 {
318
+ err = wh .KubeClient .AdmissionregistrationV1 ().MutatingWebhookConfigurations ().Delete (context .TODO (), imageManagerWebhookCfgName , metav1.DeleteOptions {})
319
+ if err != nil {
320
+ klog .Info ("delete webhook configuration error, " , err )
321
+ return err
322
+ }
323
+ } else {
324
+ return retry .RetryOnConflict (retry .DefaultRetry , func () error {
325
+ updating , err := wh .KubeClient .AdmissionregistrationV1 ().MutatingWebhookConfigurations ().Get (context .TODO (), imageManagerWebhookCfgName , metav1.GetOptions {})
326
+ if err != nil {
327
+ if apierrors .IsNotFound (err ) {
328
+ klog .Info ("webhook configuration not found, " , imageManagerWebhookCfgName )
329
+ return nil
330
+ }
331
+ return err
332
+ }
333
+ updating .Webhooks = append (existing .Webhooks [:i ], existing .Webhooks [i + 1 :]... )
334
+ klog .Info ("removing the webhook, " , imwhName )
335
+ _ , err = wh .KubeClient .AdmissionregistrationV1 ().MutatingWebhookConfigurations ().Update (context .Background (), updating , metav1.UpdateOptions {})
336
+ if ! apierrors .IsConflict (err ) {
337
+ klog .Error ("Error updating MutatingWebhookConfiguration " , err )
338
+ }
339
+ return err
340
+ })
341
+ }
342
+ }
343
+ }
344
+ klog .Infof ("success to clean imagemanager webhook" )
345
+ return nil
346
+ }
347
+
205
348
func mutatingWebhookName () string {
206
349
// should be a domain with at least three segments separated by dots
207
350
return mutatingWebhookNamePrefix + "." + constants .Namespace + ".ns"
208
351
}
352
+
353
+ func imageManagerWebhookName () string {
354
+ return imageManagerWebhookPrefix + "." + constants .Namespace + ".ns"
355
+ }
0 commit comments