diff --git a/pkg/admission/attributes.go b/pkg/admission/attributes.go index 36aa4acdbef..687aeaa1160 100644 --- a/pkg/admission/attributes.go +++ b/pkg/admission/attributes.go @@ -22,22 +22,24 @@ import ( ) type attributesRecord struct { - kind string - namespace string - resource string - operation Operation - object runtime.Object - userInfo user.Info + kind string + namespace string + resource string + subresource string + operation Operation + object runtime.Object + userInfo user.Info } -func NewAttributesRecord(object runtime.Object, kind, namespace, resource string, operation Operation, userInfo user.Info) Attributes { +func NewAttributesRecord(object runtime.Object, kind, namespace, resource, subresource string, operation Operation, userInfo user.Info) Attributes { return &attributesRecord{ - kind: kind, - namespace: namespace, - resource: resource, - operation: operation, - object: object, - userInfo: userInfo, + kind: kind, + namespace: namespace, + resource: resource, + subresource: subresource, + operation: operation, + object: object, + userInfo: userInfo, } } @@ -53,6 +55,10 @@ func (record *attributesRecord) GetResource() string { return record.resource } +func (record *attributesRecord) GetSubresource() string { + return record.subresource +} + func (record *attributesRecord) GetOperation() Operation { return record.operation } diff --git a/pkg/admission/chain_test.go b/pkg/admission/chain_test.go index bfb3c1d5b1e..f68d6b1525b 100644 --- a/pkg/admission/chain_test.go +++ b/pkg/admission/chain_test.go @@ -98,7 +98,7 @@ func TestAdmit(t *testing.T) { }, } for _, test := range tests { - err := test.chain.Admit(NewAttributesRecord(nil, "", "", "", test.operation, nil)) + err := test.chain.Admit(NewAttributesRecord(nil, "", "", "", "", test.operation, nil)) accepted := (err == nil) if accepted != test.accept { t.Errorf("%s: unexpected result of admit call: %v\n", test.name, accepted) diff --git a/pkg/admission/interfaces.go b/pkg/admission/interfaces.go index c282dee9d29..5fb2dda303f 100644 --- a/pkg/admission/interfaces.go +++ b/pkg/admission/interfaces.go @@ -24,11 +24,21 @@ import ( // Attributes is an interface used by AdmissionController to get information about a request // that is used to make an admission decision. type Attributes interface { + // GetNamespace is the namespace associated with the request (if any) GetNamespace() string + // GetResource is the name of the resource being requested. This is not the kind. For example: pods GetResource() string + // GetSubresource is the name of the subresource being requested. This is a different resource, scoped to the parent resource, but it may have a different kind. + // For instance, /pods has the resource "pods" and the kind "Pod", while /pods/foo/status has the resource "pods", the sub resource "status", and the kind "Pod" + // (because status operates on pods). The binding resource for a pod though may be /pods/foo/binding, which has resource "pods", subresource "binding", and kind "Binding". + GetSubresource() string + // GetOperation is the operation being performed GetOperation() Operation + // GetObject is the object from the incoming request prior to default values being applied GetObject() runtime.Object + // GetKind is the type of object being manipulated. For example: Pod GetKind() string + // GetUserInfo is information about the requesting user GetUserInfo() user.Info } diff --git a/pkg/apiserver/api_installer.go b/pkg/apiserver/api_installer.go index fdefcac2626..fde652b9cf6 100644 --- a/pkg/apiserver/api_installer.go +++ b/pkg/apiserver/api_installer.go @@ -365,6 +365,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag APIVersion: a.group.Version, ServerAPIVersion: serverVersion, Resource: resource, + Subresource: subresource, Kind: kind, } for _, action := range actions { diff --git a/pkg/apiserver/resthandler.go b/pkg/apiserver/resthandler.go index 567a3d837dd..0b2956e7360 100644 --- a/pkg/apiserver/resthandler.go +++ b/pkg/apiserver/resthandler.go @@ -67,9 +67,10 @@ type RequestScope struct { Creater runtime.ObjectCreater Convertor runtime.ObjectConvertor - Resource string - Kind string - APIVersion string + Resource string + Subresource string + Kind string + APIVersion string // The version of apiserver resources to use ServerAPIVersion string @@ -164,7 +165,7 @@ func ConnectResource(connecter rest.Connecter, scope RequestScope, admit admissi ResourcePath: restPath, } userInfo, _ := api.UserFrom(ctx) - err = admit.Admit(admission.NewAttributesRecord(connectRequest, scope.Kind, namespace, scope.Resource, admission.Connect, userInfo)) + err = admit.Admit(admission.NewAttributesRecord(connectRequest, scope.Kind, namespace, scope.Resource, scope.Subresource, admission.Connect, userInfo)) if err != nil { errorJSON(err, scope.Codec, w) return @@ -308,7 +309,7 @@ func createHandler(r rest.NamedCreater, scope RequestScope, typer runtime.Object if admit.Handles(admission.Create) { userInfo, _ := api.UserFrom(ctx) - err = admit.Admit(admission.NewAttributesRecord(obj, scope.Kind, namespace, scope.Resource, admission.Create, userInfo)) + err = admit.Admit(admission.NewAttributesRecord(obj, scope.Kind, namespace, scope.Resource, scope.Subresource, admission.Create, userInfo)) if err != nil { errorJSON(err, scope.Codec, w) return @@ -378,7 +379,7 @@ func PatchResource(r rest.Patcher, scope RequestScope, typer runtime.ObjectTyper // PATCH requires same permission as UPDATE if admit.Handles(admission.Update) { userInfo, _ := api.UserFrom(ctx) - err = admit.Admit(admission.NewAttributesRecord(obj, scope.Kind, namespace, scope.Resource, admission.Update, userInfo)) + err = admit.Admit(admission.NewAttributesRecord(obj, scope.Kind, namespace, scope.Resource, scope.Subresource, admission.Update, userInfo)) if err != nil { errorJSON(err, scope.Codec, w) return @@ -478,7 +479,7 @@ func UpdateResource(r rest.Updater, scope RequestScope, typer runtime.ObjectType if admit.Handles(admission.Update) { userInfo, _ := api.UserFrom(ctx) - err = admit.Admit(admission.NewAttributesRecord(obj, scope.Kind, namespace, scope.Resource, admission.Update, userInfo)) + err = admit.Admit(admission.NewAttributesRecord(obj, scope.Kind, namespace, scope.Resource, scope.Subresource, admission.Update, userInfo)) if err != nil { errorJSON(err, scope.Codec, w) return @@ -542,7 +543,7 @@ func DeleteResource(r rest.GracefulDeleter, checkBody bool, scope RequestScope, if admit.Handles(admission.Delete) { userInfo, _ := api.UserFrom(ctx) - err = admit.Admit(admission.NewAttributesRecord(nil, scope.Kind, namespace, scope.Resource, admission.Delete, userInfo)) + err = admit.Admit(admission.NewAttributesRecord(nil, scope.Kind, namespace, scope.Resource, scope.Subresource, admission.Delete, userInfo)) if err != nil { errorJSON(err, scope.Codec, w) return diff --git a/plugin/pkg/admission/deny/admission_test.go b/plugin/pkg/admission/deny/admission_test.go index 478cc8567b1..6f24a9c7f97 100644 --- a/plugin/pkg/admission/deny/admission_test.go +++ b/plugin/pkg/admission/deny/admission_test.go @@ -24,7 +24,7 @@ import ( func TestAdmission(t *testing.T) { handler := NewAlwaysDeny() - err := handler.Admit(admission.NewAttributesRecord(nil, "Pod", "foo", "Pod", "ignored", nil)) + err := handler.Admit(admission.NewAttributesRecord(nil, "kind", "namespace", "resource", "subresource", admission.Create, nil)) if err == nil { t.Errorf("Expected error returned from admission handler") } diff --git a/plugin/pkg/admission/exec/denyprivileged/admission_test.go b/plugin/pkg/admission/exec/denyprivileged/admission_test.go index e3e90aa71cd..dfd4a03dcee 100644 --- a/plugin/pkg/admission/exec/denyprivileged/admission_test.go +++ b/plugin/pkg/admission/exec/denyprivileged/admission_test.go @@ -49,7 +49,7 @@ func testAdmission(t *testing.T, pod *api.Pod, shouldAccept bool) { client: mockClient, } req := &rest.ConnectRequest{Name: pod.Name, ResourcePath: "pods/exec"} - err := handler.Admit(admission.NewAttributesRecord(req, "Pod", "test", "pods", admission.Connect, nil)) + err := handler.Admit(admission.NewAttributesRecord(req, "Pod", "test", "pods", "exec", admission.Connect, nil)) if shouldAccept && err != nil { t.Errorf("Unexpected error returned from admission handler: %v", err) } diff --git a/plugin/pkg/admission/limitranger/admission.go b/plugin/pkg/admission/limitranger/admission.go index 7ff6cbb42d8..274b7693859 100644 --- a/plugin/pkg/admission/limitranger/admission.go +++ b/plugin/pkg/admission/limitranger/admission.go @@ -48,6 +48,12 @@ type limitRanger struct { // Admit admits resources into cluster that do not violate any defined LimitRange in the namespace func (l *limitRanger) Admit(a admission.Attributes) (err error) { + + // Ignore all calls to subresources + if a.GetSubresource() != "" { + return nil + } + obj := a.GetObject() resource := a.GetResource() name := "Unknown" diff --git a/plugin/pkg/admission/limitranger/admission_test.go b/plugin/pkg/admission/limitranger/admission_test.go index 9765509b19b..5e62a0a648a 100644 --- a/plugin/pkg/admission/limitranger/admission_test.go +++ b/plugin/pkg/admission/limitranger/admission_test.go @@ -20,8 +20,11 @@ import ( "strconv" "testing" + "github.com/GoogleCloudPlatform/kubernetes/pkg/admission" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource" + "github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache" + "github.com/GoogleCloudPlatform/kubernetes/pkg/client/testclient" ) func getResourceList(cpu, memory string) api.ResourceList { @@ -45,7 +48,8 @@ func getResourceRequirements(limits, requests api.ResourceList) api.ResourceRequ func validLimitRange() api.LimitRange { return api.LimitRange{ ObjectMeta: api.ObjectMeta{ - Name: "abc", + Name: "abc", + Namespace: "test", }, Spec: api.LimitRangeSpec{ Limits: []api.LimitRangeItem{ @@ -65,9 +69,32 @@ func validLimitRange() api.LimitRange { } } +func validLimitRangeNoDefaults() api.LimitRange { + return api.LimitRange{ + ObjectMeta: api.ObjectMeta{ + Name: "abc", + Namespace: "test", + }, + Spec: api.LimitRangeSpec{ + Limits: []api.LimitRangeItem{ + { + Type: api.LimitTypePod, + Max: getResourceList("200m", "4Gi"), + Min: getResourceList("50m", "2Mi"), + }, + { + Type: api.LimitTypeContainer, + Max: getResourceList("100m", "2Gi"), + Min: getResourceList("25m", "1Mi"), + }, + }, + }, + } +} + func validPod(name string, numContainers int, resources api.ResourceRequirements) api.Pod { pod := api.Pod{ - ObjectMeta: api.ObjectMeta{Name: name}, + ObjectMeta: api.ObjectMeta{Name: name, Namespace: "test"}, Spec: api.PodSpec{}, } pod.Spec.Containers = make([]api.Container, 0, numContainers) @@ -192,3 +219,29 @@ func TestPodLimitFuncApplyDefault(t *testing.T) { } } } + +func TestLimitRangerIgnoresSubresource(t *testing.T) { + client := testclient.NewSimpleFake() + indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{"namespace": cache.MetaNamespaceIndexFunc}) + handler := &limitRanger{ + Handler: admission.NewHandler(admission.Create, admission.Update), + client: client, + limitFunc: Limit, + indexer: indexer, + } + + limitRange := validLimitRangeNoDefaults() + testPod := validPod("testPod", 1, api.ResourceRequirements{}) + + indexer.Add(&limitRange) + err := handler.Admit(admission.NewAttributesRecord(&testPod, "Pod", limitRange.Namespace, "pods", "", admission.Update, nil)) + if err == nil { + t.Errorf("Expected an error since the pod did not specify resource limits in its update call") + } + + err = handler.Admit(admission.NewAttributesRecord(&testPod, "Pod", limitRange.Namespace, "pods", "status", admission.Update, nil)) + if err != nil { + t.Errorf("Should have ignored calls to any subresource of pod %v", err) + } + +} diff --git a/plugin/pkg/admission/namespace/autoprovision/admission_test.go b/plugin/pkg/admission/namespace/autoprovision/admission_test.go index edaa4a1ad9b..de0be632868 100644 --- a/plugin/pkg/admission/namespace/autoprovision/admission_test.go +++ b/plugin/pkg/admission/namespace/autoprovision/admission_test.go @@ -41,7 +41,7 @@ func TestAdmission(t *testing.T) { Containers: []api.Container{{Name: "ctr", Image: "image"}}, }, } - err := handler.Admit(admission.NewAttributesRecord(&pod, "Pod", namespace, "pods", admission.Create, nil)) + err := handler.Admit(admission.NewAttributesRecord(&pod, "Pod", namespace, "pods", "", admission.Create, nil)) if err != nil { t.Errorf("Unexpected error returned from admission handler") } @@ -72,7 +72,7 @@ func TestAdmissionNamespaceExists(t *testing.T) { Containers: []api.Container{{Name: "ctr", Image: "image"}}, }, } - err := handler.Admit(admission.NewAttributesRecord(&pod, "Pod", namespace, "pods", admission.Create, nil)) + err := handler.Admit(admission.NewAttributesRecord(&pod, "Pod", namespace, "pods", "", admission.Create, nil)) if err != nil { t.Errorf("Unexpected error returned from admission handler") } @@ -93,7 +93,7 @@ func TestIgnoreAdmission(t *testing.T) { Containers: []api.Container{{Name: "ctr", Image: "image"}}, }, } - err := handler.Admit(admission.NewAttributesRecord(&pod, "Pod", namespace, "pods", admission.Update, nil)) + err := handler.Admit(admission.NewAttributesRecord(&pod, "Pod", namespace, "pods", "", admission.Update, nil)) if err != nil { t.Errorf("Unexpected error returned from admission handler") } @@ -120,7 +120,7 @@ func TestAdmissionNamespaceExistsUnknownToHandler(t *testing.T) { Containers: []api.Container{{Name: "ctr", Image: "image"}}, }, } - err := handler.Admit(admission.NewAttributesRecord(&pod, "Pod", namespace, "pods", admission.Create, nil)) + err := handler.Admit(admission.NewAttributesRecord(&pod, "Pod", namespace, "pods", "", admission.Create, nil)) if err != nil { t.Errorf("Unexpected error returned from admission handler") } diff --git a/plugin/pkg/admission/namespace/lifecycle/admission_test.go b/plugin/pkg/admission/namespace/lifecycle/admission_test.go index 5c3ce76e271..ef6c3002335 100644 --- a/plugin/pkg/admission/namespace/lifecycle/admission_test.go +++ b/plugin/pkg/admission/namespace/lifecycle/admission_test.go @@ -49,7 +49,7 @@ func TestAdmission(t *testing.T) { Containers: []api.Container{{Name: "ctr", Image: "image"}}, }, } - err := handler.Admit(admission.NewAttributesRecord(&pod, "Pod", namespaceObj.Namespace, "pods", admission.Create, nil)) + err := handler.Admit(admission.NewAttributesRecord(&pod, "Pod", namespaceObj.Namespace, "pods", "", admission.Create, nil)) if err != nil { t.Errorf("Unexpected error returned from admission handler: %v", err) } @@ -59,19 +59,19 @@ func TestAdmission(t *testing.T) { store.Add(namespaceObj) // verify create operations in the namespace cause an error - err = handler.Admit(admission.NewAttributesRecord(&pod, "Pod", namespaceObj.Namespace, "pods", admission.Create, nil)) + err = handler.Admit(admission.NewAttributesRecord(&pod, "Pod", namespaceObj.Namespace, "pods", "", admission.Create, 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, "Pod", namespaceObj.Namespace, "pods", admission.Update, nil)) + err = handler.Admit(admission.NewAttributesRecord(&pod, "Pod", namespaceObj.Namespace, "pods", "", admission.Update, 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, "Pod", namespaceObj.Namespace, "pods", admission.Delete, nil)) + err = handler.Admit(admission.NewAttributesRecord(nil, "Pod", namespaceObj.Namespace, "pods", "", admission.Delete, nil)) if err != nil { t.Errorf("Unexpected error returned from admission handler: %v", err) } diff --git a/plugin/pkg/admission/resourcequota/admission.go b/plugin/pkg/admission/resourcequota/admission.go index af43288fb8d..cc6133eadb5 100644 --- a/plugin/pkg/admission/resourcequota/admission.go +++ b/plugin/pkg/admission/resourcequota/admission.go @@ -80,6 +80,10 @@ var resourceToResourceName = map[string]api.ResourceName{ } func (q *quota) Admit(a admission.Attributes) (err error) { + if a.GetSubresource() != "" { + return nil + } + if a.GetOperation() == "DELETE" { return nil } diff --git a/plugin/pkg/admission/resourcequota/admission_test.go b/plugin/pkg/admission/resourcequota/admission_test.go index 97992ce8b0e..c65f5ad13b9 100644 --- a/plugin/pkg/admission/resourcequota/admission_test.go +++ b/plugin/pkg/admission/resourcequota/admission_test.go @@ -22,6 +22,7 @@ import ( "github.com/GoogleCloudPlatform/kubernetes/pkg/admission" "github.com/GoogleCloudPlatform/kubernetes/pkg/api" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource" + "github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache" "github.com/GoogleCloudPlatform/kubernetes/pkg/client/testclient" ) @@ -41,12 +42,47 @@ func getResourceRequirements(cpu, memory string) api.ResourceRequirements { func TestAdmissionIgnoresDelete(t *testing.T) { namespace := "default" handler := createResourceQuota(&testclient.Fake{}, nil) - err := handler.Admit(admission.NewAttributesRecord(nil, "Pod", namespace, "pods", admission.Delete, nil)) + err := handler.Admit(admission.NewAttributesRecord(nil, "Pod", namespace, "pods", "", admission.Delete, nil)) if err != nil { t.Errorf("ResourceQuota should admit all deletes: %v", err) } } +func TestAdmissionIgnoresSubresources(t *testing.T) { + indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{"namespace": cache.MetaNamespaceIndexFunc}) + handler := createResourceQuota(&testclient.Fake{}, indexer) + + quota := &api.ResourceQuota{} + quota.Name = "quota" + quota.Namespace = "test" + quota.Status = api.ResourceQuotaStatus{ + Hard: api.ResourceList{}, + Used: api.ResourceList{}, + } + quota.Status.Hard[api.ResourceMemory] = resource.MustParse("2Gi") + quota.Status.Used[api.ResourceMemory] = resource.MustParse("1Gi") + + indexer.Add(quota) + + newPod := &api.Pod{ + ObjectMeta: api.ObjectMeta{Name: "123", Namespace: quota.Namespace}, + Spec: api.PodSpec{ + Volumes: []api.Volume{{Name: "vol"}}, + Containers: []api.Container{{Name: "ctr", Image: "image", Resources: getResourceRequirements("100m", "2Gi")}}, + }} + + err := handler.Admit(admission.NewAttributesRecord(newPod, "Pod", newPod.Namespace, "pods", "", admission.Create, nil)) + if err == nil { + t.Errorf("Expected an error because the pod exceeded allowed quota") + } + + err = handler.Admit(admission.NewAttributesRecord(newPod, "Pod", newPod.Namespace, "pods", "subresource", admission.Create, nil)) + if err != nil { + t.Errorf("Did not expect an error because the action went to a subresource: %v", err) + } + +} + func TestIncrementUsagePods(t *testing.T) { namespace := "default" client := testclient.NewSimpleFake(&api.PodList{ @@ -67,7 +103,7 @@ func TestIncrementUsagePods(t *testing.T) { r := api.ResourcePods status.Hard[r] = resource.MustParse("2") status.Used[r] = resource.MustParse("1") - dirty, err := IncrementUsage(admission.NewAttributesRecord(&api.Pod{}, "Pod", namespace, "pods", admission.Create, nil), status, client) + dirty, err := IncrementUsage(admission.NewAttributesRecord(&api.Pod{}, "Pod", namespace, "pods", "", admission.Create, nil), status, client) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -107,7 +143,7 @@ func TestIncrementUsageMemory(t *testing.T) { Volumes: []api.Volume{{Name: "vol"}}, Containers: []api.Container{{Name: "ctr", Image: "image", Resources: getResourceRequirements("100m", "1Gi")}}, }} - dirty, err := IncrementUsage(admission.NewAttributesRecord(newPod, "Pod", namespace, "pods", admission.Create, nil), status, client) + dirty, err := IncrementUsage(admission.NewAttributesRecord(newPod, "Pod", namespace, "pods", "", admission.Create, nil), status, client) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -148,7 +184,7 @@ func TestExceedUsageMemory(t *testing.T) { Volumes: []api.Volume{{Name: "vol"}}, Containers: []api.Container{{Name: "ctr", Image: "image", Resources: getResourceRequirements("100m", "3Gi")}}, }} - _, err := IncrementUsage(admission.NewAttributesRecord(newPod, "Pod", namespace, "pods", admission.Create, nil), status, client) + _, err := IncrementUsage(admission.NewAttributesRecord(newPod, "Pod", namespace, "pods", "", admission.Create, nil), status, client) if err == nil { t.Errorf("Expected memory usage exceeded error") } @@ -181,7 +217,7 @@ func TestIncrementUsageCPU(t *testing.T) { Volumes: []api.Volume{{Name: "vol"}}, Containers: []api.Container{{Name: "ctr", Image: "image", Resources: getResourceRequirements("100m", "1Gi")}}, }} - dirty, err := IncrementUsage(admission.NewAttributesRecord(newPod, "Pod", namespace, "pods", admission.Create, nil), status, client) + dirty, err := IncrementUsage(admission.NewAttributesRecord(newPod, "Pod", namespace, "pods", "", admission.Create, nil), status, client) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -222,7 +258,7 @@ func TestUnboundedCPU(t *testing.T) { Volumes: []api.Volume{{Name: "vol"}}, Containers: []api.Container{{Name: "ctr", Image: "image", Resources: getResourceRequirements("0m", "1Gi")}}, }} - _, err := IncrementUsage(admission.NewAttributesRecord(newPod, "Pod", namespace, "pods", admission.Create, nil), status, client) + _, err := IncrementUsage(admission.NewAttributesRecord(newPod, "Pod", namespace, "pods", "", admission.Create, nil), status, client) if err == nil { t.Errorf("Expected CPU unbounded usage error") } @@ -255,7 +291,7 @@ func TestUnboundedMemory(t *testing.T) { Volumes: []api.Volume{{Name: "vol"}}, Containers: []api.Container{{Name: "ctr", Image: "image", Resources: getResourceRequirements("250m", "0")}}, }} - _, err := IncrementUsage(admission.NewAttributesRecord(newPod, "Pod", namespace, "pods", admission.Create, nil), status, client) + _, err := IncrementUsage(admission.NewAttributesRecord(newPod, "Pod", namespace, "pods", "", admission.Create, nil), status, client) if err == nil { t.Errorf("Expected memory unbounded usage error") } @@ -288,7 +324,7 @@ func TestExceedUsageCPU(t *testing.T) { Volumes: []api.Volume{{Name: "vol"}}, Containers: []api.Container{{Name: "ctr", Image: "image", Resources: getResourceRequirements("500m", "1Gi")}}, }} - _, err := IncrementUsage(admission.NewAttributesRecord(newPod, "Pod", namespace, "pods", admission.Create, nil), status, client) + _, err := IncrementUsage(admission.NewAttributesRecord(newPod, "Pod", namespace, "pods", "", admission.Create, nil), status, client) if err == nil { t.Errorf("Expected CPU usage exceeded error") } @@ -314,7 +350,7 @@ func TestExceedUsagePods(t *testing.T) { r := api.ResourcePods status.Hard[r] = resource.MustParse("1") status.Used[r] = resource.MustParse("1") - _, err := IncrementUsage(admission.NewAttributesRecord(&api.Pod{}, "Pod", namespace, "pods", admission.Create, nil), status, client) + _, err := IncrementUsage(admission.NewAttributesRecord(&api.Pod{}, "Pod", namespace, "pods", "", admission.Create, nil), status, client) if err == nil { t.Errorf("Expected error because this would exceed your quota") } @@ -336,7 +372,7 @@ func TestIncrementUsageServices(t *testing.T) { r := api.ResourceServices status.Hard[r] = resource.MustParse("2") status.Used[r] = resource.MustParse("1") - dirty, err := IncrementUsage(admission.NewAttributesRecord(&api.Service{}, "Service", namespace, "services", admission.Create, nil), status, client) + dirty, err := IncrementUsage(admission.NewAttributesRecord(&api.Service{}, "Service", namespace, "services", "", admission.Create, nil), status, client) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -365,7 +401,7 @@ func TestExceedUsageServices(t *testing.T) { r := api.ResourceServices status.Hard[r] = resource.MustParse("1") status.Used[r] = resource.MustParse("1") - _, err := IncrementUsage(admission.NewAttributesRecord(&api.Service{}, "Service", namespace, "services", admission.Create, nil), status, client) + _, err := IncrementUsage(admission.NewAttributesRecord(&api.Service{}, "Service", namespace, "services", "", admission.Create, nil), status, client) if err == nil { t.Errorf("Expected error because this would exceed usage") } @@ -387,7 +423,7 @@ func TestIncrementUsageReplicationControllers(t *testing.T) { r := api.ResourceReplicationControllers status.Hard[r] = resource.MustParse("2") status.Used[r] = resource.MustParse("1") - dirty, err := IncrementUsage(admission.NewAttributesRecord(&api.ReplicationController{}, "ReplicationController", namespace, "replicationControllers", admission.Create, nil), status, client) + dirty, err := IncrementUsage(admission.NewAttributesRecord(&api.ReplicationController{}, "ReplicationController", namespace, "replicationControllers", "", admission.Create, nil), status, client) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -416,7 +452,7 @@ func TestExceedUsageReplicationControllers(t *testing.T) { r := api.ResourceReplicationControllers status.Hard[r] = resource.MustParse("1") status.Used[r] = resource.MustParse("1") - _, err := IncrementUsage(admission.NewAttributesRecord(&api.ReplicationController{}, "ReplicationController", namespace, "replicationControllers", admission.Create, nil), status, client) + _, err := IncrementUsage(admission.NewAttributesRecord(&api.ReplicationController{}, "ReplicationController", namespace, "replicationControllers", "", admission.Create, nil), status, client) if err == nil { t.Errorf("Expected error for exceeding hard limits") } @@ -438,7 +474,7 @@ func TestExceedUsageSecrets(t *testing.T) { r := api.ResourceSecrets status.Hard[r] = resource.MustParse("1") status.Used[r] = resource.MustParse("1") - _, err := IncrementUsage(admission.NewAttributesRecord(&api.Secret{}, "Secret", namespace, "secrets", admission.Create, nil), status, client) + _, err := IncrementUsage(admission.NewAttributesRecord(&api.Secret{}, "Secret", namespace, "secrets", "", admission.Create, nil), status, client) if err == nil { t.Errorf("Expected error for exceeding hard limits") } @@ -460,7 +496,7 @@ func TestExceedUsagePersistentVolumeClaims(t *testing.T) { r := api.ResourcePersistentVolumeClaims status.Hard[r] = resource.MustParse("1") status.Used[r] = resource.MustParse("1") - _, err := IncrementUsage(admission.NewAttributesRecord(&api.PersistentVolumeClaim{}, "PersistentVolumeClaim", namespace, "persistentVolumeClaims", admission.Create, nil), status, client) + _, err := IncrementUsage(admission.NewAttributesRecord(&api.PersistentVolumeClaim{}, "PersistentVolumeClaim", namespace, "persistentVolumeClaims", "", admission.Create, nil), status, client) if err == nil { t.Errorf("Expected error for exceeding hard limits") } diff --git a/plugin/pkg/admission/securitycontext/scdeny/admission_test.go b/plugin/pkg/admission/securitycontext/scdeny/admission_test.go index 6a0cd111bf0..98a2b3a475e 100644 --- a/plugin/pkg/admission/securitycontext/scdeny/admission_test.go +++ b/plugin/pkg/admission/securitycontext/scdeny/admission_test.go @@ -44,7 +44,7 @@ func TestAdmission(t *testing.T) { } for k, v := range successCases { pod.Spec.Containers[0].SecurityContext = v - err := handler.Admit(admission.NewAttributesRecord(&pod, "Pod", "foo", string(api.ResourcePods), "ignored", nil)) + err := handler.Admit(admission.NewAttributesRecord(&pod, "Pod", "foo", string(api.ResourcePods), "", "ignored", nil)) if err != nil { t.Errorf("Unexpected error returned from admission handler for case %s", k) } @@ -57,7 +57,7 @@ func TestAdmission(t *testing.T) { } for k, v := range errorCases { pod.Spec.Containers[0].SecurityContext = v - err := handler.Admit(admission.NewAttributesRecord(&pod, "Pod", "foo", string(api.ResourcePods), "ignored", nil)) + err := handler.Admit(admission.NewAttributesRecord(&pod, "Pod", "foo", string(api.ResourcePods), "", "ignored", nil)) if err == nil { t.Errorf("Expected error returned from admission handler for case %s", k) } diff --git a/plugin/pkg/admission/serviceaccount/admission_test.go b/plugin/pkg/admission/serviceaccount/admission_test.go index 7c7fa0e4332..9b71d8e93f8 100644 --- a/plugin/pkg/admission/serviceaccount/admission_test.go +++ b/plugin/pkg/admission/serviceaccount/admission_test.go @@ -30,7 +30,7 @@ import ( func TestIgnoresNonCreate(t *testing.T) { pod := &api.Pod{} for _, op := range []admission.Operation{admission.Update, admission.Delete, admission.Connect} { - attrs := admission.NewAttributesRecord(pod, "Pod", "myns", string(api.ResourcePods), op, nil) + attrs := admission.NewAttributesRecord(pod, "Pod", "myns", string(api.ResourcePods), "", op, nil) handler := admission.NewChainHandler(NewServiceAccount(nil)) err := handler.Admit(attrs) if err != nil { @@ -41,7 +41,7 @@ func TestIgnoresNonCreate(t *testing.T) { func TestIgnoresNonPodResource(t *testing.T) { pod := &api.Pod{} - attrs := admission.NewAttributesRecord(pod, "Pod", "myns", "CustomResource", admission.Create, nil) + attrs := admission.NewAttributesRecord(pod, "Pod", "myns", "CustomResource", "", admission.Create, nil) err := NewServiceAccount(nil).Admit(attrs) if err != nil { t.Errorf("Expected non-pod resource allowed, got err: %v", err) @@ -49,7 +49,7 @@ func TestIgnoresNonPodResource(t *testing.T) { } func TestIgnoresNilObject(t *testing.T) { - attrs := admission.NewAttributesRecord(nil, "Pod", "myns", string(api.ResourcePods), admission.Create, nil) + attrs := admission.NewAttributesRecord(nil, "Pod", "myns", string(api.ResourcePods), "", admission.Create, nil) err := NewServiceAccount(nil).Admit(attrs) if err != nil { t.Errorf("Expected nil object allowed allowed, got err: %v", err) @@ -58,7 +58,7 @@ func TestIgnoresNilObject(t *testing.T) { func TestIgnoresNonPodObject(t *testing.T) { obj := &api.Namespace{} - attrs := admission.NewAttributesRecord(obj, "Pod", "myns", string(api.ResourcePods), admission.Create, nil) + attrs := admission.NewAttributesRecord(obj, "Pod", "myns", string(api.ResourcePods), "", admission.Create, nil) err := NewServiceAccount(nil).Admit(attrs) if err != nil { t.Errorf("Expected non pod object allowed, got err: %v", err) @@ -78,7 +78,7 @@ func TestIgnoresMirrorPod(t *testing.T) { }, }, } - attrs := admission.NewAttributesRecord(pod, "Pod", "myns", string(api.ResourcePods), admission.Create, nil) + attrs := admission.NewAttributesRecord(pod, "Pod", "myns", string(api.ResourcePods), "", admission.Create, nil) err := NewServiceAccount(nil).Admit(attrs) if err != nil { t.Errorf("Expected mirror pod without service account or secrets allowed, got err: %v", err) @@ -96,7 +96,7 @@ func TestRejectsMirrorPodWithServiceAccount(t *testing.T) { ServiceAccountName: "default", }, } - attrs := admission.NewAttributesRecord(pod, "Pod", "myns", string(api.ResourcePods), admission.Create, nil) + attrs := admission.NewAttributesRecord(pod, "Pod", "myns", string(api.ResourcePods), "", admission.Create, nil) err := NewServiceAccount(nil).Admit(attrs) if err == nil { t.Errorf("Expected a mirror pod to be prevented from referencing a service account") @@ -116,7 +116,7 @@ func TestRejectsMirrorPodWithSecretVolumes(t *testing.T) { }, }, } - attrs := admission.NewAttributesRecord(pod, "Pod", "myns", string(api.ResourcePods), admission.Create, nil) + attrs := admission.NewAttributesRecord(pod, "Pod", "myns", string(api.ResourcePods), "", admission.Create, nil) err := NewServiceAccount(nil).Admit(attrs) if err == nil { t.Errorf("Expected a mirror pod to be prevented from referencing a secret volume") @@ -138,7 +138,7 @@ func TestAssignsDefaultServiceAccountAndToleratesMissingAPIToken(t *testing.T) { }) pod := &api.Pod{} - attrs := admission.NewAttributesRecord(pod, "Pod", ns, string(api.ResourcePods), admission.Create, nil) + attrs := admission.NewAttributesRecord(pod, "Pod", ns, string(api.ResourcePods), "", admission.Create, nil) err := admit.Admit(attrs) if err != nil { t.Errorf("Unexpected error: %v", err) @@ -162,7 +162,7 @@ func TestFetchesUncachedServiceAccount(t *testing.T) { admit := NewServiceAccount(client) pod := &api.Pod{} - attrs := admission.NewAttributesRecord(pod, "Pod", ns, string(api.ResourcePods), admission.Create, nil) + attrs := admission.NewAttributesRecord(pod, "Pod", ns, string(api.ResourcePods), "", admission.Create, nil) err := admit.Admit(attrs) if err != nil { t.Errorf("Unexpected error: %v", err) @@ -181,7 +181,7 @@ func TestDeniesInvalidServiceAccount(t *testing.T) { admit := NewServiceAccount(client) pod := &api.Pod{} - attrs := admission.NewAttributesRecord(pod, "Pod", ns, string(api.ResourcePods), admission.Create, nil) + attrs := admission.NewAttributesRecord(pod, "Pod", ns, string(api.ResourcePods), "", admission.Create, nil) err := admit.Admit(attrs) if err == nil { t.Errorf("Expected error for missing service account, got none") @@ -243,7 +243,7 @@ func TestAutomountsAPIToken(t *testing.T) { }, }, } - attrs := admission.NewAttributesRecord(pod, "Pod", ns, string(api.ResourcePods), admission.Create, nil) + attrs := admission.NewAttributesRecord(pod, "Pod", ns, string(api.ResourcePods), "", admission.Create, nil) err := admit.Admit(attrs) if err != nil { t.Errorf("Unexpected error: %v", err) @@ -321,7 +321,7 @@ func TestRespectsExistingMount(t *testing.T) { }, }, } - attrs := admission.NewAttributesRecord(pod, "Pod", ns, string(api.ResourcePods), "CREATE", nil) + attrs := admission.NewAttributesRecord(pod, "Pod", ns, string(api.ResourcePods), "", admission.Create, nil) err := admit.Admit(attrs) if err != nil { t.Errorf("Unexpected error: %v", err) @@ -364,7 +364,7 @@ func TestAllowsReferencedSecretVolumes(t *testing.T) { }, }, } - attrs := admission.NewAttributesRecord(pod, "Pod", ns, string(api.ResourcePods), "CREATE", nil) + attrs := admission.NewAttributesRecord(pod, "Pod", ns, string(api.ResourcePods), "", admission.Create, nil) err := admit.Admit(attrs) if err != nil { t.Errorf("Unexpected error: %v", err) @@ -392,7 +392,7 @@ func TestRejectsUnreferencedSecretVolumes(t *testing.T) { }, }, } - attrs := admission.NewAttributesRecord(pod, "Pod", ns, string(api.ResourcePods), admission.Create, nil) + attrs := admission.NewAttributesRecord(pod, "Pod", ns, string(api.ResourcePods), "", admission.Create, nil) err := admit.Admit(attrs) if err == nil { t.Errorf("Expected rejection for using a secret the service account does not reference") @@ -421,7 +421,7 @@ func TestAllowsReferencedImagePullSecrets(t *testing.T) { ImagePullSecrets: []api.LocalObjectReference{{Name: "foo"}}, }, } - attrs := admission.NewAttributesRecord(pod, "Pod", ns, string(api.ResourcePods), "CREATE", nil) + attrs := admission.NewAttributesRecord(pod, "Pod", ns, string(api.ResourcePods), "", admission.Create, nil) err := admit.Admit(attrs) if err != nil { t.Errorf("Unexpected error: %v", err) @@ -447,7 +447,7 @@ func TestRejectsUnreferencedImagePullSecrets(t *testing.T) { ImagePullSecrets: []api.LocalObjectReference{{Name: "foo"}}, }, } - attrs := admission.NewAttributesRecord(pod, "Pod", ns, string(api.ResourcePods), "CREATE", nil) + attrs := admission.NewAttributesRecord(pod, "Pod", ns, string(api.ResourcePods), "", admission.Create, nil) err := admit.Admit(attrs) if err == nil { t.Errorf("Expected rejection for using a secret the service account does not reference") @@ -477,7 +477,7 @@ func TestDoNotAddImagePullSecrets(t *testing.T) { ImagePullSecrets: []api.LocalObjectReference{{Name: "foo"}}, }, } - attrs := admission.NewAttributesRecord(pod, "Pod", ns, string(api.ResourcePods), "CREATE", nil) + attrs := admission.NewAttributesRecord(pod, "Pod", ns, string(api.ResourcePods), "", admission.Create, nil) err := admit.Admit(attrs) if err != nil { t.Errorf("Unexpected error: %v", err) @@ -508,7 +508,7 @@ func TestAddImagePullSecrets(t *testing.T) { admit.serviceAccounts.Add(sa) pod := &api.Pod{} - attrs := admission.NewAttributesRecord(pod, "Pod", ns, string(api.ResourcePods), "CREATE", nil) + attrs := admission.NewAttributesRecord(pod, "Pod", ns, string(api.ResourcePods), "", admission.Create, nil) err := admit.Admit(attrs) if err != nil { t.Errorf("Unexpected error: %v", err)