Support plugin-only secrets (#1344)

Closes #1071
This commit is contained in:
qwerty287
2022-10-27 04:21:07 +02:00
committed by GitHub
parent 9ece7a1c49
commit e568c42e84
17 changed files with 154 additions and 50 deletions

View File

@@ -35,9 +35,14 @@ type Registry struct {
}
type Secret struct {
Name string
Value string
Match []string
Name string
Value string
Match []string
PluginOnly bool
}
func (s *Secret) Available(container *yaml.Container) bool {
return (len(s.Match) == 0 || matchImage(container.Image, s.Match...)) && (!s.PluginOnly || container.IsPlugin())
}
type secretMap map[string]Secret

View File

@@ -0,0 +1,42 @@
package compiler
import (
"testing"
"github.com/docker/docker/api/types/strslice"
"github.com/stretchr/testify/assert"
"github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml"
"github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml/types"
)
func TestSecretAvailable(t *testing.T) {
secret := Secret{
Match: []string{"golang"},
PluginOnly: false,
}
assert.True(t, secret.Available(&yaml.Container{
Image: "golang",
Commands: types.Stringorslice(strslice.StrSlice{"echo 'this is not a plugin'"}),
}))
assert.False(t, secret.Available(&yaml.Container{
Image: "not-golang",
Commands: types.Stringorslice(strslice.StrSlice{"echo 'this is not a plugin'"}),
}))
// secret only available for "golang" plugin
secret = Secret{
Match: []string{"golang"},
PluginOnly: true,
}
assert.True(t, secret.Available(&yaml.Container{
Image: "golang",
Commands: types.Stringorslice(strslice.StrSlice{}),
}))
assert.False(t, secret.Available(&yaml.Container{
Image: "not-golang",
Commands: types.Stringorslice(strslice.StrSlice{}),
}))
assert.False(t, secret.Available(&yaml.Container{
Image: "not-golang",
Commands: types.Stringorslice(strslice.StrSlice{"echo 'this is not a plugin'"}),
}))
}

View File

@@ -73,7 +73,14 @@ func (c *Compiler) createProcess(name string, container *yaml.Container, section
}
if !detached {
if err := settings.ParamsToEnv(container.Settings, environment, c.secrets.toStringMap()); err != nil {
pluginSecrets := secretMap{}
for name, secret := range c.secrets {
if secret.Available(container) {
pluginSecrets[name] = secret
}
}
if err := settings.ParamsToEnv(container.Settings, environment, pluginSecrets.toStringMap()); err != nil {
log.Error().Err(err).Msg("paramsToEnv")
}
}
@@ -116,7 +123,7 @@ func (c *Compiler) createProcess(name string, container *yaml.Container, section
for _, requested := range container.Secrets.Secrets {
secret, ok := c.secrets[strings.ToLower(requested.Source)]
if ok && (len(secret.Match) == 0 || matchImage(container.Image, secret.Match...)) {
if ok && secret.Available(container) {
environment[strings.ToUpper(requested.Target)] = secret.Value
}
}

View File

@@ -111,3 +111,7 @@ func (c *Containers) UnmarshalYAML(value *yaml.Node) error {
return nil
}
func (c *Container) IsPlugin() bool {
return len(c.Commands) == 0 && len(c.Command) == 0
}

View File

@@ -3,6 +3,7 @@ package yaml
import (
"testing"
"github.com/docker/docker/api/types/strslice"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
@@ -301,3 +302,13 @@ func stringsToInterface(val ...string) []interface{} {
}
return res
}
func TestIsPlugin(t *testing.T) {
assert.True(t, (&Container{}).IsPlugin())
assert.True(t, (&Container{
Commands: types.Stringorslice(strslice.StrSlice{}),
}).IsPlugin())
assert.False(t, (&Container{
Commands: types.Stringorslice(strslice.StrSlice{"echo 'this is not a plugin'"}),
}).IsPlugin())
}