Skip to content

Commit

Permalink
feat: configure workspace security context for container builds
Browse files Browse the repository at this point in the history
Fix eclipse-che/che#21770

Signed-off-by: Andrew Obuchowicz <[email protected]>
  • Loading branch information
AObuchow committed Oct 26, 2022
1 parent 21b652e commit ee5e888
Show file tree
Hide file tree
Showing 4 changed files with 209 additions and 25 deletions.
18 changes: 18 additions & 0 deletions pkg/common/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@

package constants

import (
corev1 "k8s.io/api/core/v1"
"k8s.io/utils/pointer"
)

const (
// PostgresSQL
DefaultPostgresUser = "pgche"
Expand Down Expand Up @@ -135,4 +140,17 @@ var (
"app": "che",
"component": "che-gateway-config",
}

// TODO: Remove? Not necessary?
DefaultWorkspacePodSecurityContext = &corev1.PodSecurityContext{}

DefaultWorkspaceContainerSecurityContext = &corev1.SecurityContext{
Capabilities: &corev1.Capabilities{
Add: []corev1.Capability{
"SETGID",
"SETUID",
},
},
AllowPrivilegeEscalation: pointer.BoolPtr(false),
}
)
7 changes: 7 additions & 0 deletions pkg/common/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@ func GetValue(value string, defaultValue string) string {
return value
}

func GetBool(value *bool, defaultValue bool) bool {
if value == nil {
value = &defaultValue
}
return *value
}

