Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
3 changes: 3 additions & 0 deletions pkg/apis/helm.cattle.io/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ type HelmChartSpec struct {

AuthPassCredentials bool `json:"authPassCredentials,omitempty"`
DockerRegistrySecret *corev1.LocalObjectReference `json:"dockerRegistrySecret,omitempty"`

PodSecurityContext *corev1.PodSecurityContext `json:"podSecurityContext,omitempty"`
SecurityContext *corev1.SecurityContext `json:"securityContext,omitempty"`
}

type HelmChartStatus struct {
Expand Down
98 changes: 98 additions & 0 deletions pkg/controllers/chart/chart.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"crypto/sha256"
"fmt"
"os"
"reflect"
"regexp"
"sort"
"strings"
Expand Down Expand Up @@ -56,6 +57,22 @@ var (
DefaultJobImage = "rancher/klipper-helm:v0.8.2-build20230815"
DefaultFailurePolicy = FailurePolicyReinstall
defaultBackOffLimit = pointer.Int32(1000)

defaultPodSecurityContext = &corev1.PodSecurityContext{
RunAsNonRoot: pointer.BoolPtr(true),
SeccompProfile: &corev1.SeccompProfile{
Type: "RuntimeDefault",
},
}
defaultSecurityContext = &corev1.SecurityContext{
AllowPrivilegeEscalation: pointer.BoolPtr(false),
Capabilities: &corev1.Capabilities{
Drop: []corev1.Capability{
"ALL",
},
},
ReadOnlyRootFilesystem: pointer.BoolPtr(true),
}
)

type Controller struct {
Expand Down Expand Up @@ -377,6 +394,9 @@ func job(chart *v1.HelmChart, apiServerPort string) (*batch.Job, *corev1.Secret,
chartName = chart.Name + "/" + chart.Spec.Chart
}

podSecurityContext := defaultPodSecurityContext.DeepCopy()
securityContext := defaultSecurityContext.DeepCopy()

job := &batch.Job{
TypeMeta: metav1.TypeMeta{
APIVersion: "batch/v1",
Expand Down Expand Up @@ -443,9 +463,51 @@ func job(chart *v1.HelmChart, apiServerPort string) (*batch.Job, *corev1.Secret,
Value: fmt.Sprintf("%t", chart.Spec.AuthPassCredentials),
},
},
SecurityContext: securityContext,
VolumeMounts: []corev1.VolumeMount{
{
Name: "klipper-helm",
MountPath: "/home/klipper-helm/.helm",
},
{
Name: "klipper-cache",
MountPath: "/home/klipper-helm/.cache",
},
{
Name: "klipper-config",
MountPath: "/home/klipper-helm/.config",
},
},
},
},
ServiceAccountName: fmt.Sprintf("helm-%s", chart.Name),
SecurityContext: podSecurityContext,
Volumes: []corev1.Volume{
{
Name: "klipper-helm",
VolumeSource: corev1.VolumeSource{
EmptyDir: &corev1.EmptyDirVolumeSource{
Medium: "Memory",
},
},
},
{
Name: "klipper-cache",
VolumeSource: corev1.VolumeSource{
EmptyDir: &corev1.EmptyDirVolumeSource{
Medium: "Memory",
},
},
},
{
Name: "klipper-config",
VolumeSource: corev1.VolumeSource{
EmptyDir: &corev1.EmptyDirVolumeSource{
Medium: "Memory",
},
},
},
},
},
},
},
Expand Down Expand Up @@ -507,6 +569,7 @@ func job(chart *v1.HelmChart, apiServerPort string) (*batch.Job, *corev1.Secret,
setAuthSecret(job, chart)
setDockerRegistrySecret(job, chart)
setRepoCAConfigMap(job, chart)
setSecurityContext(job, chart)
valuesSecret := setValuesSecret(job, chart)
contentConfigMap := setContentConfigMap(job, chart)

Expand Down Expand Up @@ -831,3 +894,38 @@ func hashObjects(job *batch.Job, objs ...metav1.Object) {
func setBackOffLimit(job *batch.Job, backOffLimit *int32) {
job.Spec.BackoffLimit = backOffLimit
}

func deepMergeStruct(target, source interface{}) {
targetVal := reflect.ValueOf(target).Elem()
sourceVal := reflect.ValueOf(source).Elem()

for i := 0; i < targetVal.NumField(); i++ {
targetField := targetVal.Field(i)
sourceField := sourceVal.Field(i)

if !sourceField.IsNil() {
if targetField.IsNil() {
targetField.Set(sourceField)
} else {
// If fields are pointers and Structs, merge recursively
if targetField.Kind() == reflect.Ptr && targetField.Elem().Kind() == reflect.Struct &&
sourceField.Kind() == reflect.Ptr && sourceField.Elem().Kind() == reflect.Struct {
deepMergeStruct(targetField.Interface(), sourceField.Interface())
} else {
// Otherwise, overwrite target field with source field value
targetField.Set(sourceField)
}
}
}
}
}

func setSecurityContext(job *batch.Job, chart *v1.HelmChart) {
if chart.Spec.PodSecurityContext != nil {
deepMergeStruct(job.Spec.Template.Spec.SecurityContext, chart.Spec.PodSecurityContext)
}

if chart.Spec.SecurityContext != nil {
deepMergeStruct(job.Spec.Template.Spec.Containers[0].SecurityContext, chart.Spec.SecurityContext)
}
}
Loading