/
globalrole.go
99 lines (83 loc) · 3.32 KB
/
globalrole.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
package globalrole
import (
"net/http"
"github.com/rancher/webhook/pkg/admission"
"github.com/rancher/webhook/pkg/auth"
objectsv3 "github.com/rancher/webhook/pkg/generated/objects/management.cattle.io/v3"
admissionv1 "k8s.io/api/admission/v1"
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/kubernetes/pkg/registry/rbac/validation"
"k8s.io/utils/trace"
)
var gvr = schema.GroupVersionResource{
Group: "management.cattle.io",
Version: "v3",
Resource: "globalroles",
}
// NewValidator returns a new validator used for validation globalRoles.
func NewValidator(resolver validation.AuthorizationRuleResolver) *Validator {
return &Validator{
admitter: admitter{
resolver: resolver,
},
}
}
// Validator implements admission.ValidatingAdmissionHandler.
type Validator struct {
admitter admitter
}
// GVR returns the GroupVersionKind for this CRD.
func (v *Validator) GVR() schema.GroupVersionResource {
return gvr
}
// Operations returns list of operations handled by this validator.
func (v *Validator) Operations() []admissionregistrationv1.OperationType {
return []admissionregistrationv1.OperationType{admissionregistrationv1.Update, admissionregistrationv1.Create}
}
// ValidatingWebhook returns the ValidatingWebhook used for this CRD.
func (v *Validator) ValidatingWebhook(clientConfig admissionregistrationv1.WebhookClientConfig) []admissionregistrationv1.ValidatingWebhook {
return []admissionregistrationv1.ValidatingWebhook{*admission.NewDefaultValidatingWebhook(v, clientConfig, admissionregistrationv1.ClusterScope, v.Operations())}
}
// Admitters returns the admitter objects used to validate globalRoles.
func (v *Validator) Admitters() []admission.Admitter {
return []admission.Admitter{&v.admitter}
}
type admitter struct {
resolver validation.AuthorizationRuleResolver
}
// Admit is the entrypoint for the validator. Admit will return an error if it unable to process the request.
// If this function is called without NewValidator(..) calls will panic.
func (a *admitter) Admit(request *admission.Request) (*admissionv1.AdmissionResponse, error) {
listTrace := trace.New("globalRoleValidator Admit", trace.Field{Key: "user", Value: request.UserInfo.Username})
defer listTrace.LogIfLong(admission.SlowTraceDuration)
newGR, err := objectsv3.GlobalRoleFromRequest(&request.AdmissionRequest)
if err != nil {
return nil, err
}
// object is in the process of being deleted, so admit it
// this admits update operations that happen to remove finalizers
if newGR.DeletionTimestamp != nil {
return &admissionv1.AdmissionResponse{
Allowed: true,
}, nil
}
// ensure all PolicyRules have at least one verb, otherwise RBAC controllers may encounter issues when creating Roles and ClusterRoles
for _, rule := range newGR.Rules {
if len(rule.Verbs) == 0 {
return &admissionv1.AdmissionResponse{
Result: &metav1.Status{
Status: "Failure",
Message: "GlobalRole.Rules: PolicyRules must have at least one verb",
Reason: metav1.StatusReasonBadRequest,
Code: http.StatusBadRequest,
},
Allowed: false,
}, nil
}
}
response := &admissionv1.AdmissionResponse{}
auth.SetEscalationResponse(response, auth.ConfirmNoEscalation(request, newGR.Rules, "", a.resolver))
return response, nil
}