Skip to content

Commit

Permalink
Add support for sizing sandboxes
Browse files Browse the repository at this point in the history
  • Loading branch information
jpreese committed Mar 2, 2020
1 parent 2ffe6fd commit 168a98f
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 8 deletions.
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ kind: Sandbox
metadata:
name: foo
spec:
size: small
owners:
- [email protected]
```
Expand Down Expand Up @@ -137,9 +138,33 @@ One `RoleBinding` per name in the `owners` field

### ResourceQuota (sandbox-foo-resourcequota)

The `ResourceQuota` that is applied to the `Namespace` depends on the `size` of the `Sandbox` that was created.

#### Small

|Resource Name|Quantity|
|---|---|
|ResourceRequestsMemory|1Gi|
|ResourceRequestsCPU|0.25|
|ResourceLimitsCPU|0.5|
|ResourceRequestsMemory|250Mi|
|ResourceLimitsMemory|500Mi|
|ResourceRequestsStorage|10Gi|
|ResourcePersistentVolumeClaims|2|

#### Large

|Resource Name|Quantity|
|---|---|
|ResourceRequestsCPU|1|
|ResourceLimitsCPU|2|
|ResourceRequestsMemory|2Gi|
|ResourceLimitsMemory|8Gi|
|ResourceRequestsStorage|40Gi|
|ResourcePersistentVolumeClaims|8|

```text
NOTE: If no size is given, small is the default.
```

## Managing Owners of a Sandbox

Expand All @@ -153,6 +178,7 @@ kind: Sandbox
metadata:
name: foo
spec:
size: small
owners:
- [email protected]
- [email protected]
Expand Down
1 change: 1 addition & 0 deletions apis/operators/v1alpha1/sandbox_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
// +k8s:openapi-gen=true
type SandboxSpec struct {
Owners []string `json:"owners"`
Size string `json:"size"`
}

// SandboxStatus defines the observed state of Sandbox
Expand Down
43 changes: 38 additions & 5 deletions controller/sandbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,21 +302,54 @@ func getClusterRoleBinding(sandbox operatorsv1alpha1.Sandbox) rbacv1.ClusterRole
}

func getResourceQuota(sandbox operatorsv1alpha1.Sandbox) corev1.ResourceQuota {
var resourceQuotaSpec corev1.ResourceQuotaSpec
if sandbox.Spec.Size == "large" {
resourceQuotaSpec = getLargeResourceQuotaSpec()
} else {
resourceQuotaSpec = getSmallResourceQuotaSpec()
}

resourceQuota := corev1.ResourceQuota{
ObjectMeta: metav1.ObjectMeta{
Name: "sandbox-" + sandbox.Name + "-resourcequota",
Namespace: "sandbox-" + sandbox.Name,
},
Spec: corev1.ResourceQuotaSpec{
Hard: corev1.ResourceList{
corev1.ResourceRequestsMemory: resource.MustParse("1Gi"),
},
},
Spec: resourceQuotaSpec,
}

return resourceQuota
}

func getLargeResourceQuotaSpec() corev1.ResourceQuotaSpec {
resourceQuotaSpec := corev1.ResourceQuotaSpec{
Hard: corev1.ResourceList{
corev1.ResourceRequestsCPU: resource.MustParse("1"),
corev1.ResourceLimitsCPU: resource.MustParse("2"),
corev1.ResourceRequestsMemory: resource.MustParse("2Gi"),
corev1.ResourceLimitsMemory: resource.MustParse("8Gi"),
corev1.ResourceRequestsStorage: resource.MustParse("40Gi"),
corev1.ResourcePersistentVolumeClaims: resource.MustParse("8"),
},
}

return resourceQuotaSpec
}

func getSmallResourceQuotaSpec() corev1.ResourceQuotaSpec {
resourceQuotaSpec := corev1.ResourceQuotaSpec{
Hard: corev1.ResourceList{
corev1.ResourceRequestsCPU: resource.MustParse("0.25"),
corev1.ResourceLimitsCPU: resource.MustParse("0.5"),
corev1.ResourceRequestsMemory: resource.MustParse("250Mi"),
corev1.ResourceLimitsMemory: resource.MustParse("500Mi"),
corev1.ResourceRequestsStorage: resource.MustParse("10Gi"),
corev1.ResourcePersistentVolumeClaims: resource.MustParse("2"),
},
}

return resourceQuotaSpec
}

// DefaultSubjects represents default subjects
type DefaultSubjects struct{}

Expand Down
18 changes: 17 additions & 1 deletion controller/sandbox_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func TestSandboxControllerIntegration(t *testing.T) {
Name: "test",
},
Spec: operatorsv1alpha1.SandboxSpec{
Size: "small",
Owners: []string{"[email protected]"},
},
}
Expand Down Expand Up @@ -78,6 +79,21 @@ func TestSandboxControllerIntegration(t *testing.T) {
t.Errorf("role not found: %v", err)
}

resourceQuota := getResourceQuota(sandbox)
err = wait.PollImmediate(intervalTime, waitTime, func() (bool, error) {
geterr := client.Get(ctx, types.NamespacedName{Namespace: resourceQuota.Namespace, Name: resourceQuota.Name}, &corev1.ResourceQuota{})
if geterr == nil {
return true, nil
} else if errors.IsNotFound(geterr) {
return false, nil
} else {
return false, fmt.Errorf("get resourcequota: %w", geterr)
}
})
if err != nil {
t.Errorf("resourcequota not found: %v", err)
}

if err := client.Delete(ctx, &sandbox); err != nil {
t.Fatalf("delete sandbox: %v", err)
}
Expand All @@ -89,7 +105,7 @@ func TestSandboxControllerIntegration(t *testing.T) {
} else if err == nil {
return false, nil
} else {
return false, fmt.Errorf("get sandbox: %v", err)
return false, fmt.Errorf("get namespace: %v", err)
}
})
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions example/sandbox.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ kind: Sandbox
metadata:
name: test
spec:
size: small
owners:
- [email protected]
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.13

require (
github.com/Azure/azure-sdk-for-go v32.5.0+incompatible
github.com/Azure/go-autorest v13.3.3+incompatible
github.com/Azure/go-autorest v13.3.3+incompatible // indirect
github.com/Azure/go-autorest/autorest v0.9.5 // indirect
github.com/Azure/go-autorest/autorest/azure/auth v0.4.2
github.com/Azure/go-autorest/autorest/to v0.3.0 // indirect
Expand Down
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSW
github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g=
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc=
github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM=
github.com/Azure/go-autorest/autorest/to v0.3.0 h1:zebkZaadz7+wIQYgC7GXaz3Wb28yKYfVkkBKwc38VF8=
github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA=
Expand Down

0 comments on commit 168a98f

Please sign in to comment.