This is an automated email from the ASF dual-hosted git repository. rabbah pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk.git
The following commit(s) were added to refs/heads/master by this push: new c2c44c3 Allow FQN with 3 parts (namespace/package/action) to be input with/without leading slash in CLI (#2424) c2c44c3 is described below commit c2c44c3c45c46d42c4c8042c0288e094607dbd68 Author: Brandon Lee Underwood <brandon.lee.underw...@ibm.com> 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) --- docs/reference.md | 19 +- tests/src/test/scala/common/Wsk.scala | 2 +- .../test/scala/system/basic/WskActionTests.scala | 1 - .../whisk/core/cli/test/WskBasicUsageTests.scala | 29 +++ tools/cli/go-whisk-cli/commands/action.go | 108 +++++------ tools/cli/go-whisk-cli/commands/activation.go | 10 +- tools/cli/go-whisk-cli/commands/api.go | 23 ++- tools/cli/go-whisk-cli/commands/namespace.go | 12 +- tools/cli/go-whisk-cli/commands/package.go | 109 +++++------ tools/cli/go-whisk-cli/commands/qualified_name.go | 215 +++++++++++++++++++++ tools/cli/go-whisk-cli/commands/rule.go | 82 ++++---- tools/cli/go-whisk-cli/commands/shared.go | 13 -- tools/cli/go-whisk-cli/commands/trigger.go | 108 +++++------ tools/cli/go-whisk-cli/commands/util.go | 122 ------------ 14 files changed, 482 insertions(+), 371 deletions(-) diff --git a/docs/reference.md b/docs/reference.md index e5ec838..783b06e 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -19,7 +19,10 @@ You can create your own namespaces if you're entitled to do so. The `/whisk.syst ### Fully qualified names The fully qualified name of an entity is -`/namespaceName[/packageName]/entityName`. Notice that `/` is used to delimit namespaces, packages, and entities. Also, namespaces must be prefixed with a `/`. +`/namespaceName[/packageName]/entityName`. Notice that `/` is used to delimit namespaces, packages, and entities. + +If the fully qualified name has three parts: +`/namespaceName/packageName/entityName`, then the namespace can be entered without a prefixed `/`; otherwise, namespaces must be prefixed with a `/`. For convenience, the namespace can be left off if it is the user's *default namespace*. @@ -219,23 +222,23 @@ The following packages are available to be used in the Node.js 6.9.1 environment - [glob v7.1.1](https://www.npmjs.com/package/glob) - Match files using the patterns the shell uses, like stars and stuff. - [gm v1.23.0](https://www.npmjs.com/package/gm) - GraphicsMagick and ImageMagick for Node. - [lodash v4.17.2](https://www.npmjs.com/package/lodash) - The Lodash library exported as Node.js modules. -- [log4js v0.6.38](https://www.npmjs.com/package/log4js) - This is a conversion of the log4js framework to work with Node. +- [log4js v0.6.38](https://www.npmjs.com/package/log4js) - This is a conversion of the log4js framework to work with Node. - [iconv-lite v0.4.15](https://www.npmjs.com/package/iconv-lite) - Pure JS character encoding conversion - [marked v0.3.6](https://www.npmjs.com/package/marked) - A full-featured markdown parser and compiler, written in JavaScript. Built for speed. -- [merge v1.2.0](https://www.npmjs.com/package/merge) - Merge multiple objects into one, optionally creating a new cloned object. +- [merge v1.2.0](https://www.npmjs.com/package/merge) - Merge multiple objects into one, optionally creating a new cloned object. - [moment v2.17.0](https://www.npmjs.com/package/moment) - A lightweight JavaScript date library for parsing, validating, manipulating, and formatting dates. - [mongodb v2.2.11](https://www.npmjs.com/package/mongodb) - The official MongoDB driver for Node.js. - [mustache v2.3.0](https://www.npmjs.com/package/mustache) - mustache.js is an implementation of the mustache template system in JavaScript. - [nano v6.2.0](https://www.npmjs.com/package/nano) - minimalistic couchdb driver for Node.js. -- [node-uuid v1.4.7](https://www.npmjs.com/package/node-uuid) - Deprecated UUID packaged. +- [node-uuid v1.4.7](https://www.npmjs.com/package/node-uuid) - Deprecated UUID packaged. - [nodemailer v2.6.4](https://www.npmjs.com/package/nodemailer) - Send e-mails from Node.js – easy as cake! - [oauth2-server v2.4.1](https://www.npmjs.com/package/oauth2-server) - Complete, compliant and well tested module for implementing an OAuth2 Server/Provider with express in Node.js. - [openwhisk v3.3.2](https://www.npmjs.com/package/openwhisk) - JavaScript client library for the OpenWhisk platform. Provides a wrapper around the OpenWhisk APIs. - [pkgcloud v1.4.0](https://www.npmjs.com/package/pkgcloud) - pkgcloud is a standard library for Node.js that abstracts away differences among multiple cloud providers. - [process v0.11.9](https://www.npmjs.com/package/process) - require('process'); just like any other module. - [pug v2.0.0-beta6](https://www.npmjs.com/package/pug) - Implements the Pug templating language. -- [redis v2.6.3](https://www.npmjs.com/package/redis) - This is a complete and feature rich Redis client for Node.js. -- [request v2.79.0](https://www.npmjs.com/package/request) - Request is designed to be the simplest way possible to make HTTP calls. +- [redis v2.6.3](https://www.npmjs.com/package/redis) - This is a complete and feature rich Redis client for Node.js. +- [request v2.79.0](https://www.npmjs.com/package/request) - Request is designed to be the simplest way possible to make HTTP calls. - [request-promise v4.1.1](https://www.npmjs.com/package/request-promise) - The simplified HTTP request client 'request' with Promise support. Powered by Bluebird. - [rimraf v2.5.4](https://www.npmjs.com/package/rimraf) - The UNIX command rm -rf for node. - [semver v5.3.0](https://www.npmjs.com/package/semver) - Supports semantic versioning. @@ -251,10 +254,10 @@ The following packages are available to be used in the Node.js 6.9.1 environment - [uuid v3.0.0](https://www.npmjs.com/package/uuid) - Simple, fast generation of RFC4122 UUIDS. - [validator v6.1.0](https://www.npmjs.com/package/validator) - A library of string validators and sanitizers. - [watson-developer-cloud v2.29.0](https://www.npmjs.com/package/watson-developer-cloud) - Node.js client library to use the Watson Developer Cloud services, a collection of APIs that use cognitive computing to solve complex problems. -- [when v3.7.7](https://www.npmjs.com/package/when) - When.js is a rock solid, battle-tested Promises/A+ and when() implementation, including a complete ES6 Promise shim. +- [when v3.7.7](https://www.npmjs.com/package/when) - When.js is a rock solid, battle-tested Promises/A+ and when() implementation, including a complete ES6 Promise shim. - [winston v2.3.0](https://www.npmjs.com/package/winston) - A multi-transport async logging library for node.js. "CHILL WINSTON! ... I put it in the logs." - [ws v1.1.1](https://www.npmjs.com/package/ws) - ws is a simple to use, blazing fast, and thoroughly tested WebSocket client and server implementation. -- [xml2js v0.4.17](https://www.npmjs.com/package/xml2js) - Simple XML to JavaScript object converter. It supports bi-directional conversion. +- [xml2js v0.4.17](https://www.npmjs.com/package/xml2js) - Simple XML to JavaScript object converter. It supports bi-directional conversion. - [xmlhttprequest v1.8.0](https://www.npmjs.com/package/xmlhttprequest) - node-XMLHttpRequest is a wrapper for the built-in http client to emulate the browser XMLHttpRequest object. - [yauzl v2.7.0](https://www.npmjs.com/package/yauzl) - yet another unzip library for node. For zipping. diff --git a/tests/src/test/scala/common/Wsk.scala b/tests/src/test/scala/common/Wsk.scala index 540857b..79a1054 100644 --- a/tests/src/test/scala/common/Wsk.scala +++ b/tests/src/test/scala/common/Wsk.scala @@ -111,7 +111,7 @@ trait FullyQualifiedNames { */ def fqn(name: String)(implicit wp: WskProps) = { val sep = "/" // Namespace.PATHSEP - if (name.startsWith(sep)) name + if (name.startsWith(sep) || name.count(_ == sep(0)) == 2) name else s"$sep${wp.namespace}$sep$name" } diff --git a/tests/src/test/scala/system/basic/WskActionTests.scala b/tests/src/test/scala/system/basic/WskActionTests.scala index 05a1c83..90e92b9 100644 --- a/tests/src/test/scala/system/basic/WskActionTests.scala +++ b/tests/src/test/scala/system/basic/WskActionTests.scala @@ -355,5 +355,4 @@ class WskActionTests activation.logs.get.mkString(" ") should include(s"hello $utf8") } } - } 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 59ede45..c451bbd 100644 --- a/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala +++ b/tests/src/test/scala/whisk/core/cli/test/WskBasicUsageTests.scala @@ -91,6 +91,35 @@ class WskBasicUsageTests result.stderr should include regex ("""(?i)Run 'wsk --help' for usage""") } + it should "allow a 3 part Fully Qualified Name (FQN) without a leading '/'" in withAssetCleaner(wskprops) { + (wp, assetHelper) => + val guestNamespace = wsk.namespace.whois() + val packageName = "packageName3ptFQN" + val actionName = "actionName3ptFQN" + val triggerName = "triggerName3ptFQN" + val ruleName = "ruleName3ptFQN" + val fullQualifiedName = s"${guestNamespace}/${packageName}/${actionName}" + // Used for action and rule creation below + assetHelper.withCleaner(wsk.pkg, packageName) { + (pkg, _) => pkg.create(packageName) + } + assetHelper.withCleaner(wsk.trigger, triggerName) { + (trigger, _) => trigger.create(triggerName) + } + // Test action and rule creation where action name is 3 part FQN w/out leading slash + assetHelper.withCleaner(wsk.action, fullQualifiedName) { + (action, _) => action.create(fullQualifiedName, defaultAction) + } + assetHelper.withCleaner(wsk.rule, ruleName) { + (rule, _) => + rule.create(ruleName, trigger = triggerName, action = fullQualifiedName) + } + + wsk.action.invoke(fullQualifiedName).stdout should include(s"ok: invoked /$fullQualifiedName") + wsk.action.get(fullQualifiedName).stdout should include(s"ok: got action ${packageName}/${actionName}") + } + + behavior of "Wsk actions" it should "reject creating entities with invalid names" in withAssetCleaner(wskprops) { diff --git a/tools/cli/go-whisk-cli/commands/action.go b/tools/cli/go-whisk-cli/commands/action.go index 33fd5ab..3008a57 100644 --- a/tools/cli/go-whisk-cli/commands/action.go +++ b/tools/cli/go-whisk-cli/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 { @@ -148,12 +148,12 @@ var actionInvokeCmd = &cobra.Command{ if flags.action.result {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) }, } @@ -164,29 +164,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) } } } @@ -204,7 +204,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 @@ -218,29 +218,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) + 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) } } @@ -255,7 +255,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( @@ -267,17 +267,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 }, @@ -290,7 +290,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 @@ -304,11 +304,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{ @@ -316,8 +316,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) @@ -334,16 +334,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), @@ -372,19 +372,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...) @@ -407,7 +407,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) @@ -874,10 +874,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/tools/cli/go-whisk-cli/commands/activation.go b/tools/cli/go-whisk-cli/commands/activation.go index 868f216..4ae62fe 100644 --- a/tools/cli/go-whisk-cli/commands/activation.go +++ b/tools/cli/go-whisk-cli/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/tools/cli/go-whisk-cli/commands/api.go b/tools/cli/go-whisk-cli/commands/api.go index 95b5c16..b4c4306 100644 --- a/tools/cli/go-whisk-cli/commands/api.go +++ b/tools/cli/go-whisk-cli/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/tools/cli/go-whisk-cli/commands/namespace.go b/tools/cli/go-whisk-cli/commands/namespace.go index cee13ba..f132913 100644 --- a/tools/cli/go-whisk-cli/commands/namespace.go +++ b/tools/cli/go-whisk-cli/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/tools/cli/go-whisk-cli/commands/package.go b/tools/cli/go-whisk-cli/commands/package.go index 7680fcf..6721f34 100644 --- a/tools/cli/go-whisk-cli/commands/package.go +++ b/tools/cli/go-whisk-cli/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/tools/cli/go-whisk-cli/commands/qualified_name.go b/tools/cli/go-whisk-cli/commands/qualified_name.go new file mode 100644 index 0000000..61512f6 --- /dev/null +++ b/tools/cli/go-whisk-cli/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/tools/cli/go-whisk-cli/commands/rule.go b/tools/cli/go-whisk-cli/commands/rule.go index 996c368..47607cd 100644 --- a/tools/cli/go-whisk-cli/commands/rule.go +++ b/tools/cli/go-whisk-cli/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/tools/cli/go-whisk-cli/commands/shared.go b/tools/cli/go-whisk-cli/commands/shared.go index ed8364d..77afb10 100644 --- a/tools/cli/go-whisk-cli/commands/shared.go +++ b/tools/cli/go-whisk-cli/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/tools/cli/go-whisk-cli/commands/trigger.go b/tools/cli/go-whisk-cli/commands/trigger.go index 4f94451..b6f8b0b 100644 --- a/tools/cli/go-whisk-cli/commands/trigger.go +++ b/tools/cli/go-whisk-cli/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/tools/cli/go-whisk-cli/commands/util.go b/tools/cli/go-whisk-cli/commands/util.go index 3ef9ff0..afe7cbe 100644 --- a/tools/cli/go-whisk-cli/commands/util.go +++ b/tools/cli/go-whisk-cli/commands/util.go @@ -41,128 +41,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 ['"commits@openwhisk.apache.org" <commits@openwhisk.apache.org>'].