Skip to content

Commit

Permalink
Update unpack job pod security (#2793)
Browse files Browse the repository at this point in the history
* Update unpack job security

Signed-off-by: perdasilva <perdasilva@redhat.com>

* Refactor catsrc pod creation to use security package

Signed-off-by: perdasilva <perdasilva@redhat.com>
Upstream-repository: operator-lifecycle-manager
Upstream-commit: eedad287de8d2326e2ad1f701737df1fb8d38756
  • Loading branch information
perdasilva committed Jun 13, 2022
1 parent 15b71ff commit dc160ba
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 49 deletions.
Expand Up @@ -28,6 +28,7 @@ import (
listersoperatorsv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/listers/operators/v1alpha1"
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install"
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver/projection"
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/security"
)

const (
Expand Down Expand Up @@ -190,6 +191,10 @@ func (c *ConfigMapUnpacker) job(cmRef *corev1.ObjectReference, bundlePath string
},
},
}

// Apply Pod security
security.ApplyPodSpecSecurity(&job.Spec.Template.Spec)

job.SetNamespace(cmRef.Namespace)
job.SetName(cmRef.Name)
job.SetOwnerReferences([]metav1.OwnerReference{ownerRef(cmRef)})
Expand Down
Expand Up @@ -68,6 +68,29 @@ func TestConfigMapUnpacker(t *testing.T) {
roleBindings []*rbacv1.RoleBinding
}

var expectedReadOnlyRootFilesystem = false
var expectedAllowPrivilegeEscalation = false
var expectedRunAsNonRoot = true
var expectedRunAsUser int64 = 1001
var expectedPrivileged = false

var expectedContainerSecurityContext = &corev1.SecurityContext{
Privileged: &expectedPrivileged,
ReadOnlyRootFilesystem: &expectedReadOnlyRootFilesystem,
AllowPrivilegeEscalation: &expectedAllowPrivilegeEscalation,
Capabilities: &corev1.Capabilities{
Drop: []corev1.Capability{"ALL"},
},
}

var expectedPodSecurityContext = &corev1.PodSecurityContext{
RunAsNonRoot: &expectedRunAsNonRoot,
RunAsUser: &expectedRunAsUser,
SeccompProfile: &corev1.SeccompProfile{
Type: corev1.SeccompProfileTypeRuntimeDefault,
},
}

