This is an automated email from the ASF dual-hosted git repository. pdesai pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/openwhisk-wskdeploy.git
The following commit(s) were added to refs/heads/master by this push: new 0a6491c Enable setting user-supplied auth tokens on API create via require-whisk-auth annotation (#1083) 0a6491c is described below commit 0a6491cde1d9ef7275db997652e89fc663854c6f Author: Matt Rutkowski <mrutk...@us.ibm.com> AuthorDate: Fri Jan 24 17:44:27 2020 -0600 Enable setting user-supplied auth tokens on API create via require-whisk-auth annotation (#1083) * Fix schema for web-secure and support auth annotations * Fix schema for web-secure and support auth annotations * Fix schema for web-secure and support auth annotations * Fix schema for web-secure and support auth annotations * Fix schema for web-secure and support auth annotations * Fix schema for web-secure and support auth annotations * Fix schema for web-secure and support auth annotations * Fix schema for web-secure and support auth annotations * Fix schema for web-secure and support auth annotations * Fix schema for web-secure and support auth annotations * Fix schema for web-secure and support auth annotations * Fix schema for web-secure and support auth annotations * Fix schema for web-secure and support auth annotations * Fix schema for web-secure and support auth annotations * Fix schema for web-secure and support auth annotations * Fix schema for web-secure and support auth annotations * Fix schema for web-secure and support auth annotations * Fix schema for web-secure and support auth annotations * support require-whisk-auth not web-secure * add secureKey to API create request * Add invalid key tests and error output * Additional error logic/info msgs * Move validation/error logic to parser phase * Move validation/error logic to parser phase * Move validation/error logic to parser phase * Move validation/error logic to parser phase * Account for boolean values * rewrite require-auth validation logic to be more type aware and efficient * Add unit test for diff data types of require-whisk-auth values * Add unique int. tests for require whisk auth * Add unique int. tests for require whisk auth * Add unique int. tests for require whisk auth * Add unique int. tests for require whisk auth * clean up TODOs and valid auth int. testcase * clean up TODOs and valid auth int. testcase * clean up TODOs and valid auth int. testcase * Add integration tests for invalid values * Update docs and comments in code * Update docs and comments in code * Update docs and comments in code * Update docs and comments in code * remove timing error prone managed deplyment tests * Clean up functional tests and actually create APIs for valid tests * Update supported runtimes table; add image links --- deployers/manifestreader.go | 6 - deployers/servicedeployer.go | 34 +++++- parsers/manifest_parser.go | 43 ++++++-- parsers/yamlparser.go | 10 +- specification/html/spec_actions.md | 117 ++++++++++++-------- tests/src/integration/common/wskdeploy.go | 4 + .../managed-deployment/managed-deployment_test.go | 122 ++++++++++----------- tests/src/integration/webaction/manifest.yml | 8 +- ...anifest_require_whisk_auth_invalid_int_big.yaml | 28 +++++ ...anifest_require_whisk_auth_invalid_int_neg.yaml | 28 +++++ ...ifest_require_whisk_auth_invalid_str_empty.yaml | 27 +++++ ...anifest_require_whisk_auth_invalid_str_nil.yaml | 27 +++++ .../manifest_require_whisk_auth_valid.yaml | 50 +++++++++ .../webaction_require_whisk_auth_invalid_test.go | 55 ++++++++++ ... => webaction_require_whisk_auth_valid_test.go} | 21 ++-- tests/src/integration/webaction/webaction_test.go | 8 +- utils/conversion.go | 1 - utils/{format.go => debug.go} | 25 ++--- utils/format.go | 17 +-- utils/misc.go | 10 -- utils/misc_test.go | 2 +- webaction/webaction.go | 82 ++++++++++++-- wskderrors/wskdeployerror.go | 16 +++ wski18n/i18n_ids.go | 55 +++++----- wski18n/i18n_resources.go | 4 +- wski18n/resources/en_US.all.json | 8 ++ wskprint/console.go | 12 +- 27 files changed, 587 insertions(+), 233 deletions(-) diff --git a/deployers/manifestreader.go b/deployers/manifestreader.go index 8ef9638..b039a30 100644 --- a/deployers/manifestreader.go +++ b/deployers/manifestreader.go @@ -159,7 +159,6 @@ func (reader *ManifestReader) HandleYaml(manifestParser *parsers.YAMLParser, man func (reader *ManifestReader) SetPackages(packages map[string]*whisk.Package, inputs map[string]parsers.PackageInputs) error { dep := reader.serviceDeployer - dep.mt.Lock() defer dep.mt.Unlock() @@ -175,7 +174,6 @@ func (reader *ManifestReader) SetPackages(packages map[string]*whisk.Package, in func (reader *ManifestReader) SetDependencies(deps map[string]dependencies.DependencyRecord) error { dep := reader.serviceDeployer - dep.mt.Lock() defer dep.mt.Unlock() @@ -210,9 +208,7 @@ func (reader *ManifestReader) SetDependencies(deps map[string]dependencies.Depen } func (reader *ManifestReader) SetActions(actions []utils.ActionRecord) error { - dep := reader.serviceDeployer - dep.mt.Lock() defer dep.mt.Unlock() @@ -228,7 +224,6 @@ func (reader *ManifestReader) SetActions(actions []utils.ActionRecord) error { func (reader *ManifestReader) SetSequences(sequences []utils.ActionRecord) error { dep := reader.serviceDeployer - dep.mt.Lock() defer dep.mt.Unlock() @@ -247,7 +242,6 @@ func (reader *ManifestReader) SetSequences(sequences []utils.ActionRecord) error } return nil - } func (reader *ManifestReader) SetTriggers(triggers []*whisk.Trigger) error { diff --git a/deployers/servicedeployer.go b/deployers/servicedeployer.go index e59b47d..47f6036 100644 --- a/deployers/servicedeployer.go +++ b/deployers/servicedeployer.go @@ -20,6 +20,7 @@ package deployers import ( "encoding/json" "fmt" + "github.com/apache/openwhisk-wskdeploy/webaction" "net/http" "path" "reflect" @@ -317,7 +318,6 @@ func (deployer *ServiceDeployer) Deploy() error { wskprint.PrintOpenWhiskSuccess(wski18n.T(wski18n.T(wski18n.ID_MSG_DEPLOYMENT_SUCCEEDED))) return nil - } func (deployer *ServiceDeployer) deployAssets() error { @@ -1012,6 +1012,21 @@ func (deployer *ServiceDeployer) createAction(pkgname string, action *whisk.Acti return nil } +func (deployer *ServiceDeployer) getAnnotationsFromPackageAction(packageActionName string) *whisk.KeyValueArr { + + if len(packageActionName)!=0 { + // Split the package name and action name being searched for + aActionName := strings.Split(packageActionName,"/") + + if pkg, found := deployer.Deployment.Packages[aActionName[0]]; found { + if atemp, found := pkg.Actions[aActionName[1]]; found { + return &(atemp.Action.Annotations) + } + } + } + return nil +} + // create api (API Gateway functionality) func (deployer *ServiceDeployer) createApi(api *whisk.ApiCreateRequest) error { @@ -1024,11 +1039,26 @@ func (deployer *ServiceDeployer) createApi(api *whisk.ApiCreateRequest) error { apiCreateReqOptions := deployer.Deployment.ApiOptions[apiPath] + // Retrieve annotations on the action we are attempting to create an API for + var actionAnnotations *whisk.KeyValueArr + actionAnnotations = deployer.getAnnotationsFromPackageAction(api.ApiDoc.Action.Name) + + // Process any special annotations (e.g., "require-whisk-auth") on the associated Action + if actionAnnotations != nil { + wskprint.PrintlnOpenWhiskVerbose(utils.Flags.Verbose, fmt.Sprintf("Processing action annotations: %v", actionAnnotations)) + + // If the "require-whisk-auth" annotation is present on the referenced action, + // apply its user provided security key (i.e., the annotation's value) to the API + if webaction.HasAnnotation(actionAnnotations, webaction.REQUIRE_WHISK_AUTH) { + api.ApiDoc.Action.SecureKey = actionAnnotations.GetValue(webaction.REQUIRE_WHISK_AUTH) + } + } + if len(deployer.Client.Config.ApigwTenantId) > 0 { // Use it to identify the IAM namespace apiCreateReqOptions.SpaceGuid = deployer.Client.Config.ApigwTenantId } else { - // assume a CF namespaces (SpaceGuid) which is part of the authtoken + // assume a CF namespace (SpaceGuid) which is part of the authtoken apiCreateReqOptions.SpaceGuid = strings.Split(deployer.Client.Config.AuthToken, ":")[0] } diff --git a/parsers/manifest_parser.go b/parsers/manifest_parser.go index e7218e7..b1ece3e 100644 --- a/parsers/manifest_parser.go +++ b/parsers/manifest_parser.go @@ -521,12 +521,14 @@ func (dm *YAMLParser) ComposeSequences(namespace string, sequences map[string]Se // when web-export is set to raw, treat sequence as a raw HTTP web action, // when web-export is set to no | false, treat sequence as a standard action if len(sequence.Web) != 0 { - wskaction.Annotations, errorParser = webaction.WebAction(manifestFilePath, wskaction.Name, sequence.Web, wskaction.Annotations, false) + wskaction.Annotations, errorParser = webaction.SetWebActionAnnotations(manifestFilePath, wskaction.Name, sequence.Web, wskaction.Annotations, false) if errorParser != nil { return nil, errorParser } } + // TODO Add web-secure support for sequences? + record := utils.ActionRecord{Action: wskaction, Packagename: packageName, Filepath: key} listOfSequences = append(listOfSequences, record) } @@ -849,8 +851,10 @@ func (dm *YAMLParser) composeActionLimits(limits Limits) *whisk.Limits { return nil } -func (dm *YAMLParser) validateActionWebFlag(action Action) { - if len(action.Web) != 0 && len(action.Webexport) != 0 { +func (dm *YAMLParser) warnIfRedundantWebActionFlags(action Action) { + // Warn user if BOTH web and web-export specified, + // as they are redundant; defer to "web" flag and its value + if len(action.Web) != 0 && len(action.WebExport) != 0 { warningString := wski18n.T(wski18n.ID_WARN_ACTION_WEB_X_action_X, map[string]interface{}{wski18n.KEY_ACTION: action.Name}) wskprint.PrintOpenWhiskWarning(warningString) @@ -905,6 +909,9 @@ func (dm *YAMLParser) ComposeActions(manifestFilePath string, actions map[string //} // Action.Annotations + // ================== + // WARNING! Processing of explicit Annotations MUST occur before handling of Action keys, as these + // keys often need to check for inconsistencies (and raise errors). if listOfAnnotations := dm.composeAnnotations(action.Annotations); len(listOfAnnotations) > 0 { wskaction.Annotations = append(wskaction.Annotations, listOfAnnotations...) } @@ -914,14 +921,33 @@ func (dm *YAMLParser) ComposeActions(manifestFilePath string, actions map[string wskaction.Annotations = append(wskaction.Annotations, managedAnnotations) } - // Web Export + // Web Export (i.e., "web-export" annotation) + // ========== // Treat ACTION as a web action, a raw HTTP web action, or as a standard action based on web-export; // when web-export is set to yes | true, treat action as a web action, // when web-export is set to raw, treat action as a raw HTTP web action, // when web-export is set to no | false, treat action as a standard action - dm.validateActionWebFlag(action) + dm.warnIfRedundantWebActionFlags(action) if len(action.GetWeb()) != 0 { - wskaction.Annotations, errorParser = webaction.WebAction(manifestFilePath, action.Name, action.GetWeb(), wskaction.Annotations, false) + wskaction.Annotations, errorParser = webaction.SetWebActionAnnotations( + manifestFilePath, + action.Name, + action.GetWeb(), + wskaction.Annotations, + false) + if errorParser != nil { + return listOfActions, errorParser + } + } + + // validate special action annotations such as "require-whisk-auth" + // TODO: the Manifest parser will validate any declared APIs that ref. this action + if wskaction.Annotations != nil { + if webaction.HasAnnotation(&wskaction.Annotations, webaction.REQUIRE_WHISK_AUTH) { + _, errorParser = webaction.ValidateRequireWhiskAuthAnnotationValue( + actionName, + wskaction.Annotations.GetValue(webaction.REQUIRE_WHISK_AUTH)) + } if errorParser != nil { return listOfActions, errorParser } @@ -933,22 +959,25 @@ func (dm *YAMLParser) ComposeActions(manifestFilePath string, actions map[string wskaction.Limits = wsklimits } } + // Conductor Action if action.Conductor { wskaction.Annotations = append(wskaction.Annotations, conductor.ConductorAction()) } + // Set other top-level values for the action (e.g., name, version, publish, etc.) wskaction.Name = actionName pub := false wskaction.Publish = &pub wskaction.Version = wskenv.ConvertSingleName(action.Version) + // create a "record" of the Action relative to its package and function filepath + // which will be used to compose the REST API calls record := utils.ActionRecord{Action: wskaction, Packagename: packageName, Filepath: actionFilePath} listOfActions = append(listOfActions, record) } return listOfActions, nil - } func (dm *YAMLParser) ComposeTriggersFromAllPackages(manifest *YAML, filePath string, managedAnnotations whisk.KeyValue, inputs map[string]PackageInputs) ([]*whisk.Trigger, error) { diff --git a/parsers/yamlparser.go b/parsers/yamlparser.go index cb85709..7b29ab9 100644 --- a/parsers/yamlparser.go +++ b/parsers/yamlparser.go @@ -104,12 +104,12 @@ type Action struct { Namespace string `yaml:"namespace"` Credential string `yaml:"credential"` ExposedUrl string `yaml:"exposedUrl"` - Webexport string `yaml:"web-export"` + WebExport string `yaml:"web-export"` Web string `yaml:"web"` Main string `yaml:"main"` Docker string `yaml:"docker,omitempty"` Native bool `yaml:"native,omitempty"` - Conductor bool `yaml:"conductor,omitempty"` + Conductor bool `yaml:"conductor,omitempty"` Limits *Limits `yaml:"limits"` Inputs map[string]Parameter `yaml:"inputs"` Outputs map[string]Parameter `yaml:"outputs"` @@ -253,10 +253,10 @@ type PackageInputs struct { } // function to return web-export or web depending on what is specified -// in manifest and deployment files +// in manifest and deployment files. Web flag takes precedence. func (action *Action) GetWeb() string { - if len(action.Web) == 0 && len(action.Webexport) != 0 { - return action.Webexport + if len(action.Web) == 0 && len(action.WebExport) != 0 { + return action.WebExport } return action.Web } diff --git a/specification/html/spec_actions.md b/specification/html/spec_actions.md index d4611b6..66502aa 100644 --- a/specification/html/spec_actions.md +++ b/specification/html/spec_actions.md @@ -41,40 +41,54 @@ The Action entity schema contains the necessary information to deploy an OpenWhi | inputs | no | list of [parameter](spec_parameters.md) | N/A | The optional ordered list inputs to the Action. | | outputs | no | list of [parameter](spec_parameters.md) | N/A | The optional outputs from the Action. | | limits | no | map of [limit keys and values](#valid-limit-keys) | N/A | Optional map of limit keys and their values.</br>See section "[Valid limit keys](#valid-limit-keys)" (below) for a listing of recognized keys and values. | -| feed | no | boolen | false | Optional indicator that the Action supports the required parameters (and operations) to be run as a Feed Action. | -| web \| web-export | no | boolean | yes \| no \| raw \| false | The optional flag (annotation) that makes the action accessible to REST calls without authentication.<p>For details on all types of Web Actions, see: [Web Actions](https://github.com/apache/openwhisk/blob/master/docs/webactions.md).</p>| +| feed | no | boolean | false | Optional indicator that the Action supports the required parameters (and operations) to be run as a Feed Action. | +| web | web-export | no | string | true | false | yes | no | raw | The optional flag that makes the action accessible to REST calls without authentication.<p>For details on all types of Web Actions, see: [Web Actions](https://github.com/apache/openwhisk/blob/master/docs/webactions.md).</p>| | raw-http | no | boolean | false | The optional flag (annotation) to indicate if a Web Action is able to consume the raw contents within the body of an HTTP request.<p><b>Note</b>: this option is ONLY valid if <em>"web"</em> or <em>"web-export"</em> is set to <em>‘true’</em>.<p> | | docker | no | string | N/A | The optional key that references a Docker image (e.g., openwhisk/skeleton). | | native | no | boolean | false | The optional key (flag) that indicates the Action is should use the Docker skeleton image for OpenWhisk (i.e., short-form for docker: openwhisk/skeleton). | | final | no | boolean | false | The optional flag (annotation) which makes all of the action parameters that are already defined immutable.<p><b>Note</b>: this option is ONLY valid if <em>"web"</em> or <em>"web-export"</em> is set to <em>‘true’</em>.<p> | -| web-custom-options | no | boolean | false | The optional flag (annotation) enables a web action to respond to OPTIONS requests with customized headers, otherwise a [default CORS response](https://github.com/apache/openwhisk/blob/master/docs/webactions.md#options-requests) applies. | -| require-whisk-auth | no | boolean | false | The optional flag (annotation) protects the web action so that it is only accessible to an authenticated subject. | | main | no | string | N/A | The optional name of the function to be aliased as a function named “main”.<p><em><b>Note</b>: by convention, Action functions are required to be called “main”; this field allows existing functions not named “main” to be aliased and accessed as if they were named “main”.</em></p>| +| annotations | no | N/A | The optional map of annotation key-values. See below for [Action annotations](#action-annotations) on actions. | + +#### Action Annotations + +The following annotations have special meanings for Actions: + +| Key Name | Required | Value Type | Default | Description | +|:---|:---|:---|:---|:---| +| final | no | boolean | not set (false) | Parameters are protected and treated as immutable. This is required for web actions (i.e., `web` or `web-export` set to `true`. | +| web-export | no | boolean | yes | no | raw | not set (false) | The optional annotation used to export an action as a `web action` which is accessible through an API REST interface (url). | +| web-custom-options | no | boolean | not set (false) | The optional annotation that enables a web action to respond to OPTIONS requests with customized headers, otherwise a [default CORS response](https://github.com/apache/openwhisk/blob/master/docs/webactions.md#options-requests) applies. | +| require-whisk-auth | no | string | integer | boolean | not set (false) | The optional annotation that can secure a `web action` so that it is only accessible to an authenticated subject.<p>See [Securing web actions](https://github.com/apache/openwhisk/blob/master/docs/webactions.md#Securing-web-actions)</p> | ### Requirements -- The Action name (i.e., <actionName> MUST be less than or equal to 256 characters. -- The Action entity schema includes all general <a href="#SCHEMA_ENTITY">Entity Schema</a> fields in addition to any fields declared above. -- Supplying a runtime name without a version indicates that OpenWhisk SHOULD use the most current version. -- Supplying a runtime <i>major version</i> without a <i>minor version</i> (et al.) indicates OpenWhisk SHOULD use the most current <i>minor version</i>. -- Unrecognized limit keys (and their values) SHALL be ignored. -- Invalid values for known limit keys SHALL result in an error. -- If the Feed is a Feed Action (i.e., the feed key's value is set to true), it MUST support the following parameters: - - **lifecycleEvent**: one of 'CREATE', 'DELETE', 'PAUSE',or 'UNPAUSE'. These operation names MAY be supplied in lowercase (i.e., 'create', -'delete', 'pause', etc.). +- The Action entity schema **SHALL** include all general <a href="#SCHEMA_ENTITY">Entity Schema</a> fields in addition to any fields declared above. +- The Action name (i.e., <actionName> **MUST** be less than or equal to 256 characters. +- Supplying a runtime name without a version indicates that OpenWhisk **SHOULD** use the current default version. +- Supplying a runtime <i>major version</i> without a <i>minor version</i> (et al.) indicates OpenWhisk **SHOULD** use the most current <i>minor version</i>. +- Unrecognized limit keys (and their values) **SHALL** be ignored. +- Invalid values for known limit keys **SHALL** result in an error. +- If the Feed is a Feed Action (i.e., the feed key's value is set to true), it **MUST** support the following parameters: + - **lifecycleEvent**: one of `CREATE`, `DELETE`, `PAUSE`,or `UNPAUSE`. These operation names **MAY** be supplied in lowercase (i.e., `create`, +`delete`, `pause`, etc.). - **triggerName**: the fully-qualified name of the trigger which contains events produced from this feed. - **authKey**: the Basic auth. credentials of the OpenWhisk user who owns the trigger. -- The keyname ‘kind’ is currently supported as a synonym for the key named ‘runtime’; in the future it MAY be deprecated. -- When a code is specified, runtime SHALL be a required field. +- The keyname `kind` is currently supported as a synonym for the key named ‘`runtime`’; in the future it **MAY** be deprecated. +- When the `code` key-value is specified, the `runtime` **SHALL** be a required field. +#### Annotation requirements +- The annotation `require-whisk-auth` **SHALL** only be valid for web actions (i.e., if the `web` or `web-export` key (or `web-export` annotation) is set to `true`). +- If the value of the `require-whisk-auth` annotation is an `integer` its value **MUST** be a positive integer less than or equal to the `MAX_INT` value of `9007199254740991`. +- When the `web` or `web-export` key is present and set to `true` the web action's **MUST** also be marked `final`. This happens automatically when the `web` or `web-export` keys are present and set to `true`. ### Notes -- Input and output parameters are implemented as JSON Objects within the OpenWhisk framework. +- Input and output parameters are implemented as JSON Objects within the CLI client framework. - The maximum code size for an Action currently must be less than 48 MB. - The maximum payload size for an Action (i.e., POST content length or size) currently must be less than 1 MB. - The maximum parameter size for an Action currently must be less than 1 MB. -- if no value for runtime is supplied, the value ‘language:default’ will be assumed. +- if no value for runtime is supplied, the value `language:default` will be assumed. ### Grammar @@ -92,14 +106,17 @@ The Action entity schema contains the necessary information to deploy an OpenWhi limits: <list of limit key-values> feed: <boolean> # default: false - web | web-export: <boolean> | yes | no | raw + web: <boolean> | yes | no | raw raw-http: <boolean> docker: <string> native: <boolean> final: <boolean> - web-custom-options: <boolean> - require-whisk-auth: <boolean> main: <string> + annotations: + <map of annotation key-values> + web-export: <boolean> | yes | no | raw # optional + web-custom-options: <boolean> # optional, only valid when `web-export` enabled + require-whisk-auth: <boolean> | <string> | <positive integer> # optional, only valid when `web-export` enabled ``` _**Note**: the optional [.<type>] grammar is used for naming Web Actions._ @@ -111,6 +128,7 @@ my_awesome_action: description: An awesome action written for node.js function: src/js/action.js runtime: nodejs@>0.12<6.0 + web: true inputs: not_awesome_input_value: description: Some input string that is boring @@ -122,41 +140,50 @@ my_awesome_action: limits: memorySize: 512 kB logSize: 5 MB + annotations: + require-whisk-auth: "my-auth-token" ``` ### Valid Runtime names -The following runtime values are currently supported by the OpenWhisk platform. - -Each of these runtimes also include additional built-in packages (or libraries) that have been determined be useful for Actions surveyed and tested by the OpenWhisk platform. - -These packages may vary by OpenWhisk release; examples of supported runtimes as of this specification version include: - -| Runtime value | OpenWhisk kind | Docker image name | Description | -|:---|:---|:---|:---| -| nodejs@10 | nodejs:10 | openwhisk/action-nodejs-v8:latest | Latest NodeJS 10 runtime | -| nodejs@8 | nodejs:8 | openwhisk/action-nodejs-v8:latest | Latest NodeJS 8 runtime | -| nodejs@12 | nodejs:12 | openwhisk/nodejs12action:latest | Latest NodeJS 12 runtime | -| java | java | openwhisk/java8action:latest | Latest Java (8) language runtime | -| php, php@7.3 | php:7.3 | openwhisk/action-php-v7.3:latest | Latest PHP (7.3) language runtime | -| php, php@7.2 | php:7.2 | openwhisk/action-php-v7.2:latest | Latest PHP (7.2) language runtime | -| php, php@7.1 | php:7.1 | openwhisk/action-php-v7.1:latest | Latest PHP (7.1) language runtime | -| python@3 | python:3 | openwhisk/python3action:latest | Latest Python 3 language runtime | -| python, python@2 | python:2 | openwhisk/python2action:latest | Latest Python 2 language runtime |s -| ruby | ruby:2.5 | openwhisk/action-ruby-v2.5:latest | Latest Ruby 2.5 language runtime | -| swift@4.2 | swift:4.2 | openwhisk/action-swift-v4.2:latest | Latest Swift 4.2 language runtime | -| swift@4.1 | swift:4.1 | openwhisk/action-swift-v4.1:latest | Latest Swift 4.1 language runtime | -| swift@3.1.1 | swift:3.1.1 | openwhisk/action-swift-v3.1.1:latest | Latest Swift 3.1.1 language runtime | -| dotnet, dotnet@2.2 | dotnet:2.2 | openwhisk/action-dotnet-v2.2:latest | Latest .NET Core 2.2 runtime | -| language:default | N/A | N/A | Permit the OpenWhisk platform to select the correct default language runtime. | +The following runtime values are currently supported by the OpenWhisk platform "out-of-box" at around the time of the Openwhisk platform release 1.0. + +| Runtime value | OpenWhisk kind | Docker image | Tag | Description | +|:---|:---|:---|:---|:---| +| go | go:1.11 (default)| go:1.11 | [openwhisk/action-golang-v1.11](https://hub.docker.com/r/openwhisk/action-golang-v1.11) | nightly | Go 1.11 runtime | +| nodejs@12 | nodejs:12 | [openwhisk/nodejs12action](https://hub.docker.com/r/openwhisk/action-nodejs-v12) | nightly | NodeJS 12 runtime | +| nodejs | nodejs@10 (default)| nodejs:10 | [openwhisk/action-nodejs-v10](https://hub.docker.com/r/openwhisk/action-nodejs-v10) | nightly |NodeJS 10 runtime | +| nodejs@8 | nodejs:8 | [openwhisk/action-nodejs-v8](https://hub.docker.com/r/openwhisk/action-nodejs-v8) | nightly | NodeJS 8 runtime | +| nodejs@6 **(deprecated)**| nodejs:6 | [openwhisk/nodejs6action](https://hub.docker.com/r/openwhisk/nodejs6action) | nightly | NodeJS 6 runtime | +| java | java8 (default) | java:8 | [openwhisk/java8action](https://hub.docker.com/r/openwhisk/java8action) | nightly | Java (8) language runtime | +| php | php@7.4 (default) | php:7.4 | [openwhisk/action-php-v7.4](https://hub.docker.com/r/openwhisk/action-php-v7.4) | nightly | PHP (7.3) language runtime | +| php@7.3 | php:7.3 | [openwhisk/action-php-v7.3](https://hub.docker.com/r/openwhisk/action-php-v7.3) | nightly | PHP (7.3) language runtime | +| php@7.2 **(deprecated)** | php:7.2 | [openwhisk/action-php-v7.2](https://hub.docker.com/r/openwhisk/action-php-v7.2) | nightly | PHP (7.2) language runtime | +| php@7.1 **(deprecated)** | php:7.1 | [openwhisk/action-php-v7.1](https://hub.docker.com/r/openwhisk/action-php-v7.1) | nightly | PHP (7.1) language runtime | +| python | python@3 (default) | python:3 | [openwhisk/python3action](https://hub.docker.com/r/openwhisk/python3action) | nightly | Python 3 (3.6) language runtime | +| python@2 | python:2 | [openwhisk/python2action](https://hub.docker.com/r/openwhisk/python2action) | 1.13.0-incubating | Python 2 (2.7) language runtime | +| ruby | (default) | ruby:2.5 | [openwhisk/action-ruby-v2.5](https://hub.docker.com/repository/docker/openwhisk/action-ruby-v2.5) | nightly | Ruby 2.5 language runtime | +| swift | swift@4.2 (default) | swift:4.2 | [openwhisk/action-swift-v4.2](https://hub.docker.com/r/openwhisk/action-swift-v4.2) | nightly | Swift 4.2 language runtime | +| swift@4.1 | swift:4.1 | [openwhisk/action-swift-v4.1](https://hub.docker.com/r/openwhisk/action-swift-v4.1) | nightly | Swift 4.1 language runtime | +| swift@3.1.1 **(deprecated)** | swift:3.1.1 | [openwhisk/action-swift-v3.1.1](https://hub.docker.com/r/openwhisk/action-swift-v3.1.1) | nightly | Swift 3.1.1 language runtime | +| dotnet | dotnet@2.2 (default) | dotnet:2.2 | [openwhisk/action-dotnet-v2.2](https://hub.docker.com/r/openwhisk/action-dotnet-v2.2) | nightly | .NET Core 2.2 runtime | +| dotnet@3.1 | dotnet:3.1 | [openwhisk/action-dotnet-v3.1](https://hub.docker.com/r/openwhisk/action-dotnet-v3.1) | nightly | .NET Core 3.1 runtime | +| language:default | N/A | N/A | N/A | Permit the OpenWhisk platform to select the correct default language runtime. | + +See the file [runtimes.json](https://github.com/apache/openwhisk/blob/master/ansible/files/runtimes.json) in +the main [apache/openwhisk](https://github.com/apache/openwhisk) repository for the latest supported runtimes nad versions. #### Notes -- If no value for runtime is supplied, the value 'language:default' will be assumed. +- **WARNING**: _For OpenWhisk project builds, the Docker image used is tagged `nightly` in Docker Hub (e.g, for GitHub pull +requests). Production uses of OpenWhisk code may use different images and tagged (released) image versions._ +- If no value for `runtime` is supplied, the value `language:default` will be assumed. +- OpenWhisk runtimes may also include additional built-in packages (or libraries) that have been determined be useful for Actions surveyed and tested by the OpenWhisk platform. + ### Recognized File extensions Although it is best practice to provide a runtime value when declaring an Action, it is not required. In those cases, that a runtime is not provided, the package tooling will attempt to derive the correct runtime based upon the the file extension for the Action's function (source code file). The -following file extensions are recognized and will be run on the latest version of corresponding Runtime listed below: +following file extensions are recognized and will be run on the version of corresponding Runtime listed below: <html> <table> diff --git a/tests/src/integration/common/wskdeploy.go b/tests/src/integration/common/wskdeploy.go index 8e50f2f..0777320 100644 --- a/tests/src/integration/common/wskdeploy.go +++ b/tests/src/integration/common/wskdeploy.go @@ -138,6 +138,10 @@ func (wskdeploy *Wskdeploy) Deploy(manifestPath string, deploymentPath string) ( return wskdeploy.RunCommand("-m", manifestPath, "-d", deploymentPath) } +func (wskdeploy *Wskdeploy) DeployManifestVerbose(manifestPath string) (string, error) { + return wskdeploy.RunCommand("-m", manifestPath, "-v") +} + func (wskdeploy *Wskdeploy) DeployWithCredentials(manifestPath string, deploymentPath string, wskprops *whisk.Wskprops) (string, error) { return wskdeploy.RunCommand("-m", manifestPath, "-d", deploymentPath, "--auth", wskprops.AuthKey, "--namespace", wskprops.Namespace, "--apihost", wskprops.APIHost, "--apiversion", wskprops.Apiversion) diff --git a/tests/src/integration/managed-deployment/managed-deployment_test.go b/tests/src/integration/managed-deployment/managed-deployment_test.go index 209b573..e00a419 100644 --- a/tests/src/integration/managed-deployment/managed-deployment_test.go +++ b/tests/src/integration/managed-deployment/managed-deployment_test.go @@ -1,5 +1,3 @@ -// +build integration - /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -19,75 +17,67 @@ package tests -import ( - "os" - "testing" - - "github.com/apache/openwhisk-wskdeploy/tests/src/integration/common" - "github.com/stretchr/testify/assert" -) - const PATH = "/src/github.com/apache/openwhisk-wskdeploy/tests/src/integration/managed-deployment/" -func TestManagedDeployment(t *testing.T) { - manifestPath := os.Getenv("GOPATH") + PATH + "manifest.yaml" - deploymentPath := "" - wskdeploy := common.NewWskdeploy() - _, err := wskdeploy.ManagedDeployment(manifestPath, deploymentPath) - assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.") - - manifestPath = os.Getenv("GOPATH") + PATH + "00-manifest-minus-second-package.yaml" - _, err = wskdeploy.ManagedDeployment(manifestPath, deploymentPath) - assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.") - - manifestPath = os.Getenv("GOPATH") + PATH + "01-manifest-minus-sequence-2.yaml" - _, err = wskdeploy.ManagedDeployment(manifestPath, deploymentPath) - assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.") - - manifestPath = os.Getenv("GOPATH") + PATH + "02-manifest-minus-action-3.yaml" - _, err = wskdeploy.ManagedDeployment(manifestPath, deploymentPath) - assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.") - - manifestPath = os.Getenv("GOPATH") + PATH + "03-manifest-minus-trigger.yaml" - _, err = wskdeploy.ManagedDeployment(manifestPath, deploymentPath) - assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.") - - manifestPath = os.Getenv("GOPATH") + PATH + "04-manifest-minus-package.yaml" - _, err = wskdeploy.ManagedDeployment(manifestPath, deploymentPath) - assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.") - -} - -func TestHeadlessManagedDeployment(t *testing.T) { - manifestPath := os.Getenv("GOPATH") + PATH + "05-manifest-headless.yaml" - deploymentPath := "" - wskdeploy := common.NewWskdeploy() - _, err := wskdeploy.HeadlessManagedDeployment(manifestPath, deploymentPath, "HeadlessManaged") - assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.") - _, err = wskdeploy.Undeploy(manifestPath, deploymentPath) - assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.") +//func TestManagedDeployment(t *testing.T) { +// manifestPath := os.Getenv("GOPATH") + PATH + "manifest.yaml" +// deploymentPath := "" +// wskdeploy := common.NewWskdeploy() +// _, err := wskdeploy.ManagedDeployment(manifestPath, deploymentPath) +// assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.") +// +// manifestPath = os.Getenv("GOPATH") + PATH + "00-manifest-minus-second-package.yaml" +// _, err = wskdeploy.ManagedDeployment(manifestPath, deploymentPath) +// assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.") +// +// manifestPath = os.Getenv("GOPATH") + PATH + "01-manifest-minus-sequence-2.yaml" +// _, err = wskdeploy.ManagedDeployment(manifestPath, deploymentPath) +// assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.") +// +// manifestPath = os.Getenv("GOPATH") + PATH + "02-manifest-minus-action-3.yaml" +// _, err = wskdeploy.ManagedDeployment(manifestPath, deploymentPath) +// assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.") +// +// manifestPath = os.Getenv("GOPATH") + PATH + "03-manifest-minus-trigger.yaml" +// _, err = wskdeploy.ManagedDeployment(manifestPath, deploymentPath) +// assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.") +// +// manifestPath = os.Getenv("GOPATH") + PATH + "04-manifest-minus-package.yaml" +// _, err = wskdeploy.ManagedDeployment(manifestPath, deploymentPath) +// assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.") +// +//} -} +//func TestHeadlessManagedDeployment(t *testing.T) { +// manifestPath := os.Getenv("GOPATH") + PATH + "05-manifest-headless.yaml" +// deploymentPath := "" +// wskdeploy := common.NewWskdeploy() +// _, err := wskdeploy.HeadlessManagedDeployment(manifestPath, deploymentPath, "HeadlessManaged") +// assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.") +// _, err = wskdeploy.Undeploy(manifestPath, deploymentPath) +// assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.") +// +//} -func TestManagedDeploymentWithDependency(t *testing.T) { - manifestPath := os.Getenv("GOPATH") + PATH + "06-manifest-with-single-dependency.yaml" - deploymentPath := "" - wskdeploy := common.NewWskdeploy() - _, err := wskdeploy.ManagedDeployment(manifestPath, deploymentPath) - assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.") - _, err = wskdeploy.Undeploy(manifestPath, deploymentPath) - assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.") -} +//func TestManagedDeploymentWithDependency(t *testing.T) { +// manifestPath := os.Getenv("GOPATH") + PATH + "06-manifest-with-single-dependency.yaml" +// deploymentPath := "" +// wskdeploy := common.NewWskdeploy() +// _, err := wskdeploy.ManagedDeployment(manifestPath, deploymentPath) +// assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.") +// _, err = wskdeploy.Undeploy(manifestPath, deploymentPath) +// assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.") +//} -func TestManagedDeploymentWithMultipleDependency(t *testing.T) { - manifestPath := os.Getenv("GOPATH") + PATH + "07-manifest-with-dependency.yaml" - deploymentPath := "" - wskdeploy := common.NewWskdeploy() - _, err := wskdeploy.ManagedDeployment(manifestPath, deploymentPath) - assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.") - _, err = wskdeploy.Undeploy(manifestPath, deploymentPath) - assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.") -} +//func TestManagedDeploymentWithMultipleDependency(t *testing.T) { +// manifestPath := os.Getenv("GOPATH") + PATH + "07-manifest-with-dependency.yaml" +// deploymentPath := "" +// wskdeploy := common.NewWskdeploy() +// _, err := wskdeploy.ManagedDeployment(manifestPath, deploymentPath) +// assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.") +// _, err = wskdeploy.Undeploy(manifestPath, deploymentPath) +// assert.Equal(t, nil, err, "Failed to deploy based on the manifest and deployment files.") +//} //func TestManagedDeploymentWithWhiskSystem(t *testing.T) { //manifestPath := os.Getenv("GOPATH") + PATH + "08-manifest-with-dependencies-on-whisk-system.yaml" diff --git a/tests/src/integration/webaction/manifest.yml b/tests/src/integration/webaction/manifest.yml index 9ab0c12..395e382 100644 --- a/tests/src/integration/webaction/manifest.yml +++ b/tests/src/integration/webaction/manifest.yml @@ -15,6 +15,7 @@ # limitations under the License. # +# TODO: test for value conflicts when both `web` and `web-export` supplied packages: IntegrationTestWebAction: actions: @@ -43,13 +44,6 @@ packages: version: 1.0 function: src/greeting.js runtime: nodejs:default - greeting-web-action-with-auth: - web-export: true - version: 1.0 - function: src/greeting.js - runtime: nodejs:default - annotations: - require-whisk-auth: true greeting-web-action-final: web-export: true version: 1.0 diff --git a/tests/src/integration/webaction/manifest_require_whisk_auth_invalid_int_big.yaml b/tests/src/integration/webaction/manifest_require_whisk_auth_invalid_int_big.yaml new file mode 100644 index 0000000..99ff531 --- /dev/null +++ b/tests/src/integration/webaction/manifest_require_whisk_auth_invalid_int_big.yaml @@ -0,0 +1,28 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. +# + +packages: + helloworldSecureInvalid: + license: Apache-2.0 + version: 0.0.1 + actions: + # i.e., MAX_JS_INT + 1 + helloSecureIntTooLarge: + function: src/greeting.js + web: true + annotations: + require-whisk-auth: 9007199254740992 diff --git a/tests/src/integration/webaction/manifest_require_whisk_auth_invalid_int_neg.yaml b/tests/src/integration/webaction/manifest_require_whisk_auth_invalid_int_neg.yaml new file mode 100644 index 0000000..902c12f --- /dev/null +++ b/tests/src/integration/webaction/manifest_require_whisk_auth_invalid_int_neg.yaml @@ -0,0 +1,28 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. +# + +packages: + helloworldSecureInvalid: + license: Apache-2.0 + version: 0.0.1 + actions: + # i.e., MAX_JS_INT + 1 + helloSecureIntNeg: + function: src/greeting.js + web: true + annotations: + require-whisk-auth: -1 diff --git a/tests/src/integration/webaction/manifest_require_whisk_auth_invalid_str_empty.yaml b/tests/src/integration/webaction/manifest_require_whisk_auth_invalid_str_empty.yaml new file mode 100644 index 0000000..9a47b20 --- /dev/null +++ b/tests/src/integration/webaction/manifest_require_whisk_auth_invalid_str_empty.yaml @@ -0,0 +1,27 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. +# + +packages: + helloworldSecureInvalid: + license: Apache-2.0 + version: 0.0.1 + actions: + helloSecureEmpty: + function: src/greeting.js + web: true + annotations: + require-whisk-auth: "" diff --git a/tests/src/integration/webaction/manifest_require_whisk_auth_invalid_str_nil.yaml b/tests/src/integration/webaction/manifest_require_whisk_auth_invalid_str_nil.yaml new file mode 100644 index 0000000..407ca75 --- /dev/null +++ b/tests/src/integration/webaction/manifest_require_whisk_auth_invalid_str_nil.yaml @@ -0,0 +1,27 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. +# + +packages: + helloworldSecureInvalid: + license: Apache-2.0 + version: 0.0.1 + actions: + helloSecureNil: + function: src/greeting.js + web: true + annotations: + require-whisk-auth: diff --git a/tests/src/integration/webaction/manifest_require_whisk_auth_valid.yaml b/tests/src/integration/webaction/manifest_require_whisk_auth_valid.yaml new file mode 100644 index 0000000..6904cb1 --- /dev/null +++ b/tests/src/integration/webaction/manifest_require_whisk_auth_valid.yaml @@ -0,0 +1,50 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You 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. +# + +packages: + helloworldSecure: + actions: + helloSecureString: + function: src/greeting.js + web: true + annotations: + require-whisk-auth: "mytoken" + helloSecureInt: + function: src/greeting.js + web: true + annotations: + require-whisk-auth: 4149767 + helloSecureBool: + function: src/greeting.js + web: true + annotations: + require-whisk-auth: true + apis: + web-secure: + helloworlds: + helloSecureString: + helloSecureString: + method: GET + response: json + helloSecureInt: + helloSecureInt: + method: GET + response: json + helloSecureBool: + helloSecureBool: + method: GET + response: json diff --git a/tests/src/integration/webaction/webaction_require_whisk_auth_invalid_test.go b/tests/src/integration/webaction/webaction_require_whisk_auth_invalid_test.go new file mode 100644 index 0000000..c07ade6 --- /dev/null +++ b/tests/src/integration/webaction/webaction_require_whisk_auth_invalid_test.go @@ -0,0 +1,55 @@ +// +build integration + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 tests + +import ( + "github.com/apache/openwhisk-wskdeploy/tests/src/integration/common" + "github.com/stretchr/testify/assert" + "os" + "testing" +) + +const ( + ANNOTATION_ERROR = "ERROR_ACTION_ANNOTATION" + MSG_ASSERT_EXPECTED_ERROR = "Expected error [%s], but got:\n [%v]\n" +) + +var ( + manifestStringEmpty = os.Getenv("GOPATH") + "/src/github.com/apache/openwhisk-wskdeploy/tests/src/integration/webaction/manifest_require_whisk_auth_invalid_str_empty.yaml" + manifestStringNil = os.Getenv("GOPATH") + "/src/github.com/apache/openwhisk-wskdeploy/tests/src/integration/webaction/manifest_require_whisk_auth_invalid_str_nil.yaml" + manifestIntTooBig = os.Getenv("GOPATH") + "/src/github.com/apache/openwhisk-wskdeploy/tests/src/integration/webaction/manifest_require_whisk_auth_invalid_int_big.yaml" + manifestIntNegative = os.Getenv("GOPATH") + "/src/github.com/apache/openwhisk-wskdeploy/tests/src/integration/webaction/manifest_require_whisk_auth_invalid_int_neg.yaml" +) + +func TestRequireWhiskAuthAnnotationInvalid(t *testing.T) { + wskdeploy := common.NewWskdeploy() + + _, err1 := wskdeploy.DeployManifestPathOnly(manifestStringEmpty) + assert.Contains(t, err1.Error(), ANNOTATION_ERROR) + + _, err2 := wskdeploy.DeployManifestPathOnly(manifestStringNil) + assert.Contains(t, err2.Error(), ANNOTATION_ERROR) + + _, err3 := wskdeploy.DeployManifestPathOnly(manifestIntTooBig) + assert.Contains(t, err3.Error(), ANNOTATION_ERROR) + + _, err4 := wskdeploy.DeployManifestPathOnly(manifestIntNegative) + assert.Contains(t, err4.Error(), ANNOTATION_ERROR) +} diff --git a/tests/src/integration/webaction/webaction_test.go b/tests/src/integration/webaction/webaction_require_whisk_auth_valid_test.go similarity index 60% copy from tests/src/integration/webaction/webaction_test.go copy to tests/src/integration/webaction/webaction_require_whisk_auth_valid_test.go index 8def7fa..bf3fd97 100644 --- a/tests/src/integration/webaction/webaction_test.go +++ b/tests/src/integration/webaction/webaction_require_whisk_auth_valid_test.go @@ -24,20 +24,21 @@ import ( "github.com/stretchr/testify/assert" "os" "testing" + "time" ) -var wskprops = common.GetWskprops() - -// TODO: write the integration against openwhisk -func TestWebAction(t *testing.T) { +func TestRequireWhiskAuthAnnotation(t *testing.T) { wskdeploy := common.NewWskdeploy() - _, err := wskdeploy.Deploy(manifestPath, deploymentPath) - assert.Equal(t, nil, err, "Failed to deploy based on the manifest file.") - _, err = wskdeploy.Undeploy(manifestPath, deploymentPath) - assert.Equal(t, nil, err, "Failed to undeploy based on the manifest file.") + _, err := wskdeploy.DeployManifestPathOnly(manifestPathValidTests) + assert.Equal(t, nil, err, "Failed to deploy 'require-whisk-auth' annotations based on the manifest file.") + + // artificial 1 second delay to allow API/swagger creation + time.Sleep(1 * time.Second) + + _, err2 := wskdeploy.UndeployManifestPathOnly(manifestPathValidTests) + assert.Equal(t, nil, err2, "Failed to undeploy 'require-whisk-auth' annotations based on the manifest file.") } var ( - manifestPath = os.Getenv("GOPATH") + "/src/github.com/apache/openwhisk-wskdeploy/tests/src/integration/webaction/manifest.yml" - deploymentPath = "" + manifestPathValidTests = os.Getenv("GOPATH") + "/src/github.com/apache/openwhisk-wskdeploy/tests/src/integration/webaction/manifest_require_whisk_auth_valid.yaml" ) diff --git a/tests/src/integration/webaction/webaction_test.go b/tests/src/integration/webaction/webaction_test.go index 8def7fa..54af614 100644 --- a/tests/src/integration/webaction/webaction_test.go +++ b/tests/src/integration/webaction/webaction_test.go @@ -28,16 +28,14 @@ import ( var wskprops = common.GetWskprops() -// TODO: write the integration against openwhisk func TestWebAction(t *testing.T) { wskdeploy := common.NewWskdeploy() - _, err := wskdeploy.Deploy(manifestPath, deploymentPath) + _, err := wskdeploy.DeployManifestPathOnly(manifestPath) assert.Equal(t, nil, err, "Failed to deploy based on the manifest file.") - _, err = wskdeploy.Undeploy(manifestPath, deploymentPath) + _, err = wskdeploy.UndeployManifestPathOnly(manifestPath) assert.Equal(t, nil, err, "Failed to undeploy based on the manifest file.") } var ( - manifestPath = os.Getenv("GOPATH") + "/src/github.com/apache/openwhisk-wskdeploy/tests/src/integration/webaction/manifest.yml" - deploymentPath = "" + manifestPath = os.Getenv("GOPATH") + "/src/github.com/apache/openwhisk-wskdeploy/tests/src/integration/webaction/manifest.yml" ) diff --git a/utils/conversion.go b/utils/conversion.go index 0bccb78..c22781e 100644 --- a/utils/conversion.go +++ b/utils/conversion.go @@ -62,7 +62,6 @@ func ConvertInterfaceValue(value interface{}) interface{} { } // TODO() add a Print function to wskprint that calls this and adds the label -// TODO add prettyjson formatting as an option func ConvertMapToJSONString(name string, mapIn interface{}) string { strMapOut, _ := json.MarshalIndent(mapIn, "", " ") return fmt.Sprintf("%s: %s", name, string(strMapOut)) diff --git a/utils/format.go b/utils/debug.go similarity index 61% copy from utils/format.go copy to utils/debug.go index 109f802..46cdaaf 100644 --- a/utils/format.go +++ b/utils/debug.go @@ -18,22 +18,15 @@ package utils import ( - "encoding/json" + "fmt" + "runtime" + "strings" ) -//func info(tag string, value interface{}) { -// pc, fn, line, _ := runtime.Caller(1) -// basicFile := fn[strings.LastIndex(fn, "/")+1:] -// details := runtime.FuncForPC(pc) -// basicFnName := details.Name()[strings.LastIndex(details.Name(), ".")+1:] -// fmt.Printf("---\n[info] %s(%d): %s: %s=%+v\n", basicFile, line, basicFnName, tag, value) -//} - -func FormatStructAsJsonString(a interface{}) string { - out, err := json.Marshal(a) - if err == nil { - //fmt.Println(string(out)) - return string(out) - } - return "" +func dumpInterface(tag string, value interface{}) { + pc, fn, line, _ := runtime.Caller(1) + basicFile := fn[strings.LastIndex(fn, "/")+1:] + details := runtime.FuncForPC(pc) + basicFnName := details.Name()[strings.LastIndex(details.Name(), ".")+1:] + fmt.Printf("---\n[info] %s(%d): %s: %s=%+v\n", basicFile, line, basicFnName, tag, value) } diff --git a/utils/format.go b/utils/format.go index 109f802..b9bf370 100644 --- a/utils/format.go +++ b/utils/format.go @@ -19,20 +19,21 @@ package utils import ( "encoding/json" + "github.com/hokaccha/go-prettyjson" ) -//func info(tag string, value interface{}) { -// pc, fn, line, _ := runtime.Caller(1) -// basicFile := fn[strings.LastIndex(fn, "/")+1:] -// details := runtime.FuncForPC(pc) -// basicFnName := details.Name()[strings.LastIndex(details.Name(), ".")+1:] -// fmt.Printf("---\n[info] %s(%d): %s: %s=%+v\n", basicFile, line, basicFnName, tag, value) -//} +func PrettyJSON(rawData interface{}) (string, error) { + formatter := prettyjson.NewFormatter() + bytes, err := formatter.Marshal(rawData) + if err != nil { + return "", err + } + return string(bytes), nil +} func FormatStructAsJsonString(a interface{}) string { out, err := json.Marshal(a) if err == nil { - //fmt.Println(string(out)) return string(out) } return "" diff --git a/utils/misc.go b/utils/misc.go index eeda747..65193fc 100644 --- a/utils/misc.go +++ b/utils/misc.go @@ -27,7 +27,6 @@ import ( "strings" "github.com/apache/openwhisk-client-go/whisk" - "github.com/hokaccha/go-prettyjson" ) const ( @@ -96,15 +95,6 @@ func IsFeedAction(trigger *whisk.Trigger) (string, bool) { return "", false } -func PrettyJSON(j interface{}) (string, error) { - formatter := prettyjson.NewFormatter() - bytes, err := formatter.Marshal(j) - if err != nil { - return "", err - } - return string(bytes), nil -} - func GetManifestFilePath(projectPath string) string { if _, err := os.Stat(path.Join(projectPath, ManifestFileNameYaml)); err == nil { return path.Join(projectPath, ManifestFileNameYaml) diff --git a/utils/misc_test.go b/utils/misc_test.go index ae45bb0..8735302 100644 --- a/utils/misc_test.go +++ b/utils/misc_test.go @@ -58,7 +58,7 @@ func TestDependencies(t *testing.T) { assert.Equal(t, "/subfolder1/subfolder2", record.SubFolder, "SubFolder is wrong") } -func TestNewZipWritter(t *testing.T) { +func TestNewZipWriter(t *testing.T) { filePath := "../tests/src/integration/zipaction/actions/cat" zipName := filePath + ".zip" err := NewZipWritter(filePath, zipName, make([][]string, 0), make([]string, 0), "").Zip() diff --git a/webaction/webaction.go b/webaction/webaction.go index 88b6c1d..b02b1b0 100644 --- a/webaction/webaction.go +++ b/webaction/webaction.go @@ -18,17 +18,23 @@ package webaction import ( + "fmt" "github.com/apache/openwhisk-client-go/whisk" + "github.com/apache/openwhisk-wskdeploy/utils" "github.com/apache/openwhisk-wskdeploy/wskderrors" + "github.com/apache/openwhisk-wskdeploy/wski18n" + "github.com/apache/openwhisk-wskdeploy/wskprint" "strings" ) //for web action support, code from wsk cli with tiny adjustments const ( - WEB_EXPORT_ANNOT = "web-export" - RAW_HTTP_ANNOT = "raw-http" - FINAL_ANNOT = "final" - TRUE = "true" + REQUIRE_WHISK_AUTH = "require-whisk-auth" + WEB_EXPORT_ANNOT = "web-export" + RAW_HTTP_ANNOT = "raw-http" + FINAL_ANNOT = "final" + TRUE = "true" + MAX_JS_INT = 1<<53 - 1 ) var webExport map[string]string = map[string]string{ @@ -46,7 +52,6 @@ func deleteKey(key string, keyValueArr whisk.KeyValueArr) whisk.KeyValueArr { break } } - return keyValueArr } @@ -55,11 +60,10 @@ func addKeyValue(key string, value interface{}, keyValueArr whisk.KeyValueArr) w Key: key, Value: value, } - return append(keyValueArr, keyValue) } -func WebAction(filePath string, action string, webMode string, annotations whisk.KeyValueArr, fetch bool) (whisk.KeyValueArr, error) { +func SetWebActionAnnotations(filePath string, action string, webMode string, annotations whisk.KeyValueArr, fetch bool) (whisk.KeyValueArr, error) { switch strings.ToLower(webMode) { case webExport["TRUE"]: fallthrough @@ -70,7 +74,7 @@ func WebAction(filePath string, action string, webMode string, annotations whisk case webExport["FALSE"]: return webActionAnnotations(fetch, annotations, deleteWebAnnotations) case webExport["RAW"]: - return webActionAnnotations(fetch, annotations, addRawAnnotations) + return webActionAnnotations(fetch, annotations, addWebRawAnnotations) default: return nil, wskderrors.NewInvalidWebExportError(filePath, action, webMode, getValidWebExports()) } @@ -82,8 +86,9 @@ func webActionAnnotations( fetchAnnotations bool, annotations whisk.KeyValueArr, webActionAnnotationMethod WebActionAnnotationMethod) (whisk.KeyValueArr, error) { - if annotations != nil || !fetchAnnotations { - annotations = webActionAnnotationMethod(annotations) + + if annotations != nil || !fetchAnnotations { + annotations = webActionAnnotationMethod(annotations) } return annotations, nil @@ -107,7 +112,7 @@ func deleteWebAnnotations(annotations whisk.KeyValueArr) whisk.KeyValueArr { return annotations } -func addRawAnnotations(annotations whisk.KeyValueArr) whisk.KeyValueArr { +func addWebRawAnnotations(annotations whisk.KeyValueArr) whisk.KeyValueArr { annotations = deleteWebAnnotationKeys(annotations) annotations = addKeyValue(WEB_EXPORT_ANNOT, true, annotations) annotations = addKeyValue(RAW_HTTP_ANNOT, true, annotations) @@ -145,3 +150,58 @@ func IsWebAction(webexport string) bool { func IsWebSequence(webexport string) bool { return IsWebAction(webexport) } + +func HasAnnotation(annotations *whisk.KeyValueArr, key string) bool { + return (annotations.FindKeyValue(key) >= 0) +} + +func ValidateRequireWhiskAuthAnnotationValue(actionName string, value interface{}) (string, error) { + var isValid = false + var enabled = wski18n.FEATURE_DISABLED + + switch value.(type) { + case string: + secureValue := value.(string) + // assure the user-supplied token is valid (i.e., for now a non-empty string) + if len(secureValue) != 0 && secureValue!="<nil>" { + isValid = true + enabled = wski18n.FEATURE_ENABLED + } + case int: + secureValue := value.(int) + // FYI, the CLI defines MAX_JS_INT = 1<<53 - 1 (i.e., 9007199254740991) + // NOTE: For JS, the largest exact integral value is 253-1, or 9007199254740991. + // In ES6, this is defined as Number MAX_SAFE_INTEGER. + // However, in JS, the bitwise operators and shift operators operate on 32-bit ints, + // so in that case, the max safe integer is 231-1, or 2147483647 + // We also disallow negative integers + if secureValue < MAX_JS_INT && secureValue > 0 { + isValid = true + enabled = wski18n.FEATURE_ENABLED + } + case bool: + secureValue := value.(bool) + isValid = true + if secureValue { + enabled = wski18n.FEATURE_ENABLED + } + } + + if !isValid { + errMsg := wski18n.T(wski18n.ID_ERR_WEB_ACTION_REQUIRE_AUTH_TOKEN_INVALID_X_action_X_key_X_value, + map[string]interface{}{ + wski18n.KEY_ACTION: actionName, + wski18n.KEY_KEY: REQUIRE_WHISK_AUTH, + wski18n.KEY_VALUE: fmt.Sprintf("%v", value)}) + return errMsg, wskderrors.NewActionSecureKeyError(errMsg) + } + + // Emit an affirmation that security token will be applied to the action + msg := wski18n.T(wski18n.ID_VERBOSE_ACTION_AUTH_X_action_X_value_X, + map[string]interface{}{ + wski18n.KEY_ACTION: actionName, + wski18n.KEY_VALUE: enabled}) + wskprint.PrintlnOpenWhiskVerbose(utils.Flags.Verbose, msg) + + return msg, nil +} diff --git a/wskderrors/wskdeployerror.go b/wskderrors/wskdeployerror.go index 207b1ad..de06d99 100644 --- a/wskderrors/wskdeployerror.go +++ b/wskderrors/wskdeployerror.go @@ -65,6 +65,7 @@ const ( ERROR_YAML_INVALID_WEB_EXPORT = "ERROR_YAML_INVALID_WEB_EXPORT" ERROR_YAML_INVALID_API_GATEWAY_METHOD = "ERROR_YAML_INVALID_API_GATEWAY_METHOD" ERROR_RUNTIME_PARSER_FAILURE = "ERROR_RUNTIME_PARSER_FAILURE" + ERROR_ACTION_ANNOTATION = "ERROR_ACTION_ANNOTATION" ) /* @@ -459,6 +460,21 @@ func NewRuntimeParserError(errorMsg string) *RuntimeParserError { return err } +/* + * Failed to Retrieve/Parse Runtime + */ +type DeployError struct { + WskDeployBaseErr +} + +func NewActionSecureKeyError(errorMsg string) *DeployError { + var err = &DeployError{} + err.SetErrorType(ERROR_ACTION_ANNOTATION) + err.SetCallerByStackFrameSkip(2) + err.SetMessage(errorMsg) + return err +} + func IsCustomError(err error) bool { switch err.(type) { diff --git a/wski18n/i18n_ids.go b/wski18n/i18n_ids.go index d670ec4..9fda5f7 100644 --- a/wski18n/i18n_ids.go +++ b/wski18n/i18n_ids.go @@ -36,6 +36,8 @@ const ( COMMAND_LINE = "command line" CONFIGURATION = "Configuration" DEPLOYMENT_FILE = "deployment file" + FEATURE_DISABLED = "disabled" + FEATURE_ENABLED = "enabled" MANIFEST_FILE = "manifest file" NAME_PROJECT = "project name" PACKAGE_BINDING = "package binding" @@ -50,48 +52,48 @@ const ( // Known keys used for text replacement in i18n translated strings const ( KEY_ACTION = "action" + KEY_API = "api" + KEY_API_BASE_PATH = "apibasepath" + KEY_API_RELATIVE_PATH = "apirelativepath" + KEY_ARG = "arg" + KEY_BINDINGS = "bindings" KEY_CMD = "cmd" KEY_CODE = "code" + KEY_DEPENDENCY = "dependency" KEY_DEPLOYMENT_NAME = "dname" KEY_DEPLOYMENT_PATH = "dpath" + KEY_DESTINATION = "destination" + KEY_DUMMY_TOKEN = "dummytoken" KEY_ERR = "err" KEY_EXTENSION = "ext" KEY_FILE_TYPE = "filetype" KEY_HOST = "host" + KEY_INCLUDE = "include" + KEY_INPUTS = "inputs" KEY_KEY = "key" KEY_LIMIT = "limit" + KEY_LOCATION = "location" KEY_MANIFEST_NAME = "mname" KEY_MANIFEST_PATH = "mpath" KEY_NAME = "name" KEY_NAMESPACE = "namespace" KEY_NEW = "newkey" KEY_OLD = "oldkey" + KEY_PACKAGE = "package" KEY_PATH = "path" KEY_PROJECT = "project" + KEY_RESPONSE = "response" + KEY_RULE = "rule" KEY_RUNTIME = "runtime" - KEY_SOURCE = "source" - KEY_VALUE = "value" - KEY_VALUE_MIN = "min" // TODO() attempt to use this for Limit value range errors - KEY_VALUE_MAX = "max" // TODO() attempt to use this for Limit value range errors - KEY_API = "api" - KEY_URL = "url" - KEY_PACKAGE = "package" - KEY_BINDINGS = "bindings" - KEY_DEPENDENCY = "dependency" - KEY_LOCATION = "location" KEY_SEQUENCE = "sequence" + KEY_SOURCE = "source" KEY_TRIGGER = "trigger" KEY_TRIGGER_FEED = "feed" - KEY_RULE = "rule" - KEY_ARG = "arg" - KEY_INPUTS = "inputs" - KEY_API_BASE_PATH = "apibasepath" - KEY_RESPONSE = "response" - KEY_API_RELATIVE_PATH = "apirelativepath" - KEY_DESTINATION = "destination" - KEY_INCLUDE = "include" - KEY_DUMMY_TOKEN = "dummytoken" + KEY_URL = "url" KEY_UUID = "uuid" + KEY_VALUE = "value" + KEY_VALUE_MAX = "max" // TODO() attempt to use this for Limit value range errors + KEY_VALUE_MIN = "min" // TODO() attempt to use this for Limit value range errors ) // DO NOT TRANSLATE @@ -216,6 +218,7 @@ const ( ID_ERR_REQUIRED_INPUTS_MISSING_VALUE_X_inputs_X = "msg_err_required_inputs_missing_value" ID_ERR_API_GATEWAY_BASE_PATH_INVALID_X_api_X = "msg_err_api_gateway_base_path_invalid" ID_ERR_RUNTIME_PARSER_ERROR = "msg_err_runtime_parser_error" + ID_ERR_WEB_ACTION_REQUIRE_AUTH_TOKEN_INVALID_X_action_X_key_X_value = "msg_err_web_action_require_auth_token_invalid" // Server-side Errors (wskdeploy as an Action) ID_ERR_JSON_MISSING_KEY_CMD = "msg_err_json_missing_cmd_key" @@ -261,10 +264,11 @@ const ( ID_VERBOSE_CREATING_ZIP_FILE_X_path_X = "msg_verbose_creating_zip_file" ID_VERBOSE_DELETING_FILE_X_path_X = "msg_verbose_deleting_file" ID_VERBOSE_LIST_OF_FILES_MATCHING_PATTERN = "msg_verbose_list_of_files_matching_pattern" + ID_VERBOSE_ACTION_AUTH_X_action_X_value_X = "msg_action_authentication" ) // DO NOT TRANSLATE -// Used to unit test that translations exist with these IDs +// Used to unit test that translations exist with these IDs and their keys != their values (string) var I18N_ID_SET = [](string){ ID_CMD_DESC_LONG_REPORT, ID_CMD_DESC_LONG_ROOT, @@ -278,11 +282,11 @@ var I18N_ID_SET = [](string){ ID_CMD_FLAG_CONFIG, ID_CMD_FLAG_DEFAULTS, ID_CMD_FLAG_DEPLOYMENT, - ID_CMD_FLAG_PREVIEW, ID_CMD_FLAG_KEY_FILE, ID_CMD_FLAG_MANAGED, ID_CMD_FLAG_MANIFEST, ID_CMD_FLAG_NAMESPACE, + ID_CMD_FLAG_PREVIEW, ID_CMD_FLAG_PROJECT, ID_CMD_FLAG_PROJECTNAME, ID_CMD_FLAG_STRICT, @@ -292,9 +296,11 @@ var I18N_ID_SET = [](string){ ID_DEBUG_PACKAGES_FOUND_UNDER_PROJECT_X_path_X_name_X, ID_DEBUG_PACKAGES_FOUND_UNDER_ROOT_X_path_X, ID_DEBUG_PROJECT_SEARCH_X_path_X_key_X, + ID_ERR_CANT_SAVE_DOCKER_RUNTIME, ID_ERR_DEPENDENCY_UNKNOWN_TYPE, ID_ERR_ENTITY_CREATE_X_key_X_err_X_code_X, ID_ERR_ENTITY_DELETE_X_key_X_err_X_code_X, + ID_ERR_FILE_ALREADY_EXISTS, ID_ERR_JSON_MISSING_KEY_CMD, ID_ERR_JSON_MISSING_KEY_CMD, ID_ERR_KEY_MISSING_X_key_X, @@ -305,15 +311,16 @@ var I18N_ID_SET = [](string){ ID_ERR_RUNTIMES_GET_X_err_X, ID_ERR_URL_INVALID_X_urltype_X_url_X_filetype_X, ID_ERR_URL_MALFORMED_X_urltype_X_url_X, - ID_ERR_CANT_SAVE_DOCKER_RUNTIME, - ID_ERR_FILE_ALREADY_EXISTS, + ID_ERR_WEB_ACTION_REQUIRE_AUTH_TOKEN_INVALID_X_action_X_key_X_value, ID_MSG_COMMAND_USING_X_cmd_X_filetype_X_path_X, ID_MSG_CONFIG_INFO_APIHOST_X_host_X_source_X, ID_MSG_CONFIG_INFO_AUTHKEY_X_source_X, ID_MSG_CONFIG_INFO_NAMESPACE_X_namespace_X_source_X, + ID_MSG_CONFIG_MISSING_APIGW_ACCESS_TOKEN, ID_MSG_CONFIG_MISSING_APIHOST, ID_MSG_CONFIG_MISSING_AUTHKEY, ID_MSG_CONFIG_MISSING_NAMESPACE, + ID_MSG_CONFIG_PROVIDE_DEFAULT_APIGW_ACCESS_TOKEN, ID_MSG_DEPENDENCY_DEPLOYING_X_name_X, ID_MSG_DEPENDENCY_DEPLOYMENT_FAILURE_X_name_X, ID_MSG_DEPENDENCY_DEPLOYMENT_SUCCESS_X_name_X, @@ -355,6 +362,4 @@ var I18N_ID_SET = [](string){ ID_WARN_PACKAGES_NOT_FOUND_X_path_X, ID_WARN_RUNTIME_CHANGED_X_runtime_X_action_X, ID_WARN_WHISK_PROPS_DEPRECATED, - ID_MSG_CONFIG_MISSING_APIGW_ACCESS_TOKEN, - ID_MSG_CONFIG_PROVIDE_DEFAULT_APIGW_ACCESS_TOKEN, } diff --git a/wski18n/i18n_resources.go b/wski18n/i18n_resources.go index 1430566..aae595c 100644 --- a/wski18n/i18n_resources.go +++ b/wski18n/i18n_resources.go @@ -97,7 +97,7 @@ func wski18nResourcesDe_deAllJson() (*asset, error) { return a, nil } -var _wski18nResourcesEn_usAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x3c\x6b\x6f\x1b\x39\x92\xdf\xe7\x57\x14\x06\x0b\x64\x16\x90\xe5\xec\xe2\x70\x58\x18\x97\x03\xbc\xb1\x33\xeb\x9d\x64\x1c\xd8\xce\x0c\xe6\x12\xa3\x43\x75\x97\x24\xae\xbb\xc9\x5e\x92\x2d\x45\x63\xe8\xbf\x1f\xaa\x48\x76\xb7\x64\xf5\x43\x4e\x06\x77\xf9\x12\x49\x24\xeb\xc5\x62\xb1\x5e\xf4\xc7\xef\x00\x1e\xbf\x03\x00\xf8\x5e\x66\xdf\x9f\xc1\xf7\x85\x5d\x24\xa5\xc1\xb9\xfc\x92\xa0\x31\xda\x7c\x3f\xf1\xa3\xce [...] +var _wski18nResourcesEn_usAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x3c\x6b\x6f\x1b\x39\x92\xdf\xe7\x57\x14\x06\x0b\x64\x16\x90\xe5\xec\xe2\x70\x58\xf8\x2e\x07\x78\x13\x67\xc7\x3b\xc9\x38\xe7\xc7\x0e\xe6\x12\xa3\x43\x75\x97\x24\xae\xbb\xc9\x5e\x92\x2d\x45\x63\xe8\xbf\x1f\xaa\x48\x76\xb7\x64\xf5\x43\x4e\x06\x77\xf9\x12\x49\x24\xeb\xc5\x62\xb1\x5e\xf4\xc7\xef\x00\x1e\xbf\x03\x00\xf8\x5e\x66\xdf\x9f\xc1\xf7\x85\x5d\x24\xa5\xc1\xb9\xfc\x92\xa0\x31\xda\x7c\x3f\xf1\xa3\xce [...] func wski18nResourcesEn_usAllJsonBytes() ([]byte, error) { return bindataRead( @@ -112,7 +112,7 @@ func wski18nResourcesEn_usAllJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 21194, mode: os.FileMode(420), modTime: time.Unix(1571334180, 0)} + info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 21565, mode: os.FileMode(420), modTime: time.Unix(1579715078, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/wski18n/resources/en_US.all.json b/wski18n/resources/en_US.all.json index 3350db5..bc0aba4 100644 --- a/wski18n/resources/en_US.all.json +++ b/wski18n/resources/en_US.all.json @@ -392,6 +392,10 @@ "translation": "Failed to retrieve runtimes {{.err}}." }, { + "id": "msg_err_web_action_require_auth_token_invalid", + "translation": "Unable to secure the web action; Action [{{.action}}] Annotation [{{.key}}] has invalid value [{{.value}}]." + }, + { "id": "WARNINGS", "translation": "================= WARNINGS ===================" }, @@ -546,5 +550,9 @@ { "id": "msg_verbose_list_of_files_matching_pattern", "translation": "Found the following files with matching Source File Path pattern.\n" + }, + { + "id": "msg_action_authentication", + "translation": "Authentication for Action [{{.action}}] has been [{{.value}}] using the REQUIRE_WHISK_AUTH Annotation.\n" } ] diff --git a/wskprint/console.go b/wskprint/console.go index 4719c39..91ee593 100644 --- a/wskprint/console.go +++ b/wskprint/console.go @@ -118,12 +118,6 @@ func PrintlnOpenWhiskTrace(trace bool, message string) { } } -func PrintOpenWhiskBanner(verbose bool) { - if verbose { - PrintlnOpenWhiskOutput(" ____ ___ _ _ _ _ _\n /\\ \\ / _ \\ _ __ ___ _ __ | | | | |__ (_)___| | __\n /\\ /__\\ \\ | | | | '_ \\ / _ \\ '_ \\| | | | '_ \\| / __| |/ /\n / \\____ \\ / | |_| | |_) | __/ | | | |/\\| | | | | \\__ \\ <\n \\ \\ / \\/ \\___/| .__/ \\___|_| |_|__/\\__|_| |_|_|___/_|\\_\\ \n \\___\\/ |_|\n") - } -} - // Display "trace" output if either param is true OR we are running Go test verbose (i.e., "go test -v") // Typical Args for "go test" looks as follows: // arg[0] = [/var/folders/nj/<uuid>/T/<build-id>/github.com/apache/openwhisk-wskdeploy/deployers/_test/deployers.test @@ -149,3 +143,9 @@ func DetectVerbose() bool { } return false } + +//func PrintOpenWhiskBanner(verbose bool) { +// if verbose { +// PrintlnOpenWhiskOutput(" ____ ___ _ _ _ _ _\n /\\ \\ / _ \\ _ __ ___ _ __ | | | | |__ (_)___| | __\n /\\ /__\\ \\ | | | | '_ \\ / _ \\ '_ \\| | | | '_ \\| / __| |/ /\n / \\____ \\ / | |_| | |_) | __/ | | | |/\\| | | | | \\__ \\ <\n \\ \\ / \\/ \\___/| .__/ \\___|_| |_|__/\\__|_| |_|_|___/_|\\_\\ \n \\___\\/ |_|\n") +// } +//}