You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by al...@apache.org on 2020/07/16 06:31:38 UTC

[openwhisk-wskdebug] branch dotenv created (now 3333b2e)

This is an automated email from the ASF dual-hosted git repository.

alexkli pushed a change to branch dotenv
in repository https://gitbox.apache.org/repos/asf/openwhisk-wskdebug.git.


      at 3333b2e  support openwhisk credentials stored in .env file and Adobe I/O Runtime variable names

This branch includes the following new commits:

     new f3e59bf  in verbose mode log where openwhisk credentials are picked up from
     new 3333b2e  support openwhisk credentials stored in .env file and Adobe I/O Runtime variable names

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[openwhisk-wskdebug] 02/02: support openwhisk credentials stored in .env file and Adobe I/O Runtime variable names

Posted by al...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

alexkli pushed a commit to branch dotenv
in repository https://gitbox.apache.org/repos/asf/openwhisk-wskdebug.git

commit 3333b2ec074d0f43df68582fe7c0e2adbb996cce
Author: Alexander Klimetschek <ak...@adobe.com>
AuthorDate: Wed Jul 15 23:31:12 2020 -0700

    support openwhisk credentials stored in .env file and Adobe I/O Runtime variable names
---
 .gitignore            |   2 +
 package-lock.json     |  11 ++++
 package.json          |   2 +
 src/debugger.js       |   4 ++
 src/wskprops.js       |  28 +++++----
 test/wskprops.test.js | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 195 insertions(+), 10 deletions(-)

diff --git a/.gitignore b/.gitignore
index 73ce74b..aa36988 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,3 +15,5 @@ coverage
 build
 coverage.lcov
 test-results
+
+.env
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index a39ebd8..ec6eb41 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -824,6 +824,11 @@
                 "esutils": "^2.0.2"
             }
         },
+        "dotenv": {
+            "version": "8.2.0",
+            "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
+            "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw=="
+        },
         "emoji-regex": {
             "version": "8.0.0",
             "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -2353,6 +2358,12 @@
                 }
             }
         },
