Add secrets and plugin settings
This commit is contained in:
parent
0a65c9a464
commit
6c871d13d1
23
core/map.go
23
core/map.go
|
@ -5,19 +5,32 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ValueOrSecret struct {
|
||||
Value string
|
||||
Secret string
|
||||
}
|
||||
|
||||
// MapOrEnvArray represents a map or an array of strings as environment variables.
|
||||
type MapOrEnvArray map[string]string
|
||||
type MapOrEnvArray map[string]ValueOrSecret
|
||||
|
||||
// UnmarshalYAML implements the Unmarshaler interface.
|
||||
func (m *MapOrEnvArray) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
mv := make(MapOrEnvArray)
|
||||
t := make(map[string]string)
|
||||
t := make(map[string]interface{})
|
||||
if err := unmarshal(&t); err == nil {
|
||||
for k, v := range t {
|
||||
mv[k] = v
|
||||
switch vv := v.(type) {
|
||||
case map[string]interface{}:
|
||||
if val, ok := vv["from_secret"]; ok {
|
||||
mv[k] = ValueOrSecret{Secret: fmt.Sprintf("%v", val)}
|
||||
}
|
||||
default:
|
||||
mv[k] = ValueOrSecret{Value: fmt.Sprintf("%v", vv)}
|
||||
}
|
||||
}
|
||||
*m = mv
|
||||
return nil
|
||||
|
@ -31,7 +44,7 @@ func (m *MapOrEnvArray) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||
if !ok {
|
||||
continue
|
||||
}
|
||||
mv[k] = v
|
||||
mv[k] = ValueOrSecret{Value: v}
|
||||
}
|
||||
*m = mv
|
||||
return nil
|
||||
|
@ -41,7 +54,7 @@ func (m *MapOrEnvArray) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||
func (m MapOrEnvArray) MarshalYAML() (interface{}, error) {
|
||||
arr := make([]string, 0)
|
||||
for k, v := range m {
|
||||
arr = append(arr, k+"="+v)
|
||||
arr = append(arr, k+"="+v.Value)
|
||||
}
|
||||
return arr, nil
|
||||
}
|
||||
|
|
|
@ -15,11 +15,11 @@ func TestMapUnmarshal(t *testing.T) {
|
|||
v := &struct {
|
||||
Environment MapOrEnvArray `yaml:"environment"`
|
||||
}{}
|
||||
err := yaml.Unmarshal([]byte("environment:\n FOO: bar\n BAZ: qux\n"), v)
|
||||
err := yaml.Unmarshal([]byte("environment:\n FOO:\n from_secret: bar\n BAZ: 2\n"), v)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, MapOrEnvArray{
|
||||
"FOO": "bar",
|
||||
"BAZ": "qux",
|
||||
"FOO": ValueOrSecret{Secret: "bar"},
|
||||
"BAZ": ValueOrSecret{Value: "2"},
|
||||
}, v.Environment)
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ func TestArrayUnmarshal(t *testing.T) {
|
|||
err := yaml.Unmarshal([]byte("environment:\n- FOO=bar\n- BAZ=qux\n"), v)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, MapOrEnvArray{
|
||||
"FOO": "bar",
|
||||
"BAZ": "qux",
|
||||
"FOO": ValueOrSecret{Value: "bar"},
|
||||
"BAZ": ValueOrSecret{Value: "qux"},
|
||||
}, v.Environment)
|
||||
}
|
||||
|
|
|
@ -183,7 +183,20 @@ func (d DronePipeline) Convert(pipeline *Pipeline) (*transform.Pipeline, error)
|
|||
for _, step := range pipeline.Steps {
|
||||
env := make([]string, 0, len(step.Environment))
|
||||
for k, v := range step.Environment {
|
||||
env = append(env, k+"="+v)
|
||||
if v.Secret != "" {
|
||||
continue
|
||||
}
|
||||
env = append(env, k+"="+v.Value)
|
||||
}
|
||||
secrets := make(transform.Secrets, 0)
|
||||
for k, v := range step.Environment {
|
||||
if v.Secret == "" {
|
||||
continue
|
||||
}
|
||||
secrets = append(secrets, transform.Secret{
|
||||
Target: k,
|
||||
Source: v.Secret,
|
||||
})
|
||||
}
|
||||
when, err := d.ConvertConditions(step.When)
|
||||
if err != nil {
|
||||
|
@ -194,6 +207,8 @@ func (d DronePipeline) Convert(pipeline *Pipeline) (*transform.Pipeline, error)
|
|||
Image: d.ConvertImage(step.Image),
|
||||
Pull: step.Pull == "always",
|
||||
Environment: env,
|
||||
Secrets: secrets,
|
||||
Settings: step.Settings,
|
||||
Commands: step.Commands,
|
||||
When: when,
|
||||
DependsOn: step.DependsOn,
|
||||
|
|
|
@ -42,7 +42,7 @@ func TestTransformSimple(t *testing.T) {
|
|||
pipeline := getPipelineByName(pipelines, "build")
|
||||
require.NotNil(t, pipeline, "build pipeline not found")
|
||||
|
||||
require.Len(t, pipeline.Steps, 2)
|
||||
require.Len(t, pipeline.Steps, 3)
|
||||
assert.Equal(t, "test", pipeline.Steps[0].Name)
|
||||
assert.Equal(t, "golang:1.18", pipeline.Steps[0].Image)
|
||||
assert.ElementsMatch(t, []string{"CGO=0"}, pipeline.Steps[0].Environment)
|
||||
|
@ -62,6 +62,20 @@ func TestTransformSimple(t *testing.T) {
|
|||
assert.Nil(t, pipeline.Steps[1].When)
|
||||
assert.ElementsMatch(t, []string{"test"}, pipeline.Steps[1].DependsOn)
|
||||
|
||||
assert.Equal(t, "docker", pipeline.Steps[2].Name)
|
||||
assert.Equal(t, "plugin/docker", pipeline.Steps[2].Image)
|
||||
assert.False(t, pipeline.Steps[2].Pull)
|
||||
assert.ElementsMatch(t, []string{"build"}, pipeline.Steps[2].DependsOn)
|
||||
assert.ElementsMatch(t, transform.Settings{
|
||||
{Name: "repo", Value: "org/simple"},
|
||||
{Name: "username", Value: map[string]interface{}{
|
||||
"from_secret": "docker_username",
|
||||
}},
|
||||
{Name: "password", Value: map[string]interface{}{
|
||||
"from_secret": "docker_password",
|
||||
}},
|
||||
}, pipeline.Steps[2].Settings)
|
||||
|
||||
assert.Len(t, pipeline.DependsOn, 0)
|
||||
|
||||
pipeline = getPipelineByName(pipelines, "deploy")
|
||||
|
@ -72,6 +86,7 @@ func TestTransformSimple(t *testing.T) {
|
|||
assert.Equal(t, "alpine:latest", pipeline.Steps[0].Image)
|
||||
assert.False(t, pipeline.Steps[0].Pull)
|
||||
assert.Len(t, pipeline.Steps[0].Commands, 1)
|
||||
assert.ElementsMatch(t, transform.Secrets{{Target: "PASSWORD", Source: "password"}}, pipeline.Steps[0].Secrets)
|
||||
require.NotNil(t, pipeline.Steps[0].When)
|
||||
assert.ElementsMatch(t, []string{"success", "failure"}, pipeline.Steps[0].When.Status)
|
||||
assert.ElementsMatch(t, []string{"tag"}, pipeline.Steps[0].When.Event)
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
package drone
|
||||
|
||||
import (
|
||||
transform "codeberg.org/lafriks/woodpecker-pipeline-transform"
|
||||
"codeberg.org/lafriks/woodpecker-pipeline-transform/core"
|
||||
)
|
||||
|
||||
|
@ -24,6 +25,7 @@ type Step struct {
|
|||
Image string `yaml:"image"`
|
||||
Pull string `yaml:"pull"`
|
||||
Environment core.MapOrEnvArray `yaml:"environment"`
|
||||
Settings transform.Settings `yaml:"settings,omitempty"`
|
||||
Commands []string `yaml:"commands"`
|
||||
DependsOn []string `yaml:"depends_on"`
|
||||
When *StepWhen `yaml:"when"`
|
||||
|
|
|
@ -31,6 +31,17 @@ steps:
|
|||
depends_on:
|
||||
- test
|
||||
|
||||
- name: docker
|
||||
image: plugin/docker
|
||||
settings:
|
||||
repo: org/simple
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
||||
depends_on:
|
||||
- build
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
|
@ -47,6 +58,9 @@ steps:
|
|||
- name: deploy
|
||||
image: alpine:latest
|
||||
pull: if-not-exists
|
||||
environment:
|
||||
PASSWORD:
|
||||
from_secret: password
|
||||
commands:
|
||||
- echo "Deploy"
|
||||
when:
|
||||
|
|
|
@ -45,7 +45,9 @@ type Step struct {
|
|||
Image string `yaml:"image"`
|
||||
Pull bool `yaml:"pull,omitempty"`
|
||||
Environment []string `yaml:"environment,omitempty"`
|
||||
Secrets Secrets `yaml:"secrets,omitempty"`
|
||||
Commands []string `yaml:"commands,omitempty"`
|
||||
Settings Settings `yaml:"settings,omitempty"`
|
||||
When *StepWhen `yaml:"when,omitempty"`
|
||||
DependsOn []string `yaml:"depends_on,omitempty"`
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2022 Lauris BH. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package transform
|
||||
|
||||
import "strings"
|
||||
|
||||
type Secret struct {
|
||||
Source string `yaml:"source"`
|
||||
Target string `yaml:"target"`
|
||||
}
|
||||
|
||||
type Secrets []Secret
|
||||
|
||||
func (s Secrets) MarshalYAML() (interface{}, error) {
|
||||
arr := make([]interface{}, 0, len(s))
|
||||
for _, secret := range s {
|
||||
if secret.Target == "" || strings.ToLower(secret.Source) == strings.ToLower(secret.Target) {
|
||||
arr = append(arr, Secret{
|
||||
Source: secret.Source,
|
||||
Target: strings.ToLower(secret.Target),
|
||||
})
|
||||
} else {
|
||||
arr = append(arr, secret)
|
||||
}
|
||||
}
|
||||
return arr, nil
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
// Copyright 2022 Lauris BH. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package transform
|
||||
|
||||
import (
|
||||
"github.com/goccy/go-yaml"
|
||||
)
|
||||
|
||||
type Setting struct {
|
||||
Name string
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
type Settings []Setting
|
||||
|
||||
func (s Settings) MarshalYAML() (interface{}, error) {
|
||||
v := make(yaml.MapSlice, len(s))
|
||||
for i, setting := range s {
|
||||
v[i] = yaml.MapItem{
|
||||
Key: setting.Name,
|
||||
Value: setting.Value,
|
||||
}
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func (s *Settings) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
||||
var v yaml.MapSlice
|
||||
if err := unmarshal(&v); err != nil {
|
||||
return err
|
||||
}
|
||||
val := make(Settings, 0, len(v))
|
||||
for _, item := range v {
|
||||
val = append(val, Setting{
|
||||
Name: item.Key.(string),
|
||||
Value: item.Value,
|
||||
})
|
||||
}
|
||||
*s = val
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue