From d9a4cfc09f16be00c4ca474ad6c855472d3797f9 Mon Sep 17 00:00:00 2001 From: deads2k Date: Thu, 15 Dec 2016 12:52:14 -0500 Subject: [PATCH] fix e2e tests which use SAs for permissions --- test/e2e/BUILD | 2 + test/e2e/framework/BUILD | 3 ++ test/e2e/framework/authorizer_util.go | 58 +++++++++++++++++++++++++++ test/e2e/ingress.go | 30 ++++++++++++++ test/e2e/node_problem_detector.go | 30 ++++++++++++++ test/e2e/pre_stop.go | 32 +++++++++++++++ 6 files changed, 155 insertions(+) create mode 100644 test/e2e/framework/authorizer_util.go diff --git a/test/e2e/BUILD b/test/e2e/BUILD index 4e7146d1da8..873b5abd397 100644 --- a/test/e2e/BUILD +++ b/test/e2e/BUILD @@ -128,6 +128,7 @@ go_library( "//pkg/apis/extensions:go_default_library", "//pkg/apis/extensions/v1beta1:go_default_library", "//pkg/apis/meta/v1:go_default_library", + "//pkg/apis/rbac/v1alpha1:go_default_library", "//pkg/apis/storage/util:go_default_library", "//pkg/apis/storage/v1beta1:go_default_library", "//pkg/apis/storage/v1beta1/util:go_default_library", @@ -163,6 +164,7 @@ go_library( "//pkg/runtime:go_default_library", "//pkg/runtime/schema:go_default_library", "//pkg/security/apparmor:go_default_library", + "//pkg/serviceaccount:go_default_library", "//pkg/types:go_default_library", "//pkg/util:go_default_library", "//pkg/util/exec:go_default_library", diff --git a/test/e2e/framework/BUILD b/test/e2e/framework/BUILD index ef5ffa8afff..4a5d27e89e4 100644 --- a/test/e2e/framework/BUILD +++ b/test/e2e/framework/BUILD @@ -10,6 +10,7 @@ load( go_library( name = "go_default_library", srcs = [ + "authorizer_util.go", "cleanup.go", "exec_util.go", "federation_util.go", @@ -38,6 +39,7 @@ go_library( "//pkg/api/validation:go_default_library", "//pkg/apimachinery/registered:go_default_library", "//pkg/apis/apps/v1beta1:go_default_library", + "//pkg/apis/authorization/v1beta1:go_default_library", "//pkg/apis/batch:go_default_library", "//pkg/apis/batch/v1:go_default_library", "//pkg/apis/componentconfig:go_default_library", @@ -46,6 +48,7 @@ go_library( "//pkg/apis/meta/v1:go_default_library", "//pkg/apis/meta/v1/unstructured:go_default_library", "//pkg/client/clientset_generated/clientset:go_default_library", + "//pkg/client/clientset_generated/clientset/typed/authorization/v1beta1:go_default_library", "//pkg/client/clientset_generated/clientset/typed/core/v1:go_default_library", "//pkg/client/clientset_generated/internalclientset:go_default_library", "//pkg/client/conditions:go_default_library", diff --git a/test/e2e/framework/authorizer_util.go b/test/e2e/framework/authorizer_util.go new file mode 100644 index 00000000000..106f5c759ba --- /dev/null +++ b/test/e2e/framework/authorizer_util.go @@ -0,0 +1,58 @@ +/* +Copyright 2016 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 framework + +import ( + "time" + + authorizationv1beta1 "k8s.io/kubernetes/pkg/apis/authorization/v1beta1" + v1beta1authorization "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/authorization/v1beta1" + "k8s.io/kubernetes/pkg/runtime/schema" + "k8s.io/kubernetes/pkg/util/wait" +) + +const ( + policyCachePollInterval = 100 * time.Millisecond + policyCachePollTimeout = 5 * time.Second +) + +// WaitForAuthorizationUpdate checks if the given user can perform the named verb and action. +// If policyCachePollTimeout is reached without the expected condition matching, an error is returned +func WaitForAuthorizationUpdate(c v1beta1authorization.SubjectAccessReviewsGetter, user, namespace, verb string, resource schema.GroupResource, allowed bool) error { + review := &authorizationv1beta1.SubjectAccessReview{ + Spec: authorizationv1beta1.SubjectAccessReviewSpec{ + ResourceAttributes: &authorizationv1beta1.ResourceAttributes{ + Group: resource.Group, + Verb: verb, + Resource: resource.Resource, + Namespace: namespace, + }, + User: user, + }, + } + err := wait.Poll(policyCachePollInterval, policyCachePollTimeout, func() (bool, error) { + response, err := c.SubjectAccessReviews().Create(review) + if err != nil { + return false, err + } + if response.Status.Allowed != allowed { + return false, nil + } + return true, nil + }) + return err +} diff --git a/test/e2e/ingress.go b/test/e2e/ingress.go index ae8d83dddb3..c64c59eea9b 100644 --- a/test/e2e/ingress.go +++ b/test/e2e/ingress.go @@ -21,6 +21,10 @@ import ( "path/filepath" "time" + legacyv1 "k8s.io/kubernetes/pkg/api/v1" + rbacv1alpha1 "k8s.io/kubernetes/pkg/apis/rbac/v1alpha1" + "k8s.io/kubernetes/pkg/runtime/schema" + "k8s.io/kubernetes/pkg/serviceaccount" "k8s.io/kubernetes/test/e2e/framework" . "github.com/onsi/ginkgo" @@ -70,6 +74,32 @@ var _ = framework.KubeDescribe("Loadbalancing: L7", func() { f.BeforeEach() jig = newTestJig(f.ClientSet) ns = f.Namespace.Name + + // this test wants powerful permissions. Since the namespace names are unique, we can leave this + // lying around so we don't have to race any caches + _, err := jig.client.Rbac().ClusterRoleBindings().Create(&rbacv1alpha1.ClusterRoleBinding{ + ObjectMeta: legacyv1.ObjectMeta{ + Name: f.Namespace.Name + "--cluster-admin", + }, + RoleRef: rbacv1alpha1.RoleRef{ + APIGroup: "rbac.authorization.k8s.io", + Kind: "ClusterRole", + Name: "cluster-admin", + }, + Subjects: []rbacv1alpha1.Subject{ + { + Kind: rbacv1alpha1.ServiceAccountKind, + Namespace: f.Namespace.Name, + Name: "default", + }, + }, + }) + framework.ExpectNoError(err) + + err = framework.WaitForAuthorizationUpdate(jig.client.Authorization(), + serviceaccount.MakeUsername(f.Namespace.Name, "default"), + "", "create", schema.GroupResource{Resource: "pods"}, true) + framework.ExpectNoError(err) }) // Before enabling this loadbalancer test in any other test list you must diff --git a/test/e2e/node_problem_detector.go b/test/e2e/node_problem_detector.go index aa8348935cb..b2174ba841d 100644 --- a/test/e2e/node_problem_detector.go +++ b/test/e2e/node_problem_detector.go @@ -24,11 +24,15 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/v1" + legacyv1 "k8s.io/kubernetes/pkg/api/v1" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" + rbacv1alpha1 "k8s.io/kubernetes/pkg/apis/rbac/v1alpha1" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" coreclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/core/v1" "k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/labels" + "k8s.io/kubernetes/pkg/runtime/schema" + "k8s.io/kubernetes/pkg/serviceaccount" "k8s.io/kubernetes/pkg/util/system" "k8s.io/kubernetes/pkg/util/uuid" "k8s.io/kubernetes/test/e2e/framework" @@ -57,6 +61,32 @@ var _ = framework.KubeDescribe("NodeProblemDetector", func() { configName = "node-problem-detector-config-" + uid // There is no namespace for Node, event recorder will set default namespace for node events. eventNamespace = v1.NamespaceDefault + + // this test wants extra permissions. Since the namespace names are unique, we can leave this + // lying around so we don't have to race any caches + _, err := f.ClientSet.Rbac().ClusterRoleBindings().Create(&rbacv1alpha1.ClusterRoleBinding{ + ObjectMeta: legacyv1.ObjectMeta{ + Name: f.Namespace.Name + "--cluster-admin", + }, + RoleRef: rbacv1alpha1.RoleRef{ + APIGroup: "rbac.authorization.k8s.io", + Kind: "ClusterRole", + Name: "cluster-admin", + }, + Subjects: []rbacv1alpha1.Subject{ + { + Kind: rbacv1alpha1.ServiceAccountKind, + Namespace: f.Namespace.Name, + Name: "default", + }, + }, + }) + framework.ExpectNoError(err) + + err = framework.WaitForAuthorizationUpdate(f.ClientSet.Authorization(), + serviceaccount.MakeUsername(f.Namespace.Name, "default"), + "", "create", schema.GroupResource{Resource: "pods"}, true) + framework.ExpectNoError(err) }) // Test kernel monitor. We may add other tests if we have more problem daemons in the future. diff --git a/test/e2e/pre_stop.go b/test/e2e/pre_stop.go index ecfb834367d..a83d022e61e 100644 --- a/test/e2e/pre_stop.go +++ b/test/e2e/pre_stop.go @@ -22,8 +22,12 @@ import ( "time" "k8s.io/kubernetes/pkg/api/v1" + legacyv1 "k8s.io/kubernetes/pkg/api/v1" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" + rbacv1alpha1 "k8s.io/kubernetes/pkg/apis/rbac/v1alpha1" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" + "k8s.io/kubernetes/pkg/runtime/schema" + "k8s.io/kubernetes/pkg/serviceaccount" "k8s.io/kubernetes/pkg/util/wait" "k8s.io/kubernetes/test/e2e/framework" @@ -163,6 +167,34 @@ func testPreStop(c clientset.Interface, ns string) { var _ = framework.KubeDescribe("PreStop", func() { f := framework.NewDefaultFramework("prestop") + BeforeEach(func() { + // this test wants extra permissions. Since the namespace names are unique, we can leave this + // lying around so we don't have to race any caches + _, err := f.ClientSet.Rbac().ClusterRoleBindings().Create(&rbacv1alpha1.ClusterRoleBinding{ + ObjectMeta: legacyv1.ObjectMeta{ + Name: f.Namespace.Name + "--cluster-admin", + }, + RoleRef: rbacv1alpha1.RoleRef{ + APIGroup: "rbac.authorization.k8s.io", + Kind: "ClusterRole", + Name: "cluster-admin", + }, + Subjects: []rbacv1alpha1.Subject{ + { + Kind: rbacv1alpha1.ServiceAccountKind, + Namespace: f.Namespace.Name, + Name: "default", + }, + }, + }) + framework.ExpectNoError(err) + + err = framework.WaitForAuthorizationUpdate(f.ClientSet.Authorization(), + serviceaccount.MakeUsername(f.Namespace.Name, "default"), + "", "create", schema.GroupResource{Resource: "pods"}, true) + framework.ExpectNoError(err) + }) + It("should call prestop when killing a pod [Conformance]", func() { testPreStop(f.ClientSet, f.Namespace.Name) })