Skip to content

Instantly share code, notes, and snippets.

@tobkle
Last active March 1, 2020 19:41
Show Gist options
  • Save tobkle/d7752a19e510dfbf005a689c49759de7 to your computer and use it in GitHub Desktop.
Save tobkle/d7752a19e510dfbf005a689c49759de7 to your computer and use it in GitHub Desktop.
add, update, remove now secrets as script for zeit.co
#!/usr/bin/env node
/**
* Shell script reads now.json and .env.build files
* to add, update, remove Zeit.co now secrets
*
* Usage:
* ./now_secrets add
* ./now_secrets update
* ./now_secrets remove
*
* Don't forget to set execute permissions:
* > chmod +x now_secrets
*
* Adding private or public keys or certificates into .env.build
* like so:
* > cat ./private.pem | base64
* as it contains newlines, copy the output into the .env.build
* PRIVATE_KEY="the base64 encoded string"
*
* In node.js code read it like so...
* const atob = require('atob');
* const privateKey = atob(process.env.private_key);
* then do something with your privateKey
*
* https://github.com/zeit/now/issues/749
*/
const fs = require('fs');
const util = require('util');
const exec = util.promisify(require('child_process').exec);
const args = process.argv.slice(2);
if (!args.length) {
console.log(`
Usage:
./now_secrets add
./now_secrets update
./now_secrets remove
`);
return;
}
// reads file now.json with secret-key-names
const nowJson = require('./now.json');
if (!nowJson) {
console.log(`Please edit your "now.json" file.`);
return;
}
// reads file .env.build with secret-values
const filename = '.env';
const envBuf = fs.readFileSync(`${__dirname}/${filename}`, 'utf8');
const env = envBuf.toString();
if (!env) {
console.log(`Please edit your ".env" file.`);
return;
}
function uncomment(word) {
let len = word.length;
let newWord = '';
// start and end of String whether a " or a '
if (
(word[0] === '"' || word[0] === "'") &&
(word[len - 1] === '"' || word[len - 1] === "'")
) {
for (let i = 1; i < (len - 1); i++) {
newWord = newWord.concat(word[i]);
}
} else {
newWord = word;
}
return newWord;
}
// convert strings into json
const lines = env.split('\n');
//const uncomment = /^\"(.*)\"$/gi;
const unat = /^@(.*)$/;
const kv = {};
lines.map((line) => {
const k = line.split(/=(.+)/);
const key = k[0];
const value = uncomment(k[1]); //.match(uncomment)[1];
kv[key] = value;
});
const keys = nowJson.env;
const secrets = Object.keys(keys);
// executs shell command: like `now secret add <secret-key> <secret-value>`
async function run_command(command) {
try {
console.log(`${command}`);
const { stdout, stderr } = await exec(command);
console.log(`${stdout}${stderr}`);
} catch (error) {
console.log(`${error.message}`);
}
}
// loops over all found secrets
secrets.forEach(async (secret) => {
// if there is no '@' included it contains no secret key
if (keys[secret].indexOf('@') < 0) {
console.log(`Skipping ${keys[secret]} as it contains no secret.`)
return;
}
const keyname = keys[secret].match(unat)[1];
const keysecret = kv[secret];
// handle shell arguments: add, update, remove secrets
switch (args[0]) {
case 'add':
await run_command(`now secrets add ${keyname} "${keysecret}"`);
break;
case 'update':
await run_command(`now secrets rm -y ${keyname}`);
await run_command(`now secrets add ${keyname} "${keysecret}"`);
break;
case 'remove':
await run_command(`now secrets rm -y ${keyname}`);
break;
default:
await run_command(`now secrets add ${keyname} "${keysecret}"`);
break;
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment