From 1394c0b10c03e25af468e56527aea1b20326a401 Mon Sep 17 00:00:00 2001 From: mozhuli <21621232@zju.edu.cn> Date: Thu, 31 Aug 2017 11:15:16 +0800 Subject: [PATCH] Add tenant-controller unit tests including * enhance rbac-controller unit tests * add tenant-controller unit tests Change-Id: I8a803a9c9194bc27662373099e2be34793811311 Implements: blueprint auth-controller-test Signed-off-by: mozhuli <21621232@zju.edu.cn> --- .../rbacmanager/rbac_controller_test.go | 124 +++-- .../tenant/tenant_controller_helper.go | 2 +- .../tenant/tenant_controller_test.go | 512 ++++++++++++++++++ pkg/kubecrd/crdclient_fake.go | 18 +- 4 files changed, 593 insertions(+), 63 deletions(-) create mode 100644 pkg/auth-controller/tenant/tenant_controller_test.go diff --git a/pkg/auth-controller/rbacmanager/rbac_controller_test.go b/pkg/auth-controller/rbacmanager/rbac_controller_test.go index 5143f47..2037f74 100644 --- a/pkg/auth-controller/rbacmanager/rbac_controller_test.go +++ b/pkg/auth-controller/rbacmanager/rbac_controller_test.go @@ -18,8 +18,11 @@ package rbacmanager import ( "fmt" + "reflect" "testing" + crv1 "git.openstack.org/openstack/stackube/pkg/apis/v1" + "git.openstack.org/openstack/stackube/pkg/auth-controller/rbacmanager/rbac" crdClient "git.openstack.org/openstack/stackube/pkg/kubecrd" "git.openstack.org/openstack/stackube/pkg/util" "k8s.io/api/core/v1" @@ -28,10 +31,45 @@ import ( ) const ( - userCIDR = "10.244.0.0/16" - useruserGateway = "10.244.0.1" + userCIDR = "10.244.0.0/16" + userGateway = "10.244.0.1" ) +var systemTenant = &crv1.Tenant{ + ObjectMeta: metav1.ObjectMeta{ + Name: util.SystemTenant, + Namespace: util.SystemTenant, + }, + Spec: crv1.TenantSpec{ + UserName: util.SystemTenant, + Password: util.SystemPassword, + }, +} + +var systemNetwork = &crv1.Network{ + ObjectMeta: metav1.ObjectMeta{ + Name: util.SystemNetwork, + Namespace: util.SystemTenant, + }, + Spec: crv1.NetworkSpec{ + CIDR: userCIDR, + Gateway: userGateway, + }, +} + +func newNetworkForTenant(namespace string) *crv1.Network { + return &crv1.Network{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespace, + Namespace: namespace, + }, + Spec: crv1.NetworkSpec{ + CIDR: userCIDR, + Gateway: userGateway, + }, + } +} + func newNamespace(name string) *v1.Namespace { return &v1.Namespace{ ObjectMeta: metav1.ObjectMeta{ @@ -48,7 +86,7 @@ func newController() (*Controller, *crdClient.FakeCRDClient, *fake.Clientset, er return nil, nil, nil, err } - controller, _ := NewRBACController(client, kubeCRDClient, userCIDR, useruserGateway) + controller, _ := NewRBACController(client, kubeCRDClient, userCIDR, userGateway) return controller, kubeCRDClient, client, nil } @@ -68,11 +106,12 @@ func TestCreateNetworkForTenant(t *testing.T) { testName: "Failed add network", updateFn: func() error { - // Create a new fake controller. + // Creates a new fake controller. controller, kubeCRDClient, _, err = newController() if err != nil { t.Fatalf("Failed start a new fake controller: %v", err) } + // Injects AddNetwork error. kubeCRDClient.InjectError("AddNetwork", fmt.Errorf("failed to create Network")) return controller.createNetworkForTenant(testNamespace) }, @@ -106,10 +145,7 @@ func TestCreateNetworkForTenant(t *testing.T) { network, ok := kubeCRDClient.Networks[testNamespace] if !ok { t.Errorf("Case[%d]: %s expected %s network to be created, got none", tci, tc.testName, testNamespace) - } else if network.Name != util.SystemNetwork && - network.Namespace != util.SystemNetwork && - network.Spec.CIDR != userCIDR && - network.Spec.Gateway != useruserGateway { + } else if reflect.DeepEqual(network, newNetworkForTenant(testNamespace)) { t.Errorf("Case[%d]: %s expected the created %s network has incorrect parameters: %v", tci, tc.testName, testNamespace, network) } } @@ -135,6 +171,7 @@ func TestInitSystemReservedTenantNetwork(t *testing.T) { if err != nil { t.Fatalf("Failed start a new fake controller: %v", err) } + // Injects AddTenant error. kubeCRDClient.InjectError("AddTenant", fmt.Errorf("failed to create Tenant")) return controller.initSystemReservedTenantNetwork() @@ -150,6 +187,7 @@ func TestInitSystemReservedTenantNetwork(t *testing.T) { if err != nil { t.Fatalf("Failed start a new fake controller: %v", err) } + // Inject AddNetwork error. kubeCRDClient.InjectError("AddNetwork", fmt.Errorf("failed to create Network")) return controller.initSystemReservedTenantNetwork() }, @@ -186,20 +224,14 @@ func TestInitSystemReservedTenantNetwork(t *testing.T) { tenant, ok := kubeCRDClient.Tenants["default"] if !ok { t.Errorf("Expected default tenant to be created, got none") - } else if tenant.Name != util.SystemTenant && - tenant.Namespace != util.SystemTenant && - tenant.Spec.UserName != util.SystemTenant && - tenant.Spec.Password != util.SystemPassword { + } else if reflect.DeepEqual(tenant, systemTenant) { t.Errorf("The created default tenant has incorrect parameters: %v", tenant) } network, ok := kubeCRDClient.Networks["default"] if !ok { t.Errorf("Expected default network to be created, got none") - } else if network.Name != util.SystemNetwork && - network.Namespace != util.SystemNetwork && - network.Spec.CIDR != userCIDR && - network.Spec.Gateway != useruserGateway { + } else if reflect.DeepEqual(network, systemNetwork) { t.Errorf("The created default network has incorrect parameters: %v", network) } } @@ -211,9 +243,8 @@ func testRBAC(t *testing.T, client *fake.Clientset, namespace string) { if err != nil { t.Fatalf("Failed get roleBindings: %v", err) } - if roleBinding.Namespace != namespace && - roleBinding.Subjects[0].Name != namespace && - roleBinding.RoleRef.Name != "default-role" { + + if !reflect.DeepEqual(roleBinding, rbac.GenerateRoleBinding(namespace, namespace)) { t.Errorf("Created rolebinding has incorrect parameters: %v", roleBinding) } @@ -221,11 +252,11 @@ func testRBAC(t *testing.T, client *fake.Clientset, namespace string) { if err != nil { t.Fatalf("Failed get ServiceAccount roleBindings: %v", err) } - if saroleBinding.Namespace != namespace && - saroleBinding.Subjects[0].Name != namespace && - saroleBinding.RoleRef.Name != "default-role" { - t.Errorf("Created service account rolebinding has incorrect parameters: %v", saroleBinding) + + if !reflect.DeepEqual(saroleBinding, rbac.GenerateServiceAccountRoleBinding(namespace, namespace)) { + t.Errorf("Created rolebinding has incorrect parameters: %v", saroleBinding) } + } func TestSyncRBAC(t *testing.T) { @@ -275,20 +306,14 @@ func TestOnAdd(t *testing.T) { tenant, ok := kubeCRDClient.Tenants["default"] if !ok { t.Errorf("Expected default tenant to be created, got none") - } else if tenant.Name != util.SystemTenant && - tenant.Namespace != util.SystemTenant && - tenant.Spec.UserName != util.SystemTenant && - tenant.Spec.Password != util.SystemPassword { + } else if !reflect.DeepEqual(tenant, systemTenant) { t.Errorf("The created default tenant has incorrect parameters: %v", tenant) } network, ok := kubeCRDClient.Networks["default"] if !ok { t.Errorf("Expected default network to be created, got none") - } else if network.Name != util.SystemNetwork && - network.Namespace != util.SystemNetwork && - network.Spec.CIDR != userCIDR && - network.Spec.Gateway != useruserGateway { + } else if !reflect.DeepEqual(network, systemNetwork) { t.Errorf("The created default network has incorrect parameters: %v", network) } @@ -313,20 +338,14 @@ func TestOnAdd(t *testing.T) { tenant, ok := kubeCRDClient.Tenants["default"] if !ok { t.Errorf("Expected default tenant to be created, got none") - } else if tenant.Name != util.SystemTenant && - tenant.Namespace != util.SystemTenant && - tenant.Spec.UserName != util.SystemTenant && - tenant.Spec.Password != util.SystemPassword { + } else if !reflect.DeepEqual(tenant, systemTenant) { t.Errorf("The created default tenant has incorrect parameters: %v", tenant) } network, ok := kubeCRDClient.Networks["default"] if !ok { t.Errorf("Expected default network to be created, got none") - } else if network.Name != util.SystemNetwork && - network.Namespace != util.SystemNetwork && - network.Spec.CIDR != userCIDR && - network.Spec.Gateway != useruserGateway { + } else if !reflect.DeepEqual(network, systemNetwork) { t.Errorf("The created default network has incorrect parameters: %v", network) } @@ -351,20 +370,14 @@ func TestOnAdd(t *testing.T) { tenant, ok := kubeCRDClient.Tenants["default"] if !ok { t.Errorf("Expected default tenant to be created, got none") - } else if tenant.Name != util.SystemTenant && - tenant.Namespace != util.SystemTenant && - tenant.Spec.UserName != util.SystemTenant && - tenant.Spec.Password != util.SystemPassword { + } else if !reflect.DeepEqual(tenant, systemTenant) { t.Errorf("The created default tenant has incorrect parameters: %v", tenant) } network, ok := kubeCRDClient.Networks["default"] if !ok { t.Errorf("Expected default network to be created, got none") - } else if network.Name != util.SystemNetwork && - network.Namespace != util.SystemNetwork && - network.Spec.CIDR != userCIDR && - network.Spec.Gateway != useruserGateway { + } else if !reflect.DeepEqual(network, systemNetwork) { t.Errorf("The created default network has incorrect parameters: %v", network) } @@ -390,31 +403,22 @@ func TestOnAdd(t *testing.T) { tenant, ok := kubeCRDClient.Tenants["default"] if !ok { t.Errorf("Expected default tenant to be created, got none") - } else if tenant.Name != util.SystemTenant && - tenant.Namespace != util.SystemTenant && - tenant.Spec.UserName != util.SystemTenant && - tenant.Spec.Password != util.SystemPassword { + } else if !reflect.DeepEqual(tenant, systemTenant) { t.Errorf("The created default tenant has incorrect parameters: %v", tenant) } network, ok := kubeCRDClient.Networks["default"] if !ok { t.Errorf("Expected default network to be created, got none") - } else if network.Name != util.SystemNetwork && - network.Namespace != util.SystemNetwork && - network.Spec.CIDR != userCIDR && - network.Spec.Gateway != useruserGateway { + } else if !reflect.DeepEqual(network, systemNetwork) { t.Errorf("The created default network has incorrect parameters: %v", network) } network, ok = kubeCRDClient.Networks[namespace] if !ok { t.Errorf("Expected %s network to be created, got none", namespace) - } else if network.Name != namespace && - network.Namespace != namespace && - network.Spec.CIDR != userCIDR && - network.Spec.Gateway != useruserGateway { - t.Errorf("The created default network has incorrect parameters: %v", network) + } else if !reflect.DeepEqual(network, newNetworkForTenant(namespace)) { + t.Errorf("The created %s network has incorrect parameters: %v", namespace, network) } testRBAC(t, client, namespace) diff --git a/pkg/auth-controller/tenant/tenant_controller_helper.go b/pkg/auth-controller/tenant/tenant_controller_helper.go index a6f2b42..a70d6ea 100644 --- a/pkg/auth-controller/tenant/tenant_controller_helper.go +++ b/pkg/auth-controller/tenant/tenant_controller_helper.go @@ -43,7 +43,7 @@ func (c *TenantController) syncTenant(tenant *crv1.Tenant) { return } } else { - // Create tenant if the tenant not exist in keystone + // Create tenant if the tenant not exist in keystone, or get the tenantID by tenantName tenantID, err := c.openstackClient.CreateTenant(tenant.Name) if err != nil { glog.Errorf("Failed create tenant %#v: %v", tenant, err) diff --git a/pkg/auth-controller/tenant/tenant_controller_test.go b/pkg/auth-controller/tenant/tenant_controller_test.go new file mode 100644 index 0000000..0f11b43 --- /dev/null +++ b/pkg/auth-controller/tenant/tenant_controller_test.go @@ -0,0 +1,512 @@ +/* +Copyright (c) 2017 OpenStack Foundation. + +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 tenant + +import ( + "fmt" + "reflect" + "testing" + + crv1 "git.openstack.org/openstack/stackube/pkg/apis/v1" + "git.openstack.org/openstack/stackube/pkg/auth-controller/rbacmanager/rbac" + crdClient "git.openstack.org/openstack/stackube/pkg/kubecrd" + "git.openstack.org/openstack/stackube/pkg/openstack" + "git.openstack.org/openstack/stackube/pkg/util" + apismetav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes/fake" +) + +const ( + password = "123456" +) + +var systemTenant = &crv1.Tenant{ + ObjectMeta: apismetav1.ObjectMeta{ + Name: util.SystemTenant, + Namespace: util.SystemTenant, + }, + Spec: crv1.TenantSpec{ + UserName: util.SystemTenant, + Password: util.SystemPassword, + }, +} + +func newTenant(name, userName, password, tenantID string) *crv1.Tenant { + return &crv1.Tenant{ + ObjectMeta: apismetav1.ObjectMeta{ + Name: name, + }, + Spec: crv1.TenantSpec{ + UserName: userName, + Password: password, + TenantID: tenantID, + }, + } +} + +func newNetwork(name string) *crv1.Network { + return &crv1.Network{ + ObjectMeta: apismetav1.ObjectMeta{ + Name: name, + }, + } +} + +func newTenantController() (*TenantController, *crdClient.FakeCRDClient, *openstack.FakeOSClient, *fake.Clientset, error) { + kubeCRDClient, err := crdClient.NewFake() + if err != nil { + return nil, nil, nil, nil, err + } + osClient := openstack.NewFake(kubeCRDClient) + + client := fake.NewSimpleClientset() + + c := &TenantController{ + kubeCRDClient: kubeCRDClient, + k8sClient: client, + openstackClient: osClient, + } + + if err = c.createClusterRoles(); err != nil { + return nil, nil, nil, nil, fmt.Errorf("failed to create cluster roles to kube-apiserver: %v", err) + } + + return c, kubeCRDClient, osClient, client, nil +} + +func TestOperateNamespace(t *testing.T) { + testNamespace := "foo" + // Created a new fake TenantController. + controller, _, _, client, err := newTenantController() + if err != nil { + t.Fatalf("Failed start a new fake TenantController") + } + + // test create namespace + err = controller.createNamespace(testNamespace) + if err != nil { + t.Fatalf("Create namespace %s error:%v", testNamespace, err) + } + ns, err := client.Core().Namespaces().Get(testNamespace, apismetav1.GetOptions{}) + if err != nil { + t.Fatalf("Get namespace %v error: %v", testNamespace, err) + } + if ns.Name != testNamespace { + t.Errorf("Created namespce has incorrect parameters: %v", ns) + } + + // test delete namespace + err = controller.deleteNamespace(testNamespace) + if err != nil { + t.Fatalf("Delete namespace %v error: %v", testNamespace, err) + } + _, err = client.Core().Namespaces().Get(testNamespace, apismetav1.GetOptions{}) + if err.Error() != fmt.Errorf("namespaces %q not found", testNamespace).Error() { + t.Fatalf("Unexpected error: %v", err) + } +} + +func TestCreateClusterRoles(t *testing.T) { + // Created a new fake TenantController. + controller, _, _, client, err := newTenantController() + if err != nil { + t.Fatalf("Failed start a new fake TenantController") + } + err = controller.createClusterRoles() + if err != nil { + t.Fatalf("Create cluster role error:%v", err) + } + + clusterRole, err := client.Rbac().ClusterRoles().Get("namespace-creater", apismetav1.GetOptions{}) + if err != nil { + t.Fatalf("Failed get cluster role: %v", err) + } + + if !reflect.DeepEqual(clusterRole, rbac.GenerateClusterRole()) { + t.Errorf("Created cluster role has incorrect parameters: %v", clusterRole) + } +} + +func TestOnAdd(t *testing.T) { + var controller *TenantController + var kubeCRDClient *crdClient.FakeCRDClient + var osClient *openstack.FakeOSClient + var client *fake.Clientset + var err error + tenantID := "123" + + testCases := []struct { + testName string + tenantName string + updateFn func(tenantName string) + expectedFn func(tenantName string) error + }{ + { + testName: "Add default Tenant", + tenantName: "default", + updateFn: func(tenantName string) { + // Created a new fake TenantController. + controller, kubeCRDClient, osClient, client, err = newTenantController() + if err != nil { + t.Fatalf("Failed start a new fake TenantController") + } + // Add default tenant + controller.onAdd(systemTenant) + + }, + expectedFn: func(tenantName string) error { + // test ClusterRoleBinding created + err := testClusterRoleBindingCreated(t, client, tenantName) + if err != nil { + return err + } + // test tenant created + tenant, ok := osClient.Tenants[tenantName] + if !ok { + return fmt.Errorf("expected %s tenant to be created, got none", tenantName) + } else if tenant.Name != tenantName { + return fmt.Errorf("the created %s tenant has incorrect parameter: %v", tenantName, tenant) + } + // test user created + user, ok := osClient.Users[tenant.ID] + if !ok { + return fmt.Errorf("expected %s user to be created, got none", tenantName) + } else if user.Name != tenantName && + user.TenantID != tenant.ID { + return fmt.Errorf("the created %s user has incorrect parameters: %v", tenantName, user) + } + // test namespace created + err = testNamespaceCreated(t, client, tenantName) + if err != nil { + return err + } + return nil + }, + }, + { + testName: "Add foo1 Tenant with no spec tenantID", + tenantName: "foo1", + updateFn: func(tenantName string) { + // Add tenant + tenant := newTenant(tenantName, tenantName, password, "") + controller.onAdd(tenant) + + }, + expectedFn: func(tenantName string) error { + // test ClusterRoleBinding created + err := testClusterRoleBindingCreated(t, client, tenantName) + if err != nil { + return err + } + // test tenant created + tenant, ok := osClient.Tenants[tenantName] + if !ok { + return fmt.Errorf("expected %s tenant to be created, got none", tenantName) + } else if tenant.Name != tenantName { + return fmt.Errorf("the created %s tenant has incorrect parameter: %v", tenantName, tenant) + } + // test user created + user, ok := osClient.Users[tenant.ID] + if !ok { + return fmt.Errorf("expected %s user to be created, got none", tenantName) + } else if user.Name != tenantName && + user.TenantID != tenant.ID { + return fmt.Errorf("the created %s user has incorrect parameters: %v", tenantName, user) + } + // test namespace created + err = testNamespaceCreated(t, client, tenantName) + if err != nil { + return err + } + return nil + }, + }, + { + testName: "Add foo2 Tenant with spec tenantID", + tenantName: "foo2", + updateFn: func(tenantName string) { + + tenant := newTenant(tenantName, tenantName, password, tenantID) + // Injects fake tenant. + osClient.SetTenant(tenantName, tenantID) + + controller.onAdd(tenant) + + }, + expectedFn: func(tenantName string) error { + // test ClusterRoleBinding created + err := testClusterRoleBindingCreated(t, client, tenantName) + if err != nil { + return err + } + // test user created + user, ok := osClient.Users[tenantID] + if !ok { + return fmt.Errorf("expected %s user to be created, got none", tenantName) + } else if user.Name != tenantName && + user.TenantID != tenantID { + return fmt.Errorf("the created %s user has incorrect parameters: %v", tenantName, user) + } + // test namespace created + err = testNamespaceCreated(t, client, tenantName) + if err != nil { + return err + } + return nil + }, + }, + { + testName: "Add foo3 Tenant, and the tenant exist in openstack", + tenantName: "foo3", + updateFn: func(tenantName string) { + + tenant := newTenant(tenantName, tenantName, password, "") + // Injects fake tenant. + osClient.SetTenant(tenantName, tenantID) + + controller.onAdd(tenant) + + }, + expectedFn: func(tenantName string) error { + // test ClusterRoleBinding created + err := testClusterRoleBindingCreated(t, client, tenantName) + if err != nil { + return err + } + // test user created + tenant, _ := osClient.Tenants[tenantName] + user, ok := osClient.Users[tenant.ID] + if !ok { + return fmt.Errorf("expected %s user to be created, got none", tenantName) + } else if user.Name != tenantName && + user.TenantID != tenant.ID { + return fmt.Errorf("the created %s user has incorrect parameters: %v", tenantName, user) + } + // test namespace created + err = testNamespaceCreated(t, client, tenantName) + if err != nil { + return err + } + return nil + }, + }, + { + testName: "Add foo4 Tenant, and create user with error", + tenantName: "foo4", + updateFn: func(tenantName string) { + + tenant := newTenant(tenantName, tenantName, password, "") + // Injects error. + osClient.InjectError("CreateUser", fmt.Errorf("Failed create user")) + + controller.onAdd(tenant) + + }, + expectedFn: func(tenantName string) error { + // test ClusterRoleBinding created + err := testClusterRoleBindingCreated(t, client, tenantName) + if err != nil { + return err + } + // test no user created + tenant, _ := osClient.Tenants[tenantName] + user, ok := osClient.Users[tenant.ID] + if ok { + return fmt.Errorf("expected no user to be created, got %v", user) + } + return nil + }, + }, + } + + for tci, tc := range testCases { + tc.updateFn(tc.tenantName) + err := tc.expectedFn(tc.tenantName) + if err != nil { + t.Errorf("Case[%d]: %s %v", tci, tc.testName, err) + } + } +} + +func TestOnDelete(t *testing.T) { + var controller *TenantController + var kubeCRDClient *crdClient.FakeCRDClient + var osClient *openstack.FakeOSClient + var client *fake.Clientset + var err error + var tenantID string + + testCases := []struct { + testName string + tenantName string + updateFn func(tenantName string) + expectedFn func(tenantName string) error + }{ + { + testName: "fool Tenant with no spec tenantID", + tenantName: "foo1", + updateFn: func(tenantName string) { + // Created a new fake TenantController. + controller, kubeCRDClient, osClient, client, err = newTenantController() + if err != nil { + t.Fatalf("Failed start a new fake TenantController") + } + + // Injects fake network + network := newNetwork(tenantName) + kubeCRDClient.SetNetworks(network) + // Add tenant + ns := newTenant(tenantName, tenantName, password, "") + controller.onAdd(ns) + tenantID = osClient.Tenants[tenantName].ID + // Delete tenant + controller.onDelete(ns) + + }, + expectedFn: func(tenantName string) error { + // test ClusterRoleBinding deleted + err := testClusterRoleBindingDeleted(t, client, tenantName) + if err != nil { + return err + } + // test network deleted + network, ok := kubeCRDClient.Networks[tenantName] + if ok { + return fmt.Errorf("expected %s network to be deleted, got %v", tenantName, network) + } + // test tenant deleted + tenant, ok := osClient.Tenants[tenantName] + if ok { + return fmt.Errorf("expected %s tenant to be deleted, got %v", tenantName, tenant) + } + // test user deleted + user, ok := osClient.Users[tenantID] + if ok { + return fmt.Errorf("expected %s user to be deleted, got %v", tenantName, user) + } + // test namespace deleted + err = testNamespaceDeleted(t, client, tenantName) + if err != nil { + return err + } + return nil + }, + }, + { + testName: "foo2 Tenant with spec tenantID", + tenantName: "foo2", + updateFn: func(tenantName string) { + // Created a new fake TenantController. + controller, kubeCRDClient, osClient, client, err = newTenantController() + if err != nil { + t.Fatalf("Failed start a new fake TenantController") + } + + // Injects fake network + network := newNetwork(tenantName) + kubeCRDClient.SetNetworks(network) + + tenantID = "123" + ns := newTenant(tenantName, tenantName, password, tenantID) + // Injects fake tenant + osClient.SetTenant(tenantName, tenantID) + // Add tenant + controller.onAdd(ns) + tenantID = osClient.Tenants[tenantName].ID + // Delete tenant + controller.onDelete(ns) + + }, + expectedFn: func(tenantName string) error { + // test ClusterRoleBinding deleted + err := testClusterRoleBindingDeleted(t, client, tenantName) + if err != nil { + return err + } + // test network deleted + network, ok := kubeCRDClient.Networks[tenantName] + if ok { + return fmt.Errorf("expected %s network to be deleted, got %v", tenantName, network) + } + // test tenant remain existed + _, ok = osClient.Tenants[tenantName] + if !ok { + return fmt.Errorf("expected %s tenant remain existed, got none", tenantName) + } + // test user deleted + user, ok := osClient.Users[tenantID] + if ok { + return fmt.Errorf("expected %s user to be deleted, got %v", tenantName, user) + } + // test namespace deleted + err = testNamespaceDeleted(t, client, tenantName) + if err != nil { + return err + } + return nil + }, + }, + } + + for tci, tc := range testCases { + tc.updateFn(tc.tenantName) + err := tc.expectedFn(tc.tenantName) + if err != nil { + t.Errorf("Case[%d]: %s %v", tci, tc.testName, err) + } + } +} + +func testClusterRoleBindingCreated(t *testing.T, client *fake.Clientset, tenantName string) error { + clusterRoleBinding, err := client.Rbac().ClusterRoleBindings().Get(tenantName+"-namespace-creater", apismetav1.GetOptions{}) + if err != nil { + t.Fatalf("Failed get ClusterRoleBinding: %v", err) + } + + if !reflect.DeepEqual(clusterRoleBinding, rbac.GenerateClusterRoleBindingByTenant(tenantName)) { + return fmt.Errorf("created ClusterRoleBinding has incorrect parameters: %v", clusterRoleBinding) + } + return nil +} + +func testClusterRoleBindingDeleted(t *testing.T, client *fake.Clientset, tenantName string) error { + _, err := client.Rbac().ClusterRoleBindings().Get(tenantName+"-namespace-creater", apismetav1.GetOptions{}) + + if err.Error() != fmt.Errorf("clusterrolebindings.rbac.authorization.k8s.io %q not found", tenantName+"-namespace-creater").Error() { + return fmt.Errorf("unexpected error: %v", err) + } + return nil +} + +func testNamespaceCreated(t *testing.T, client *fake.Clientset, namespace string) error { + ns, err := client.Core().Namespaces().Get(namespace, apismetav1.GetOptions{}) + if err != nil { + t.Fatalf("Get namespace %v error: %v", namespace, err) + } + if ns.Name != namespace { + return fmt.Errorf("created namespce %v has incorrect parameters: %v", namespace, ns) + } + return nil +} + +func testNamespaceDeleted(t *testing.T, client *fake.Clientset, namespace string) error { + _, err := client.Core().Namespaces().Get(namespace, apismetav1.GetOptions{}) + if err.Error() != fmt.Errorf("namespaces %q not found", namespace).Error() { + return fmt.Errorf("unexpected error: %v", err) + } + return nil +} diff --git a/pkg/kubecrd/crdclient_fake.go b/pkg/kubecrd/crdclient_fake.go index 3b539fd..ba7abee 100644 --- a/pkg/kubecrd/crdclient_fake.go +++ b/pkg/kubecrd/crdclient_fake.go @@ -118,7 +118,7 @@ func (f *FakeCRDClient) GetCalledDetails() []CalledDetail { } // SetTenants injects fake tenant. -func (f *FakeCRDClient) SetTenants(tenants []*crv1.Tenant) { +func (f *FakeCRDClient) SetTenants(tenants ...*crv1.Tenant) { f.Lock() defer f.Unlock() for _, tenant := range tenants { @@ -127,7 +127,7 @@ func (f *FakeCRDClient) SetTenants(tenants []*crv1.Tenant) { } // SetNetworks injects fake network. -func (f *FakeCRDClient) SetNetworks(networks []*crv1.Network) { +func (f *FakeCRDClient) SetNetworks(networks ...*crv1.Network) { f.Lock() defer f.Unlock() for _, network := range networks { @@ -179,6 +179,20 @@ func (f *FakeCRDClient) GetTenant(tenantName string) (*crv1.Tenant, error) { return tenant, nil } +// DeleteTenant is a test implementation of Interface.DeleteTenant. +func (f *FakeCRDClient) DeleteTenant(tenantName string) error { + f.Lock() + defer f.Unlock() + f.appendCalled("DeleteTenant", tenantName) + if err := f.getError("DeleteTenant"); err != nil { + return err + } + + delete(f.Tenants, tenantName) + + return nil +} + // AddNetwork is a test implementation of Interface.AddNetwork. func (f *FakeCRDClient) AddNetwork(network *crv1.Network) error { f.Lock()