mothership-client
Advanced tools
Comparing version 2.0.0 to 3.0.0
const _get = require('lodash/get'); | ||
const got = require('got'); | ||
const debug = require('debug')('mothership:client'); | ||
const fs = require('fs'); | ||
const Util = require('util'); | ||
const readFileAsync = Util.promisify(fs.readFile); | ||
const MOTHERHIP_BASE_URL = process.env.MOTHERSHIP_BASE_URL || 'https://app.mothership.cloud'; | ||
const syncRequest = require('sync-request'); | ||
const asyncRequest = got.extend({ | ||
@@ -13,13 +16,31 @@ json: true | ||
let config = null; | ||
let refreshIntervalSecs = 600; // 10 minutes (in seconds) | ||
function init(key, opts) { | ||
async function init(key, opts) { | ||
if (typeof key === 'object') { | ||
key = key.key; | ||
opts = key; | ||
key = opts.key; | ||
} | ||
opts = { | ||
sync: false, | ||
...opts | ||
}; | ||
if (process.env.MOTHERSHIP_KEY) { | ||
key = process.env.MOTHERSHIP_KEY; | ||
} | ||
// Load key from file if present | ||
if (opts.keyPath || process.env.MOTHERSHIP_KEY_PATH) { | ||
try { | ||
key = await readFileAsync(opts.keyPath || process.env.MOTHERSHIP_KEY_PATH); | ||
} catch (err) { | ||
configError(err) | ||
} | ||
} | ||
if (opts.refreshInterval) { | ||
refreshIntervalSecs = opts.refreshInterval; | ||
} | ||
// Ensure we don't re-use a previous config | ||
@@ -33,28 +54,17 @@ config = null; | ||
if (opts.sync) { | ||
return config = syncClient(configUrl, headers); | ||
} | ||
// Can't use async/await here, since function can be either sync or async | ||
return asyncClient(configUrl, headers).then(body => { | ||
return config = body; | ||
}); | ||
} | ||
await fetchConfig(configUrl, headers); | ||
function syncClient(url, headers) { | ||
try { | ||
let resp = syncRequest('GET', url, { headers }); | ||
return JSON.parse(resp.getBody('utf-8')); | ||
} catch (err) { | ||
configError(err); | ||
} | ||
return { get }; | ||
} | ||
async function asyncClient(url, headers) { | ||
async function fetchConfig(url, headers) { | ||
try { | ||
let resp = await asyncRequest.get(url, { headers }); | ||
return resp.body; | ||
config = resp.body; | ||
} catch (err) { | ||
configError(err); | ||
} | ||
setTimeout(fetchConfig.bind(null, url, headers), refreshIntervalSecs * 1000); | ||
} | ||
@@ -68,2 +78,6 @@ | ||
function get(path, defaultVal) { | ||
if (!config) { | ||
configError(new Error('Config not initialized. Please run init() first.')); | ||
} | ||
if (path) { | ||
@@ -70,0 +84,0 @@ return _get(config, path, defaultVal); |
{ | ||
"name": "mothership-client", | ||
"version": "2.0.0", | ||
"version": "3.0.0", | ||
"description": "Node.js client for loading config data from Mothership", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "DEBUG=mothership ava" | ||
"test": "DEBUG=mothership nyc --check-coverage ava --serial --timeout=15s" | ||
}, | ||
@@ -27,11 +27,13 @@ "repository": { | ||
"got": "^9.6.0", | ||
"lodash": "^4.17.11", | ||
"lodash": "^4.17.15", | ||
"sync-request": "^6.0.0" | ||
}, | ||
"devDependencies": { | ||
"ava": "^1.4.1", | ||
"ava": "^3.7.1", | ||
"body-parser": "^1.18.3", | ||
"delay": "^4.3.0", | ||
"express": "^4.16.4", | ||
"morgan": "^1.9.1", | ||
"nock": "^10.0.1" | ||
"nock": "^10.0.1", | ||
"nyc": "^15.0.1" | ||
}, | ||
@@ -38,0 +40,0 @@ "files": [ |
@@ -17,3 +17,3 @@ # mothership-client | ||
> If you're upgrading from v1.x, see the [upgrading](#upgrading) section at the bottom of this doc. | ||
> If you're upgrading from v1.x or v2.x, see the [upgrading](#upgrading) section at the bottom of this doc. | ||
@@ -27,14 +27,22 @@ Since most configuration values are needed during intial bootstrap of an app, this | ||
const mothership = require('mothership-client'); | ||
const config = mothership.init('<config-key>'); | ||
const config = await mothership.init('<config-key>'); | ||
``` | ||
Then simply reference your config like: `config.someKey`; | ||
or, set the `MOTHERSHIP_KEY` environment variable: | ||
When you need config in another module, simply require the module and call `get()`: | ||
``` | ||
MOTHERSHIP_KEY=my_key | ||
... | ||
const config = await mothership.init(); | ||
``` | ||
Then simply reference your config like: `config.get('someKey')`; | ||
When you need config in another module, simply require the module and call `mothership.get('anotherKey')`: | ||
``` | ||
const config = require('mothership-client').get(); | ||
const config = require('mothership-client').get('anotherKey); | ||
``` | ||
Or, if you want a specific portion of the config object, you can use `lodash` dotted-notation syntax, and even specify a default if the key isn't found: | ||
The Mothership client uses `lodash` dotted-notation syntax for fetching keys, and even allows specifying a default value if the key isn't found: | ||
@@ -45,2 +53,28 @@ ``` | ||
You can grab the entire config at once; however, we don't recommend doing this, as Mothership will refresh the config periodically, so you could end up with stale values. | ||
### Loading the config key from a file / secret | ||
Given the rise of Kubernetes, there are cases where you may want to provide the Mothership config key via a mounted secret rather than as a string value or environment variable. In such a case, simply tell Mothership where to find the secret file on disk via either: | ||
``` | ||
const config = await mothership.init({ keyPath: '/absolute/path/to/secret/file' }); | ||
``` | ||
or using the environment variable | ||
``` | ||
MOTHERSHIP_KEY_PATH=/absolute/path/to/secret/file | ||
``` | ||
Mothership will use the contents of the file as the key during initialization. | ||
### Configuration auto-refresh | ||
By default, Mothership auto-refreshes the local configuration cache every ten minutes. This ensures that changes made from the Mothership dashboard will propagate to connected applications. | ||
If you want to adjust the refresh frequency, provide the desired frequency (in seconds) as an option during initialization: | ||
``` | ||
const config = await mothership.init({ refreshInterval: 60 }); | ||
``` | ||
For more info, see [our documentation](https://docs.mothership.cloud). | ||
@@ -50,2 +84,5 @@ | ||
### To v3.x | ||
Version 3.x removes the synchronous mode entirely. Calling `init()` returns a Promise that resolves when the config is loaded (e.g. `await mothership.init('config-key')`). If you need synchronous mode, stick with v2.x. Though, do [drop us a line](https://support.mothership.cloud) so we can better understand your use-case! | ||
### To v2.x | ||
@@ -52,0 +89,0 @@ The release of v2.x enables both synchronous and asynchronus modes of operation. v1.x only supported synchronous mode, which was incompatible with some platforms. |
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
7566
69
93
7
6
Updatedlodash@^4.17.15