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

Issue-635: Pod level security context configuration for Pega chart & Hazelcast sub chart #750

Merged
merged 9 commits into from
May 16, 2024
2 changes: 1 addition & 1 deletion charts/pega/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ requestor:
### Security context

By default, security context for your Pega pod deployments `pegasystems/pega` image uses `pegauser`(9001) as the user and volume mounts uses `root`(0) as the group. To configure an alternative user for your custom image, set value for `runAsUser` and to configure an alternative group for volume mounts, set value for `fsGroup`. Note that pegasystems/pega image works only with pegauser(9001).
`runAsUser` and `fsGroup` must be configured in `securityContext` under each tier block and will be applied to Deployments/Statefulsets, see the [Kubernetes Documentation](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/).
`runAsUser` and `fsGroup` must be configured in `securityContext` under each tier block and will be applied to Deployments/Statefulsets, along with these settings other allowed configuration can also be supplied here, see the [Kubernetes Documentation](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/).

Example:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ spec:
{{- include "generatedClusteringServicePodAnnotations" . | indent 8 }}
spec:
terminationGracePeriodSeconds: {{ .Values.server.graceful_shutdown_max_wait_seconds }}
{{- if .Values.securityContext }}
securityContext:
{{ toYaml .Values.securityContext | indent 8 }}
{{- end }}
containers:
- name: hazelcast
image: {{ .Values.clusteringServiceImage }}
Expand Down
4 changes: 4 additions & 0 deletions charts/pega/charts/hazelcast/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,7 @@ server:
diagnostics_metric_level: "info"
diagnostic_log_file_size_mb: "50"
diagnostics_file_count: "3"

# Apply securityContext to clustering service pods. For example to set `runAsUser: 1000`:
# securityContext:
# runAsUser: 1000
16 changes: 3 additions & 13 deletions charts/pega/templates/_pega-deployment.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -112,23 +112,13 @@ spec:
nodeSelector:
{{ toYaml .node.nodeSelector | indent 8 }}
{{- end }}
{{- if (ne .root.Values.global.provider "openshift") }}
securityContext:
{{- if .node.securityContext }}
{{- if .node.securityContext.runAsUser }}
runAsUser: {{ .node.securityContext.runAsUser }}
{{- else }}
runAsUser: 9001
{{- end }}
{{- if .node.securityContext.fsGroup }}
fsGroup: {{ .node.securityContext.fsGroup }}
{{- else }}
fsGroup: 0
{{- end }}
{{- else }}
{{- if (ne .root.Values.global.provider "openshift") }}
runAsUser: 9001
fsGroup: 0
{{- end }}
{{- if .node.securityContext }}
{{ toYaml .node.securityContext | indent 8 }}
{{- end }}
{{- if .node.topologySpreadConstraints }}
topologySpreadConstraints:
Expand Down
40 changes: 37 additions & 3 deletions terratest/src/test/pega/clustering-service-deployment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ package pega

import (
"fmt"
"path/filepath"
"strings"
"testing"

"github.com/gruntwork-io/terratest/modules/helm"
"github.com/stretchr/testify/require"
appsv1beta2 "k8s.io/api/apps/v1beta2"
"k8s.io/apimachinery/pkg/util/intstr"
"path/filepath"
"strings"
"testing"
)

func TestClusteringServiceDeployment(t *testing.T) {
Expand Down Expand Up @@ -64,3 +65,36 @@ func VerifyClusteringServiceDeployment(t *testing.T, yamlContent string) {
}
}
}

