mirror of
https://github.com/openfaas/faas.git
synced 2025-06-17 12:46:59 +00:00
**What** - Add the ability to specify secrets as a csv - Vendor the docker/cli/opts - Update the guide for secrets to use the `faas-cli` **Why** - Allowing the csv specification of secrets gives users more control about how those secrets are mounted into the container. This is good for things like key rotation and for developers that are building on top of OpenFaaS. Signed-off-by: Lucas Roesler <lucas.roesler@gmail.com>
99 lines
2.0 KiB
Go
99 lines
2.0 KiB
Go
package opts
|
|
|
|
import (
|
|
"encoding/csv"
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
|
|
swarmtypes "github.com/docker/docker/api/types/swarm"
|
|
)
|
|
|
|
// SecretOpt is a Value type for parsing secrets
|
|
type SecretOpt struct {
|
|
values []*swarmtypes.SecretReference
|
|
}
|
|
|
|
// Set a new secret value
|
|
func (o *SecretOpt) Set(value string) error {
|
|
csvReader := csv.NewReader(strings.NewReader(value))
|
|
fields, err := csvReader.Read()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
options := &swarmtypes.SecretReference{
|
|
File: &swarmtypes.SecretReferenceFileTarget{
|
|
UID: "0",
|
|
GID: "0",
|
|
Mode: 0444,
|
|
},
|
|
}
|
|
|
|
// support a simple syntax of --secret foo
|
|
if len(fields) == 1 {
|
|
options.File.Name = fields[0]
|
|
options.SecretName = fields[0]
|
|
o.values = append(o.values, options)
|
|
return nil
|
|
}
|
|
|
|
for _, field := range fields {
|
|
parts := strings.SplitN(field, "=", 2)
|
|
key := strings.ToLower(parts[0])
|
|
|
|
if len(parts) != 2 {
|
|
return fmt.Errorf("invalid field '%s' must be a key=value pair", field)
|
|
}
|
|
|
|
value := parts[1]
|
|
switch key {
|
|
case "source", "src":
|
|
options.SecretName = value
|
|
case "target":
|
|
options.File.Name = value
|
|
case "uid":
|
|
options.File.UID = value
|
|
case "gid":
|
|
options.File.GID = value
|
|
case "mode":
|
|
m, err := strconv.ParseUint(value, 0, 32)
|
|
if err != nil {
|
|
return fmt.Errorf("invalid mode specified: %v", err)
|
|
}
|
|
|
|
options.File.Mode = os.FileMode(m)
|
|
default:
|
|
return fmt.Errorf("invalid field in secret request: %s", key)
|
|
}
|
|
}
|
|
|
|
if options.SecretName == "" {
|
|
return fmt.Errorf("source is required")
|
|
}
|
|
|
|
o.values = append(o.values, options)
|
|
return nil
|
|
}
|
|
|
|
// Type returns the type of this option
|
|
func (o *SecretOpt) Type() string {
|
|
return "secret"
|
|
}
|
|
|
|
// String returns a string repr of this option
|
|
func (o *SecretOpt) String() string {
|
|
secrets := []string{}
|
|
for _, secret := range o.values {
|
|
repr := fmt.Sprintf("%s -> %s", secret.SecretName, secret.File.Name)
|
|
secrets = append(secrets, repr)
|
|
}
|
|
return strings.Join(secrets, ", ")
|
|
}
|
|
|
|
// Value returns the secret requests
|
|
func (o *SecretOpt) Value() []*swarmtypes.SecretReference {
|
|
return o.values
|
|
}
|