diff --git a/pkg/kubectl/cmd/create_clusterrole_test.go b/pkg/kubectl/cmd/create_clusterrole_test.go index 750c12acbc9d3..eff9a9f63430a 100644 --- a/pkg/kubectl/cmd/create_clusterrole_test.go +++ b/pkg/kubectl/cmd/create_clusterrole_test.go @@ -59,6 +59,7 @@ func TestCreateClusterRole(t *testing.T) { tests := map[string]struct { verbs string resources string + nonResourceURL string resourceNames string expectedClusterRole *rbac.ClusterRole }{ @@ -102,6 +103,43 @@ func TestCreateClusterRole(t *testing.T) { }, }, }, + "test-non-resource-url": { + verbs: "get", + nonResourceURL: "/logs/,/healthz", + expectedClusterRole: &rbac.ClusterRole{ + ObjectMeta: v1.ObjectMeta{ + Name: clusterRoleName, + }, + Rules: []rbac.PolicyRule{ + { + Verbs: []string{"get"}, + NonResourceURLs: []string{"/logs/", "/healthz"}, + }, + }, + }, + }, + "test-resource-and-non-resource-url": { + verbs: "get", + nonResourceURL: "/logs/,/healthz", + resources: "pods", + expectedClusterRole: &rbac.ClusterRole{ + ObjectMeta: v1.ObjectMeta{ + Name: clusterRoleName, + }, + Rules: []rbac.PolicyRule{ + { + Verbs: []string{"get"}, + Resources: []string{"pods"}, + APIGroups: []string{""}, + ResourceNames: []string{}, + }, + { + Verbs: []string{"get"}, + NonResourceURLs: []string{"/logs/", "/healthz"}, + }, + }, + }, + }, } for name, test := range tests { @@ -111,6 +149,7 @@ func TestCreateClusterRole(t *testing.T) { cmd.Flags().Set("output", "object") cmd.Flags().Set("verb", test.verbs) cmd.Flags().Set("resource", test.resources) + cmd.Flags().Set("non-resource-url", test.nonResourceURL) if test.resourceNames != "" { cmd.Flags().Set("resource-name", test.resourceNames) } @@ -120,3 +159,254 @@ func TestCreateClusterRole(t *testing.T) { } } } + +func TestClusterRoleValidate(t *testing.T) { + f, tf, _, _ := cmdtesting.NewAPIFactory() + tf.Printer = &testPrinter{} + tf.Namespace = "test" + + tests := map[string]struct { + clusterRoleOptions *CreateClusterRoleOptions + expectErr bool + }{ + "test-missing-name": { + clusterRoleOptions: &CreateClusterRoleOptions{ + CreateRoleOptions: &CreateRoleOptions{}, + }, + expectErr: true, + }, + "test-missing-verb": { + clusterRoleOptions: &CreateClusterRoleOptions{ + CreateRoleOptions: &CreateRoleOptions{ + Name: "my-clusterrole", + }, + }, + expectErr: true, + }, + "test-missing-resource": { + clusterRoleOptions: &CreateClusterRoleOptions{ + CreateRoleOptions: &CreateRoleOptions{ + Name: "my-clusterrole", + Verbs: []string{"get"}, + }, + }, + expectErr: true, + }, + "test-missing-resource-existing-apigroup": { + clusterRoleOptions: &CreateClusterRoleOptions{ + CreateRoleOptions: &CreateRoleOptions{ + Name: "my-clusterrole", + Verbs: []string{"get"}, + Resources: []ResourceOptions{ + { + Group: "extensions", + }, + }, + }, + }, + expectErr: true, + }, + "test-missing-resource-existing-subresource": { + clusterRoleOptions: &CreateClusterRoleOptions{ + CreateRoleOptions: &CreateRoleOptions{ + Name: "my-clusterrole", + Verbs: []string{"get"}, + Resources: []ResourceOptions{ + { + SubResource: "scale", + }, + }, + }, + }, + expectErr: true, + }, + "test-invalid-verb": { + clusterRoleOptions: &CreateClusterRoleOptions{ + CreateRoleOptions: &CreateRoleOptions{ + Name: "my-clusterrole", + Verbs: []string{"invalid-verb"}, + Resources: []ResourceOptions{ + { + Resource: "pods", + }, + }, + }, + }, + expectErr: true, + }, + "test-nonresource-verb": { + clusterRoleOptions: &CreateClusterRoleOptions{ + CreateRoleOptions: &CreateRoleOptions{ + Name: "my-clusterrole", + Verbs: []string{"post"}, + Resources: []ResourceOptions{ + { + Resource: "pods", + }, + }, + }, + }, + expectErr: true, + }, + "test-special-verb": { + clusterRoleOptions: &CreateClusterRoleOptions{ + CreateRoleOptions: &CreateRoleOptions{ + Name: "my-clusterrole", + Verbs: []string{"use"}, + Resources: []ResourceOptions{ + { + Resource: "pods", + }, + }, + }, + }, + expectErr: true, + }, + "test-mix-verbs": { + clusterRoleOptions: &CreateClusterRoleOptions{ + CreateRoleOptions: &CreateRoleOptions{ + Name: "my-clusterrole", + Verbs: []string{"impersonate", "use"}, + Resources: []ResourceOptions{ + { + Resource: "userextras", + SubResource: "scopes", + }, + }, + }, + }, + expectErr: true, + }, + "test-special-verb-with-wrong-apigroup": { + clusterRoleOptions: &CreateClusterRoleOptions{ + CreateRoleOptions: &CreateRoleOptions{ + Name: "my-clusterrole", + Verbs: []string{"impersonate"}, + Resources: []ResourceOptions{ + { + Resource: "userextras", + SubResource: "scopes", + Group: "extensions", + }, + }, + }, + }, + expectErr: true, + }, + "test-invalid-resource": { + clusterRoleOptions: &CreateClusterRoleOptions{ + CreateRoleOptions: &CreateRoleOptions{ + Name: "my-clusterrole", + Verbs: []string{"get"}, + Resources: []ResourceOptions{ + { + Resource: "invalid-resource", + }, + }, + }, + }, + expectErr: true, + }, + "test-resource-name-with-multiple-resources": { + clusterRoleOptions: &CreateClusterRoleOptions{ + CreateRoleOptions: &CreateRoleOptions{ + Name: "my-clusterrole", + Verbs: []string{"get"}, + Resources: []ResourceOptions{ + { + Resource: "pods", + }, + { + Resource: "deployments", + Group: "extensions", + }, + }, + }, + }, + expectErr: false, + }, + "test-valid-case": { + clusterRoleOptions: &CreateClusterRoleOptions{ + CreateRoleOptions: &CreateRoleOptions{ + Name: "role-binder", + Verbs: []string{"get", "list", "bind"}, + Resources: []ResourceOptions{ + { + Resource: "roles", + Group: "rbac.authorization.k8s.io", + }, + }, + }, + }, + expectErr: false, + }, + "test-valid-case-with-subresource": { + clusterRoleOptions: &CreateClusterRoleOptions{ + CreateRoleOptions: &CreateRoleOptions{ + Name: "my-clusterrole", + Verbs: []string{"get", "list"}, + Resources: []ResourceOptions{ + { + Resource: "replicasets", + SubResource: "scale", + }, + }, + }, + }, + expectErr: false, + }, + "test-valid-case-with-additional-resource": { + clusterRoleOptions: &CreateClusterRoleOptions{ + CreateRoleOptions: &CreateRoleOptions{ + Name: "my-clusterrole", + Verbs: []string{"impersonate"}, + Resources: []ResourceOptions{ + { + Resource: "userextras", + SubResource: "scopes", + Group: "authentication.k8s.io", + }, + }, + }, + }, + expectErr: false, + }, + "test-invalid-verb-for-non-resource-url": { + clusterRoleOptions: &CreateClusterRoleOptions{ + CreateRoleOptions: &CreateRoleOptions{ + Name: "my-clusterrole", + Verbs: []string{"create"}, + }, + NonResourceURLs: []string{"/logs/"}, + }, + expectErr: true, + }, + "test-resource-and-non-resource-url-specified-together": { + clusterRoleOptions: &CreateClusterRoleOptions{ + CreateRoleOptions: &CreateRoleOptions{ + Name: "my-clusterrole", + Verbs: []string{"get"}, + Resources: []ResourceOptions{ + { + Resource: "replicasets", + SubResource: "scale", + }, + }, + }, + NonResourceURLs: []string{"/logs/"}, + }, + expectErr: false, + }, + } + + for name, test := range tests { + test.clusterRoleOptions.Mapper, _ = f.Object() + err := test.clusterRoleOptions.Validate() + if test.expectErr && err == nil { + t.Errorf("%s: expect error happens, but validate passes.", name) + } + if !test.expectErr && err != nil { + t.Errorf("%s: unexpected error: %v", name, err) + } + } +}