+        "mock-fs": {
+            "version": "4.12.0",
+            "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.12.0.tgz",
+            "integrity": "sha512-/P/HtrlvBxY4o/PzXY9cCNBrdylDNxg7gnrv2sMNxj+UJ2m8jSpl0/A6fuJeNAWr99ZvGWH8XCbE0vmnM5KupQ==",
+            "dev": true
+        },
         "mock-require": {
             "version": "3.0.3",
             "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz",
diff --git a/package.json b/package.json
index f53afc3..cac0c22 100644
--- a/package.json
+++ b/package.json
@@ -46,6 +46,7 @@
         "clone": "^2.1.2",
         "debug": "^4.1.1",
         "dockerode": "^3.2.0",
+        "dotenv": "^8.2.0",
         "fetch-retry": "^3.1.0",
         "fs-extra": "^8.1.0",
         "get-port": "^5.1.1",
@@ -69,6 +70,7 @@
         "eslint-plugin-mocha": "^6.3.0",
         "mocha": "^7.1.0",
         "mocha-multi-reporters": "^1.1.7",
+        "mock-fs": "^4.12.0",
         "mock-require": "^3.0.3",
         "nock": "^12.0.2",
         "nyc": "^15.0.0",
diff --git a/src/debugger.js b/src/debugger.js
index e3b282e..f2e1596 100644
--- a/src/debugger.js
+++ b/src/debugger.js
@@ -54,6 +54,10 @@ class Debugger {
         this.actionName = argv.action;
 
         this.wskProps = wskprops.get();
+        if (Object.keys(this.wskProps).length === 0) {
+            log.error(`Error: Missing openwhisk credentials. Found no ~/.wskprops file or WSK_* environment variable.`);
+            process.exit(1);
+        }
         if (argv.ignoreCerts) {
             this.wskProps.ignore_certs = true;
         }
diff --git a/src/wskprops.js b/src/wskprops.js
index 4ea744d..310b2bb 100644
--- a/src/wskprops.js
+++ b/src/wskprops.js
@@ -23,6 +23,7 @@
 
 const log = require('./log');
 
+const dotenv = require('dotenv');
 const path = require('path');
 const fs = require('fs-extra');
 
@@ -58,35 +59,42 @@ function getWskProps() {
     return wskProps;
 }
 
+function getAioEnvProps() {
+    const envProps = {};
+    // do first, as OW_* ones later shall take precedence
+    if (process.env.AIO_runtime_auth) {
+        envProps.apihost = "https://adobeioruntime.net";
+        envProps.auth = process.env.AIO_runtime_auth;
+        envProps.namespace = process.env.AIO_runtime_namespace;
+        log.verbose(`Using openwhisk credential from AIO_runtime_auth environment variable`);
+    }
+    return envProps;
+}
+
 function getWskEnvProps() {
     const envProps = {};
-    let authEnvVar;
     ENV_PARAMS.forEach((envName) => {
         if (process.env[envName]) {
             const key = envName.slice(3).toLowerCase();
             envProps[key] = process.env[envName];
             if (key === "auth" || key === "api_key") {
-                authEnvVar = envName;
+                log.verbose(`Using openwhisk credential from ${envName} environment variable`);
             }
         }
     });
-    if (authEnvVar) {
-        log.verbose(`Using openwhisk credential from ${authEnvVar} environment variable`);
-    }
     return envProps;
 }
 
 module.exports = {
     get() {
-        const props = Object.assign(getWskProps(), getWskEnvProps());
+        // load .env file if present
+        dotenv.config();
+
+        const props = Object.assign(getAioEnvProps(), getWskProps(), getWskEnvProps());
         if (props.auth) {
             props.api_key = props.auth;
             delete props.auth;
         }
-        if (Object.keys(props).length === 0) {
-            log.error(`Error: Missing openwhisk credentials. Found no ~/.wskprops file or WSK_* environment variable.`);
-            process.exit(1);
-        }
         return props;
     },
     ENV_PARAMS,
diff --git a/test/wskprops.test.js b/test/wskprops.test.js
new file mode 100644
index 0000000..fe2af13
--- /dev/null
+++ b/test/wskprops.test.js
@@ -0,0 +1,158 @@
+/*
+ * 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.
+ */
+
+
+/* eslint-env mocha */
+
+'use strict';
+
+const wskprops = require('../src/wskprops');
+const assert = require('assert');
+const mockFs = require('mock-fs');
+const os = require('os');
+
+function resetEnvVars() {
+    delete process.env.OW_AUTH;
+    delete process.env.OW_NAMESPACE;
+    delete process.env.OW_APIHOST;
+    delete process.env.WSK_CONFIG_FILE;
+    delete process.env.AIO_runtime_auth;
+    delete process.env.AIO_runtime_namespace;
+}
+
+describe('wskprops', function() {
+
+    beforeEach(function() {
+        resetEnvVars();
+    });
+
+    afterEach(function() {
+        resetEnvVars();
+        mockFs.restore();
+    });
+
+    it("should read WSK_CONFIG_FILE", async function() {
+        process.env.WSK_CONFIG_FILE = "test/wskprops";
+
+        const props = wskprops.get();
+        assert.strictEqual(props.apihost, "https://example.com");
+        assert.strictEqual(props.namespace, "test");
+        assert.strictEqual(props.api_key, "super-secret-key");
+    });
+
+    it("should read ~/.wskprops", async function() {
+        mockFs({
+            [`${os.homedir()}/.wskprops`]:
+`APIHOST=https://home-wskprops
+NAMESPACE=home-wskprops-namespace
+AUTH=home-wskprops-auth`
+        });
+
+        const props = wskprops.get();
+        assert.strictEqual(props.apihost, "https://home-wskprops");
+        assert.strictEqual(props.namespace, "home-wskprops-namespace");
+        assert.strictEqual(props.api_key, "home-wskprops-auth");
+    });
+
+    it("should read OW_* vars", async function() {
+        process.env.OW_APIHOST = "https://ow_apihost";
+        process.env.OW_NAMESPACE = "ow_namespace";
+        process.env.OW_AUTH = "ow_auth";
+
+        const props = wskprops.get();
+        assert.strictEqual(props.apihost, "https://ow_apihost");
+        assert.strictEqual(props.namespace, "ow_namespace");
+        assert.strictEqual(props.api_key, "ow_auth");
+    });
+
+    it("should give OW_* vars precedence over WSK_CONFIG_FILE", async function() {
+        process.env.WSK_CONFIG_FILE = "test/wskprops";
+
+        process.env.OW_APIHOST = "https://ow_apihost";
+        process.env.OW_NAMESPACE = "ow_namespace";
+        process.env.OW_AUTH = "ow_auth";
+
+        const props = wskprops.get();
+        assert.strictEqual(props.apihost, "https://ow_apihost");
+        assert.strictEqual(props.namespace, "ow_namespace");
+        assert.strictEqual(props.api_key, "ow_auth");
+    });
+
+    it("should read AIO_* vars", async function() {
+        process.env.AIO_runtime_namespace = "aio_namespace";
+        process.env.AIO_runtime_auth = "aio_auth";
+
+        const props = wskprops.get();
+        assert.strictEqual(props.apihost, "https://adobeioruntime.net");
+        assert.strictEqual(props.namespace, "aio_namespace");
+        assert.strictEqual(props.api_key, "aio_auth");
+    });
+
+    it("should give WSK_CONFIG_FILE precedence over AIO_* vars", async function() {
+        process.env.WSK_CONFIG_FILE = "test/wskprops";
+        process.env.AIO_runtime_namespace = "aio_namespace";
+        process.env.AIO_runtime_auth = "aio_auth";
+
+        const props = wskprops.get();
+        assert.strictEqual(props.apihost, "https://example.com");
+        assert.strictEqual(props.namespace, "test");
+        assert.strictEqual(props.api_key, "super-secret-key");
+    });
+
+    it("should give OW_* precedence over AIO_* vars", async function() {
+        process.env.AIO_runtime_namespace = "aio_namespace";
+        process.env.AIO_runtime_auth = "aio_auth";
+
+        process.env.OW_APIHOST = "https://ow_apihost";
+        process.env.OW_NAMESPACE = "ow_namespace";
+        process.env.OW_AUTH = "ow_auth";
+
+        const props = wskprops.get();
+        assert.strictEqual(props.apihost, "https://ow_apihost");
+        assert.strictEqual(props.namespace, "ow_namespace");
+        assert.strictEqual(props.api_key, "ow_auth");
+    });
+
+    it("should read AIO_* from .env", async function() {
+        mockFs({
+            ".env":
+`AIO_runtime_namespace=aio_namespace
+AIO_runtime_auth=aio_auth`
+        });
+
+        const props = wskprops.get();
+        assert.strictEqual(props.apihost, "https://adobeioruntime.net");
+        assert.strictEqual(props.namespace, "aio_namespace");
+        assert.strictEqual(props.api_key, "aio_auth");
+    });
+
+    it("should read WSK_CONFIG_FILE from .env", async function() {
+        mockFs({
+            ".env": "WSK_CONFIG_FILE=mywskprops",
+            "mywskprops":
+`APIHOST=https://example.com
+NAMESPACE=test
+AUTH=super-secret-key`
+        });
+
+        const props = wskprops.get();
+        assert.strictEqual(props.apihost, "https://example.com");
+        assert.strictEqual(props.namespace, "test");
+        assert.strictEqual(props.api_key, "super-secret-key");
+    });
+
+});


[openwhisk-wskdebug] 01/02: in verbose mode log where openwhisk credentials are picked up from

Posted by al...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

alexkli pushed a commit to branch dotenv
in repository https://gitbox.apache.org/repos/asf/openwhisk-wskdebug.git

commit f3e59bf827ffc30fc2e2f372e41688a84005b7f2
Author: Alexander Klimetschek <ak...@adobe.com>
AuthorDate: Wed Jul 15 22:30:46 2020 -0700

    in verbose mode log where openwhisk credentials are picked up from
---
 src/debugger.js |  4 ----
 src/wskprops.js | 25 +++++++++++++++++++++----
 test/test.js    |  4 ++++
 3 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/src/debugger.js b/src/debugger.js
index f2e1596..e3b282e 100644
--- a/src/debugger.js
+++ b/src/debugger.js
@@ -54,10 +54,6 @@ class Debugger {
         this.actionName = argv.action;
 
         this.wskProps = wskprops.get();
-        if (Object.keys(this.wskProps).length === 0) {
-            log.error(`Error: Missing openwhisk credentials. Found no ~/.wskprops file or WSK_* environment variable.`);
-            process.exit(1);
-        }
         if (argv.ignoreCerts) {
             this.wskProps.ignore_certs = true;
         }
diff --git a/src/wskprops.js b/src/wskprops.js
index 4f4c8fb..4ea744d 100644
--- a/src/wskprops.js
+++ b/src/wskprops.js
@@ -21,20 +21,23 @@
 
 'use strict';
 
+const log = require('./log');
+
 const path = require('path');
 const fs = require('fs-extra');
 
 const ENV_PARAMS = ['OW_APIHOST', 'OW_AUTH', 'OW_NAMESPACE', 'OW_APIGW_ACCESS_TOKEN'];
 
-function getWskPropsFile() {
+function getWskPropsUserHomeFile() {
     const Home = process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME'];
-    return process.env.WSK_CONFIG_FILE || path.format({ dir: Home, base: '.wskprops' });
+    return path.format({ dir: Home, base: '.wskprops' });
 }
 
 function readWskPropsFile() {
-    const wskFilePath = getWskPropsFile();
+    const wskFilePath = process.env.WSK_CONFIG_FILE || getWskPropsUserHomeFile();
 
     if (fs.existsSync(wskFilePath)) {
+        log.verbose(`Using openwhisk credentials from ${wskFilePath}${process.env.WSK_CONFIG_FILE ? " (set by WSK_CONFIG_FILE)" : ""}`);
         return fs.readFileSync(wskFilePath, 'utf8');
     } else {
         return null;
@@ -57,9 +60,19 @@ function getWskProps() {
 
 function getWskEnvProps() {
     const envProps = {};
+    let authEnvVar;
     ENV_PARAMS.forEach((envName) => {
-        if (process.env[envName]) envProps[envName.slice(3).toLowerCase()] = process.env[envName];
+        if (process.env[envName]) {
+            const key = envName.slice(3).toLowerCase();
+            envProps[key] = process.env[envName];
+            if (key === "auth" || key === "api_key") {
+                authEnvVar = envName;
+            }
+        }
     });
+    if (authEnvVar) {
+        log.verbose(`Using openwhisk credential from ${authEnvVar} environment variable`);
+    }
     return envProps;
 }
 
@@ -70,6 +83,10 @@ module.exports = {
             props.api_key = props.auth;
             delete props.auth;
         }
+        if (Object.keys(props).length === 0) {
+            log.error(`Error: Missing openwhisk credentials. Found no ~/.wskprops file or WSK_* environment variable.`);
+            process.exit(1);
+        }
         return props;
     },
     ENV_PARAMS,
diff --git a/test/test.js b/test/test.js
index 3d501ea..ce8904d 100644
--- a/test/test.js
+++ b/test/test.js
@@ -41,7 +41,11 @@ function isDockerInstalled() {
 }
 
 async function beforeEach() {
+    delete process.env.OW_AUTH;
+    delete process.env.OW_NAMESPACE;
+    delete process.env.OW_APIHOST;
     process.env.WSK_CONFIG_FILE = path.join(process.cwd(), "test/wskprops");
+
     openwhisk = nock(FAKE_OPENWHISK_SERVER);
     mockOpenwhiskSwagger(openwhisk);