You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by pd...@apache.org on 2019/10/24 17:51:31 UTC

[openwhisk-wskdeploy] branch master updated: Support alt. namespace resource uuid as tenant id to API gatway service (#1076)

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 fb12a16  Support alt. namespace resource uuid as tenant id to API gatway service (#1076)
fb12a16 is described below

commit fb12a167b4f0b0f4a917a6758b3feb7672781a6b
Author: Matt Rutkowski <mr...@us.ibm.com>
AuthorDate: Thu Oct 24 19:51:22 2019 +0200

    Support alt. namespace resource uuid as tenant id to API gatway service (#1076)
    
    * Support alt. namespace resource uuid as tenant id to API gatway service
    
    * gofmt
    
    * gofmt
    
    * wskclient update and remove some trace output
    
    * Attempt to figure out Travis failure
    
    * Attempt to figure out Travis failure
    
    * Attempt to figure out Travis failure
    
    * Attempt to figure out Travis failure
    
    * Update GoDeps to use the latest openwhisk-client-go commit level
    
    * Attempt to figure out Travis failure
    
    * Update GoDeps to use the latest openwhisk-client-go commit level
---
 .travis.yml                                        | 19 +++++++----
 Godeps/Godeps.json                                 |  4 +--
 build.gradle                                       |  4 +--
 deployers/manifestreader_test.go                   |  4 +--
 deployers/servicedeployer.go                       | 10 +++++-
 deployers/whiskclient.go                           | 39 +++++++++++++++++-----
 docs/sync_projects_between_client_and_server.md    |  6 ++--
 docs/wskdeploy_interpolation.md                    |  2 +-
 parsers/manifest_parser_test.go                    | 38 ++++++++++-----------
 parsers/yamlparser.go                              |  2 +-
 tests/dat/manifest_validate_dependencies.yaml      | 14 ++++----
 .../dat/manifest_validate_dependencies_bogus.yaml  | 14 ++++----
 tests/src/integration/dependency/manifest.yaml     |  2 +-
 .../06-manifest-with-single-dependency.yaml        |  2 +-
 .../07-manifest-with-dependency.yaml               |  4 +--
 .../validate-packages-in-manifest/manifest.yaml    |  8 ++---
 tests/usecases/dependency/README.md                |  8 ++---
 tests/usecases/dependency/manifest.yaml            |  4 +--
 utils/conversion.go                                |  1 +
 utils/flags.go                                     | 14 ++++----
 utils/format.go                                    | 39 ++++++++++++++++++++++
 utils/misc.go                                      |  1 +
 wski18n/i18n_ids.go                                | 22 +++++++-----
 wski18n/i18n_resources.go                          | 22 ++++++------
 wski18n/resources/en_US.all.json                   |  6 +++-
 wskprint/console.go                                |  1 -
 26 files changed, 189 insertions(+), 101 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 3ee1845..593c0f9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -17,10 +17,15 @@
 
 sudo: required
 language: go
-go:
-- 1.9
-services:
-- docker
+
+matrix:
+  include:
+    - os: linux
+      sudo: required
+      go: "1.9.3"
+      services: docker
+      dist: xenial
+
 git:
   depth: 3
 
@@ -41,8 +46,10 @@ install:
 before_script:
 - GO_FILES=$(find . -iname '*.go' -type f -not -path "./wski18n/i18n_resources.go")
 - export BAD_GO=$(gofmt -s -l $(echo $GO_FILES))
-- echo $BAD_GO
-- test -z "$BAD_GO"
+- echo "["$BAD_GO"]"
+#- test -z "$BAD_GO"
+#- test -z "$(gofmt -s -l $(echo $GO_FILES))"
+
 script:
 - echo $TRAVIS
 - echo $TRAVIS_PULL_REQUEST
diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json
index debe7a2..1b463cb 100644
--- a/Godeps/Godeps.json
+++ b/Godeps/Godeps.json
@@ -105,11 +105,11 @@
 		},
 		{
 			"ImportPath": "github.com/apache/openwhisk-client-go/whisk",
-			"Rev": "d8ccb1442651beee6a9245913e3ca0cb182888b1"
+			"Rev": "ee5b8709787cd37201c42e38040e9709f6d1e9c8"
 		},
 		{
 			"ImportPath": "github.com/apache/openwhisk-client-go/wski18n",
-			"Rev": "d8ccb1442651beee6a9245913e3ca0cb182888b1"
+			"Rev": "ee5b8709787cd37201c42e38040e9709f6d1e9c8"
 		},
 		{
 			"ImportPath": "github.com/pelletier/go-buffruneio",
diff --git a/build.gradle b/build.gradle
index bc5c8d0..a6f115b 100644
--- a/build.gradle
+++ b/build.gradle
@@ -62,8 +62,8 @@ dependencies {
         build(['name':'github.com/nicksnyder/go-i18n/i18n/bundle', 'version':'991e81cc94f6c54209edb3192cb98e3995ad71c1', 'transitive':false])
         build(['name':'github.com/nicksnyder/go-i18n/i18n/language', 'version':'991e81cc94f6c54209edb3192cb98e3995ad71c1', 'transitive':false])
         build(['name':'github.com/nicksnyder/go-i18n/i18n/translation', 'version':'991e81cc94f6c54209edb3192cb98e3995ad71c1', 'transitive':false])
-        build(['name':'github.com/apache/openwhisk-client-go/whisk', 'version':'d8ccb1442651beee6a9245913e3ca0cb182888b1', 'transitive':false])
-        build(['name':'github.com/apache/openwhisk-client-go/wski18n', 'version':'d8ccb1442651beee6a9245913e3ca0cb182888b1', 'transitive':false])
+        build(['name':'github.com/apache/openwhisk-client-go/whisk', 'version':'ee5b8709787cd37201c42e38040e9709f6d1e9c8', 'transitive':false])
+        build(['name':'github.com/apache/openwhisk-client-go/wski18n', 'version':'ee5b8709787cd37201c42e38040e9709f6d1e9c8', 'transitive':false])
         build(['name':'github.com/pelletier/go-buffruneio', 'version':'df1e16fde7fc330a0ca68167c23bf7ed6ac31d6d', 'transitive':false])
         build(['name':'github.com/pelletier/go-toml', 'version':'45932ad32dfdd20826f5671da37a5f3ce9f26a8d', 'transitive':false])
         build(['name':'github.com/spf13/afero', 'version':'06b7e5f50606ecd49148a01a6008942d9b669217', 'transitive':false])
diff --git a/deployers/manifestreader_test.go b/deployers/manifestreader_test.go
index 978243e..570cda1 100644
--- a/deployers/manifestreader_test.go
+++ b/deployers/manifestreader_test.go
@@ -171,8 +171,8 @@ func TestManifestReader_SetDependencies(t *testing.T) {
 	err = manifestReader.HandleYaml(manifestParser, manifest, whisk.KeyValue{})
 	assert.Nil(t, err, fmt.Sprintf(TEST_ERROR_MANIFEST_PARSE_FAILURE, manifestFile))
 
-	expectedLocationHelloWorlds := "https://github.com/apache/incubator-openwhisk-test/packages/helloworlds"
-	expectedLocationHelloWhisk := "https://github.com/apache/incubator-openwhisk-test/packages/hellowhisk"
+	expectedLocationHelloWorlds := "https://github.com/apache/openwhisk-test/packages/helloworlds"
+	expectedLocationHelloWhisk := "https://github.com/apache/openwhisk-test/packages/hellowhisk"
 	expectedLocationUtils := "/whisk.system/utils"
 
 	for pkgName, pkg := range deployer.Deployment.Packages {
diff --git a/deployers/servicedeployer.go b/deployers/servicedeployer.go
index ef40e07..450090f 100644
--- a/deployers/servicedeployer.go
+++ b/deployers/servicedeployer.go
@@ -1011,7 +1011,15 @@ func (deployer *ServiceDeployer) createApi(api *whisk.ApiCreateRequest) error {
 	var response *http.Response
 
 	apiCreateReqOptions := deployer.Deployment.ApiOptions[apiPath]
-	apiCreateReqOptions.SpaceGuid = strings.Split(deployer.Client.Config.AuthToken, ":")[0]
+
+	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
+		apiCreateReqOptions.SpaceGuid = strings.Split(deployer.Client.Config.AuthToken, ":")[0]
+	}
+
 	apiCreateReqOptions.AccessToken = deployer.Client.Config.ApigwAccessToken
 
 	err = retry(DEFAULT_ATTEMPTS, DEFAULT_INTERVAL, func() error {
diff --git a/deployers/whiskclient.go b/deployers/whiskclient.go
index 74cff36..4d980b4 100644
--- a/deployers/whiskclient.go
+++ b/deployers/whiskclient.go
@@ -36,7 +36,7 @@ import (
 const (
 	SOURCE_WSKPROPS         = ".wskprops"
 	SOURCE_WHISK_PROPERTIES = "whisk.properties"
-	SOURCE_DEFAULT_VALUE    = "wskdeploy default" // TODO() i18n?
+	SOURCE_DEFAULT_VALUE    = "wskdeploy default"
 )
 
 var (
@@ -46,6 +46,7 @@ var (
 	key               = PropertyValue{}
 	cert              = PropertyValue{}
 	apigwAccessToken  = PropertyValue{}
+	apigwTenantId     = PropertyValue{}
 	additionalHeaders = make(http.Header)
 )
 
@@ -70,6 +71,7 @@ var GetWskPropFromWhiskProperty = func(pi whisk.Properties) (*whisk.Wskprops, er
 	return whisk.GetWskPropFromWhiskProperty(pi)
 }
 
+// TODO implement a command line flag for APIGW_TENANT_ID
 var GetCommandLineFlags = func() (string, string, string, string, string, string) {
 	return utils.Flags.ApiHost, utils.Flags.Auth, utils.Flags.Namespace, utils.Flags.Key, utils.Flags.Cert, utils.Flags.ApigwAccessToken
 }
@@ -92,6 +94,7 @@ func resetWhiskConfig() {
 	key = PropertyValue{}
 	cert = PropertyValue{}
 	apigwAccessToken = PropertyValue{}
+	apigwTenantId = PropertyValue{}
 }
 
 func readFromCLI() {
@@ -103,6 +106,8 @@ func readFromCLI() {
 	key = GetPropertyValue(key, keyfile, wski18n.COMMAND_LINE)
 	cert = GetPropertyValue(cert, certfile, wski18n.COMMAND_LINE)
 	apigwAccessToken = GetPropertyValue(apigwAccessToken, accessToken, wski18n.COMMAND_LINE)
+	// TODO optionally allow this value to be set from command line arg.
+	//apigwTenantId = GetPropertyValue(apigwTenantId, tenantId, wski18n.COMMAND_LINE)
 }
 
 func setWhiskConfig(cred string, ns string, host string, token string, source string) {
@@ -110,6 +115,7 @@ func setWhiskConfig(cred string, ns string, host string, token string, source st
 	namespace = GetPropertyValue(namespace, ns, source)
 	apiHost = GetPropertyValue(apiHost, host, source)
 	apigwAccessToken = GetPropertyValue(apigwAccessToken, token, source)
+	// TODO decide if we should allow APIGW_TENANT_ID in manifest
 }
 
 func readFromDeploymentFile(deploymentPath string) {
@@ -129,6 +135,7 @@ func readFromManifestFile(manifestPath string) {
 			mm := parsers.NewYAMLParser()
 			manifest, _ := mm.ParseManifest(manifestPath)
 			p := manifest.GetProject()
+			// TODO look to deprecate reading Namespace, APIGW values from manifest or depl. YAML files
 			setWhiskConfig(p.Credential, p.Namespace, p.ApiHost, p.ApigwAccessToken, path.Base(manifestPath))
 		}
 	}
@@ -143,6 +150,7 @@ func readFromWskprops(pi whisk.PropertiesImp, proppath string) {
 	key = GetPropertyValue(key, wskprops.Key, SOURCE_WSKPROPS)
 	cert = GetPropertyValue(cert, wskprops.Cert, SOURCE_WSKPROPS)
 	apigwAccessToken = GetPropertyValue(apigwAccessToken, wskprops.AuthAPIGWKey, SOURCE_WSKPROPS)
+	apigwTenantId = GetPropertyValue(apigwTenantId, wskprops.APIGWTenantId, SOURCE_WSKPROPS)
 }
 
 func readFromWhiskProperty(pi whisk.PropertiesImp) {
@@ -174,6 +182,12 @@ func readFromWhiskProperty(pi whisk.PropertiesImp) {
 			map[string]interface{}{wski18n.KEY_KEY: wski18n.APIGW_ACCESS_TOKEN})
 		wskprint.PrintlnOpenWhiskWarning(warnMsg)
 	}
+	apigwTenantId = GetPropertyValue(apigwTenantId, whiskproperty.APIGWTenantId, SOURCE_WHISK_PROPERTIES)
+	if apigwTenantId.Source == SOURCE_WHISK_PROPERTIES {
+		warnMsg = wski18n.T(wski18n.ID_WARN_WHISK_PROPS_DEPRECATED,
+			map[string]interface{}{wski18n.KEY_KEY: wski18n.APIGW_TENANT_ID})
+		wskprint.PrintlnOpenWhiskWarning(warnMsg)
+	}
 }
 
 // we are reading openwhisk credentials (apihost, namespace, and auth) in the following precedence order:
@@ -198,7 +212,7 @@ func NewWhiskConfig(proppath string, deploymentPath string, manifestPath string)
 
 	// TODO() i18n
 	// Print all flags / values if verbose
-	wskprint.PrintlnOpenWhiskVerbose(utils.Flags.Verbose, wski18n.CONFIGURATION+":\n"+utils.Flags.Format())
+	//wskprint.PrintlnOpenWhiskVerbose(utils.Flags.Verbose, wski18n.CONFIGURATION+":\n"+utils.Flags.Format())
 
 	// now, read them from deployment file if not found on command line
 	readFromDeploymentFile(deploymentPath)
@@ -228,17 +242,22 @@ func NewWhiskConfig(proppath string, deploymentPath string, manifestPath string)
 	}
 
 	clientConfig = &whisk.Config{
-		AuthToken:         credential.Value, //Authtoken
-		Namespace:         namespace.Value,  //Namespace
-		Host:              apiHost.Value,
-		Version:           "v1", // TODO() should not be hardcoded, should warn user of default
+		AuthToken: credential.Value, //Authtoken
+		Namespace: namespace.Value,  //Namespace
+		Host:      apiHost.Value,
+		Version:   "v1", // TODO() should not be hardcoded, should warn user of default
+		//Version:           Apiversion
 		Cert:              cert.Value,
 		Key:               key.Value,
 		Insecure:          mode, // true if you want to ignore certificate signing
 		ApigwAccessToken:  apigwAccessToken.Value,
+		ApigwTenantId:     apigwTenantId.Value,
 		AdditionalHeaders: additionalHeaders,
 	}
 
+	// Print all flags / values if verbose
+	wskprint.PrintlnOpenWhiskVerbose(utils.Flags.Verbose, wski18n.CLI_FLAGS+":\n"+utils.Flags.Format())
+
 	// validate we have credential, apihost and namespace
 	err := validateClientConfig(credential, apiHost, namespace)
 	return clientConfig, err
@@ -258,13 +277,11 @@ func validateClientConfig(credential PropertyValue, apiHost PropertyValue, names
 		if len(apiHost.Value) == 0 {
 			errorMsg = wskderrors.AppendDetailToErrorMessage(
 				errorMsg, wski18n.T(wski18n.ID_MSG_CONFIG_MISSING_APIHOST), 1)
-
 		}
 
 		if len(namespace.Value) == 0 {
 			errorMsg = wskderrors.AppendDetailToErrorMessage(
 				errorMsg, wski18n.T(wski18n.ID_MSG_CONFIG_MISSING_NAMESPACE), 1)
-
 		}
 
 		if len(errorMsg) > 0 {
@@ -291,5 +308,11 @@ func validateClientConfig(credential PropertyValue, apiHost PropertyValue, names
 		wskprint.PrintOpenWhiskVerbose(utils.Flags.Verbose, stdout)
 	}
 
+	if len(apigwTenantId.Value) != 0 {
+		stdout = wski18n.T(wski18n.ID_MSG_CONFIG_INFO_APIGW_TENANT_ID_X_source_X,
+			map[string]interface{}{wski18n.KEY_UUID: apigwTenantId, wski18n.KEY_SOURCE: apigwTenantId.Source})
+		wskprint.PrintOpenWhiskVerbose(utils.Flags.Verbose, stdout)
+	}
+
 	return nil
 }
diff --git a/docs/sync_projects_between_client_and_server.md b/docs/sync_projects_between_client_and_server.md
index d5fe584..412e8a0 100644
--- a/docs/sync_projects_between_client_and_server.md
+++ b/docs/sync_projects_between_client_and_server.md
@@ -208,7 +208,7 @@ project:
         Extension1:
             dependencies:
                 helloworlds:
-                    location: github.com/apache/incubator-openwhisk-test/packages/helloworlds
+                    location: github.com/apache/openwhisk-test/packages/helloworlds
 ```
 
 After deploying this project with `wskdeploy sync -m manifest.yaml`, package `Extension2` has following annotation:
@@ -277,9 +277,9 @@ project:
         Extension2:
             dependencies:
                 helloworlds:
-                    location: github.com/apache/incubator-openwhisk-test/packages/helloworlds
+                    location: github.com/apache/openwhisk-test/packages/helloworlds
                 custom-hellowhisk:
-                    location: github.com/apache/incubator-openwhisk-test/packages/hellowhisk
+                    location: github.com/apache/openwhisk-test/packages/hellowhisk
 ...
 ```
 
diff --git a/docs/wskdeploy_interpolation.md b/docs/wskdeploy_interpolation.md
index acd1e12..de3e9d7 100644
--- a/docs/wskdeploy_interpolation.md
+++ b/docs/wskdeploy_interpolation.md
@@ -75,7 +75,7 @@ project:
                 hello3:
                     function: ${OPENWHISK_FUNCTION_PYTHON}.py
                 hello4:
-                    function: https://${OPENWHISK_FUNCTION_GITHUB_DIR}.js                    function: github.com/apache/incubator-openwhisk-test/packages/helloworlds
+                    function: https://${OPENWHISK_FUNCTION_GITHUB_DIR}.js                    function: github.com/apache/openwhisk-test/packages/helloworlds
 ```
 
 #### Trigger Feed
diff --git a/parsers/manifest_parser_test.go b/parsers/manifest_parser_test.go
index c43421a..d482804 100644
--- a/parsers/manifest_parser_test.go
+++ b/parsers/manifest_parser_test.go
@@ -190,12 +190,12 @@ func testUnmarshalTemporaryFile(data []byte, filename string) (p *YAMLParser, m
 func TestUnmarshalForHelloNodeJS(t *testing.T) {
 	testUnmarshalManifestPackageAndActionBasic(t,
 		"../tests/dat/manifest_hello_nodejs.yaml", // Manifest path
-		"helloworld",                              // Package name
-		1,                                         // # of Actions
-		"helloNodejs",                             // Action name
-		"actions/hello.js",                        // Function path
-		"nodejs:6",                                // "Runtime
-		"")                                        // "Main" function name
+		"helloworld",       // Package name
+		1,                  // # of Actions
+		"helloNodejs",      // Action name
+		"actions/hello.js", // Function path
+		"nodejs:6",         // "Runtime
+		"")                 // "Main" function name
 }
 
 // Test 2: validate manifest_parser:Unmarshal() method with a sample manifest in Java
@@ -203,12 +203,12 @@ func TestUnmarshalForHelloNodeJS(t *testing.T) {
 func TestUnmarshalForHelloJava(t *testing.T) {
 	testUnmarshalManifestPackageAndActionBasic(t,
 		"../tests/dat/manifest_hello_java_jar.yaml", // Manifest path
-		"helloworld",                                // Package name
-		1,                                           // # of Actions
-		"helloJava",                                 // Action name
-		"actions/hello.jar",                         // Function path
-		"java",                                      // "Runtime
-		"Hello")                                     // "Main" function name
+		"helloworld",        // Package name
+		1,                   // # of Actions
+		"helloJava",         // Action name
+		"actions/hello.jar", // Function path
+		"java",              // "Runtime
+		"Hello")             // "Main" function name
 }
 
 // Test 3: validate manifest_parser:Unmarshal() method with a sample manifest in Python
@@ -216,12 +216,12 @@ func TestUnmarshalForHelloJava(t *testing.T) {
 func TestUnmarshalForHelloPython(t *testing.T) {
 	testUnmarshalManifestPackageAndActionBasic(t,
 		"../tests/dat/manifest_hello_python.yaml", // Manifest path
-		"helloworld",                              // Package name
-		1,                                         // # of Actions
-		"helloPython",                             // Action name
-		"actions/hello.py",                        // Function path
-		"python",                                  // "Runtime
-		"")                                        // "Main" function name
+		"helloworld",       // Package name
+		1,                  // # of Actions
+		"helloPython",      // Action name
+		"actions/hello.py", // Function path
+		"python",           // "Runtime
+		"")                 // "Main" function name
 }
 
 // Test 4: validate manifest_parser:Unmarshal() method with a sample manifest in Swift
@@ -1910,7 +1910,7 @@ func TestParseYAML_param(t *testing.T) {
 				case "inline6":
 					assert.Equal(t, -531, param.Value, "Get param value failed.")
 				case "inline7":
-					assert.Equal(t, 432.432E-43, param.Value, "Get param value failed.")
+					assert.Equal(t, 432.432e-43, param.Value, "Get param value failed.")
 				case "inline8":
 					assert.Equal(t, "[ true, null, \"boo\", { \"key\": 0 }]", param.Value, "Get param value failed.")
 				case "inline9":
diff --git a/parsers/yamlparser.go b/parsers/yamlparser.go
index b46ed98..707a361 100644
--- a/parsers/yamlparser.go
+++ b/parsers/yamlparser.go
@@ -229,7 +229,7 @@ type Project struct {
 	Namespace        string               `yaml:"namespace"`
 	Credential       string               `yaml:"credential"`
 	ApiHost          string               `yaml:"apiHost"`
-	ApigwAccessToken string               `yaml:"apigwAccessToken"`
+	ApigwAccessToken string               `yaml:"apigwAccessToken"` // TODO: support apigwTenantId? deprecate?
 	Version          string               `yaml:"version"`
 	Packages         map[string]Package   `yaml:"packages"`
 	Inputs           map[string]Parameter `yaml: parameters`
diff --git a/tests/dat/manifest_validate_dependencies.yaml b/tests/dat/manifest_validate_dependencies.yaml
index a8b9daf..c3fdb00 100644
--- a/tests/dat/manifest_validate_dependencies.yaml
+++ b/tests/dat/manifest_validate_dependencies.yaml
@@ -19,22 +19,22 @@ packages:
     helloworld1:
         dependencies:
             helloworlds:
-                location: github.com/apache/incubator-openwhisk-test/packages/helloworlds
+                location: github.com/apache/openwhisk-test/packages/helloworlds
             dependency1:
-                location: github.com/apache/incubator-openwhisk-test/packages/helloworlds
+                location: github.com/apache/openwhisk-test/packages/helloworlds
             dependency2:
-                location: github.com/apache/incubator-openwhisk-test/packages/hellowhisk
+                location: github.com/apache/openwhisk-test/packages/hellowhisk
             dependency3:
                 location: /whisk.system/utils
     helloworld2:
         dependencies:
             helloworlds:
-                location: github.com/apache/incubator-openwhisk-test/packages/helloworlds
+                location: github.com/apache/openwhisk-test/packages/helloworlds
             dependency1:
-                location: github.com/apache/incubator-openwhisk-test/packages/helloworlds
+                location: github.com/apache/openwhisk-test/packages/helloworlds
             dependency4:
-                location: github.com/apache/incubator-openwhisk-test/packages/helloworlds
+                location: github.com/apache/openwhisk-test/packages/helloworlds
             dependency5:
-                location: github.com/apache/incubator-openwhisk-test/packages/hellowhisk
+                location: github.com/apache/openwhisk-test/packages/hellowhisk
             dependency6:
                 location: /whisk.system/utils
diff --git a/tests/dat/manifest_validate_dependencies_bogus.yaml b/tests/dat/manifest_validate_dependencies_bogus.yaml
index 476d47f..654fd0d 100644
--- a/tests/dat/manifest_validate_dependencies_bogus.yaml
+++ b/tests/dat/manifest_validate_dependencies_bogus.yaml
@@ -19,23 +19,23 @@ packages:
     helloworld1:
         dependencies:
             helloworlds:
-                location: github.com/apache/incubator-openwhisk-test/packages/helloworlds
+                location: github.com/apache/openwhisk-test/packages/helloworlds
             dependency1:
-                location: github.com/apache/incubator-openwhisk-test/packages/helloworlds
+                location: github.com/apache/openwhisk-test/packages/helloworlds
             dependency2:
-                location: github.com/apache/incubator-openwhisk-test/packages/hellowhisk
+                location: github.com/apache/openwhisk-test/packages/hellowhisk
             dependency3:
                 location: /whisk.system/utils
     helloworld2:
         dependencies:
             helloworlds:
-                location: github.com/apache/incubator-openwhisk-test/packages/helloworlds
+                location: github.com/apache/openwhisk-test/packages/helloworlds
             dependency1:
-                location: github.com/apache/incubator-openwhisk-test/packages/hellowhisk
+                location: github.com/apache/openwhisk-test/packages/hellowhisk
             dependency4:
-                location: github.com/apache/incubator-openwhisk-test/packages/helloworlds
+                location: github.com/apache/openwhisk-test/packages/helloworlds
             dependency5:
-                location: github.com/apache/incubator-openwhisk-test/packages/hellowhisk
+                location: github.com/apache/openwhisk-test/packages/hellowhisk
             dependency6:
                 location: /whisk.system/utils
 
diff --git a/tests/src/integration/dependency/manifest.yaml b/tests/src/integration/dependency/manifest.yaml
index 3fa28c2..c0b50da 100644
--- a/tests/src/integration/dependency/manifest.yaml
+++ b/tests/src/integration/dependency/manifest.yaml
@@ -19,7 +19,7 @@ packages:
   TestGitHubDependency:
       dependencies:
         helloworlds:
-          location: github.com/apache/incubator-openwhisk-test/packages/helloworlds
+          location: github.com/apache/openwhisk-test/packages/helloworlds
       triggers:
         trigger1:
         trigger2:
diff --git a/tests/src/integration/managed-deployment/06-manifest-with-single-dependency.yaml b/tests/src/integration/managed-deployment/06-manifest-with-single-dependency.yaml
index 18b776e..f595d7b 100644
--- a/tests/src/integration/managed-deployment/06-manifest-with-single-dependency.yaml
+++ b/tests/src/integration/managed-deployment/06-manifest-with-single-dependency.yaml
@@ -21,7 +21,7 @@ project:
         Extension1:
             dependencies:
                 helloworlds:
-                    location: github.com/apache/incubator-openwhisk-test/packages/helloworlds
+                    location: github.com/apache/openwhisk-test/packages/helloworlds
             triggers:
                 triggerInExtension1:
             rules:
diff --git a/tests/src/integration/managed-deployment/07-manifest-with-dependency.yaml b/tests/src/integration/managed-deployment/07-manifest-with-dependency.yaml
index d8e9c97..fb411b5 100644
--- a/tests/src/integration/managed-deployment/07-manifest-with-dependency.yaml
+++ b/tests/src/integration/managed-deployment/07-manifest-with-dependency.yaml
@@ -21,9 +21,9 @@ project:
         Extension2:
             dependencies:
                 hellowhisk-with-managed-project:
-                    location: github.com/apache/incubator-openwhisk-test/packages/hellowhisk
+                    location: github.com/apache/openwhisk-test/packages/hellowhisk
                 helloworlds-with-managed-project:
-                    location: github.com/apache/incubator-openwhisk-test/packages/helloworlds
+                    location: github.com/apache/openwhisk-test/packages/helloworlds
             sequences:
                 helloworld-sequence:
                    actions: helloworlds-with-managed-project/hello-js, hellowhisk-with-managed-project/greeting
diff --git a/tests/src/integration/validate-packages-in-manifest/manifest.yaml b/tests/src/integration/validate-packages-in-manifest/manifest.yaml
index 06a143e..50cf958 100644
--- a/tests/src/integration/validate-packages-in-manifest/manifest.yaml
+++ b/tests/src/integration/validate-packages-in-manifest/manifest.yaml
@@ -19,9 +19,9 @@ packages:
     packageNodeJS:
 #        dependencies:
 #            hellowhisk:
-#                location: github.com/apache/incubator-openwhisk-test/packages/hellowhisk
+#                location: github.com/apache/openwhisk-test/packages/hellowhisk
 #            myhelloworlds:
-#                location: github.com/apache/incubator-openwhisk-test/packages/helloworlds
+#                location: github.com/apache/openwhisk-test/packages/helloworlds
         actions:
             helloNodejs-1:
                 function: actions/hello.js
@@ -62,9 +62,9 @@ packages:
     packagePython:
 #        dependencies:
 #            hellowhisk:
-#                location: github.com/apache/incubator-openwhisk-test/packages/hellowhisk
+#                location: github.com/apache/openwhisk-test/packages/hellowhisk
 #            helloworlds:
-#                location: github.com/apache/incubator-openwhisk-test/packages/helloworlds
+#                location: github.com/apache/openwhisk-test/packages/helloworlds
         actions:
             helloPython-1:
                 function: actions/hello.py
diff --git a/tests/usecases/dependency/README.md b/tests/usecases/dependency/README.md
index c7197d4..4571909 100644
--- a/tests/usecases/dependency/README.md
+++ b/tests/usecases/dependency/README.md
@@ -35,11 +35,11 @@ a dependent package and can be specified in `manifest.yaml` with the following
 ```yaml
 dependencies:
     hellowhisk:
-        location: github.com/apache/incubator-openwhisk-test/packages/hellowhisk
+        location: github.com/apache/openwhisk-test/packages/hellowhisk
 ```
 
 where `hellowhisk` is an external package whose source code is located in
-GitHub repo under https://github.com/apache/incubator-openwhisk-test/. When we
+GitHub repo under https://github.com/apache/openwhisk-test/. When we
 deploy our application, `hellowhisk` will be deployed based on the manifest and
 deployment files located in the folder `packages/hellowhisk`.
 
@@ -49,9 +49,9 @@ package name, we can define `manifest` with:
 ```yaml
 dependencies:
     hellowhisk:
-        location: github.com/apache/incubator-openwhisk-test/packages/hellowhisk
+        location: github.com/apache/openwhisk-test/packages/hellowhisk
     myhelloworlds:
-        location: github.com/apache/incubator-openwhisk-test/packages/helloworlds
+        location: github.com/apache/openwhisk-test/packages/helloworlds
 ```
 
 ### Package Binding
diff --git a/tests/usecases/dependency/manifest.yaml b/tests/usecases/dependency/manifest.yaml
index 2d229dd..cc9a39d 100644
--- a/tests/usecases/dependency/manifest.yaml
+++ b/tests/usecases/dependency/manifest.yaml
@@ -19,9 +19,9 @@ packages:
     dependency-demo:
         dependencies:
             hellowhisk:
-                location: github.com/apache/incubator-openwhisk-test/packages/hellowhisk
+                location: github.com/apache/openwhisk-test/packages/hellowhisk
             myhelloworlds:
-                location: github.com/apache/incubator-openwhisk-test/packages/helloworlds
+                location: github.com/apache/openwhisk-test/packages/helloworlds
             cloudant-package-binding:
                 location: /whisk.system/cloudant
                 inputs:
diff --git a/utils/conversion.go b/utils/conversion.go
index c22781e..0bccb78 100644
--- a/utils/conversion.go
+++ b/utils/conversion.go
@@ -62,6 +62,7 @@ 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/flags.go b/utils/flags.go
index 3025bf6..c448706 100644
--- a/utils/flags.go
+++ b/utils/flags.go
@@ -41,14 +41,16 @@ type WskDeployFlags struct {
 	Managed          bool   // OpenWhisk Managed Deployments
 	ProjectName      string // Project name
 	ApigwAccessToken string
-	Verbose          bool
-	Trace            bool
-	Sync             bool
-	Report           bool
-	Param            []string
-	ParamFile        string
+	//ApigwTenantId    string // APIGW_TENANT_ID (IAM namespace resource identifier); not avail. as CLI flag yet
+	Verbose   bool
+	Trace     bool
+	Sync      bool
+	Report    bool
+	Param     []string
+	ParamFile string
 }
 
+// TODO turn this into a generic utility for formatting any struct
 func (flags *WskDeployFlags) Format() string {
 
 	flagNames := reflect.TypeOf(*flags)
diff --git a/utils/format.go b/utils/format.go
new file mode 100644
index 0000000..109f802
--- /dev/null
+++ b/utils/format.go
@@ -0,0 +1,39 @@
+/*
+ * 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 utils
+
+import (
+	"encoding/json"
+)
+
+//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 ""
+}
diff --git a/utils/misc.go b/utils/misc.go
index 81b666a..eeda747 100644
--- a/utils/misc.go
+++ b/utils/misc.go
@@ -164,6 +164,7 @@ func Read(url string) ([]byte, error) {
 	}
 }
 
+// TODO make generic and put into a separate JSON utils source file
 func GetJSONFromStrings(content []string, keyValueFormat bool) (interface{}, error) {
 	var data map[string]interface{}
 	var res interface{}
diff --git a/wski18n/i18n_ids.go b/wski18n/i18n_ids.go
index cb5b377..d670ec4 100644
--- a/wski18n/i18n_ids.go
+++ b/wski18n/i18n_ids.go
@@ -20,28 +20,30 @@ package wski18n
 // DO NOT TRANSLATE
 // descriptive key names
 const (
-	ACTIONS            = "Actions"
-	ACTIVATIONS        = "Activations"
+	//ACTIONS            = "Actions"
+	//ACTIVATIONS        = "Activations"
+	//CMD_SYNC           = "sync"
+	//NAMESPACES         = "Namespaces"
+	//PACKAGES           = "Packages"
 	API_HOST           = "API host"
 	APIGW_ACCESS_TOKEN = "API Gateway Access Token"
+	APIGW_TENANT_ID    = "API Gateway Tenant ID"
 	AUTH_KEY           = "authentication key"
-	COMMAND_LINE       = "wskdeploy command line"
+	BINDING            = "binding"
+	CLI_FLAGS          = "CLI Flags"
+	CMD_DEPLOY         = "deploy"
+	CMD_UNDEPLOY       = "undeploy"
+	COMMAND_LINE       = "command line"
 	CONFIGURATION      = "Configuration"
 	DEPLOYMENT_FILE    = "deployment file"
 	MANIFEST_FILE      = "manifest file"
 	NAME_PROJECT       = "project name"
-	NAMESPACES         = "Namespaces"
 	PACKAGE_BINDING    = "package binding"
 	PACKAGE_LICENSE    = "package license"
 	PACKAGE_VERSION    = "package version"
-	PACKAGES           = "Packages"
 	RULES              = "Rules"
 	TRIGGER_FEED       = "trigger feed"
-	CMD_DEPLOY         = "deploy"
-	CMD_UNDEPLOY       = "undeploy"
-	CMD_SYNC           = "sync"
 	TRIGGERS           = "Triggers"
-	BINDING            = "binding"
 )
 
 // DO NOT TRANSLATE
@@ -89,6 +91,7 @@ const (
 	KEY_DESTINATION       = "destination"
 	KEY_INCLUDE           = "include"
 	KEY_DUMMY_TOKEN       = "dummytoken"
+	KEY_UUID              = "uuid"
 )
 
 // DO NOT TRANSLATE
@@ -146,6 +149,7 @@ const (
 	ID_MSG_CONFIG_INFO_APIHOST_X_host_X_source_X        = "msg_config_apihost_info"
 	ID_MSG_CONFIG_INFO_AUTHKEY_X_source_X               = "msg_config_authkey_info"
 	ID_MSG_CONFIG_INFO_NAMESPACE_X_namespace_X_source_X = "msg_config_namespace_info"
+	ID_MSG_CONFIG_INFO_APIGW_TENANT_ID_X_source_X       = "msg_config_apigw_tenant_id_info"
 	ID_MSG_CONFIG_INFO_APIGE_ACCESS_TOKEN_X_source_X    = "msg_config_apigw_access_token_info"
 
 	// YAML marshal / unmarshal
diff --git a/wski18n/i18n_resources.go b/wski18n/i18n_resources.go
index 07b2822..1430566 100644
--- a/wski18n/i18n_resources.go
+++ b/wski18n/i18n_resources.go
@@ -92,12 +92,12 @@ func wski18nResourcesDe_deAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/de_DE.all.json", size: 0, mode: os.FileMode(436), modTime: time.Unix(1566374831, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/de_DE.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
 	a := &asset{bytes: bytes, info: info}
 	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\x89\x33\xeb\x9d\x64\x6c\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\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 [...]
 
 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: 21051, mode: os.FileMode(436), modTime: time.Unix(1568172362, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 21194, mode: os.FileMode(420), modTime: time.Unix(1571334180, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
@@ -132,7 +132,7 @@ func wski18nResourcesEs_esAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/es_ES.all.json", size: 0, mode: os.FileMode(436), modTime: time.Unix(1566374831, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/es_ES.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
@@ -152,7 +152,7 @@ func wski18nResourcesFr_frAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/fr_FR.all.json", size: 101, mode: os.FileMode(436), modTime: time.Unix(1566374831, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/fr_FR.all.json", size: 101, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
@@ -172,7 +172,7 @@ func wski18nResourcesIt_itAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/it_IT.all.json", size: 0, mode: os.FileMode(436), modTime: time.Unix(1566374831, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/it_IT.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
@@ -192,7 +192,7 @@ func wski18nResourcesJa_jaAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/ja_JA.all.json", size: 0, mode: os.FileMode(436), modTime: time.Unix(1566374831, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/ja_JA.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
@@ -212,7 +212,7 @@ func wski18nResourcesKo_krAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/ko_KR.all.json", size: 0, mode: os.FileMode(436), modTime: time.Unix(1566374831, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/ko_KR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
@@ -232,7 +232,7 @@ func wski18nResourcesPt_brAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/pt_BR.all.json", size: 0, mode: os.FileMode(436), modTime: time.Unix(1566374831, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/pt_BR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
@@ -252,7 +252,7 @@ func wski18nResourcesZh_hansAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/zh_Hans.all.json", size: 0, mode: os.FileMode(436), modTime: time.Unix(1566374831, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/zh_Hans.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 0)}
 	a := &asset{bytes: bytes, info: info}
 	return a, nil
 }
@@ -272,7 +272,7 @@ func wski18nResourcesZh_hantAllJson() (*asset, error) {
 		return nil, err
 	}
 
-	info := bindataFileInfo{name: "wski18n/resources/zh_Hant.all.json", size: 0, mode: os.FileMode(436), modTime: time.Unix(1566374831, 0)}
+	info := bindataFileInfo{name: "wski18n/resources/zh_Hant.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1515697090, 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 6dff755..3350db5 100644
--- a/wski18n/resources/en_US.all.json
+++ b/wski18n/resources/en_US.all.json
@@ -160,8 +160,12 @@
     "translation": "The namespace is [{{.namespace}}], from {{.source}}.\n"
   },
   {
+    "id": "msg_config_apigw_tenant_id_info",
+    "translation": "The API Gateway Tenant ID is [{{.uuid}}], from {{.source}}.\n"
+  },
+  {
     "id": "msg_config_apigw_access_token_info",
-    "translation": "The apigw access token is set, from {{.source}}.\n"
+    "translation": "The API Gateway access token is set, from {{.source}}.\n"
   },
   {
     "id": "msg_unmarshal_local",
diff --git a/wskprint/console.go b/wskprint/console.go
index 145881f..4719c39 100644
--- a/wskprint/console.go
+++ b/wskprint/console.go
@@ -111,7 +111,6 @@ func PrintlnOpenWhiskVerbose(verbose bool, message string) {
 }
 
 func PrintlnOpenWhiskTrace(trace bool, message string) {
-
 	if trace {
 		_, fname, lineNum, _ := runtime.Caller(2)
 		out := fmt.Sprintf("%s [%v]: %s\n", filepath.Base(fname), lineNum, message)