forked from labring/sealos
-
Notifications
You must be signed in to change notification settings - Fork 0
/
operationrequest_webhook.go
111 lines (92 loc) · 3.75 KB
/
operationrequest_webhook.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
Copyright 2022 labring.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
import (
"context"
"errors"
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
logf "sigs.k8s.io/controller-runtime/pkg/log"
)
// log is for logging in this package.
var operationrequestlog = logf.Log.WithName("operationrequest-resource")
func (r *Operationrequest) SetupWebhookWithManager(mgr ctrl.Manager) error {
m := &ReqMutator{Client: mgr.GetClient()}
v := &ReqValidator{Client: mgr.GetClient()}
return ctrl.NewWebhookManagedBy(mgr).
For(r).
WithDefaulter(m).
WithValidator(v).
Complete()
}
// +kubebuilder:webhook:path=/mutate-user-sealos-io-v1-operationrequest,mutating=true,failurePolicy=fail,sideEffects=None,groups=user.sealos.io,resources=operationrequests,verbs=create;update,versions=v1,name=moperationrequest.kb.io,admissionReviewVersions=v1
//+kubebuilder:object:generate=false
type ReqMutator struct {
client.Client
}
func (r ReqMutator) Default(_ context.Context, obj runtime.Object) error {
req, ok := obj.(*Operationrequest)
if !ok {
return errors.New("obj convert Operationrequest is error")
}
// mutate the request with an owner label
operationrequestlog.Info("mutate", "name", req.Name)
req.ObjectMeta = initAnnotationAndLabels(req.ObjectMeta)
req.Labels[UserLabelOwnerKey] = req.Spec.User
return nil
}
//+kubebuilder:webhook:path=/validate-user-sealos-io-v1-operationrequest,mutating=false,failurePolicy=fail,sideEffects=None,groups=user.sealos.io,resources=operationrequests,verbs=create;update,versions=v1,name=voperationrequest.kb.io,admissionReviewVersions=v1
//+kubebuilder:object:generate=false
type ReqValidator struct {
client.Client
}
func (r ReqValidator) ValidateCreate(ctx context.Context, obj runtime.Object) error {
req, ok := obj.(*Operationrequest)
if !ok {
return errors.New("obj convert Operationrequest is error")
}
// todo check request, _ := admission.RequestFromContext(ctx), request.UserInfo.Username if legal
// list all requests in the same namespace with a same owner
var reqList OperationrequestList
err := r.List(ctx, &reqList, client.InNamespace(req.Namespace), client.MatchingLabels{UserLabelOwnerKey: req.Spec.User})
if client.IgnoreNotFound(err) != nil {
operationrequestlog.Error(err, "list operationrequest error")
return err
}
for _, item := range reqList.Items {
if item.Status.Phase != RequestCompleted {
operationrequestlog.Info("there is a request not completed, can not create new request", "name", item.Name, "phase", item.Status.Phase)
return errors.New("there is a request not completed, can not create new request")
}
}
return nil
}
func (r ReqValidator) ValidateUpdate(_ context.Context, oldObj, newObj runtime.Object) error {
// todo check request, _ := admission.RequestFromContext(ctx), request.UserInfo.Username if legal
oldReq, ok := oldObj.(*Operationrequest)
if !ok {
return errors.New("obj convert Operationrequest error")
}
newReq, ok := newObj.(*Operationrequest)
if !ok {
return errors.New("obj convert Operationrequest error")
}
if oldReq.Spec != newReq.Spec {
return errors.New("operation request spec do not support update")
}
return nil
}
func (r ReqValidator) ValidateDelete(_ context.Context, _ runtime.Object) error {
return nil
}