func TestClusteringServiceDeploymentSecurityContext(t *testing.T) {
var supportedVendors = []string{"k8s", "openshift", "eks", "gke", "aks", "pks"}
var supportedOperations = []string{"deploy", "install-deploy"}

helmChartPath, err := filepath.Abs(PegaHelmChartPath)
require.NoError(t, err)

for _, vendor := range supportedVendors {

for _, operation := range supportedOperations {

fmt.Println(vendor + "-" + operation)

var options = &helm.Options{
SetValues: map[string]string{
"global.provider": vendor,
"global.actions.execute": operation,
"hazelcast.clusteringServiceEnabled": "true",
"hazelcast.securityContext.runAsUser": "1000",
},
}

yamlContent := RenderTemplate(t, options, helmChartPath, []string{"charts/hazelcast/templates/clustering-service-deployment.yaml"})
yamlSplit := strings.Split(yamlContent, "---")
var statefulsetObj appsv1beta2.StatefulSet
UnmarshalK8SYaml(t, yamlSplit[1], &statefulsetObj)

require.Equal(t, int64(1000), *statefulsetObj.Spec.Template.Spec.SecurityContext.RunAsUser)

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package pega

import (
"fmt"
"path/filepath"
"strings"
"testing"

"github.com/gruntwork-io/terratest/modules/helm"
"github.com/stretchr/testify/require"
appsv1 "k8s.io/api/apps/v1"
)

func TestPegaTierDeploymentSecurityContextDefaults(t *testing.T) {
var supportedVendors = []string{"k8s", "openshift", "eks", "gke", "aks", "pks"}
var supportedOperations = []string{"deploy"}
var deploymentNames = []string{"myapp-dev"}

helmChartPath, err := filepath.Abs(PegaHelmChartPath)
require.NoError(t, err)

for _, vendor := range supportedVendors {

var depObj appsv1.Deployment

for _, operation := range supportedOperations {

for _, depName := range deploymentNames {

fmt.Println(vendor + "-" + operation)

var options = &helm.Options{
SetValues: map[string]string{
"global.provider": vendor,
"global.actions.execute": operation,
"global.deployment.name": depName,
},
}

yamlContent := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-deployment.yaml"})
yamlSplit := strings.Split(yamlContent, "---")
UnmarshalK8SYaml(t, yamlSplit[1], &depObj)

if vendor != "openshift" {
// for openshift and for others
require.Equal(t, int64(0), *depObj.Spec.Template.Spec.SecurityContext.FSGroup)
require.Equal(t, int64(9001), *depObj.Spec.Template.Spec.SecurityContext.RunAsUser)
} else {
require.Nil(t, depObj.Spec.Template.Spec.SecurityContext)
}

}
}
}
}

func TestPegaTierDeploymentSecurityContextAdditional(t *testing.T) {
var supportedVendors = []string{"k8s", "openshift"}
var supportedOperations = []string{"deploy"}
var deploymentNames = []string{"myapp-dev"}

helmChartPath, err := filepath.Abs(PegaHelmChartPath)
require.NoError(t, err)

for _, vendor := range supportedVendors {

var depObj appsv1.Deployment

for _, operation := range supportedOperations {

for _, depName := range deploymentNames {

fmt.Println(vendor + "-" + operation)

var options = &helm.Options{
SetValues: map[string]string{
"global.provider": vendor,
"global.actions.execute": operation,
"global.deployment.name": depName,
"global.tier[0].securityContext.runAsNonRoot": "true",
"global.tier[0].securityContext.supplementalGroups[0]": "2000",
},
}

yamlContent := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-deployment.yaml"})
yamlSplit := strings.Split(yamlContent, "---")
UnmarshalK8SYaml(t, yamlSplit[1], &depObj)

require.Equal(t, bool(true), *depObj.Spec.Template.Spec.SecurityContext.RunAsNonRoot)
require.Equal(t, int64(2000), *&depObj.Spec.Template.Spec.SecurityContext.SupplementalGroups[0])

if vendor != "openshift" {
// for openshift and for others
require.Equal(t, int64(0), *depObj.Spec.Template.Spec.SecurityContext.FSGroup)
require.Equal(t, int64(9001), *depObj.Spec.Template.Spec.SecurityContext.RunAsUser)
} else {
require.Nil(t, depObj.Spec.Template.Spec.SecurityContext.FSGroup)
require.Nil(t, depObj.Spec.Template.Spec.SecurityContext.RunAsUser)
}

}
}
}
}

func TestPegaTierDeploymentSecurityContextOverrideDefault(t *testing.T) {
var supportedVendors = []string{"k8s", "eks", "gke"}
var supportedOperations = []string{"deploy"}
var deploymentNames = []string{"myapp-dev"}

helmChartPath, err := filepath.Abs(PegaHelmChartPath)
require.NoError(t, err)

for _, vendor := range supportedVendors {
var depObj appsv1.Deployment

for _, operation := range supportedOperations {

for _, depName := range deploymentNames {

fmt.Println(vendor + "-" + operation)

var options = &helm.Options{
SetValues: map[string]string{
"global.provider": vendor,
"global.actions.execute": operation,
"global.deployment.name": depName,
"global.tier[0].securityContext.fsGroup": "2",
},
}

yamlContent := RenderTemplate(t, options, helmChartPath, []string{"templates/pega-tier-deployment.yaml"})
yamlSplit := strings.Split(yamlContent, "---")
UnmarshalK8SYaml(t, yamlSplit[1], &depObj)

if vendor != "openshift" {
// for openshift and for others
require.Equal(t, int64(2), *depObj.Spec.Template.Spec.SecurityContext.FSGroup)
require.Equal(t, int64(9001), *depObj.Spec.Template.Spec.SecurityContext.RunAsUser)
} else {
require.Equal(t, int64(2), *depObj.Spec.Template.Spec.SecurityContext.FSGroup)
require.Nil(t, depObj.Spec.Template.Spec.SecurityContext.RunAsUser)
}
}
}
}
}
Loading