Skip to content

Commit add0bb3

Browse files
committed
improved appwrapper webhook configuration
Define mock appwrapper webhooks to enable reasonable error messages for users when AppWrappers are disabled by configuration.
1 parent 0cac6ca commit add0bb3

File tree

4 files changed

+87
-12
lines changed

4 files changed

+87
-12
lines changed

main.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,9 @@ func main() {
144144
MTLSEnabled: ptr.To(true),
145145
},
146146
AppWrapper: &config.AppWrapperConfiguration{
147-
Enabled: ptr.To(false),
148-
Config: awconfig.NewAppWrapperConfig(),
147+
Enabled: ptr.To(false),
148+
ExternalController: ptr.To(false),
149+
Config: awconfig.NewAppWrapperConfig(),
149150
},
150151
}
151152

@@ -236,14 +237,20 @@ func waitForRayClusterAPIandSetupController(ctx context.Context, mgr ctrl.Manage
236237
func setupAppWrapperComponents(ctx context.Context, cancel context.CancelFunc, mgr ctrl.Manager,
237238
cfg *config.CodeFlareOperatorConfiguration, certsReady chan struct{}) error {
238239
if cfg.AppWrapper == nil || !ptr.Deref(cfg.AppWrapper.Enabled, false) {
239-
setupLog.Info("AppWrappers are disabled by operator configuration")
240+
setupLog.Info("Embedded AppWrapper controller is disabled by config")
241+
externalController := cfg.AppWrapper != nil && ptr.Deref(cfg.AppWrapper.ExternalController, false)
242+
go func() {
243+
<-certsReady
244+
setupLog.Info("Setting up mock AppWrapper webhooks", "externalController", externalController)
245+
exitOnError(controllers.SetupMockAppWrapperWebhooks(mgr, externalController), "unable to setup AppWrapper webhooks")
246+
}()
240247
return nil
241248
}
242249

243250
// AppWrapper webhook doesn't depend on WorkloadAPI availablity but does need certsReady
244251
go func() {
245252
<-certsReady
246-
setupLog.Info("Setting up AppWrapper webhook")
253+
setupLog.Info("Setting up AppWrapper webhooks")
247254
exitOnError(awctrl.SetupWebhooks(mgr, cfg.AppWrapper.Config), "unable to setup AppWrapper webhooks")
248255
}()
249256

pkg/config/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ type CodeFlareOperatorConfiguration struct {
3838
type AppWrapperConfiguration struct {
3939
// Enabled controls whether or not the AppWrapper Controller is enabled
4040
Enabled *bool `json:"enabled,omitempty"`
41+
// ExternalController indicates that an AppWrapper Controller external to the Codeflare Operator is deployed
42+
ExternalController *bool `json:"externalController,omitempty"`
4143
// AppWrapper contains the AppWrapper controller configuration
4244
Config *awconfig.AppWrapperConfig `json:"config,omitempty"`
4345
}

pkg/controllers/appwrapper_controller.go

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,3 @@ package controllers
4040
// +kubebuilder:rbac:groups=kueue.x-k8s.io,resources=workloads/finalizers,verbs=update
4141
// +kubebuilder:rbac:groups=kueue.x-k8s.io,resources=resourceflavors,verbs=get;list;watch
4242
// +kubebuilder:rbac:groups=kueue.x-k8s.io,resources=workloadpriorityclasses,verbs=get;list;watch
43-
44-
// webhook configuration
45-
//+kubebuilder:webhook:path=/mutate-workload-codeflare-dev-v1beta2-appwrapper,mutating=true,failurePolicy=fail,sideEffects=None,groups=workload.codeflare.dev,resources=appwrappers,verbs=create,versions=v1beta2,name=mappwrapper.kb.io,admissionReviewVersions=v1
46-
//+kubebuilder:webhook:path=/validate-workload-codeflare-dev-v1beta2-appwrapper,mutating=false,failurePolicy=fail,sideEffects=None,groups=workload.codeflare.dev,resources=appwrappers,verbs=create;update,versions=v1beta2,name=vappwrapper.kb.io,admissionReviewVersions=v1
47-
48-
// permissions needed by Webhook to enable SubjectAccessReview
49-
//+kubebuilder:rbac:groups=authorization.k8s.io,resources=subjectaccessreviews,verbs=create
50-
//+kubebuilder:rbac:groups=apiextensions.k8s.io,resources=customresourcedefinitions,verbs=list

pkg/controllers/appwrapper_webhook.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
Copyright 2024.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package controllers
18+
19+
import (
20+
"context"
21+
"fmt"
22+
23+
awv1beta2 "github.com/project-codeflare/appwrapper/api/v1beta2"
24+
25+
"k8s.io/apimachinery/pkg/runtime"
26+
ctrl "sigs.k8s.io/controller-runtime"
27+
"sigs.k8s.io/controller-runtime/pkg/webhook"
28+
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
29+
)
30+
31+
// webhook configuration
32+
//+kubebuilder:webhook:path=/mutate-workload-codeflare-dev-v1beta2-appwrapper,mutating=true,failurePolicy=fail,sideEffects=None,groups=workload.codeflare.dev,resources=appwrappers,verbs=create,versions=v1beta2,name=mappwrapper.kb.io,admissionReviewVersions=v1
33+
//+kubebuilder:webhook:path=/validate-workload-codeflare-dev-v1beta2-appwrapper,mutating=false,failurePolicy=fail,sideEffects=None,groups=workload.codeflare.dev,resources=appwrappers,verbs=create;update,versions=v1beta2,name=vappwrapper.kb.io,admissionReviewVersions=v1
34+
35+
// permissions needed by the "real" Webhook in the appwrapper project to enable SubjectAccessReview
36+
//+kubebuilder:rbac:groups=authorization.k8s.io,resources=subjectaccessreviews,verbs=create
37+
//+kubebuilder:rbac:groups=apiextensions.k8s.io,resources=customresourcedefinitions,verbs=list
38+
39+
type appwrapperWebhook struct {
40+
externalController bool
41+
}
42+
43+
var _ webhook.CustomDefaulter = &appwrapperWebhook{}
44+
45+
func (w *appwrapperWebhook) Default(ctx context.Context, obj runtime.Object) error {
46+
return nil
47+
}
48+
49+
var _ webhook.CustomValidator = &appwrapperWebhook{}
50+
51+
func (w *appwrapperWebhook) ValidateCreate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) {
52+
if w.externalController {
53+
return nil, nil
54+
} else {
55+
return nil, fmt.Errorf("AppWrappers disabled by CodeFlare operator configuration")
56+
}
57+
}
58+
59+
func (w *appwrapperWebhook) ValidateUpdate(ctx context.Context, oldObj, newObj runtime.Object) (admission.Warnings, error) {
60+
return nil, nil
61+
}
62+
63+
func (w *appwrapperWebhook) ValidateDelete(context.Context, runtime.Object) (admission.Warnings, error) {
64+
return nil, nil
65+
}
66+
67+
func SetupMockAppWrapperWebhooks(mgr ctrl.Manager, externalController bool) error {
68+
wh := &appwrapperWebhook{externalController: externalController}
69+
return ctrl.NewWebhookManagedBy(mgr).
70+
For(&awv1beta2.AppWrapper{}).
71+
WithDefaulter(wh).
72+
WithValidator(wh).
73+
Complete()
74+
}

0 commit comments

Comments
 (0)