Add ObjectInterfaces to Admission and Validation
Kubernetes-commit: 513a87c7b25aa58f84fafe0dc170cee4c76e481b
This commit is contained in:
parent
cfef629361
commit
87b5ac0c06
|
@ -44,7 +44,7 @@ func WithAudit(i Interface, ae *auditinternal.Event) Interface {
|
|||
return &auditHandler{i, ae}
|
||||
}
|
||||
|
||||
func (handler auditHandler) Admit(a Attributes) error {
|
||||
func (handler auditHandler) Admit(a Attributes, o ObjectInterfaces) error {
|
||||
if !handler.Interface.Handles(a.GetOperation()) {
|
||||
return nil
|
||||
}
|
||||
|
@ -53,13 +53,13 @@ func (handler auditHandler) Admit(a Attributes) error {
|
|||
}
|
||||
var err error
|
||||
if mutator, ok := handler.Interface.(MutationInterface); ok {
|
||||
err = mutator.Admit(a)
|
||||
err = mutator.Admit(a, o)
|
||||
handler.logAnnotations(a)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (handler auditHandler) Validate(a Attributes) error {
|
||||
func (handler auditHandler) Validate(a Attributes, o ObjectInterfaces) error {
|
||||
if !handler.Interface.Handles(a.GetOperation()) {
|
||||
return nil
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ func (handler auditHandler) Validate(a Attributes) error {
|
|||
}
|
||||
var err error
|
||||
if validator, ok := handler.Interface.(ValidationInterface); ok {
|
||||
err = validator.Validate(a)
|
||||
err = validator.Validate(a, o)
|
||||
handler.logAnnotations(a)
|
||||
}
|
||||
return err
|
||||
|
|
|
@ -45,14 +45,14 @@ var _ Interface = &fakeHandler{}
|
|||
var _ MutationInterface = &fakeHandler{}
|
||||
var _ ValidationInterface = &fakeHandler{}
|
||||
|
||||
func (h fakeHandler) Admit(a Attributes) error {
|
||||
func (h fakeHandler) Admit(a Attributes, o ObjectInterfaces) error {
|
||||
for k, v := range h.admitAnnotations {
|
||||
a.AddAnnotation(k, v)
|
||||
}
|
||||
return h.admit
|
||||
}
|
||||
|
||||
func (h fakeHandler) Validate(a Attributes) error {
|
||||
func (h fakeHandler) Validate(a Attributes, o ObjectInterfaces) error {
|
||||
for k, v := range h.validateAnnotations {
|
||||
a.AddAnnotation(k, v)
|
||||
}
|
||||
|
@ -149,13 +149,13 @@ func TestWithAudit(t *testing.T) {
|
|||
require.True(t, ok)
|
||||
auditMutator, ok := auditHandler.(MutationInterface)
|
||||
require.True(t, ok)
|
||||
assert.Equal(t, mutator.Admit(a), auditMutator.Admit(a), tcName+": WithAudit decorator should not effect the return value")
|
||||
assert.Equal(t, mutator.Admit(a, nil), auditMutator.Admit(a, nil), tcName+": WithAudit decorator should not effect the return value")
|
||||
|
||||
validator, ok := handler.(ValidationInterface)
|
||||
require.True(t, ok)
|
||||
auditValidator, ok := auditHandler.(ValidationInterface)
|
||||
require.True(t, ok)
|
||||
assert.Equal(t, validator.Validate(a), auditValidator.Validate(a), tcName+": WithAudit decorator should not effect the return value")
|
||||
assert.Equal(t, validator.Validate(a, nil), auditValidator.Validate(a, nil), tcName+": WithAudit decorator should not effect the return value")
|
||||
|
||||
annotations := make(map[string]string, len(tc.admitAnnotations)+len(tc.validateAnnotations))
|
||||
for k, v := range tc.admitAnnotations {
|
||||
|
|
|
@ -26,13 +26,13 @@ func NewChainHandler(handlers ...Interface) chainAdmissionHandler {
|
|||
}
|
||||
|
||||
// Admit performs an admission control check using a chain of handlers, and returns immediately on first error
|
||||
func (admissionHandler chainAdmissionHandler) Admit(a Attributes) error {
|
||||
func (admissionHandler chainAdmissionHandler) Admit(a Attributes, o ObjectInterfaces) error {
|
||||
for _, handler := range admissionHandler {
|
||||
if !handler.Handles(a.GetOperation()) {
|
||||
continue
|
||||
}
|
||||
if mutator, ok := handler.(MutationInterface); ok {
|
||||
err := mutator.Admit(a)
|
||||
err := mutator.Admit(a, o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -42,13 +42,13 @@ func (admissionHandler chainAdmissionHandler) Admit(a Attributes) error {
|
|||
}
|
||||
|
||||
// Validate performs an admission control check using a chain of handlers, and returns immediately on first error
|
||||
func (admissionHandler chainAdmissionHandler) Validate(a Attributes) error {
|
||||
func (admissionHandler chainAdmissionHandler) Validate(a Attributes, o ObjectInterfaces) error {
|
||||
for _, handler := range admissionHandler {
|
||||
if !handler.Handles(a.GetOperation()) {
|
||||
continue
|
||||
}
|
||||
if validator, ok := handler.(ValidationInterface); ok {
|
||||
err := validator.Validate(a)
|
||||
err := validator.Validate(a, o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ type FakeHandler struct {
|
|||
validate, validateCalled bool
|
||||
}
|
||||
|
||||
func (h *FakeHandler) Admit(a Attributes) (err error) {
|
||||
func (h *FakeHandler) Admit(a Attributes, o ObjectInterfaces) (err error) {
|
||||
h.admitCalled = true
|
||||
if h.admit {
|
||||
return nil
|
||||
|
@ -39,7 +39,7 @@ func (h *FakeHandler) Admit(a Attributes) (err error) {
|
|||
return fmt.Errorf("Don't admit")
|
||||
}
|
||||
|
||||
func (h *FakeHandler) Validate(a Attributes) (err error) {
|
||||
func (h *FakeHandler) Validate(a Attributes, o ObjectInterfaces) (err error) {
|
||||
h.validateCalled = true
|
||||
if h.validate {
|
||||
return nil
|
||||
|
@ -119,7 +119,7 @@ func TestAdmitAndValidate(t *testing.T) {
|
|||
for _, test := range tests {
|
||||
t.Logf("testcase = %s", test.name)
|
||||
// call admit and check that validate was not called at all
|
||||
err := test.chain.Admit(NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, test.ns, "", schema.GroupVersionResource{}, "", test.operation, false, nil))
|
||||
err := test.chain.Admit(NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, test.ns, "", schema.GroupVersionResource{}, "", test.operation, false, nil), nil)
|
||||
accepted := (err == nil)
|
||||
if accepted != test.accept {
|
||||
t.Errorf("unexpected result of admit call: %v", accepted)
|
||||
|
@ -140,7 +140,7 @@ func TestAdmitAndValidate(t *testing.T) {
|
|||
}
|
||||
|
||||
// call validate and check that admit was not called at all
|
||||
err = test.chain.Validate(NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, test.ns, "", schema.GroupVersionResource{}, "", test.operation, false, nil))
|
||||
err = test.chain.Validate(NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, test.ns, "", schema.GroupVersionResource{}, "", test.operation, false, nil), nil)
|
||||
accepted = (err == nil)
|
||||
if accepted != test.accept {
|
||||
t.Errorf("unexpected result of validate call: %v\n", accepted)
|
||||
|
|
|
@ -85,7 +85,9 @@ type WantExternalKubeInformerFactory struct {
|
|||
func (self *WantExternalKubeInformerFactory) SetExternalKubeInformerFactory(sf informers.SharedInformerFactory) {
|
||||
self.sf = sf
|
||||
}
|
||||
func (self *WantExternalKubeInformerFactory) Admit(a admission.Attributes) error { return nil }
|
||||
func (self *WantExternalKubeInformerFactory) Admit(a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
return nil
|
||||
}
|
||||
func (self *WantExternalKubeInformerFactory) Handles(o admission.Operation) bool { return false }
|
||||
func (self *WantExternalKubeInformerFactory) ValidateInitialization() error { return nil }
|
||||
|
||||
|
@ -98,9 +100,11 @@ type WantExternalKubeClientSet struct {
|
|||
}
|
||||
|
||||
func (self *WantExternalKubeClientSet) SetExternalKubeClientSet(cs kubernetes.Interface) { self.cs = cs }
|
||||
func (self *WantExternalKubeClientSet) Admit(a admission.Attributes) error { return nil }
|
||||
func (self *WantExternalKubeClientSet) Handles(o admission.Operation) bool { return false }
|
||||
func (self *WantExternalKubeClientSet) ValidateInitialization() error { return nil }
|
||||
func (self *WantExternalKubeClientSet) Admit(a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
return nil
|
||||
}
|
||||
func (self *WantExternalKubeClientSet) Handles(o admission.Operation) bool { return false }
|
||||
func (self *WantExternalKubeClientSet) ValidateInitialization() error { return nil }
|
||||
|
||||
var _ admission.Interface = &WantExternalKubeClientSet{}
|
||||
var _ initializer.WantsExternalKubeClientSet = &WantExternalKubeClientSet{}
|
||||
|
@ -111,9 +115,11 @@ type WantAuthorizerAdmission struct {
|
|||
}
|
||||
|
||||
func (self *WantAuthorizerAdmission) SetAuthorizer(a authorizer.Authorizer) { self.auth = a }
|
||||
func (self *WantAuthorizerAdmission) Admit(a admission.Attributes) error { return nil }
|
||||
func (self *WantAuthorizerAdmission) Handles(o admission.Operation) bool { return false }
|
||||
func (self *WantAuthorizerAdmission) ValidateInitialization() error { return nil }
|
||||
func (self *WantAuthorizerAdmission) Admit(a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
return nil
|
||||
}
|
||||
func (self *WantAuthorizerAdmission) Handles(o admission.Operation) bool { return false }
|
||||
func (self *WantAuthorizerAdmission) ValidateInitialization() error { return nil }
|
||||
|
||||
var _ admission.Interface = &WantAuthorizerAdmission{}
|
||||
var _ initializer.WantsAuthorizer = &WantAuthorizerAdmission{}
|
||||
|
@ -130,8 +136,10 @@ type clientCertWanter struct {
|
|||
gotCert, gotKey []byte
|
||||
}
|
||||
|
||||
func (s *clientCertWanter) SetClientCert(cert, key []byte) { s.gotCert, s.gotKey = cert, key }
|
||||
func (s *clientCertWanter) Admit(a admission.Attributes) error { return nil }
|
||||
func (s *clientCertWanter) SetClientCert(cert, key []byte) { s.gotCert, s.gotKey = cert, key }
|
||||
func (s *clientCertWanter) Admit(a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
return nil
|
||||
}
|
||||
func (s *clientCertWanter) Handles(o admission.Operation) bool { return false }
|
||||
func (s *clientCertWanter) ValidateInitialization() error { return nil }
|
||||
|
||||
|
@ -140,8 +148,10 @@ type WantSchemeAdmission struct {
|
|||
scheme *runtime.Scheme
|
||||
}
|
||||
|
||||
func (self *WantSchemeAdmission) SetScheme(s *runtime.Scheme) { self.scheme = s }
|
||||
func (self *WantSchemeAdmission) Admit(a admission.Attributes) error { return nil }
|
||||
func (self *WantSchemeAdmission) SetScheme(s *runtime.Scheme) { self.scheme = s }
|
||||
func (self *WantSchemeAdmission) Admit(a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
return nil
|
||||
}
|
||||
func (self *WantSchemeAdmission) Handles(o admission.Operation) bool { return false }
|
||||
func (self *WantSchemeAdmission) ValidateInitialization() error { return nil }
|
||||
|
||||
|
|
|
@ -62,6 +62,20 @@ type Attributes interface {
|
|||
AddAnnotation(key, value string) error
|
||||
}
|
||||
|
||||
// ObjectInterfaces is an interface used by AdmissionController to get object interfaces
|
||||
// such as Converter or Defaulter. These interfaces are normally coming from Request Scope
|
||||
// to handle special cases like CRDs.
|
||||
type ObjectInterfaces interface {
|
||||
// GetObjectCreater is the ObjectCreator appropriate for the requested object.
|
||||
GetObjectCreater() runtime.ObjectCreater
|
||||
// GetObjectTyper is the ObjectTyper appropriate for the requested object.
|
||||
GetObjectTyper() runtime.ObjectTyper
|
||||
// GetObjectDefaulter is the ObjectDefaulter appropriate for the requested object.
|
||||
GetObjectDefaulter() runtime.ObjectDefaulter
|
||||
// GetObjectConvertor is the ObjectConvertor appropriate for the requested object.
|
||||
GetObjectConvertor() runtime.ObjectConvertor
|
||||
}
|
||||
|
||||
// privateAnnotationsGetter is a private interface which allows users to get annotations from Attributes.
|
||||
type privateAnnotationsGetter interface {
|
||||
getAnnotations() map[string]string
|
||||
|
@ -84,7 +98,7 @@ type MutationInterface interface {
|
|||
Interface
|
||||
|
||||
// Admit makes an admission decision based on the request attributes
|
||||
Admit(a Attributes) (err error)
|
||||
Admit(a Attributes, o ObjectInterfaces) (err error)
|
||||
}
|
||||
|
||||
// ValidationInterface is an abstract, pluggable interface for Admission Control decisions.
|
||||
|
@ -92,7 +106,7 @@ type ValidationInterface interface {
|
|||
Interface
|
||||
|
||||
// Validate makes an admission decision based on the request attributes. It is NOT allowed to mutate
|
||||
Validate(a Attributes) (err error)
|
||||
Validate(a Attributes, o ObjectInterfaces) (err error)
|
||||
}
|
||||
|
||||
// Operation is the type of resource operation being checked for admission control
|
||||
|
|
|
@ -75,27 +75,27 @@ type pluginHandlerWithMetrics struct {
|
|||
}
|
||||
|
||||
// Admit performs a mutating admission control check and emit metrics.
|
||||
func (p pluginHandlerWithMetrics) Admit(a admission.Attributes) error {
|
||||
func (p pluginHandlerWithMetrics) Admit(a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
mutatingHandler, ok := p.Interface.(admission.MutationInterface)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
err := mutatingHandler.Admit(a)
|
||||
err := mutatingHandler.Admit(a, o)
|
||||
p.observer(time.Since(start), err != nil, a, stepAdmit, p.extraLabels...)
|
||||
return err
|
||||
}
|
||||
|
||||
// Validate performs a non-mutating admission control check and emits metrics.
|
||||
func (p pluginHandlerWithMetrics) Validate(a admission.Attributes) error {
|
||||
func (p pluginHandlerWithMetrics) Validate(a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
validatingHandler, ok := p.Interface.(admission.ValidationInterface)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
err := validatingHandler.Validate(a)
|
||||
err := validatingHandler.Validate(a, o)
|
||||
p.observer(time.Since(start), err != nil, a, stepValidate, p.extraLabels...)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -34,8 +34,8 @@ var (
|
|||
func TestObserveAdmissionStep(t *testing.T) {
|
||||
Metrics.reset()
|
||||
handler := WithStepMetrics(&mutatingAndValidatingFakeHandler{admission.NewHandler(admission.Create), true, true})
|
||||
handler.(admission.MutationInterface).Admit(attr)
|
||||
handler.(admission.ValidationInterface).Validate(attr)
|
||||
handler.(admission.MutationInterface).Admit(attr, nil)
|
||||
handler.(admission.ValidationInterface).Validate(attr, nil)
|
||||
wantLabels := map[string]string{
|
||||
"operation": string(admission.Create),
|
||||
"type": "admit",
|
||||
|
@ -52,8 +52,8 @@ func TestObserveAdmissionStep(t *testing.T) {
|
|||
func TestObserveAdmissionController(t *testing.T) {
|
||||
Metrics.reset()
|
||||
handler := WithControllerMetrics(&mutatingAndValidatingFakeHandler{admission.NewHandler(admission.Create), true, true}, "a")
|
||||
handler.(admission.MutationInterface).Admit(attr)
|
||||
handler.(admission.ValidationInterface).Validate(attr)
|
||||
handler.(admission.MutationInterface).Admit(attr, nil)
|
||||
handler.(admission.ValidationInterface).Validate(attr, nil)
|
||||
wantLabels := map[string]string{
|
||||
"name": "a",
|
||||
"operation": string(admission.Create),
|
||||
|
@ -144,7 +144,7 @@ func TestWithMetrics(t *testing.T) {
|
|||
h := WithMetrics(test.handler, Metrics.ObserveAdmissionController, test.name)
|
||||
|
||||
// test mutation
|
||||
err := h.(admission.MutationInterface).Admit(admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, test.ns, "", schema.GroupVersionResource{}, "", test.operation, false, nil))
|
||||
err := h.(admission.MutationInterface).Admit(admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, test.ns, "", schema.GroupVersionResource{}, "", test.operation, false, nil), nil)
|
||||
if test.admit && err != nil {
|
||||
t.Errorf("expected admit to succeed, but failed: %v", err)
|
||||
continue
|
||||
|
@ -169,7 +169,7 @@ func TestWithMetrics(t *testing.T) {
|
|||
}
|
||||
|
||||
// test validation
|
||||
err = h.(admission.ValidationInterface).Validate(admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, test.ns, "", schema.GroupVersionResource{}, "", test.operation, false, nil))
|
||||
err = h.(admission.ValidationInterface).Validate(admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{}, test.ns, "", schema.GroupVersionResource{}, "", test.operation, false, nil), nil)
|
||||
if test.validate && err != nil {
|
||||
t.Errorf("expected admit to succeed, but failed: %v", err)
|
||||
continue
|
||||
|
@ -196,14 +196,14 @@ type mutatingAndValidatingFakeHandler struct {
|
|||
validate bool
|
||||
}
|
||||
|
||||
func (h *mutatingAndValidatingFakeHandler) Admit(a admission.Attributes) (err error) {
|
||||
func (h *mutatingAndValidatingFakeHandler) Admit(a admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
if h.admit {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("don't admit")
|
||||
}
|
||||
|
||||
func (h *mutatingAndValidatingFakeHandler) Validate(a admission.Attributes) (err error) {
|
||||
func (h *mutatingAndValidatingFakeHandler) Validate(a admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
if h.validate {
|
||||
return nil
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ type validatingFakeHandler struct {
|
|||
validate bool
|
||||
}
|
||||
|
||||
func (h *validatingFakeHandler) Validate(a admission.Attributes) (err error) {
|
||||
func (h *validatingFakeHandler) Validate(a admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
if h.validate {
|
||||
return nil
|
||||
}
|
||||
|
@ -227,7 +227,7 @@ type mutatingFakeHandler struct {
|
|||
admit bool
|
||||
}
|
||||
|
||||
func (h *mutatingFakeHandler) Admit(a admission.Attributes) (err error) {
|
||||
func (h *mutatingFakeHandler) Admit(a admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
if h.admit {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -17,39 +17,25 @@ limitations under the License.
|
|||
package generic
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
)
|
||||
|
||||
// convertor converts objects to the desired version.
|
||||
type convertor struct {
|
||||
Scheme *runtime.Scheme
|
||||
}
|
||||
|
||||
// ConvertToGVK converts object to the desired gvk.
|
||||
func (c *convertor) ConvertToGVK(obj runtime.Object, gvk schema.GroupVersionKind) (runtime.Object, error) {
|
||||
func ConvertToGVK(obj runtime.Object, gvk schema.GroupVersionKind, o admission.ObjectInterfaces) (runtime.Object, error) {
|
||||
// Unlike other resources, custom resources do not have internal version, so
|
||||
// if obj is a custom resource, it should not need conversion.
|
||||
if obj.GetObjectKind().GroupVersionKind() == gvk {
|
||||
return obj, nil
|
||||
}
|
||||
out, err := c.Scheme.New(gvk)
|
||||
out, err := o.GetObjectCreater().New(gvk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = c.Scheme.Convert(obj, out, nil)
|
||||
err = o.GetObjectConvertor().Convert(obj, out, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Validate checks if the conversion has a scheme.
|
||||
func (c *convertor) Validate() error {
|
||||
if c.Scheme == nil {
|
||||
return fmt.Errorf("the convertor requires a scheme")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/apiserver/pkg/apis/example"
|
||||
examplev1 "k8s.io/apiserver/pkg/apis/example/v1"
|
||||
example2v1 "k8s.io/apiserver/pkg/apis/example2/v1"
|
||||
|
@ -41,7 +42,7 @@ func initiateScheme(t *testing.T) *runtime.Scheme {
|
|||
|
||||
func TestConvertToGVK(t *testing.T) {
|
||||
scheme := initiateScheme(t)
|
||||
c := convertor{Scheme: scheme}
|
||||
o := &admission.SchemeBasedObjectInterfaces{scheme}
|
||||
table := map[string]struct {
|
||||
obj runtime.Object
|
||||
gvk schema.GroupVersionKind
|
||||
|
@ -122,7 +123,7 @@ func TestConvertToGVK(t *testing.T) {
|
|||
|
||||
for name, test := range table {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
actual, err := c.ConvertToGVK(test.obj, test.gvk)
|
||||
actual, err := ConvertToGVK(test.obj, test.gvk, o)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
|
|
@ -43,7 +43,6 @@ type Webhook struct {
|
|||
|
||||
hookSource Source
|
||||
clientManager *webhook.ClientManager
|
||||
convertor *convertor
|
||||
namespaceMatcher *namespace.Matcher
|
||||
dispatcher Dispatcher
|
||||
}
|
||||
|
@ -79,7 +78,6 @@ func NewWebhook(handler *admission.Handler, configFile io.Reader, sourceFactory
|
|||
Handler: handler,
|
||||
sourceFactory: sourceFactory,
|
||||
clientManager: &cm,
|
||||
convertor: &convertor{},
|
||||
namespaceMatcher: &namespace.Matcher{},
|
||||
dispatcher: dispatcherFactory(&cm),
|
||||
}, nil
|
||||
|
@ -100,9 +98,6 @@ func (a *Webhook) SetServiceResolver(sr webhook.ServiceResolver) {
|
|||
|
||||
// SetScheme sets a serializer(NegotiatedSerializer) which is derived from the scheme
|
||||
func (a *Webhook) SetScheme(scheme *runtime.Scheme) {
|
||||
if scheme != nil {
|
||||
a.convertor.Scheme = scheme
|
||||
}
|
||||
}
|
||||
|
||||
// SetExternalKubeClientSet implements the WantsExternalKubeInformerFactory interface.
|
||||
|
@ -132,9 +127,6 @@ func (a *Webhook) ValidateInitialization() error {
|
|||
if err := a.clientManager.Validate(); err != nil {
|
||||
return fmt.Errorf("clientManager is not properly setup: %v", err)
|
||||
}
|
||||
if err := a.convertor.Validate(); err != nil {
|
||||
return fmt.Errorf("convertor is not properly setup: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -156,7 +148,7 @@ func (a *Webhook) ShouldCallHook(h *v1beta1.Webhook, attr admission.Attributes)
|
|||
}
|
||||
|
||||
// Dispatch is called by the downstream Validate or Admit methods.
|
||||
func (a *Webhook) Dispatch(attr admission.Attributes) error {
|
||||
func (a *Webhook) Dispatch(attr admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
if rules.IsWebhookConfigurationResource(attr) {
|
||||
return nil
|
||||
}
|
||||
|
@ -188,14 +180,14 @@ func (a *Webhook) Dispatch(attr admission.Attributes) error {
|
|||
Attributes: attr,
|
||||
}
|
||||
if oldObj := attr.GetOldObject(); oldObj != nil {
|
||||
out, err := a.convertor.ConvertToGVK(oldObj, attr.GetKind())
|
||||
out, err := ConvertToGVK(oldObj, attr.GetKind(), o)
|
||||
if err != nil {
|
||||
return apierrors.NewInternalError(err)
|
||||
}
|
||||
versionedAttr.VersionedOldObject = out
|
||||
}
|
||||
if obj := attr.GetObject(); obj != nil {
|
||||
out, err := a.convertor.ConvertToGVK(obj, attr.GetKind())
|
||||
out, err := ConvertToGVK(obj, attr.GetKind(), o)
|
||||
if err != nil {
|
||||
return apierrors.NewInternalError(err)
|
||||
}
|
||||
|
|
|
@ -91,6 +91,6 @@ func (a *Plugin) ValidateInitialization() error {
|
|||
}
|
||||
|
||||
// Admit makes an admission decision based on the request attributes.
|
||||
func (a *Plugin) Admit(attr admission.Attributes) error {
|
||||
return a.Webhook.Dispatch(attr)
|
||||
func (a *Plugin) Admit(attr admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
return a.Webhook.Dispatch(attr, o)
|
||||
}
|
||||
|
|
|
@ -23,23 +23,15 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"k8s.io/api/admission/v1beta1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
webhooktesting "k8s.io/apiserver/pkg/admission/plugin/webhook/testing"
|
||||
)
|
||||
|
||||
// TestAdmit tests that MutatingWebhook#Admit works as expected
|
||||
func TestAdmit(t *testing.T) {
|
||||
scheme := runtime.NewScheme()
|
||||
require.NoError(t, v1beta1.AddToScheme(scheme))
|
||||
require.NoError(t, corev1.AddToScheme(scheme))
|
||||
|
||||
testServer := webhooktesting.NewTestServer(t)
|
||||
testServer.StartTLS()
|
||||
defer testServer.Close()
|
||||
|
@ -48,6 +40,8 @@ func TestAdmit(t *testing.T) {
|
|||
t.Fatalf("this should never happen? %v", err)
|
||||
}
|
||||
|
||||
objectInterfaces := webhooktesting.NewObjectInterfacesForTest()
|
||||
|
||||
stopCh := make(chan struct{})
|
||||
defer close(stopCh)
|
||||
|
||||
|
@ -66,7 +60,6 @@ func TestAdmit(t *testing.T) {
|
|||
|
||||
wh.SetAuthenticationInfoResolverWrapper(webhooktesting.Wrapper(webhooktesting.NewAuthenticationInfoResolver(new(int32))))
|
||||
wh.SetServiceResolver(webhooktesting.NewServiceResolver(*serverURL))
|
||||
wh.SetScheme(scheme)
|
||||
wh.SetExternalKubeClientSet(client)
|
||||
wh.SetExternalKubeInformerFactory(informer)
|
||||
|
||||
|
@ -85,7 +78,7 @@ func TestAdmit(t *testing.T) {
|
|||
attr = webhooktesting.NewAttribute(ns, tt.AdditionalLabels, tt.IsDryRun)
|
||||
}
|
||||
|
||||
err = wh.Admit(attr)
|
||||
err = wh.Admit(attr, objectInterfaces)
|
||||
if tt.ExpectAllow != (err == nil) {
|
||||
t.Errorf("%s: expected allowed=%v, but got err=%v", tt.Name, tt.ExpectAllow, err)
|
||||
}
|
||||
|
@ -118,10 +111,6 @@ func TestAdmit(t *testing.T) {
|
|||
|
||||
// TestAdmitCachedClient tests that MutatingWebhook#Admit should cache restClient
|
||||
func TestAdmitCachedClient(t *testing.T) {
|
||||
scheme := runtime.NewScheme()
|
||||
require.NoError(t, v1beta1.AddToScheme(scheme))
|
||||
require.NoError(t, corev1.AddToScheme(scheme))
|
||||
|
||||
testServer := webhooktesting.NewTestServer(t)
|
||||
testServer.StartTLS()
|
||||
defer testServer.Close()
|
||||
|
@ -130,6 +119,8 @@ func TestAdmitCachedClient(t *testing.T) {
|
|||
t.Fatalf("this should never happen? %v", err)
|
||||
}
|
||||
|
||||
objectInterfaces := webhooktesting.NewObjectInterfacesForTest()
|
||||
|
||||
stopCh := make(chan struct{})
|
||||
defer close(stopCh)
|
||||
|
||||
|
@ -138,7 +129,6 @@ func TestAdmitCachedClient(t *testing.T) {
|
|||
t.Fatalf("Failed to create mutating webhook: %v", err)
|
||||
}
|
||||
wh.SetServiceResolver(webhooktesting.NewServiceResolver(*serverURL))
|
||||
wh.SetScheme(scheme)
|
||||
|
||||
for _, tt := range webhooktesting.NewCachedClientTestcases(serverURL) {
|
||||
ns := "webhook-test"
|
||||
|
@ -158,7 +148,7 @@ func TestAdmitCachedClient(t *testing.T) {
|
|||
continue
|
||||
}
|
||||
|
||||
err = wh.Admit(webhooktesting.NewAttribute(ns, nil, false))
|
||||
err = wh.Admit(webhooktesting.NewAttribute(ns, nil, false), objectInterfaces)
|
||||
if tt.ExpectAllow != (err == nil) {
|
||||
t.Errorf("%s: expected allowed=%v, but got err=%v", tt.Name, tt.ExpectAllow, err)
|
||||
}
|
||||
|
|
|
@ -649,3 +649,10 @@ func newMatchEverythingRules() []registrationv1beta1.RuleWithOperations {
|
|||
},
|
||||
}}
|
||||
}
|
||||
|
||||
// NewObjectInterfacesForTest returns an ObjectInterfaces appropriate for test cases in this file.
|
||||
func NewObjectInterfacesForTest() admission.ObjectInterfaces {
|
||||
scheme := runtime.NewScheme()
|
||||
corev1.AddToScheme(scheme)
|
||||
return &admission.SchemeBasedObjectInterfaces{scheme}
|
||||
}
|
||||
|
|
|
@ -59,6 +59,6 @@ func NewValidatingAdmissionWebhook(configFile io.Reader) (*Plugin, error) {
|
|||
}
|
||||
|
||||
// Validate makes an admission decision based on the request attributes.
|
||||
func (a *Plugin) Validate(attr admission.Attributes) error {
|
||||
return a.Webhook.Dispatch(attr)
|
||||
func (a *Plugin) Validate(attr admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
return a.Webhook.Dispatch(attr, o)
|
||||
}
|
||||
|
|
|
@ -22,25 +22,19 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"k8s.io/api/admission/v1beta1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
webhooktesting "k8s.io/apiserver/pkg/admission/plugin/webhook/testing"
|
||||
)
|
||||
|
||||
// TestValidate tests that ValidatingWebhook#Validate works as expected
|
||||
func TestValidate(t *testing.T) {
|
||||
scheme := runtime.NewScheme()
|
||||
require.NoError(t, v1beta1.AddToScheme(scheme))
|
||||
require.NoError(t, corev1.AddToScheme(scheme))
|
||||
|
||||
testServer := webhooktesting.NewTestServer(t)
|
||||
testServer.StartTLS()
|
||||
defer testServer.Close()
|
||||
|
||||
objectInterfaces := webhooktesting.NewObjectInterfacesForTest()
|
||||
|
||||
serverURL, err := url.ParseRequestURI(testServer.URL)
|
||||
if err != nil {
|
||||
t.Fatalf("this should never happen? %v", err)
|
||||
|
@ -61,7 +55,6 @@ func TestValidate(t *testing.T) {
|
|||
|
||||
wh.SetAuthenticationInfoResolverWrapper(webhooktesting.Wrapper(webhooktesting.NewAuthenticationInfoResolver(new(int32))))
|
||||
wh.SetServiceResolver(webhooktesting.NewServiceResolver(*serverURL))
|
||||
wh.SetScheme(scheme)
|
||||
wh.SetExternalKubeClientSet(client)
|
||||
wh.SetExternalKubeInformerFactory(informer)
|
||||
|
||||
|
@ -74,7 +67,7 @@ func TestValidate(t *testing.T) {
|
|||
}
|
||||
|
||||
attr := webhooktesting.NewAttribute(ns, nil, tt.IsDryRun)
|
||||
err = wh.Validate(attr)
|
||||
err = wh.Validate(attr, objectInterfaces)
|
||||
if tt.ExpectAllow != (err == nil) {
|
||||
t.Errorf("%s: expected allowed=%v, but got err=%v", tt.Name, tt.ExpectAllow, err)
|
||||
}
|
||||
|
@ -102,10 +95,6 @@ func TestValidate(t *testing.T) {
|
|||
|
||||
// TestValidateCachedClient tests that ValidatingWebhook#Validate should cache restClient
|
||||
func TestValidateCachedClient(t *testing.T) {
|
||||
scheme := runtime.NewScheme()
|
||||
require.NoError(t, v1beta1.AddToScheme(scheme))
|
||||
require.NoError(t, corev1.AddToScheme(scheme))
|
||||
|
||||
testServer := webhooktesting.NewTestServer(t)
|
||||
testServer.StartTLS()
|
||||
defer testServer.Close()
|
||||
|
@ -114,6 +103,8 @@ func TestValidateCachedClient(t *testing.T) {
|
|||
t.Fatalf("this should never happen? %v", err)
|
||||
}
|
||||
|
||||
objectInterfaces := webhooktesting.NewObjectInterfacesForTest()
|
||||
|
||||
stopCh := make(chan struct{})
|
||||
defer close(stopCh)
|
||||
|
||||
|
@ -122,7 +113,6 @@ func TestValidateCachedClient(t *testing.T) {
|
|||
t.Fatalf("Failed to create validating webhook: %v", err)
|
||||
}
|
||||
wh.SetServiceResolver(webhooktesting.NewServiceResolver(*serverURL))
|
||||
wh.SetScheme(scheme)
|
||||
|
||||
for _, tt := range webhooktesting.NewCachedClientTestcases(serverURL) {
|
||||
ns := "webhook-test"
|
||||
|
@ -142,7 +132,7 @@ func TestValidateCachedClient(t *testing.T) {
|
|||
continue
|
||||
}
|
||||
|
||||
err = wh.Validate(webhooktesting.NewAttribute(ns, nil, false))
|
||||
err = wh.Validate(webhooktesting.NewAttribute(ns, nil, false), objectInterfaces)
|
||||
if tt.ExpectAllow != (err == nil) {
|
||||
t.Errorf("%s: expected allowed=%v, but got err=%v", tt.Name, tt.ExpectAllow, err)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
Copyright 2019 The Kubernetes Authors.
|
||||
|
||||
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 admission
|
||||
|
||||
import "k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
type SchemeBasedObjectInterfaces struct {
|
||||
Scheme *runtime.Scheme
|
||||
}
|
||||
|
||||
func (r *SchemeBasedObjectInterfaces) GetObjectCreater() runtime.ObjectCreater { return r.Scheme }
|
||||
func (r *SchemeBasedObjectInterfaces) GetObjectTyper() runtime.ObjectTyper { return r.Scheme }
|
||||
func (r *SchemeBasedObjectInterfaces) GetObjectDefaulter() runtime.ObjectDefaulter { return r.Scheme }
|
||||
func (r *SchemeBasedObjectInterfaces) GetObjectConvertor() runtime.ObjectConvertor { return r.Scheme }
|
|
@ -76,7 +76,7 @@ import (
|
|||
|
||||
type alwaysMutatingDeny struct{}
|
||||
|
||||
func (alwaysMutatingDeny) Admit(a admission.Attributes) (err error) {
|
||||
func (alwaysMutatingDeny) Admit(a admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
return admission.NewForbidden(a, errors.New("Mutating admission control is denying all modifications"))
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ func (alwaysMutatingDeny) Handles(operation admission.Operation) bool {
|
|||
|
||||
type alwaysValidatingDeny struct{}
|
||||
|
||||
func (alwaysValidatingDeny) Validate(a admission.Attributes) (err error) {
|
||||
func (alwaysValidatingDeny) Validate(a admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
return admission.NewForbidden(a, errors.New("Validating admission control is denying all modifications"))
|
||||
}
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ func createHandler(r rest.NamedCreater, scope RequestScope, admit admission.Inte
|
|||
userInfo, _ := request.UserFrom(ctx)
|
||||
admissionAttributes := admission.NewAttributesRecord(obj, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Create, dryrun.IsDryRun(options.DryRun), userInfo)
|
||||
if mutatingAdmission, ok := admit.(admission.MutationInterface); ok && mutatingAdmission.Handles(admission.Create) {
|
||||
err = mutatingAdmission.Admit(admissionAttributes)
|
||||
err = mutatingAdmission.Admit(admissionAttributes, &scope)
|
||||
if err != nil {
|
||||
scope.err(err, w, req)
|
||||
return
|
||||
|
@ -154,7 +154,7 @@ func createHandler(r rest.NamedCreater, scope RequestScope, admit admission.Inte
|
|||
ctx,
|
||||
name,
|
||||
obj,
|
||||
rest.AdmissionToValidateObjectFunc(admit, admissionAttributes),
|
||||
rest.AdmissionToValidateObjectFunc(admit, admissionAttributes, &scope),
|
||||
options,
|
||||
)
|
||||
})
|
||||
|
|
|
@ -119,13 +119,13 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope RequestSco
|
|||
userInfo, _ := request.UserFrom(ctx)
|
||||
attrs := admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Delete, dryrun.IsDryRun(options.DryRun), userInfo)
|
||||
if mutatingAdmission, ok := admit.(admission.MutationInterface); ok {
|
||||
if err := mutatingAdmission.Admit(attrs); err != nil {
|
||||
if err := mutatingAdmission.Admit(attrs, &scope); err != nil {
|
||||
scope.err(err, w, req)
|
||||
return
|
||||
}
|
||||
}
|
||||
if validatingAdmission, ok := admit.(admission.ValidationInterface); ok {
|
||||
if err := validatingAdmission.Validate(attrs); err != nil {
|
||||
if err := validatingAdmission.Validate(attrs, &scope); err != nil {
|
||||
scope.err(err, w, req)
|
||||
return
|
||||
}
|
||||
|
@ -269,7 +269,7 @@ func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope RequestSco
|
|||
userInfo, _ := request.UserFrom(ctx)
|
||||
attrs := admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, "", scope.Resource, scope.Subresource, admission.Delete, dryrun.IsDryRun(options.DryRun), userInfo)
|
||||
if mutatingAdmission, ok := admit.(admission.MutationInterface); ok {
|
||||
err = mutatingAdmission.Admit(attrs)
|
||||
err = mutatingAdmission.Admit(attrs, &scope)
|
||||
if err != nil {
|
||||
scope.err(err, w, req)
|
||||
return
|
||||
|
@ -277,7 +277,7 @@ func DeleteCollection(r rest.CollectionDeleter, checkBody bool, scope RequestSco
|
|||
}
|
||||
|
||||
if validatingAdmission, ok := admit.(admission.ValidationInterface); ok {
|
||||
err = validatingAdmission.Validate(attrs)
|
||||
err = validatingAdmission.Validate(attrs, &scope)
|
||||
if err != nil {
|
||||
scope.err(err, w, req)
|
||||
return
|
||||
|
|
|
@ -191,10 +191,12 @@ func PatchResource(r rest.Patcher, scope RequestScope, admit admission.Interface
|
|||
subresource: scope.Subresource,
|
||||
dryRun: dryrun.IsDryRun(options.DryRun),
|
||||
|
||||
objectInterfaces: &scope,
|
||||
|
||||
hubGroupVersion: scope.HubGroupVersion,
|
||||
|
||||
createValidation: withAuthorization(rest.AdmissionToValidateObjectFunc(admit, staticCreateAttributes), scope.Authorizer, createAuthorizerAttributes),
|
||||
updateValidation: rest.AdmissionToValidateObjectUpdateFunc(admit, staticUpdateAttributes),
|
||||
createValidation: withAuthorization(rest.AdmissionToValidateObjectFunc(admit, staticCreateAttributes, &scope), scope.Authorizer, createAuthorizerAttributes),
|
||||
updateValidation: rest.AdmissionToValidateObjectUpdateFunc(admit, staticUpdateAttributes, &scope),
|
||||
admissionCheck: mutatingAdmission,
|
||||
|
||||
codec: codec,
|
||||
|
@ -257,6 +259,8 @@ type patcher struct {
|
|||
subresource string
|
||||
dryRun bool
|
||||
|
||||
objectInterfaces admission.ObjectInterfaces
|
||||
|
||||
hubGroupVersion schema.GroupVersion
|
||||
|
||||
// Validation functions
|
||||
|
@ -507,7 +511,7 @@ func (p *patcher) applyAdmission(ctx context.Context, patchedObject runtime.Obje
|
|||
}
|
||||
if p.admissionCheck != nil && p.admissionCheck.Handles(operation) {
|
||||
attributes := p.admissionAttributes(ctx, patchedObject, currentObject, operation)
|
||||
return patchedObject, p.admissionCheck.Admit(attributes)
|
||||
return patchedObject, p.admissionCheck.Admit(attributes, p.objectInterfaces)
|
||||
}
|
||||
return patchedObject, nil
|
||||
}
|
||||
|
|
|
@ -103,6 +103,13 @@ func (scope *RequestScope) AllowsStreamSchema(s string) bool {
|
|||
return s == "watch"
|
||||
}
|
||||
|
||||
var _ admission.ObjectInterfaces = &RequestScope{}
|
||||
|
||||
func (r *RequestScope) GetObjectCreater() runtime.ObjectCreater { return r.Creater }
|
||||
func (r *RequestScope) GetObjectTyper() runtime.ObjectTyper { return r.Typer }
|
||||
func (r *RequestScope) GetObjectDefaulter() runtime.ObjectDefaulter { return r.Defaulter }
|
||||
func (r *RequestScope) GetObjectConvertor() runtime.ObjectConvertor { return r.Convertor }
|
||||
|
||||
// ConnectResource returns a function that handles a connect request on a rest.Storage object.
|
||||
func ConnectResource(connecter rest.Connecter, scope RequestScope, admit admission.Interface, restPath string, isSubresource bool) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, req *http.Request) {
|
||||
|
@ -131,14 +138,14 @@ func ConnectResource(connecter rest.Connecter, scope RequestScope, admit admissi
|
|||
userInfo, _ := request.UserFrom(ctx)
|
||||
// TODO: remove the mutating admission here as soon as we have ported all plugin that handle CONNECT
|
||||
if mutatingAdmission, ok := admit.(admission.MutationInterface); ok {
|
||||
err = mutatingAdmission.Admit(admission.NewAttributesRecord(opts, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Connect, false, userInfo))
|
||||
err = mutatingAdmission.Admit(admission.NewAttributesRecord(opts, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Connect, false, userInfo), &scope)
|
||||
if err != nil {
|
||||
scope.err(err, w, req)
|
||||
return
|
||||
}
|
||||
}
|
||||
if validatingAdmission, ok := admit.(admission.ValidationInterface); ok {
|
||||
err = validatingAdmission.Validate(admission.NewAttributesRecord(opts, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Connect, false, userInfo))
|
||||
err = validatingAdmission.Validate(admission.NewAttributesRecord(opts, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Connect, false, userInfo), &scope)
|
||||
if err != nil {
|
||||
scope.err(err, w, req)
|
||||
return
|
||||
|
|
|
@ -365,6 +365,7 @@ func (tc *patchTestCase) Run(t *testing.T) {
|
|||
creater := runtime.ObjectCreater(scheme)
|
||||
defaulter := runtime.ObjectDefaulter(scheme)
|
||||
convertor := runtime.UnsafeObjectConvertor(scheme)
|
||||
objectInterfaces := &admission.SchemeBasedObjectInterfaces{scheme}
|
||||
kind := examplev1.SchemeGroupVersion.WithKind("Pod")
|
||||
resource := examplev1.SchemeGroupVersion.WithResource("pods")
|
||||
schemaReferenceObj := &examplev1.Pod{}
|
||||
|
@ -441,6 +442,8 @@ func (tc *patchTestCase) Run(t *testing.T) {
|
|||
kind: kind,
|
||||
resource: resource,
|
||||
|
||||
objectInterfaces: objectInterfaces,
|
||||
|
||||
hubGroupVersion: hubVersion,
|
||||
|
||||
createValidation: rest.ValidateAllObjectFunc,
|
||||
|
@ -944,6 +947,6 @@ func (f mutateObjectUpdateFunc) Handles(operation admission.Operation) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (f mutateObjectUpdateFunc) Admit(a admission.Attributes) (err error) {
|
||||
func (f mutateObjectUpdateFunc) Admit(a admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
return f(a.GetObject(), a.GetOldObject())
|
||||
}
|
||||
|
|
|
@ -138,11 +138,11 @@ func UpdateResource(r rest.Updater, scope RequestScope, admit admission.Interfac
|
|||
return nil, fmt.Errorf("unexpected error when extracting UID from oldObj: %v", err.Error())
|
||||
} else if !isNotZeroObject {
|
||||
if mutatingAdmission.Handles(admission.Create) {
|
||||
return newObj, mutatingAdmission.Admit(admission.NewAttributesRecord(newObj, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Create, dryrun.IsDryRun(options.DryRun), userInfo))
|
||||
return newObj, mutatingAdmission.Admit(admission.NewAttributesRecord(newObj, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Create, dryrun.IsDryRun(options.DryRun), userInfo), &scope)
|
||||
}
|
||||
} else {
|
||||
if mutatingAdmission.Handles(admission.Update) {
|
||||
return newObj, mutatingAdmission.Admit(admission.NewAttributesRecord(newObj, oldObj, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Update, dryrun.IsDryRun(options.DryRun), userInfo))
|
||||
return newObj, mutatingAdmission.Admit(admission.NewAttributesRecord(newObj, oldObj, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Update, dryrun.IsDryRun(options.DryRun), userInfo), &scope)
|
||||
}
|
||||
}
|
||||
return newObj, nil
|
||||
|
@ -172,11 +172,11 @@ func UpdateResource(r rest.Updater, scope RequestScope, admit admission.Interfac
|
|||
rest.DefaultUpdatedObjectInfo(obj, transformers...),
|
||||
withAuthorization(rest.AdmissionToValidateObjectFunc(
|
||||
admit,
|
||||
admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Create, dryrun.IsDryRun(options.DryRun), userInfo)),
|
||||
admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Create, dryrun.IsDryRun(options.DryRun), userInfo), &scope),
|
||||
scope.Authorizer, createAuthorizerAttributes),
|
||||
rest.AdmissionToValidateObjectUpdateFunc(
|
||||
admit,
|
||||
admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Update, dryrun.IsDryRun(options.DryRun), userInfo)),
|
||||
admission.NewAttributesRecord(nil, nil, scope.Kind, namespace, name, scope.Resource, scope.Subresource, admission.Update, dryrun.IsDryRun(options.DryRun), userInfo), &scope),
|
||||
false,
|
||||
options,
|
||||
)
|
||||
|
|
|
@ -160,7 +160,7 @@ type NamespaceScopedStrategy interface {
|
|||
}
|
||||
|
||||
// AdmissionToValidateObjectFunc converts validating admission to a rest validate object func
|
||||
func AdmissionToValidateObjectFunc(admit admission.Interface, staticAttributes admission.Attributes) ValidateObjectFunc {
|
||||
func AdmissionToValidateObjectFunc(admit admission.Interface, staticAttributes admission.Attributes, o admission.ObjectInterfaces) ValidateObjectFunc {
|
||||
validatingAdmission, ok := admit.(admission.ValidationInterface)
|
||||
if !ok {
|
||||
return func(obj runtime.Object) error { return nil }
|
||||
|
@ -181,6 +181,6 @@ func AdmissionToValidateObjectFunc(admit admission.Interface, staticAttributes a
|
|||
if !validatingAdmission.Handles(finalAttributes.GetOperation()) {
|
||||
return nil
|
||||
}
|
||||
return validatingAdmission.Validate(finalAttributes)
|
||||
return validatingAdmission.Validate(finalAttributes, o)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -256,7 +256,7 @@ func (i *wrappedUpdatedObjectInfo) UpdatedObject(ctx context.Context, oldObj run
|
|||
}
|
||||
|
||||
// AdmissionToValidateObjectUpdateFunc converts validating admission to a rest validate object update func
|
||||
func AdmissionToValidateObjectUpdateFunc(admit admission.Interface, staticAttributes admission.Attributes) ValidateObjectUpdateFunc {
|
||||
func AdmissionToValidateObjectUpdateFunc(admit admission.Interface, staticAttributes admission.Attributes, o admission.ObjectInterfaces) ValidateObjectUpdateFunc {
|
||||
validatingAdmission, ok := admit.(admission.ValidationInterface)
|
||||
if !ok {
|
||||
return func(obj, old runtime.Object) error { return nil }
|
||||
|
@ -277,6 +277,6 @@ func AdmissionToValidateObjectUpdateFunc(admit admission.Interface, staticAttrib
|
|||
if !validatingAdmission.Handles(finalAttributes.GetOperation()) {
|
||||
return nil
|
||||
}
|
||||
return validatingAdmission.Validate(finalAttributes)
|
||||
return validatingAdmission.Validate(finalAttributes, o)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue