This is an automated email from the ASF dual-hosted git repository. csantanapr pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk-cli.git
commit 9b26034e9a3879a415115f2a01c2dbd582a82bca Author: Brandon Lee Underwood <[email protected]> AuthorDate: Thu Aug 10 21:42:13 2017 -0400 Allow FQN with 3 parts (namespace/package/action) to be input with/without leading slash in CLI (#2424) --- commands/action.go | 110 +++++++++++------------ commands/activation.go | 10 +-- commands/api.go | 23 +++-- commands/namespace.go | 12 +-- commands/package.go | 109 +++++++++++------------ commands/qualified_name.go | 215 +++++++++++++++++++++++++++++++++++++++++++++ commands/rule.go | 82 ++++++++--------- commands/shared.go | 13 --- commands/trigger.go | 108 +++++++++++------------ commands/util.go | 122 ------------------------- 10 files changed, 442 insertions(+), 362 deletions(-) diff --git a/commands/action.go b/commands/action.go index 40eaeff..83e89fa 100644 --- a/commands/action.go +++ b/commands/action.go @@ -121,7 +121,7 @@ var actionInvokeCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { var err error var parameters interface{} - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) var paramArgs []string if whiskErr := checkArgs( @@ -133,11 +133,11 @@ var actionInvokeCmd = &cobra.Command{ return whiskErr } - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - client.Namespace = qualifiedName.namespace + client.Namespace = qualifiedName.GetNamespace() paramArgs = Flags.common.param if len(paramArgs) > 0 { @@ -149,12 +149,12 @@ var actionInvokeCmd = &cobra.Command{ Flags.common.blocking = true} res, _, err := client.Actions.Invoke( - qualifiedName.entityName, + qualifiedName.GetEntityName(), parameters, Flags.common.blocking, Flags.action.result) - return handleInvocationResponse(qualifiedName, parameters, res, err) + return handleInvocationResponse(*qualifiedName, parameters, res, err) }, } @@ -165,29 +165,29 @@ func handleInvocationResponse( err error) (error) { if err == nil { printInvocationMsg( - qualifiedName.namespace, - qualifiedName.entityName, + qualifiedName.GetNamespace(), + qualifiedName.GetEntityName(), getValueFromJSONResponse(ACTIVATION_ID, result), result, color.Output) } else { if !Flags.common.blocking { - return handleInvocationError(err, qualifiedName.entityName, parameters) + return handleInvocationError(err, qualifiedName.GetEntityName(), parameters) } else { if isBlockingTimeout(err) { printBlockingTimeoutMsg( - qualifiedName.namespace, - qualifiedName.entityName, + qualifiedName.GetNamespace(), + qualifiedName.GetEntityName(), getValueFromJSONResponse(ACTIVATION_ID, result)) } else if isApplicationError(err) { printInvocationMsg( - qualifiedName.namespace, - qualifiedName.entityName, + qualifiedName.GetNamespace(), + qualifiedName.GetEntityName(), getValueFromJSONResponse(ACTIVATION_ID, result), result, colorable.NewColorableStderr()) } else { - return handleInvocationError(err, qualifiedName.entityName, parameters) + return handleInvocationError(err, qualifiedName.GetEntityName(), parameters) } } } @@ -205,7 +205,7 @@ var actionGetCmd = &cobra.Command{ var err error var field string var action *whisk.Action - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) if whiskErr := checkArgs(args, 1, 2, "Action get", wski18n.T("An action name is required.")); whiskErr != nil { return whiskErr @@ -219,29 +219,29 @@ var actionGetCmd = &cobra.Command{ } } - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - client.Namespace = qualifiedName.namespace + client.Namespace = qualifiedName.GetNamespace() - if action, _, err = client.Actions.Get(qualifiedName.entityName); err != nil { - return actionGetError(qualifiedName.entityName, err) + if action, _, err = client.Actions.Get(qualifiedName.GetEntityName()); err != nil { + return actionGetError(qualifiedName.GetEntityName(), err) } if Flags.action.url { actionURL := action.ActionURL(Properties.APIHost, DefaultOpenWhiskApiPath, Properties.APIVersion, - qualifiedName.packageName) - printActionGetWithURL(qualifiedName.entity, actionURL) - } else if Flags.common.summary { + qualifiedName.GetPackageName()) + printActionGetWithURL(qualifiedName.GetEntity(), actionURL) + } else if flags.common.summary { printSummary(action) } else { if len(field) > 0 { - printActionGetWithField(qualifiedName.entityName, field, action) + printActionGetWithField(qualifiedName.GetEntityName(), field, action) } else { - printActionGet(qualifiedName.entityName, action) + printActionGet(qualifiedName.GetEntityName(), action) } } @@ -256,7 +256,7 @@ var actionDeleteCmd = &cobra.Command{ SilenceErrors: true, PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) var err error if whiskErr := checkArgs( @@ -268,17 +268,17 @@ var actionDeleteCmd = &cobra.Command{ return whiskErr } - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - client.Namespace = qualifiedName.namespace + client.Namespace = qualifiedName.GetNamespace() - if _, err = client.Actions.Delete(qualifiedName.entityName); err != nil { - return actionDeleteError(qualifiedName.entityName, err) + if _, err = client.Actions.Delete(qualifiedName.GetEntityName()); err != nil { + return actionDeleteError(qualifiedName.GetEntityName(), err) } - printActionDeleted(qualifiedName.entityName) + printActionDeleted(qualifiedName.GetEntityName()) return nil }, @@ -291,7 +291,7 @@ var actionListCmd = &cobra.Command{ SilenceErrors: true, PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) var actions []whisk.Action var err error @@ -305,11 +305,11 @@ var actionListCmd = &cobra.Command{ } if len(args) == 1 { - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - client.Namespace = qualifiedName.namespace + client.Namespace = qualifiedName.GetNamespace() } options := &whisk.ActionListOptions{ @@ -317,8 +317,8 @@ var actionListCmd = &cobra.Command{ Limit: Flags.common.limit, } - if actions, _, err = client.Actions.List(qualifiedName.entityName, options); err != nil { - return actionListError(qualifiedName.entityName, options, err) + if actions, _, err = client.Actions.List(qualifiedName.GetEntityName(), options); err != nil { + return actionListError(qualifiedName.GetEntityName(), options, err) } printList(actions) @@ -335,16 +335,16 @@ func parseAction(cmd *cobra.Command, args []string, update bool) (*whisk.Action, var parameters interface{} var annotations interface{} - qualifiedName := QualifiedName{} + var qualifiedName = new(QualifiedName) - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return nil, parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return nil, NewQualifiedNameError(args[0], err) } - client.Namespace = qualifiedName.namespace + client.Namespace = qualifiedName.GetNamespace() action := new(whisk.Action) - action.Name = qualifiedName.entityName - action.Namespace = qualifiedName.namespace + action.Name = qualifiedName.GetEntityName() + action.Namespace = qualifiedName.GetNamespace() action.Limits = getLimits( cmd.LocalFlags().Changed(MEMORY_FLAG), cmd.LocalFlags().Changed(LOG_SIZE_FLAG), @@ -373,19 +373,19 @@ func parseAction(cmd *cobra.Command, args []string, update bool) (*whisk.Action, } if Flags.action.copy { - copiedQualifiedName := QualifiedName{} + var copiedQualifiedName = new(QualifiedName) - if copiedQualifiedName, err = parseQualifiedName(args[1]); err != nil { - return nil, parseQualifiedNameError(args[1], err) + if copiedQualifiedName, err = NewQualifiedName(args[1]); err != nil { + return nil, NewQualifiedNameError(args[1], err) } - client.Namespace = copiedQualifiedName.namespace + client.Namespace = copiedQualifiedName.GetNamespace() - if existingAction, _, err = client.Actions.Get(copiedQualifiedName.entityName); err != nil { - return nil, actionGetError(copiedQualifiedName.entityName, err) + if existingAction, _, err = client.Actions.Get(copiedQualifiedName.GetEntityName()); err != nil { + return nil, actionGetError(copiedQualifiedName.GetEntityName(), err) } - client.Namespace = qualifiedName.namespace + client.Namespace = qualifiedName.GetNamespace() action.Exec = existingAction.Exec action.Parameters = append(action.Parameters, existingAction.Parameters...) action.Annotations = append(action.Annotations, existingAction.Annotations...) @@ -408,7 +408,7 @@ func parseAction(cmd *cobra.Command, args []string, update bool) (*whisk.Action, if cmd.LocalFlags().Changed(WEB_FLAG) { preserveAnnotations := action.Annotations == nil - action.Annotations, err = webAction(Flags.action.web, action.Annotations, qualifiedName.entityName, preserveAnnotations) + action.Annotations, err = webAction(Flags.action.web, action.Annotations, qualifiedName.GetEntityName(), preserveAnnotations) } whisk.Debug(whisk.DbgInfo, "Parsed action struct: %#v\n", action) @@ -875,10 +875,10 @@ func isWebAction(client *whisk.Client, qname QualifiedName) (error) { var err error = nil savedNs := client.Namespace - client.Namespace = qname.namespace - fullActionName := "/" + qname.namespace + "/" + qname.entityName + client.Namespace = qname.GetNamespace() + fullActionName := "/" + qname.GetNamespace() + "/" + qname.GetEntityName() - action, _, err := client.Actions.Get(qname.entityName) + action, _, err := client.Actions.Get(qname.GetEntityName()) if err != nil { whisk.Debug(whisk.DbgError, "client.Actions.Get(%s) error: %s\n", fullActionName, err) diff --git a/commands/activation.go b/commands/activation.go index cd6a871..8273351 100644 --- a/commands/activation.go +++ b/commands/activation.go @@ -52,7 +52,7 @@ var activationListCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) if whiskErr := checkArgs(args, 0, 1, "Activation list", wski18n.T("An optional namespace is the only valid argument.")); whiskErr != nil { @@ -63,15 +63,15 @@ var activationListCmd = &cobra.Command{ if len(args) == 1 { whisk.Debug(whisk.DbgInfo, "Activation item name filter '%s' provided\n", args[0]) - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - client.Namespace = qualifiedName.namespace + client.Namespace = qualifiedName.GetNamespace() } options := &whisk.ActivationListOptions{ - Name: qualifiedName.entityName, + Name: qualifiedName.GetEntityName(), Limit: Flags.common.limit, Skip: Flags.common.skip, Upto: Flags.activation.upto, diff --git a/commands/api.go b/commands/api.go index 9d89f47..cec47eb 100644 --- a/commands/api.go +++ b/commands/api.go @@ -128,7 +128,7 @@ var apiCreateCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { var api *whisk.Api var err error - var qname *QualifiedName + var qname = new(QualifiedName) if (len(args) == 0 && Flags.api.configfile == "") { whisk.Debug(whisk.DbgError, "No swagger file and no arguments\n") @@ -746,19 +746,18 @@ func parseApi(cmd *cobra.Command, args []string) (*whisk.Api, *QualifiedName, er } // Is the specified action name valid? - var qName QualifiedName + var qName = new(QualifiedName) if (len(args) == 3) { - qName = QualifiedName{} - qName, err = parseQualifiedName(args[2]) + qName, err = NewQualifiedName(args[2]) if err != nil { - whisk.Debug(whisk.DbgError, "parseQualifiedName(%s) failed: %s\n", args[2], err) + whisk.Debug(whisk.DbgError, "NewQualifiedName(%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.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE) return nil, nil, whiskErr } - if (qName.entityName == "") { + if (qName.GetEntityName() == "") { 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.EXIT_CODE_ERR_GENERAL, @@ -782,22 +781,22 @@ func parseApi(cmd *cobra.Command, args []string) (*whisk.Api, *QualifiedName, er api.Namespace = client.Config.Namespace api.Action = new(whisk.ApiAction) var urlActionPackage string - if (len(qName.packageName) > 0) { - urlActionPackage = qName.packageName + if (len(qName.GetPackageName()) > 0) { + urlActionPackage = qName.GetPackageName() } else { urlActionPackage = "default" } - api.Action.BackendUrl = "https://" + client.Config.Host + "/api/v1/web/" + qName.namespace + "/" + urlActionPackage + "/" + qName.entity + ".http" + api.Action.BackendUrl = "https://" + client.Config.Host + "/api/v1/web/" + qName.GetNamespace() + "/" + urlActionPackage + "/" + qName.GetEntity() + ".http" api.Action.BackendMethod = api.GatewayMethod - api.Action.Name = qName.entityName - api.Action.Namespace = qName.namespace + api.Action.Name = qName.GetEntityName() + api.Action.Namespace = qName.GetNamespace() api.Action.Auth = client.Config.AuthToken api.ApiName = apiname api.GatewayBasePath = basepath if (!basepathArgIsApiName) { api.Id = "API:"+api.Namespace+":"+api.GatewayBasePath } whisk.Debug(whisk.DbgInfo, "Parsed api struct: %#v\n", api) - return api, &qName, nil + return api, qName, nil } func parseSwaggerApi() (*whisk.Api, error) { diff --git a/commands/namespace.go b/commands/namespace.go index 8bcbb1e..a9f7bef 100644 --- a/commands/namespace.go +++ b/commands/namespace.go @@ -67,7 +67,7 @@ var namespaceGetCmd = &cobra.Command{ SilenceErrors: true, PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) var err error if whiskErr := checkArgs(args, 0, 1, "Namespace get", @@ -77,16 +77,16 @@ var namespaceGetCmd = &cobra.Command{ // Namespace argument is optional; defaults to configured property namespace if len(args) == 1 { - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - if len(qualifiedName.entityName) > 0 { - return entityNameError(qualifiedName.entityName) + if len(qualifiedName.GetEntityName()) > 0 { + return entityNameError(qualifiedName.GetEntityName()) } } - namespace, _, err := client.Namespaces.Get(qualifiedName.namespace) + namespace, _, err := client.Namespaces.Get(qualifiedName.GetNamespace()) if err != nil { whisk.Debug(whisk.DbgError, "client.Namespaces.Get(%s) error: %s\n", getClientNamespace(), err) diff --git a/commands/package.go b/commands/package.go index aed7c19..fcf6652 100644 --- a/commands/package.go +++ b/commands/package.go @@ -42,7 +42,8 @@ var packageBindCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error - var pkgQualifiedName, bindQualifiedName QualifiedName + var pkgQualifiedName = new(QualifiedName) + var bindQualifiedName = new(QualifiedName) if whiskErr := checkArgs(args, 2, 2, "Package bind", wski18n.T("A package name and binding name are required.")); whiskErr != nil { @@ -50,16 +51,16 @@ var packageBindCmd = &cobra.Command{ } packageName := args[0] - if pkgQualifiedName, err = parseQualifiedName(packageName); err != nil { - return parseQualifiedNameError(packageName, err) + if pkgQualifiedName, err = NewQualifiedName(packageName); err != nil { + return NewQualifiedNameError(packageName, err) } bindingName := args[1] - if bindQualifiedName, err = parseQualifiedName(bindingName); err != nil { - return parseQualifiedNameError(bindingName, err) + if bindQualifiedName, err = NewQualifiedName(bindingName); err != nil { + return NewQualifiedNameError(bindingName, err) } - client.Namespace = bindQualifiedName.namespace + client.Namespace = bindQualifiedName.GetNamespace() // 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 @@ -91,12 +92,12 @@ var packageBindCmd = &cobra.Command{ } binding := whisk.Binding{ - Name: pkgQualifiedName.entityName, - Namespace: pkgQualifiedName.namespace, + Name: pkgQualifiedName.GetEntityName(), + Namespace: pkgQualifiedName.GetNamespace(), } p := &whisk.BindingPackage{ - Name: bindQualifiedName.entityName, + Name: bindQualifiedName.GetEntityName(), Annotations: annotations.(whisk.KeyValueArr), Parameters: parameters.(whisk.KeyValueArr), Binding: binding, @@ -125,17 +126,17 @@ var packageCreateCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { var err error var shared, sharedSet bool - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) if whiskErr := checkArgs(args, 1, 1, "Package create", wski18n.T("A package name is required.")); whiskErr != nil { return whiskErr } - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - client.Namespace = qualifiedName.namespace + client.Namespace = qualifiedName.GetNamespace() if shared, sharedSet, err = parseShared(Flags.common.shared); err != nil { whisk.Debug(whisk.DbgError, "parseShared(%s) failed: %s\n", Flags.common.shared, err) @@ -165,8 +166,8 @@ var packageCreateCmd = &cobra.Command{ } p := &whisk.Package{ - Name: qualifiedName.entityName, - Namespace: qualifiedName.namespace, + Name: qualifiedName.GetEntityName(), + Namespace: qualifiedName.GetNamespace(), Annotations: annotations.(whisk.KeyValueArr), Parameters: parameters.(whisk.KeyValueArr), } @@ -181,7 +182,7 @@ var packageCreateCmd = &cobra.Command{ errStr := wski18n.T( "Unable to create package '{{.name}}': {{.err}}", map[string]interface{}{ - "name": qualifiedName.entityName, + "name": qualifiedName.GetEntityName(), "err": err, }) werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) @@ -189,7 +190,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(qualifiedName.entityName)})) + map[string]interface{}{"ok": color.GreenString(wski18n.T("ok:")), "name":boldString(qualifiedName.GetEntityName())})) return nil }, } @@ -203,17 +204,17 @@ var packageUpdateCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { var err error var shared, sharedSet bool - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) if whiskErr := checkArgs(args, 1, 1, "Package update", wski18n.T("A package name is required.")); whiskErr != nil { return whiskErr } - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - client.Namespace = qualifiedName.namespace + client.Namespace = qualifiedName.GetNamespace() if shared, sharedSet, err = parseShared(Flags.common.shared); err != nil { whisk.Debug(whisk.DbgError, "parseShared(%s) failed: %s\n", Flags.common.shared, err) @@ -242,8 +243,8 @@ var packageUpdateCmd = &cobra.Command{ } p := &whisk.Package{ - Name: qualifiedName.entityName, - Namespace: qualifiedName.namespace, + Name: qualifiedName.GetEntityName(), + Namespace: qualifiedName.GetNamespace(), Annotations: annotations.(whisk.KeyValueArr), Parameters: parameters.(whisk.KeyValueArr), } @@ -261,7 +262,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(qualifiedName.entityName)})) + map[string]interface{}{"ok": color.GreenString(wski18n.T("ok:")), "name":boldString(qualifiedName.GetEntityName())})) return nil }, } @@ -275,7 +276,7 @@ var packageGetCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { var err error var field string - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) if whiskErr := checkArgs(args, 1, 2, "Package get", wski18n.T("A package name is required.")); whiskErr != nil { return whiskErr @@ -292,18 +293,18 @@ var packageGetCmd = &cobra.Command{ } } - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - client.Namespace = qualifiedName.namespace + client.Namespace = qualifiedName.GetNamespace() - xPackage, _, err := client.Packages.Get(qualifiedName.entityName) + xPackage, _, err := client.Packages.Get(qualifiedName.GetEntityName()) if err != nil { - whisk.Debug(whisk.DbgError, "client.Packages.Get(%s) failed: %s\n", qualifiedName.entityName, err) + whisk.Debug(whisk.DbgError, "client.Packages.Get(%s) failed: %s\n", qualifiedName.GetEntityName(), err) errStr := wski18n.T( "Unable to get package '{{.name}}': {{.err}}", map[string]interface{}{ - "name": qualifiedName.entityName, + "name": qualifiedName.GetEntityName(), "err":err, }) werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) @@ -316,12 +317,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(qualifiedName.entityName), + map[string]interface{}{"ok": color.GreenString("ok:"), "name": boldString(qualifiedName.GetEntityName()), "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(qualifiedName.entityName)})) + map[string]interface{}{"ok": color.GreenString("ok:"), "name": boldString(qualifiedName.GetEntityName())})) printJSON(xPackage) } } @@ -338,25 +339,25 @@ var packageDeleteCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) if whiskErr := checkArgs(args, 1, 1, "Package delete", wski18n.T("A package name is required.")); whiskErr != nil { return whiskErr } - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - client.Namespace = qualifiedName.namespace + client.Namespace = qualifiedName.GetNamespace() - _, err = client.Packages.Delete(qualifiedName.entityName) + _, err = client.Packages.Delete(qualifiedName.GetEntityName()) if err != nil { - whisk.Debug(whisk.DbgError, "client.Packages.Delete(%s) failed: %s\n", qualifiedName.entityName, err) + whisk.Debug(whisk.DbgError, "client.Packages.Delete(%s) failed: %s\n", qualifiedName.GetEntityName(), err) errStr := wski18n.T( "Unable to delete package '{{.name}}': {{.err}}", map[string]interface{}{ - "name": qualifiedName.entityName, + "name": qualifiedName.GetEntityName(), "err": err, }) werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) @@ -365,7 +366,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(qualifiedName.entityName)})) + map[string]interface{}{"ok": color.GreenString("ok:"), "name": boldString(qualifiedName.GetEntityName())})) return nil }, } @@ -378,7 +379,7 @@ var packageListCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) if whiskErr := checkArgs(args, 0, 1, "Package list", wski18n.T("An optional namespace is the only valid argument.")); whiskErr != nil { @@ -386,15 +387,15 @@ var packageListCmd = &cobra.Command{ } if len(args) == 1 { - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - if len(qualifiedName.entityName) > 0 { - return entityNameError(qualifiedName.entityName) + if len(qualifiedName.GetEntityName()) > 0 { + return entityNameError(qualifiedName.GetEntityName()) } - client.Namespace = qualifiedName.namespace + client.Namespace = qualifiedName.GetNamespace() } options := &whisk.PackageListOptions{ @@ -425,7 +426,7 @@ var packageRefreshCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) if whiskErr := checkArgs(args, 0, 1, "Package refresh", wski18n.T("An optional namespace is the only valid argument.")); whiskErr != nil { @@ -433,19 +434,19 @@ var packageRefreshCmd = &cobra.Command{ } if len(args) == 0 { - qualifiedName.namespace = getNamespace() + qualifiedName.namespace = getNamespaceFromProp() } else { - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - if len(qualifiedName.entityName) > 0 { - return entityNameError(qualifiedName.entityName) + if len(qualifiedName.GetEntityName()) > 0 { + return entityNameError(qualifiedName.GetEntityName()) } } currentNamespace := client.Config.Namespace - client.Config.Namespace = qualifiedName.namespace + client.Config.Namespace = qualifiedName.GetNamespace() defer func() { client.Config.Namespace = currentNamespace diff --git a/commands/qualified_name.go b/commands/qualified_name.go new file mode 100644 index 0000000..61512f6 --- /dev/null +++ b/commands/qualified_name.go @@ -0,0 +1,215 @@ +/* + * 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" + "fmt" + "strings" + "../../go-whisk/whisk" + "../wski18n" +) + +type QualifiedName struct { + namespace string // namespace. does not include leading '/'. may be "" (i.e. default namespace) + packageName string // package. may be "". does not include leading/trailing '/' + entity string // entity. should not be "" + entityName string // pkg+entity +} + +/////////////////////////// +// QualifiedName Methods // +/////////////////////////// + +// GetFullQualifiedName() returns a full qualified name in proper string format +// from qualifiedName with proper syntax. +// Example: /namespace/[package/]entity +func (qualifiedName *QualifiedName) GetFullQualifiedName() string { + output := []string{} + + if len(qualifiedName.GetNamespace()) > 0 { + output = append(output, "/", qualifiedName.GetNamespace(), "/") + } + if len(qualifiedName.GetPackageName()) > 0 { + output = append(output, qualifiedName.GetPackageName(), "/") + } + output = append(output, qualifiedName.GetEntity()) + + return strings.Join(output, "") +} + +// GetPackageName() returns the package name from qualifiedName without a +// leading '/' +func (qualifiedName *QualifiedName) GetPackageName() string { + return qualifiedName.packageName +} + +// GetEntityName() returns the entity name ([package/]entity) of qualifiedName +// without a leading '/' +func (qualifiedName *QualifiedName) GetEntityName() string { + return qualifiedName.entityName +} + +// GetEntity() returns the name of entity in qualifiedName without a leading '/' +func (qualifiedName *QualifiedName) GetEntity() string { + return qualifiedName.entity +} + +// GetNamespace() returns the name of the namespace in qualifiedName without +// a leading '/' +func (qualifiedName *QualifiedName) GetNamespace() string { + return qualifiedName.namespace +} + +// NewQualifiedName(name) initializes and constructs a (possibly fully qualified) +// QualifiedName struct. +// +// NOTE: If the given qualified name is None, then this is a default qualified +// name and it is resolved from properties. +// NOTE: If the namespace is missing from the qualified name, the namespace +// is also resolved from the property file. +// +// Examples: +// 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 NewQualifiedName(name string) (*QualifiedName, error) { + qualifiedName := new(QualifiedName) + + // If name has a preceding delimiter (/), or if it has two delimiters with a + // leading non-empty string, then it contains a namespace. Otherwise the name + // does not specify a namespace, so default the namespace to the namespace + // value set in the properties file; if that is not set, use "_" + name = addLeadSlash(name) + parts := strings.Split(name, "/") + if strings.HasPrefix(name, "/") { + qualifiedName.namespace = parts[1] + + if len(parts) < 2 || len(parts) > 4 { + return qualifiedName, qualifiedNameNotSpecifiedErr() + } + + for i := 1; i < len(parts); i++ { + if len(parts[i]) == 0 || parts[i] == "." { + return qualifiedName, qualifiedNameNotSpecifiedErr() + } + } + + qualifiedName.entityName = strings.Join(parts[2:], "/") + if len(parts) == 4 { + qualifiedName.packageName = parts[2] + } + qualifiedName.entity = parts[len(parts)-1] + } else { + if len(name) == 0 || name == "." { + return qualifiedName, qualifiedNameNotSpecifiedErr() + } + + qualifiedName.entity = parts[len(parts)-1] + if len(parts) == 2 { + qualifiedName.packageName = parts[0] + } + qualifiedName.entityName = name + qualifiedName.namespace = getNamespaceFromProp() + } + + whisk.Debug(whisk.DbgInfo, "Qualified pkg+entity (EntityName): %s\n", qualifiedName.GetEntityName()) + whisk.Debug(whisk.DbgInfo, "Qualified namespace: %s\n", qualifiedName.GetNamespace()) + whisk.Debug(whisk.DbgInfo, "Qualified package: %s\n", qualifiedName.GetPackageName()) + whisk.Debug(whisk.DbgInfo, "Qualified entity: %s\n", qualifiedName.GetEntity()) + + return qualifiedName, nil +} + +///////////////////// +// Error Functions // +///////////////////// + +// qualifiedNameNotSpecifiedErr() returns generic whisk error for +// invalid qualified names detected while building a new +// QualifiedName struct. +func qualifiedNameNotSpecifiedErr() error { + whisk.Debug(whisk.DbgError, "A valid qualified name was not detected\n") + errStr := wski18n.T("A valid qualified name must be specified.") + return whisk.MakeWskError(errors.New(errStr), whisk.NOT_ALLOWED, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) +} + +// NewQualifiedNameError(entityName, err) returns specific whisk error +// for invalid qualified names. +func NewQualifiedNameError(entityName string, err error) (error) { + whisk.Debug(whisk.DbgError, "NewQualifiedName(%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.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE) +} + +/////////////////////////// +// Helper/Misc Functions // +/////////////////////////// + +// addLeadSlash(name) returns a (possibly fully qualified) resource name, +// inserting a leading '/' if it is of 3 parts (namespace/package/action) +// and lacking the leading '/'. +func addLeadSlash(name string) string { + parts := strings.Split(name, "/") + if len(parts) == 3 && parts[0] != "" { + name = "/" + name + } + return name +} + +// getNamespaceFromProp() returns a namespace from Properties if one exists, +// else defaults to returning "_" +func getNamespaceFromProp() (string) { + namespace := "_" + + if Properties.Namespace != "" { + namespace = Properties.Namespace + } + + return namespace +} + +// getQualifiedName(name, namespace) returns a fully qualified name given a +// (possibly fully qualified) resource name and optional namespace. +// +// Examples: +// (foo, None) => /_/foo +// (pkg/foo, None) => /_/pkg/foo +// (foo, ns) => /ns/foo +// (/ns/pkg/foo, None) => /ns/pkg/foo +// (/ns/pkg/foo, otherns) => /ns/pkg/foo +func getQualifiedName(name string, namespace string) (string) { + name = addLeadSlash(name) + if strings.HasPrefix(name, "/") { + return name + } else if strings.HasPrefix(namespace, "/") { + return fmt.Sprintf("%s/%s", namespace, name) + } else { + if len(namespace) == 0 { + namespace = Properties.Namespace + } + return fmt.Sprintf("/%s/%s", namespace, name) + } +} diff --git a/commands/rule.go b/commands/rule.go index 918b6df..4d34af6 100644 --- a/commands/rule.go +++ b/commands/rule.go @@ -42,18 +42,18 @@ var ruleEnableCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) if whiskErr := checkArgs(args, 1, 1, "Rule enable", wski18n.T("A rule name is required.")); whiskErr != nil { return whiskErr } - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - client.Namespace = qualifiedName.namespace - ruleName := qualifiedName.entityName + client.Namespace = qualifiedName.GetNamespace() + ruleName := qualifiedName.GetEntityName() _, _, err = client.Rules.SetState(ruleName, "active") if err != nil { @@ -79,18 +79,18 @@ var ruleDisableCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) if whiskErr := checkArgs(args, 1, 1, "Rule disable", wski18n.T("A rule name is required.")); whiskErr != nil { return whiskErr } - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - client.Namespace = qualifiedName.namespace - ruleName := qualifiedName.entityName + client.Namespace = qualifiedName.GetNamespace() + ruleName := qualifiedName.GetEntityName() _, _, err = client.Rules.SetState(ruleName, "inactive") if err != nil { @@ -116,18 +116,18 @@ var ruleStatusCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) if whiskErr := checkArgs(args, 1, 1, "Rule status", wski18n.T("A rule name is required.")); whiskErr != nil { return whiskErr } - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - client.Namespace = qualifiedName.namespace - ruleName := qualifiedName.entityName + client.Namespace = qualifiedName.GetNamespace() + ruleName := qualifiedName.GetEntityName() rule, _, err := client.Rules.Get(ruleName) if err != nil { @@ -153,19 +153,19 @@ var ruleCreateCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) if whiskErr := checkArgs(args, 3, 3, "Rule create", wski18n.T("A rule, trigger and action name are required.")); whiskErr != nil { return whiskErr } - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - client.Namespace = qualifiedName.namespace - ruleName := qualifiedName.entityName + client.Namespace = qualifiedName.GetNamespace() + ruleName := qualifiedName.GetEntityName() triggerName := getQualifiedName(args[1], Properties.Namespace) actionName := getQualifiedName(args[2], Properties.Namespace) @@ -202,19 +202,19 @@ var ruleUpdateCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) if whiskErr := checkArgs(args, 3, 3, "Rule update", wski18n.T("A rule, trigger and action name are required.")); whiskErr != nil { return whiskErr } - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - client.Namespace = qualifiedName.namespace - ruleName := qualifiedName.entityName + client.Namespace = qualifiedName.GetNamespace() + ruleName := qualifiedName.GetEntityName() triggerName := getQualifiedName(args[1], Properties.Namespace) actionName := getQualifiedName(args[2], Properties.Namespace) @@ -249,7 +249,7 @@ var ruleGetCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { var err error var field string - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) if whiskErr := checkArgs(args, 1, 2, "Rule get", wski18n.T("A rule name is required.")); whiskErr != nil { return whiskErr @@ -266,12 +266,12 @@ var ruleGetCmd = &cobra.Command{ } } - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - client.Namespace = qualifiedName.namespace - ruleName := qualifiedName.entityName + client.Namespace = qualifiedName.GetNamespace() + ruleName := qualifiedName.GetEntityName() rule, _, err := client.Rules.Get(ruleName) if err != nil { @@ -309,18 +309,18 @@ var ruleDeleteCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) if whiskErr := checkArgs(args, 1, 1, "Rule delete", wski18n.T("A rule name is required.")); whiskErr != nil { return whiskErr } - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - client.Namespace = qualifiedName.namespace - ruleName := qualifiedName.entityName + client.Namespace = qualifiedName.GetNamespace() + ruleName := qualifiedName.GetEntityName() if Flags.rule.disable { _, _, err := client.Rules.SetState(ruleName, "inactive") @@ -357,7 +357,7 @@ var ruleListCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) if whiskErr := checkArgs(args, 0, 1, "Rule list", wski18n.T("An optional namespace is the only valid argument.")); whiskErr != nil { @@ -365,15 +365,15 @@ var ruleListCmd = &cobra.Command{ } if len(args) == 1 { - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - if len(qualifiedName.entityName) > 0 { - return entityNameError(qualifiedName.entityName) + if len(qualifiedName.GetEntityName()) > 0 { + return entityNameError(qualifiedName.GetEntityName()) } - client.Namespace = qualifiedName.namespace + client.Namespace = qualifiedName.GetNamespace() } ruleListOptions := &whisk.RuleListOptions{ diff --git a/commands/shared.go b/commands/shared.go index 916debc..b380d5b 100644 --- a/commands/shared.go +++ b/commands/shared.go @@ -33,16 +33,3 @@ func entityNameError(entityName string) (error) { return whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_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.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE) -} diff --git a/commands/trigger.go b/commands/trigger.go index 40524b6..4b1c2e9 100644 --- a/commands/trigger.go +++ b/commands/trigger.go @@ -49,18 +49,18 @@ var triggerFireCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { var err error var parameters interface{} - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) if whiskErr := checkArgs(args, 1, 2, "Trigger fire", wski18n.T("A trigger name is required. A payload is optional.")); whiskErr != nil { return whiskErr } - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - client.Namespace = qualifiedName.namespace + client.Namespace = qualifiedName.GetNamespace() // Add payload to parameters if len(args) == 2 { @@ -80,11 +80,11 @@ var triggerFireCmd = &cobra.Command{ } } - trigResp, _, err := client.Triggers.Fire(qualifiedName.entityName, parameters) + trigResp, _, err := client.Triggers.Fire(qualifiedName.GetEntityName(), parameters) if err != nil { - whisk.Debug(whisk.DbgError, "client.Triggers.Fire(%s, %#v) failed: %s\n", qualifiedName.entityName, parameters, err) + whisk.Debug(whisk.DbgError, "client.Triggers.Fire(%s, %#v) failed: %s\n", qualifiedName.GetEntityName(), parameters, err) errStr := wski18n.T("Unable to fire trigger '{{.name}}': {{.err}}", - map[string]interface{}{"name": qualifiedName.entityName, "err": err}) + map[string]interface{}{"name": qualifiedName.GetEntityName(), "err": err}) werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) return werr @@ -94,8 +94,8 @@ var triggerFireCmd = &cobra.Command{ wski18n.T("{{.ok}} triggered /{{.namespace}}/{{.name}} with id {{.id}}\n", map[string]interface{}{ "ok": color.GreenString("ok:"), - "namespace": boldString(qualifiedName.namespace), - "name": boldString(qualifiedName.entityName), + "namespace": boldString(qualifiedName.GetNamespace()), + "name": boldString(qualifiedName.GetEntityName()), "id": boldString(trigResp.ActivationId)})) return nil }, @@ -111,31 +111,31 @@ var triggerCreateCmd = &cobra.Command{ var err error var annotations interface{} var feedArgPassed bool = (Flags.common.feed != "") - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) if whiskErr := checkArgs(args, 1, 1, "Trigger create", wski18n.T("A trigger name is required.")); whiskErr != nil { return whiskErr } - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - client.Namespace = qualifiedName.namespace + client.Namespace = qualifiedName.GetNamespace() var fullTriggerName string var fullFeedName string - var feedQualifiedName QualifiedName + var feedQualifiedName = new(QualifiedName) if feedArgPassed { whisk.Debug(whisk.DbgInfo, "Trigger has a feed\n") - if feedQualifiedName, err = parseQualifiedName(Flags.common.feed); err != nil { - return parseQualifiedNameError(Flags.common.feed, err) + if feedQualifiedName, err = NewQualifiedName(Flags.common.feed); err != nil { + return NewQualifiedNameError(Flags.common.feed, err) } - fullFeedName = fmt.Sprintf("/%s/%s", feedQualifiedName.namespace, feedQualifiedName.entityName) - fullTriggerName = fmt.Sprintf("/%s/%s", qualifiedName.namespace, qualifiedName.entityName) + fullFeedName = fmt.Sprintf("/%s/%s", feedQualifiedName.GetNamespace(), feedQualifiedName.GetEntityName()) + fullTriggerName = fmt.Sprintf("/%s/%s", qualifiedName.GetNamespace(), qualifiedName.GetEntityName()) 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)) @@ -173,7 +173,7 @@ var triggerCreateCmd = &cobra.Command{ } trigger := &whisk.Trigger{ - Name: qualifiedName.entityName, + Name: qualifiedName.GetEntityName(), Annotations: annotations.(whisk.KeyValueArr), } @@ -224,18 +224,18 @@ var triggerUpdateCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) if whiskErr := checkArgs(args, 1, 1, "Trigger update", wski18n.T("A trigger name is required.")); whiskErr != nil { return whiskErr } - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - client.Namespace = qualifiedName.namespace + client.Namespace = qualifiedName.GetNamespace() // 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 @@ -264,7 +264,7 @@ var triggerUpdateCmd = &cobra.Command{ } trigger := &whisk.Trigger{ - Name: qualifiedName.entityName, + Name: qualifiedName.GetEntityName(), Parameters: parameters.(whisk.KeyValueArr), Annotations: annotations.(whisk.KeyValueArr), } @@ -294,7 +294,7 @@ var triggerGetCmd = &cobra.Command{ RunE: func(cmd *cobra.Command, args []string) error { var err error var field string - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) if whiskErr := checkArgs(args, 1, 2, "Trigger get", wski18n.T("A trigger name is required.")); whiskErr != nil { return whiskErr @@ -311,17 +311,17 @@ var triggerGetCmd = &cobra.Command{ } } - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - client.Namespace = qualifiedName.namespace + client.Namespace = qualifiedName.GetNamespace() - retTrigger, _, err := client.Triggers.Get(qualifiedName.entityName) + retTrigger, _, err := client.Triggers.Get(qualifiedName.GetEntityName()) if err != nil { - whisk.Debug(whisk.DbgError, "client.Triggers.Get(%s) failed: %s\n", qualifiedName.entityName, err) + whisk.Debug(whisk.DbgError, "client.Triggers.Get(%s) failed: %s\n", qualifiedName.GetEntityName(), err) errStr := wski18n.T("Unable to get trigger '{{.name}}': {{.err}}", - map[string]interface{}{"name": qualifiedName.entityName, "err": err}) + map[string]interface{}{"name": qualifiedName.GetEntityName(), "err": err}) werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) return werr } @@ -331,12 +331,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(qualifiedName.entityName), + map[string]interface{}{"ok": color.GreenString("ok:"), "name": boldString(qualifiedName.GetEntityName()), "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(qualifiedName.entityName)})) + map[string]interface{}{"ok": color.GreenString("ok:"), "name": boldString(qualifiedName.GetEntityName())})) printJSON(retTrigger) } } @@ -356,24 +356,24 @@ var triggerDeleteCmd = &cobra.Command{ var retTrigger *whisk.Trigger var fullFeedName string var origParams []string - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) if whiskErr := checkArgs(args, 1, 1, "Trigger delete", wski18n.T("A trigger name is required.")); whiskErr != nil { return whiskErr } - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - client.Namespace = qualifiedName.namespace + client.Namespace = qualifiedName.GetNamespace() - retTrigger, _, err = client.Triggers.Get(qualifiedName.entityName) + retTrigger, _, err = client.Triggers.Get(qualifiedName.GetEntityName()) if err != nil { - whisk.Debug(whisk.DbgError, "client.Triggers.Get(%s) failed: %s\n", qualifiedName.entityName, err) + whisk.Debug(whisk.DbgError, "client.Triggers.Get(%s) failed: %s\n", qualifiedName.GetEntityName(), err) errStr := wski18n.T("Unable to get trigger '{{.name}}': {{.err}}", - map[string]interface{}{"name": qualifiedName.entityName, "err": err}) + map[string]interface{}{"name": qualifiedName.GetEntityName(), "err": err}) werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXIT_CODE_ERR_GENERAL, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) return werr } @@ -384,34 +384,34 @@ var triggerDeleteCmd = &cobra.Command{ if len(fullFeedName) > 0 { origParams = Flags.common.param - fullTriggerName := fmt.Sprintf("/%s/%s", qualifiedName.namespace, qualifiedName.entityName) + fullTriggerName := fmt.Sprintf("/%s/%s", qualifiedName.GetNamespace(), qualifiedName.GetEntityName()) 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(qualifiedName.entityName, fullFeedName) + err = configureFeed(qualifiedName.GetEntityName(), fullFeedName) if err != nil { - whisk.Debug(whisk.DbgError, "configureFeed(%s, %s) failed: %s\n", qualifiedName.entityName, fullFeedName, err) + whisk.Debug(whisk.DbgError, "configureFeed(%s, %s) failed: %s\n", qualifiedName.GetEntityName(), fullFeedName, err) } Flags.common.param = origParams - client.Namespace = qualifiedName.namespace + client.Namespace = qualifiedName.GetNamespace() } } - retTrigger, _, err = client.Triggers.Delete(qualifiedName.entityName) + retTrigger, _, err = client.Triggers.Delete(qualifiedName.GetEntityName()) if err != nil { - whisk.Debug(whisk.DbgError, "client.Triggers.Delete(%s) failed: %s\n", qualifiedName.entityName, err) + whisk.Debug(whisk.DbgError, "client.Triggers.Delete(%s) failed: %s\n", qualifiedName.GetEntityName(), err) errStr := wski18n.T("Unable to delete trigger '{{.name}}': {{.err}}", - map[string]interface{}{"name": qualifiedName.entityName, "err": err}) + map[string]interface{}{"name": qualifiedName.GetEntityName(), "err": err}) werr := whisk.MakeWskErrorFromWskError(errors.New(errStr), err, whisk.EXIT_CODE_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(qualifiedName.entityName)})) + map[string]interface{}{"ok": color.GreenString("ok:"), "name": boldString(qualifiedName.GetEntityName())})) return nil }, @@ -425,7 +425,7 @@ var triggerListCmd = &cobra.Command{ PreRunE: setupClientConfig, RunE: func(cmd *cobra.Command, args []string) error { var err error - var qualifiedName QualifiedName + var qualifiedName = new(QualifiedName) if whiskErr := checkArgs(args, 0, 1, "Trigger list", wski18n.T("An optional namespace is the only valid argument.")); whiskErr != nil { @@ -433,15 +433,15 @@ var triggerListCmd = &cobra.Command{ } if len(args) == 1 { - if qualifiedName, err = parseQualifiedName(args[0]); err != nil { - return parseQualifiedNameError(args[0], err) + if qualifiedName, err = NewQualifiedName(args[0]); err != nil { + return NewQualifiedNameError(args[0], err) } - if len(qualifiedName.entityName) > 0 { - return entityNameError(qualifiedName.entityName) + if len(qualifiedName.GetEntityName()) > 0 { + return entityNameError(qualifiedName.GetEntityName()) } - client.Namespace = qualifiedName.namespace + client.Namespace = qualifiedName.GetNamespace() } options := &whisk.TriggerListOptions{ diff --git a/commands/util.go b/commands/util.go index faeb728..8bb5aae 100644 --- a/commands/util.go +++ b/commands/util.go @@ -42,128 +42,6 @@ import ( "bytes" ) -type QualifiedName struct { - namespace string // namespace. does not include leading '/'. may be "" (i.e. default namespace) - packageName string // package. may be "". does not include leading/trailing '/' - entity string // entity. should not be "" - entityName string // pkg+entity -} - -func (qualifiedName QualifiedName) String() string { - output := []string{} - - if len(qualifiedName.namespace) > 0 { - output = append(output, "/", qualifiedName.namespace, "/") - } - if len(qualifiedName.packageName) > 0 { - output = append(output, qualifiedName.packageName, "/") - } - output = append(output, qualifiedName.entityName) - - return strings.Join(output, "") -} - -/* -Parse a (possibly fully qualified) resource name into namespace and name components. If the given qualified name isNone, -then this is a default qualified name and it is resolved from properties. If the namespace is missing from the qualified -name, the namespace is also resolved from the property file. - -Return a qualifiedName struct - -Examples: - 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 - - // If name has a preceding delimiter (/), it contains a namespace. Otherwise the name does not specify a namespace, - // so default the namespace to the namespace value set in the properties file; if that is not set, use "_" - if strings.HasPrefix(name, "/") { - parts := strings.Split(name, "/") - qualifiedName.namespace = parts[1] - - if len(parts) < 2 || len(parts) > 4 { - whisk.Debug(whisk.DbgError, "A valid qualified name was not detected\n") - errStr := wski18n.T("A valid qualified name must be specified.") - err := whisk.MakeWskError(errors.New(errStr), whisk.NOT_ALLOWED, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - return qualifiedName, err - } - - for i := 1; i < len(parts); i++ { - if len(parts[i]) == 0 || parts[i] == "." { - whisk.Debug(whisk.DbgError, "A valid qualified name was not detected\n") - errStr := wski18n.T("A valid qualified name must be specified.") - err := whisk.MakeWskError(errors.New(errStr), whisk.NOT_ALLOWED, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - return qualifiedName, err - } - } - - qualifiedName.entityName = strings.Join(parts[2:], "/") - if len(parts) == 4 { - qualifiedName.packageName = parts[2] - } - qualifiedName.entity = parts[len(parts)-1] - } else { - if len(name) == 0 || name == "." { - whisk.Debug(whisk.DbgError, "A valid qualified name was not detected\n") - errStr := wski18n.T("A valid qualified name must be specified.") - err := whisk.MakeWskError(errors.New(errStr), whisk.NOT_ALLOWED, whisk.DISPLAY_MSG, whisk.NO_DISPLAY_USAGE) - return qualifiedName, err - } - - parts := strings.Split(name, "/") - qualifiedName.entity = parts[len(parts)-1] - if len(parts) == 2 { - qualifiedName.packageName = parts[0] - } - qualifiedName.entityName = name - qualifiedName.namespace = getNamespace() - } - - whisk.Debug(whisk.DbgInfo, "Qualified pkg+entity (EntityName): %s\n", qualifiedName.entityName) - whisk.Debug(whisk.DbgInfo, "Qualified namespace: %s\n", qualifiedName.namespace) - whisk.Debug(whisk.DbgInfo, "Qualified package: %s\n", qualifiedName.packageName) - whisk.Debug(whisk.DbgInfo, "Qualified entity: %s\n", qualifiedName.entity) - - return qualifiedName, nil -} - -func getNamespace() (string) { - namespace := "_" - - if Properties.Namespace != "" { - namespace = Properties.Namespace - } - - return namespace -} - -/* -Return a fully qualified name given a (possibly fully qualified) resource name and optional namespace. - -Examples: - (foo, None) => /_/foo - (pkg/foo, None) => /_/pkg/foo - (foo, ns) => /ns/foo - (/ns/pkg/foo, None) => /ns/pkg/foo - (/ns/pkg/foo, otherns) => /ns/pkg/foo -*/ -func getQualifiedName(name string, namespace string) (string) { - if strings.HasPrefix(name, "/") { - return name - } else if strings.HasPrefix(namespace, "/") { - return fmt.Sprintf("%s/%s", namespace, name) - } else { - if len(namespace) == 0 { - namespace = Properties.Namespace - } - return fmt.Sprintf("/%s/%s", namespace, name) - } -} - func csvToQualifiedActions(artifacts string) ([]string) { var res []string actions := strings.Split(artifacts, ",") -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
