/
admission.go
108 lines (91 loc) · 3.21 KB
/
admission.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
// Copyright Contributors to the Open Cluster Management project
package managedclustersetbindingvalidating
import (
"context"
"fmt"
"io"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/uuid"
"k8s.io/apiserver/pkg/admission"
genericadmissioninitializer "k8s.io/apiserver/pkg/admission/initializer"
"k8s.io/apiserver/pkg/admission/plugin/webhook/generic"
"k8s.io/apiserver/pkg/admission/plugin/webhook/request"
"k8s.io/client-go/kubernetes"
clusterv1beta2api "open-cluster-management.io/api/cluster/v1beta2"
webhookv1beta2 "open-cluster-management.io/ocm/pkg/registration/webhook/v1beta2"
runtimeadmission "sigs.k8s.io/controller-runtime/pkg/webhook/admission"
)
const PluginName = "ManagedClusterSetBindingValidating"
func Register(plugins *admission.Plugins) {
plugins.Register(PluginName, func(config io.Reader) (admission.Interface, error) {
return NewPlugin(), nil
})
}
type Plugin struct {
*admission.Handler
webhook *webhookv1beta2.ManagedClusterSetBindingWebhook
}
func (p *Plugin) SetExternalKubeClientSet(client kubernetes.Interface) {
p.webhook.SetExternalKubeClientSet(client)
}
func (p *Plugin) ValidateInitialization() error {
if p.webhook == nil {
return fmt.Errorf("missing admission")
}
return nil
}
var _ admission.ValidationInterface = &Plugin{}
var _ admission.InitializationValidator = &Plugin{}
var _ = genericadmissioninitializer.WantsExternalKubeClientSet(&Plugin{})
func NewPlugin() *Plugin {
return &Plugin{
Handler: admission.NewHandler(admission.Create, admission.Update),
webhook: &webhookv1beta2.ManagedClusterSetBindingWebhook{},
}
}
func (p *Plugin) Validate(ctx context.Context, a admission.Attributes, o admission.ObjectInterfaces) error {
v := admission.VersionedAttributes{
Attributes: a,
VersionedOldObject: a.GetOldObject(),
VersionedObject: a.GetObject(),
VersionedKind: a.GetKind(),
}
gvr := clusterv1beta2api.GroupVersion.WithResource("managedclustersetbindings")
gvk := clusterv1beta2api.GroupVersion.WithKind("ManagedClusterSetBinding")
// resource is not mcl
if a.GetKind() != gvk {
return nil
}
// don't set kind cause do not use it in code logical
i := generic.WebhookInvocation{
Resource: gvr,
Kind: gvk,
}
uid := types.UID(uuid.NewUUID())
ar := request.CreateV1AdmissionReview(uid, &v, &i)
binding := &clusterv1beta2api.ManagedClusterSetBinding{}
obj := a.GetObject().(*unstructured.Unstructured)
err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, binding)
if err != nil {
return err
}
r := runtimeadmission.Request{AdmissionRequest: *ar.Request}
admissionContext := runtimeadmission.NewContextWithRequest(ctx, r)
switch a.GetOperation() {
case admission.Create:
_, err := p.webhook.ValidateCreate(admissionContext, binding)
return err
case admission.Update:
oldBinding := &clusterv1beta2api.ManagedClusterSetBinding{}
oldObj := a.GetOldObject().(*unstructured.Unstructured)
err := runtime.DefaultUnstructuredConverter.FromUnstructured(oldObj.Object, oldBinding)
if err != nil {
return err
}
_, err = p.webhook.ValidateUpdate(admissionContext, oldBinding, binding)
return err
}
return nil
}