Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: configure workspace security context for container builds #1549

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ go 1.16
require (
github.com/Shopify/logrus-bugsnag v0.0.0-00010101000000-000000000000 // indirect
github.com/che-incubator/kubernetes-image-puller-operator v0.0.0-20210929175054-0128446f5af7
github.com/devfile/api/v2 v2.0.0-20220414122024-32cae1f8e42c
github.com/devfile/devworkspace-operator v0.15.2
github.com/devfile/api/v2 v2.0.0-20220928161623-fe7c10eaa530
github.com/devfile/devworkspace-operator v0.17.0
github.com/go-logr/logr v0.4.0
github.com/golang/mock v1.5.0
github.com/google/go-cmp v0.5.6
Expand Down Expand Up @@ -388,7 +388,6 @@ replace (
k8s.io/klog/v2 => k8s.io/klog/v2 v2.8.0
k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.0.0-20180912235703-14b8d2d93fcb
k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20200923105717-7eba4cbaebdf
k8s.io/utils => k8s.io/utils v0.0.0-20201110183641-67b214c5f920
kubernetes/klog => kubernetes/klog v1.0.0
modernc.org/b => modernc.org/b v1.0.0
modernc.org/db => modernc.org/db v1.0.0
Expand Down
12 changes: 7 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,10 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE=
github.com/deislabs/oras v0.8.1/go.mod h1:Mx0rMSbBNaNfY9hjpccEnxkOqJL6KGjtxNHPLC4G4As=
github.com/denisenkom/go-mssqldb v0.0.0-20190204142019-df6d76eb9289/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc=
github.com/devfile/api/v2 v2.0.0-20220414122024-32cae1f8e42c h1:yyidoxal8ngJWDxRuVZMNh4PBwqDIzOkTeOagtmRiy0=
github.com/devfile/api/v2 v2.0.0-20220414122024-32cae1f8e42c/go.mod h1:kLX/nW93gigOHXK3NLeJL2fSS/sgEe+OHu8bo3aoOi4=
github.com/devfile/devworkspace-operator v0.15.2 h1:CcLGHtuBOKdwpeYV8Iy7ZwUSgavcMbjuPA9ejupM7BE=
github.com/devfile/devworkspace-operator v0.15.2/go.mod h1:fM3/GhPWEL8JZOEImCnpyxTYEf9dN6PsjzJq+ffcD1k=
github.com/devfile/api/v2 v2.0.0-20220928161623-fe7c10eaa530 h1:pZvf4AZrf/ZwV2AwQnTInlUpns+Wj9JYtPRtBDiFHzk=
github.com/devfile/api/v2 v2.0.0-20220928161623-fe7c10eaa530/go.mod h1:dN7xFrOVG+iPqn4UKGibXLd5oVsdE8XyK9OEb5JL3aI=
github.com/devfile/devworkspace-operator v0.17.0 h1:Ml8ncEQAVf/d+DTttQ76oe/btnFQpicRG/XncdflOZo=
github.com/devfile/devworkspace-operator v0.17.0/go.mod h1:xLELAolfebwROqGSvOWhdC0eH7S+V7iVFzHxtm3Jf2A=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dhui/dktest v0.3.2/go.mod h1:l1/ib23a/CmxAe7yixtrYPc8Iy90Zy2udyaHINM5p58=
Expand Down Expand Up @@ -706,8 +706,10 @@ k8s.io/kube-openapi v0.0.0-20200923105717-7eba4cbaebdf h1:7RCqblb9HTvcWeOYwrt1SV
k8s.io/kube-openapi v0.0.0-20200923105717-7eba4cbaebdf/go.mod h1:bfCVj+qXcEaE5SCvzBaqpOySr6tuCcpPKqF6HD8nyCw=
k8s.io/kubectl v0.0.0-20201218185502-10b66c3fd14b/go.mod h1:2bE0JLYTRDVKDiTREFsjLAx4R2GvUtL/mGYFXfFFMzY=
k8s.io/metrics v0.20.2/go.mod h1:yTck5nl5wt/lIeLcU6g0b8/AKJf2girwe0PQiaM4Mwk=
k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw=
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210111153108-fddb29f9d009/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210722164352-7f3ee0f31471 h1:DnzUXII7sVg1FJ/4JX6YDRJfLNAC7idRatPwe07suiI=
k8s.io/utils v0.0.0-20210722164352-7f3ee0f31471/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
modernc.org/b v1.0.0/go.mod h1:uZWcZfRj1BpYzfN9JTerzlNUnnPsV9O2ZA8JsRcubNg=
modernc.org/db v1.0.0/go.mod h1:kYD/cO29L/29RM0hXYl4i3+Q5VojL31kTUVpVJDw0s8=
modernc.org/file v1.0.0/go.mod h1:uqEokAEn1u6e+J45e54dsEA/pw4o7zLrA2GwyntZzjw=
Expand Down
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

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading