Skip to content
This repository has been archived by the owner on Jun 26, 2023. It is now read-only.

Commit

Permalink
resolved conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
phoenixking25 committed Apr 27, 2020
2 parents 1fccb49 + 2f94410 commit 395194c
Show file tree
Hide file tree
Showing 143 changed files with 8,405 additions and 1,632 deletions.
1 change: 1 addition & 0 deletions benchmarks/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
e2e.go merge=union
5 changes: 5 additions & 0 deletions benchmarks/documentation/run.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ tenantA:
go test ./e2e/tests
```

#### You can also pass in the path to your config. The path can either be absolute or a relative file to `benchmarks/e2e/config`
```shell
go test ./e2e/tests -config <path-to-config>
```

### To see a more verbose output from the test

```shell
Expand Down
15 changes: 14 additions & 1 deletion benchmarks/e2e/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import (
"reflect"
)

const ConfigPath = "../../config.yaml"
// ConfigFlagType is the type for flags for the tests
var ConfigPath string

type BenchmarkConfig struct {
Adminkubeconfig string `yaml:"adminKubeconfig"`
Expand All @@ -29,3 +30,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")
}
4 changes: 2 additions & 2 deletions benchmarks/e2e/config/utils.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package test

import (
"io/ioutil"
"os"
"errors"
"gopkg.in/yaml.v2"
"io/ioutil"
kubernetes "k8s.io/client-go/kubernetes"
clientcmd "k8s.io/client-go/tools/clientcmd"
"k8s.io/kubernetes/test/e2e/framework"
"os"
)

func GetContextFromKubeconfig(kubeconfigpath string) string {
Expand Down
9 changes: 2 additions & 7 deletions benchmarks/e2e/tests/block_multitenant_resources/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,11 @@ Tenants can escalate priviliges and impact other tenants if they are able to del
**Audit:**

The resources managed by the cluster administrator and that cannot be modified by tenant administrator can be identified by a label configured in the benchmarks configuration YAML file. If no label is provided, then this test looks for any existing network policy and role binding (resource quotas are handled by a separate test) and tries to modify and delete them.

Run the following commands to retrieve the list of resources managed by the cluster administrator

kubectl --kubeconfig=cluster-admin -n a1 get all -l <key>=<value>
kubectl --kubeconfig=cluster-admin -n a1 get all -l <key>=<value>

For each returned by the first command verify that the resource cannot be modified by the tenant administrator:

kubectl --dry-run --kubeconfig=tenant-a -n a1 annotate <resource-type> <resource-name> key1=value1
kubectl --dry-run=true --kubeconfig=tenant-a -n a1 annotate <resource-type> <resource-name> key1=value1

Each command must return 403 FORBIDDEN



Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
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 tenant's permission to modify multi-tenancy resources", func() {
var config *configutil.BenchmarkConfig
var resourceList string
var err error
var dryrun = "--dry-run=true"
var nsFlag = "-n"
var outputFlag = "-o=name"

ginkgo.BeforeEach(func() {
ginkgo.By("get resources managed by the cluster administrator in tenant's namespace")

config, err = configutil.ReadConfig(configutil.ConfigPath)
framework.ExpectNoError(err)

os.Setenv("KUBECONFIG", config.Adminkubeconfig)
labelFlg := fmt.Sprintf("-l")

tenantkubeconfig, err := config.GetValidTenant()
framework.ExpectNoError(err)

resourceList, err = framework.RunKubectl("get", "all", labelFlg, config.Label , nsFlag, tenantkubeconfig.Namespace, outputFlag)
framework.ExpectNoError(err)
})

framework.KubeDescribe("tenant cannot modify resources managed by the cluster administrator in tenant's namespace", func() {
var user string

ginkgo.BeforeEach(func() {
tenantkubeconfig, err := config.GetValidTenant()
framework.ExpectNoError(err)
os.Setenv("KUBECONFIG", tenantkubeconfig.Kubeconfig)
user = configutil.GetContextFromKubeconfig(tenantkubeconfig.Kubeconfig)
})

ginkgo.It("annotate resources managed by the cluster administrator in tenant's namespace", func() {
ginkgo.By(fmt.Sprintf("tenant %s cannot annotate resources managed by the cluster administrator in tenant's namespace", user))

resources := strings.Fields(resourceList)
annotate := fmt.Sprintf("test=multi")

tenantkubeconfig, err := config.GetValidTenant()
framework.ExpectNoError(err)

for _, resource := range resources {
_, errNew := framework.LookForString(expectedVal, time.Minute, func() string {
_, err := framework.RunKubectl(dryrun, nsFlag, tenantkubeconfig.Namespace, "annotate", resource, annotate)
return err.Error()
})

framework.ExpectNoError(errNew)
}
})
})
})