tests := []struct {
description string
fields fields
Expand Down Expand Up @@ -220,6 +243,7 @@ func TestConfigMapUnpacker(t *testing.T) {
Spec: corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyNever,
ImagePullSecrets: []corev1.LocalObjectReference{{Name: "my-secret"}},
SecurityContext: expectedPodSecurityContext,
Containers: []corev1.Container{
{
Name: "extract",
Expand All @@ -243,6 +267,7 @@ func TestConfigMapUnpacker(t *testing.T) {
corev1.ResourceMemory: resource.MustParse("50Mi"),
},
},
SecurityContext: expectedContainerSecurityContext,
},
},
InitContainers: []corev1.Container{
Expand All @@ -262,6 +287,7 @@ func TestConfigMapUnpacker(t *testing.T) {
corev1.ResourceMemory: resource.MustParse("50Mi"),
},
},
SecurityContext: expectedContainerSecurityContext,
},
{
Name: "pull",
Expand All @@ -284,6 +310,7 @@ func TestConfigMapUnpacker(t *testing.T) {
corev1.ResourceMemory: resource.MustParse("50Mi"),
},
},
SecurityContext: expectedContainerSecurityContext,
},
},
Volumes: []corev1.Volume{
Expand Down Expand Up @@ -396,7 +423,8 @@ func TestConfigMapUnpacker(t *testing.T) {
Name: pathHash,
},
Spec: corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyNever,
RestartPolicy: corev1.RestartPolicyNever,
SecurityContext: expectedPodSecurityContext,
Containers: []corev1.Container{
{
Name: "extract",
Expand All @@ -420,6 +448,7 @@ func TestConfigMapUnpacker(t *testing.T) {
corev1.ResourceMemory: resource.MustParse("50Mi"),
},
},
SecurityContext: expectedContainerSecurityContext,
},
},
InitContainers: []corev1.Container{
Expand All @@ -439,6 +468,7 @@ func TestConfigMapUnpacker(t *testing.T) {
corev1.ResourceMemory: resource.MustParse("50Mi"),
},
},
SecurityContext: expectedContainerSecurityContext,
},
{
Name: "pull",
Expand All @@ -461,6 +491,7 @@ func TestConfigMapUnpacker(t *testing.T) {
corev1.ResourceMemory: resource.MustParse("50Mi"),
},
},
SecurityContext: expectedContainerSecurityContext,
},
},
Volumes: []corev1.Volume{
Expand Down Expand Up @@ -614,7 +645,8 @@ func TestConfigMapUnpacker(t *testing.T) {
Name: pathHash,
},
Spec: corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyNever,
RestartPolicy: corev1.RestartPolicyNever,
SecurityContext: expectedPodSecurityContext,
Containers: []corev1.Container{
{
Name: "extract",
Expand All @@ -638,6 +670,7 @@ func TestConfigMapUnpacker(t *testing.T) {
corev1.ResourceMemory: resource.MustParse("50Mi"),
},
},
SecurityContext: expectedContainerSecurityContext,
},
},
InitContainers: []corev1.Container{
Expand All @@ -657,6 +690,7 @@ func TestConfigMapUnpacker(t *testing.T) {
corev1.ResourceMemory: resource.MustParse("50Mi"),
},
},
SecurityContext: expectedContainerSecurityContext,
},
{
Name: "pull",
Expand All @@ -679,6 +713,7 @@ func TestConfigMapUnpacker(t *testing.T) {
corev1.ResourceMemory: resource.MustParse("50Mi"),
},
},
SecurityContext: expectedContainerSecurityContext,
},
},
Volumes: []corev1.Volume{
Expand Down Expand Up @@ -826,7 +861,8 @@ func TestConfigMapUnpacker(t *testing.T) {
Name: pathHash,
},
Spec: corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyNever,
RestartPolicy: corev1.RestartPolicyNever,
SecurityContext: expectedPodSecurityContext,
Containers: []corev1.Container{
{
Name: "extract",
Expand All @@ -850,6 +886,7 @@ func TestConfigMapUnpacker(t *testing.T) {
corev1.ResourceMemory: resource.MustParse("50Mi"),
},
},
SecurityContext: expectedContainerSecurityContext,
},
},
InitContainers: []corev1.Container{
Expand All @@ -869,6 +906,7 @@ func TestConfigMapUnpacker(t *testing.T) {
corev1.ResourceMemory: resource.MustParse("50Mi"),
},
},
SecurityContext: expectedContainerSecurityContext,
},
{
Name: "pull",
Expand All @@ -891,6 +929,7 @@ func TestConfigMapUnpacker(t *testing.T) {
corev1.ResourceMemory: resource.MustParse("50Mi"),
},
},
SecurityContext: expectedContainerSecurityContext,
},
},
Volumes: []corev1.Volume{
Expand Down Expand Up @@ -1008,7 +1047,8 @@ func TestConfigMapUnpacker(t *testing.T) {
Name: pathHash,
},
Spec: corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyNever,
RestartPolicy: corev1.RestartPolicyNever,
SecurityContext: expectedPodSecurityContext,
Containers: []corev1.Container{
{
Name: "extract",
Expand All @@ -1032,6 +1072,7 @@ func TestConfigMapUnpacker(t *testing.T) {
corev1.ResourceMemory: resource.MustParse("50Mi"),
},
},
SecurityContext: expectedContainerSecurityContext,
},
},
InitContainers: []corev1.Container{
Expand All @@ -1051,6 +1092,7 @@ func TestConfigMapUnpacker(t *testing.T) {
corev1.ResourceMemory: resource.MustParse("50Mi"),
},
},
SecurityContext: expectedContainerSecurityContext,
},
{
Name: "pull",
Expand All @@ -1073,6 +1115,7 @@ func TestConfigMapUnpacker(t *testing.T) {
corev1.ResourceMemory: resource.MustParse("50Mi"),
},
},
SecurityContext: expectedContainerSecurityContext,
},
},
Volumes: []corev1.Volume{
Expand Down Expand Up @@ -1201,7 +1244,8 @@ func TestConfigMapUnpacker(t *testing.T) {
Name: pathHash,
},
Spec: corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyNever,
RestartPolicy: corev1.RestartPolicyNever,
SecurityContext: expectedPodSecurityContext,
Containers: []corev1.Container{
{
Name: "extract",
Expand All @@ -1225,6 +1269,7 @@ func TestConfigMapUnpacker(t *testing.T) {
corev1.ResourceMemory: resource.MustParse("50Mi"),
},
},
SecurityContext: expectedContainerSecurityContext,
},
},
InitContainers: []corev1.Container{
Expand All @@ -1244,6 +1289,7 @@ func TestConfigMapUnpacker(t *testing.T) {
corev1.ResourceMemory: resource.MustParse("50Mi"),
},
},
SecurityContext: expectedContainerSecurityContext,
},
{
Name: "pull",
Expand All @@ -1266,6 +1312,7 @@ func TestConfigMapUnpacker(t *testing.T) {
corev1.ResourceMemory: resource.MustParse("50Mi"),
},
},
SecurityContext: expectedContainerSecurityContext,
},
},
Volumes: []corev1.Volume{
Expand Down
Expand Up @@ -12,6 +12,7 @@ import (
"k8s.io/apimachinery/pkg/util/rand"

operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/security"
controllerclient "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/controller-runtime/client"
hashutil "github.com/operator-framework/operator-lifecycle-manager/pkg/lib/kubernetes/pkg/util/hash"
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
Expand Down Expand Up @@ -113,14 +114,6 @@ func Pod(source *operatorsv1alpha1.CatalogSource, name string, image string, saN
pullPolicy = corev1.PullAlways
}

// Security context
readOnlyRootFilesystem := false
allowPrivilegeEscalation := false
runAsNonRoot := true

// See: https://github.com/operator-framework/operator-registry/blob/master/Dockerfile#L27
runAsUser := int64(1001)

pod := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
GenerateName: source.GetName() + "-",
Expand Down Expand Up @@ -163,31 +156,20 @@ func Pod(source *operatorsv1alpha1.CatalogSource, name string, image string, saN
corev1.ResourceMemory: resource.MustParse("50Mi"),
},
},
SecurityContext: &corev1.SecurityContext{
ReadOnlyRootFilesystem: &readOnlyRootFilesystem,
AllowPrivilegeEscalation: &allowPrivilegeEscalation,
Capabilities: &corev1.Capabilities{
Drop: []corev1.Capability{"ALL"},
},
},
ImagePullPolicy: pullPolicy,
TerminationMessagePolicy: corev1.TerminationMessageFallbackToLogsOnError,
},
},
SecurityContext: &corev1.PodSecurityContext{
RunAsNonRoot: &runAsNonRoot,
RunAsUser: &runAsUser,
SeccompProfile: &corev1.SeccompProfile{
Type: corev1.SeccompProfileTypeRuntimeDefault,
},
},
NodeSelector: map[string]string{
"kubernetes.io/os": "linux",
},
ServiceAccountName: saName,
},
}

