diff --git a/benchmarks/e2e/config/config.go b/benchmarks/e2e/config/config.go index b9e4a5587..f75906935 100644 --- a/benchmarks/e2e/config/config.go +++ b/benchmarks/e2e/config/config.go @@ -29,3 +29,15 @@ func (c *BenchmarkConfig) GetValidTenant() (TenantSpec, error) { return c.TenantB, nil } + +func (c *BenchmarkConfig) ValidateTenant(t TenantSpec) (error) { + if c == nil { + return errors.New("Please fill in a valid/non-empty config.yaml") + } + + if !reflect.DeepEqual(t, TenantSpec{}) { + return nil + } + + return errors.New("Given tenant does not match with TenantSpec") +} diff --git a/benchmarks/e2e/tests/block_other_tenant_resources/block_other_tenant_resources.go b/benchmarks/e2e/tests/block_other_tenant_resources/block_other_tenant_resources.go new file mode 100644 index 000000000..dd9922d8e --- /dev/null +++ b/benchmarks/e2e/tests/block_other_tenant_resources/block_other_tenant_resources.go @@ -0,0 +1,83 @@ +package test + +import ( + "fmt" + "os" + "strings" + "time" + + "github.com/onsi/ginkgo" + configutil "sigs.k8s.io/multi-tenancy/benchmarks/e2e/config" + "k8s.io/kubernetes/test/e2e/framework" +) + +const ( + expectedVal = "Error from server (Forbidden)" +) + +var _ = framework.KubeDescribe("test across tenants permission", func() { + var config *configutil.BenchmarkConfig + var resourceList string + var err error + var tenantA, tenantB string + var namespaceFlag = "-n" + var dryrun = "--dry-run=true" + var all = "--all=true" + + ginkgo.BeforeEach(func() { + ginkgo.By("get tenant's namespace wide api-resources") + + config, err = configutil.ReadConfig(configutil.ConfigPath) + framework.ExpectNoError(err) + + err = config.ValidateTenant(config.TenantA) + framework.ExpectNoError(err) + + os.Setenv("KUBECONFIG", config.TenantA.Kubeconfig) + tenantA = configutil.GetContextFromKubeconfig(config.TenantA.Kubeconfig) + + outputFlag := fmt.Sprintf("-o=name") + nsdFlag := fmt.Sprintf("--namespaced=true") + + resourceList, err = framework.RunKubectl(namespaceFlag, config.TenantA.Namespace, "api-resources", nsdFlag, outputFlag) + framework.ExpectNoError(err) + }) + + framework.KubeDescribe("tenant cannot access other tenant namespaced resources", func() { + + ginkgo.BeforeEach(func() { + err = config.ValidateTenant(config.TenantB) + framework.ExpectNoError(err) + + os.Setenv("KUBECONFIG", config.TenantB.Kubeconfig) + tenantB = configutil.GetContextFromKubeconfig(config.TenantB.Kubeconfig) + }) + + ginkgo.It("get tenant namespaced resources", func() { + ginkgo.By(fmt.Sprintf("tenant %s cannot get tenant %s namespaced resources", tenantB, tenantA)) + resources := strings.Fields(resourceList) + for _, resource := range resources { + _, errNew := framework.LookForString(expectedVal, time.Minute, func() string { + _, err := framework.RunKubectl(namespaceFlag, config.TenantA.Namespace, "get", resource) + return err.Error() + }) + + framework.ExpectNoError(errNew) + } + }) + + ginkgo.It("edit other tenant namespaced resources", func() { + ginkgo.By(fmt.Sprintf("tenant %s cannot edit tenant %s namespaced resources", tenantB, tenantA)) + resources := strings.Fields(resourceList) + annotation := "test=multi-tenancy" + for _, resource := range resources { + _, errNew := framework.LookForString(expectedVal, time.Minute, func() string { + _, err := framework.RunKubectl(namespaceFlag, config.TenantA.Namespace, "annotate", resource, annotation, dryrun, all) + return err.Error() + }) + + framework.ExpectNoError(errNew) + } + }) + }) +}) diff --git a/benchmarks/e2e/tests/e2e.go b/benchmarks/e2e/tests/e2e.go index 9e887bd67..8bd78f207 100644 --- a/benchmarks/e2e/tests/e2e.go +++ b/benchmarks/e2e/tests/e2e.go @@ -14,6 +14,7 @@ import ( _ "sigs.k8s.io/multi-tenancy/benchmarks/e2e/tests/configure_ns_quotas" _ "sigs.k8s.io/multi-tenancy/benchmarks/e2e/tests/block_privileged_containers" _ "sigs.k8s.io/multi-tenancy/benchmarks/e2e/tests/block_host_pid" + _ "sigs.k8s.io/multi-tenancy/benchmarks/e2e/tests/block_other_tenant_resources" ) // RunE2ETests runs the multi-tenancy benchmark tests