From 4b7f93189db865cdf5bee4ece8d0efd793f92075 Mon Sep 17 00:00:00 2001 From: Daniel Jiang Date: Fri, 6 Dec 2024 15:08:31 +0800 Subject: [PATCH] Add SecurityContext to restore-helper This commit adds SecurityContext that complies with "restricted" level per Pod Security Standards to "restore-helper" initContainer. It ensures the restore won't fail when the cluster enforces PSA. Signed-off-by: Daniel Jiang --- changelogs/unreleased/8491-reasonerjt | 1 + .../actions/pod_volume_restore_action.go | 32 +++++++++++++++++-- .../actions/pod_volume_restore_action_test.go | 16 ++++++++-- 3 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 changelogs/unreleased/8491-reasonerjt diff --git a/changelogs/unreleased/8491-reasonerjt b/changelogs/unreleased/8491-reasonerjt new file mode 100644 index 0000000000..29fd4acaf5 --- /dev/null +++ b/changelogs/unreleased/8491-reasonerjt @@ -0,0 +1 @@ +Add SecurityContext to restore-helper \ No newline at end of file diff --git a/pkg/restore/actions/pod_volume_restore_action.go b/pkg/restore/actions/pod_volume_restore_action.go index 36722b0a29..71af336ceb 100644 --- a/pkg/restore/actions/pod_volume_restore_action.go +++ b/pkg/restore/actions/pod_volume_restore_action.go @@ -21,6 +21,8 @@ import ( "fmt" "strings" + "github.com/vmware-tanzu/velero/pkg/util/boolptr" + "github.com/pkg/errors" "github.com/sirupsen/logrus" corev1 "k8s.io/api/core/v1" @@ -44,6 +46,7 @@ const ( defaultCPURequestLimit = "100m" defaultMemRequestLimit = "128Mi" defaultCommand = "/velero-restore-helper" + restoreHelperUID = 1000 ) type PodVolumeRestoreAction struct { @@ -143,9 +146,15 @@ func (a *PodVolumeRestoreAction) Execute(input *velero.RestoreItemActionExecuteI runAsUser, runAsGroup, allowPrivilegeEscalation, secCtx := getSecurityContext(log, config) - securityContext, err := kube.ParseSecurityContext(runAsUser, runAsGroup, allowPrivilegeEscalation, secCtx) - if err != nil { - log.Errorf("Using default securityContext values, couldn't parse securityContext requirements: %s.", err) + var securityContext corev1.SecurityContext + if runAsUser == "" && runAsGroup == "" && allowPrivilegeEscalation == "" && secCtx == "" { + securityContext = defaultSecurityCtx() + } else { + securityContext, err = kube.ParseSecurityContext(runAsUser, runAsGroup, allowPrivilegeEscalation, secCtx) + if err != nil { + log.Errorf("Using default securityContext values, couldn't parse securityContext requirements: %s.", err) + securityContext = defaultSecurityCtx() + } } initContainerBuilder := newRestoreInitContainerBuilder(image, string(input.Restore.UID)) @@ -282,3 +291,20 @@ func newRestoreInitContainerBuilder(image, restoreUID string) *builder.Container }, }...) } + +// defaultSecurityCtx returns a default security context for the init container, which has the level "restricted" per +// Pod Security Standards. +func defaultSecurityCtx() corev1.SecurityContext { + uid := int64(restoreHelperUID) + return corev1.SecurityContext{ + AllowPrivilegeEscalation: boolptr.False(), + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{"ALL"}, + }, + SeccompProfile: &corev1.SeccompProfile{ + Type: corev1.SeccompProfileTypeRuntimeDefault, + }, + RunAsUser: &uid, + RunAsNonRoot: boolptr.True(), + } +} diff --git a/pkg/restore/actions/pod_volume_restore_action_test.go b/pkg/restore/actions/pod_volume_restore_action_test.go index 7be617bd40..5b836cba15 100644 --- a/pkg/restore/actions/pod_volume_restore_action_test.go +++ b/pkg/restore/actions/pod_volume_restore_action_test.go @@ -20,6 +20,8 @@ import ( "sort" "testing" + "github.com/vmware-tanzu/velero/pkg/util/boolptr" + "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -113,8 +115,18 @@ func TestPodVolumeRestoreActionExecute(t *testing.T) { defaultCPURequestLimit, defaultMemRequestLimit, // requests defaultCPURequestLimit, defaultMemRequestLimit, // limits ) - - securityContext, _ := kube.ParseSecurityContext("", "", "", "") + id := int64(1000) + securityContext := corev1api.SecurityContext{ + AllowPrivilegeEscalation: boolptr.False(), + Capabilities: &corev1api.Capabilities{ + Drop: []corev1api.Capability{"ALL"}, + }, + SeccompProfile: &corev1api.SeccompProfile{ + Type: corev1api.SeccompProfileTypeRuntimeDefault, + }, + RunAsUser: &id, + RunAsNonRoot: boolptr.True(), + } var ( restoreName = "my-restore"