github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/opts/secret.go (about) 1 package opts 2 3 import ( 4 "encoding/csv" 5 "fmt" 6 "os" 7 "path/filepath" 8 "strconv" 9 "strings" 10 11 "github.com/docker/docker/api/types" 12 ) 13 14 // SecretOpt is a Value type for parsing secrets 15 type SecretOpt struct { 16 values []*types.SecretRequestOption 17 } 18 19 // Set a new secret value 20 func (o *SecretOpt) Set(value string) error { 21 csvReader := csv.NewReader(strings.NewReader(value)) 22 fields, err := csvReader.Read() 23 if err != nil { 24 return err 25 } 26 27 options := &types.SecretRequestOption{ 28 Source: "", 29 Target: "", 30 UID: "0", 31 GID: "0", 32 Mode: 0444, 33 } 34 35 // support a simple syntax of --secret foo 36 if len(fields) == 1 { 37 options.Source = fields[0] 38 options.Target = fields[0] 39 o.values = append(o.values, options) 40 return nil 41 } 42 43 for _, field := range fields { 44 parts := strings.SplitN(field, "=", 2) 45 key := strings.ToLower(parts[0]) 46 47 if len(parts) != 2 { 48 return fmt.Errorf("invalid field '%s' must be a key=value pair", field) 49 } 50 51 value := parts[1] 52 switch key { 53 case "source": 54 options.Source = value 55 case "target": 56 tDir, _ := filepath.Split(value) 57 if tDir != "" { 58 return fmt.Errorf("target must not be a path") 59 } 60 options.Target = value 61 case "uid": 62 options.UID = value 63 case "gid": 64 options.GID = value 65 case "mode": 66 m, err := strconv.ParseUint(value, 0, 32) 67 if err != nil { 68 return fmt.Errorf("invalid mode specified: %v", err) 69 } 70 71 options.Mode = os.FileMode(m) 72 default: 73 if len(fields) == 1 && value == "" { 74 75 } else { 76 return fmt.Errorf("invalid field in secret request: %s", key) 77 } 78 } 79 } 80 81 if options.Source == "" { 82 return fmt.Errorf("source is required") 83 } 84 85 o.values = append(o.values, options) 86 return nil 87 } 88 89 // Type returns the type of this option 90 func (o *SecretOpt) Type() string { 91 return "secret" 92 } 93 94 // String returns a string repr of this option 95 func (o *SecretOpt) String() string { 96 secrets := []string{} 97 for _, secret := range o.values { 98 repr := fmt.Sprintf("%s -> %s", secret.Source, secret.Target) 99 secrets = append(secrets, repr) 100 } 101 return strings.Join(secrets, ", ") 102 } 103 104 // Value returns the secret requests 105 func (o *SecretOpt) Value() []*types.SecretRequestOption { 106 return o.values 107 }