From dad7243269ba2554a81fcdd9dabfba4201eb7f7f Mon Sep 17 00:00:00 2001 From: James Dubee Date: Tue, 20 Jun 2017 09:27:38 -0400 Subject: [PATCH] Error when Entity Names are Provided to List Commands (#2075) * Error when Entity Names are Provided to List Commands - When entity names are pass to list commands display an appropriate error - Share qualified name parsing error messages between commands --- .../core/cli/test/WskBasicUsageTests.scala | 9 +- tools/cli/go-whisk-cli/commands/action.go | 33 ++-- tools/cli/go-whisk-cli/commands/activation.go | 31 ++-- tools/cli/go-whisk-cli/commands/api.go | 22 +-- tools/cli/go-whisk-cli/commands/namespace.go | 27 +-- tools/cli/go-whisk-cli/commands/package.go | 174 +++++++----------- tools/cli/go-whisk-cli/commands/rule.go | 136 +++++--------- tools/cli/go-whisk-cli/commands/shared.go | 47 +++++ tools/cli/go-whisk-cli/commands/trigger.go | 170 +++++++---------- tools/cli/go-whisk-cli/commands/util.go | 20 +- tools/cli/go-whisk-cli/commands/wsk.go | 10 +- .../wski18n/resources/en_US.all.json | 8 +- 12 files changed, 295 insertions(+), 392 deletions(-) create mode 100644 tools/cli/go-whisk-cli/commands/shared.go diff --git a/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala b/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala index 83f27d80fd8..be5d36b3cea 100644 --- a/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala +++ b/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala @@ -245,7 +245,7 @@ class WskBasicUsageTests it should "reject creating entities with invalid names" in withAssetCleaner(wskprops) { (wp, assetHelper) => val names = Seq( - ("", NOT_ALLOWED), + ("", ERROR_EXIT), (" ", BAD_REQUEST), ("hi+there", BAD_REQUEST), ("$hola", BAD_REQUEST), @@ -1194,6 +1194,7 @@ class WskBasicUsageTests val apiDeleteReqMsg = "An API base path or API name is required. An optional API relative path and operation may also be provided." val apiListReqMsg = "Optional parameters are: API base path (or API name), API relative path and operation." val invalidShared = s"Cannot use value '$invalidArg' for shared" + val entityNameMsg = s"An entity name, '$invalidArg', was provided instead of a namespace. Valid namespaces are of the following format: /NAMESPACE." val invalidArgs = Seq( (Seq("api-experimental", "create"), s"${tooFewArgsMsg} ${apiCreateReqMsg}"), (Seq("api-experimental", "create", "/basepath", "/path", "GET", "action", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${apiCreateReqMsg}"), @@ -1241,10 +1242,12 @@ class WskBasicUsageTests (Seq("package", "bind", "packageName", "bindingName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."), (Seq("package", "list", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"), + (Seq("package", "list", invalidArg), entityNameMsg), (Seq("package", "delete"), s"${tooFewArgsMsg} ${packageNameReqMsg}"), (Seq("package", "delete", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}."), (Seq("package", "refresh", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"), + (Seq("package", "refresh", invalidArg), entityNameMsg), (Seq("rule", "enable"), s"${tooFewArgsMsg} ${ruleNameReqMsg}"), (Seq("rule", "enable", "ruleName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."), (Seq("rule", "disable"), s"${tooFewArgsMsg} ${ruleNameReqMsg}"), @@ -1266,6 +1269,7 @@ class WskBasicUsageTests (Seq("rule", "delete"), s"${tooFewArgsMsg} ${ruleNameReqMsg}"), (Seq("rule", "delete", "ruleName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."), (Seq("rule", "list", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"), + (Seq("rule", "list", invalidArg), entityNameMsg), (Seq("trigger", "fire"), s"${tooFewArgsMsg} ${triggerNameReqMsg} ${optPayloadMsg}"), (Seq("trigger", "fire", "triggerName", "triggerPayload", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${triggerNameReqMsg} ${optPayloadMsg}"), @@ -1277,7 +1281,8 @@ class WskBasicUsageTests (Seq("trigger", "get", "triggerName", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}."), (Seq("trigger", "delete"), s"${tooFewArgsMsg} ${triggerNameReqMsg}"), (Seq("trigger", "delete", "triggerName", invalidArg), s"${tooManyArgsMsg}${invalidArg}."), - (Seq("trigger", "list", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}")) + (Seq("trigger", "list", "namespace", invalidArg), s"${tooManyArgsMsg}${invalidArg}. ${optNamespaceMsg}"), + (Seq("trigger", "list", invalidArg), entityNameMsg)) invalidArgs foreach { case (cmd, err) => diff --git a/tools/cli/go-whisk-cli/commands/action.go b/tools/cli/go-whisk-cli/commands/action.go index 0931e0682a3..a9a161453e8 100644 --- a/tools/cli/go-whisk-cli/commands/action.go +++ b/tools/cli/go-whisk-cli/commands/action.go @@ -277,8 +277,8 @@ var actionDeleteCmd = &cobra.Command{ } var actionListCmd = &cobra.Command{ - Use: "list [NAMESPACE]", - Short: wski18n.T("list all actions"), + Use: "list [ NAMESPACE | PACKAGE_NAME ]", + Short: wski18n.T("list all actions in a namespace or actions contained in a package"), SilenceUsage: true, SilenceErrors: true, PreRunE: setupClientConfig, @@ -287,13 +287,7 @@ var actionListCmd = &cobra.Command{ var actions []whisk.Action var err error - if len(args) == 1 { - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) - } - - client.Namespace = qualifiedName.namespace - } else if whiskErr := checkArgs( + if whiskErr := checkArgs( args, 0, 1, @@ -302,6 +296,14 @@ var actionListCmd = &cobra.Command{ return whiskErr } + if len(args) == 1 { + if qualifiedName, err = parseQualifiedName(args[0]); err != nil { + return parseQualifiedNameError(args[0], err) + } + + client.Namespace = qualifiedName.namespace + } + options := &whisk.ActionListOptions{ Skip: flags.common.skip, Limit: flags.common.limit, @@ -615,19 +617,6 @@ func actionInsertError(action *whisk.Action, err error) (error) { return nestedError(errMsg, err) } -func parseQualifiedNameError(entityName string, err error) (error) { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", entityName, err) - - errMsg := wski18n.T( - "'{{.name}}' is not a valid qualified name: {{.err}}", - map[string]interface{}{ - "name": entityName, - "err": err, - }) - - return nestedError(errMsg, err) -} - func getJSONFromStringsParamError(params []string, keyValueFormat bool, err error) (error) { whisk.Debug(whisk.DbgError, "getJSONFromStrings(%#v, %t) failed: %s\n", params, keyValueFormat, err) diff --git a/tools/cli/go-whisk-cli/commands/activation.go b/tools/cli/go-whisk-cli/commands/activation.go index 04c879a67d2..b98c59751c7 100644 --- a/tools/cli/go-whisk-cli/commands/activation.go +++ b/tools/cli/go-whisk-cli/commands/activation.go @@ -50,35 +50,26 @@ var activationListCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error - qName := QualifiedName{} + var qualifiedName QualifiedName + + if whiskErr := checkArgs(args, 0, 1, "Activation list", + wski18n.T("An optional namespace is the only valid argument.")); whiskErr != nil { + return whiskErr + } // Specifying an activation item name filter is optional if len(args) == 1 { whisk.Debug(whisk.DbgInfo, "Activation item name filter '%s' provided\n", args[0]) - qName, err = parseQualifiedName(args[0]) - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", args[0], err) - errStr := wski18n.T("'{{.name}}' is not a valid qualified name: {{.err}}", - map[string]interface{}{"name": args[0], "err": err}) - werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXITCODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - return werr - } - ns := qName.namespace - if len(ns) == 0 { - whisk.Debug(whisk.DbgError, "Namespace '%s' is invalid\n", ns) - errStr := wski18n.T("Namespace '{{.name}}' is invalid", map[string]interface{}{"name": ns}) - werr := whisk.MakeWskError(errors.New(errStr), whisk.EXITCODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE) - return werr + + if qualifiedName, err = parseQualifiedName(args[0]); err != nil { + return parseQualifiedNameError(args[0], err) } - client.Namespace = ns - } else if whiskErr := checkArgs(args, 0, 1, "Activation list", - wski18n.T("An optional namespace is the only valid argument.")); whiskErr != nil { - return whiskErr + client.Namespace = qualifiedName.namespace } options := &whisk.ActivationListOptions{ - Name: qName.entityName, + Name: qualifiedName.entityName, Limit: flags.common.limit, Skip: flags.common.skip, Upto: flags.activation.upto, diff --git a/tools/cli/go-whisk-cli/commands/api.go b/tools/cli/go-whisk-cli/commands/api.go index a5cbaea4335..5e4f89dcd55 100644 --- a/tools/cli/go-whisk-cli/commands/api.go +++ b/tools/cli/go-whisk-cli/commands/api.go @@ -606,19 +606,13 @@ func parseApi(cmd *cobra.Command, args []string) (*whisk.Api, error) { } // Is the specified action name valid? - var qName QualifiedName + var qualifiedName QualifiedName if (len(args) == 3) { - qName = QualifiedName{} - qName, err = parseQualifiedName(args[2]) - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", args[2], err) - errMsg := wski18n.T("'{{.name}}' is not a valid action name: {{.err}}", - map[string]interface{}{"name": args[2], "err": err}) - whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXITCODE_ERR_GENERAL, - whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE) - return nil, whiskErr + if qualifiedName, err = parseQualifiedName(args[2]); err != nil { + return nil, parseQualifiedNameError(args[2], err) } - if (qName.entityName == "") { + + if (qualifiedName.entityName == "") { whisk.Debug(whisk.DbgError, "Action name '%s' is invalid\n", args[2]) errMsg := wski18n.T("'{{.name}}' is not a valid action name.", map[string]interface{}{"name": args[2]}) whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXITCODE_ERR_GENERAL, @@ -641,10 +635,10 @@ func parseApi(cmd *cobra.Command, args []string) (*whisk.Api, error) { api.Namespace = client.Config.Namespace api.Action = new(whisk.ApiAction) - api.Action.BackendUrl = "https://" + client.Config.Host + "/api/v1/namespaces/" + qName.namespace + "/actions/" + qName.entityName + api.Action.BackendUrl = "https://" + client.Config.Host + "/api/v1/namespaces/" + qualifiedName.namespace + "/actions/" + qualifiedName.entityName api.Action.BackendMethod = "POST" - api.Action.Name = qName.entityName - api.Action.Namespace = qName.namespace + api.Action.Name = qualifiedName.entityName + api.Action.Namespace = qualifiedName.namespace api.Action.Auth = client.Config.AuthToken api.ApiName = apiname api.GatewayBasePath = basepath diff --git a/tools/cli/go-whisk-cli/commands/namespace.go b/tools/cli/go-whisk-cli/commands/namespace.go index cafed6f61c3..bbe8766a5e9 100644 --- a/tools/cli/go-whisk-cli/commands/namespace.go +++ b/tools/cli/go-whisk-cli/commands/namespace.go @@ -66,7 +66,7 @@ var namespaceGetCmd = &cobra.Command{ SilenceErrors: true, PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { - var qName QualifiedName + var qualifiedName QualifiedName var err error if whiskErr := checkArgs(args, 0, 1, "Namespace get", @@ -76,18 +76,16 @@ var namespaceGetCmd = &cobra.Command{ // Namespace argument is optional; defaults to configured property namespace if len(args) == 1 { - qName, err = parseQualifiedName(args[0]) - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", args[0], err) - errMsg := wski18n.T("'{{.name}}' is not a valid qualified name: {{.err}}", - map[string]interface{}{"name": args[0], "err": err}) - werr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXITCODE_ERR_GENERAL, - whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - return werr + if qualifiedName, err = parseQualifiedName(args[0]); err != nil { + return parseQualifiedNameError(args[0], err) + } + + if len(qualifiedName.entityName) > 0 { + return entityNameError(qualifiedName.entityName) } } - namespace, _, err := client.Namespaces.Get(qName.namespace) + namespace, _, err := client.Namespaces.Get(qualifiedName.namespace) if err != nil { whisk.Debug(whisk.DbgError, "client.Namespaces.Get(%s) error: %s\n", getClientNamespace(), err) @@ -109,15 +107,6 @@ var namespaceGetCmd = &cobra.Command{ }, } -var listCmd = &cobra.Command{ - Use: "list", - Short: wski18n.T("list entities in the current namespace"), - SilenceUsage: true, - SilenceErrors: true, - PreRunE: setupClientConfig, - RunE: namespaceGetCmd.RunE, -} - func init() { namespaceCmd.AddCommand( namespaceListCmd, diff --git a/tools/cli/go-whisk-cli/commands/package.go b/tools/cli/go-whisk-cli/commands/package.go index 6020b7261c3..1edb94976b0 100644 --- a/tools/cli/go-whisk-cli/commands/package.go +++ b/tools/cli/go-whisk-cli/commands/package.go @@ -41,6 +41,7 @@ var packageBindCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error + var pkgQualifiedName, bindQualifiedName QualifiedName if whiskErr := checkArgs(args, 2, 2, "Package bind", wski18n.T("A package name and binding name are required.")); whiskErr != nil { @@ -48,28 +49,16 @@ var packageBindCmd = &cobra.Command{ } packageName := args[0] - pkgQName, err := parseQualifiedName(packageName) - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", packageName, err) - errMsg := wski18n.T("'{{.name}}' is not a valid qualified name: {{.err}}", - map[string]interface{}{"name": packageName, "err": err}) - werr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXITCODE_ERR_GENERAL, - whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - return werr + if pkgQualifiedName, err = parseQualifiedName(packageName); err != nil { + return parseQualifiedNameError(packageName, err) } bindingName := args[1] - bindQName, err := parseQualifiedName(bindingName) - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", bindingName, err) - errMsg := wski18n.T("'{{.name}}' is not a valid qualified name: {{.err}}", - map[string]interface{}{"name": bindingName, "err": err}) - werr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXITCODE_ERR_GENERAL, - whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - return werr + if bindQualifiedName, err = parseQualifiedName(bindingName); err != nil { + return parseQualifiedNameError(bindingName, err) } - client.Namespace = bindQName.namespace + client.Namespace = bindQualifiedName.namespace // Convert the binding's list of default parameters from a string into []KeyValue // The 1 or more --param arguments have all been combined into a single []string @@ -101,12 +90,12 @@ var packageBindCmd = &cobra.Command{ } binding := whisk.Binding{ - Name: pkgQName.entityName, - Namespace: pkgQName.namespace, + Name: pkgQualifiedName.entityName, + Namespace: pkgQualifiedName.namespace, } p := &whisk.BindingPackage{ - Name: bindQName.entityName, + Name: bindQualifiedName.entityName, Annotations: annotations.(whisk.KeyValueArr), Parameters: parameters.(whisk.KeyValueArr), Binding: binding, @@ -135,21 +124,17 @@ var packageCreateCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { var err error var shared, sharedSet bool + var qualifiedName QualifiedName if whiskErr := checkArgs(args, 1, 1, "Package create", wski18n.T("A package name is required.")); whiskErr != nil { return whiskErr } - qName, err := parseQualifiedName(args[0]) - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", args[0], err) - errMsg := wski18n.T("'{{.name}}' is not a valid qualified name: {{.err}}", - map[string]interface{}{"name": args[0], "err": err}) - werr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXITCODE_ERR_GENERAL, - whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - return werr + if qualifiedName, err = parseQualifiedName(args[0]); err != nil { + return parseQualifiedNameError(args[0], err) } - client.Namespace = qName.namespace + + client.Namespace = qualifiedName.namespace if shared, sharedSet, err = parseShared(flags.common.shared); err != nil { whisk.Debug(whisk.DbgError, "parseShared(%s) failed: %s\n", flags.common.shared, err) @@ -179,8 +164,8 @@ var packageCreateCmd = &cobra.Command{ } p := &whisk.Package{ - Name: qName.entityName, - Namespace: qName.namespace, + Name: qualifiedName.entityName, + Namespace: qualifiedName.namespace, Annotations: annotations.(whisk.KeyValueArr), Parameters: parameters.(whisk.KeyValueArr), } @@ -195,7 +180,7 @@ var packageCreateCmd = &cobra.Command{ errStr := wski18n.T( "Unable to create package '{{.name}}': {{.err}}", map[string]interface{}{ - "name": qName.entityName, + "name": qualifiedName.entityName, "err": err, }) werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXITCODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) @@ -203,7 +188,7 @@ var packageCreateCmd = &cobra.Command{ } fmt.Fprintf(color.Output, wski18n.T("{{.ok}} created package {{.name}}\n", - map[string]interface{}{"ok": color.GreenString(wski18n.T("ok:")), "name":boldString(qName.entityName)})) + map[string]interface{}{"ok": color.GreenString(wski18n.T("ok:")), "name":boldString(qualifiedName.entityName)})) return nil }, } @@ -217,21 +202,17 @@ var packageUpdateCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { var err error var shared, sharedSet bool + var qualifiedName QualifiedName if whiskErr := checkArgs(args, 1, 1, "Package update", wski18n.T("A package name is required.")); whiskErr != nil { return whiskErr } - qName, err := parseQualifiedName(args[0]) - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", args[0], err) - errMsg := wski18n.T("'{{.name}}' is not a valid qualified name: {{.err}}", - map[string]interface{}{"name": args[0], "err": err}) - werr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXITCODE_ERR_GENERAL, - whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - return werr + if qualifiedName, err = parseQualifiedName(args[0]); err != nil { + return parseQualifiedNameError(args[0], err) } - client.Namespace = qName.namespace + + client.Namespace = qualifiedName.namespace if shared, sharedSet, err = parseShared(flags.common.shared); err != nil { whisk.Debug(whisk.DbgError, "parseShared(%s) failed: %s\n", flags.common.shared, err) @@ -260,8 +241,8 @@ var packageUpdateCmd = &cobra.Command{ } p := &whisk.Package{ - Name: qName.entityName, - Namespace: qName.namespace, + Name: qualifiedName.entityName, + Namespace: qualifiedName.namespace, Annotations: annotations.(whisk.KeyValueArr), Parameters: parameters.(whisk.KeyValueArr), } @@ -279,7 +260,7 @@ var packageUpdateCmd = &cobra.Command{ } fmt.Fprintf(color.Output, wski18n.T("{{.ok}} updated package {{.name}}\n", - map[string]interface{}{"ok": color.GreenString(wski18n.T("ok:")), "name":boldString(qName.entityName)})) + map[string]interface{}{"ok": color.GreenString(wski18n.T("ok:")), "name":boldString(qualifiedName.entityName)})) return nil }, } @@ -293,6 +274,7 @@ var packageGetCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { var err error var field string + var qualifiedName QualifiedName if whiskErr := checkArgs(args, 1, 2, "Package get", wski18n.T("A package name is required.")); whiskErr != nil { return whiskErr @@ -309,24 +291,18 @@ var packageGetCmd = &cobra.Command{ } } - qName, err := parseQualifiedName(args[0]) - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", args[0], err) - errMsg := wski18n.T("'{{.name}}' is not a valid qualified name: {{.err}}", - map[string]interface{}{"name": args[0], "err": err}) - werr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXITCODE_ERR_GENERAL, - whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - return werr + if qualifiedName, err = parseQualifiedName(args[0]); err != nil { + return parseQualifiedNameError(args[0], err) } - client.Namespace = qName.namespace + client.Namespace = qualifiedName.namespace - xPackage, _, err := client.Packages.Get(qName.entityName) + xPackage, _, err := client.Packages.Get(qualifiedName.entityName) if err != nil { - whisk.Debug(whisk.DbgError, "client.Packages.Get(%s) failed: %s\n", qName.entityName, err) + whisk.Debug(whisk.DbgError, "client.Packages.Get(%s) failed: %s\n", qualifiedName.entityName, err) errStr := wski18n.T( "Unable to get package '{{.name}}': {{.err}}", map[string]interface{}{ - "name": qName.entityName, + "name": qualifiedName.entityName, "err":err, }) werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXITCODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) @@ -339,12 +315,12 @@ var packageGetCmd = &cobra.Command{ if len(field) > 0 { fmt.Fprintf(color.Output, wski18n.T("{{.ok}} got package {{.name}}, displaying field {{.field}}\n", - map[string]interface{}{"ok": color.GreenString("ok:"), "name": boldString(qName.entityName), + map[string]interface{}{"ok": color.GreenString("ok:"), "name": boldString(qualifiedName.entityName), "field": boldString(field)})) printField(xPackage, field) } else { fmt.Fprintf(color.Output, wski18n.T("{{.ok}} got package {{.name}}\n", - map[string]interface{}{"ok": color.GreenString("ok:"), "name": boldString(qName.entityName)})) + map[string]interface{}{"ok": color.GreenString("ok:"), "name": boldString(qualifiedName.entityName)})) printJSON(xPackage) } } @@ -361,29 +337,25 @@ var packageDeleteCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error + var qualifiedName QualifiedName if whiskErr := checkArgs(args, 1, 1, "Package delete", wski18n.T("A package name is required.")); whiskErr != nil { return whiskErr } - qName, err := parseQualifiedName(args[0]) - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", args[0], err) - errMsg := wski18n.T("'{{.name}}' is not a valid qualified name: {{.err}}", - map[string]interface{}{"name": args[0], "err": err}) - werr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXITCODE_ERR_GENERAL, - whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - return werr + if qualifiedName, err = parseQualifiedName(args[0]); err != nil { + return parseQualifiedNameError(args[0], err) } - client.Namespace = qName.namespace - _, err = client.Packages.Delete(qName.entityName) + client.Namespace = qualifiedName.namespace + + _, err = client.Packages.Delete(qualifiedName.entityName) if err != nil { - whisk.Debug(whisk.DbgError, "client.Packages.Delete(%s) failed: %s\n", qName.entityName, err) + whisk.Debug(whisk.DbgError, "client.Packages.Delete(%s) failed: %s\n", qualifiedName.entityName, err) errStr := wski18n.T( "Unable to delete package '{{.name}}': {{.err}}", map[string]interface{}{ - "name": qName.entityName, + "name": qualifiedName.entityName, "err": err, }) werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXITCODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) @@ -392,7 +364,7 @@ var packageDeleteCmd = &cobra.Command{ fmt.Fprintf(color.Output, wski18n.T("{{.ok}} deleted package {{.name}}\n", - map[string]interface{}{"ok": color.GreenString("ok:"), "name": boldString(qName.entityName)})) + map[string]interface{}{"ok": color.GreenString("ok:"), "name": boldString(qualifiedName.entityName)})) return nil }, } @@ -406,30 +378,23 @@ var packageListCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { var err error var shared bool + var qualifiedName QualifiedName + + if whiskErr := checkArgs(args, 0, 1, "Package list", + wski18n.T("An optional namespace is the only valid argument.")); whiskErr != nil { + return whiskErr + } - qName := QualifiedName{} if len(args) == 1 { - qName, err = parseQualifiedName(args[0]) - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", args[0], err) - errMsg := wski18n.T("'{{.name}}' is not a valid qualified name: {{.err}}", - map[string]interface{}{"name": args[0], "err": err}) - werr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXITCODE_ERR_GENERAL, - whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - return werr + if qualifiedName, err = parseQualifiedName(args[0]); err != nil { + return parseQualifiedNameError(args[0], err) } - ns := qName.namespace - if len(ns) == 0 { - whisk.Debug(whisk.DbgError, "An empty namespace in the package name '%s' is invalid \n", args[0]) - errStr := wski18n.T("No valid namespace detected. Run 'wsk property set --namespace' or ensure the name argument is preceded by a \"/\"") - werr := whisk.MakeWskError(errors.New(errStr), whisk.EXITCODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE) - return werr + + if len(qualifiedName.entityName) > 0 { + return entityNameError(qualifiedName.entityName) } - client.Namespace = ns - } else if whiskErr := checkArgs(args, 0, 1, "Package list", - wski18n.T("An optional namespace is the only valid argument.")); whiskErr != nil { - return whiskErr + client.Namespace = qualifiedName.namespace } if flags.common.shared == "yes" { @@ -466,30 +431,27 @@ var packageRefreshCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error - var qName QualifiedName + var qualifiedName QualifiedName if whiskErr := checkArgs(args, 0, 1, "Package refresh", wski18n.T("An optional namespace is the only valid argument.")); whiskErr != nil { return whiskErr + } + + if len(args) == 0 { + qualifiedName.namespace = getNamespace() } else { - if len(args) == 0 { - qName.namespace = getNamespace() - } else { - qName, err = parseQualifiedName(args[0]) - - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", args[0], err) - errMsg := wski18n.T("'{{.name}}' is not a valid qualified name: {{.err}}", - map[string]interface{}{"name": args[0], "err": err}) - werr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXITCODE_ERR_GENERAL, - whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - return werr - } + if qualifiedName, err = parseQualifiedName(args[0]); err != nil { + return parseQualifiedNameError(args[0], err) + } + + if len(qualifiedName.entityName) > 0 { + return entityNameError(qualifiedName.entityName) } } currentNamespace := client.Config.Namespace - client.Config.Namespace = qName.namespace + client.Config.Namespace = qualifiedName.namespace defer func() { client.Config.Namespace = currentNamespace diff --git a/tools/cli/go-whisk-cli/commands/rule.go b/tools/cli/go-whisk-cli/commands/rule.go index e29b6776d74..418b35bcdd1 100644 --- a/tools/cli/go-whisk-cli/commands/rule.go +++ b/tools/cli/go-whisk-cli/commands/rule.go @@ -41,23 +41,18 @@ var ruleEnableCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error + var qualifiedName QualifiedName if whiskErr := checkArgs(args, 1, 1, "Rule enable", wski18n.T("A rule name is required.")); whiskErr != nil { return whiskErr } - qName, err := parseQualifiedName(args[0]) - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", args[0], err) - errMsg := wski18n.T("'{{.name}}' is not a valid qualified name: {{.err}}", - map[string]interface{}{"name": args[0], "err": err}) - werr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXITCODE_ERR_GENERAL, - whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - return werr + if qualifiedName, err = parseQualifiedName(args[0]); err != nil { + return parseQualifiedNameError(args[0], err) } - client.Namespace = qName.namespace - ruleName := qName.entityName + client.Namespace = qualifiedName.namespace + ruleName := qualifiedName.entityName _, _, err = client.Rules.SetState(ruleName, "active") if err != nil { @@ -83,23 +78,18 @@ var ruleDisableCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error + var qualifiedName QualifiedName if whiskErr := checkArgs(args, 1, 1, "Rule disable", wski18n.T("A rule name is required.")); whiskErr != nil { return whiskErr } - qName, err := parseQualifiedName(args[0]) - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", args[0], err) - errMsg := wski18n.T("'{{.name}}' is not a valid qualified name: {{.err}}", - map[string]interface{}{"name": args[0], "err": err}) - werr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXITCODE_ERR_GENERAL, - whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - return werr + if qualifiedName, err = parseQualifiedName(args[0]); err != nil { + return parseQualifiedNameError(args[0], err) } - client.Namespace = qName.namespace - ruleName := qName.entityName + client.Namespace = qualifiedName.namespace + ruleName := qualifiedName.entityName _, _, err = client.Rules.SetState(ruleName, "inactive") if err != nil { @@ -125,23 +115,18 @@ var ruleStatusCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error + var qualifiedName QualifiedName if whiskErr := checkArgs(args, 1, 1, "Rule status", wski18n.T("A rule name is required.")); whiskErr != nil { return whiskErr } - qName, err := parseQualifiedName(args[0]) - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", args[0], err) - errMsg := wski18n.T("'{{.name}}' is not a valid qualified name: {{.err}}", - map[string]interface{}{"name": args[0], "err": err}) - werr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXITCODE_ERR_GENERAL, - whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - return werr + if qualifiedName, err = parseQualifiedName(args[0]); err != nil { + return parseQualifiedNameError(args[0], err) } - client.Namespace = qName.namespace - ruleName := qName.entityName + client.Namespace = qualifiedName.namespace + ruleName := qualifiedName.entityName rule, _, err := client.Rules.Get(ruleName) if err != nil { @@ -167,24 +152,19 @@ var ruleCreateCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error + var qualifiedName QualifiedName if whiskErr := checkArgs(args, 3, 3, "Rule create", wski18n.T("A rule, trigger and action name are required.")); whiskErr != nil { return whiskErr } - qName, err := parseQualifiedName(args[0]) - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", args[0], err) - errMsg := wski18n.T("'{{.name}}' is not a valid qualified name: {{.err}}", - map[string]interface{}{"name": args[0], "err": err}) - werr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXITCODE_ERR_GENERAL, - whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - return werr + if qualifiedName, err = parseQualifiedName(args[0]); err != nil { + return parseQualifiedNameError(args[0], err) } - client.Namespace = qName.namespace - ruleName := qName.entityName + client.Namespace = qualifiedName.namespace + ruleName := qualifiedName.entityName triggerName := getQualifiedName(args[1], Properties.Namespace) actionName := getQualifiedName(args[2], Properties.Namespace) @@ -221,24 +201,19 @@ var ruleUpdateCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error + var qualifiedName QualifiedName if whiskErr := checkArgs(args, 3, 3, "Rule update", wski18n.T("A rule, trigger and action name are required.")); whiskErr != nil { return whiskErr } - qName, err := parseQualifiedName(args[0]) - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", args[0], err) - errMsg := wski18n.T("'{{.name}}' is not a valid qualified name: {{.err}}", - map[string]interface{}{"name": args[0], "err": err}) - werr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXITCODE_ERR_GENERAL, - whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - return werr + if qualifiedName, err = parseQualifiedName(args[0]); err != nil { + return parseQualifiedNameError(args[0], err) } - client.Namespace = qName.namespace - ruleName := qName.entityName + client.Namespace = qualifiedName.namespace + ruleName := qualifiedName.entityName triggerName := getQualifiedName(args[1], Properties.Namespace) actionName := getQualifiedName(args[2], Properties.Namespace) @@ -273,6 +248,7 @@ var ruleGetCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { var err error var field string + var qualifiedName QualifiedName if whiskErr := checkArgs(args, 1, 2, "Rule get", wski18n.T("A rule name is required.")); whiskErr != nil { return whiskErr @@ -289,18 +265,12 @@ var ruleGetCmd = &cobra.Command{ } } - qName, err := parseQualifiedName(args[0]) - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", args[0], err) - errMsg := wski18n.T("'{{.name}}' is not a valid qualified name: {{.err}}", - map[string]interface{}{"name": args[0], "err": err}) - werr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXITCODE_ERR_GENERAL, - whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - return werr + if qualifiedName, err = parseQualifiedName(args[0]); err != nil { + return parseQualifiedNameError(args[0], err) } - client.Namespace = qName.namespace - ruleName := qName.entityName + client.Namespace = qualifiedName.namespace + ruleName := qualifiedName.entityName rule, _, err := client.Rules.Get(ruleName) if err != nil { @@ -338,23 +308,18 @@ var ruleDeleteCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error + var qualifiedName QualifiedName if whiskErr := checkArgs(args, 1, 1, "Rule delete", wski18n.T("A rule name is required.")); whiskErr != nil { return whiskErr } - qName, err := parseQualifiedName(args[0]) - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", args[0], err) - errMsg := wski18n.T("'{{.name}}' is not a valid qualified name: {{.err}}", - map[string]interface{}{"name": args[0], "err": err}) - werr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXITCODE_ERR_GENERAL, - whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - return werr + if qualifiedName, err = parseQualifiedName(args[0]); err != nil { + return parseQualifiedNameError(args[0], err) } - client.Namespace = qName.namespace - ruleName := qName.entityName + client.Namespace = qualifiedName.namespace + ruleName := qualifiedName.entityName if flags.rule.disable { _, _, err := client.Rules.SetState(ruleName, "inactive") @@ -391,28 +356,23 @@ var ruleListCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error - qName := QualifiedName{} + var qualifiedName QualifiedName + + if whiskErr := checkArgs(args, 0, 1, "Rule list", + wski18n.T("An optional namespace is the only valid argument.")); whiskErr != nil { + return whiskErr + } if len(args) == 1 { - qName, err = parseQualifiedName(args[0]) - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", args[0], err) - errStr := wski18n.T("Namespace '{{.name}}' is invalid: {{.err}}\n", - map[string]interface{}{"name": args[0], "err": err}) - werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXITCODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - return werr + if qualifiedName, err = parseQualifiedName(args[0]); err != nil { + return parseQualifiedNameError(args[0], err) } - ns := qName.namespace - if len(ns) == 0 { - whisk.Debug(whisk.DbgError, "Namespace is missing from '%s'\n", args[0]) - errStr := wski18n.T("No valid namespace detected. Run 'wsk property set --namespace' or ensure the name argument is preceded by a \"/\"") - werr := whisk.MakeWskError(errors.New(errStr), whisk.EXITCODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE) - return werr + + if len(qualifiedName.entityName) > 0 { + return entityNameError(qualifiedName.entityName) } - client.Namespace = ns - } else if whiskErr := checkArgs(args, 0, 1, "Rule list", - wski18n.T("An optional namespace is the only valid argument.")); whiskErr != nil { - return whiskErr + + client.Namespace = qualifiedName.namespace } ruleListOptions := &whisk.RuleListOptions{ diff --git a/tools/cli/go-whisk-cli/commands/shared.go b/tools/cli/go-whisk-cli/commands/shared.go new file mode 100644 index 00000000000..33cf01b3624 --- /dev/null +++ b/tools/cli/go-whisk-cli/commands/shared.go @@ -0,0 +1,47 @@ +/* + * Copyright 2015-2016 IBM Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package commands + +import ( + "errors" + + "../wski18n" + "../../go-whisk/whisk" +) + +func entityNameError(entityName string) (error) { + errMsg := wski18n.T( + "An entity name, '{{.name}}', was provided instead of a namespace. Valid namespaces are of the following format: /NAMESPACE.", + map[string]interface{}{ + "name": entityName, + }) + + return whisk.MakeWskError(errors.New(errMsg), whisk.EXITCODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE) +} + +func parseQualifiedNameError(entityName string, err error) (error) { + whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", entityName, err) + + errMsg := wski18n.T( + "'{{.name}}' is not a valid qualified name: {{.err}}", + map[string]interface{}{ + "name": entityName, + "err": err, + }) + + return whisk.MakeWskError(errors.New(errMsg), whisk.EXITCODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE) +} diff --git a/tools/cli/go-whisk-cli/commands/trigger.go b/tools/cli/go-whisk-cli/commands/trigger.go index 2978aa7c46c..254c898c20e 100644 --- a/tools/cli/go-whisk-cli/commands/trigger.go +++ b/tools/cli/go-whisk-cli/commands/trigger.go @@ -48,24 +48,18 @@ var triggerFireCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { var err error var parameters interface{} + var qualifiedName QualifiedName if whiskErr := checkArgs(args, 1, 2, "Trigger fire", wski18n.T("A trigger name is required. A payload is optional.")); whiskErr != nil { return whiskErr } - qName, err := parseQualifiedName(args[0]) - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", args[0], err) - errMsg := wski18n.T("'{{.name}}' is not a valid qualified name: {{.err}}", - map[string]interface{}{"name": args[0], "err": err}) - whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXITCODE_ERR_GENERAL, - whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - - return whiskErr + if qualifiedName, err = parseQualifiedName(args[0]); err != nil { + return parseQualifiedNameError(args[0], err) } - client.Namespace = qName.namespace + client.Namespace = qualifiedName.namespace // Add payload to parameters if len(args) == 2 { @@ -85,11 +79,11 @@ var triggerFireCmd = &cobra.Command{ } } - trigResp, _, err := client.Triggers.Fire(qName.entityName, parameters) + trigResp, _, err := client.Triggers.Fire(qualifiedName.entityName, parameters) if err != nil { - whisk.Debug(whisk.DbgError, "client.Triggers.Fire(%s, %#v) failed: %s\n", qName.entityName, parameters, err) + whisk.Debug(whisk.DbgError, "client.Triggers.Fire(%s, %#v) failed: %s\n", qualifiedName.entityName, parameters, err) errStr := wski18n.T("Unable to fire trigger '{{.name}}': {{.err}}", - map[string]interface{}{"name": qName.entityName, "err": err}) + map[string]interface{}{"name": qualifiedName.entityName, "err": err}) werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXITCODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) return werr @@ -99,8 +93,8 @@ var triggerFireCmd = &cobra.Command{ wski18n.T("{{.ok}} triggered /{{.namespace}}/{{.name}} with id {{.id}}\n", map[string]interface{}{ "ok": color.GreenString("ok:"), - "namespace": boldString(qName.namespace), - "name": boldString(qName.entityName), + "namespace": boldString(qualifiedName.namespace), + "name": boldString(qualifiedName.entityName), "id": boldString(trigResp.ActivationId)})) return nil }, @@ -116,46 +110,31 @@ var triggerCreateCmd = &cobra.Command{ var err error var annotations interface{} var feedArgPassed bool = (flags.common.feed != "") + var qualifiedName QualifiedName if whiskErr := checkArgs(args, 1, 1, "Trigger create", wski18n.T("A trigger name is required.")); whiskErr != nil { return whiskErr } - qName, err := parseQualifiedName(args[0]) - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", args[0], err) - errMsg := wski18n.T("'{{.name}}' is not a valid qualified name: {{.err}}", - map[string]interface{}{"name": args[0], "err": err}) - whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXITCODE_ERR_GENERAL, - whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - return whiskErr + if qualifiedName, err = parseQualifiedName(args[0]); err != nil { + return parseQualifiedNameError(args[0], err) } - client.Namespace = qName.namespace + client.Namespace = qualifiedName.namespace var fullTriggerName string var fullFeedName string + var feedQualifiedName QualifiedName if feedArgPassed { whisk.Debug(whisk.DbgInfo, "Trigger has a feed\n") - feedqName, err := parseQualifiedName(flags.common.feed) - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", flags.common.feed, err) - errMsg := wski18n.T("'{{.name}}' is not a valid qualified name: {{.err}}", - map[string]interface{}{"name": flags.common.feed, "err": err}) - whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXITCODE_ERR_GENERAL, - whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE) - return whiskErr - } - if len(feedqName.namespace) == 0 { - whisk.Debug(whisk.DbgError, "Namespace is missing from '%s'\n", flags.common.feed) - errStr := wski18n.T("No valid namespace detected. Run 'wsk property set --namespace' or ensure the name argument is preceded by a \"/\"") - werr := whisk.MakeWskError(errors.New(errStr), whisk.EXITCODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE) - return werr + + if feedQualifiedName, err = parseQualifiedName(flags.common.feed); err != nil { + return parseQualifiedNameError(flags.common.feed, err) } - fullFeedName = fmt.Sprintf("/%s/%s", feedqName.namespace, feedqName.entityName) - fullTriggerName = fmt.Sprintf("/%s/%s", qName.namespace, qName.entityName) + fullFeedName = fmt.Sprintf("/%s/%s", feedQualifiedName.namespace, feedQualifiedName.entityName) + fullTriggerName = fmt.Sprintf("/%s/%s", qualifiedName.namespace, qualifiedName.entityName) flags.common.param = append(flags.common.param, getFormattedJSON(FEED_LIFECYCLE_EVENT, FEED_CREATE)) flags.common.param = append(flags.common.param, getFormattedJSON(FEED_TRIGGER_NAME, fullTriggerName)) flags.common.param = append(flags.common.param, getFormattedJSON(FEED_AUTH_KEY, client.Config.AuthToken)) @@ -193,7 +172,7 @@ var triggerCreateCmd = &cobra.Command{ } trigger := &whisk.Trigger{ - Name: qName.entityName, + Name: qualifiedName.entityName, Annotations: annotations.(whisk.KeyValueArr), } @@ -244,24 +223,18 @@ var triggerUpdateCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error + var qualifiedName QualifiedName if whiskErr := checkArgs(args, 1, 1, "Trigger update", wski18n.T("A trigger name is required.")); whiskErr != nil { return whiskErr } - qName, err := parseQualifiedName(args[0]) - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", args[0], err) - errMsg := wski18n.T("'{{.name}}' is not a valid qualified name: {{.err}}", - map[string]interface{}{"name": args[0], "err": err}) - whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXITCODE_ERR_GENERAL, - whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - - return whiskErr + if qualifiedName, err = parseQualifiedName(args[0]); err != nil { + return parseQualifiedNameError(args[0], err) } - client.Namespace = qName.namespace + client.Namespace = qualifiedName.namespace // Convert the trigger's list of default parameters from a string into []KeyValue // The 1 or more --param arguments have all been combined into a single []string @@ -290,7 +263,7 @@ var triggerUpdateCmd = &cobra.Command{ } trigger := &whisk.Trigger{ - Name: qName.entityName, + Name: qualifiedName.entityName, Parameters: parameters.(whisk.KeyValueArr), Annotations: annotations.(whisk.KeyValueArr), } @@ -320,6 +293,7 @@ var triggerGetCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { var err error var field string + var qualifiedName QualifiedName if whiskErr := checkArgs(args, 1, 2, "Trigger get", wski18n.T("A trigger name is required.")); whiskErr != nil { return whiskErr @@ -336,24 +310,17 @@ var triggerGetCmd = &cobra.Command{ } } - qName, err := parseQualifiedName(args[0]) - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", args[0], err) - errMsg := wski18n.T("'{{.name}}' is not a valid qualified name: {{.err}}", - map[string]interface{}{"name": args[0], "err": err}) - whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXITCODE_ERR_GENERAL, - whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - - return whiskErr + if qualifiedName, err = parseQualifiedName(args[0]); err != nil { + return parseQualifiedNameError(args[0], err) } - client.Namespace = qName.namespace + client.Namespace = qualifiedName.namespace - retTrigger, _, err := client.Triggers.Get(qName.entityName) + retTrigger, _, err := client.Triggers.Get(qualifiedName.entityName) if err != nil { - whisk.Debug(whisk.DbgError, "client.Triggers.Get(%s) failed: %s\n", qName.entityName, err) + whisk.Debug(whisk.DbgError, "client.Triggers.Get(%s) failed: %s\n", qualifiedName.entityName, err) errStr := wski18n.T("Unable to get trigger '{{.name}}': {{.err}}", - map[string]interface{}{"name": qName.entityName, "err": err}) + map[string]interface{}{"name": qualifiedName.entityName, "err": err}) werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXITCODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) return werr } @@ -363,12 +330,12 @@ var triggerGetCmd = &cobra.Command{ } else { if len(field) > 0 { fmt.Fprintf(color.Output, wski18n.T("{{.ok}} got trigger {{.name}}, displaying field {{.field}}\n", - map[string]interface{}{"ok": color.GreenString("ok:"), "name": boldString(qName.entityName), + map[string]interface{}{"ok": color.GreenString("ok:"), "name": boldString(qualifiedName.entityName), "field": boldString(field)})) printField(retTrigger, field) } else { fmt.Fprintf(color.Output, wski18n.T("{{.ok}} got trigger {{.name}}\n", - map[string]interface{}{"ok": color.GreenString("ok:"), "name": boldString(qName.entityName)})) + map[string]interface{}{"ok": color.GreenString("ok:"), "name": boldString(qualifiedName.entityName)})) printJSON(retTrigger) } } @@ -388,30 +355,24 @@ var triggerDeleteCmd = &cobra.Command{ var retTrigger *whisk.Trigger var fullFeedName string var origParams []string + var qualifiedName QualifiedName if whiskErr := checkArgs(args, 1, 1, "Trigger delete", wski18n.T("A trigger name is required.")); whiskErr != nil { return whiskErr } - qName, err := parseQualifiedName(args[0]) - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", args[0], err) - errMsg := wski18n.T("'{{.name}}' is not a valid qualified name: {{.err}}", - map[string]interface{}{"name": args[0], "err": err}) - whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXITCODE_ERR_GENERAL, - whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - - return whiskErr + if qualifiedName, err = parseQualifiedName(args[0]); err != nil { + return parseQualifiedNameError(args[0], err) } - client.Namespace = qName.namespace + client.Namespace = qualifiedName.namespace - retTrigger, _, err = client.Triggers.Get(qName.entityName) + retTrigger, _, err = client.Triggers.Get(qualifiedName.entityName) if err != nil { - whisk.Debug(whisk.DbgError, "client.Triggers.Get(%s) failed: %s\n", qName.entityName, err) + whisk.Debug(whisk.DbgError, "client.Triggers.Get(%s) failed: %s\n", qualifiedName.entityName, err) errStr := wski18n.T("Unable to get trigger '{{.name}}': {{.err}}", - map[string]interface{}{"name": qName.entityName, "err": err}) + map[string]interface{}{"name": qualifiedName.entityName, "err": err}) werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXITCODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) return werr } @@ -422,34 +383,34 @@ var triggerDeleteCmd = &cobra.Command{ if len(fullFeedName) > 0 { origParams = flags.common.param - fullTriggerName := fmt.Sprintf("/%s/%s", qName.namespace, qName.entityName) + fullTriggerName := fmt.Sprintf("/%s/%s", qualifiedName.namespace, qualifiedName.entityName) flags.common.param = append(flags.common.param, getFormattedJSON(FEED_LIFECYCLE_EVENT, FEED_DELETE)) flags.common.param = append(flags.common.param, getFormattedJSON(FEED_TRIGGER_NAME, fullTriggerName)) flags.common.param = append(flags.common.param, getFormattedJSON(FEED_AUTH_KEY, client.Config.AuthToken)) - err = configureFeed(qName.entityName, fullFeedName) + err = configureFeed(qualifiedName.entityName, fullFeedName) if err != nil { - whisk.Debug(whisk.DbgError, "configureFeed(%s, %s) failed: %s\n", qName.entityName, fullFeedName, err) + whisk.Debug(whisk.DbgError, "configureFeed(%s, %s) failed: %s\n", qualifiedName.entityName, fullFeedName, err) } flags.common.param = origParams - client.Namespace = qName.namespace + client.Namespace = qualifiedName.namespace } } - retTrigger, _, err = client.Triggers.Delete(qName.entityName) + retTrigger, _, err = client.Triggers.Delete(qualifiedName.entityName) if err != nil { - whisk.Debug(whisk.DbgError, "client.Triggers.Delete(%s) failed: %s\n", qName.entityName, err) + whisk.Debug(whisk.DbgError, "client.Triggers.Delete(%s) failed: %s\n", qualifiedName.entityName, err) errStr := wski18n.T("Unable to delete trigger '{{.name}}': {{.err}}", - map[string]interface{}{"name": qName.entityName, "err": err}) + map[string]interface{}{"name": qualifiedName.entityName, "err": err}) werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXITCODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) return werr } fmt.Fprintf(color.Output, wski18n.T("{{.ok}} deleted trigger {{.name}}\n", - map[string]interface{}{"ok": color.GreenString("ok:"), "name": boldString(qName.entityName)})) + map[string]interface{}{"ok": color.GreenString("ok:"), "name": boldString(qualifiedName.entityName)})) return nil }, @@ -463,28 +424,23 @@ var triggerListCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error - qName := QualifiedName{} + var qualifiedName QualifiedName + + if whiskErr := checkArgs(args, 0, 1, "Trigger list", + wski18n.T("An optional namespace is the only valid argument.")); whiskErr != nil { + return whiskErr + } + if len(args) == 1 { - qName, err = parseQualifiedName(args[0]) - if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", args[0], err) - errStr := wski18n.T("'{{.name}}' is not a valid qualified name: {{.err}}", - map[string]interface{}{"name": args[0], "err": err}) - werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXITCODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE) - return werr + if qualifiedName, err = parseQualifiedName(args[0]); err != nil { + return parseQualifiedNameError(args[0], err) } - ns := qName.namespace - if len(ns) == 0 { - whisk.Debug(whisk.DbgError, "Namespace is missing from '%s'\n", args[0]) - errStr := wski18n.T("No valid namespace detected. Run 'wsk property set --namespace' or ensure the name argument is preceded by a \"/\"") - werr := whisk.MakeWskError(errors.New(errStr), whisk.EXITCODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE) - return werr + + if len(qualifiedName.entityName) > 0 { + return entityNameError(qualifiedName.entityName) } - client.Namespace = ns - whisk.Debug(whisk.DbgInfo, "Using namespace '%s' from argument '%s''\n", ns, args[0]) - } else if whiskErr := checkArgs(args, 0, 1, "Trigger list", - wski18n.T("An optional namespace is the only valid argument.")); whiskErr != nil { - return whiskErr + + client.Namespace = qualifiedName.namespace } options := &whisk.TriggerListOptions{ diff --git a/tools/cli/go-whisk-cli/commands/util.go b/tools/cli/go-whisk-cli/commands/util.go index b63efdce841..d6c6c4ea4c8 100644 --- a/tools/cli/go-whisk-cli/commands/util.go +++ b/tools/cli/go-whisk-cli/commands/util.go @@ -47,16 +47,16 @@ type QualifiedName struct { entityName string // pkg+entity } -func (qName QualifiedName) String() string { +func (qualifiedName QualifiedName) String() string { output := []string{} - if len(qName.namespace) > 0 { - output = append(output, "/", qName.namespace, "/") + if len(qualifiedName.namespace) > 0 { + output = append(output, "/", qualifiedName.namespace, "/") } - if len(qName.packageName) > 0 { - output = append(output, qName.packageName, "/") + if len(qualifiedName.packageName) > 0 { + output = append(output, qualifiedName.packageName, "/") } - output = append(output, qName.entityName) + output = append(output, qualifiedName.entityName) return strings.Join(output, "") } @@ -69,10 +69,10 @@ name, the namespace is also resolved from the property file. Return a qualifiedName struct Examples: - foo => qName {namespace: "_", entityName: foo} - pkg/foo => qName {namespace: "_", entityName: pkg/foo} - /ns/foo => qName {namespace: ns, entityName: foo} - /ns/pkg/foo => qName {namespace: ns, entityName: pkg/foo} + foo => qualifiedName {namespace: "_", entityName: foo} + pkg/foo => qualifiedName {namespace: "_", entityName: pkg/foo} + /ns/foo => qualifiedName {namespace: ns, entityName: foo} + /ns/pkg/foo => qualifiedName {namespace: ns, entityName: pkg/foo} */ func parseQualifiedName(name string) (QualifiedName, error) { var qualifiedName QualifiedName diff --git a/tools/cli/go-whisk-cli/commands/wsk.go b/tools/cli/go-whisk-cli/commands/wsk.go index 72905495db1..9a17402f4d4 100644 --- a/tools/cli/go-whisk-cli/commands/wsk.go +++ b/tools/cli/go-whisk-cli/commands/wsk.go @@ -30,8 +30,14 @@ var WskCmd = &cobra.Command{ PersistentPreRunE:parseConfigFlags, } - - +var listCmd = &cobra.Command{ + Use: "list", + Short: wski18n.T("list entities in the current namespace"), + SilenceUsage: true, + SilenceErrors: true, + PreRunE: setupClientConfig, + RunE: namespaceGetCmd.RunE, +} func init() { WskCmd.SetHelpTemplate(`{{with or .Long .Short }}{{.}} diff --git a/tools/cli/go-whisk-cli/wski18n/resources/en_US.all.json b/tools/cli/go-whisk-cli/wski18n/resources/en_US.all.json index 7a9b7780bbb..fd279466b02 100644 --- a/tools/cli/go-whisk-cli/wski18n/resources/en_US.all.json +++ b/tools/cli/go-whisk-cli/wski18n/resources/en_US.all.json @@ -832,8 +832,8 @@ "translation": "{{.ok}} deleted action {{.name}}\n" }, { - "id": "list all actions", - "translation": "list all actions" + "id": "list all actions in a namespace or actions contained in a package", + "translation": "list all actions in a namespace or actions contained in a package" }, { "id": "Unable to obtain the list of actions for namespace '{{.name}}': {{.err}}", @@ -1462,5 +1462,9 @@ { "id": "Invalid format type: {{.type}}", "translation": "Invalid format type: {{.type}}" + }, + { + "id": "An entity name, '{{.name}}', was provided instead of a namespace. Valid namespaces are of the following format: /NAMESPACE.", + "translation": "An entity name, '{{.name}}', was provided instead of a namespace. Valid namespaces are of the following format: /NAMESPACE." } ]