diff --git a/cluster/gce/gci/configure-helper.sh b/cluster/gce/gci/configure-helper.sh index 543f53ac1de..aa4f54fefe0 100644 --- a/cluster/gce/gci/configure-helper.sh +++ b/cluster/gce/gci/configure-helper.sh @@ -786,7 +786,6 @@ function start-kube-apiserver { local params="${API_SERVER_TEST_LOG_LEVEL:-"--v=2"} ${APISERVER_TEST_ARGS:-} ${CLOUD_CONFIG_OPT}" params+=" --address=127.0.0.1" params+=" --allow-privileged=true" - params+=" --authorization-policy-file=/etc/srv/kubernetes/abac-authz-policy.jsonl" params+=" --cloud-provider=gce" params+=" --client-ca-file=/etc/srv/kubernetes/ca.crt" params+=" --etcd-servers=http://127.0.0.1:2379" @@ -864,7 +863,7 @@ function start-kube-apiserver { webhook_authn_config_volume="{\"name\": \"webhookauthnconfigmount\",\"hostPath\": {\"path\": \"/etc/gcp_authn.config\"}}," fi - params+=" --authorization-mode=RBAC,ABAC" + params+=" --authorization-mode=RBAC" local webhook_config_mount="" local webhook_config_volume="" if [[ -n "${GCP_AUTHZ_URL:-}" ]]; then @@ -874,17 +873,6 @@ function start-kube-apiserver { fi local -r src_dir="${KUBE_HOME}/kube-manifests/kubernetes/gci-trusty" - if [[ -n "${KUBE_USER:-}" || ! -e /etc/srv/kubernetes/abac-authz-policy.jsonl ]]; then - local -r abac_policy_json="${src_dir}/abac-authz-policy.jsonl" - remove-salt-config-comments "${abac_policy_json}" - if [[ -n "${KUBE_USER:-}" ]]; then - sed -i -e "s/{{kube_user}}/${KUBE_USER}/g" "${abac_policy_json}" - else - sed -i -e "/{{kube_user}}/d" "${abac_policy_json}" - fi - cp "${abac_policy_json}" /etc/srv/kubernetes/ - fi - src_file="${src_dir}/kube-apiserver.manifest" remove-salt-config-comments "${src_file}" # Evaluate variables. diff --git a/test/e2e/framework/BUILD b/test/e2e/framework/BUILD index 4a5d27e89e4..cf56e10511e 100644 --- a/test/e2e/framework/BUILD +++ b/test/e2e/framework/BUILD @@ -47,9 +47,11 @@ go_library( "//pkg/apis/extensions/v1beta1:go_default_library", "//pkg/apis/meta/v1:go_default_library", "//pkg/apis/meta/v1/unstructured:go_default_library", + "//pkg/apis/rbac/v1alpha1: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/clientset/typed/rbac/v1alpha1:go_default_library", "//pkg/client/clientset_generated/internalclientset:go_default_library", "//pkg/client/conditions:go_default_library", "//pkg/client/restclient:go_default_library", diff --git a/test/e2e/framework/authorizer_util.go b/test/e2e/framework/authorizer_util.go index b8ef478c85c..a878470c86d 100644 --- a/test/e2e/framework/authorizer_util.go +++ b/test/e2e/framework/authorizer_util.go @@ -17,11 +17,15 @@ limitations under the License. package framework import ( + "fmt" "time" apierrors "k8s.io/kubernetes/pkg/api/errors" + legacyv1 "k8s.io/kubernetes/pkg/api/v1" authorizationv1beta1 "k8s.io/kubernetes/pkg/apis/authorization/v1beta1" + rbacv1alpha1 "k8s.io/kubernetes/pkg/apis/rbac/v1alpha1" v1beta1authorization "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/authorization/v1beta1" + v1alpha1rbac "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/rbac/v1alpha1" "k8s.io/kubernetes/pkg/runtime/schema" "k8s.io/kubernetes/pkg/util/wait" ) @@ -50,6 +54,7 @@ func WaitForAuthorizationUpdate(c v1beta1authorization.SubjectAccessReviewsGette // GKE doesn't enable the SAR endpoint. Without this endpoint, we cannot determine if the policy engine // has adjusted as expected. In this case, simply wait one second and hope it's up to date if apierrors.IsNotFound(err) { + fmt.Printf("SubjectAccessReview endpoint is missing\n") time.Sleep(1 * time.Second) return true, nil } @@ -63,3 +68,45 @@ func WaitForAuthorizationUpdate(c v1beta1authorization.SubjectAccessReviewsGette }) return err } + +// BindClusterRole binds the cluster role at the cluster scope +func BindClusterRole(c v1alpha1rbac.ClusterRoleBindingsGetter, clusterRole, ns string, subjects ...rbacv1alpha1.Subject) { + // Since the namespace names are unique, we can leave this lying around so we don't have to race any caches + _, err := c.ClusterRoleBindings().Create(&rbacv1alpha1.ClusterRoleBinding{ + ObjectMeta: legacyv1.ObjectMeta{ + Name: ns + "--" + clusterRole, + }, + RoleRef: rbacv1alpha1.RoleRef{ + APIGroup: "rbac.authorization.k8s.io", + Kind: "ClusterRole", + Name: clusterRole, + }, + Subjects: subjects, + }) + + // if we failed, don't fail the entire test because it may still work. RBAC may simply be disabled. + if err != nil { + fmt.Printf("Error binding clusterrole/%s for %q for %v\n", clusterRole, ns, subjects) + } +} + +// BindClusterRoleInNamespace binds the cluster role at the namespace scope +func BindClusterRoleInNamespace(c v1alpha1rbac.RoleBindingsGetter, clusterRole, ns string, subjects ...rbacv1alpha1.Subject) { + // Since the namespace names are unique, we can leave this lying around so we don't have to race any caches + _, err := c.RoleBindings(ns).Create(&rbacv1alpha1.RoleBinding{ + ObjectMeta: legacyv1.ObjectMeta{ + Name: ns + "--" + clusterRole, + }, + RoleRef: rbacv1alpha1.RoleRef{ + APIGroup: "rbac.authorization.k8s.io", + Kind: "ClusterRole", + Name: clusterRole, + }, + Subjects: subjects, + }) + + // if we failed, don't fail the entire test because it may still work. RBAC may simply be disabled. + if err != nil { + fmt.Printf("Error binding clusterrole/%s into %q for %v\n", clusterRole, ns, subjects) + } +} diff --git a/test/e2e/ingress.go b/test/e2e/ingress.go index 011a39152de..41b35c7aabd 100644 --- a/test/e2e/ingress.go +++ b/test/e2e/ingress.go @@ -21,8 +21,6 @@ import ( "path/filepath" "time" - apierrors "k8s.io/kubernetes/pkg/api/errors" - 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" @@ -78,33 +76,10 @@ var _ = framework.KubeDescribe("Loadbalancing: L7", func() { // 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", - }, - }, - }) - if apierrors.IsForbidden(err) { - // The user is not allowed to create ClusterRoleBindings. This - // probably means that RBAC is not being used. If RBAC is being - // used, this test will probably fail later. - framework.Logf("Attempt to create ClusterRoleBinding was forbidden: %v.", err) - return - } - framework.ExpectNoError(err) + framework.BindClusterRole(jig.client.Rbac(), "cluster-admin", f.Namespace.Name, + rbacv1alpha1.Subject{Kind: rbacv1alpha1.ServiceAccountKind, Namespace: f.Namespace.Name, Name: "default"}) - err = framework.WaitForAuthorizationUpdate(jig.client.Authorization(), + err := framework.WaitForAuthorizationUpdate(jig.client.Authorization(), serviceaccount.MakeUsername(f.Namespace.Name, "default"), "", "create", schema.GroupResource{Resource: "pods"}, true) framework.ExpectNoError(err) diff --git a/test/e2e/kubectl.go b/test/e2e/kubectl.go index a2285a0d4d0..0dbbfffa9a8 100644 --- a/test/e2e/kubectl.go +++ b/test/e2e/kubectl.go @@ -46,11 +46,14 @@ import ( "k8s.io/kubernetes/pkg/api/resource" "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/controller" "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/labels" genericregistry "k8s.io/kubernetes/pkg/registry/generic/registry" + "k8s.io/kubernetes/pkg/runtime/schema" + "k8s.io/kubernetes/pkg/serviceaccount" uexec "k8s.io/kubernetes/pkg/util/exec" utilnet "k8s.io/kubernetes/pkg/util/net" "k8s.io/kubernetes/pkg/util/uuid" @@ -566,6 +569,16 @@ var _ = framework.KubeDescribe("Kubectl client", func() { }) It("should handle in-cluster config", func() { + By("adding rbac permissions") + // grant the view permission widely to allow inspection of the `invalid` namespace. + framework.BindClusterRole(f.ClientSet.Rbac(), "view", f.Namespace.Name, + rbacv1alpha1.Subject{Kind: rbacv1alpha1.ServiceAccountKind, Namespace: f.Namespace.Name, Name: "default"}) + + err := framework.WaitForAuthorizationUpdate(f.ClientSet.Authorization(), + serviceaccount.MakeUsername(f.Namespace.Name, "default"), + f.Namespace.Name, "list", schema.GroupResource{Resource: "pods"}, true) + framework.ExpectNoError(err) + By("overriding icc with values provided by flags") kubectlPath := framework.TestContext.KubectlPath @@ -580,7 +593,7 @@ var _ = framework.KubeDescribe("Kubectl client", func() { } By("trying to use kubectl with invalid token") - _, err := framework.RunHostCmd(ns, simplePodName, "/kubectl get pods --token=invalid --v=7 2>&1") + _, err = framework.RunHostCmd(ns, simplePodName, "/kubectl get pods --token=invalid --v=7 2>&1") framework.Logf("got err %v", err) Expect(err).To(HaveOccurred()) Expect(err).To(ContainSubstring("Using in-cluster namespace")) @@ -604,7 +617,6 @@ var _ = framework.KubeDescribe("Kubectl client", func() { if matched, _ := regexp.MatchString(fmt.Sprintf("GET http[s]?://%s:%s/api/v1/namespaces/invalid/pods", inClusterHost, inClusterPort), output); !matched { framework.Failf("Unexpected kubectl exec output: ", output) } - }) }) diff --git a/test/e2e/node_problem_detector.go b/test/e2e/node_problem_detector.go index 60f9a1d8537..052a308ca82 100644 --- a/test/e2e/node_problem_detector.go +++ b/test/e2e/node_problem_detector.go @@ -23,9 +23,7 @@ import ( "time" "k8s.io/kubernetes/pkg/api" - apierrors "k8s.io/kubernetes/pkg/api/errors" "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" @@ -65,33 +63,10 @@ var _ = framework.KubeDescribe("NodeProblemDetector", 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", - }, - }, - }) - if apierrors.IsForbidden(err) { - // The user is not allowed to create ClusterRoleBindings. This - // probably means that RBAC is not being used. If RBAC is being - // used, this test will probably fail later. - framework.Logf("Attempt to create ClusterRoleBinding was forbidden: %v.", err) - return - } - framework.ExpectNoError(err) + framework.BindClusterRole(f.ClientSet.Rbac(), "cluster-admin", f.Namespace.Name, + rbacv1alpha1.Subject{Kind: rbacv1alpha1.ServiceAccountKind, Namespace: f.Namespace.Name, Name: "default"}) - err = framework.WaitForAuthorizationUpdate(f.ClientSet.Authorization(), + err := framework.WaitForAuthorizationUpdate(f.ClientSet.Authorization(), serviceaccount.MakeUsername(f.Namespace.Name, "default"), "", "create", schema.GroupResource{Resource: "pods"}, true) framework.ExpectNoError(err) diff --git a/test/e2e/pre_stop.go b/test/e2e/pre_stop.go index 11a41e72cca..ecbc8ee666c 100644 --- a/test/e2e/pre_stop.go +++ b/test/e2e/pre_stop.go @@ -21,9 +21,7 @@ import ( "fmt" "time" - apierrors "k8s.io/kubernetes/pkg/api/errors" "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" @@ -171,33 +169,10 @@ var _ = framework.KubeDescribe("PreStop", func() { 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", - }, - }, - }) - if apierrors.IsForbidden(err) { - // The user is not allowed to create ClusterRoleBindings. This - // probably means that RBAC is not being used. If RBAC is being - // used, this test will probably fail later. - framework.Logf("Attempt to create ClusterRoleBinding was forbidden: %v.", err) - return - } - framework.ExpectNoError(err) + framework.BindClusterRole(f.ClientSet.Rbac(), "cluster-admin", f.Namespace.Name, + rbacv1alpha1.Subject{Kind: rbacv1alpha1.ServiceAccountKind, Namespace: f.Namespace.Name, Name: "default"}) - err = framework.WaitForAuthorizationUpdate(f.ClientSet.Authorization(), + err := framework.WaitForAuthorizationUpdate(f.ClientSet.Authorization(), serviceaccount.MakeUsername(f.Namespace.Name, "default"), "", "create", schema.GroupResource{Resource: "pods"}, true) framework.ExpectNoError(err)