Skip to content

Commit 247866e

Browse files
committed
Add prompt on change when delete or update action
As more and more production system uses openwhisk, Users will need some feature to protect their action to be deleted or updated by mistake.
1 parent e01606d commit 247866e

File tree

4 files changed

+107
-26
lines changed

4 files changed

+107
-26
lines changed

commands/action.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,15 @@ var actionUpdateCmd = &cobra.Command{
139139
return actionParseError(cmd, args, err)
140140
}
141141

142+
if Properties.PromptOnChange == "true" {
143+
if Flags.action.confirm != "yes" && Flags.action.confirm != "y" {
144+
errMsg := wski18n.T("please update action using --confirm yes(or y) if you really want to update it")
145+
whiskErr := whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL,
146+
whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
147+
return whiskErr
148+
}
149+
}
150+
142151
if _, _, err = Client.Actions.Insert(action, true); err != nil {
143152
return actionInsertError(action, err)
144153
}
@@ -335,6 +344,15 @@ var actionDeleteCmd = &cobra.Command{
335344

336345
Client.Namespace = qualifiedName.GetNamespace()
337346

347+
if Properties.PromptOnChange == "true" {
348+
if Flags.action.confirm != "yes" && Flags.action.confirm != "y" {
349+
errMsg := wski18n.T("please delete action using --confirm yes(or y) if you really want to delete it")
350+
whiskErr := whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL,
351+
whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
352+
return whiskErr
353+
}
354+
}
355+
338356
if _, err = Client.Actions.Delete(qualifiedName.GetEntityName()); err != nil {
339357
return actionDeleteError(qualifiedName.GetEntityName(), err)
340358
}
@@ -1269,6 +1287,8 @@ func init() {
12691287
actionCreateCmd.Flags().StringVar(&Flags.action.web, WEB_FLAG, "", wski18n.T("treat ACTION as a web action, a raw HTTP web action, or as a standard action; yes | true = web action, raw = raw HTTP web action, no | false = standard action"))
12701288
actionCreateCmd.Flags().StringVar(&Flags.action.websecure, WEB_SECURE_FLAG, "", wski18n.T("secure the web action. where `SECRET` is true, false, or any string. Only valid when the ACTION is a web action"))
12711289

1290+
actionDeleteCmd.Flags().StringVar(&Flags.action.confirm, "confirm", "no", wski18n.T("you confirm do this operation?yes(or y) | no (property promptOnChange=true works)"))
1291+
12721292
actionUpdateCmd.Flags().BoolVar(&Flags.action.native, "native", false, wski18n.T("treat ACTION as native action (zip file provides a compatible executable to run)"))
12731293
actionUpdateCmd.Flags().StringVar(&Flags.action.docker, "docker", "", wski18n.T("use provided docker image (a path on DockerHub) to run the action"))
12741294
actionUpdateCmd.Flags().BoolVar(&Flags.action.copy, "copy", false, wski18n.T("treat ACTION as the name of an existing action"))
@@ -1284,6 +1304,7 @@ func init() {
12841304
actionUpdateCmd.Flags().StringVarP(&Flags.common.paramFile, "param-file", "P", "", wski18n.T("`FILE` containing parameter values in JSON format"))
12851305
actionUpdateCmd.Flags().StringVar(&Flags.action.web, WEB_FLAG, "", wski18n.T("treat ACTION as a web action, a raw HTTP web action, or as a standard action; yes | true = web action, raw = raw HTTP web action, no | false = standard action"))
12861306
actionUpdateCmd.Flags().StringVar(&Flags.action.websecure, WEB_SECURE_FLAG, "", wski18n.T("secure the web action. where `SECRET` is true, false, or any string. Only valid when the ACTION is a web action"))
1307+
actionUpdateCmd.Flags().StringVar(&Flags.action.confirm, "confirm", "no", wski18n.T("you confirm do this operation?yes(or y) | no (property promptOnChange=true works)"))
12871308

12881309
actionInvokeCmd.Flags().StringSliceVarP(&Flags.common.param, "param", "p", []string{}, wski18n.T("parameter values in `KEY VALUE` format"))
12891310
actionInvokeCmd.Flags().StringVarP(&Flags.common.paramFile, "param-file", "P", "", wski18n.T("`FILE` containing parameter values in JSON format"))

commands/flags.go

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -69,20 +69,22 @@ type FlagsStruct struct {
6969
}
7070

7171
property struct {
72-
cert bool
73-
key bool
74-
auth bool
75-
apihost bool
76-
apiversion bool
77-
namespace bool
78-
cliversion bool
79-
apibuild bool
80-
apibuildno bool
81-
insecure bool
82-
all bool
83-
apihostSet string
84-
apiversionSet string
85-
namespaceSet string
72+
cert bool
73+
key bool
74+
auth bool
75+
apihost bool
76+
apiversion bool
77+
namespace bool
78+
promptOnChange bool
79+
cliversion bool
80+
apibuild bool
81+
apibuildno bool
82+
insecure bool
83+
all bool
84+
apihostSet string
85+
apiversionSet string
86+
namespaceSet string
87+
promptOnChangeSet string
8688
}
8789

8890
action ActionFlags
@@ -145,6 +147,7 @@ type ActionFlags struct {
145147
url bool
146148
save bool
147149
saveAs string
150+
confirm string
148151
}
149152

150153
func IsVerbose() bool {

commands/property.go

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,17 @@ import (
3131
)
3232

3333
var Properties struct {
34-
Cert string
35-
Key string
36-
Auth string
37-
APIHost string
38-
APIVersion string
39-
APIBuild string
40-
APIBuildNo string
41-
CLIVersion string
42-
Namespace string
43-
PropsFile string
34+
Cert string
35+
Key string
36+
Auth string
37+
APIHost string
38+
APIVersion string
39+
APIBuild string
40+
APIBuildNo string
41+
CLIVersion string
42+
Namespace string
43+
PromptOnChange string
44+
PropsFile string
4445
}
4546

4647
const DefaultCert string = ""
@@ -51,6 +52,7 @@ const DefaultAPIVersion string = "v1"
5152
const DefaultAPIBuild string = ""
5253
const DefaultAPIBuildNo string = ""
5354
const DefaultNamespace string = "_"
55+
const DefaultPromptOnChange string = "false"
5456
const DefaultPropsFile string = "~/.wskprops"
5557

5658
var propertyCmd = &cobra.Command{
@@ -165,6 +167,13 @@ var propertySetCmd = &cobra.Command{
165167
}
166168
}
167169

170+
if promptOnChange := Flags.property.promptOnChangeSet; len(promptOnChange) > 0 {
171+
props["PROMPTONCHANGE"] = promptOnChange
172+
okMsg += fmt.Sprintf(
173+
wski18n.T("{{.ok}} prompt on change when action delete or update set to {{.name}}\n",
174+
map[string]interface{}{"ok": color.GreenString("ok:"), "name": boldString(promptOnChange)}))
175+
}
176+
168177
err = WriteProps(Properties.PropsFile, props)
169178
if err != nil {
170179
whisk.Debug(whisk.DbgError, "writeProps(%s, %#v) failed: %s\n", Properties.PropsFile, props, err)
@@ -261,6 +270,13 @@ var propertyUnsetCmd = &cobra.Command{
261270
}
262271
}
263272

273+
if Flags.property.promptOnChange {
274+
delete(props, "PROMPTONCHANGE")
275+
okMsg += fmt.Sprintf(
276+
wski18n.T("{{.ok}} prompt on change when action delete or update unset.\n",
277+
map[string]interface{}{"ok": color.GreenString("ok:")}))
278+
}
279+
264280
err = WriteProps(Properties.PropsFile, props)
265281
if err != nil {
266282
whisk.Debug(whisk.DbgError, "writeProps(%s, %#v) failed: %s\n", Properties.PropsFile, props, err)
@@ -291,8 +307,9 @@ var propertyGetCmd = &cobra.Command{
291307
if !(Flags.property.all || Flags.property.cert ||
292308
Flags.property.key || Flags.property.auth ||
293309
Flags.property.apiversion || Flags.property.cliversion ||
294-
Flags.property.namespace || Flags.property.apibuild ||
295-
Flags.property.apihost || Flags.property.apibuildno) {
310+
Flags.property.namespace || Flags.property.promptOnChange ||
311+
Flags.property.apibuild || Flags.property.apihost ||
312+
Flags.property.apibuildno) {
296313
Flags.property.all = true
297314
}
298315

@@ -320,6 +337,10 @@ var propertyGetCmd = &cobra.Command{
320337
fmt.Fprintf(color.Output, "%s\t\t%s\n", wski18n.T("whisk namespace"), boldString(Properties.Namespace))
321338
}
322339

340+
if Flags.property.all || Flags.property.promptOnChange {
341+
fmt.Fprintf(color.Output, "%s\t\t%s\n", wski18n.T("prompt on change when action delete or update"), boldString(Properties.PromptOnChange))
342+
}
343+
323344
if Flags.property.all || Flags.property.cliversion {
324345
fmt.Fprintf(color.Output, "%s\t%s\n", wski18n.T("whisk CLI version"), boldString(Properties.CLIVersion))
325346
}
@@ -368,6 +389,7 @@ func init() {
368389
propertyGetCmd.Flags().BoolVar(&Flags.property.apibuildno, "apibuildno", false, wski18n.T("whisk API build number"))
369390
propertyGetCmd.Flags().BoolVar(&Flags.property.cliversion, "cliversion", false, wski18n.T("whisk CLI version"))
370391
propertyGetCmd.Flags().BoolVar(&Flags.property.namespace, "namespace", false, wski18n.T("whisk namespace"))
392+
propertyGetCmd.Flags().BoolVar(&Flags.property.promptOnChange, "promptOnChange", false, wski18n.T("prompt on change when action delete or update"))
371393
propertyGetCmd.Flags().BoolVar(&Flags.property.all, "all", false, wski18n.T("all properties"))
372394

373395
propertySetCmd.Flags().StringVarP(&Flags.Global.Auth, "auth", "u", "", wski18n.T("authorization `KEY`"))
@@ -376,13 +398,15 @@ func init() {
376398
propertySetCmd.Flags().StringVar(&Flags.property.apihostSet, "apihost", "", wski18n.T("whisk API `HOST`"))
377399
propertySetCmd.Flags().StringVar(&Flags.property.apiversionSet, "apiversion", "", wski18n.T("whisk API `VERSION`"))
378400
propertySetCmd.Flags().StringVar(&Flags.property.namespaceSet, "namespace", "", wski18n.T("whisk `NAMESPACE`"))
401+
propertySetCmd.Flags().StringVar(&Flags.property.promptOnChangeSet, "promptOnChange", "", wski18n.T("prompt on change when action delete or update"))
379402

380403
propertyUnsetCmd.Flags().BoolVar(&Flags.property.cert, "cert", false, wski18n.T("client cert"))
381404
propertyUnsetCmd.Flags().BoolVar(&Flags.property.key, "key", false, wski18n.T("client key"))
382405
propertyUnsetCmd.Flags().BoolVar(&Flags.property.auth, "auth", false, wski18n.T("authorization key"))
383406
propertyUnsetCmd.Flags().BoolVar(&Flags.property.apihost, "apihost", false, wski18n.T("whisk API host"))
384407
propertyUnsetCmd.Flags().BoolVar(&Flags.property.apiversion, "apiversion", false, wski18n.T("whisk API version"))
385408
propertyUnsetCmd.Flags().BoolVar(&Flags.property.namespace, "namespace", false, wski18n.T("whisk namespace"))
409+
propertyUnsetCmd.Flags().BoolVar(&Flags.property.promptOnChange, "promptOnChange", false, wski18n.T("prompt on change when action delete or update"))
386410

387411
}
388412

@@ -391,6 +415,7 @@ func SetDefaultProperties() {
391415
Properties.Cert = DefaultKey
392416
Properties.Auth = DefaultAuth
393417
Properties.Namespace = DefaultNamespace
418+
Properties.PromptOnChange = DefaultPromptOnChange
394419
Properties.APIHost = DefaultAPIHost
395420
Properties.APIBuild = DefaultAPIBuild
396421
Properties.APIBuildNo = DefaultAPIBuildNo
@@ -492,6 +517,10 @@ func loadProperties() error {
492517
Properties.Namespace = namespace
493518
}
494519

520+
if promptOnChange, hasProp := props["PROMPTONCHANGE"]; hasProp && len(promptOnChange) > 0 {
521+
Properties.PromptOnChange = promptOnChange
522+
}
523+
495524
return nil
496525
}
497526

@@ -549,6 +578,10 @@ func parseConfigFlags(cmd *cobra.Command, args []string) error {
549578
}
550579
}
551580

581+
if promptOnChange := Flags.property.promptOnChangeSet; len(promptOnChange) > 0 {
582+
Properties.PromptOnChange = promptOnChange
583+
}
584+
552585
if Flags.Global.Debug {
553586
whisk.SetDebug(true)
554587
}

wski18n/resources/en_US.all.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,30 @@
288288
"id": "{{.ok}} whisk namespace set to {{.name}}\n",
289289
"translation": "{{.ok}} whisk namespace set to {{.name}}\n"
290290
},
291+
{
292+
"id": "{{.ok}} prompt on change when action delete or update set to {{.name}}\n",
293+
"translation": "{{.ok}} prompt on change when action delete or update set to {{.name}}\n"
294+
},
295+
{
296+
"id": "{{.ok}} prompt on change when action delete or update unset.\n",
297+
"translation": "{{.ok}} prompt on change when action delete or update unset.\n"
298+
},
299+
{
300+
"id": "prompt on change when action delete or update",
301+
"translation": "prompt on change when action delete or update"
302+
},
303+
{
304+
"id": "you confirm do this operation?yes(or y) | no (property promptOnChange=true works)",
305+
"translation": "you confirm do this operation?yes(or y) | no (property promptOnChange=true works)"
306+
},
307+
{
308+
"id": "please update action using --confirm yes(or y) if you really want to update it",
309+
"translation": "please update action using --confirm yes(or y) if you really want to update it"
310+
},
311+
{
312+
"id": "please delete action using --confirm yes(or y) if you really want to delete it",
313+
"translation": "please delete action using --confirm yes(or y) if you really want to delete it"
314+
},
291315
{
292316
"id": "Unable to set the property value(s): {{.err}}",
293317
"translation": "Unable to set the property value(s): {{.err}}"

0 commit comments

Comments
 (0)