mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2024-06-16 12:20:45 +00:00
K8s secrets reference from step
This commit is contained in:
parent
2d66cfcce2
commit
f33488c80f
|
@ -14,6 +14,7 @@ type BackendOptions struct {
|
|||
NodeSelector map[string]string `mapstructure:"nodeSelector"`
|
||||
Tolerations []Toleration `mapstructure:"tolerations"`
|
||||
SecurityContext *SecurityContext `mapstructure:"securityContext"`
|
||||
SecretNames []string `mapstructure:"secretNames"`
|
||||
}
|
||||
|
||||
// Resources defines two maps for kubernetes resource definitions
|
||||
|
|
|
@ -42,6 +42,9 @@ func Test_parseBackendOptions(t *testing.T) {
|
|||
"localhostProfile": "k8s-apparmor-example-deny-write",
|
||||
},
|
||||
},
|
||||
"secretNames": []string{
|
||||
"test-secret",
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@ -69,5 +72,8 @@ func Test_parseBackendOptions(t *testing.T) {
|
|||
LocalhostProfile: "k8s-apparmor-example-deny-write",
|
||||
},
|
||||
},
|
||||
SecretNames: []string{
|
||||
"test-secret",
|
||||
},
|
||||
}, got)
|
||||
}
|
||||
|
|
|
@ -66,4 +66,10 @@ var Flags = []cli.Flag{
|
|||
Usage: "backend k8s pull secret names for private registries",
|
||||
Value: cli.NewStringSlice("regcred"),
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
EnvVars: []string{"WOODPECKER_BACKEND_K8S_NATIVE_SECRETS_ALLOW_FROM_STEP"},
|
||||
Name: "backend-k8s-native-secrets-allow-from-step",
|
||||
Usage: "whether to allow existing Kubernetes secrets to be referenced from step",
|
||||
Value: false,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -55,14 +55,15 @@ type kube struct {
|
|||
}
|
||||
|
||||
type config struct {
|
||||
Namespace string
|
||||
StorageClass string
|
||||
VolumeSize string
|
||||
StorageRwx bool
|
||||
PodLabels map[string]string
|
||||
PodAnnotations map[string]string
|
||||
ImagePullSecretNames []string
|
||||
SecurityContext SecurityContextConfig
|
||||
Namespace string
|
||||
StorageClass string
|
||||
VolumeSize string
|
||||
StorageRwx bool
|
||||
PodLabels map[string]string
|
||||
PodAnnotations map[string]string
|
||||
ImagePullSecretNames []string
|
||||
SecurityContext SecurityContextConfig
|
||||
NativeSecretsAllowFromStep bool
|
||||
}
|
||||
type SecurityContextConfig struct {
|
||||
RunAsNonRoot bool
|
||||
|
@ -92,6 +93,7 @@ func configFromCliContext(ctx context.Context) (*config, error) {
|
|||
SecurityContext: SecurityContextConfig{
|
||||
RunAsNonRoot: c.Bool("backend-k8s-secctx-nonroot"),
|
||||
},
|
||||
NativeSecretsAllowFromStep: c.Bool("backend-k8s-native-secrets-allow-from-step"),
|
||||
}
|
||||
// TODO: remove in next major
|
||||
if len(config.ImagePullSecretNames) == 1 && config.ImagePullSecretNames[0] == "regcred" {
|
||||
|
|
|
@ -48,7 +48,7 @@ func mkPod(step *types.Step, config *config, podName, goos string, options Backe
|
|||
return nil, err
|
||||
}
|
||||
|
||||
container, err := podContainer(step, podName, goos, options)
|
||||
container, err := podContainer(step, config, podName, goos, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ func podSpec(step *types.Step, config *config, options BackendOptions) (v1.PodSp
|
|||
return spec, nil
|
||||
}
|
||||
|
||||
func podContainer(step *types.Step, podName, goos string, options BackendOptions) (v1.Container, error) {
|
||||
func podContainer(step *types.Step, config *config, podName, goos string, options BackendOptions) (v1.Container, error) {
|
||||
var err error
|
||||
container := v1.Container{
|
||||
Name: podName,
|
||||
|
@ -159,6 +159,14 @@ func podContainer(step *types.Step, podName, goos string, options BackendOptions
|
|||
|
||||
container.Env = mapToEnvVars(step.Environment)
|
||||
|
||||
if len(options.SecretNames) > 0 {
|
||||
if config.NativeSecretsAllowFromStep {
|
||||
container.EnvFrom = containerSecrets(options.SecretNames)
|
||||
} else {
|
||||
log.Debug().Msg("Secret names were defined in backend options, but its using disallowed by instance configuration ")
|
||||
}
|
||||
}
|
||||
|
||||
container.Resources, err = resourceRequirements(options.Resources)
|
||||
if err != nil {
|
||||
return container, err
|
||||
|
@ -236,6 +244,25 @@ func containerPort(port types.Port) v1.ContainerPort {
|
|||
}
|
||||
}
|
||||
|
||||
func containerSecrets(secretNames []string) []v1.EnvFromSource {
|
||||
if secretNames == nil || len(secretNames) == 0 {
|
||||
return nil
|
||||
}
|
||||
secretRefs := make([]v1.EnvFromSource, len(secretNames))
|
||||
for i, secretName := range secretNames {
|
||||
secretRefs[i] = containerSecret(secretName)
|
||||
}
|
||||
return secretRefs
|
||||
}
|
||||
|
||||
func containerSecret(secretName string) v1.EnvFromSource {
|
||||
return v1.EnvFromSource{
|
||||
SecretRef: &v1.SecretEnvSource{
|
||||
LocalObjectReference: secretReference(secretName),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Here is the service IPs (placed in /etc/hosts in the Pod)
|
||||
func hostAliases(extraHosts []types.HostAlias) []v1.HostAlias {
|
||||
var hostAliases []v1.HostAlias
|
||||
|
@ -258,14 +285,14 @@ func imagePullSecretsReferences(imagePullSecretNames []string) []v1.LocalObjectR
|
|||
|
||||
secretReferences := make([]v1.LocalObjectReference, len(imagePullSecretNames))
|
||||
for i, imagePullSecretName := range imagePullSecretNames {
|
||||
secretReferences[i] = imagePullSecretsReference(imagePullSecretName)
|
||||
secretReferences[i] = secretReference(imagePullSecretName)
|
||||
}
|
||||
return secretReferences
|
||||
}
|
||||
|
||||
func imagePullSecretsReference(imagePullSecretName string) v1.LocalObjectReference {
|
||||
func secretReference(secretName string) v1.LocalObjectReference {
|
||||
return v1.LocalObjectReference{
|
||||
Name: imagePullSecretName,
|
||||
Name: secretName,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -200,6 +200,19 @@ func TestFullPod(t *testing.T) {
|
|||
"protocol": "UDP"
|
||||
}
|
||||
],
|
||||
"envFrom": [
|
||||
"<<UNORDERED>>",
|
||||
{
|
||||
"secretRef": {
|
||||
"name": "ghcr-push-secret"
|
||||
}
|
||||
},
|
||||
{
|
||||
"secretRef": {
|
||||
"name": "aws-ecr"
|
||||
}
|
||||
}
|
||||
],
|
||||
"env": [
|
||||
"<<UNORDERED>>",
|
||||
{
|
||||
|
@ -328,11 +341,12 @@ func TestFullPod(t *testing.T) {
|
|||
ExtraHosts: hostAliases,
|
||||
Ports: ports,
|
||||
}, &config{
|
||||
Namespace: "woodpecker",
|
||||
ImagePullSecretNames: []string{"regcred", "another-pull-secret"},
|
||||
PodLabels: map[string]string{"app": "test"},
|
||||
PodAnnotations: map[string]string{"apps.kubernetes.io/pod-index": "0"},
|
||||
SecurityContext: SecurityContextConfig{RunAsNonRoot: false},
|
||||
Namespace: "woodpecker",
|
||||
ImagePullSecretNames: []string{"regcred", "another-pull-secret"},
|
||||
PodLabels: map[string]string{"app": "test"},
|
||||
PodAnnotations: map[string]string{"apps.kubernetes.io/pod-index": "0"},
|
||||
SecurityContext: SecurityContextConfig{RunAsNonRoot: false},
|
||||
NativeSecretsAllowFromStep: true,
|
||||
}, "wp-01he8bebctabr3kgk0qj36d2me-0", "linux/amd64", BackendOptions{
|
||||
NodeSelector: map[string]string{"storage": "ssd"},
|
||||
RuntimeClassName: &runtimeClass,
|
||||
|
@ -343,6 +357,7 @@ func TestFullPod(t *testing.T) {
|
|||
Limits: map[string]string{"memory": "256Mi", "cpu": "2"},
|
||||
},
|
||||
SecurityContext: &secCtx,
|
||||
SecretNames: []string{"ghcr-push-secret", "aws-ecr"},
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
|
|
@ -700,6 +700,12 @@
|
|||
"runtimeClassName": {
|
||||
"description": "Read more: https://woodpecker-ci.org/docs/administration/backends/kubernetes#runtimeclassname",
|
||||
"type": "string"
|
||||
},
|
||||
"secretNames": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue