opts/secret.go
c0013874
 package opts
 
 import (
 	"encoding/csv"
 	"fmt"
 	"os"
 	"path/filepath"
 	"strconv"
 	"strings"
 
 	"github.com/docker/docker/api/types"
 )
 
 // SecretOpt is a Value type for parsing secrets
 type SecretOpt struct {
5b2230a3
 	values []*types.SecretRequestOption
c0013874
 }
 
 // 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
 	}
 
5b2230a3
 	options := &types.SecretRequestOption{
c0013874
 		Source: "",
 		Target: "",
 		UID:    "0",
 		GID:    "0",
 		Mode:   0444,
 	}
 
a257f674
 	// support a simple syntax of --secret foo
 	if len(fields) == 1 {
 		options.Source = fields[0]
 		options.Target = fields[0]
 		o.values = append(o.values, options)
 		return nil
 	}
 
c0013874
 	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":
 			options.Source = value
 		case "target":
 			tDir, _ := filepath.Split(value)
 			if tDir != "" {
 				return fmt.Errorf("target must not be a path")
 			}
 			options.Target = value
 		case "uid":
 			options.UID = value
 		case "gid":
 			options.GID = value
 		case "mode":
 			m, err := strconv.ParseUint(value, 0, 32)
 			if err != nil {
 				return fmt.Errorf("invalid mode specified: %v", err)
 			}
 
 			options.Mode = os.FileMode(m)
 		default:
a257f674
 			if len(fields) == 1 && value == "" {
 
 			} else {
 				return fmt.Errorf("invalid field in secret request: %s", key)
 			}
c0013874
 		}
 	}
 
 	if options.Source == "" {
 		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.Source, secret.Target)
 		secrets = append(secrets, repr)
 	}
 	return strings.Join(secrets, ", ")
 }
 
 // Value returns the secret requests
5b2230a3
 func (o *SecretOpt) Value() []*types.SecretRequestOption {
c0013874
 	return o.values
 }