From 8cf96d6a8ff7e86b09e740036fe4e65c68a4ed49 Mon Sep 17 00:00:00 2001 From: Homaja Marisetty Date: Tue, 3 Sep 2024 14:32:32 -0400 Subject: [PATCH] chore(RHTAPWATCH-1237): Reorganize workspace-manager test suites Since functional tests BeforeSuite runs all the tests, separate package for unit and functional tests. Jira-Url: https://issues.redhat.com/browse/RHTAPWATCH-1237 Signed-off-by: Homaja Marisetty --- cmd/main.go | 11 +- cmd/main_test.go | 428 ++++++++++++++++++++++------------------------- 2 files changed, 202 insertions(+), 237 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 25333c6..b769175 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -45,9 +45,11 @@ func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) } +type NamespaceWithAccess func(e *echo.Echo, c echo.Context, authCl authorizationv1Client.AuthorizationV1Interface, allNamespaces []core.Namespace) ([]core.Namespace, error) + // Given all relevant user namespaces, return all workspaces for the calling user func getWorkspacesWithAccess( - e *echo.Echo, c echo.Context, allNamespaces []core.Namespace, + e *echo.Echo, c echo.Context, allNamespaces []core.Namespace, getNamespacesWithAccess NamespaceWithAccess, ) (crt.WorkspaceList, error) { cfg, err := config.GetConfig() if err != nil { @@ -103,7 +105,7 @@ func getWorkspacesWithAccess( // Get all the namespace in which the calling user is allowed to perform enough actions // to allow workspace access -func getNamespacesWithAccess( +var getNamespacesWithAccess = func( e *echo.Echo, c echo.Context, authCl authorizationv1Client.AuthorizationV1Interface, @@ -232,7 +234,7 @@ func main() { if err != nil { e.Logger.Fatal(err) } - workspaces, err := getWorkspacesWithAccess(e, c, userNamespaces) + workspaces, err := getWorkspacesWithAccess(e, c, userNamespaces, getNamespacesWithAccess) if err != nil { e.Logger.Fatal(err) } @@ -248,11 +250,10 @@ func main() { if err != nil { e.Logger.Fatal(err) } - workspaces, err := getWorkspacesWithAccess(e, c, userNamespaces) + workspaces, err := getWorkspacesWithAccess(e, c, userNamespaces, getNamespacesWithAccess) if err != nil { e.Logger.Fatal(err) } - wsParam := c.Param("ws") for _, ws := range workspaces.Items { if ws.Name == wsParam { diff --git a/cmd/main_test.go b/cmd/main_test.go index 940fd3e..60d0ef7 100644 --- a/cmd/main_test.go +++ b/cmd/main_test.go @@ -16,6 +16,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/selection" "k8s.io/client-go/kubernetes" + authorizationv1Client "k8s.io/client-go/kubernetes/typed/authorization/v1" "context" "net/http/httptest" @@ -110,38 +111,6 @@ func createNamespace(k8sClient client.Client, name string) (k8sapi.Namespace, er return *namespaced, nil } -func deleteRole(k8sClient client.Client, nsName string, roleName string) { - role := &rbacv1.Role{ - ObjectMeta: metav1.ObjectMeta{ - Name: roleName, - Namespace: nsName, - }, - } - err := k8sClient.Delete(context.Background(), role) - Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Error deleting the role %s in namespace %s: %v\n", roleName, nsName, err)) -} - -func deleteRoleBinding(k8sClient client.Client, nsName string, roleBindingName string) { - roleBinding := &rbacv1.RoleBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: roleBindingName, - Namespace: nsName, - }, - } - err := k8sClient.Delete(context.Background(), roleBinding) - Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Error deleting the role binding %s in namespace %s: %v\n", roleBindingName, nsName, err)) -} - -func deleteNamespace(k8sClient client.Client, nsName string) { - ns := &k8sapi.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: nsName, - }, - } - err := k8sClient.Delete(context.Background(), ns) - Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Error deleting the namespace: %s: %v\n", nsName, err)) -} - func performHTTPGetCall(url string, header HTTPheader) (*HTTPResponse, error) { req, err := http.NewRequest("GET", url, nil) if err != nil { @@ -181,7 +150,6 @@ var _ = Describe("Signup endpoint", func() { url := "http://localhost:5000/api/v1/signup" expectedCode := http.StatusOK expectedBody := `{"status":{"ready":true,"reason":"SignedUp"}}` - resp, err := performHTTPGetCall(url, HTTPheader{}) Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Unexpected error testing the \"%s\" endpoint: %v", url, err)) Expect(resp.StatusCode).To(Equal(expectedCode)) @@ -198,27 +166,27 @@ var _ = DescribeTable("Workspace endpoint", func(header HTTPheader, expectedCode Expect(strings.TrimSpace(expectedBody)).To(Equal(strings.TrimSpace(resp.Body))) }, Entry( - "Calling the workspace endpoint for user1 responds only with the 'test-tenant' workspace info", - HTTPheader{"X-Email", "user1@konflux.dev"}, + "Calling the workspace endpoint for funcuser1 responds only with the 'func-test-tenant' workspace info", + HTTPheader{"X-Email", "funcuser1@konflux.dev"}, http.StatusOK, `{"kind":"WorkspaceList","apiVersion":"toolchain.dev.openshift.com/v1alpha1","metadata":{},`+ `"items":[{"kind":"Workspace","apiVersion":"toolchain.dev.openshift.com/v1alpha1",`+ - `"metadata":{"name":"test-tenant","creationTimestamp":null},"status":`+ - `{"namespaces":[{"name":"test-tenant","type":"default"}]}}]}`), + `"metadata":{"name":"func-test-tenant","creationTimestamp":null},"status":`+ + `{"namespaces":[{"name":"func-test-tenant","type":"default"}]}}]}`), Entry( - "Workspace endpoint for user2 responds with 2 namespaces info", - HTTPheader{"X-Email", "user2@konflux.dev"}, + "Workspace endpoint for funcuser2 responds with 2 namespaces info", + HTTPheader{"X-Email", "funcuser2@konflux.dev"}, http.StatusOK, `{"kind":"WorkspaceList","apiVersion":"toolchain.dev.openshift.com/v1alpha1","metadata":{},`+ `"items":[{"kind":"Workspace","apiVersion":"toolchain.dev.openshift.com/v1alpha1",`+ - `"metadata":{"name":"test-tenant","creationTimestamp":null},"status":{"namespaces":`+ - `[{"name":"test-tenant","type":"default"}]}},{"kind":"Workspace","apiVersion":`+ - `"toolchain.dev.openshift.com/v1alpha1","metadata":{"name":"test-tenant-2",`+ - `"creationTimestamp":null},"status":{"namespaces":[{"name":"test-tenant-2",`+ + `"metadata":{"name":"func-test-tenant","creationTimestamp":null},"status":{"namespaces":`+ + `[{"name":"func-test-tenant","type":"default"}]}},{"kind":"Workspace","apiVersion":`+ + `"toolchain.dev.openshift.com/v1alpha1","metadata":{"name":"func-test-tenant-2",`+ + `"creationTimestamp":null},"status":{"namespaces":[{"name":"func-test-tenant-2",`+ `"type":"default"}]}}]}`), Entry( - "Workspace endpoint for user3 responds with no namespaces", - HTTPheader{"X-Email", "user3@konflux.dev"}, + "Workspace endpoint for funcuser3 responds with no namespaces", + HTTPheader{"X-Email", "funcuser3@konflux.dev"}, http.StatusOK, `{"kind":"WorkspaceList","apiVersion":"toolchain.dev.openshift.com/v1alpha1","metadata":{},"items":null}`), Entry( @@ -236,17 +204,17 @@ var _ = DescribeTable("Specific workspace endpoint", func(endpoint string, heade Expect(strings.TrimSpace(expectedBody)).To(Equal(strings.TrimSpace(resp.Body))) }, Entry( - "Calling the workspace endpoint for the test-tenant workspace for user2", - "test-tenant", - HTTPheader{"X-Email", "user2@konflux.dev"}, + "Calling the workspace endpoint for the func-test-tenant workspace for funcuser2", + "func-test-tenant", + HTTPheader{"X-Email", "funcuser2@konflux.dev"}, http.StatusOK, `{"kind":"Workspace","apiVersion":"toolchain.dev.openshift.com/v1alpha1","metadata":`+ - `{"name":"test-tenant","creationTimestamp":null},"status":{"namespaces":`+ - `[{"name":"test-tenant","type":"default"}]}}`), + `{"name":"func-test-tenant","creationTimestamp":null},"status":{"namespaces":`+ + `[{"name":"func-test-tenant","type":"default"}]}}`), Entry( - "Specific workspace endpoint for test-tenant-2 for user1 only", - "test-tenant-2", - HTTPheader{"X-Email", "user1@konflux.dev"}, + "Specific workspace endpoint for func-test-tenant-2 for funcuser1 only", + "func-test-tenant-2", + HTTPheader{"X-Email", "funcuser1@konflux.dev"}, 404, `{"message":"Not Found"}`), ) @@ -263,18 +231,18 @@ var _ = BeforeSuite(func() { serverProcess, serverCancelFunc = utils.CreateWorkspaceManagerServer("main.go", nil, "") utils.WaitForWorkspaceManagerServerToServe() - user1 := "user1@konflux.dev" - user2 := "user2@konflux.dev" - namespaceNames := []string{"test-tenant", "test-tenant-2", "test-tenant-3"} + user1 := "funcuser1@konflux.dev" + user2 := "funcuser2@konflux.dev" + namespaceNames := []string{"func-test-tenant", "func-test-tenant-2", "func-test-tenant-3"} for _, name := range namespaceNames { _, err := createNamespace(k8sClient, name) Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Error while creating the namespace %s: %v", name, err)) } - createRole(k8sClient, "test-tenant", "namespace-access", []string{"create", "list", "watch", "delete"}) - createRole(k8sClient, "test-tenant-2", "namespace-access-2", []string{"create", "list", "watch", "delete"}) - createRoleBinding(k8sClient, "namespace-access-user-binding", "test-tenant", user1, "namespace-access") - createRoleBinding(k8sClient, "namespace-access-user-binding-2", "test-tenant", user2, "namespace-access") - createRoleBinding(k8sClient, "namespace-access-user-binding-3", "test-tenant-2", user2, "namespace-access-2") + createRole(k8sClient, "func-test-tenant", "func-namespace-access", []string{"create", "list", "watch", "delete"}) + createRole(k8sClient, "func-test-tenant-2", "func-namespace-access-2", []string{"create", "list", "watch", "delete"}) + createRoleBinding(k8sClient, "func-namespace-access-user-binding", "func-test-tenant", user1, "func-namespace-access") + createRoleBinding(k8sClient, "func-namespace-access-user-binding-2", "func-test-tenant", user2, "func-namespace-access") + createRoleBinding(k8sClient, "func-namespace-access-user-binding-3", "func-test-tenant-2", user2, "func-namespace-access-2") }) var _ = AfterSuite(func() { @@ -282,53 +250,96 @@ var _ = AfterSuite(func() { utils.StopEnvTest(testEnv) }) -var _ = DescribeTable("TestRunAccessCheck", func(user string, namespace string, resource string, verb string, expectedResult bool) { - cfg, _ := config.GetConfig() - clientset, _ := kubernetes.NewForConfig(cfg) - authCl := clientset.AuthorizationV1() +var _ = Describe("TestRunAccessCheck", func() { + var authCl authorizationv1Client.AuthorizationV1Interface - boolresult, err := runAccessCheck(authCl, user, namespace, "appstudio.redhat.com", resource, verb) - Expect(boolresult).To(Equal(expectedResult)) - Expect(err).NotTo(HaveOccurred(), "Unexpected error testing RunAccessCheck") -}, - Entry( - "A user that has access to the resource should return true (user2 has permission to 'create' on test-tenant-1)", - "user2@konflux.dev", - "test-tenant", - "applications", - "create", - true), - Entry( - "A user that does not have any premissions on the namespace should return false (user1 doesn't have access to test-tenant-2)", - "user1@konflux.dev", - "test-tenant-2", - "applications", - "create", - false), - Entry( - "A user that does not have the permissions to perform the specific action on the namespace should return false (user1 doesn't have permission to 'patch' on test-tenant-1)", - "user1@konflux.dev", - "test-tenant-1", - "applications", - "patch", - false), -) + BeforeEach(func() { + // Set up Kubernetes client + cfg, err := config.GetConfig() + Expect(err).NotTo(HaveOccurred(), "Unexpected error getting Kubernetes config") + clientset, err := kubernetes.NewForConfig(cfg) + Expect(err).NotTo(HaveOccurred(), "Unexpected error creating Kubernetes clientset") + authCl = clientset.AuthorizationV1() + }) + + Context("When a user has access to the resource", func() { + It("should return true for a user with 'create' permission on test-tenant", func() { + user := "user3@konflux.dev" + namespace := "test-tenant" + resource := "applications" + verb := "create" + expectedResult := true + _, err := createNamespace(k8sClient, namespace) + Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Error while creating the namespace %s: %v", namespace, err)) + createRole(k8sClient, "test-tenant", "namespace-access", []string{"create", "list", "watch", "delete"}) + createRoleBinding(k8sClient, "namespace-access-user-binding", "test-tenant", user, "namespace-access") + boolresult, err := runAccessCheck(authCl, user, namespace, "appstudio.redhat.com", resource, verb) + Expect(boolresult).To(Equal(expectedResult)) + Expect(err).NotTo(HaveOccurred(), "Unexpected error testing RunAccessCheck") + }) + }) + + Context("When a user does not have any permissions on the namespace", func() { + It("should return false for a user without access to test-tenant-2", func() { + user := "user4@konflux.dev" + namespace := "test-tenant-2" + resource := "applications" + verb := "create" + expectedResult := false + _, err := createNamespace(k8sClient, namespace) + Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Error while creating the namespace %s: %v", namespace, err)) + + createRole(k8sClient, "test-tenant-2", "namespace-access-2", []string{"create", "list", "watch", "delete"}) + createRoleBinding(k8sClient, "namespace-access-user-binding-3", "test-tenant-2", user, "namespace-access-2") + boolresult, err := runAccessCheck(authCl, "user3@konflux.dev", namespace, "appstudio.redhat.com", resource, verb) + Expect(boolresult).To(Equal(expectedResult)) + Expect(err).NotTo(HaveOccurred(), "Unexpected error testing RunAccessCheck") + }) + }) + + Context("When a user lacks the specific action permission on the namespace", func() { + It("should return false for a user without 'patch' permission on test-tenant-1", func() { + user := "user5@konflux.dev" + namespace := "test-tenant-1" + resource := "applications" + verb := "patch" + expectedResult := false + _, err := createNamespace(k8sClient, namespace) + Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Error while creating the namespace %s: %v", namespace, err)) + createRole(k8sClient, "test-tenant-1", "namespace-access", []string{"create", "list", "watch", "delete"}) + createRoleBinding(k8sClient, "namespace-access-user-binding", "test-tenant-1", user, "namespace-access") + boolresult, err := runAccessCheck(authCl, user, namespace, "appstudio.redhat.com", resource, verb) + Expect(boolresult).To(Equal(expectedResult)) + Expect(err).NotTo(HaveOccurred(), "Unexpected error testing RunAccessCheck") + }) + }) +}) + +var _ = Describe("GetWorkspacesWithAccess querying for workspaces with access", func() { + var ( + allNamespaces []k8sapi.Namespace + expectedWorkspaces []crt.Workspace + e *echo.Echo + c echo.Context + gv string + ) + + BeforeEach(func() { + e = echo.New() + req := httptest.NewRequest(http.MethodGet, "/", nil) + rec := httptest.NewRecorder() + c = e.NewContext(req, rec) + c.Request().Header.Set("X-Email", "user@konflux.dev") + }) -var _ = DescribeTable("GetWorkspacesWithAccess querying for workspaces with access", func(gv string, allNamespaces []k8sapi.Namespace, expectedWorkspaces []crt.Workspace) { - e := echo.New() - c := e.NewContext(nil, nil) Context("When workspace test-tenant's namespaces has all the necessary permissions", func() { namespaceNames := []string{"ws-test-tenant-1", "ws-test-tenant-2"} - roleNames := []string{"ws-namespace-access-1", "ws-namespace-access-2"} - roleBindings := []string{"ws-namespace-access-user-binding-1", "ws-namespace-access-user-binding-2"} BeforeEach(func() { - gv = "v1alpha1" - for i, name := range namespaceNames { + gv = crt.GroupVersion.String() + for _, name := range namespaceNames { ns, err := createNamespace(k8sClient, name) Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Error while creating the namespace %s: %v", name, err)) allNamespaces = append(allNamespaces, ns) - createRole(k8sClient, name, roleNames[i], []string{"create", "list", "watch", "delete"}) - createRoleBinding(k8sClient, roleBindings[i], name, "user1@konflux.dev", roleNames[i]) } expectedWorkspaces = []crt.Workspace{ { @@ -367,33 +378,36 @@ var _ = DescribeTable("GetWorkspacesWithAccess querying for workspaces with acce }, } }) - It("Should return a WorkspaceList with test-tenant workspace and both namespaces in it", func() { - actualWorkspaces, err := getWorkspacesWithAccess(e, c, allNamespaces) + mockNamespaceWithAccess := func(e *echo.Echo, c echo.Context, authCl authorizationv1Client.AuthorizationV1Interface, allNamespaces []k8sapi.Namespace) ([]k8sapi.Namespace, error) { + return []k8sapi.Namespace{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "ws-test-tenant-1", + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "ws-test-tenant-2", + }, + }, + }, nil + } + actualWorkspaces, err := getWorkspacesWithAccess(e, c, allNamespaces, mockNamespaceWithAccess) Expect(actualWorkspaces.Items).To(Equal(expectedWorkspaces)) Expect(err).NotTo(HaveOccurred(), "Unexpected error testing GetWorkspacesWithAccess") }) - - AfterEach(func() { - for i, name := range namespaceNames { - deleteRoleBinding(k8sClient, name, roleBindings[i]) - deleteRole(k8sClient, name, roleNames[i]) - deleteNamespace(k8sClient, name) - } - }) }) - Context("When workspace with only test-tenant namespace has all the necessary permissions", func() { - namespaceNames := []string{"ws-test-tenant-1", "ws-test-tenant-2"} + Context("When workspace with only ws-test-tenant-3 namespace has all the necessary permissions", func() { + namespaceNames := []string{"ws-test-tenant-3", "ws-test-tenant-4"} BeforeEach(func() { - gv = "v1alpha1" + gv = crt.GroupVersion.String() for _, name := range namespaceNames { ns, err := createNamespace(k8sClient, name) Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Error while creating the namespace %s: %v", name, err)) allNamespaces = append(allNamespaces, ns) } - createRole(k8sClient, "ws-test-tenant-1", "ws-namespace-access-1", []string{"create", "list", "watch", "delete"}) - createRoleBinding(k8sClient, "ws-namespace-access-user-binding-1", "ws-test-tenant-1", "user1@konflux.dev", "ws-namespace-access-1") expectedWorkspaces = []crt.Workspace{ { TypeMeta: metav1.TypeMeta{ @@ -401,12 +415,12 @@ var _ = DescribeTable("GetWorkspacesWithAccess querying for workspaces with acce APIVersion: gv, }, ObjectMeta: metav1.ObjectMeta{ - Name: "ws-test-tenant-1", + Name: "ws-test-tenant-3", }, Status: crt.WorkspaceStatus{ Namespaces: []crt.SpaceNamespace{ { - Name: "ws-test-tenant-1", + Name: "ws-test-tenant-3", Type: "default", }, }, @@ -414,69 +428,70 @@ var _ = DescribeTable("GetWorkspacesWithAccess querying for workspaces with acce }, } }) - It("Should return a WorkspaceList with test-tenant workspace and only test-tenant namespace in it", func() { - actualWorkspaces, err := getWorkspacesWithAccess(e, c, allNamespaces) + mockNamespaceWithAccess := func(e *echo.Echo, c echo.Context, authCl authorizationv1Client.AuthorizationV1Interface, allNamespaces []k8sapi.Namespace) ([]k8sapi.Namespace, error) { + return []k8sapi.Namespace{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "ws-test-tenant-3", + }, + }, + }, nil + } + actualWorkspaces, err := getWorkspacesWithAccess(e, c, allNamespaces, mockNamespaceWithAccess) Expect(actualWorkspaces.Items).To(Equal(expectedWorkspaces)) Expect(err).NotTo(HaveOccurred(), "Unexpected error testing GetWorkspacesWithAccess") }) - - AfterEach(func() { - deleteRoleBinding(k8sClient, "ws-test-tenant-1", "ws-namespace-access-user-binding-1") - deleteRole(k8sClient, "ws-test-tenant-1", "ws-namespace-access-1") - for _, name := range namespaceNames { - deleteNamespace(k8sClient, name) - } - }) }) Context("When no workspaces has all the necessary permissions", func() { - namespaceNames := []string{"ws-test-tenant-1", "ws-test-tenant-2"} + namespaceNames := []string{"ws-test-tenant-5", "ws-test-tenant-6"} BeforeEach(func() { - gv = "v1alpha1" for _, name := range namespaceNames { ns, err := createNamespace(k8sClient, name) Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Error while creating the namespace %s: %v", name, err)) allNamespaces = append(allNamespaces, ns) } - createRole(k8sClient, "ws-test-tenant-1", "ws-namespace-access-1", []string{"create", "list"}) - createRoleBinding(k8sClient, "ws-namespace-access-user-binding-1", "ws-test-tenant-1", "user1@konflux.dev", "ws-namespace-access-1") - expectedWorkspaces = []crt.Workspace{} }) - It("Should return a empty WorkspaceList", func() { - actualWorkspaces, err := getWorkspacesWithAccess(e, c, allNamespaces) - Expect(actualWorkspaces.Items).To(Equal(expectedWorkspaces)) - Expect(err).NotTo(HaveOccurred(), "Unexpected error testing GetWorkspacesWithAccess") - }) - - AfterEach(func() { - deleteRoleBinding(k8sClient, "ws-test-tenant-1", "ws-namespace-access-user-binding-1") - deleteRole(k8sClient, "ws-test-tenant-1", "ws-namespace-access-1") - for _, name := range namespaceNames { - deleteNamespace(k8sClient, name) + mockNamespaceWithAccess := func(e *echo.Echo, c echo.Context, authCl authorizationv1Client.AuthorizationV1Interface, allNamespaces []k8sapi.Namespace) ([]k8sapi.Namespace, error) { + return []k8sapi.Namespace{}, nil } + actualWorkspaces, err := getWorkspacesWithAccess(e, c, allNamespaces, mockNamespaceWithAccess) + Expect(actualWorkspaces.Items).To(BeEmpty()) + Expect(err).NotTo(HaveOccurred(), "Unexpected error testing GetWorkspacesWithAccess") }) }) }) -var _ = DescribeTable("TestGetNamespacesWithAccess", func(allNamespaces []k8sapi.Namespace, - expectedNs []k8sapi.Namespace, actualNs []k8sapi.Namespace, err error) { - e := echo.New() - cfg, _ := config.GetConfig() - clientset, _ := kubernetes.NewForConfig(cfg) - req := httptest.NewRequest(http.MethodGet, "/", nil) - rec := httptest.NewRecorder() - c := e.NewContext(req, rec) - c.Request().Header.Set("X-Email", "user1@konflux.dev") - authCl := clientset.AuthorizationV1() - - JustBeforeEach(func() { - actualNs, err = getNamespacesWithAccess(e, c, authCl, allNamespaces) +var _ = Describe("TestGetNamespacesWithAccess", func() { + var ( + allNamespaces, actualNs, expectedNs []k8sapi.Namespace + err error + mappings []NamespaceRoleBinding + e *echo.Echo + authCl authorizationv1Client.AuthorizationV1Interface + c echo.Context + ) + + BeforeEach(func() { + e = echo.New() + cfg, err := config.GetConfig() + Expect(err).NotTo(HaveOccurred(), "Error getting Kubernetes config") + + clientset, err := kubernetes.NewForConfig(cfg) + Expect(err).NotTo(HaveOccurred(), "Error creating Kubernetes client") + + authCl = clientset.AuthorizationV1() + + req := httptest.NewRequest(http.MethodGet, "/", nil) + rec := httptest.NewRecorder() + c = e.NewContext(req, rec) + c.Request().Header.Set("X-Email", "user@konflux.dev") }) - Context("When all the namespaces have all the necessary permissions like create, list, watch and delete", func() { - mappings := []NamespaceRoleBinding{ + Context("When all the namespaces have the necessary permissions", func() { + mappings = []NamespaceRoleBinding{ { Namespace: "ns-test-tenant-1", Role: "ns-namespace-access-1", @@ -491,94 +506,58 @@ var _ = DescribeTable("TestGetNamespacesWithAccess", func(allNamespaces []k8sapi BeforeEach(func() { for _, name := range mappings { ns, err := createNamespace(k8sClient, name.Namespace) - Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Error while creating the namespace %s: %v", name.Namespace, err)) + Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Error while creating the namespace %s", name.Namespace)) allNamespaces = append(allNamespaces, ns) createRole(k8sClient, name.Namespace, name.Role, []string{"create", "list", "watch", "delete"}) - createRoleBinding(k8sClient, name.RoleBinding, name.Namespace, "user1@konflux.dev", name.Role) + createRoleBinding(k8sClient, name.RoleBinding, name.Namespace, "user@konflux.dev", name.Role) } - expectedNs = allNamespaces }) It("returns all namespaces in the list", func() { - Expect(actualNs).To(Equal(expectedNs)) + actualNs, err = getNamespacesWithAccess(e, c, authCl, allNamespaces) + Expect(actualNs).To(Equal(allNamespaces)) Expect(err).NotTo(HaveOccurred(), "Unexpected error testing GetNamespacesWithAccess") }) AfterEach(func() { - for _, name := range mappings { - deleteRoleBinding(k8sClient, name.Namespace, name.RoleBinding) - deleteRole(k8sClient, name.Namespace, name.Role) - deleteNamespace(k8sClient, name.Namespace) - } + allNamespaces = nil }) }) - Context("When namspace ns3 doesn't have necessary permissions", func() { + Context("When none of the namspaces have necessary permissions", func() { + var name = "ns-test-tenant-3" BeforeEach(func() { - var ns3 k8sapi.Namespace - ns3, err = createNamespace(k8sClient, "ns-test-tenant-3") - Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Error while creating the namespace ns3: %v", err)) + ns3, err := createNamespace(k8sClient, name) + Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Error while creating the namespace %s", name)) allNamespaces = []k8sapi.Namespace{ns3} - expectedNs = []k8sapi.Namespace{} }) It("doesn't return any namespace", func() { - Expect(actualNs).To(Equal(expectedNs)) + actualNs, err = getNamespacesWithAccess(e, c, authCl, allNamespaces) + Expect(actualNs).To(BeEmpty()) Expect(err).NotTo(HaveOccurred(), "Unexpected error testing GetNamespacesWithAccess") }) AfterEach(func() { - deleteNamespace(k8sClient, "ns-test-tenant-3") + allNamespaces = nil }) }) - Context("When only namespaces ns-test-tenant-1 and ns-test-tenant-2 has all necessary permissions and other's don't", func() { - mappings := []NamespaceRoleBinding{ - { - Namespace: "ns-test-tenant-1", - Role: "ns-namespace-access-1", - RoleBinding: "ns-namespace-access-user-binding-1", - }, - { - Namespace: "ns-test-tenant-2", - Role: "ns-namespace-access-2", - RoleBinding: "ns-namespace-access-user-binding-2", - }, - { - Namespace: "ns-test-tenant-3", - Role: "ns-namespace-access-3", - RoleBinding: "ns-namespace-access-user-binding-3", - }, - { - Namespace: "ns-test-tenant-4", - Role: "", - RoleBinding: "", - }, - } + Context("When namspace ns-test-tenant-5 doesn't have necessary permissions", func() { BeforeEach(func() { - for _, name := range mappings { - ns, err := createNamespace(k8sClient, name.Namespace) - Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Error while creating the namespace %s: %v", name.Namespace, err)) + var names = []string{"ns-test-tenant-5", "ns-test-tenant-6"} + for _, name := range names { + ns, err := createNamespace(k8sClient, name) + Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Error while creating the namespace %s", name)) allNamespaces = append(allNamespaces, ns) + expectedNs = []k8sapi.Namespace{ns} } - createRole(k8sClient, "ns-test-tenant-1", "ns-namespace-access-1", []string{"create", "list", "watch", "delete"}) - createRole(k8sClient, "ns-test-tenant-2", "ns-namespace-access-2", []string{"create", "list", "watch", "delete"}) - createRole(k8sClient, "ns-test-tenant-3", "ns-namespace-access-3", []string{"create", "list", "watch"}) - createRoleBinding(k8sClient, "ns-namespace-access-user-binding-1", "ns-test-tenant-1", "user1@konflux.dev", "ns-namespace-access-1") - createRoleBinding(k8sClient, "ns-namespace-access-user-binding-2", "ns-test-tenant-2", "user2@konflux.dev", "ns-namespace-access-2") - createRoleBinding(k8sClient, "ns-namespace-access-user-binding-3", "ns-test-tenant-3", "user3@konflux.dev", "ns-namespace-access-3") - expectedNs = append(expectedNs, allNamespaces[0], allNamespaces[1]) + createRole(k8sClient, "ns-test-tenant-6", "ns-namespace-access-6", []string{"create", "list", "watch", "delete"}) + createRoleBinding(k8sClient, "ns-namespace-access-user-binding-6", "ns-test-tenant-6", "user@konflux.dev", "ns-namespace-access-6") }) - It("returns only namespaces test-tenant and test-tenant-2", func() { + It("only returns ns-test-tenant-6 namespace", func() { + actualNs, err = getNamespacesWithAccess(e, c, authCl, allNamespaces) Expect(actualNs).To(Equal(expectedNs)) Expect(err).NotTo(HaveOccurred(), "Unexpected error testing GetNamespacesWithAccess") }) AfterEach(func() { - deleteRoleBinding(k8sClient, "ns-test-tenant-1", "ns-namespace-access-user-binding-1") - deleteRoleBinding(k8sClient, "ns-test-tenant-2", "ns-namespace-access-user-binding-2") - deleteRoleBinding(k8sClient, "ns-test-tenant-3", "ns-namespace-access-user-binding-3") - deleteRole(k8sClient, "ns-test-tenant-1", "ns-namespace-access-1") - deleteRole(k8sClient, "ns-test-tenant-2", "ns-namespace-access-2") - deleteRole(k8sClient, "ns-test-tenant-3", "ns-namespace-access-3") - for _, name := range mappings { - deleteNamespace(k8sClient, name.Namespace) - } + allNamespaces = nil }) }) }) @@ -614,9 +593,6 @@ var _ = Describe("GetUserNamespaces", func() { }) AfterEach(func() { - for _, ns := range createdNamespaces { - deleteNamespace(k8sClient, ns) - } createdNamespaces = nil }) }) @@ -643,12 +619,6 @@ var _ = Describe("GetUserNamespaces", func() { Expect(actualNamespaces).To(ConsistOf("in-test-1", "in-test-2")) Expect(actualNamespaces).NotTo(ContainElement("not-in-test")) }) - - AfterEach(func() { - for _, ns := range createdNamespaces { - deleteNamespace(k8sClient, ns) - } - }) }) Context("When querying for namespaces using NotIn", func() { @@ -673,11 +643,5 @@ var _ = Describe("GetUserNamespaces", func() { Expect(actualNamespaces).To(ContainElements("ts-keep-1", "ts-keep-2")) Expect(actualNamespaces).NotTo(ContainElements("ts-exclude-1", "ts-exclude-2")) }) - - AfterEach(func() { - for _, ns := range createdNamespaces { - deleteNamespace(k8sClient, ns) - } - }) }) })