CLI: implement init and bugfix .greenlockrc
This commit is contained in:
parent
5b38fe7fcd
commit
341347ba3e
|
@ -5,7 +5,7 @@ var args = process.argv.slice(2);
|
|||
var arg0 = args[0];
|
||||
//console.log(args);
|
||||
|
||||
var found = ['certonly', 'add', 'update', 'config', 'defaults', 'remove'].some(
|
||||
var found = ['certonly', 'add', 'update', 'config', 'defaults', 'remove', 'init'].some(
|
||||
function(k) {
|
||||
if (k === arg0) {
|
||||
require('./' + k);
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
'use strict';
|
||||
|
||||
var P = require('../plugins.js');
|
||||
var args = process.argv.slice(3);
|
||||
var cli = require('./lib/cli.js');
|
||||
//var path = require('path');
|
||||
//var pkgpath = path.join(__dirname, '..', 'package.json');
|
||||
//var pkgpath = path.join(process.cwd(), 'package.json');
|
||||
|
||||
var Flags = require('./lib/flags.js');
|
||||
|
||||
var flagOptions = Flags.flags();
|
||||
var myFlags = {};
|
||||
['maintainer-email', 'cluster', 'manager', 'manager-xxxx'].forEach(function(k) {
|
||||
myFlags[k] = flagOptions[k];
|
||||
});
|
||||
|
||||
cli.parse(myFlags);
|
||||
cli.main(async function(argList, flags) {
|
||||
var path = require('path');
|
||||
var pkgpath = path.join(process.cwd(), 'package.json');
|
||||
var pkgdir = path.dirname(pkgpath);
|
||||
//var rcpath = path.join(pkgpath, '.greenlockrc');
|
||||
var configFile = path.join(pkgdir, 'greenlock.d/manager.json');
|
||||
var manager = flags.manager;
|
||||
|
||||
// TODO move to bin/lib/greenlockrc.js
|
||||
if (!manager) {
|
||||
manager = 'greenlock-cloud-fs';
|
||||
if (!flags.managerOpts.configFile) {
|
||||
flags.managerOpts.configFile = configFile;
|
||||
}
|
||||
}
|
||||
if (['fs', 'cloud'].includes(manager)) {
|
||||
// TODO publish the 1st party modules under a secure namespace
|
||||
flags.manager = '@greenlock/manager-' + flags.manager;
|
||||
}
|
||||
flags.manager = flags.managerOpts;
|
||||
delete flags.managerOpts;
|
||||
flags.manager.manager = manager;
|
||||
|
||||
try {
|
||||
P._loadSync(manager);
|
||||
} catch (e) {
|
||||
try {
|
||||
P._installSync(manager);
|
||||
} catch (e) {
|
||||
console.error(
|
||||
'error:',
|
||||
JSON.stringify(manager),
|
||||
'could not be loaded, and could not be installed.'
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
var GreenlockRc = require('./lib/greenlockrc.js');
|
||||
//var rc = await GreenlockRc(pkgpath, manager, flags.manager);
|
||||
await GreenlockRc(pkgpath, manager, flags.manager);
|
||||
writeServerJs(pkgdir, flags);
|
||||
writeAppJs(pkgdir);
|
||||
|
||||
/*
|
||||
rc._bin_mode = true;
|
||||
var Greenlock = require('../');
|
||||
// this is a copy, so it's safe to modify
|
||||
var greenlock = Greenlock.create(rc);
|
||||
var mconf = await greenlock.manager.defaults();
|
||||
var flagOptions = Flags.flags(mconf, myOpts);
|
||||
*/
|
||||
}, args);
|
||||
|
||||
function writeServerJs(pkgdir, flags) {
|
||||
var serverJs = 'server.js';
|
||||
var bakTmpl = 'server-greenlock-tmpl.js';
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var tmpl = fs.readFileSync(
|
||||
path.join(__dirname, 'tmpl/server.tmpl.js'),
|
||||
'utf8'
|
||||
);
|
||||
|
||||
try {
|
||||
fs.accessSync(path.join(pkgdir, serverJs));
|
||||
console.warn(
|
||||
JSON.stringify(serverJs),
|
||||
' exists, writing to ',
|
||||
JSON.stringify(bakTmpl),
|
||||
'instead'
|
||||
);
|
||||
serverJs = bakTmpl;
|
||||
} catch (e) {
|
||||
// continue
|
||||
}
|
||||
|
||||
if (flags.cluster) {
|
||||
tmpl = tmpl.replace(
|
||||
/options.cluster = false/g,
|
||||
'options.cluster = true'
|
||||
);
|
||||
}
|
||||
if (flags.maintainerEmail) {
|
||||
tmpl = tmpl.replace(
|
||||
/pkg.author/g,
|
||||
JSON.stringify(flags.maintainerEmail)
|
||||
);
|
||||
}
|
||||
fs.writeFileSync(path.join(pkgdir, serverJs), tmpl);
|
||||
}
|
||||
|
||||
function writeAppJs(pkgdir) {
|
||||
var bakTmpl = 'app-greenlock-tmpl.js';
|
||||
var appJs = 'app.js';
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var tmpl = fs.readFileSync(
|
||||
path.join(__dirname, 'tmpl/app.tmpl.js'),
|
||||
'utf8'
|
||||
);
|
||||
|
||||
try {
|
||||
fs.accessSync(path.join(pkgdir, appJs));
|
||||
console.warn(
|
||||
JSON.stringify(appJs),
|
||||
' exists, writing to ',
|
||||
JSON.stringify(bakTmpl),
|
||||
'instead'
|
||||
);
|
||||
appJs = bakTmpl;
|
||||
} catch (e) {
|
||||
// continue
|
||||
}
|
||||
|
||||
fs.writeFileSync(path.join(pkgdir, appJs), tmpl);
|
||||
}
|
|
@ -14,7 +14,7 @@ CLI.parse = function(conf) {
|
|||
var v = conf[k];
|
||||
if (!v) {
|
||||
console.error(
|
||||
'Developer Error: missing config value for',
|
||||
'Developer Error: missing cli flag definition for',
|
||||
JSON.stringify(k)
|
||||
);
|
||||
process.exit(1);
|
||||
|
|
|
@ -7,18 +7,20 @@ var path = require('path');
|
|||
var pkgpath = path.join(process.cwd(), 'package.json');
|
||||
var GreenlockRc = require('./greenlockrc.js');
|
||||
|
||||
Flags.init = function(myOpts) {
|
||||
// These are ALL options
|
||||
// The individual CLI files each select a subset of them
|
||||
Flags.flags = function(mconf, myOpts) {
|
||||
// Current Manager Config
|
||||
if (!mconf) {
|
||||
mconf = {};
|
||||
}
|
||||
|
||||
// Extra Override Options
|
||||
if (!myOpts) {
|
||||
myOpts = {};
|
||||
}
|
||||
return GreenlockRc(pkgpath).then(async function(rc) {
|
||||
var Greenlock = require('../../');
|
||||
// this is a copy, so it's safe to modify
|
||||
rc._bin_mode = true;
|
||||
var greenlock = Greenlock.create(rc);
|
||||
var mconf = await greenlock.manager.defaults();
|
||||
|
||||
var flagOptions = {
|
||||
return {
|
||||
subject: [
|
||||
false,
|
||||
'the "subject" (primary domain) of the certificate',
|
||||
|
@ -39,6 +41,7 @@ Flags.init = function(myOpts) {
|
|||
'a list of names that matches a subject or altname',
|
||||
'string'
|
||||
],
|
||||
cluster: [false, 'initialize with cluster mode on', 'boolean', false],
|
||||
'renew-offset': [
|
||||
false,
|
||||
"time to wait until renewing the cert such as '45d' (45 days after being issued) or '-3w' (3 weeks before expiration date)",
|
||||
|
@ -55,6 +58,11 @@ Flags.init = function(myOpts) {
|
|||
"the email address of the Let's Encrypt or ACME Account subscriber (not necessarily the domain owner)",
|
||||
'string'
|
||||
],
|
||||
'maintainer-email': [
|
||||
false,
|
||||
'the maintainance contact for security and critical bug notices',
|
||||
'string'
|
||||
],
|
||||
'account-key-type': [
|
||||
false,
|
||||
"either 'P-256' (ECDSA) or 'RSA-2048' - although other values are technically supported, they don't make sense and won't work with many services (More bits != More security)",
|
||||
|
@ -78,6 +86,17 @@ Flags.init = function(myOpts) {
|
|||
'an option for the chosen store module, such as --store-apikey or --store-bucket',
|
||||
'bag'
|
||||
],
|
||||
manager: [
|
||||
false,
|
||||
'the module name or file path of the manager module to use',
|
||||
'string',
|
||||
'greenlock-manager-fs'
|
||||
],
|
||||
'manager-xxxx': [
|
||||
false,
|
||||
'an option for the chosen manager module, such as --manager-apikey or --manager-dburl',
|
||||
'bag'
|
||||
],
|
||||
challenge: [
|
||||
false,
|
||||
'the module name or file path of the HTTP-01, DNS-01, or TLS-ALPN-01 challenge module to use',
|
||||
|
@ -142,7 +161,16 @@ Flags.init = function(myOpts) {
|
|||
myOpts.forceSave || false
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
Flags.init = function(myOpts) {
|
||||
return GreenlockRc(pkgpath).then(async function(rc) {
|
||||
rc._bin_mode = true;
|
||||
var Greenlock = require('../../');
|
||||
// this is a copy, so it's safe to modify
|
||||
var greenlock = Greenlock.create(rc);
|
||||
var mconf = await greenlock.manager.defaults();
|
||||
var flagOptions = Flags.flags(mconf, myOpts);
|
||||
return {
|
||||
flagOptions,
|
||||
rc,
|
||||
|
|
|
@ -89,7 +89,7 @@ module.exports = async function(pkgpath, manager, rc) {
|
|||
if (rc) {
|
||||
changed = true;
|
||||
Object.keys(rc).forEach(function(k) {
|
||||
_rc[k] = rc;
|
||||
_rc[k] = rc[k];
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
// Here's a vanilla HTTP app to start,
|
||||
// but feel free to replace it with Express, Koa, etc
|
||||
var app = function(req, res) {
|
||||
res.end('Hello, Encrypted World!');
|
||||
};
|
||||
|
||||
module.exports = app;
|
|
@ -0,0 +1,36 @@
|
|||
'use strict';
|
||||
|
||||
require('greenlock-express')
|
||||
.init(function() {
|
||||
// .greenlockrc defines which manager to use
|
||||
// (i.e. greenlock-manager-fs or greenlock-manager-cloud)
|
||||
var options = getGreenlockRc() || {};
|
||||
|
||||
// name & version for ACME client user agent
|
||||
var pkg = require('./package.json');
|
||||
options.packageAgent = pkg.name + '/' + pkg.version;
|
||||
|
||||
// contact for security and critical bug notices
|
||||
options.maintainerEmail = pkg.author;
|
||||
|
||||
// whether or not to run at cloudscale
|
||||
options.cluster = false;
|
||||
|
||||
return options;
|
||||
})
|
||||
.ready(function(glx) {
|
||||
var app = require('./app.js');
|
||||
|
||||
// Serves on 80 and 443
|
||||
// Get's SSL certificates magically!
|
||||
glx.serveApp(app);
|
||||
});
|
||||
|
||||
function getGreenlockRc() {
|
||||
// The RC file is also used by the (optional) CLI and (optional) Web GUI.
|
||||
// You are free to forego CLI and GUI support.
|
||||
var fs = require('fs');
|
||||
var rcPath = '.greenlockrc';
|
||||
var rc = fs.readFileSync(rcPath, 'utf8');
|
||||
return JSON.parse(rc);
|
||||
}
|
|
@ -208,6 +208,11 @@ P._loadSync = function(modname) {
|
|||
};
|
||||
|
||||
P._installSync = function(moduleName) {
|
||||
try {
|
||||
return require(moduleName);
|
||||
} catch (e) {
|
||||
// continue
|
||||
}
|
||||
var npm = 'npm';
|
||||
var args = ['install', '--save', moduleName];
|
||||
var out = '';
|
||||
|
|
|
@ -14,13 +14,13 @@ node bin/greenlock.js defaults
|
|||
node bin/greenlock.js defaults --challenge-dns-01 foo-http-01-bar --challenge-dns-01-token BIG_TOKEN
|
||||
# using --challenge is exclusive (will delete things not mentioned)
|
||||
node bin/greenlock.js defaults --challenge acme-http-01-standalone
|
||||
node bin/greenlock.js remove --subject example.com
|
||||
# should delete all and add just this one anew
|
||||
node bin/greenlock.js update --subject example.com --challenge bar-http-01-baz
|
||||
# should add, leaving the existing
|
||||
node bin/greenlock.js update --subject example.com --challenge-dns-01 baz-dns-01-qux --challenge-dns-01-token BIG_TOKEN
|
||||
# should delete all and add just this one anew
|
||||
node bin/greenlock.js update --subject example.com --challenge bar-http-01-baz
|
||||
node bin/greenlock.js remove --subject example.com
|
||||
|
||||
# TODO test for failure
|
||||
# node bin/greenlock.js add --subject example.com
|
||||
|
|
Loading…
Reference in New Issue