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 Nov 10, 2022
1 parent e1e7789 commit 15f5872
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 25 deletions.
15 changes: 15 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,14 @@ var (
"app": "che",
"component": "che-gateway-config",
}

DefaultWorkspaceContainerSecurityContext = corev1.SecurityContext{
Capabilities: &corev1.Capabilities{
Add: []corev1.Capability{
"SETGID",
"SETUID",
},
},
AllowPrivilegeEscalation: pointer.BoolPtr(false),
}
)
55 changes: 31 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, 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(cheCluster *chev2.CheCluster, operatorConfig *controllerv1alpha1.OperatorConfiguration) error {
var pvc *chev2.PVC
storage := cheCluster.Spec.DevEnvironments.Storage

pvcStrategy := utils.GetValue(storage.PvcStrategy, constants.DefaultPvcStorageStrategy)
switch pvcStrategy {
Expand All @@ -88,35 +89,41 @@ 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
}
return updateWorkspaceConfig(pvc, pvcStrategy == constants.PerWorkspacePVCStorageStrategy, cheCluster.IsContainerBuildCapabilitiesEnabled(), operatorConfig.Workspace)
}

if pvc.ClaimSize != "" {
if workspaceConfig.DefaultStorageSize == nil {
workspaceConfig.DefaultStorageSize = &controllerv1alpha1.StorageSizes{}
func updateWorkspaceConfig(pvc *chev2.PVC, isPerWorkspacePVCStorageStrategy bool, enabledContainerBuildCapabilities bool, workspaceConfig *controllerv1alpha1.WorkspaceConfig) error {
if pvc != nil {
if pvc.StorageClass != "" {
workspaceConfig.StorageClassName = &pvc.StorageClass
}

pvcSize, err := resource.ParseQuantity(pvc.ClaimSize)
if err != nil {
return err
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 isPerWorkspacePVCStorageStrategy {
workspaceConfig.DefaultStorageSize.PerWorkspace = &pvcSize
} else {
workspaceConfig.DefaultStorageSize.Common = &pvcSize
}
workspaceConfig.ContainerSecurityContext = nil
if enabledContainerBuildCapabilities {
workspaceConfig.ContainerSecurityContext = constants.DefaultWorkspaceContainerSecurityContext.DeepCopy()
}

return nil
}
144 changes: 143 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,9 @@ func TestReconcileDevWorkspaceConfigPerUserStorage(t *testing.T) {
DevEnvironments: chev2.CheClusterDevEnvironments{},
},
},
expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{},
expectedOperatorConfig: &controllerv1alpha1.OperatorConfiguration{
Workspace: &controllerv1alpha1.WorkspaceConfig{},
},
},
{
name: "Create DevWorkspaceOperatorConfig with StorageClassName only",
Expand Down Expand Up @@ -315,6 +319,144 @@ 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{
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,
},
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,
},
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 15f5872

Please sign in to comment.