Merge pull request #74154 from mbohlool/gimli
Use Request Object interfaces instead of static scheme that is more appropriate for CRDs
This commit is contained in:
commit
0ffd59e403
@ -70,7 +70,6 @@ func createAggregatorConfig(
|
||||
&genericConfig,
|
||||
externalInformers,
|
||||
genericConfig.LoopbackClientConfig,
|
||||
aggregatorscheme.Scheme,
|
||||
pluginInitializers...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -52,7 +52,6 @@ func createAPIExtensionsConfig(
|
||||
&genericConfig,
|
||||
externalInformers,
|
||||
genericConfig.LoopbackClientConfig,
|
||||
apiextensionsapiserver.Scheme,
|
||||
pluginInitializers...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -491,7 +491,6 @@ func buildGenericConfig(
|
||||
genericConfig,
|
||||
versionedInformers,
|
||||
kubeClientConfig,
|
||||
legacyscheme.Scheme,
|
||||
pluginInitializers...)
|
||||
if err != nil {
|
||||
lastErr = fmt.Errorf("failed to initialize admission: %v", err)
|
||||
|
@ -24,7 +24,9 @@ import (
|
||||
|
||||
type doNothingAdmission struct{}
|
||||
|
||||
func (doNothingAdmission) Admit(a admission.Attributes) error { return nil }
|
||||
func (doNothingAdmission) Admit(a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
return nil
|
||||
}
|
||||
func (doNothingAdmission) Handles(o admission.Operation) bool { return false }
|
||||
func (doNothingAdmission) Validate() error { return nil }
|
||||
|
||||
|
@ -51,7 +51,6 @@ go_library(
|
||||
"//plugin/pkg/admission/storage/persistentvolume/resize:go_default_library",
|
||||
"//plugin/pkg/admission/storage/storageclass/setdefault:go_default_library",
|
||||
"//plugin/pkg/admission/storage/storageobjectinuseprotection:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
|
@ -22,7 +22,6 @@ import (
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/apiserver/pkg/server"
|
||||
@ -108,7 +107,6 @@ func (a *AdmissionOptions) ApplyTo(
|
||||
c *server.Config,
|
||||
informers informers.SharedInformerFactory,
|
||||
kubeAPIServerClientConfig *rest.Config,
|
||||
scheme *runtime.Scheme,
|
||||
pluginInitializers ...admission.PluginInitializer,
|
||||
) error {
|
||||
if a == nil {
|
||||
@ -120,7 +118,7 @@ func (a *AdmissionOptions) ApplyTo(
|
||||
a.GenericAdmission.EnablePlugins, a.GenericAdmission.DisablePlugins = computePluginNames(a.PluginNames, a.GenericAdmission.RecommendedPluginOrder)
|
||||
}
|
||||
|
||||
return a.GenericAdmission.ApplyTo(c, informers, kubeAPIServerClientConfig, scheme, pluginInitializers...)
|
||||
return a.GenericAdmission.ApplyTo(c, informers, kubeAPIServerClientConfig, pluginInitializers...)
|
||||
}
|
||||
|
||||
// explicitly disable all plugins that are not in the enabled list
|
||||
|
@ -40,12 +40,12 @@ var _ admission.MutationInterface = alwaysAdmit{}
|
||||
var _ admission.ValidationInterface = alwaysAdmit{}
|
||||
|
||||
// Admit makes an admission decision based on the request attributes
|
||||
func (alwaysAdmit) Admit(a admission.Attributes) (err error) {
|
||||
func (alwaysAdmit) Admit(a admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate makes an admission decision based on the request attributes. It is NOT allowed to mutate.
|
||||
func (alwaysAdmit) Validate(a admission.Attributes) (err error) {
|
||||
func (alwaysAdmit) Validate(a admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ import (
|
||||
|
||||
func TestAdmissionNonNilAttribute(t *testing.T) {
|
||||
handler := NewAlwaysAdmit()
|
||||
err := handler.(*alwaysAdmit).Admit(admission.NewAttributesRecord(nil, nil, api.Kind("kind").WithVersion("version"), "namespace", "name", api.Resource("resource").WithVersion("version"), "subresource", admission.Create, false, nil))
|
||||
err := handler.(*alwaysAdmit).Admit(admission.NewAttributesRecord(nil, nil, api.Kind("kind").WithVersion("version"), "namespace", "name", api.Resource("resource").WithVersion("version"), "subresource", admission.Create, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error returned from admission handler")
|
||||
}
|
||||
@ -33,7 +33,7 @@ func TestAdmissionNonNilAttribute(t *testing.T) {
|
||||
|
||||
func TestAdmissionNilAttribute(t *testing.T) {
|
||||
handler := NewAlwaysAdmit()
|
||||
err := handler.(*alwaysAdmit).Admit(nil)
|
||||
err := handler.(*alwaysAdmit).Admit(nil, nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error returned from admission handler")
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ var _ admission.MutationInterface = &AlwaysPullImages{}
|
||||
var _ admission.ValidationInterface = &AlwaysPullImages{}
|
||||
|
||||
// Admit makes an admission decision based on the request attributes
|
||||
func (a *AlwaysPullImages) Admit(attributes admission.Attributes) (err error) {
|
||||
func (a *AlwaysPullImages) Admit(attributes admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
// Ignore all calls to subresources or resources other than pods.
|
||||
if shouldIgnore(attributes) {
|
||||
return nil
|
||||
@ -75,7 +75,7 @@ func (a *AlwaysPullImages) Admit(attributes admission.Attributes) (err error) {
|
||||
}
|
||||
|
||||
// Validate makes sure that all containers are set to always pull images
|
||||
func (*AlwaysPullImages) Validate(attributes admission.Attributes) (err error) {
|
||||
func (*AlwaysPullImages) Validate(attributes admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
if shouldIgnore(attributes) {
|
||||
return nil
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ func TestAdmission(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
err := handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err := handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error returned from admission handler")
|
||||
}
|
||||
@ -84,7 +84,7 @@ func TestValidate(t *testing.T) {
|
||||
},
|
||||
}
|
||||
expectedError := `pods "123" is forbidden: spec.initContainers[0].imagePullPolicy: Unsupported value: "": supported values: "Always"`
|
||||
err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err == nil {
|
||||
t.Fatal("missing expected error")
|
||||
}
|
||||
@ -139,7 +139,7 @@ func TestOtherResources(t *testing.T) {
|
||||
for _, tc := range tests {
|
||||
handler := &AlwaysPullImages{}
|
||||
|
||||
err := handler.Admit(admission.NewAttributesRecord(tc.object, nil, api.Kind(tc.kind).WithVersion("version"), namespace, name, api.Resource(tc.resource).WithVersion("version"), tc.subresource, admission.Create, false, nil))
|
||||
err := handler.Admit(admission.NewAttributesRecord(tc.object, nil, api.Kind(tc.kind).WithVersion("version"), namespace, name, api.Resource(tc.resource).WithVersion("version"), tc.subresource, admission.Create, false, nil), nil)
|
||||
|
||||
if tc.expectError {
|
||||
if err == nil {
|
||||
|
@ -51,7 +51,7 @@ func NewInterPodAntiAffinity() *Plugin {
|
||||
|
||||
// Validate will deny any pod that defines AntiAffinity topology key other than v1.LabelHostname i.e. "kubernetes.io/hostname"
|
||||
// in requiredDuringSchedulingRequiredDuringExecution and requiredDuringSchedulingIgnoredDuringExecution.
|
||||
func (p *Plugin) Validate(attributes admission.Attributes) (err error) {
|
||||
func (p *Plugin) Validate(attributes admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
// Ignore all calls to subresources or resources other than pods.
|
||||
if len(attributes.GetSubresource()) != 0 || attributes.GetResource().GroupResource() != api.Resource("pods") {
|
||||
return nil
|
||||
|
@ -199,7 +199,7 @@ func TestInterPodAffinityAdmission(t *testing.T) {
|
||||
}
|
||||
for _, test := range tests {
|
||||
pod.Spec.Affinity = test.affinity
|
||||
err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", false, nil), nil)
|
||||
|
||||
if test.errorExpected && err == nil {
|
||||
t.Errorf("Expected error for Anti Affinity %+v but did not get an error", test.affinity)
|
||||
@ -267,7 +267,7 @@ func TestOtherResources(t *testing.T) {
|
||||
for _, tc := range tests {
|
||||
handler := &Plugin{}
|
||||
|
||||
err := handler.Validate(admission.NewAttributesRecord(tc.object, nil, api.Kind(tc.kind).WithVersion("version"), namespace, name, api.Resource(tc.resource).WithVersion("version"), tc.subresource, admission.Create, false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(tc.object, nil, api.Kind(tc.kind).WithVersion("version"), namespace, name, api.Resource(tc.resource).WithVersion("version"), tc.subresource, admission.Create, false, nil), nil)
|
||||
|
||||
if tc.expectError {
|
||||
if err == nil {
|
||||
|
@ -81,7 +81,7 @@ func NewDefaultTolerationSeconds() *Plugin {
|
||||
}
|
||||
|
||||
// Admit makes an admission decision based on the request attributes
|
||||
func (p *Plugin) Admit(attributes admission.Attributes) (err error) {
|
||||
func (p *Plugin) Admit(attributes admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
if attributes.GetResource().GroupResource() != api.Resource("pods") {
|
||||
return nil
|
||||
}
|
||||
|
@ -263,7 +263,7 @@ func TestForgivenessAdmission(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
err := handler.Admit(admission.NewAttributesRecord(&test.requestedPod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", false, nil))
|
||||
err := handler.Admit(admission.NewAttributesRecord(&test.requestedPod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("[%s]: unexpected error %v for pod %+v", test.description, err, test.requestedPod)
|
||||
}
|
||||
|
@ -42,12 +42,12 @@ var _ admission.MutationInterface = alwaysDeny{}
|
||||
var _ admission.ValidationInterface = alwaysDeny{}
|
||||
|
||||
// Admit makes an admission decision based on the request attributes.
|
||||
func (alwaysDeny) Admit(a admission.Attributes) (err error) {
|
||||
func (alwaysDeny) Admit(a admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
return admission.NewForbidden(a, errors.New("admission control is denying all modifications"))
|
||||
}
|
||||
|
||||
// Validate makes an admission decision based on the request attributes. It is NOT allowed to mutate.
|
||||
func (alwaysDeny) Validate(a admission.Attributes) (err error) {
|
||||
func (alwaysDeny) Validate(a admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
return admission.NewForbidden(a, errors.New("admission control is denying all modifications"))
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ import (
|
||||
|
||||
func TestAdmission(t *testing.T) {
|
||||
handler := NewAlwaysDeny()
|
||||
err := handler.(*alwaysDeny).Admit(admission.NewAttributesRecord(nil, nil, api.Kind("kind").WithVersion("version"), "namespace", "name", api.Resource("resource").WithVersion("version"), "subresource", admission.Create, false, nil))
|
||||
err := handler.(*alwaysDeny).Admit(admission.NewAttributesRecord(nil, nil, api.Kind("kind").WithVersion("version"), "namespace", "name", api.Resource("resource").WithVersion("version"), "subresource", admission.Create, false, nil), nil)
|
||||
if err == nil {
|
||||
t.Error("Expected error returned from admission handler")
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ func newEventRateLimit(config *eventratelimitapi.Configuration, clock flowcontro
|
||||
}
|
||||
|
||||
// Validate makes admission decisions while enforcing event rate limits
|
||||
func (a *Plugin) Validate(attr admission.Attributes) (err error) {
|
||||
func (a *Plugin) Validate(attr admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
// ignore all operations that do not correspond to an Event kind
|
||||
if attr.GetKind().GroupKind() != api.Kind("Event") {
|
||||
return nil
|
||||
|
@ -504,7 +504,7 @@ func TestEventRateLimiting(t *testing.T) {
|
||||
clock.Step(rq.delay)
|
||||
}
|
||||
attributes := attributesForRequest(rq)
|
||||
err = eventratelimit.Validate(attributes)
|
||||
err = eventratelimit.Validate(attributes, nil)
|
||||
if rq.accepted != (err == nil) {
|
||||
expectedAction := "admitted"
|
||||
if !rq.accepted {
|
||||
|
@ -111,7 +111,7 @@ func (d *DenyExec) ValidateInitialization() error {
|
||||
}
|
||||
|
||||
// Validate makes an admission decision based on the request attributes
|
||||
func (d *DenyExec) Validate(a admission.Attributes) (err error) {
|
||||
func (d *DenyExec) Validate(a admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
path := a.GetResource().Resource
|
||||
if subresource := a.GetSubresource(); subresource != "" {
|
||||
path = path + "/" + subresource
|
||||
|
@ -120,7 +120,7 @@ func testAdmission(t *testing.T, pod *corev1.Pod, handler *DenyExec, shouldAccep
|
||||
|
||||
// pods/exec
|
||||
{
|
||||
err := handler.Validate(admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), "test", pod.Name, api.Resource("pods").WithVersion("version"), "exec", admission.Connect, false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), "test", pod.Name, api.Resource("pods").WithVersion("version"), "exec", admission.Connect, false, nil), nil)
|
||||
if shouldAccept && err != nil {
|
||||
t.Errorf("Unexpected error returned from admission handler: %v", err)
|
||||
}
|
||||
@ -131,7 +131,7 @@ func testAdmission(t *testing.T, pod *corev1.Pod, handler *DenyExec, shouldAccep
|
||||
|
||||
// pods/attach
|
||||
{
|
||||
err := handler.Validate(admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), "test", pod.Name, api.Resource("pods").WithVersion("version"), "attach", admission.Connect, false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), "test", pod.Name, api.Resource("pods").WithVersion("version"), "attach", admission.Connect, false, nil), nil)
|
||||
if shouldAccept && err != nil {
|
||||
t.Errorf("Unexpected error returned from admission handler: %v", err)
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ type plugin struct {
|
||||
// a toleration with key "example.com/device", operator "Exists" and effect "NoSchedule".
|
||||
// The rationale for this is described in:
|
||||
// https://github.com/kubernetes/kubernetes/issues/55080
|
||||
func (p *plugin) Admit(attributes admission.Attributes) error {
|
||||
func (p *plugin) Admit(attributes admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
// Ignore all calls to subresources or resources other than pods.
|
||||
if len(attributes.GetSubresource()) != 0 || attributes.GetResource().GroupResource() != core.Resource("pods") {
|
||||
return nil
|
||||
|
@ -354,7 +354,7 @@ func TestAdmit(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for i, test := range tests {
|
||||
err := plugin.Admit(admission.NewAttributesRecord(&test.requestedPod, nil, core.Kind("Pod").WithVersion("version"), "foo", "name", core.Resource("pods").WithVersion("version"), "", "ignored", false, nil))
|
||||
err := plugin.Admit(admission.NewAttributesRecord(&test.requestedPod, nil, core.Kind("Pod").WithVersion("version"), "foo", "name", core.Resource("pods").WithVersion("version"), "", "ignored", false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("[%d: %s] unexpected error %v for pod %+v", i, test.description, err, test.requestedPod)
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ func (a *gcPermissionsEnforcement) isWhiteListed(groupResource schema.GroupResou
|
||||
return false
|
||||
}
|
||||
|
||||
func (a *gcPermissionsEnforcement) Validate(attributes admission.Attributes) (err error) {
|
||||
func (a *gcPermissionsEnforcement) Validate(attributes admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
// // if the request is in the whitelist, we skip mutation checks for this resource.
|
||||
if a.isWhiteListed(attributes.GetResource().GroupResource(), attributes.GetSubresource()) {
|
||||
return nil
|
||||
|
@ -100,7 +100,7 @@ func newGCPermissionsEnforcement() (*gcPermissionsEnforcement, error) {
|
||||
whiteList: whiteList,
|
||||
}
|
||||
|
||||
genericPluginInitializer := initializer.New(nil, nil, fakeAuthorizer{}, nil)
|
||||
genericPluginInitializer := initializer.New(nil, nil, fakeAuthorizer{})
|
||||
fakeDiscoveryClient := &fakediscovery.FakeDiscovery{Fake: &coretesting.Fake{}}
|
||||
fakeDiscoveryClient.Resources = []*metav1.APIResourceList{
|
||||
{
|
||||
@ -308,7 +308,7 @@ func TestGCAdmission(t *testing.T) {
|
||||
user := &user.DefaultInfo{Name: tc.username}
|
||||
attributes := admission.NewAttributesRecord(tc.newObj, tc.oldObj, schema.GroupVersionKind{}, metav1.NamespaceDefault, "foo", tc.resource, tc.subresource, operation, false, user)
|
||||
|
||||
err = gcAdmit.Validate(attributes)
|
||||
err = gcAdmit.Validate(attributes, nil)
|
||||
if !tc.checkError(err) {
|
||||
t.Errorf("unexpected err: %v", err)
|
||||
}
|
||||
@ -611,7 +611,7 @@ func TestBlockOwnerDeletionAdmission(t *testing.T) {
|
||||
user := &user.DefaultInfo{Name: tc.username}
|
||||
attributes := admission.NewAttributesRecord(tc.newObj, tc.oldObj, schema.GroupVersionKind{}, metav1.NamespaceDefault, "foo", tc.resource, tc.subresource, operation, false, user)
|
||||
|
||||
err := gcAdmit.Validate(attributes)
|
||||
err := gcAdmit.Validate(attributes, nil)
|
||||
if !tc.checkError(err) {
|
||||
t.Errorf("%v: unexpected err: %v", tc.name, err)
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ func (a *Plugin) webhookError(pod *api.Pod, attributes admission.Attributes, err
|
||||
}
|
||||
|
||||
// Validate makes an admission decision based on the request attributes
|
||||
func (a *Plugin) Validate(attributes admission.Attributes) (err error) {
|
||||
func (a *Plugin) Validate(attributes admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
// Ignore all calls to subresources or resources other than pods.
|
||||
if attributes.GetSubresource() != "" || attributes.GetResource().GroupResource() != api.Resource("pods") {
|
||||
return nil
|
||||
|
@ -487,7 +487,7 @@ func TestTLSConfig(t *testing.T) {
|
||||
// Allow all and see if we get an error.
|
||||
service.Allow()
|
||||
|
||||
err = wh.Validate(attr)
|
||||
err = wh.Validate(attr, nil)
|
||||
if tt.wantAllowed {
|
||||
if err != nil {
|
||||
t.Errorf("expected successful admission")
|
||||
@ -509,7 +509,7 @@ func TestTLSConfig(t *testing.T) {
|
||||
}
|
||||
|
||||
service.Deny()
|
||||
if err := wh.Validate(attr); err == nil {
|
||||
if err := wh.Validate(attr, nil); err == nil {
|
||||
t.Errorf("%s: incorrectly admitted with DenyAll policy", tt.test)
|
||||
}
|
||||
})
|
||||
@ -526,7 +526,7 @@ type webhookCacheTestCase struct {
|
||||
func testWebhookCacheCases(t *testing.T, serv *mockService, wh *Plugin, attr admission.Attributes, tests []webhookCacheTestCase) {
|
||||
for _, test := range tests {
|
||||
serv.statusCode = test.statusCode
|
||||
err := wh.Validate(attr)
|
||||
err := wh.Validate(attr, nil)
|
||||
authorized := err == nil
|
||||
|
||||
if test.expectedErr && err == nil {
|
||||
@ -759,7 +759,7 @@ func TestContainerCombinations(t *testing.T) {
|
||||
|
||||
attr := admission.NewAttributesRecord(tt.pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, false, &user.DefaultInfo{})
|
||||
|
||||
err = wh.Validate(attr)
|
||||
err = wh.Validate(attr, nil)
|
||||
if tt.wantAllowed {
|
||||
if err != nil {
|
||||
t.Errorf("expected successful admission: %s", tt.test)
|
||||
@ -855,7 +855,7 @@ func TestDefaultAllow(t *testing.T) {
|
||||
annotations := make(map[string]string)
|
||||
attr = &fakeAttributes{attr, annotations}
|
||||
|
||||
err = wh.Validate(attr)
|
||||
err = wh.Validate(attr, nil)
|
||||
if tt.wantAllowed {
|
||||
if err != nil {
|
||||
t.Errorf("expected successful admission")
|
||||
@ -963,7 +963,7 @@ func TestAnnotationFiltering(t *testing.T) {
|
||||
|
||||
attr := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, false, &user.DefaultInfo{})
|
||||
|
||||
err = wh.Validate(attr)
|
||||
err = wh.Validate(attr, nil)
|
||||
if err != nil {
|
||||
t.Errorf("expected successful admission")
|
||||
}
|
||||
@ -1055,7 +1055,7 @@ func TestReturnedAnnotationAdd(t *testing.T) {
|
||||
annotations := make(map[string]string)
|
||||
attr = &fakeAttributes{attr, annotations}
|
||||
|
||||
err = wh.Validate(attr)
|
||||
err = wh.Validate(attr, nil)
|
||||
if !reflect.DeepEqual(annotations, tt.expectedAnnotations) {
|
||||
t.Errorf("got audit annotations: %v; want: %v", annotations, tt.expectedAnnotations)
|
||||
}
|
||||
|
@ -99,12 +99,12 @@ func (l *LimitRanger) ValidateInitialization() error {
|
||||
}
|
||||
|
||||
// Admit admits resources into cluster that do not violate any defined LimitRange in the namespace
|
||||
func (l *LimitRanger) Admit(a admission.Attributes) (err error) {
|
||||
func (l *LimitRanger) Admit(a admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
return l.runLimitFunc(a, l.actions.MutateLimit)
|
||||
}
|
||||
|
||||
// Validate admits resources into cluster that do not violate any defined LimitRange in the namespace
|
||||
func (l *LimitRanger) Validate(a admission.Attributes) (err error) {
|
||||
func (l *LimitRanger) Validate(a admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
return l.runLimitFunc(a, l.actions.ValidateLimit)
|
||||
}
|
||||
|
||||
|
@ -705,20 +705,20 @@ func TestLimitRangerIgnoresSubresource(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
testPod := validPod("testPod", 1, api.ResourceRequirements{})
|
||||
err = handler.Admit(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error since the pod did not specify resource limits in its create call")
|
||||
}
|
||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Expected not to call limitranger actions on pod updates")
|
||||
}
|
||||
|
||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "status", admission.Update, false, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "status", admission.Update, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Should have ignored calls to any subresource of pod %v", err)
|
||||
}
|
||||
@ -735,20 +735,20 @@ func TestLimitRangerAdmitPod(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
testPod := validPod("testPod", 1, api.ResourceRequirements{})
|
||||
err = handler.Admit(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error since the pod did not specify resource limits in its create call")
|
||||
}
|
||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Expected not to call limitranger actions on pod updates")
|
||||
}
|
||||
|
||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "status", admission.Update, false, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(&testPod, nil, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "testPod", api.Resource("pods").WithVersion("version"), "status", admission.Update, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Should have ignored calls to any subresource of pod %v", err)
|
||||
}
|
||||
@ -757,7 +757,7 @@ func TestLimitRangerAdmitPod(t *testing.T) {
|
||||
terminatingPod := validPod("terminatingPod", 1, api.ResourceRequirements{})
|
||||
now := metav1.Now()
|
||||
terminatingPod.DeletionTimestamp = &now
|
||||
err = handler.Validate(admission.NewAttributesRecord(&terminatingPod, &terminatingPod, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "terminatingPod", api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(&terminatingPod, &terminatingPod, api.Kind("Pod").WithVersion("version"), limitRange.Namespace, "terminatingPod", api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("LimitRange should ignore a pod marked for termination")
|
||||
}
|
||||
@ -788,7 +788,7 @@ func newHandlerForTest(c clientset.Interface) (*LimitRanger, informers.SharedInf
|
||||
if err != nil {
|
||||
return nil, f, err
|
||||
}
|
||||
pluginInitializer := genericadmissioninitializer.New(c, f, nil, nil)
|
||||
pluginInitializer := genericadmissioninitializer.New(c, f, nil)
|
||||
pluginInitializer.Initialize(handler)
|
||||
err = admission.ValidateInitialization(handler)
|
||||
return handler, f, err
|
||||
|
@ -55,7 +55,7 @@ var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&Provision{
|
||||
var _ = genericadmissioninitializer.WantsExternalKubeClientSet(&Provision{})
|
||||
|
||||
// Admit makes an admission decision based on the request attributes
|
||||
func (p *Provision) Admit(a admission.Attributes) error {
|
||||
func (p *Provision) Admit(a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
// Don't create a namespace if the request is for a dry-run.
|
||||
if a.IsDryRun() {
|
||||
return nil
|
||||
|
@ -39,7 +39,7 @@ import (
|
||||
func newHandlerForTest(c clientset.Interface) (admission.MutationInterface, informers.SharedInformerFactory, error) {
|
||||
f := informers.NewSharedInformerFactory(c, 5*time.Minute)
|
||||
handler := NewProvision()
|
||||
pluginInitializer := genericadmissioninitializer.New(c, f, nil, nil)
|
||||
pluginInitializer := genericadmissioninitializer.New(c, f, nil)
|
||||
pluginInitializer.Initialize(handler)
|
||||
err := admission.ValidateInitialization(handler)
|
||||
return handler, f, err
|
||||
@ -99,7 +99,7 @@ func TestAdmission(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
pod := newPod(namespace)
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error returned from admission handler")
|
||||
}
|
||||
@ -119,7 +119,7 @@ func TestAdmissionNamespaceExists(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
pod := newPod(namespace)
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error returned from admission handler")
|
||||
}
|
||||
@ -139,7 +139,7 @@ func TestAdmissionDryRun(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
pod := newPod(namespace)
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, true, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, true, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error returned from admission handler")
|
||||
}
|
||||
@ -160,7 +160,7 @@ func TestIgnoreAdmission(t *testing.T) {
|
||||
chainHandler := admission.NewChainHandler(handler)
|
||||
|
||||
pod := newPod(namespace)
|
||||
err = chainHandler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil))
|
||||
err = chainHandler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error returned from admission handler")
|
||||
}
|
||||
@ -182,7 +182,7 @@ func TestAdmissionWithLatentCache(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
pod := newPod(namespace)
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error returned from admission handler")
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&Exists{})
|
||||
var _ = genericadmissioninitializer.WantsExternalKubeClientSet(&Exists{})
|
||||
|
||||
// Validate makes an admission decision based on the request attributes
|
||||
func (e *Exists) Validate(a admission.Attributes) error {
|
||||
func (e *Exists) Validate(a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
// if we're here, then we've already passed authentication, so we're allowed to do what we're trying to do
|
||||
// if we're here, then the API server has found a route, which means that if we have a non-empty namespace
|
||||
// its a namespaced resource.
|
||||
|
@ -38,7 +38,7 @@ import (
|
||||
func newHandlerForTest(c kubernetes.Interface) (admission.ValidationInterface, informers.SharedInformerFactory, error) {
|
||||
f := informers.NewSharedInformerFactory(c, 5*time.Minute)
|
||||
handler := NewExists()
|
||||
pluginInitializer := genericadmissioninitializer.New(c, f, nil, nil)
|
||||
pluginInitializer := genericadmissioninitializer.New(c, f, nil)
|
||||
pluginInitializer.Initialize(handler)
|
||||
err := admission.ValidateInitialization(handler)
|
||||
return handler, f, err
|
||||
@ -88,7 +88,7 @@ func TestAdmissionNamespaceExists(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
pod := newPod(namespace)
|
||||
err = handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error returned from admission handler")
|
||||
}
|
||||
@ -108,7 +108,7 @@ func TestAdmissionNamespaceDoesNotExist(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
pod := newPod(namespace)
|
||||
err = handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err == nil {
|
||||
actions := ""
|
||||
for _, action := range mockClient.Actions() {
|
||||
|
@ -102,7 +102,7 @@ var (
|
||||
csiNodeInfoResource = csiv1alpha1.Resource("csinodeinfos")
|
||||
)
|
||||
|
||||
func (c *nodePlugin) Admit(a admission.Attributes) error {
|
||||
func (c *nodePlugin) Admit(a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
nodeName, isNode := c.nodeIdentifier.NodeIdentity(a.GetUserInfo())
|
||||
|
||||
// Our job is just to restrict nodes
|
||||
|
@ -1234,7 +1234,7 @@ func Test_nodePlugin_Admit(t *testing.T) {
|
||||
c.features = tt.features
|
||||
}
|
||||
c.podsGetter = tt.podsGetter
|
||||
err := c.Admit(tt.attributes)
|
||||
err := c.Admit(tt.attributes, nil)
|
||||
if (err == nil) != (len(tt.err) == 0) {
|
||||
t.Errorf("nodePlugin.Admit() error = %v, expected %v", err, tt.err)
|
||||
return
|
||||
|
@ -64,7 +64,7 @@ var (
|
||||
)
|
||||
|
||||
// Admit is the main function that checks node identity and adds taints as needed.
|
||||
func (p *Plugin) Admit(a admission.Attributes) error {
|
||||
func (p *Plugin) Admit(a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
// If TaintNodesByCondition is not enabled, we don't need to do anything.
|
||||
if !p.features.Enabled(features.TaintNodesByCondition) {
|
||||
return nil
|
||||
|
@ -100,7 +100,7 @@ func Test_nodeTaints(t *testing.T) {
|
||||
if tt.features != nil {
|
||||
c.features = tt.features
|
||||
}
|
||||
err := c.Admit(attributes)
|
||||
err := c.Admit(attributes, nil)
|
||||
if err != nil {
|
||||
t.Errorf("nodePlugin.Admit() error = %v", err)
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ func readConfig(config io.Reader) *pluginConfig {
|
||||
}
|
||||
|
||||
// Admit enforces that pod and its namespace node label selectors matches at least a node in the cluster.
|
||||
func (p *podNodeSelector) Admit(a admission.Attributes) error {
|
||||
func (p *podNodeSelector) Admit(a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
if shouldIgnore(a) {
|
||||
return nil
|
||||
}
|
||||
@ -117,11 +117,11 @@ func (p *podNodeSelector) Admit(a admission.Attributes) error {
|
||||
// second selector wins
|
||||
podNodeSelectorLabels := labels.Merge(namespaceNodeSelector, pod.Spec.NodeSelector)
|
||||
pod.Spec.NodeSelector = map[string]string(podNodeSelectorLabels)
|
||||
return p.Validate(a)
|
||||
return p.Validate(a, o)
|
||||
}
|
||||
|
||||
// Validate ensures that the pod node selector is allowed
|
||||
func (p *podNodeSelector) Validate(a admission.Attributes) error {
|
||||
func (p *podNodeSelector) Validate(a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
if shouldIgnore(a) {
|
||||
return nil
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ func TestPodAdmission(t *testing.T) {
|
||||
handler.clusterNodeSelectors[namespace.Name] = test.whitelist
|
||||
pod.Spec = api.PodSpec{NodeSelector: test.podNodeSelector}
|
||||
|
||||
err := handler.Admit(admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err := handler.Admit(admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if test.admit && err != nil {
|
||||
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
|
||||
} else if !test.admit && err == nil {
|
||||
@ -170,7 +170,7 @@ func TestPodAdmission(t *testing.T) {
|
||||
if test.admit && !labels.Equals(test.mergedNodeSelector, labels.Set(pod.Spec.NodeSelector)) {
|
||||
t.Errorf("Test: %s, expected: %s but got: %s", test.testName, test.mergedNodeSelector, pod.Spec.NodeSelector)
|
||||
}
|
||||
err = handler.Validate(admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if test.admit && err != nil {
|
||||
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
|
||||
} else if !test.admit && err == nil {
|
||||
@ -197,7 +197,7 @@ func TestHandles(t *testing.T) {
|
||||
func newHandlerForTest(c kubernetes.Interface) (*podNodeSelector, informers.SharedInformerFactory, error) {
|
||||
f := informers.NewSharedInformerFactory(c, 5*time.Minute)
|
||||
handler := NewPodNodeSelector(nil)
|
||||
pluginInitializer := genericadmissioninitializer.New(c, f, nil, nil)
|
||||
pluginInitializer := genericadmissioninitializer.New(c, f, nil)
|
||||
pluginInitializer.Initialize(handler)
|
||||
err := admission.ValidateInitialization(handler)
|
||||
return handler, f, err
|
||||
|
@ -90,7 +90,7 @@ func (a *podPresetPlugin) SetExternalKubeInformerFactory(f informers.SharedInfor
|
||||
}
|
||||
|
||||
// Admit injects a pod with the specific fields for each pod preset it matches.
|
||||
func (c *podPresetPlugin) Admit(a admission.Attributes) error {
|
||||
func (c *podPresetPlugin) Admit(a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
// Ignore all calls to subresources or resources other than pods.
|
||||
// Ignore all operations other than CREATE.
|
||||
if len(a.GetSubresource()) != 0 || a.GetResource().GroupResource() != api.Resource("pods") || a.GetOperation() != admission.Create {
|
||||
|
@ -823,7 +823,7 @@ func admitPod(pod *api.Pod, pip *settingsv1alpha1.PodPreset) error {
|
||||
&user.DefaultInfo{},
|
||||
)
|
||||
|
||||
err := plugin.Admit(attrs)
|
||||
err := plugin.Admit(attrs, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ type podTolerationsPlugin struct {
|
||||
// instead if specified. Tolerations to a namespace are assigned via
|
||||
// scheduler.alpha.kubernetes.io/defaultTolerations and scheduler.alpha.kubernetes.io/tolerationsWhitelist
|
||||
// annotations keys.
|
||||
func (p *podTolerationsPlugin) Admit(a admission.Attributes) error {
|
||||
func (p *podTolerationsPlugin) Admit(a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
if shouldIgnore(a) {
|
||||
return nil
|
||||
}
|
||||
@ -134,9 +134,9 @@ func (p *podTolerationsPlugin) Admit(a admission.Attributes) error {
|
||||
}
|
||||
pod.Spec.Tolerations = finalTolerations
|
||||
|
||||
return p.Validate(a)
|
||||
return p.Validate(a, o)
|
||||
}
|
||||
func (p *podTolerationsPlugin) Validate(a admission.Attributes) error {
|
||||
func (p *podTolerationsPlugin) Validate(a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
if shouldIgnore(a) {
|
||||
return nil
|
||||
}
|
||||
|
@ -254,7 +254,7 @@ func TestPodAdmission(t *testing.T) {
|
||||
pod := test.pod
|
||||
pod.Spec.Tolerations = test.podTolerations
|
||||
|
||||
err = handler.Admit(admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "testNamespace", namespace.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if test.admit && err != nil {
|
||||
t.Errorf("Test: %s, expected no error but got: %s", test.testName, err)
|
||||
} else if !test.admit && err == nil {
|
||||
@ -331,7 +331,7 @@ func TestIgnoreUpdatingInitializedPod(t *testing.T) {
|
||||
}
|
||||
|
||||
// if the update of initialized pod is not ignored, an error will be returned because the pod's Tolerations conflicts with namespace's Tolerations.
|
||||
err = handler.Admit(admission.NewAttributesRecord(pod, pod, api.Kind("Pod").WithVersion("version"), "testNamespace", pod.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(pod, pod, api.Kind("Pod").WithVersion("version"), "testNamespace", pod.ObjectMeta.Name, api.Resource("pods").WithVersion("version"), "", admission.Update, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("expected no error, got: %v", err)
|
||||
}
|
||||
@ -346,7 +346,7 @@ func newHandlerForTest(c kubernetes.Interface) (*podTolerationsPlugin, informers
|
||||
return nil, nil, err
|
||||
}
|
||||
handler := NewPodTolerationsPlugin(pluginConfig)
|
||||
pluginInitializer := genericadmissioninitializer.New(c, f, nil, nil)
|
||||
pluginInitializer := genericadmissioninitializer.New(c, f, nil)
|
||||
pluginInitializer.Initialize(handler)
|
||||
err = admission.ValidateInitialization(handler)
|
||||
return handler, f, err
|
||||
|
@ -97,7 +97,7 @@ var (
|
||||
|
||||
// Admit checks Pods and admits or rejects them. It also resolves the priority of pods based on their PriorityClass.
|
||||
// Note that pod validation mechanism prevents update of a pod priority.
|
||||
func (p *priorityPlugin) Admit(a admission.Attributes) error {
|
||||
func (p *priorityPlugin) Admit(a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.PodPriority) {
|
||||
return nil
|
||||
}
|
||||
@ -121,7 +121,7 @@ func (p *priorityPlugin) Admit(a admission.Attributes) error {
|
||||
}
|
||||
|
||||
// Validate checks PriorityClasses and admits or rejects them.
|
||||
func (p *priorityPlugin) Validate(a admission.Attributes) error {
|
||||
func (p *priorityPlugin) Validate(a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
operation := a.GetOperation()
|
||||
// Ignore all calls to subresources
|
||||
if len(a.GetSubresource()) != 0 {
|
||||
|
@ -158,7 +158,7 @@ func TestPriorityClassAdmission(t *testing.T) {
|
||||
false,
|
||||
test.userInfo,
|
||||
)
|
||||
err := ctrl.Validate(attrs)
|
||||
err := ctrl.Validate(attrs, nil)
|
||||
klog.Infof("Got %v", err)
|
||||
if err != nil && !test.expectError {
|
||||
t.Errorf("Test %q: unexpected error received: %v", test.name, err)
|
||||
@ -254,7 +254,7 @@ func TestDefaultPriority(t *testing.T) {
|
||||
test.name, test.expectedDefaultNameBefore, test.expectedDefaultBefore, pcName, defaultPriority)
|
||||
}
|
||||
if test.attributes != nil {
|
||||
err := ctrl.Validate(test.attributes)
|
||||
err := ctrl.Validate(test.attributes, nil)
|
||||
if err != nil {
|
||||
t.Errorf("Test %q: unexpected error received: %v", test.name, err)
|
||||
}
|
||||
@ -603,7 +603,7 @@ func TestPodAdmission(t *testing.T) {
|
||||
false,
|
||||
nil,
|
||||
)
|
||||
err := ctrl.Admit(attrs)
|
||||
err := ctrl.Admit(attrs, nil)
|
||||
klog.Infof("Got %v", err)
|
||||
if !test.expectError {
|
||||
if err != nil {
|
||||
|
@ -127,7 +127,7 @@ func (a *QuotaAdmission) ValidateInitialization() error {
|
||||
}
|
||||
|
||||
// Validate makes admission decisions while enforcing quota
|
||||
func (a *QuotaAdmission) Validate(attr admission.Attributes) (err error) {
|
||||
func (a *QuotaAdmission) Validate(attr admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
// ignore all operations that correspond to sub-resource actions
|
||||
if attr.GetSubresource() != "" {
|
||||
return nil
|
||||
|
@ -153,7 +153,7 @@ func TestAdmissionIgnoresDelete(t *testing.T) {
|
||||
evaluator: evaluator,
|
||||
}
|
||||
namespace := "default"
|
||||
err := handler.Validate(admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), namespace, "name", corev1.Resource("pods").WithVersion("version"), "", admission.Delete, false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), namespace, "name", corev1.Resource("pods").WithVersion("version"), "", admission.Delete, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("ResourceQuota should admit all deletes: %v", err)
|
||||
}
|
||||
@ -190,11 +190,11 @@ func TestAdmissionIgnoresSubresources(t *testing.T) {
|
||||
}
|
||||
informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
||||
newPod := validPod("123", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error because the pod exceeded allowed quota")
|
||||
}
|
||||
err = handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "subresource", admission.Create, false, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "subresource", admission.Create, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Did not expect an error because the action went to a subresource: %v", err)
|
||||
}
|
||||
@ -235,7 +235,7 @@ func TestAdmitBelowQuotaLimit(t *testing.T) {
|
||||
}
|
||||
informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@ -318,13 +318,13 @@ func TestAdmitDryRun(t *testing.T) {
|
||||
informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
||||
|
||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, true, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, true, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
newPod = validPod("too-large-pod", 1, getResourceRequirements(getResourceList("100m", "60Gi"), getResourceList("", "")))
|
||||
err = handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, true, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, true, nil), nil)
|
||||
if err == nil {
|
||||
t.Errorf("Expected error but got none")
|
||||
}
|
||||
@ -384,7 +384,7 @@ func TestAdmitHandlesOldObjects(t *testing.T) {
|
||||
Ports: []api.ServicePort{{Port: 1234}},
|
||||
},
|
||||
}
|
||||
err := handler.Validate(admission.NewAttributesRecord(newService, existingService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, corev1.Resource("services").WithVersion("version"), "", admission.Update, false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newService, existingService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, corev1.Resource("services").WithVersion("version"), "", admission.Update, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@ -485,7 +485,7 @@ func TestAdmitHandlesNegativePVCUpdates(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPVC, oldPVC, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPVC.Namespace, newPVC.Name, corev1.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Update, false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPVC, oldPVC, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPVC.Namespace, newPVC.Name, corev1.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Update, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@ -544,7 +544,7 @@ func TestAdmitHandlesPVCUpdates(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPVC, oldPVC, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPVC.Namespace, newPVC.Name, corev1.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Update, false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPVC, oldPVC, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPVC.Namespace, newPVC.Name, corev1.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Update, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@ -641,7 +641,7 @@ func TestAdmitHandlesCreatingUpdates(t *testing.T) {
|
||||
Ports: []api.ServicePort{{Port: 1234}},
|
||||
},
|
||||
}
|
||||
err := handler.Validate(admission.NewAttributesRecord(newService, oldService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, corev1.Resource("services").WithVersion("version"), "", admission.Update, false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newService, oldService, api.Kind("Service").WithVersion("version"), newService.Namespace, newService.Name, corev1.Resource("services").WithVersion("version"), "", admission.Update, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@ -724,7 +724,7 @@ func TestAdmitExceedQuotaLimit(t *testing.T) {
|
||||
}
|
||||
informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
||||
newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error exceeding quota")
|
||||
}
|
||||
@ -770,7 +770,7 @@ func TestAdmitEnforceQuotaConstraints(t *testing.T) {
|
||||
informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
||||
// verify all values are specified as required on the quota
|
||||
newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("200m", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error because the pod does not specify a memory limit")
|
||||
}
|
||||
@ -821,7 +821,7 @@ func TestAdmitPodInNamespaceWithoutQuota(t *testing.T) {
|
||||
newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("200m", "")))
|
||||
// Add to the lru cache so we do not do a live client lookup
|
||||
liveLookupCache.Add(newPod.Namespace, liveLookupEntry{expiry: time.Now().Add(time.Duration(30 * time.Second)), items: []*corev1.ResourceQuota{}})
|
||||
err = handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Did not expect an error because the pod is in a different namespace than the quota")
|
||||
}
|
||||
@ -890,7 +890,7 @@ func TestAdmitBelowTerminatingQuotaLimit(t *testing.T) {
|
||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("100m", "2Gi"), getResourceList("", "")))
|
||||
activeDeadlineSeconds := int64(30)
|
||||
newPod.Spec.ActiveDeadlineSeconds = &activeDeadlineSeconds
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@ -994,7 +994,7 @@ func TestAdmitBelowBestEffortQuotaLimit(t *testing.T) {
|
||||
|
||||
// create a pod that is best effort because it does not make a request for anything
|
||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("", ""), getResourceList("", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@ -1084,7 +1084,7 @@ func TestAdmitBestEffortQuotaLimitIgnoresBurstable(t *testing.T) {
|
||||
}
|
||||
informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("100m", "1Gi"), getResourceList("", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@ -1174,7 +1174,7 @@ func TestAdmissionSetsMissingNamespace(t *testing.T) {
|
||||
// unset the namespace
|
||||
newPod.ObjectMeta.Namespace = ""
|
||||
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Got unexpected error: %v", err)
|
||||
}
|
||||
@ -1217,14 +1217,14 @@ func TestAdmitRejectsNegativeUsage(t *testing.T) {
|
||||
informerFactory.Core().V1().ResourceQuotas().Informer().GetIndexer().Add(resourceQuota)
|
||||
// verify quota rejects negative pvc storage requests
|
||||
newPvc := validPersistentVolumeClaim("not-allowed-pvc", getResourceRequirements(api.ResourceList{api.ResourceStorage: resource.MustParse("-1Gi")}, api.ResourceList{}))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPvc, nil, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPvc.Namespace, newPvc.Name, corev1.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPvc, nil, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPvc.Namespace, newPvc.Name, corev1.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error because the pvc has negative storage usage")
|
||||
}
|
||||
|
||||
// verify quota accepts non-negative pvc storage requests
|
||||
newPvc = validPersistentVolumeClaim("not-allowed-pvc", getResourceRequirements(api.ResourceList{api.ResourceStorage: resource.MustParse("1Gi")}, api.ResourceList{}))
|
||||
err = handler.Validate(admission.NewAttributesRecord(newPvc, nil, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPvc.Namespace, newPvc.Name, corev1.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(newPvc, nil, api.Kind("PersistentVolumeClaim").WithVersion("version"), newPvc.Namespace, newPvc.Name, corev1.Resource("persistentvolumeclaims").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@ -1265,7 +1265,7 @@ func TestAdmitWhenUnrelatedResourceExceedsQuota(t *testing.T) {
|
||||
|
||||
// create a pod that should pass existing quota
|
||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("", ""), getResourceList("", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@ -1299,7 +1299,7 @@ func TestAdmitLimitedResourceNoQuota(t *testing.T) {
|
||||
evaluator: evaluator,
|
||||
}
|
||||
newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error for consuming a limited resource without quota.")
|
||||
}
|
||||
@ -1333,7 +1333,7 @@ func TestAdmitLimitedResourceNoQuotaIgnoresNonMatchingResources(t *testing.T) {
|
||||
evaluator: evaluator,
|
||||
}
|
||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
@ -1381,7 +1381,7 @@ func TestAdmitLimitedResourceWithQuota(t *testing.T) {
|
||||
}
|
||||
indexer.Add(resourceQuota)
|
||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
@ -1441,7 +1441,7 @@ func TestAdmitLimitedResourceWithMultipleQuota(t *testing.T) {
|
||||
indexer.Add(resourceQuota1)
|
||||
indexer.Add(resourceQuota2)
|
||||
newPod := validPod("allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
@ -1489,7 +1489,7 @@ func TestAdmitLimitedResourceWithQuotaThatDoesNotCover(t *testing.T) {
|
||||
}
|
||||
indexer.Add(resourceQuota)
|
||||
newPod := validPod("not-allowed-pod", 1, getResourceRequirements(getResourceList("3", "2Gi"), getResourceList("", "")))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err == nil {
|
||||
t.Fatalf("Expected an error since the quota did not cover cpu")
|
||||
}
|
||||
@ -2150,7 +2150,7 @@ func TestAdmitLimitedScopeWithCoverQuota(t *testing.T) {
|
||||
if testCase.anotherQuota != nil {
|
||||
indexer.Add(testCase.anotherQuota)
|
||||
}
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(newPod, nil, api.Kind("Pod").WithVersion("version"), newPod.Namespace, newPod.Name, corev1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if testCase.expErr == "" {
|
||||
if err != nil {
|
||||
t.Fatalf("Testcase, %v, failed with unexpected error: %v. ExpErr: %v", testCase.description, err, testCase.expErr)
|
||||
|
@ -109,7 +109,7 @@ func (a *PodSecurityPolicyPlugin) SetExternalKubeInformerFactory(f informers.Sha
|
||||
// 3. Try to generate and validate a PSP with providers. If we find one then admit the pod
|
||||
// with the validated PSP. If we don't find any reject the pod and give all errors from the
|
||||
// failed attempts.
|
||||
func (c *PodSecurityPolicyPlugin) Admit(a admission.Attributes) error {
|
||||
func (c *PodSecurityPolicyPlugin) Admit(a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
if ignore, err := shouldIgnore(a); err != nil {
|
||||
return err
|
||||
} else if ignore {
|
||||
@ -149,7 +149,7 @@ func (c *PodSecurityPolicyPlugin) Admit(a admission.Attributes) error {
|
||||
return admission.NewForbidden(a, fmt.Errorf("unable to validate against any pod security policy: %v", validationErrs))
|
||||
}
|
||||
|
||||
func (c *PodSecurityPolicyPlugin) Validate(a admission.Attributes) error {
|
||||
func (c *PodSecurityPolicyPlugin) Validate(a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
if ignore, err := shouldIgnore(a); err != nil {
|
||||
return err
|
||||
} else if ignore {
|
||||
|
@ -475,7 +475,7 @@ func TestFailClosedOnInvalidPod(t *testing.T) {
|
||||
pod := &v1.Pod{}
|
||||
attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), pod.Namespace, pod.Name, kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, false, &user.DefaultInfo{})
|
||||
|
||||
err := plugin.Admit(attrs)
|
||||
err := plugin.Admit(attrs, nil)
|
||||
if err == nil {
|
||||
t.Fatalf("expected versioned pod object to fail mutating admission")
|
||||
}
|
||||
@ -483,7 +483,7 @@ func TestFailClosedOnInvalidPod(t *testing.T) {
|
||||
t.Errorf("expected type error on Admit but got: %v", err)
|
||||
}
|
||||
|
||||
err = plugin.Validate(attrs)
|
||||
err = plugin.Validate(attrs, nil)
|
||||
if err == nil {
|
||||
t.Fatalf("expected versioned pod object to fail validating admission")
|
||||
}
|
||||
@ -1779,7 +1779,7 @@ func testPSPAdmitAdvanced(testCaseName string, op kadmission.Operation, psps []*
|
||||
attrs := kadmission.NewAttributesRecord(pod, oldPod, kapi.Kind("Pod").WithVersion("version"), pod.Namespace, "", kapi.Resource("pods").WithVersion("version"), "", op, false, userInfo)
|
||||
annotations := make(map[string]string)
|
||||
attrs = &fakeAttributes{attrs, annotations}
|
||||
err := plugin.Admit(attrs)
|
||||
err := plugin.Admit(attrs, nil)
|
||||
|
||||
if shouldPassAdmit && err != nil {
|
||||
t.Errorf("%s: expected no errors on Admit but received %v", testCaseName, err)
|
||||
@ -1807,7 +1807,7 @@ func testPSPAdmitAdvanced(testCaseName string, op kadmission.Operation, psps []*
|
||||
t.Errorf("%s: expected errors on Admit but received none", testCaseName)
|
||||
}
|
||||
|
||||
err = plugin.Validate(attrs)
|
||||
err = plugin.Validate(attrs, nil)
|
||||
psp := ""
|
||||
if shouldPassAdmit && op == kadmission.Create {
|
||||
psp = expectedPSP
|
||||
|
@ -50,7 +50,7 @@ func NewSecurityContextDeny() *Plugin {
|
||||
}
|
||||
|
||||
// Validate will deny any pod that defines SupplementalGroups, SELinuxOptions, RunAsUser or FSGroup
|
||||
func (p *Plugin) Validate(a admission.Attributes) (err error) {
|
||||
func (p *Plugin) Validate(a admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
if a.GetSubresource() != "" || a.GetResource().GroupResource() != api.Resource("pods") {
|
||||
return nil
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ func TestAdmission(t *testing.T) {
|
||||
p.Spec.SecurityContext = tc.podSc
|
||||
p.Spec.Containers[0].SecurityContext = tc.sc
|
||||
|
||||
err := handler.Validate(admission.NewAttributesRecord(p, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(p, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", false, nil), nil)
|
||||
if err != nil && !tc.expectError {
|
||||
t.Errorf("%v: unexpected error: %v", tc.name, err)
|
||||
} else if err == nil && tc.expectError {
|
||||
@ -96,7 +96,7 @@ func TestAdmission(t *testing.T) {
|
||||
p.Spec.InitContainers = p.Spec.Containers
|
||||
p.Spec.Containers = nil
|
||||
|
||||
err = handler.Validate(admission.NewAttributesRecord(p, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", false, nil))
|
||||
err = handler.Validate(admission.NewAttributesRecord(p, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", false, nil), nil)
|
||||
if err != nil && !tc.expectError {
|
||||
t.Errorf("%v: unexpected error: %v", tc.name, err)
|
||||
} else if err == nil && tc.expectError {
|
||||
@ -140,7 +140,7 @@ func TestPodSecurityContextAdmission(t *testing.T) {
|
||||
}
|
||||
for _, test := range tests {
|
||||
pod.Spec.SecurityContext = &test.securityContext
|
||||
err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", false, nil))
|
||||
err := handler.Validate(admission.NewAttributesRecord(&pod, nil, api.Kind("Pod").WithVersion("version"), "foo", "name", api.Resource("pods").WithVersion("version"), "", "ignored", false, nil), nil)
|
||||
|
||||
if test.errorExpected && err == nil {
|
||||
t.Errorf("Expected error for security context %+v but did not get an error", test.securityContext)
|
||||
|
@ -148,7 +148,7 @@ func (a *serviceAccount) ValidateInitialization() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *serviceAccount) Admit(a admission.Attributes) (err error) {
|
||||
func (s *serviceAccount) Admit(a admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
if shouldIgnore(a) {
|
||||
return nil
|
||||
}
|
||||
@ -159,7 +159,7 @@ func (s *serviceAccount) Admit(a admission.Attributes) (err error) {
|
||||
// That makes the kubelet very angry and confused, and it immediately deletes the pod (because the spec doesn't match)
|
||||
// That said, don't allow mirror pods to reference ServiceAccounts or SecretVolumeSources either
|
||||
if _, isMirrorPod := pod.Annotations[api.MirrorPodAnnotationKey]; isMirrorPod {
|
||||
return s.Validate(a)
|
||||
return s.Validate(a, o)
|
||||
}
|
||||
|
||||
// Set the default service account if needed
|
||||
@ -186,10 +186,10 @@ func (s *serviceAccount) Admit(a admission.Attributes) (err error) {
|
||||
}
|
||||
}
|
||||
|
||||
return s.Validate(a)
|
||||
return s.Validate(a, o)
|
||||
}
|
||||
|
||||
func (s *serviceAccount) Validate(a admission.Attributes) (err error) {
|
||||
func (s *serviceAccount) Validate(a admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
if shouldIgnore(a) {
|
||||
return nil
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ func TestIgnoresNonCreate(t *testing.T) {
|
||||
func TestIgnoresNonPodResource(t *testing.T) {
|
||||
pod := &api.Pod{}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("CustomResource").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := NewServiceAccount().Admit(attrs)
|
||||
err := NewServiceAccount().Admit(attrs, nil)
|
||||
if err != nil {
|
||||
t.Errorf("Expected non-pod resource allowed, got err: %v", err)
|
||||
}
|
||||
@ -73,7 +73,7 @@ func TestIgnoresNonPodResource(t *testing.T) {
|
||||
|
||||
func TestIgnoresNilObject(t *testing.T) {
|
||||
attrs := admission.NewAttributesRecord(nil, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := NewServiceAccount().Admit(attrs)
|
||||
err := NewServiceAccount().Admit(attrs, nil)
|
||||
if err != nil {
|
||||
t.Errorf("Expected nil object allowed allowed, got err: %v", err)
|
||||
}
|
||||
@ -82,7 +82,7 @@ func TestIgnoresNilObject(t *testing.T) {
|
||||
func TestIgnoresNonPodObject(t *testing.T) {
|
||||
obj := &api.Namespace{}
|
||||
attrs := admission.NewAttributesRecord(obj, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := NewServiceAccount().Admit(attrs)
|
||||
err := NewServiceAccount().Admit(attrs, nil)
|
||||
if err != nil {
|
||||
t.Errorf("Expected non pod object allowed, got err: %v", err)
|
||||
}
|
||||
@ -102,7 +102,7 @@ func TestIgnoresMirrorPod(t *testing.T) {
|
||||
},
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := NewServiceAccount().Admit(attrs)
|
||||
err := NewServiceAccount().Admit(attrs, nil)
|
||||
if err != nil {
|
||||
t.Errorf("Expected mirror pod without service account or secrets allowed, got err: %v", err)
|
||||
}
|
||||
@ -120,7 +120,7 @@ func TestRejectsMirrorPodWithServiceAccount(t *testing.T) {
|
||||
},
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := NewServiceAccount().Admit(attrs)
|
||||
err := NewServiceAccount().Admit(attrs, nil)
|
||||
if err == nil {
|
||||
t.Errorf("Expected a mirror pod to be prevented from referencing a service account")
|
||||
}
|
||||
@ -140,7 +140,7 @@ func TestRejectsMirrorPodWithSecretVolumes(t *testing.T) {
|
||||
},
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := NewServiceAccount().Admit(attrs)
|
||||
err := NewServiceAccount().Admit(attrs, nil)
|
||||
if err == nil {
|
||||
t.Errorf("Expected a mirror pod to be prevented from referencing a secret volume")
|
||||
}
|
||||
@ -165,7 +165,7 @@ func TestRejectsMirrorPodWithServiceAccountTokenVolumeProjections(t *testing.T)
|
||||
},
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), "myns", "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := NewServiceAccount().Admit(attrs)
|
||||
err := NewServiceAccount().Admit(attrs, nil)
|
||||
if err == nil {
|
||||
t.Errorf("Expected a mirror pod to be prevented from referencing a ServiceAccountToken volume projection")
|
||||
}
|
||||
@ -190,7 +190,7 @@ func TestAssignsDefaultServiceAccountAndToleratesMissingAPIToken(t *testing.T) {
|
||||
|
||||
pod := &api.Pod{}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := admit.Admit(attrs)
|
||||
err := admit.Admit(attrs, nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@ -218,7 +218,7 @@ func TestAssignsDefaultServiceAccountAndRejectsMissingAPIToken(t *testing.T) {
|
||||
|
||||
pod := &api.Pod{}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := admit.Admit(attrs)
|
||||
err := admit.Admit(attrs, nil)
|
||||
if err == nil || !errors.IsServerTimeout(err) {
|
||||
t.Errorf("Expected server timeout error for missing API token: %v", err)
|
||||
}
|
||||
@ -243,7 +243,7 @@ func TestFetchesUncachedServiceAccount(t *testing.T) {
|
||||
|
||||
pod := &api.Pod{}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := admit.Admit(attrs)
|
||||
err := admit.Admit(attrs, nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@ -265,7 +265,7 @@ func TestDeniesInvalidServiceAccount(t *testing.T) {
|
||||
|
||||
pod := &api.Pod{}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := admit.Admit(attrs)
|
||||
err := admit.Admit(attrs, nil)
|
||||
if err == nil {
|
||||
t.Errorf("Expected error for missing service account, got none")
|
||||
}
|
||||
@ -331,7 +331,7 @@ func TestAutomountsAPIToken(t *testing.T) {
|
||||
},
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := admit.Admit(attrs)
|
||||
err := admit.Admit(attrs, nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@ -360,7 +360,7 @@ func TestAutomountsAPIToken(t *testing.T) {
|
||||
},
|
||||
}
|
||||
attrs = admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
if err := admit.Admit(attrs); err != nil {
|
||||
if err := admit.Admit(attrs, nil); err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
if pod.Spec.ServiceAccountName != DefaultServiceAccountName {
|
||||
@ -442,7 +442,7 @@ func TestRespectsExistingMount(t *testing.T) {
|
||||
},
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := admit.Admit(attrs)
|
||||
err := admit.Admit(attrs, nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@ -472,7 +472,7 @@ func TestRespectsExistingMount(t *testing.T) {
|
||||
},
|
||||
}
|
||||
attrs = admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
if err := admit.Admit(attrs); err != nil {
|
||||
if err := admit.Admit(attrs, nil); err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
if pod.Spec.ServiceAccountName != DefaultServiceAccountName {
|
||||
@ -518,7 +518,7 @@ func TestAllowsReferencedSecret(t *testing.T) {
|
||||
},
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(pod1, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
if err := admit.Admit(attrs); err != nil {
|
||||
if err := admit.Admit(attrs, nil); err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
@ -542,7 +542,7 @@ func TestAllowsReferencedSecret(t *testing.T) {
|
||||
},
|
||||
}
|
||||
attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
if err := admit.Admit(attrs); err != nil {
|
||||
if err := admit.Admit(attrs, nil); err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
@ -566,7 +566,7 @@ func TestAllowsReferencedSecret(t *testing.T) {
|
||||
},
|
||||
}
|
||||
attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
if err := admit.Admit(attrs); err != nil {
|
||||
if err := admit.Admit(attrs, nil); err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
@ -596,7 +596,7 @@ func TestRejectsUnreferencedSecretVolumes(t *testing.T) {
|
||||
},
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(pod1, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
if err := admit.Admit(attrs); err == nil {
|
||||
if err := admit.Admit(attrs, nil); err == nil {
|
||||
t.Errorf("Expected rejection for using a secret the service account does not reference")
|
||||
}
|
||||
|
||||
@ -620,7 +620,7 @@ func TestRejectsUnreferencedSecretVolumes(t *testing.T) {
|
||||
},
|
||||
}
|
||||
attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
if err := admit.Admit(attrs); err == nil || !strings.Contains(err.Error(), "with envVar") {
|
||||
if err := admit.Admit(attrs, nil); err == nil || !strings.Contains(err.Error(), "with envVar") {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
@ -644,7 +644,7 @@ func TestRejectsUnreferencedSecretVolumes(t *testing.T) {
|
||||
},
|
||||
}
|
||||
attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
if err := admit.Admit(attrs); err == nil || !strings.Contains(err.Error(), "with envVar") {
|
||||
if err := admit.Admit(attrs, nil); err == nil || !strings.Contains(err.Error(), "with envVar") {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
@ -675,7 +675,7 @@ func TestAllowUnreferencedSecretVolumesForPermissiveSAs(t *testing.T) {
|
||||
},
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := admit.Admit(attrs)
|
||||
err := admit.Admit(attrs, nil)
|
||||
if err == nil {
|
||||
t.Errorf("Expected rejection for using a secret the service account does not reference")
|
||||
}
|
||||
@ -707,7 +707,7 @@ func TestAllowsReferencedImagePullSecrets(t *testing.T) {
|
||||
},
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := admit.Admit(attrs)
|
||||
err := admit.Admit(attrs, nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@ -736,7 +736,7 @@ func TestRejectsUnreferencedImagePullSecrets(t *testing.T) {
|
||||
},
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := admit.Admit(attrs)
|
||||
err := admit.Admit(attrs, nil)
|
||||
if err == nil {
|
||||
t.Errorf("Expected rejection for using a secret the service account does not reference")
|
||||
}
|
||||
@ -769,7 +769,7 @@ func TestDoNotAddImagePullSecrets(t *testing.T) {
|
||||
},
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := admit.Admit(attrs)
|
||||
err := admit.Admit(attrs, nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@ -803,7 +803,7 @@ func TestAddImagePullSecrets(t *testing.T) {
|
||||
|
||||
pod := &api.Pod{}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := admit.Admit(attrs)
|
||||
err := admit.Admit(attrs, nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
@ -884,7 +884,7 @@ func TestMultipleReferencedSecrets(t *testing.T) {
|
||||
}
|
||||
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
if err := admit.Admit(attrs); err != nil {
|
||||
if err := admit.Admit(attrs, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@ -1038,7 +1038,7 @@ func TestAutomountIsBackwardsCompatible(t *testing.T) {
|
||||
},
|
||||
}
|
||||
attrs := admission.NewAttributesRecord(pod, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, false, nil)
|
||||
err := admit.Admit(attrs)
|
||||
err := admit.Admit(attrs, nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ func nodeSelectorRequirementKeysExistInNodeSelectorTerms(reqs []api.NodeSelector
|
||||
return false
|
||||
}
|
||||
|
||||
func (l *persistentVolumeLabel) Admit(a admission.Attributes) (err error) {
|
||||
func (l *persistentVolumeLabel) Admit(a admission.Attributes, o admission.ObjectInterfaces) (err error) {
|
||||
if a.GetResource().GroupResource() != api.Resource("persistentvolumes") {
|
||||
return nil
|
||||
}
|
||||
|
@ -756,7 +756,7 @@ func Test_PVLAdmission(t *testing.T) {
|
||||
setPVLabeler(testcase.handler, testcase.pvlabeler)
|
||||
handler := admission.NewChainHandler(testcase.handler)
|
||||
|
||||
err := handler.Admit(admission.NewAttributesRecord(testcase.preAdmissionPV, nil, api.Kind("PersistentVolume").WithVersion("version"), testcase.preAdmissionPV.Namespace, testcase.preAdmissionPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err := handler.Admit(admission.NewAttributesRecord(testcase.preAdmissionPV, nil, api.Kind("PersistentVolume").WithVersion("version"), testcase.preAdmissionPV.Namespace, testcase.preAdmissionPV.Name, api.Resource("persistentvolumes").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if !reflect.DeepEqual(err, testcase.err) {
|
||||
t.Logf("expected error: %q", testcase.err)
|
||||
t.Logf("actual error: %q", err)
|
||||
|
@ -71,7 +71,7 @@ func (pvcr *persistentVolumeClaimResize) ValidateInitialization() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pvcr *persistentVolumeClaimResize) Validate(a admission.Attributes) error {
|
||||
func (pvcr *persistentVolumeClaimResize) Validate(a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
if a.GetResource().GroupResource() != api.Resource("persistentvolumeclaims") {
|
||||
return nil
|
||||
}
|
||||
|
@ -256,7 +256,7 @@ func TestPVCResizeAdmission(t *testing.T) {
|
||||
operation := admission.Update
|
||||
attributes := admission.NewAttributesRecord(tc.newObj, tc.oldObj, schema.GroupVersionKind{}, metav1.NamespaceDefault, "foo", tc.resource, tc.subresource, operation, false, nil)
|
||||
|
||||
err := ctrl.Validate(attributes)
|
||||
err := ctrl.Validate(attributes, nil)
|
||||
if !tc.checkError(err) {
|
||||
t.Errorf("%v: unexpected err: %v", tc.name, err)
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ func (a *claimDefaulterPlugin) ValidateInitialization() error {
|
||||
// 1. Find available StorageClasses.
|
||||
// 2. Figure which is the default
|
||||
// 3. Write to the PVClaim
|
||||
func (a *claimDefaulterPlugin) Admit(attr admission.Attributes) error {
|
||||
func (a *claimDefaulterPlugin) Admit(attr admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
if attr.GetResource().GroupResource() != api.Resource("persistentvolumeclaims") {
|
||||
return nil
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ func TestAdmission(t *testing.T) {
|
||||
false, // dryRun
|
||||
nil, // userInfo
|
||||
)
|
||||
err := ctrl.Admit(attrs)
|
||||
err := ctrl.Admit(attrs, nil)
|
||||
klog.Infof("Got %v", err)
|
||||
if err != nil && !test.expectError {
|
||||
t.Errorf("Test %q: unexpected error received: %v", test.name, err)
|
||||
|
@ -65,7 +65,7 @@ var (
|
||||
//
|
||||
// This prevents users from deleting a PVC that's used by a running pod.
|
||||
// This also prevents admin from deleting a PV that's bound by a PVC
|
||||
func (c *storageProtectionPlugin) Admit(a admission.Attributes) error {
|
||||
func (c *storageProtectionPlugin) Admit(a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
if !feature.DefaultFeatureGate.Enabled(features.StorageObjectInUseProtection) {
|
||||
return nil
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ func TestAdmit(t *testing.T) {
|
||||
nil, // userInfo
|
||||
)
|
||||
|
||||
err := ctrl.Admit(attrs)
|
||||
err := ctrl.Admit(attrs, nil)
|
||||
if err != nil {
|
||||
t.Errorf("Test %q: got unexpected error: %v", test.name, err)
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ func (o CustomResourceDefinitionsServerOptions) Config() (*apiserver.Config, err
|
||||
}
|
||||
|
||||
serverConfig := genericapiserver.NewRecommendedConfig(apiserver.Codecs)
|
||||
if err := o.RecommendedOptions.ApplyTo(serverConfig, apiserver.Scheme); err != nil {
|
||||
if err := o.RecommendedOptions.ApplyTo(serverConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := o.APIEnablement.ApplyTo(&serverConfig.Config, apiserver.DefaultAPIResourceConfigSource(), apiserver.Scheme); err != nil {
|
||||
|
@ -42,6 +42,7 @@ go_library(
|
||||
"handler.go",
|
||||
"interfaces.go",
|
||||
"plugins.go",
|
||||
"util.go",
|
||||
],
|
||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/admission",
|
||||
importpath = "k8s.io/apiserver/pkg/admission",
|
||||
|
@ -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)
|
||||
|
@ -15,7 +15,6 @@ go_library(
|
||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/apiserver/pkg/admission/initializer",
|
||||
importpath = "k8s.io/apiserver/pkg/admission/initializer",
|
||||
deps = [
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/informers:go_default_library",
|
||||
@ -28,7 +27,6 @@ go_test(
|
||||
srcs = ["initializer_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/informers:go_default_library",
|
||||
|
@ -17,7 +17,6 @@ limitations under the License.
|
||||
package initializer
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
"k8s.io/client-go/informers"
|
||||
@ -28,7 +27,6 @@ type pluginInitializer struct {
|
||||
externalClient kubernetes.Interface
|
||||
externalInformers informers.SharedInformerFactory
|
||||
authorizer authorizer.Authorizer
|
||||
scheme *runtime.Scheme
|
||||
}
|
||||
|
||||
// New creates an instance of admission plugins initializer.
|
||||
@ -37,13 +35,11 @@ func New(
|
||||
extClientset kubernetes.Interface,
|
||||
extInformers informers.SharedInformerFactory,
|
||||
authz authorizer.Authorizer,
|
||||
scheme *runtime.Scheme,
|
||||
) pluginInitializer {
|
||||
return pluginInitializer{
|
||||
externalClient: extClientset,
|
||||
externalInformers: extInformers,
|
||||
authorizer: authz,
|
||||
scheme: scheme,
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,10 +57,6 @@ func (i pluginInitializer) Initialize(plugin admission.Interface) {
|
||||
if wants, ok := plugin.(WantsAuthorizer); ok {
|
||||
wants.SetAuthorizer(i.authorizer)
|
||||
}
|
||||
|
||||
if wants, ok := plugin.(WantsScheme); ok {
|
||||
wants.SetScheme(i.scheme)
|
||||
}
|
||||
}
|
||||
|
||||
var _ admission.PluginInitializer = pluginInitializer{}
|
||||
|
@ -20,7 +20,6 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/apiserver/pkg/admission/initializer"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
@ -29,22 +28,10 @@ import (
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
)
|
||||
|
||||
// TestWantsScheme ensures that the scheme is injected when
|
||||
// the WantsScheme interface is implemented by a plugin.
|
||||
func TestWantsScheme(t *testing.T) {
|
||||
scheme := runtime.NewScheme()
|
||||
target := initializer.New(nil, nil, nil, scheme)
|
||||
wantSchemeAdmission := &WantSchemeAdmission{}
|
||||
target.Initialize(wantSchemeAdmission)
|
||||
if wantSchemeAdmission.scheme != scheme {
|
||||
t.Errorf("expected scheme to be initialized")
|
||||
}
|
||||
}
|
||||
|
||||
// TestWantsAuthorizer ensures that the authorizer is injected
|
||||
// when the WantsAuthorizer interface is implemented by a plugin.
|
||||
func TestWantsAuthorizer(t *testing.T) {
|
||||
target := initializer.New(nil, nil, &TestAuthorizer{}, nil)
|
||||
target := initializer.New(nil, nil, &TestAuthorizer{})
|
||||
wantAuthorizerAdmission := &WantAuthorizerAdmission{}
|
||||
target.Initialize(wantAuthorizerAdmission)
|
||||
if wantAuthorizerAdmission.auth == nil {
|
||||
@ -56,7 +43,7 @@ func TestWantsAuthorizer(t *testing.T) {
|
||||
// when the WantsExternalKubeClientSet interface is implemented by a plugin.
|
||||
func TestWantsExternalKubeClientSet(t *testing.T) {
|
||||
cs := &fake.Clientset{}
|
||||
target := initializer.New(cs, nil, &TestAuthorizer{}, nil)
|
||||
target := initializer.New(cs, nil, &TestAuthorizer{})
|
||||
wantExternalKubeClientSet := &WantExternalKubeClientSet{}
|
||||
target.Initialize(wantExternalKubeClientSet)
|
||||
if wantExternalKubeClientSet.cs != cs {
|
||||
@ -69,7 +56,7 @@ func TestWantsExternalKubeClientSet(t *testing.T) {
|
||||
func TestWantsExternalKubeInformerFactory(t *testing.T) {
|
||||
cs := &fake.Clientset{}
|
||||
sf := informers.NewSharedInformerFactory(cs, time.Duration(1)*time.Second)
|
||||
target := initializer.New(cs, sf, &TestAuthorizer{}, nil)
|
||||
target := initializer.New(cs, sf, &TestAuthorizer{})
|
||||
wantExternalKubeInformerFactory := &WantExternalKubeInformerFactory{}
|
||||
target.Initialize(wantExternalKubeInformerFactory)
|
||||
if wantExternalKubeInformerFactory.sf != sf {
|
||||
@ -85,7 +72,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 +87,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 +102,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,20 +123,9 @@ 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 }
|
||||
|
||||
// WantSchemeAdmission is a test stub that fulfills the WantsScheme interface.
|
||||
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) Handles(o admission.Operation) bool { return false }
|
||||
func (self *WantSchemeAdmission) ValidateInitialization() error { return nil }
|
||||
|
||||
var _ admission.Interface = &WantSchemeAdmission{}
|
||||
var _ initializer.WantsScheme = &WantSchemeAdmission{}
|
||||
|
@ -17,7 +17,6 @@ limitations under the License.
|
||||
package initializer
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
"k8s.io/client-go/informers"
|
||||
@ -41,9 +40,3 @@ type WantsAuthorizer interface {
|
||||
SetAuthorizer(authorizer.Authorizer)
|
||||
admission.InitializationValidator
|
||||
}
|
||||
|
||||
// WantsScheme defines a function that accepts runtime.Scheme for admission plugins that need it.
|
||||
type WantsScheme interface {
|
||||
SetScheme(*runtime.Scheme)
|
||||
admission.InitializationValidator
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ var _ = initializer.WantsExternalKubeInformerFactory(&Lifecycle{})
|
||||
var _ = initializer.WantsExternalKubeClientSet(&Lifecycle{})
|
||||
|
||||
// Admit makes an admission decision based on the request attributes
|
||||
func (l *Lifecycle) Admit(a admission.Attributes) error {
|
||||
func (l *Lifecycle) Admit(a admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
// prevent deletion of immortal namespaces
|
||||
if a.GetOperation() == admission.Delete && a.GetKind().GroupKind() == v1.SchemeGroupVersion.WithKind("Namespace").GroupKind() && l.immortalNamespaces.Has(a.GetName()) {
|
||||
return errors.NewForbidden(a.GetResource().GroupResource(), a.GetName(), fmt.Errorf("this namespace may not be deleted"))
|
||||
|
@ -48,7 +48,7 @@ func newHandlerForTestWithClock(c clientset.Interface, cacheClock clock.Clock) (
|
||||
if err != nil {
|
||||
return nil, f, err
|
||||
}
|
||||
pluginInitializer := kubeadmission.New(c, f, nil, nil)
|
||||
pluginInitializer := kubeadmission.New(c, f, nil)
|
||||
pluginInitializer.Initialize(handler)
|
||||
err = admission.ValidateInitialization(handler)
|
||||
return handler, f, err
|
||||
@ -104,7 +104,7 @@ func TestAccessReviewCheckOnMissingNamespace(t *testing.T) {
|
||||
}
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
err = handler.Admit(admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{Group: "authorization.k8s.io", Version: "v1", Kind: "LocalSubjectAccesReview"}, namespace, "", schema.GroupVersionResource{Group: "authorization.k8s.io", Version: "v1", Resource: "localsubjectaccessreviews"}, "", admission.Create, false, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(nil, nil, schema.GroupVersionKind{Group: "authorization.k8s.io", Version: "v1", Kind: "LocalSubjectAccesReview"}, namespace, "", schema.GroupVersionResource{Group: "authorization.k8s.io", Version: "v1", Resource: "localsubjectaccessreviews"}, "", admission.Create, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@ -124,7 +124,7 @@ func TestAdmissionNamespaceDoesNotExist(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
pod := newPod(namespace)
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err == nil {
|
||||
actions := ""
|
||||
for _, action := range mockClient.Actions() {
|
||||
@ -134,19 +134,19 @@ func TestAdmissionNamespaceDoesNotExist(t *testing.T) {
|
||||
}
|
||||
|
||||
// verify create operations in the namespace cause an error
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err == nil {
|
||||
t.Errorf("Expected error rejecting creates in a namespace when it is missing")
|
||||
}
|
||||
|
||||
// verify update operations in the namespace cause an error
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Update, false, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Update, false, nil), nil)
|
||||
if err == nil {
|
||||
t.Errorf("Expected error rejecting updates in a namespace when it is missing")
|
||||
}
|
||||
|
||||
// verify delete operations in the namespace can proceed
|
||||
err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Delete, false, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Delete, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error returned from admission handler: %v", err)
|
||||
}
|
||||
@ -166,7 +166,7 @@ func TestAdmissionNamespaceActive(t *testing.T) {
|
||||
informerFactory.Start(wait.NeverStop)
|
||||
|
||||
pod := newPod(namespace)
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error returned from admission handler")
|
||||
}
|
||||
@ -187,31 +187,31 @@ func TestAdmissionNamespaceTerminating(t *testing.T) {
|
||||
|
||||
pod := newPod(namespace)
|
||||
// verify create operations in the namespace cause an error
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err == nil {
|
||||
t.Errorf("Expected error rejecting creates in a namespace when it is terminating")
|
||||
}
|
||||
|
||||
// verify update operations in the namespace can proceed
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Update, false, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Update, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error returned from admission handler: %v", err)
|
||||
}
|
||||
|
||||
// verify delete operations in the namespace can proceed
|
||||
err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Delete, false, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Delete, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error returned from admission handler: %v", err)
|
||||
}
|
||||
|
||||
// verify delete of namespace default can never proceed
|
||||
err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Namespace").GroupKind().WithVersion("version"), "", metav1.NamespaceDefault, v1.Resource("namespaces").WithVersion("version"), "", admission.Delete, false, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Namespace").GroupKind().WithVersion("version"), "", metav1.NamespaceDefault, v1.Resource("namespaces").WithVersion("version"), "", admission.Delete, false, nil), nil)
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error that this namespace can never be deleted")
|
||||
}
|
||||
|
||||
// verify delete of namespace other than default can proceed
|
||||
err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Namespace").GroupKind().WithVersion("version"), "", "other", v1.Resource("namespaces").WithVersion("version"), "", admission.Delete, false, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Namespace").GroupKind().WithVersion("version"), "", "other", v1.Resource("namespaces").WithVersion("version"), "", admission.Delete, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Did not expect an error %v", err)
|
||||
}
|
||||
@ -238,7 +238,7 @@ func TestAdmissionNamespaceForceLiveLookup(t *testing.T) {
|
||||
|
||||
pod := newPod(namespace)
|
||||
// verify create operations in the namespace is allowed
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error rejecting creates in an active namespace")
|
||||
}
|
||||
@ -248,7 +248,7 @@ func TestAdmissionNamespaceForceLiveLookup(t *testing.T) {
|
||||
getCalls = 0
|
||||
|
||||
// verify delete of namespace can proceed
|
||||
err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Namespace").GroupKind().WithVersion("version"), namespace, namespace, v1.Resource("namespaces").WithVersion("version"), "", admission.Delete, false, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(nil, nil, v1.SchemeGroupVersion.WithKind("Namespace").GroupKind().WithVersion("version"), namespace, namespace, v1.Resource("namespaces").WithVersion("version"), "", admission.Delete, false, nil), nil)
|
||||
if err != nil {
|
||||
t.Errorf("Expected namespace deletion to be allowed")
|
||||
}
|
||||
@ -261,7 +261,7 @@ func TestAdmissionNamespaceForceLiveLookup(t *testing.T) {
|
||||
phases[namespace] = v1.NamespaceTerminating
|
||||
|
||||
// verify create operations in the namespace cause an error
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err == nil {
|
||||
t.Errorf("Expected error rejecting creates in a namespace right after deleting it")
|
||||
}
|
||||
@ -274,7 +274,7 @@ func TestAdmissionNamespaceForceLiveLookup(t *testing.T) {
|
||||
fakeClock.Step(forceLiveLookupTTL)
|
||||
|
||||
// verify create operations in the namespace cause an error
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
err = handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if err == nil {
|
||||
t.Errorf("Expected error rejecting creates in a namespace right after deleting it")
|
||||
}
|
||||
@ -287,7 +287,7 @@ func TestAdmissionNamespaceForceLiveLookup(t *testing.T) {
|
||||
fakeClock.Step(time.Millisecond)
|
||||
|
||||
// verify create operations in the namespace don't force a live lookup after the timeout
|
||||
handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil))
|
||||
handler.Admit(admission.NewAttributesRecord(&pod, nil, v1.SchemeGroupVersion.WithKind("Pod").GroupKind().WithVersion("version"), pod.Namespace, pod.Name, v1.Resource("pods").WithVersion("version"), "", admission.Create, false, nil), nil)
|
||||
if getCalls != 0 {
|
||||
t.Errorf("Expected no live lookup of the namespace at t=forceLiveLookupTTL+1ms, got %d", getCalls)
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ go_test(
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/apis/example:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/apis/example/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/apis/example2/v1:go_default_library",
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -41,5 +41,5 @@ type VersionedAttributes struct {
|
||||
// Dispatcher dispatches webhook call to a list of webhooks with admission attributes as argument.
|
||||
type Dispatcher interface {
|
||||
// Dispatch a request to the webhooks using the given webhooks. A non-nil error means the request is rejected.
|
||||
Dispatch(ctx context.Context, a *VersionedAttributes, hooks []*v1beta1.Webhook) error
|
||||
Dispatch(ctx context.Context, a *VersionedAttributes, o admission.ObjectInterfaces, hooks []*v1beta1.Webhook) error
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ import (
|
||||
admissionv1beta1 "k8s.io/api/admission/v1beta1"
|
||||
"k8s.io/api/admissionregistration/v1beta1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
genericadmissioninit "k8s.io/apiserver/pkg/admission/initializer"
|
||||
"k8s.io/apiserver/pkg/admission/plugin/webhook/config"
|
||||
@ -43,7 +42,6 @@ type Webhook struct {
|
||||
|
||||
hookSource Source
|
||||
clientManager *webhook.ClientManager
|
||||
convertor *convertor
|
||||
namespaceMatcher *namespace.Matcher
|
||||
dispatcher Dispatcher
|
||||
}
|
||||
@ -79,7 +77,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
|
||||
@ -98,13 +95,6 @@ func (a *Webhook) SetServiceResolver(sr webhook.ServiceResolver) {
|
||||
a.clientManager.SetServiceResolver(sr)
|
||||
}
|
||||
|
||||
// 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.
|
||||
// It sets external ClientSet for admission plugins that need it
|
||||
func (a *Webhook) SetExternalKubeClientSet(client clientset.Interface) {
|
||||
@ -132,9 +122,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 +143,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,18 +175,18 @@ 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)
|
||||
}
|
||||
versionedAttr.VersionedObject = out
|
||||
}
|
||||
return a.dispatcher.Dispatch(ctx, &versionedAttr, relevantHooks)
|
||||
return a.dispatcher.Dispatch(ctx, &versionedAttr, o, relevantHooks)
|
||||
}
|
||||
|
@ -39,8 +39,6 @@ go_test(
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//staging/src/k8s.io/api/admission/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||
|
@ -31,7 +31,9 @@ import (
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/json"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
admissionmetrics "k8s.io/apiserver/pkg/admission/metrics"
|
||||
webhookerrors "k8s.io/apiserver/pkg/admission/plugin/webhook/errors"
|
||||
"k8s.io/apiserver/pkg/admission/plugin/webhook/generic"
|
||||
@ -53,10 +55,10 @@ func newMutatingDispatcher(p *Plugin) func(cm *webhook.ClientManager) generic.Di
|
||||
|
||||
var _ generic.Dispatcher = &mutatingDispatcher{}
|
||||
|
||||
func (a *mutatingDispatcher) Dispatch(ctx context.Context, attr *generic.VersionedAttributes, relevantHooks []*v1beta1.Webhook) error {
|
||||
func (a *mutatingDispatcher) Dispatch(ctx context.Context, attr *generic.VersionedAttributes, o admission.ObjectInterfaces, relevantHooks []*v1beta1.Webhook) error {
|
||||
for _, hook := range relevantHooks {
|
||||
t := time.Now()
|
||||
err := a.callAttrMutatingHook(ctx, hook, attr)
|
||||
err := a.callAttrMutatingHook(ctx, hook, attr, o)
|
||||
admissionmetrics.Metrics.ObserveWebhook(time.Since(t), err != nil, attr.Attributes, "admit", hook.Name)
|
||||
if err == nil {
|
||||
continue
|
||||
@ -76,13 +78,13 @@ func (a *mutatingDispatcher) Dispatch(ctx context.Context, attr *generic.Version
|
||||
|
||||
// convert attr.VersionedObject to the internal version in the underlying admission.Attributes
|
||||
if attr.VersionedObject != nil {
|
||||
return a.plugin.scheme.Convert(attr.VersionedObject, attr.Attributes.GetObject(), nil)
|
||||
return o.GetObjectConvertor().Convert(attr.VersionedObject, attr.Attributes.GetObject(), nil)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// note that callAttrMutatingHook updates attr
|
||||
func (a *mutatingDispatcher) callAttrMutatingHook(ctx context.Context, h *v1beta1.Webhook, attr *generic.VersionedAttributes) error {
|
||||
func (a *mutatingDispatcher) callAttrMutatingHook(ctx context.Context, h *v1beta1.Webhook, attr *generic.VersionedAttributes, o admission.ObjectInterfaces) error {
|
||||
if attr.IsDryRun() {
|
||||
if h.SideEffects == nil {
|
||||
return &webhook.ErrCallingWebhook{WebhookName: h.Name, Reason: fmt.Errorf("Webhook SideEffects is nil")}
|
||||
@ -135,7 +137,8 @@ func (a *mutatingDispatcher) callAttrMutatingHook(ctx context.Context, h *v1beta
|
||||
return apierrors.NewInternalError(fmt.Errorf("admission webhook %q attempted to modify the object, which is not supported for this operation", h.Name))
|
||||
}
|
||||
|
||||
objJS, err := runtime.Encode(a.plugin.jsonSerializer, attr.VersionedObject)
|
||||
jsonSerializer := json.NewSerializer(json.DefaultMetaFactory, o.GetObjectCreater(), o.GetObjectTyper(), false)
|
||||
objJS, err := runtime.Encode(jsonSerializer, attr.VersionedObject)
|
||||
if err != nil {
|
||||
return apierrors.NewInternalError(err)
|
||||
}
|
||||
@ -150,17 +153,17 @@ func (a *mutatingDispatcher) callAttrMutatingHook(ctx context.Context, h *v1beta
|
||||
// They are represented as Unstructured.
|
||||
newVersionedObject = &unstructured.Unstructured{}
|
||||
} else {
|
||||
newVersionedObject, err = a.plugin.scheme.New(attr.GetKind())
|
||||
newVersionedObject, err = o.GetObjectCreater().New(attr.GetKind())
|
||||
if err != nil {
|
||||
return apierrors.NewInternalError(err)
|
||||
}
|
||||
}
|
||||
// TODO: if we have multiple mutating webhooks, we can remember the json
|
||||
// instead of encoding and decoding for each one.
|
||||
if _, _, err := a.plugin.jsonSerializer.Decode(patchedJS, nil, newVersionedObject); err != nil {
|
||||
if _, _, err := jsonSerializer.Decode(patchedJS, nil, newVersionedObject); err != nil {
|
||||
return apierrors.NewInternalError(err)
|
||||
}
|
||||
attr.VersionedObject = newVersionedObject
|
||||
a.plugin.scheme.Default(attr.VersionedObject)
|
||||
o.GetObjectDefaulter().Default(attr.VersionedObject)
|
||||
return nil
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ func TestDispatch(t *testing.T) {
|
||||
require.NoError(t, example.AddToScheme(scheme))
|
||||
require.NoError(t, examplev1.AddToScheme(scheme))
|
||||
require.NoError(t, example2v1.AddToScheme(scheme))
|
||||
objectInterfaces := &admission.SchemeBasedObjectInterfaces{scheme}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
@ -118,16 +119,14 @@ func TestDispatch(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
a := &mutatingDispatcher{
|
||||
plugin: &Plugin{
|
||||
scheme: scheme,
|
||||
},
|
||||
plugin: &Plugin{},
|
||||
}
|
||||
attr := generic.VersionedAttributes{
|
||||
Attributes: admission.NewAttributesRecord(test.out, nil, schema.GroupVersionKind{}, "", "", schema.GroupVersionResource{}, "", admission.Operation(""), false, nil),
|
||||
VersionedOldObject: nil,
|
||||
VersionedObject: test.in,
|
||||
}
|
||||
if err := a.Dispatch(context.TODO(), &attr, nil); err != nil {
|
||||
if err := a.Dispatch(context.TODO(), &attr, objectInterfaces, nil); err != nil {
|
||||
t.Fatalf("%s: unexpected error: %v", test.name, err)
|
||||
}
|
||||
if !reflect.DeepEqual(attr.Attributes.GetObject(), test.expectedObj) {
|
||||
|
@ -17,11 +17,8 @@ limitations under the License.
|
||||
package mutating
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/json"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
"k8s.io/apiserver/pkg/admission/configuration"
|
||||
"k8s.io/apiserver/pkg/admission/plugin/webhook/generic"
|
||||
@ -47,9 +44,6 @@ func Register(plugins *admission.Plugins) {
|
||||
// Plugin is an implementation of admission.Interface.
|
||||
type Plugin struct {
|
||||
*generic.Webhook
|
||||
|
||||
scheme *runtime.Scheme
|
||||
jsonSerializer *json.Serializer
|
||||
}
|
||||
|
||||
var _ admission.MutationInterface = &Plugin{}
|
||||
@ -67,30 +61,15 @@ func NewMutatingWebhook(configFile io.Reader) (*Plugin, error) {
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// SetScheme sets a serializer(NegotiatedSerializer) which is derived from the scheme
|
||||
func (a *Plugin) SetScheme(scheme *runtime.Scheme) {
|
||||
a.Webhook.SetScheme(scheme)
|
||||
if scheme != nil {
|
||||
a.scheme = scheme
|
||||
a.jsonSerializer = json.NewSerializer(json.DefaultMetaFactory, scheme, scheme, false)
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateInitialization implements the InitializationValidator interface.
|
||||
func (a *Plugin) ValidateInitialization() error {
|
||||
if err := a.Webhook.ValidateInitialization(); err != nil {
|
||||
return err
|
||||
}
|
||||
if a.scheme == nil {
|
||||
return fmt.Errorf("scheme is not properly setup")
|
||||
}
|
||||
if a.jsonSerializer == nil {
|
||||
return fmt.Errorf("jsonSerializer is not properly setup")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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}
|
||||
}
|
||||
|
@ -32,13 +32,9 @@ go_test(
|
||||
srcs = ["plugin_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//staging/src/k8s.io/api/admission/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/testing:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/require:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -28,6 +28,7 @@ import (
|
||||
"k8s.io/api/admissionregistration/v1beta1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
admissionmetrics "k8s.io/apiserver/pkg/admission/metrics"
|
||||
webhookerrors "k8s.io/apiserver/pkg/admission/plugin/webhook/errors"
|
||||
"k8s.io/apiserver/pkg/admission/plugin/webhook/generic"
|
||||
@ -46,7 +47,7 @@ func newValidatingDispatcher(cm *webhook.ClientManager) generic.Dispatcher {
|
||||
|
||||
var _ generic.Dispatcher = &validatingDispatcher{}
|
||||
|
||||
func (d *validatingDispatcher) Dispatch(ctx context.Context, attr *generic.VersionedAttributes, relevantHooks []*v1beta1.Webhook) error {
|
||||
func (d *validatingDispatcher) Dispatch(ctx context.Context, attr *generic.VersionedAttributes, o admission.ObjectInterfaces, relevantHooks []*v1beta1.Webhook) error {
|
||||
wg := sync.WaitGroup{}
|
||||
errCh := make(chan error, len(relevantHooks))
|
||||
wg.Add(len(relevantHooks))
|
||||
|
@ -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)
|
||||
}
|
||||
|
28
staging/src/k8s.io/apiserver/pkg/admission/util.go
Normal file
28
staging/src/k8s.io/apiserver/pkg/admission/util.go
Normal file
@ -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)
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user