summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/bindings/play/types.go2
-rw-r--r--pkg/bindings/play/types_kube_options.go15
-rw-r--r--pkg/domain/entities/play.go2
-rw-r--r--pkg/domain/infra/abi/play.go77
-rw-r--r--pkg/domain/infra/tunnel/play.go2
-rw-r--r--pkg/specgen/generate/kube/kube.go61
6 files changed, 109 insertions, 50 deletions
diff --git a/pkg/bindings/play/types.go b/pkg/bindings/play/types.go
index dbff4304b..5aaa87b8c 100644
--- a/pkg/bindings/play/types.go
+++ b/pkg/bindings/play/types.go
@@ -43,4 +43,6 @@ type KubeOptions struct {
LogOptions *[]string
// Start - don't start the pod if false
Start *bool
+ // Userns - define the user namespace to use.
+ Userns *string
}
diff --git a/pkg/bindings/play/types_kube_options.go b/pkg/bindings/play/types_kube_options.go
index d7a452ea2..54c9a8e74 100644
--- a/pkg/bindings/play/types_kube_options.go
+++ b/pkg/bindings/play/types_kube_options.go
@@ -272,3 +272,18 @@ func (o *KubeOptions) GetStart() bool {
}
return *o.Start
}
+
+// WithUserns set field Userns to given value
+func (o *KubeOptions) WithUserns(value string) *KubeOptions {
+ o.Userns = &value
+ return o
+}
+
+// GetUserns returns value of field Userns
+func (o *KubeOptions) GetUserns() string {
+ if o.Userns == nil {
+ var z string
+ return z
+ }
+ return *o.Userns
+}
diff --git a/pkg/domain/entities/play.go b/pkg/domain/entities/play.go
index c9dc3f08c..bf7c33f2b 100644
--- a/pkg/domain/entities/play.go
+++ b/pkg/domain/entities/play.go
@@ -54,6 +54,8 @@ type PlayKubeOptions struct {
LogOptions []string
// Start - don't start the pod if false
Start types.OptionalBool
+ // Userns - define the user namespace to use.
+ Userns string
}
// PlayKubePod represents a single pod and associated containers created by play kube
diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go
index b3ded7db6..019361694 100644
--- a/pkg/domain/infra/abi/play.go
+++ b/pkg/domain/infra/abi/play.go
@@ -222,6 +222,16 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
podOpt.Net.NetworkOptions = netOpts
}
+ if options.Userns == "" {
+ options.Userns = "host"
+ }
+
+ // Validate the userns modes supported.
+ podOpt.Userns, err = specgen.ParseUserNamespace(options.Userns)
+ if err != nil {
+ return nil, err
+ }
+
// FIXME This is very hard to support properly with a good ux
if len(options.StaticIPs) > *ipIndex {
if !podOpt.Net.Network.IsBridge() {
@@ -352,6 +362,7 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
infraImage := util.DefaultContainerConfig().Engine.InfraImage
infraOptions := entities.NewInfraContainerCreateOptions()
infraOptions.Hostname = podSpec.PodSpecGen.PodBasicConfig.Hostname
+ infraOptions.UserNS = options.Userns
podSpec.PodSpecGen.InfraImage = infraImage
podSpec.PodSpecGen.NoInfra = false
podSpec.PodSpecGen.InfraContainerSpec = specgen.NewSpecGenerator(infraImage, false)
@@ -412,22 +423,24 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
}
specgenOpts := kube.CtrSpecGenOptions{
- Annotations: annotations,
- Container: initCtr,
- Image: pulledImage,
- Volumes: volumes,
- PodID: pod.ID(),
- PodName: podName,
- PodInfraID: podInfraID,
- ConfigMaps: configMaps,
- SeccompPaths: seccompPaths,
- RestartPolicy: ctrRestartPolicy,
- NetNSIsHost: p.NetNS.IsHost(),
- SecretsManager: secretsManager,
- LogDriver: options.LogDriver,
- LogOptions: options.LogOptions,
- Labels: labels,
- InitContainerType: define.AlwaysInitContainer,
+ Annotations: annotations,
+ ConfigMaps: configMaps,
+ Container: initCtr,
+ Image: pulledImage,
+ InitContainerType: define.AlwaysInitContainer,
+ Labels: labels,
+ LogDriver: options.LogDriver,
+ LogOptions: options.LogOptions,
+ NetNSIsHost: p.NetNS.IsHost(),
+ PodID: pod.ID(),
+ PodInfraID: podInfraID,
+ PodName: podName,
+ PodSecurityContext: podYAML.Spec.SecurityContext,
+ RestartPolicy: ctrRestartPolicy,
+ SeccompPaths: seccompPaths,
+ SecretsManager: secretsManager,
+ UserNSIsHost: p.Userns.IsHost(),
+ Volumes: volumes,
}
specGen, err := kube.ToSpecGen(ctx, &specgenOpts)
if err != nil {
@@ -460,21 +473,23 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
}
specgenOpts := kube.CtrSpecGenOptions{
- Annotations: annotations,
- Container: container,
- Image: pulledImage,
- Volumes: volumes,
- PodID: pod.ID(),
- PodName: podName,
- PodInfraID: podInfraID,
- ConfigMaps: configMaps,
- SeccompPaths: seccompPaths,
- RestartPolicy: ctrRestartPolicy,
- NetNSIsHost: p.NetNS.IsHost(),
- SecretsManager: secretsManager,
- LogDriver: options.LogDriver,
- LogOptions: options.LogOptions,
- Labels: labels,
+ Annotations: annotations,
+ ConfigMaps: configMaps,
+ Container: container,
+ Image: pulledImage,
+ Labels: labels,
+ LogDriver: options.LogDriver,
+ LogOptions: options.LogOptions,
+ NetNSIsHost: p.NetNS.IsHost(),
+ PodID: pod.ID(),
+ PodInfraID: podInfraID,
+ PodName: podName,
+ PodSecurityContext: podYAML.Spec.SecurityContext,
+ RestartPolicy: ctrRestartPolicy,
+ SeccompPaths: seccompPaths,
+ SecretsManager: secretsManager,
+ UserNSIsHost: p.Userns.IsHost(),
+ Volumes: volumes,
}
specGen, err := kube.ToSpecGen(ctx, &specgenOpts)
if err != nil {
diff --git a/pkg/domain/infra/tunnel/play.go b/pkg/domain/infra/tunnel/play.go
index d9637254a..d731a1d6c 100644
--- a/pkg/domain/infra/tunnel/play.go
+++ b/pkg/domain/infra/tunnel/play.go
@@ -20,7 +20,7 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, body io.Reader, opts en
if opts.Annotations != nil {
options.WithAnnotations(opts.Annotations)
}
- options.WithNoHosts(opts.NoHosts)
+ options.WithNoHosts(opts.NoHosts).WithUserns(opts.Userns)
if s := opts.SkipTLSVerify; s != types.OptionalBoolUndefined {
options.WithSkipTLSVerify(s == types.OptionalBoolTrue)
}
diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go
index d56b50fd5..e4c149abf 100644
--- a/pkg/specgen/generate/kube/kube.go
+++ b/pkg/specgen/generate/kube/kube.go
@@ -120,6 +120,8 @@ type CtrSpecGenOptions struct {
RestartPolicy string
// NetNSIsHost tells the container to use the host netns
NetNSIsHost bool
+ // UserNSIsHost tells the container to use the host userns
+ UserNSIsHost bool
// SecretManager to access the secrets
SecretsManager *secrets.SecretsManager
// LogDriver which should be used for the container
@@ -133,6 +135,8 @@ type CtrSpecGenOptions struct {
// InitContainerType sets what type the init container is
// Note: When playing a kube yaml, the inti container type will be set to "always" only
InitContainerType string
+ // PodSecurityContext is the security context specified for the pod
+ PodSecurityContext *v1.PodSecurityContext
}
func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGenerator, error) {
@@ -188,7 +192,7 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener
s.InitContainerType = opts.InitContainerType
- setupSecurityContext(s, opts.Container)
+ setupSecurityContext(s, opts.Container.SecurityContext, opts.PodSecurityContext)
err := setupLivenessProbe(s, opts.Container, opts.RestartPolicy)
if err != nil {
return nil, errors.Wrap(err, "Failed to configure livenessProbe")
@@ -387,8 +391,9 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener
if opts.NetNSIsHost {
s.NetNS.NSMode = specgen.Host
}
- // Always set the userns to host since k8s doesn't have support for userns yet
- s.UserNS.NSMode = specgen.Host
+ if opts.UserNSIsHost {
+ s.UserNS.NSMode = specgen.Host
+ }
// Add labels that come from kube
if len(s.Labels) == 0 {
@@ -531,22 +536,30 @@ func makeHealthCheck(inCmd string, interval int32, retries int32, timeout int32,
return &hc, nil
}
-func setupSecurityContext(s *specgen.SpecGenerator, containerYAML v1.Container) {
- if containerYAML.SecurityContext == nil {
- return
+func setupSecurityContext(s *specgen.SpecGenerator, securityContext *v1.SecurityContext, podSecurityContext *v1.PodSecurityContext) {
+ if securityContext == nil {
+ securityContext = &v1.SecurityContext{}
+ }
+ if podSecurityContext == nil {
+ podSecurityContext = &v1.PodSecurityContext{}
}
- if containerYAML.SecurityContext.ReadOnlyRootFilesystem != nil {
- s.ReadOnlyFilesystem = *containerYAML.SecurityContext.ReadOnlyRootFilesystem
+
+ if securityContext.ReadOnlyRootFilesystem != nil {
+ s.ReadOnlyFilesystem = *securityContext.ReadOnlyRootFilesystem
}
- if containerYAML.SecurityContext.Privileged != nil {
- s.Privileged = *containerYAML.SecurityContext.Privileged
+ if securityContext.Privileged != nil {
+ s.Privileged = *securityContext.Privileged
}
- if containerYAML.SecurityContext.AllowPrivilegeEscalation != nil {
- s.NoNewPrivileges = !*containerYAML.SecurityContext.AllowPrivilegeEscalation
+ if securityContext.AllowPrivilegeEscalation != nil {
+ s.NoNewPrivileges = !*securityContext.AllowPrivilegeEscalation
}
- if seopt := containerYAML.SecurityContext.SELinuxOptions; seopt != nil {
+ seopt := securityContext.SELinuxOptions
+ if seopt == nil {
+ seopt = podSecurityContext.SELinuxOptions
+ }
+ if seopt != nil {
if seopt.User != "" {
s.SelinuxOpts = append(s.SelinuxOpts, fmt.Sprintf("user:%s", seopt.User))
}
@@ -560,7 +573,7 @@ func setupSecurityContext(s *specgen.SpecGenerator, containerYAML v1.Container)
s.SelinuxOpts = append(s.SelinuxOpts, fmt.Sprintf("level:%s", seopt.Level))
}
}
- if caps := containerYAML.SecurityContext.Capabilities; caps != nil {
+ if caps := securityContext.Capabilities; caps != nil {
for _, capability := range caps.Add {
s.CapAdd = append(s.CapAdd, string(capability))
}
@@ -568,14 +581,26 @@ func setupSecurityContext(s *specgen.SpecGenerator, containerYAML v1.Container)
s.CapDrop = append(s.CapDrop, string(capability))
}
}
- if containerYAML.SecurityContext.RunAsUser != nil {
- s.User = fmt.Sprintf("%d", *containerYAML.SecurityContext.RunAsUser)
+ runAsUser := securityContext.RunAsUser
+ if runAsUser == nil {
+ runAsUser = podSecurityContext.RunAsUser
}
- if containerYAML.SecurityContext.RunAsGroup != nil {
+ if runAsUser != nil {
+ s.User = fmt.Sprintf("%d", *runAsUser)
+ }
+
+ runAsGroup := securityContext.RunAsGroup
+ if runAsGroup == nil {
+ runAsGroup = podSecurityContext.RunAsGroup
+ }
+ if runAsGroup != nil {
if s.User == "" {
s.User = "0"
}
- s.User = fmt.Sprintf("%s:%d", s.User, *containerYAML.SecurityContext.RunAsGroup)
+ s.User = fmt.Sprintf("%s:%d", s.User, *runAsGroup)
+ }
+ for _, group := range podSecurityContext.SupplementalGroups {
+ s.Groups = append(s.Groups, fmt.Sprintf("%d", group))
}
}