Skip to content

Commit 5ab31e5

Browse files
committed
operator: rework webhooks
Signed-off-by: Mikko Ylinen <[email protected]>
1 parent 99ef5bb commit 5ab31e5

7 files changed

+470
-215
lines changed

pkg/apis/deviceplugin/v1/dlbdeviceplugin_webhook.go

Lines changed: 63 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,73 +15,107 @@
1515
package v1
1616

1717
import (
18+
"context"
19+
"fmt"
20+
1821
"k8s.io/apimachinery/pkg/runtime"
1922
ctrl "sigs.k8s.io/controller-runtime"
2023
logf "sigs.k8s.io/controller-runtime/pkg/log"
21-
"sigs.k8s.io/controller-runtime/pkg/webhook"
2224
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
2325

2426
"github.com/intel/intel-device-plugins-for-kubernetes/pkg/controllers"
2527
)
2628

27-
var (
28-
// dlbdevicepluginlog is for logging in this package.
29-
dlbdevicepluginlog = logf.Log.WithName("dlbdeviceplugin-resource")
30-
31-
dlbMinVersion = controllers.ImageMinVersion
32-
)
29+
var dlbMinVersion = controllers.ImageMinVersion
3330

3431
// SetupWebhookWithManager sets up a webhook for DlbDevicePlugin custom resources.
3532
func (r *DlbDevicePlugin) SetupWebhookWithManager(mgr ctrl.Manager) error {
3633
return ctrl.NewWebhookManagedBy(mgr).
3734
For(r).
35+
WithDefaulter(&dlbDevicePluginDefaulter{}).
36+
WithValidator(&dlbDevicePluginValidator{}).
3837
Complete()
3938
}
4039

4140
// +kubebuilder:webhook:path=/mutate-deviceplugin-intel-com-v1-dlbdeviceplugin,mutating=true,failurePolicy=fail,groups=deviceplugin.intel.com,resources=dlbdeviceplugins,verbs=create;update,versions=v1,name=mdlbdeviceplugin.kb.io,sideEffects=None,admissionReviewVersions=v1
4241

43-
var _ webhook.Defaulter = &DlbDevicePlugin{}
42+
type dlbDevicePluginDefaulter struct{}
43+
44+
var _ admission.CustomDefaulter = &dlbDevicePluginDefaulter{}
4445

