openwhisk-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From alex...@apache.org
Subject [openwhisk-wskdebug] 02/02: support openwhisk credentials stored in .env file and Adobe I/O Runtime variable names
Date Thu, 16 Jul 2020 06:31:40 GMT
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 <aklimets@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");
+    });
+
+});


Mime
View raw message