var _ = framework.KubeDescribe("test tenant's permission to modify multi-tenancy rolebindings", func() {
var config *configutil.BenchmarkConfig
var resourceList string
var err error
var dryrun = "--dry-run=true"
var nsFlag = "-n"
var outputFlag = "-o=name"

ginkgo.BeforeEach(func() {
ginkgo.By("get rolebindings managed by the cluster administrator in tenant's namespace")

config, err = configutil.ReadConfig(configutil.ConfigPath)
framework.ExpectNoError(err)

os.Setenv("KUBECONFIG", config.Adminkubeconfig)

tenantkubeconfig, err := config.GetValidTenant()
framework.ExpectNoError(err)

resourceList, err = framework.RunKubectl("get", "rolebinding", nsFlag, tenantkubeconfig.Namespace, outputFlag)
framework.ExpectNoError(err)
})

framework.KubeDescribe("tenant cannot modify rolebinding in tenant's namespace", func() {
var user string

ginkgo.BeforeEach(func() {
tenantkubeconfig, err := config.GetValidTenant()
framework.ExpectNoError(err)

os.Setenv("KUBECONFIG", tenantkubeconfig.Kubeconfig)
user = configutil.GetContextFromKubeconfig(tenantkubeconfig.Kubeconfig)
})

ginkgo.It("annotate rolebinding in tenant's namespace", func() {
ginkgo.By(fmt.Sprintf("tenant %s cannot annotate rolebinding in tenant's namespace", user))

resources := strings.Fields(resourceList)
annotate := fmt.Sprintf("test=multi")

tenantkubeconfig, err := config.GetValidTenant()
framework.ExpectNoError(err)
for _, resource := range resources {
_, errNew := framework.LookForString(expectedVal, time.Minute, func() string {
_, err := framework.RunKubectl(dryrun, nsFlag, tenantkubeconfig.Namespace, "annotate", resource, annotate)
return err.Error()
})

framework.ExpectNoError(errNew)
}
})
})
})

Original file line number Diff line number Diff line change
@@ -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)
}
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"strings"

"github.com/onsi/ginkgo"
configutil "github.com/realshuting/multi-tenancy/benchmarks/e2e/config"
configutil "sigs.k8s.io/multi-tenancy/benchmarks/e2e/config"
"k8s.io/kubernetes/test/e2e/framework"
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
)
Expand All @@ -24,19 +24,20 @@ var _ = framework.KubeDescribe("Tenants should not be allowed to run privileged
config, err = configutil.ReadConfig(configutil.ConfigPath)
framework.ExpectNoError(err)

tenantA = config.GetValidTenant()
tenantA, err = config.GetValidTenant()
framework.ExpectNoError(err)
user = configutil.GetContextFromKubeconfig(tenantA.Kubeconfig)
})

ginkgo.It("validate tenants can't create privileged containers", func() {
ginkgo.By(fmt.Sprintf("tenant ${user} cannot create pod/container with securityContext.privileged set to true",
ginkgo.By(fmt.Sprintf("tenant %s cannot create pod/container with securityContext.privileged set to true",
user))
kclient := configutil.NewKubeClientWithKubeconfig(tenantA.Kubeconfig)
// IsPrivileged set to true so that pod creation would fail
pod := e2epod.MakeSecPod(tenantA.Namespace, nil, nil, true, "", false, false, nil, nil)
_, err = kclient.CoreV1().Pods(tenantA.Namespace).Create(pod)
if !strings.Contains(err.Error(),expectedVal) {
framework.Failf("%s must be unable to create pod with HostPID set to true", user)
framework.Failf("%s must be unable to create pod that sets privileged to true", user)
}
})
})
34 changes: 34 additions & 0 deletions benchmarks/e2e/tests/create_role_bindings/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# [MTB-PL2-BC-OPS-3] Create role bindings

**Profile Applicability:**

Level 2

**Type:**

Behavioral

**Category:**

Self-Service Operations

**Description:**

Tenants should be able to create roles and role-bindings in their namespaces.

**Rationale:**

Enables self-service management of roles and role-bindings within a tenant namespace.

**Audit:**

Run the following commands to check for permissions to manage `rolebinding` and `role` for each verb(get, list, create, update, patch, watch, delete, and deletecollection) in the tenant namespace:

kubectl --kubeconfig=tenant-a -n a1 auth can-i <verb> <resource>

Each command must return 'yes'

Create a `role` pod-reader with permission to view pods and create a `role binding` to this role.

kubectl --kubeconfig=tenant-a -n a1 create role <role-name> --verb=get --resource=pods
kubectl --kubeconfig=tenant-a -n a1 create rolebinding <rolebinding-name> --role=<role-name>
Loading

0 comments on commit 395194c

Please sign in to comment.