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&nbsp;&#124; web-export | no | string | true&nbsp;&#124; 
false&nbsp;&#124; yes&nbsp;&#124; no&nbsp;&#124; 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&nbsp;&#124; yes&nbsp;&#124; no&nbsp;&#124; 
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&nbsp;&#124; integer&nbsp;&#124; 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., &lt;actionName&gt; 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., &lt;actionName&gt; **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&nbsp;&#124; 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&nbsp;&#124; 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&nbsp;&#124; java8 (default) | java:8 | 
[openwhisk/java8action](https://hub.docker.com/r/openwhisk/java8action) | 
nightly | Java (8) language runtime |
+| php&nbsp;&#124; 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&nbsp;&#124; 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&nbsp;&#124; (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&nbsp;&#124; 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&nbsp;&#124; 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")
+//     }
+//}

Reply via email to