// GetImageNameAndTag returns the image repository and tag name from the provided image
// Referenced from https://github.com/che-incubator/chectl/blob/main/src/util.ts
func GetImageNameAndTag(image string) (string, string) {
Expand Down
61 changes: 37 additions & 24 deletions pkg/deploy/dev-workspace-config/dev_workspace_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (d *DevWorkspaceConfigReconciler) Reconcile(ctx *chetypes.DeployContext) (r
if dwoc.Config == nil {
dwoc.Config = &controllerv1alpha1.OperatorConfiguration{}
}
err := updateOperatorConfig(ctx.CheCluster.Spec.DevEnvironments.Storage, dwoc.Config)
err := updateOperatorConfig(ctx.CheCluster.Spec.DevEnvironments, dwoc.Config)
if err != nil {
return reconcile.Result{}, false, err
}
Expand All @@ -71,8 +71,9 @@ func (d *DevWorkspaceConfigReconciler) Finalize(ctx *chetypes.DeployContext) boo
return true
}

func updateOperatorConfig(storage chev2.WorkspaceStorage, operatorConfig *controllerv1alpha1.OperatorConfiguration) error {
func updateOperatorConfig(devEnvironments chev2.CheClusterDevEnvironments, operatorConfig *controllerv1alpha1.OperatorConfiguration) error {
var pvc *chev2.PVC
storage := devEnvironments.Storage

pvcStrategy := utils.GetValue(storage.PvcStrategy, constants.DefaultPvcStorageStrategy)
switch pvcStrategy {
Expand All @@ -88,35 +89,47 @@ func updateOperatorConfig(storage chev2.WorkspaceStorage, operatorConfig *contro
}
}

if pvc != nil {
if operatorConfig.Workspace == nil {
operatorConfig.Workspace = &controllerv1alpha1.WorkspaceConfig{}
}
return updateWorkspaceConfig(pvc, pvcStrategy == constants.PerWorkspacePVCStorageStrategy, operatorConfig.Workspace)
if operatorConfig.Workspace == nil {
operatorConfig.Workspace = &controllerv1alpha1.WorkspaceConfig{}
}
return nil
}

func updateWorkspaceConfig(pvc *chev2.PVC, isPerWorkspacePVCStorageStrategy bool, workspaceConfig *controllerv1alpha1.WorkspaceConfig) error {
if pvc.StorageClass != "" {
workspaceConfig.StorageClassName = &pvc.StorageClass
}
disabledContainerBuildCapabilities := utils.GetBool(devEnvironments.DisableContainerBuildCapabilities, true)

if pvc.ClaimSize != "" {
if workspaceConfig.DefaultStorageSize == nil {
workspaceConfig.DefaultStorageSize = &controllerv1alpha1.StorageSizes{}
}
return updateWorkspaceConfig(pvc, pvcStrategy == constants.PerWorkspacePVCStorageStrategy, disabledContainerBuildCapabilities, operatorConfig.Workspace)
}

pvcSize, err := resource.ParseQuantity(pvc.ClaimSize)
if err != nil {
return err
func updateWorkspaceConfig(pvc *chev2.PVC, isPerWorkspacePVCStorageStrategy bool, disableContainerBuildCapabilities bool, workspaceConfig *controllerv1alpha1.WorkspaceConfig) error {
if pvc != nil {
if pvc.StorageClass != "" {
workspaceConfig.StorageClassName = &pvc.StorageClass
}

if isPerWorkspacePVCStorageStrategy {
workspaceConfig.DefaultStorageSize.PerWorkspace = &pvcSize
} else {
workspaceConfig.DefaultStorageSize.Common = &pvcSize
if pvc.ClaimSize != "" {
if workspaceConfig.DefaultStorageSize == nil {
workspaceConfig.DefaultStorageSize = &controllerv1alpha1.StorageSizes{}
}

pvcSize, err := resource.ParseQuantity(pvc.ClaimSize)
if err != nil {
return err
}

if isPerWorkspacePVCStorageStrategy {
workspaceConfig.DefaultStorageSize.PerWorkspace = &pvcSize
} else {
workspaceConfig.DefaultStorageSize.Common = &pvcSize
}
}
}

if disableContainerBuildCapabilities {
workspaceConfig.PodSecurityContext = nil
workspaceConfig.ContainerSecurityContext = nil
} else {
// TODO: Should we do a deepcopy here?
workspaceConfig.PodSecurityContext = constants.DefaultWorkspacePodSecurityContext
workspaceConfig.ContainerSecurityContext = constants.DefaultWorkspaceContainerSecurityContext
}

return nil
}
148 changes: 147 additions & 1 deletion pkg/deploy/dev-workspace-config/dev_workspace_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (
"regexp"
"testing"

corev1 "k8s.io/api/core/v1"

"github.com/eclipse-che/che-operator/pkg/common/constants"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/utils/pointer"
Expand Down Expand Up @@ -85,7 +87,10 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) {
DevEnvironments: chev2.CheClusterDevEnvironments{},
},
},
expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{},
// The workspace config is now created by default since we need to enable or disable pod/container security contexts depending on Che Cluster CR
expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{
Workspace: &controllerv1alpha1.WorkspaceConfig{},
},
},
{
name: "Create DevWorkspaceOperatorConfig with StorageClassName only",
Expand Down Expand Up @@ -315,6 +320,147 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) {
},
},
},
{
name: "Create DevWorkspaceOperatorConfig without Pod Security Context if container build disabled",
cheCluster: &chev2.CheCluster{
ObjectMeta: metav1.ObjectMeta{
Namespace: "eclipse-che",
Name: "eclipse-che",
},
Spec: chev2.CheClusterSpec{
DevEnvironments: chev2.CheClusterDevEnvironments{
DisableContainerBuildCapabilities: pointer.BoolPtr(true),
},
},
},
expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{
Workspace: &controllerv1alpha1.WorkspaceConfig{},
},
},
{
name: "Create DevWorkspaceOperatorConfig with Pod and Container Security Context if container build enabled",
cheCluster: &chev2.CheCluster{
ObjectMeta: metav1.ObjectMeta{
Namespace: "eclipse-che",
Name: "eclipse-che",
},
Spec: chev2.CheClusterSpec{
DevEnvironments: chev2.CheClusterDevEnvironments{
DisableContainerBuildCapabilities: pointer.BoolPtr(false),
},
},
},
expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{
Workspace: &controllerv1alpha1.WorkspaceConfig{
PodSecurityContext: &corev1.PodSecurityContext{},
ContainerSecurityContext: &corev1.SecurityContext{
Capabilities: &corev1.Capabilities{
Add: []corev1.Capability{
"SETGID",
"SETUID",
},
},
AllowPrivilegeEscalation: pointer.BoolPtr(false),
},
},
},
},
{
name: "Update existing DevWorkspaceOperatorConfig by adding Pod and Container Security Context",
cheCluster: &chev2.CheCluster{
ObjectMeta: metav1.ObjectMeta{
Namespace: "eclipse-che",
Name: "eclipse-che",
},
Spec: chev2.CheClusterSpec{
DevEnvironments: chev2.CheClusterDevEnvironments{
DisableContainerBuildCapabilities: pointer.BoolPtr(false),
},
},
},
existedObjects: []runtime.Object{
&controllerv1alpha1.DevWorkspaceOperatorConfig{
ObjectMeta: metav1.ObjectMeta{
Name: devWorkspaceConfigName,
Namespace: "eclipse-che",
},
TypeMeta: metav1.TypeMeta{
Kind: "DevWorkspaceOperatorConfig",
APIVersion: controllerv1alpha1.GroupVersion.String(),
},
Config: &controllerv1alpha1.OperatorConfiguration{
Workspace: &controllerv1alpha1.WorkspaceConfig{
StorageClassName: pointer.StringPtr("default-storage-class"),
DefaultStorageSize: &controllerv1alpha1.StorageSizes{
Common: &quantity10Gi,
},
},
},
},
},
expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{
Workspace: &controllerv1alpha1.WorkspaceConfig{
StorageClassName: pointer.StringPtr("default-storage-class"),
DefaultStorageSize: &controllerv1alpha1.StorageSizes{
Common: &quantity10Gi,
},
PodSecurityContext: &corev1.PodSecurityContext{},
ContainerSecurityContext: &corev1.SecurityContext{
Capabilities: &corev1.Capabilities{
Add: []corev1.Capability{
"SETGID",
"SETUID",
},
},
AllowPrivilegeEscalation: pointer.BoolPtr(false),
},
},
},
},
{
name: "Update existing DevWorkspaceOperatorConfig by removing Pod and Container Security Context",
cheCluster: &chev2.CheCluster{
ObjectMeta: metav1.ObjectMeta{
Namespace: "eclipse-che",
Name: "eclipse-che",
},
Spec: chev2.CheClusterSpec{
DevEnvironments: chev2.CheClusterDevEnvironments{
DisableContainerBuildCapabilities: pointer.BoolPtr(true),
},
},
},
existedObjects: []runtime.Object{
&controllerv1alpha1.DevWorkspaceOperatorConfig{
ObjectMeta: metav1.ObjectMeta{
Name: devWorkspaceConfigName,
Namespace: "eclipse-che",
},
TypeMeta: metav1.TypeMeta{
Kind: "DevWorkspaceOperatorConfig",
APIVersion: controllerv1alpha1.GroupVersion.String(),
},
Config: &controllerv1alpha1.OperatorConfiguration{
Workspace: &controllerv1alpha1.WorkspaceConfig{
StorageClassName: pointer.StringPtr("default-storage-class"),
DefaultStorageSize: &controllerv1alpha1.StorageSizes{
Common: &quantity10Gi,
},
PodSecurityContext: &corev1.PodSecurityContext{},
ContainerSecurityContext: &corev1.SecurityContext{},
},
},
},
},
expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{
Workspace: &controllerv1alpha1.WorkspaceConfig{
StorageClassName: pointer.StringPtr("default-storage-class"),
DefaultStorageSize: &controllerv1alpha1.StorageSizes{
Common: &quantity10Gi,
},
},
},
},
}

for _, testCase := range testCases {
Expand Down

0 comments on commit ee5e888

Please sign in to comment.