secrets: allow providing secrets with env

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
v0.8
Tonis Tiigi 2020-06-16 16:59:28 -07:00
parent 7c9d706a2a
commit 64e64e424d
2 changed files with 45 additions and 9 deletions

View File

@ -35,6 +35,7 @@ func parseSecret(value string) (*secretsprovider.FileSource, error) {
fs := secretsprovider.FileSource{}
var typ string
for _, field := range fields {
parts := strings.SplitN(field, "=", 2)
key := strings.ToLower(parts[0])
@ -46,16 +47,23 @@ func parseSecret(value string) (*secretsprovider.FileSource, error) {
value := parts[1]
switch key {
case "type":
if value != "file" {
if value != "file" && value != "env" {
return nil, errors.Errorf("unsupported secret type %q", value)
}
typ = value
case "id":
fs.ID = value
case "source", "src":
fs.FilePath = value
case "env":
fs.Env = value
default:
return nil, errors.Errorf("unexpected key '%s' in '%s'", key, field)
}
}
if typ == "env" {
fs.Env = fs.FilePath
fs.FilePath = ""
}
return &fs, nil
}

View File

@ -4,6 +4,8 @@ import (
"context"
"io/ioutil"
"os"
"runtime"
"strings"
"github.com/moby/buildkit/session/secrets"
"github.com/pkg/errors"
@ -12,6 +14,7 @@ import (
type FileSource struct {
ID string
FilePath string
Env string
}
func NewFileStore(files []FileSource) (secrets.SecretStore, error) {
@ -20,15 +23,21 @@ func NewFileStore(files []FileSource) (secrets.SecretStore, error) {
if f.ID == "" {
return nil, errors.Errorf("secret missing ID")
}
if f.FilePath == "" {
f.FilePath = f.ID
if f.Env == "" && f.FilePath == "" {
if hasEnv(f.ID) {
f.Env = f.ID
} else {
f.FilePath = f.ID
}
}
fi, err := os.Stat(f.FilePath)
if err != nil {
return nil, errors.Wrapf(err, "failed to stat %s", f.FilePath)
}
if fi.Size() > MaxSecretSize {
return nil, errors.Errorf("secret %s too big. max size 500KB", f.ID)
if f.FilePath != "" {
fi, err := os.Stat(f.FilePath)
if err != nil {
return nil, errors.Wrapf(err, "failed to stat %s", f.FilePath)
}
if fi.Size() > MaxSecretSize {
return nil, errors.Errorf("secret %s too big. max size 500KB", f.ID)
}
}
m[f.ID] = f
}
@ -46,9 +55,28 @@ func (fs *fileStore) GetSecret(ctx context.Context, id string) ([]byte, error) {
if !ok {
return nil, errors.WithStack(secrets.ErrNotFound)
}
if v.Env != "" {
return []byte(os.Getenv(v.Env)), nil
}
dt, err := ioutil.ReadFile(v.FilePath)
if err != nil {
return nil, err
}
return dt, nil
}
func hasEnv(name string) bool {
for _, entry := range os.Environ() {
parts := strings.SplitN(entry, "=", 2)
if runtime.GOOS == "windows" {
// Environment variable are case-insensitive on Windows. PaTh, path and PATH are equivalent.
if strings.EqualFold(parts[0], name) {
return true
}
}
if parts[0] == name {
return true
}
}
return false
}