45-
// Default implements webhook.Defaulter so a webhook will be registered for the type.
46-
func (r *DlbDevicePlugin) Default() {
47-
dlbdevicepluginlog.Info("default", "name", r.Name)
46+
// Default implements admission.CustomDefaulter so a webhook will be registered for the type.
47+
func (r *dlbDevicePluginDefaulter) Default(ctx context.Context, obj runtime.Object) error {
48+
log := logf.FromContext(ctx).WithName("dlbdeviceplugin-resource")
49+
cr, ok := obj.(*DlbDevicePlugin)
50+
if !ok {
51+
return fmt.Errorf("expected an DlbDevicePlugin object but got %T", obj)
52+
}
53+
54+
log.Info("default", "name", cr.Name)
4855

49-
if len(r.Spec.Image) == 0 {
50-
r.Spec.Image = "intel/intel-dlb-plugin:" + dlbMinVersion.String()
56+
if len(cr.Spec.Image) == 0 {
57+
cr.Spec.Image = "intel/intel-dlb-plugin:" + dlbMinVersion.String()
5158
}
59+
60+
return nil
5261
}
5362

5463
// +kubebuilder:webhook:verbs=create;update,path=/validate-deviceplugin-intel-com-v1-dlbdeviceplugin,mutating=false,failurePolicy=fail,groups=deviceplugin.intel.com,resources=dlbdeviceplugins,versions=v1,name=vdlbdeviceplugin.kb.io,sideEffects=None,admissionReviewVersions=v1
5564

56-
var _ webhook.Validator = &DlbDevicePlugin{}
65+
type dlbDevicePluginValidator struct{}
66+
67+
var _ admission.CustomValidator = &dlbDevicePluginValidator{}
5768

58-
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type.
59-
func (r *DlbDevicePlugin) ValidateCreate() (admission.Warnings, error) {
60-
dlbdevicepluginlog.Info("validate create", "name", r.Name)
69+
// ValidateCreate implements admission.CustomValidator so a webhook will be registered for the type.
70+
func (r *dlbDevicePluginValidator) ValidateCreate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) {
71+
log := logf.FromContext(ctx).WithName("dlbdeviceplugin-resource")
72+
cr, ok := obj.(*DlbDevicePlugin)
73+
if !ok {
74+
return nil, fmt.Errorf("expected an DlbDevicePlugin object but got %T", obj)
75+
}
76+
77+
log.Info("validate create", "name", cr.Name)
6178

62-
return nil, r.validatePlugin()
79+
return nil, r.validatePlugin(ctx, obj)
6380
}
6481

65-
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type.
66-
func (r *DlbDevicePlugin) ValidateUpdate(old runtime.Object) (admission.Warnings, error) {
67-
dlbdevicepluginlog.Info("validate update", "name", r.Name)
82+
// ValidateUpdate implements admission.CustomValidator so a webhook will be registered for the type.
83+
func (r *dlbDevicePluginValidator) ValidateUpdate(ctx context.Context, oldObj runtime.Object, newObj runtime.Object) (admission.Warnings, error) {
84+
log := logf.FromContext(ctx).WithName("dlbdeviceplugin-resource")
85+
cr, ok := oldObj.(*DlbDevicePlugin)
86+
if !ok {
87+
return nil, fmt.Errorf("expected an DlbDevicePlugin object but got %T", oldObj)
88+
}
89+
90+
log.Info("validate update", "name", cr.Name)
6891

69-
return nil, r.validatePlugin()
92+
return nil, r.validatePlugin(ctx, oldObj)
7093
}
7194

72-
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type.
73-
func (r *DlbDevicePlugin) ValidateDelete() (admission.Warnings, error) {
74-
dlbdevicepluginlog.Info("validate delete", "name", r.Name)
95+
// ValidateDelete implements admission.CustomValidator so a webhook will be registered for the type.
96+
func (r *dlbDevicePluginValidator) ValidateDelete(ctx context.Context, obj runtime.Object) (admission.Warnings, error) {
97+
log := logf.FromContext(ctx).WithName("dlbdeviceplugin-resource")
98+
cr, ok := obj.(*DlbDevicePlugin)
99+
if !ok {
100+
return nil, fmt.Errorf("expected an DlbDevicePlugin object but got %T", obj)
101+
}
102+
103+
log.Info("validate delete", "name", cr.Name)
75104

76105
return nil, nil
77106
}
78107

79-
func (r *DlbDevicePlugin) validatePlugin() error {
80-
if r.Spec.InitImage != "" {
81-
if err := validatePluginImage(r.Spec.InitImage, "intel-dlb-initcontainer", dlbMinVersion); err != nil {
108+
func (r *dlbDevicePluginValidator) validatePlugin(ctx context.Context, obj runtime.Object) error {
109+
cr, ok := obj.(*DlbDevicePlugin)
110+
111+
if !ok {
112+
return fmt.Errorf("expected an DlbDevicePlugin object but got %T", obj)
113+
}
114+
if cr.Spec.InitImage != "" {
115+
if err := validatePluginImage(cr.Spec.InitImage, "intel-dlb-initcontainer", dlbMinVersion); err != nil {
82116
return err
83117
}
84118
}
85119

86-
return validatePluginImage(r.Spec.Image, "intel-dlb-plugin", dlbMinVersion)
120+
return validatePluginImage(cr.Spec.Image, "intel-dlb-plugin", dlbMinVersion)
87121
}

pkg/apis/deviceplugin/v1/dsadeviceplugin_webhook.go

Lines changed: 66 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -15,79 +15,115 @@
1515
package v1
1616

1717
import (
18+
"context"
19+
"fmt"
20+
1821
"github.com/pkg/errors"
1922
"k8s.io/apimachinery/pkg/runtime"
2023
ctrl "sigs.k8s.io/controller-runtime"
2124
logf "sigs.k8s.io/controller-runtime/pkg/log"
22-
"sigs.k8s.io/controller-runtime/pkg/webhook"
2325
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
2426

2527
"github.com/intel/intel-device-plugins-for-kubernetes/pkg/controllers"
2628
)
2729

28-
var (
29-
// dsadevicepluginlog is for logging in this package.
30-
dsadevicepluginlog = logf.Log.WithName("dsadeviceplugin-resource")
31-
32-
dsaMinVersion = controllers.ImageMinVersion
33-
)
30+
var dsaMinVersion = controllers.ImageMinVersion
3431

3532
// SetupWebhookWithManager sets up a webhook for DsaDevicePlugin custom resources.
3633
func (r *DsaDevicePlugin) SetupWebhookWithManager(mgr ctrl.Manager) error {
3734
return ctrl.NewWebhookManagedBy(mgr).
3835
For(r).
36+
WithDefaulter(&dsaDevicePluginDefaulter{}).
37+
WithValidator(&dsaDevicePluginValidator{}).
3938
Complete()
4039
}
4140

4241
// +kubebuilder:webhook:path=/mutate-deviceplugin-intel-com-v1-dsadeviceplugin,mutating=true,failurePolicy=fail,groups=deviceplugin.intel.com,resources=dsadeviceplugins,verbs=create;update,versions=v1,name=mdsadeviceplugin.kb.io,sideEffects=None,admissionReviewVersions=v1
4342

44-
var _ webhook.Defaulter = &DsaDevicePlugin{}
43+
type dsaDevicePluginDefaulter struct{}
44+
45+
var _ admission.CustomDefaulter = &dsaDevicePluginDefaulter{}
46+
47+
// Default implements admission.CustomDefaulter so a webhook will be registered for the type.
48+
func (r *dsaDevicePluginDefaulter) Default(ctx context.Context, obj runtime.Object) error {
49+
log := logf.FromContext(ctx).WithName("dsadeviceplugin-resource")
50+
cr, ok := obj.(*DsaDevicePlugin)
4551

46-
// Default implements webhook.Defaulter so a webhook will be registered for the type.
47-
func (r *DsaDevicePlugin) Default() {
48-
dsadevicepluginlog.Info("default", "name", r.Name)
52+
if !ok {
53+
return fmt.Errorf("expected an DsaDevicePlugin object but got %T", obj)
54+
}
55+
56+
log.Info("default", "name", cr.Name)
4957

50-
if len(r.Spec.Image) == 0 {
51-
r.Spec.Image = "intel/intel-dsa-plugin:" + dsaMinVersion.String()
58+
if len(cr.Spec.Image) == 0 {
59+
cr.Spec.Image = "intel/intel-dsa-plugin:" + dsaMinVersion.String()
5260
}
61+
62+
return nil
5363
}
5464

5565
// +kubebuilder:webhook:verbs=create;update,path=/validate-deviceplugin-intel-com-v1-dsadeviceplugin,mutating=false,failurePolicy=fail,groups=deviceplugin.intel.com,resources=dsadeviceplugins,versions=v1,name=vdsadeviceplugin.kb.io,sideEffects=None,admissionReviewVersions=v1
5666

57-
var _ webhook.Validator = &DsaDevicePlugin{}
67+
type dsaDevicePluginValidator struct{}
5868

59-
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type.
60-
func (r *DsaDevicePlugin) ValidateCreate() (admission.Warnings, error) {
61-
dsadevicepluginlog.Info("validate create", "name", r.Name)
69+
var _ admission.CustomValidator = &dsaDevicePluginValidator{}
6270

63-
return nil, r.validatePlugin()
71+
// ValidateCreate implements admission.CustomValidator so a webhook will be registered for the type.
72+
func (r *dsaDevicePluginValidator) ValidateCreate(ctx context.Context, obj runtime.Object) (admission.Warnings, error) {
73+
log := logf.FromContext(ctx).WithName("dsadeviceplugin-resource")
74+
cr, ok := obj.(*DsaDevicePlugin)
75+
if !ok {
76+
return nil, fmt.Errorf("expected an DsaDevicePlugin object but got %T", obj)
77+
}
78+
79+
log.Info("validate create", "name", cr.Name)
80+
81+
return nil, r.validatePlugin(ctx, obj)
6482
}
6583

66-
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type.
67-
func (r *DsaDevicePlugin) ValidateUpdate(old runtime.Object) (admission.Warnings, error) {
68-
dsadevicepluginlog.Info("validate update", "name", r.Name)
84+
// ValidateUpdate implements admission.CustomValidator so a webhook will be registered for the type.
85+
func (r *dsaDevicePluginValidator) ValidateUpdate(ctx context.Context, oldObj runtime.Object, newObj runtime.Object) (admission.Warnings, error) {
86+
log := logf.FromContext(ctx).WithName("dsadeviceplugin-resource")
87+
cr, ok := oldObj.(*DsaDevicePlugin)
88+
if !ok {
89+
return nil, fmt.Errorf("expected an DsaDevicePlugin object but got %T", oldObj)
90+
}
6991

70-
return nil, r.validatePlugin()
92+
log.Info("validate update", "name", cr.Name)
93+
94+
return nil, r.validatePlugin(ctx, oldObj)
7195
}
7296

73-
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type.
74-
func (r *DsaDevicePlugin) ValidateDelete() (admission.Warnings, error) {
75-
dsadevicepluginlog.Info("validate delete", "name", r.Name)
97+
// ValidateDelete implements admission.CustomValidator so a webhook will be registered for the type.
98+
func (r *dsaDevicePluginValidator) ValidateDelete(ctx context.Context, obj runtime.Object) (admission.Warnings, error) {
99+
log := logf.FromContext(ctx).WithName("dsadeviceplugin-resource")
100+
cr, ok := obj.(*DsaDevicePlugin)
101+
if !ok {
102+
return nil, fmt.Errorf("expected an DsaDevicePlugin object but got %T", obj)
103+
}
104+
105+
log.Info("validate delete", "name", cr.Name)
76106

77107
return nil, nil
78108
}
79109

80-
func (r *DsaDevicePlugin) validatePlugin() error {
81-
if err := validatePluginImage(r.Spec.Image, "intel-dsa-plugin", dsaMinVersion); err != nil {
110+
func (r *dsaDevicePluginValidator) validatePlugin(ctx context.Context, obj runtime.Object) error {
111+
cr, ok := obj.(*DsaDevicePlugin)
112+
113+
if !ok {
114+
return fmt.Errorf("expected an DsaDevicePlugin object but got %T", obj)
115+
}
116+
117+
if err := validatePluginImage(cr.Spec.Image, "intel-dsa-plugin", dsaMinVersion); err != nil {
82118
return err
83119
}
84120

85-
if len(r.Spec.ProvisioningConfig) > 0 && len(r.Spec.InitImage) == 0 {
121+
if len(cr.Spec.ProvisioningConfig) > 0 && len(cr.Spec.InitImage) == 0 {
86122
return errors.Errorf("ProvisioningConfig is set with no InitImage")
87123
}
88124

89-
if len(r.Spec.InitImage) > 0 {
90-
return validatePluginImage(r.Spec.InitImage, "intel-idxd-config-initcontainer", dsaMinVersion)
125+
if len(cr.Spec.InitImage) > 0 {
126+
return validatePluginImage(cr.Spec.InitImage, "intel-idxd-config-initcontainer", dsaMinVersion)
91127
}
92128

93129
return nil

0 commit comments

Comments
 (0)