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

Commit 083c78c

Browse files
authored
Merge pull request #1251 from phoenixking25/second-ns
[MTB] refactored code and added other ns flag
2 parents 66244f1 + c3a27b5 commit 083c78c

File tree

35 files changed

+173
-39
lines changed

35 files changed

+173
-39
lines changed

benchmarks/kubectl-mtb/internal/kubectl-mtb/run.go

Lines changed: 72 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ func reportSuiteDidEnd(suiteSummary *reporter.SuiteSummary, reportersArray []rep
102102
}
103103

104104
func removeBenchmarksWithIDs(ids []string) {
105-
temp := []*benchmark.Benchmark{}
105+
var temp []*benchmark.Benchmark
106106
for _, benchmark := range benchmarks {
107107
found := false
108108
for _, id := range ids {
@@ -143,22 +143,78 @@ func validateFlags(cmd *cobra.Command) error {
143143
return nil
144144
}
145145

146-
func runTests(cmd *cobra.Command, args []string) error {
147-
148-
benchmarkRunOptions.Label, _ = cmd.Flags().GetString("labels")
149-
// Get log level
146+
func setupLogger(cmd *cobra.Command) {
150147
debug, _ := cmd.Flags().GetBool("debug")
151148
if debug {
152149
benchmarkRunOptions.Logger = log.GetLogger(true)
153150
} else {
154151
// default mode production
155152
benchmarkRunOptions.Logger = log.GetLogger(false)
156153
}
154+
}
157155

156+
func setupReporters(cmd *cobra.Command) ([]reporter.Reporter, error) {
158157
// Get reporters from the user
159158
reporterFlag, _ := cmd.Flags().GetString("out")
160159
reporters := strings.Split(reporterFlag, ",")
161-
reportersArray, err := reporter.GetReporters(reporters)
160+
return reporter.GetReporters(reporters)
161+
}
162+
163+
func executePreRun(b *benchmark.Benchmark, suiteSummary *reporter.SuiteSummary, ts *reporter.TestSummary) {
164+
err := b.PreRun(benchmarkRunOptions)
165+
if err != nil {
166+
benchmarkRunOptions.Logger.Debug(err.Error())
167+
suiteSummary.NumberOfFailedValidations++
168+
ts.Validation = false
169+
ts.ValidationError = err
170+
b.Status = "Error"
171+
}
172+
}
173+
174+
func executeRun(b *benchmark.Benchmark, suiteSummary *reporter.SuiteSummary, ts *reporter.TestSummary) {
175+
if ts.Validation {
176+
err := b.Run(benchmarkRunOptions)
177+
if err != nil {
178+
benchmarkRunOptions.Logger.Debug(err.Error())
179+
suiteSummary.NumberOfFailedTests++
180+
ts.Test = false
181+
ts.TestError = err
182+
b.Status = "Fail"
183+
} else {
184+
suiteSummary.NumberOfPassedTests++
185+
b.Status = "Pass"
186+
}
187+
}
188+
}
189+
190+
func executePostRun(b *benchmark.Benchmark, suiteSummary *reporter.SuiteSummary, ts *reporter.TestSummary) {
191+
if ts.Test {
192+
if b.PostRun != nil {
193+
err := b.PostRun(benchmarkRunOptions)
194+
if err != nil {
195+
fmt.Print(err.Error())
196+
}
197+
}
198+
}
199+
}
200+
201+
func shouldSkipTest(b *benchmark.Benchmark, suiteSummary *reporter.SuiteSummary, ts *reporter.TestSummary) bool {
202+
if b.NamespaceRequired > 1 {
203+
if benchmarkRunOptions.OtherNamespace != "" && benchmarkRunOptions.OtherTenant != "" {
204+
return false
205+
}
206+
return true
207+
}
208+
return false
209+
}
210+
211+
func runTests(cmd *cobra.Command, args []string) error {
212+
213+
benchmarkRunOptions.Label, _ = cmd.Flags().GetString("labels")
214+
// Get log level
215+
setupLogger(cmd)
216+
217+
reportersArray, err := setupReporters(cmd)
162218
if err != nil {
163219
return err
164220
}
@@ -192,40 +248,17 @@ func runTests(cmd *cobra.Command, args []string) error {
192248

193249
startTest := time.Now()
194250

195-
//Run Prerun
196-
err = b.PreRun(benchmarkRunOptions)
197-
if err != nil {
198-
benchmarkRunOptions.Logger.Debug(err.Error())
199-
suiteSummary.NumberOfFailedValidations++
200-
ts.Validation = false
201-
ts.ValidationError = err
202-
b.Status = "Error"
251+
if shouldSkipTest(b, suiteSummary, ts) {
252+
continue
203253
}
204254

205-
// Check PreRun status
206-
if ts.Validation {
207-
err = b.Run(benchmarkRunOptions)
208-
if err != nil {
209-
benchmarkRunOptions.Logger.Debug(err.Error())
210-
suiteSummary.NumberOfFailedTests++
211-
ts.Test = false
212-
ts.TestError = err
213-
b.Status = "Fail"
214-
} else {
215-
suiteSummary.NumberOfPassedTests++
216-
b.Status = "Pass"
217-
}
218-
}
255+
// Lifecycles
256+
executePreRun(b, suiteSummary, ts)
257+
258+
executeRun(b, suiteSummary, ts)
259+
260+
executePostRun(b, suiteSummary, ts)
219261

220-
// Check Run status
221-
if ts.Test {
222-
if b.PostRun != nil {
223-
err = b.PostRun(benchmarkRunOptions)
224-
if err != nil {
225-
fmt.Print(err.Error())
226-
}
227-
}
228-
}
229262
elapsed := time.Since(startTest)
230263
ts.RunTime = elapsed
231264
reportTestWillRun(ts, reportersArray)
@@ -245,6 +278,8 @@ func newRunCmd() *cobra.Command {
245278
runCmd.Flags().String("as", "", "(required) user name to impersonate")
246279
runCmd.Flags().StringP("out", "o", "default", "(optional) output reporters (default, policyreport)")
247280
runCmd.Flags().StringP("skip", "s", "", "(optional) benchmark IDs to skip")
281+
runCmd.Flags().String("other-namespace", "", "(optional) other tenant namespace")
282+
runCmd.Flags().String("other-tenant-admin","", "(optional) other tenant admin")
248283
runCmd.Flags().StringP("labels", "l", "", "(optional) labels")
249284

250285
return runCmd

benchmarks/kubectl-mtb/pkg/benchmark/benchmark.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ type Benchmark struct {
1919
Status string `yaml:"status"`
2020
Rationale string `yaml:"rationale"`
2121
Audit string `yaml:"audit"`
22+
NamespaceRequired int `yaml:"namespaceRequired"`
2223
PreRun func(types.RunOptions) error
2324
Run func(types.RunOptions) error
2425
PostRun func(types.RunOptions) error

benchmarks/kubectl-mtb/test/benchmarks/block_access_to_cluster_resources/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,8 @@ kubectl --kubeconfig tenant-a auth can-i verb resource
3333
Each command must return 'no'
3434

3535

36+
37+
**namespaceRequired:**
38+
39+
1
40+

benchmarks/kubectl-mtb/test/benchmarks/block_access_to_cluster_resources/config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ category: Control Plane Isolation
55
description: Tenants should not be able to view, edit, create, or delete cluster (non-namespaced) resources such Node, ClusterRole, ClusterRoleBinding, etc.
66
remediation:
77
profileLevel: 1
8+
namespaceRequired: 1
89
rationale: Access controls should be configured for tenants so that a tenant cannot list, create, modify or delete cluster resources
910
audit: |
1011
Run the following commands to retrieve the list of non-namespaced resources

benchmarks/kubectl-mtb/test/benchmarks/block_add_capabilities/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,8 @@ Create a pod or container that adds new `capabilities` in its `securityContext`.
2828

2929
Define a `PodSecurityPolicy` with `allowedCapabilities` and map the policy to each tenant namespace, or use a policy engine such as [OPA/Gatekeeper](https://github.com/open-policy-agent/gatekeeper) or [Kyverno](https://kyverno.io) to enforce new capabilities cannot be added. You can use the policies present [here](https://github.com/kubernetes-sigs/multi-tenancy/tree/master/benchmarks/kubectl-mtb/test/policies).
3030

31+
32+
**namespaceRequired:**
33+
34+
1
35+

benchmarks/kubectl-mtb/test/benchmarks/block_add_capabilities/config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ description: Linux
66
remediation: Define a `PodSecurityPolicy` with `allowedCapabilities` and map the policy to each tenant namespace, or use a policy engine such as [OPA/Gatekeeper](https://github.com/open-policy-agent/gatekeeper) or [Kyverno](https://kyverno.io) to enforce new capabilities cannot be added. You can use the policies present [here](https://github.com/kubernetes-sigs/multi-tenancy/tree/master/benchmarks/kubectl-mtb/test/policies).
77
rationale: Linux allows defining fine-grained permissions using capabilities. With Kubernetes, it is possible to add capabilities for pods that escalate the level of kernel access and allow other potentially dangerous behaviors.
88
profileLevel: 1
9+
namespaceRequired: 1
910
audit: Create a pod or container that adds new `capabilities` in its `securityContext`. The pod creation must fail.

benchmarks/kubectl-mtb/test/benchmarks/block_multitenant_resources/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,8 @@ For each returned by the first command verify that the resource cannot be modifi
3030

3131
Each command must return 403 FORBIDDEN
3232

33+
34+
**namespaceRequired:**
35+
36+
1
37+

benchmarks/kubectl-mtb/test/benchmarks/block_multitenant_resources/config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ category: Tenant Isolation
55
description: Each tenant namespace may contain resources setup by the cluster administrator for multi-tenancy, such as role bindings, and network policies. Tenants should not be allowed to modify the namespaced resources created by the cluster administrator for multi-tenancy. However, for some resources such as network policies, tenants can configure additional instances of the resource for their workloads.
66
remediation:
77
profileLevel: 1
8+
namespaceRequired: 1
89
rationale: Tenants can escalate priviliges and impact other tenants if they are able to delete or modify required multi-tenancy resources such as namespace resource quotas or default network policy.
910
audit: |
1011
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

benchmarks/kubectl-mtb/test/benchmarks/block_ns_quota/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,8 @@ kubectl --kubeconfig=tenant-a -n a1 auth can-i deletecollection quota
3232
```
3333
Each command must return 'no'"
3434

35+
36+
**namespaceRequired:**
37+
38+
1
39+

benchmarks/kubectl-mtb/test/benchmarks/block_ns_quota/config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ category: Tenant Isolation
55
description: Tenants should not be able to modify the resource quotas defined in their namespaces
66
remediation:
77
profileLevel: 1
8+
namespaceRequired: 1
89
rationale: Resource quotas must be configured for isolation and fairness between tenants. Tenants should not be able to modify existing resource quotas as they may exhaust cluster resources and impact other tenants.
910
audit: |
1011
Run the following commands to check for permissions to manage quotas in the tenant namespace:

0 commit comments

Comments
 (0)