Last active
March 1, 2020 19:41
-
-
Save tobkle/d7752a19e510dfbf005a689c49759de7 to your computer and use it in GitHub Desktop.
add, update, remove now secrets as script for zeit.co
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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