// Update pod security
security.ApplyPodSpecSecurity(&pod.Spec)

// Override scheduling options if specified
if source.Spec.GrpcPodConfig != nil {
grpcPodConfig := source.Spec.GrpcPodConfig
Expand Down
Expand Up @@ -82,8 +82,10 @@ func TestPodContainerSecurityContext(t *testing.T) {
expectedAllowPrivilegeEscalation := false
expectedRunAsNonRoot := true
expectedRunAsUser := int64(1001)
expectedPrivileged := false

expectedContainerSecCtx := &corev1.SecurityContext{
Privileged: &expectedPrivileged,
ReadOnlyRootFilesystem: &expectedReadOnlyRootFilesystem,
AllowPrivilegeEscalation: &expectedAllowPrivilegeEscalation,
Capabilities: &corev1.Capabilities{
Expand Down
@@ -0,0 +1,42 @@
package security

import (
corev1 "k8s.io/api/core/v1"
"k8s.io/utils/pointer"
)

const readOnlyRootFilesystem = false
const allowPrivilegeEscalation = false
const privileged = false
const runAsNonRoot = true

// See: https://github.com/operator-framework/operator-registry/blob/master/Dockerfile#L27
const runAsUser int64 = 1001

// ApplyPodSpecSecurity applies the standard security profile to a pod spec
func ApplyPodSpecSecurity(spec *corev1.PodSpec) {
var containerSecurityContext = &corev1.SecurityContext{
Privileged: pointer.Bool(privileged),
ReadOnlyRootFilesystem: pointer.Bool(readOnlyRootFilesystem),
AllowPrivilegeEscalation: pointer.Bool(allowPrivilegeEscalation),
Capabilities: &corev1.Capabilities{
Drop: []corev1.Capability{"ALL"},
},
}

var podSecurityContext = &corev1.PodSecurityContext{
RunAsNonRoot: pointer.Bool(runAsNonRoot),
RunAsUser: pointer.Int64(runAsUser),
SeccompProfile: &corev1.SeccompProfile{
Type: corev1.SeccompProfileTypeRuntimeDefault,
},
}

spec.SecurityContext = podSecurityContext
for idx := 0; idx < len(spec.Containers); idx++ {
spec.Containers[idx].SecurityContext = containerSecurityContext
}
for idx := 0; idx < len(spec.InitContainers); idx++ {
spec.InitContainers[idx].SecurityContext = containerSecurityContext
}
}

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

0 comments on commit dc160ba

Please sign in to comment.