mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-11-22 09:51:01 +00:00
Simple security context options (Kubernetes) (#2550)
This commit is contained in:
parent
ffb3bd806c
commit
3adb98b287
8 changed files with 298 additions and 72 deletions
|
@ -42,6 +42,10 @@ agent:
|
|||
|
||||
Additional annotations to apply to worker pods. Must be a YAML object, e.g. `{"example.com/test-annotation":"test-value"}`.
|
||||
|
||||
- `WOODPECKER_BACKEND_K8S_SECCTX_NONROOT` (default: `false`)
|
||||
|
||||
Determines if containers must be required to run as non-root users.
|
||||
|
||||
## Job specific configuration
|
||||
|
||||
### Resources
|
||||
|
|
|
@ -57,6 +57,11 @@ var Flags = []cli.Flag{
|
|||
Usage: "backend k8s additional worker pod annotations",
|
||||
Value: "",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
EnvVars: []string{"WOODPECKER_BACKEND_K8S_SECCTX_NONROOT"},
|
||||
Name: "backend-k8s-secctx-nonroot",
|
||||
Usage: "`run as non root` Kubernetes security context option",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
EnvVars: []string{"WOODPECKER_CONNECT_RETRY_COUNT"},
|
||||
Name: "connect-retry-count",
|
||||
|
|
|
@ -55,12 +55,16 @@ type kube struct {
|
|||
}
|
||||
|
||||
type Config struct {
|
||||
Namespace string
|
||||
StorageClass string
|
||||
VolumeSize string
|
||||
StorageRwx bool
|
||||
PodLabels map[string]string
|
||||
PodAnnotations map[string]string
|
||||
Namespace string
|
||||
StorageClass string
|
||||
VolumeSize string
|
||||
StorageRwx bool
|
||||
PodLabels map[string]string
|
||||
PodAnnotations map[string]string
|
||||
SecurityContext SecurityContextConfig
|
||||
}
|
||||
type SecurityContextConfig struct {
|
||||
RunAsNonRoot bool
|
||||
}
|
||||
|
||||
func configFromCliContext(ctx context.Context) (*Config, error) {
|
||||
|
@ -73,6 +77,9 @@ func configFromCliContext(ctx context.Context) (*Config, error) {
|
|||
StorageRwx: c.Bool("backend-k8s-storage-rwx"),
|
||||
PodLabels: make(map[string]string), // just init empty map to prevent nil panic
|
||||
PodAnnotations: make(map[string]string), // just init empty map to prevent nil panic
|
||||
SecurityContext: SecurityContextConfig{
|
||||
RunAsNonRoot: c.Bool("backend-k8s-secctx-nonroot"),
|
||||
},
|
||||
}
|
||||
// Unmarshal label and annotation settings here to ensure they're valid on startup
|
||||
if labels := c.String("backend-k8s-pod-labels"); labels != "" {
|
||||
|
@ -191,7 +198,7 @@ func (e *kube) SetupWorkflow(ctx context.Context, conf *types.Config, taskUUID s
|
|||
|
||||
// Start the pipeline step.
|
||||
func (e *kube) StartStep(ctx context.Context, step *types.Step, taskUUID string) error {
|
||||
pod, err := Pod(e.config.Namespace, step, e.config.PodLabels, e.config.PodAnnotations, e.goos)
|
||||
pod, err := Pod(e.config.Namespace, step, e.config.PodLabels, e.config.PodAnnotations, e.goos, e.config.SecurityContext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import (
|
|||
"go.woodpecker-ci.org/woodpecker/pipeline/backend/types"
|
||||
)
|
||||
|
||||
func Pod(namespace string, step *types.Step, labels, annotations map[string]string, goos string) (*v1.Pod, error) {
|
||||
func Pod(namespace string, step *types.Step, labels, annotations map[string]string, goos string, secCtxConf SecurityContextConfig) (*v1.Pod, error) {
|
||||
var (
|
||||
vols []v1.Volume
|
||||
volMounts []v1.VolumeMount
|
||||
|
@ -142,6 +142,11 @@ func Pod(namespace string, step *types.Step, labels, annotations map[string]stri
|
|||
log.Trace().Msgf("Tolerations that will be used in the backend options: %v", beTolerations)
|
||||
}
|
||||
|
||||
beSecurityContext := step.BackendOptions.Kubernetes.SecurityContext
|
||||
log.Trace().Interface("Security context", beSecurityContext).Msg("Security context that will be used for pods/containers")
|
||||
podSecCtx := podSecurityContext(beSecurityContext, secCtxConf)
|
||||
containerSecCtx := containerSecurityContext(beSecurityContext, step.Privileged)
|
||||
|
||||
pod := &v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: podName,
|
||||
|
@ -155,6 +160,7 @@ func Pod(namespace string, step *types.Step, labels, annotations map[string]stri
|
|||
NodeSelector: nodeSelector,
|
||||
Tolerations: tolerations,
|
||||
ServiceAccountName: serviceAccountName,
|
||||
SecurityContext: podSecCtx,
|
||||
Containers: []v1.Container{{
|
||||
Name: podName,
|
||||
Image: step.Image,
|
||||
|
@ -165,9 +171,7 @@ func Pod(namespace string, step *types.Step, labels, annotations map[string]stri
|
|||
Env: mapToEnvVars(step.Environment),
|
||||
VolumeMounts: volMounts,
|
||||
Resources: resourceRequirements,
|
||||
SecurityContext: &v1.SecurityContext{
|
||||
Privileged: &step.Privileged,
|
||||
},
|
||||
SecurityContext: containerSecCtx,
|
||||
}},
|
||||
ImagePullSecrets: []v1.LocalObjectReference{{Name: "regcred"}},
|
||||
Volumes: vols,
|
||||
|
@ -195,3 +199,55 @@ func volumeMountPath(i string) string {
|
|||
}
|
||||
return s[0]
|
||||
}
|
||||
|
||||
func podSecurityContext(sc *types.SecurityContext, secCtxConf SecurityContextConfig) *v1.PodSecurityContext {
|
||||
var (
|
||||
nonRoot *bool
|
||||
user *int64
|
||||
group *int64
|
||||
fsGroup *int64
|
||||
)
|
||||
|
||||
if sc != nil && sc.RunAsNonRoot != nil {
|
||||
if *sc.RunAsNonRoot {
|
||||
nonRoot = sc.RunAsNonRoot // true
|
||||
}
|
||||
} else if secCtxConf.RunAsNonRoot {
|
||||
nonRoot = &secCtxConf.RunAsNonRoot // true
|
||||
}
|
||||
|
||||
if sc != nil {
|
||||
user = sc.RunAsUser
|
||||
group = sc.RunAsGroup
|
||||
fsGroup = sc.FSGroup
|
||||
}
|
||||
|
||||
if nonRoot == nil && user == nil && group == nil && fsGroup == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &v1.PodSecurityContext{
|
||||
RunAsNonRoot: nonRoot,
|
||||
RunAsUser: user,
|
||||
RunAsGroup: group,
|
||||
FSGroup: fsGroup,
|
||||
}
|
||||
}
|
||||
|
||||
func containerSecurityContext(sc *types.SecurityContext, stepPrivileged bool) *v1.SecurityContext {
|
||||
var privileged *bool
|
||||
|
||||
if sc != nil && sc.Privileged != nil && *sc.Privileged {
|
||||
privileged = sc.Privileged // true
|
||||
} else if stepPrivileged {
|
||||
privileged = &stepPrivileged // true
|
||||
}
|
||||
|
||||
if privileged == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &v1.SecurityContext{
|
||||
Privileged: privileged,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ type KubernetesBackendOptions struct {
|
|||
ServiceAccountName string `json:"serviceAccountName,omitempty"`
|
||||
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
|
||||
Tolerations []Toleration `json:"tolerations,omitempty"`
|
||||
SecurityContext *SecurityContext `json:"securityContext,omitempty"`
|
||||
}
|
||||
|
||||
// Resources defines two maps for kubernetes resource definitions
|
||||
|
@ -51,3 +52,11 @@ const (
|
|||
TolerationOpExists TolerationOperator = "Exists"
|
||||
TolerationOpEqual TolerationOperator = "Equal"
|
||||
)
|
||||
|
||||
type SecurityContext struct {
|
||||
Privileged *bool `json:"privileged,omitempty"`
|
||||
RunAsNonRoot *bool `json:"runAsNonRoot,omitempty"`
|
||||
RunAsUser *int64 `json:"runAsUser,omitempty"`
|
||||
RunAsGroup *int64 `json:"runAsGroup,omitempty"`
|
||||
FSGroup *int64 `json:"fsGroup,omitempty"`
|
||||
}
|
||||
|
|
|
@ -116,28 +116,9 @@ func (c *Compiler) createProcess(name string, container *yaml_types.Container, s
|
|||
}
|
||||
}
|
||||
|
||||
var tolerations []backend_types.Toleration
|
||||
for _, t := range container.BackendOptions.Kubernetes.Tolerations {
|
||||
tolerations = append(tolerations, backend_types.Toleration{
|
||||
Key: t.Key,
|
||||
Operator: backend_types.TolerationOperator(t.Operator),
|
||||
Value: t.Value,
|
||||
Effect: backend_types.TaintEffect(t.Effect),
|
||||
TolerationSeconds: t.TolerationSeconds,
|
||||
})
|
||||
}
|
||||
|
||||
// Kubernetes advanced settings
|
||||
// Advanced backend settings
|
||||
backendOptions := backend_types.BackendOptions{
|
||||
Kubernetes: backend_types.KubernetesBackendOptions{
|
||||
Resources: backend_types.Resources{
|
||||
Limits: container.BackendOptions.Kubernetes.Resources.Limits,
|
||||
Requests: container.BackendOptions.Kubernetes.Resources.Requests,
|
||||
},
|
||||
ServiceAccountName: container.BackendOptions.Kubernetes.ServiceAccountName,
|
||||
NodeSelector: container.BackendOptions.Kubernetes.NodeSelector,
|
||||
Tolerations: tolerations,
|
||||
},
|
||||
Kubernetes: convertKubernetesBackendOptions(&container.BackendOptions.Kubernetes),
|
||||
}
|
||||
|
||||
memSwapLimit := int64(container.MemSwapLimit)
|
||||
|
@ -223,3 +204,40 @@ func (c *Compiler) stepWorkdir(container *yaml_types.Container) string {
|
|||
}
|
||||
return path.Join(c.base, c.path, container.Directory)
|
||||
}
|
||||
|
||||
func convertKubernetesBackendOptions(kubeOpt *yaml_types.KubernetesBackendOptions) backend_types.KubernetesBackendOptions {
|
||||
resources := backend_types.Resources{
|
||||
Limits: kubeOpt.Resources.Limits,
|
||||
Requests: kubeOpt.Resources.Requests,
|
||||
}
|
||||
|
||||
var tolerations []backend_types.Toleration
|
||||
for _, t := range kubeOpt.Tolerations {
|
||||
tolerations = append(tolerations, backend_types.Toleration{
|
||||
Key: t.Key,
|
||||
Operator: backend_types.TolerationOperator(t.Operator),
|
||||
Value: t.Value,
|
||||
Effect: backend_types.TaintEffect(t.Effect),
|
||||
TolerationSeconds: t.TolerationSeconds,
|
||||
})
|
||||
}
|
||||
|
||||
var securityContext *backend_types.SecurityContext
|
||||
if kubeOpt.SecurityContext != nil {
|
||||
securityContext = &backend_types.SecurityContext{
|
||||
Privileged: kubeOpt.SecurityContext.Privileged,
|
||||
RunAsNonRoot: kubeOpt.SecurityContext.RunAsNonRoot,
|
||||
RunAsUser: kubeOpt.SecurityContext.RunAsUser,
|
||||
RunAsGroup: kubeOpt.SecurityContext.RunAsGroup,
|
||||
FSGroup: kubeOpt.SecurityContext.FSGroup,
|
||||
}
|
||||
}
|
||||
|
||||
return backend_types.KubernetesBackendOptions{
|
||||
Resources: resources,
|
||||
ServiceAccountName: kubeOpt.ServiceAccountName,
|
||||
NodeSelector: kubeOpt.NodeSelector,
|
||||
Tolerations: tolerations,
|
||||
SecurityContext: securityContext,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,28 +14,58 @@
|
|||
"variables": {
|
||||
"description": "Use yaml aliases to define variables. Read more: https://woodpecker-ci.org/docs/usage/advanced-yaml-syntax"
|
||||
},
|
||||
"clone": { "$ref": "#/definitions/clone" },
|
||||
"skip_clone": { "type": "boolean" },
|
||||
"branches": { "$ref": "#/definitions/branches" },
|
||||
"when": { "$ref": "#/definitions/pipeline_when" },
|
||||
"steps": { "$ref": "#/definitions/step_list" },
|
||||
"pipeline": { "$ref": "#/definitions/step_list", "description": "deprecated, use steps" },
|
||||
"services": { "$ref": "#/definitions/services" },
|
||||
"workspace": { "$ref": "#/definitions/workspace" },
|
||||
"matrix": { "$ref": "#/definitions/matrix" },
|
||||
"platform": { "$ref": "#/definitions/platform" },
|
||||
"labels": { "$ref": "#/definitions/labels" },
|
||||
"clone": {
|
||||
"$ref": "#/definitions/clone"
|
||||
},
|
||||
"skip_clone": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"branches": {
|
||||
"$ref": "#/definitions/branches"
|
||||
},
|
||||
"when": {
|
||||
"$ref": "#/definitions/pipeline_when"
|
||||
},
|
||||
"steps": {
|
||||
"$ref": "#/definitions/step_list"
|
||||
},
|
||||
"pipeline": {
|
||||
"$ref": "#/definitions/step_list",
|
||||
"description": "deprecated, use steps"
|
||||
},
|
||||
"services": {
|
||||
"$ref": "#/definitions/services"
|
||||
},
|
||||
"workspace": {
|
||||
"$ref": "#/definitions/workspace"
|
||||
},
|
||||
"matrix": {
|
||||
"$ref": "#/definitions/matrix"
|
||||
},
|
||||
"platform": {
|
||||
"$ref": "#/definitions/platform"
|
||||
},
|
||||
"labels": {
|
||||
"$ref": "#/definitions/labels"
|
||||
},
|
||||
"depends_on": {
|
||||
"type": "array",
|
||||
"minLength": 1,
|
||||
"items": { "type": "string" }
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"runs_on": {
|
||||
"type": "array",
|
||||
"minLength": 1,
|
||||
"items": { "type": "string" }
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"version": { "type": "number", "default": 1 }
|
||||
"version": {
|
||||
"type": "number",
|
||||
"default": 1
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"clone": {
|
||||
|
@ -74,20 +104,28 @@
|
|||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minLength": 1
|
||||
},
|
||||
{ "type": "string" }
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"include": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minLength": 1
|
||||
},
|
||||
{ "type": "string" }
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -97,8 +135,20 @@
|
|||
"step_list": {
|
||||
"description": "The steps section defines a list of steps which will be executed serially, in the order in which they are defined. Read more: https://woodpecker-ci.org/docs/usage/pipeline-syntax",
|
||||
"oneOf": [
|
||||
{ "type": "object", "additionalProperties": { "$ref": "#/definitions/step" }, "minProperties": 1 },
|
||||
{ "type": "array", "items": { "$ref": "#/definitions/step" }, "minLength": 1 }
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/step"
|
||||
},
|
||||
"minProperties": 1
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/step"
|
||||
},
|
||||
"minLength": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"pipeline_when": {
|
||||
|
@ -107,7 +157,9 @@
|
|||
{
|
||||
"type": "array",
|
||||
"minLength": 1,
|
||||
"items": { "$ref": "#/definitions/pipeline_when_condition" }
|
||||
"items": {
|
||||
"$ref": "#/definitions/pipeline_when_condition"
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/pipeline_when_condition"
|
||||
|
@ -133,7 +185,9 @@
|
|||
{
|
||||
"type": "array",
|
||||
"minLength": 1,
|
||||
"items": { "$ref": "#/definitions/event_enum" }
|
||||
"items": {
|
||||
"$ref": "#/definitions/event_enum"
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/event_enum"
|
||||
|
@ -163,7 +217,9 @@
|
|||
"path": {
|
||||
"description": "Execute a step only on commit with certain files added/removed/modified. Read more: https://woodpecker-ci.org/docs/usage/pipeline-syntax#path",
|
||||
"oneOf": [
|
||||
{ "type": "string" },
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
@ -264,7 +320,9 @@
|
|||
{
|
||||
"type": "array",
|
||||
"minLength": 1,
|
||||
"items": { "$ref": "#/definitions/step_when_condition" }
|
||||
"items": {
|
||||
"$ref": "#/definitions/step_when_condition"
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/step_when_condition"
|
||||
|
@ -290,7 +348,9 @@
|
|||
{
|
||||
"type": "array",
|
||||
"minLength": 1,
|
||||
"items": { "$ref": "#/definitions/event_enum" }
|
||||
"items": {
|
||||
"$ref": "#/definitions/event_enum"
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/event_enum"
|
||||
|
@ -311,7 +371,10 @@
|
|||
{
|
||||
"type": "array",
|
||||
"minLength": 1,
|
||||
"items": { "type": "string", "enum": ["success", "failure"] }
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": ["success", "failure"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
|
@ -341,7 +404,9 @@
|
|||
"path": {
|
||||
"description": "Execute a step only on commit with certain files added/removed/modified. Read more: https://woodpecker-ci.org/docs/usage/pipeline-syntax#path",
|
||||
"oneOf": [
|
||||
{ "type": "string" },
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
@ -388,7 +453,9 @@
|
|||
{
|
||||
"type": "array",
|
||||
"minLength": 1,
|
||||
"items": { "type": "string" }
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
|
@ -402,7 +469,9 @@
|
|||
{
|
||||
"type": "array",
|
||||
"minLength": 1,
|
||||
"items": { "type": "string" }
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -414,7 +483,9 @@
|
|||
{
|
||||
"type": "array",
|
||||
"minLength": 1,
|
||||
"items": { "type": "string" }
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -440,10 +511,14 @@
|
|||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minLength": 1
|
||||
},
|
||||
{ "type": "string" }
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"step_environment": {
|
||||
|
@ -451,7 +526,9 @@
|
|||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minLength": 1
|
||||
},
|
||||
{
|
||||
|
@ -467,13 +544,19 @@
|
|||
"type": "array",
|
||||
"items": {
|
||||
"oneOf": [
|
||||
{ "type": "string" },
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["source", "target"],
|
||||
"properties": {
|
||||
"source": { "type": "string" },
|
||||
"target": { "type": "string" }
|
||||
"source": {
|
||||
"type": "string"
|
||||
},
|
||||
"target": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -490,7 +573,9 @@
|
|||
"step_volumes": {
|
||||
"description": "Mount files or folders from the host machine into your step container. Read more: https://woodpecker-ci.org/docs/usage/volumes",
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minLength": 1
|
||||
},
|
||||
"step_directory": {
|
||||
|
@ -502,7 +587,7 @@
|
|||
"type": "object",
|
||||
"properties": {
|
||||
"kubernetes": {
|
||||
"$ref": "#/definitions/step_backend_kubernetes_resources"
|
||||
"$ref": "#/definitions/step_backend_kubernetes"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -512,6 +597,9 @@
|
|||
"properties": {
|
||||
"resources": {
|
||||
"$ref": "#/definitions/step_backend_kubernetes_resources"
|
||||
},
|
||||
"securityContext": {
|
||||
"$ref": "#/definitions/step_backend_kubernetes_security_context"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -527,6 +615,27 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"step_backend_kubernetes_security_context": {
|
||||
"description": "Pods / containers security context. Read more: https://woodpecker-ci.org/docs/administration/backends/kubernetes",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"privileged": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"runAsNonRoot": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"runAsUser": {
|
||||
"type": "number"
|
||||
},
|
||||
"runAsGroup": {
|
||||
"type": "number"
|
||||
},
|
||||
"fsGroup": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"step_kubernetes_resources_object": {
|
||||
"description": "A list of kubernetes resource mappings",
|
||||
"type": "object",
|
||||
|
@ -556,7 +665,9 @@
|
|||
"services": {
|
||||
"description": "Read more: https://woodpecker-ci.org/docs/usage/services",
|
||||
"type": "object",
|
||||
"additionalProperties": { "$ref": "#/definitions/service" },
|
||||
"additionalProperties": {
|
||||
"$ref": "#/definitions/service"
|
||||
},
|
||||
"minProperties": 1
|
||||
},
|
||||
"service": {
|
||||
|
@ -597,7 +708,14 @@
|
|||
"description": "expose ports to which other steps can connect to",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"oneOf": [{ "type": "number" }, { "type": "string" }]
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
"minLength": 1
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ type KubernetesBackendOptions struct {
|
|||
ServiceAccountName string `yaml:"serviceAccountName,omitempty"`
|
||||
NodeSelector map[string]string `yaml:"nodeSelector,omitempty"`
|
||||
Tolerations []Toleration `yaml:"tolerations,omitempty"`
|
||||
SecurityContext *SecurityContext `yaml:"securityContext,omitempty"`
|
||||
}
|
||||
|
||||
type Resources struct {
|
||||
|
@ -53,3 +54,11 @@ const (
|
|||
TolerationOpExists TolerationOperator = "Exists"
|
||||
TolerationOpEqual TolerationOperator = "Equal"
|
||||
)
|
||||
|
||||
type SecurityContext struct {
|
||||
Privileged *bool `yaml:"privileged,omitempty"`
|
||||
RunAsNonRoot *bool `yaml:"runAsNonRoot,omitempty"`
|
||||
RunAsUser *int64 `yaml:"runAsUser,omitempty"`
|
||||
RunAsGroup *int64 `yaml:"runAsGroup,omitempty"`
|
||||
FSGroup *int64 `yaml:"fsGroup,omitempty"`
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue