@@ -2,11 +2,13 @@ package main
2
2
3
3
import (
4
4
"fmt"
5
+ "io/ioutil"
5
6
"os"
6
7
7
8
"cdr.dev/coder-cli/internal/entclient"
8
9
"cdr.dev/coder-cli/internal/x/xtabwriter"
9
10
"cdr.dev/coder-cli/internal/x/xvalidate"
11
+ "github.com/manifoldco/promptui"
10
12
"github.com/spf13/pflag"
11
13
"golang.org/x/xerrors"
12
14
@@ -111,45 +113,79 @@ func (cmd viewSecretsCmd) Run(fl *pflag.FlagSet) {
111
113
}
112
114
113
115
type createSecretCmd struct {
114
- name , value , description string
115
- }
116
-
117
- func (cmd * createSecretCmd ) Validate () (e []error ) {
118
- if cmd .name == "" {
119
- e = append (e , xerrors .New ("--name is a required flag" ))
120
- }
121
- if cmd .value == "" {
122
- e = append (e , xerrors .New ("--value is a required flag" ))
123
- }
124
- return e
116
+ description string
117
+ fromFile string
118
+ fromLiteral string
119
+ fromPrompt bool
125
120
}
126
121
127
122
func (cmd * createSecretCmd ) Spec () cli.CommandSpec {
128
123
return cli.CommandSpec {
129
124
Name : "create" ,
130
- Usage : `--name MYSQL_KEY --value 123456 --description "MySQL credential for database access"` ,
131
- Desc : "insert a new secret" ,
125
+ Usage : `[secret_name] [...flags]` ,
126
+ Desc : "create a new secret" ,
127
+ }
128
+ }
129
+
130
+ func (cmd * createSecretCmd ) Validate (fl * pflag.FlagSet ) (e []error ) {
131
+ if cmd .fromPrompt && (cmd .fromLiteral != "" || cmd .fromFile != "" ) {
132
+ e = append (e , xerrors .Errorf ("--from-prompt cannot be set along with --from-file or --from-literal" ))
132
133
}
134
+ if cmd .fromLiteral != "" && cmd .fromFile != "" {
135
+ e = append (e , xerrors .Errorf ("--from-literal and --from-file cannot both be set" ))
136
+ }
137
+ if ! cmd .fromPrompt && cmd .fromFile == "" && cmd .fromLiteral == "" {
138
+ e = append (e , xerrors .Errorf ("one of [--from-literal, --from-file, --from-prompt] is required" ))
139
+ }
140
+ return e
133
141
}
134
142
135
143
func (cmd * createSecretCmd ) Run (fl * pflag.FlagSet ) {
136
144
var (
137
145
client = requireAuth ()
146
+ name = fl .Arg (0 )
147
+ value string
148
+ err error
138
149
)
139
- xvalidate .Validate (cmd )
150
+ if name == "" {
151
+ exitUsage (fl )
152
+ }
153
+ xvalidate .Validate (fl , cmd )
154
+
155
+ if cmd .fromLiteral != "" {
156
+ value = cmd .fromLiteral
157
+ } else if cmd .fromFile != "" {
158
+ contents , err := ioutil .ReadFile (cmd .fromFile )
159
+ requireSuccess (err , "failed to read file: %v" , err )
160
+ value = string (contents )
161
+ } else {
162
+ prompt := promptui.Prompt {
163
+ Label : "value" ,
164
+ Mask : '*' ,
165
+ Validate : func (s string ) error {
166
+ if len (s ) < 1 {
167
+ return xerrors .Errorf ("a length > 0 is required" )
168
+ }
169
+ return nil
170
+ },
171
+ }
172
+ value , err = prompt .Run ()
173
+ requireSuccess (err , "failed to prompt for value: %v" , err )
174
+ }
140
175
141
- err : = client .InsertSecret (entclient.InsertSecretReq {
142
- Name : cmd . name ,
143
- Value : cmd . value ,
176
+ err = client .InsertSecret (entclient.InsertSecretReq {
177
+ Name : name ,
178
+ Value : value ,
144
179
Description : cmd .description ,
145
180
})
146
181
requireSuccess (err , "failed to insert secret: %v" , err )
147
182
}
148
183
149
184
func (cmd * createSecretCmd ) RegisterFlags (fl * pflag.FlagSet ) {
150
- fl .StringVar (& cmd .name , "name" , "" , "the name of the secret" )
151
- fl .StringVar (& cmd .value , "value" , "" , "the value of the secret" )
152
- fl .StringVar (& cmd .description , "description" , "" , "a description of the secret" )
185
+ fl .StringVar (& cmd .fromFile , "from-file" , "" , "specify a file from which to read the value of the secret" )
186
+ fl .StringVar (& cmd .fromLiteral , "from-literal" , "" , "specify the value of the secret" )
187
+ fl .BoolVar (& cmd .fromPrompt , "from-prompt" , false , "specify the value of the secret through a prompt" )
188
+ fl .StringVar (& cmd .description , "description" , "" , "specify a description of the secret" )
153
189
}
154
190
155
191
type deleteSecretsCmd struct {}
0 commit comments