...
1 package opts
2
3 import (
4 "encoding/csv"
5 "fmt"
6 "os"
7 "strconv"
8 "strings"
9
10 swarmtypes "github.com/docker/docker/api/types/swarm"
11 )
12
13
14 type SecretOpt struct {
15 values []*swarmtypes.SecretReference
16 }
17
18
19 func (o *SecretOpt) Set(value string) error {
20 csvReader := csv.NewReader(strings.NewReader(value))
21 fields, err := csvReader.Read()
22 if err != nil {
23 return err
24 }
25
26 options := &swarmtypes.SecretReference{
27 File: &swarmtypes.SecretReferenceFileTarget{
28 UID: "0",
29 GID: "0",
30 Mode: 0o444,
31 },
32 }
33
34
35 if len(fields) == 1 && !strings.Contains(fields[0], "=") {
36 options.File.Name = fields[0]
37 options.SecretName = fields[0]
38 o.values = append(o.values, options)
39 return nil
40 }
41
42 for _, field := range fields {
43 key, val, ok := strings.Cut(field, "=")
44 if !ok || key == "" {
45 return fmt.Errorf("invalid field '%s' must be a key=value pair", field)
46 }
47
48 switch strings.ToLower(key) {
49 case "source", "src":
50 options.SecretName = val
51 case "target":
52 options.File.Name = val
53 case "uid":
54 options.File.UID = val
55 case "gid":
56 options.File.GID = val
57 case "mode":
58 m, err := strconv.ParseUint(val, 0, 32)
59 if err != nil {
60 return fmt.Errorf("invalid mode specified: %v", err)
61 }
62
63 options.File.Mode = os.FileMode(m)
64 default:
65 return fmt.Errorf("invalid field in secret request: %s", key)
66 }
67 }
68
69 if options.SecretName == "" {
70 return fmt.Errorf("source is required")
71 }
72 if options.File.Name == "" {
73 options.File.Name = options.SecretName
74 }
75
76 o.values = append(o.values, options)
77 return nil
78 }
79
80
81 func (o *SecretOpt) Type() string {
82 return "secret"
83 }
84
85
86 func (o *SecretOpt) String() string {
87 secrets := []string{}
88 for _, secret := range o.values {
89 repr := fmt.Sprintf("%s -> %s", secret.SecretName, secret.File.Name)
90 secrets = append(secrets, repr)
91 }
92 return strings.Join(secrets, ", ")
93 }
94
95
96 func (o *SecretOpt) Value() []*swarmtypes.SecretReference {
97 return o.values
98 }
99
View as plain text