template improvements
This commit is contained in:
parent
4dc324f26f
commit
8f3872e82e
|
@ -464,7 +464,7 @@ This is what keeps the mapping of domains <-> certificates.
|
|||
In many cases it will interact with the same database as the Key & Cert Store, and probably the code as well.
|
||||
|
||||
- set({ subject, altnames, renewAt })
|
||||
- find({ altnames, renewBefore })
|
||||
- find({ servernames, renewBefore })
|
||||
```js
|
||||
// should return a list of site configs:
|
||||
[
|
||||
|
|
|
@ -49,7 +49,7 @@ cli.main(async function(argList, flags) {
|
|||
}
|
||||
}
|
||||
|
||||
var GreenlockRc = require('./lib/greenlockrc.js');
|
||||
var GreenlockRc = require('../greenlockrc.js');
|
||||
//var rc = await GreenlockRc(pkgpath, manager, flags.manager);
|
||||
await GreenlockRc(pkgpath, manager, flags.manager);
|
||||
writeGreenlockJs(pkgdir, flags);
|
||||
|
|
|
@ -5,7 +5,7 @@ var Flags = module.exports;
|
|||
var path = require('path');
|
||||
//var pkgpath = path.join(__dirname, '..', 'package.json');
|
||||
var pkgpath = path.join(process.cwd(), 'package.json');
|
||||
var GreenlockRc = require('./greenlockrc.js');
|
||||
var GreenlockRc = require('../../greenlockrc.js');
|
||||
|
||||
// These are ALL options
|
||||
// The individual CLI files each select a subset of them
|
||||
|
@ -168,11 +168,12 @@ Flags.flags = function(mconf, myOpts) {
|
|||
};
|
||||
};
|
||||
|
||||
Flags.init = function(myOpts) {
|
||||
return GreenlockRc(pkgpath).then(async function(rc) {
|
||||
Flags.init = async function(myOpts) {
|
||||
var rc = await GreenlockRc(pkgpath);
|
||||
rc._bin_mode = true;
|
||||
var Greenlock = require('../../');
|
||||
// this is a copy, so it's safe to modify
|
||||
rc.packageRoot = path.dirname(pkgpath);
|
||||
var greenlock = Greenlock.create(rc);
|
||||
var mconf = await greenlock.manager.defaults();
|
||||
var flagOptions = Flags.flags(mconf, myOpts);
|
||||
|
@ -182,7 +183,6 @@ Flags.init = function(myOpts) {
|
|||
greenlock,
|
||||
mconf
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
Flags.mangleFlags = function(flags, mconf, sconf, extras) {
|
||||
|
|
|
@ -1,114 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
// TODO how to handle path differences when run from npx vs when required by greenlock?
|
||||
|
||||
var promisify = require('util').promisify;
|
||||
var fs = require('fs');
|
||||
var readFile = promisify(fs.readFile);
|
||||
var writeFile = promisify(fs.writeFile);
|
||||
var chmodFile = promisify(fs.chmod);
|
||||
var path = require('path');
|
||||
|
||||
function saveFile(rcpath, data, enc) {
|
||||
// because this may have a database url or some such
|
||||
return writeFile(rcpath, data, enc).then(function() {
|
||||
return chmodFile(rcpath, parseInt('0600', 8));
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = async function(pkgpath, manager, rc) {
|
||||
// TODO when run from package
|
||||
// Run from the package root (assumed) or exit
|
||||
var pkgdir = path.dirname(pkgpath);
|
||||
var rcpath = path.join(pkgdir, '.greenlockrc');
|
||||
var created = false;
|
||||
|
||||
try {
|
||||
require(pkgpath);
|
||||
} catch (e) {
|
||||
console.error(
|
||||
'npx greenlock must be run from the package root (where package.json is)'
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (manager) {
|
||||
if ('.' === manager[0]) {
|
||||
manager = path.resolve(pkgdir, manager);
|
||||
}
|
||||
try {
|
||||
require(manager);
|
||||
} catch (e) {
|
||||
console.error('npx greenlock must be run from the package root');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
var _data = await readFile(rcpath, 'utf8').catch(function(err) {
|
||||
if ('ENOENT' !== err.code) {
|
||||
throw err;
|
||||
}
|
||||
console.info('Creating ' + rcpath);
|
||||
created = true;
|
||||
var data = '{}';
|
||||
return saveFile(rcpath, data, 'utf8').then(function() {
|
||||
return data;
|
||||
});
|
||||
});
|
||||
|
||||
var changed;
|
||||
var _rc;
|
||||
try {
|
||||
_rc = JSON.parse(_data);
|
||||
} catch (e) {
|
||||
console.error("couldn't parse " + rcpath, _data);
|
||||
console.error('(perhaps you should just delete it and try again?)');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (manager) {
|
||||
if (!_rc.manager) {
|
||||
_rc.manager = manager;
|
||||
}
|
||||
if (_rc.manager !== manager) {
|
||||
console.info('Switching manager:');
|
||||
var older = _rc.manager;
|
||||
var newer = manager;
|
||||
if ('/' === older[0]) {
|
||||
older = path.relative(pkgdir, older);
|
||||
}
|
||||
if ('/' === newer[0]) {
|
||||
newer = path.relative(pkgdir, newer);
|
||||
}
|
||||
console.info('\told: ' + older);
|
||||
console.info('\tnew: ' + newer);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (rc) {
|
||||
changed = true;
|
||||
Object.keys(rc).forEach(function(k) {
|
||||
_rc[k] = rc[k];
|
||||
});
|
||||
}
|
||||
|
||||
if (['@greenlock/manager', 'greenlock-manager-fs'].includes(_rc.manager)) {
|
||||
if (!_rc.configFile) {
|
||||
changed = true;
|
||||
_rc.configFile = path.join(pkgdir, 'greenlock.json');
|
||||
}
|
||||
}
|
||||
|
||||
if (!changed) {
|
||||
return _rc;
|
||||
}
|
||||
|
||||
var data = JSON.stringify(_rc, null, 2);
|
||||
if (created) {
|
||||
console.info('Wrote ' + rcpath);
|
||||
}
|
||||
return saveFile(rcpath, data, 'utf8').then(function() {
|
||||
return _rc;
|
||||
});
|
||||
};
|
|
@ -1,29 +1,13 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = require('greenlock').create(init());
|
||||
|
||||
function init() {
|
||||
// .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;
|
||||
module.exports = require('@root/greenlock').create({
|
||||
// name & version for ACME client user agent
|
||||
packageAgent: pkg.name + '/' + pkg.version,
|
||||
|
||||
// contact for security and critical bug notices
|
||||
options.maintainerEmail = pkg.author;
|
||||
maintainerEmail: pkg.author,
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
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 path = require('path');
|
||||
var rcPath = path.join(__dirname, '.greenlockrc');
|
||||
var rc = fs.readFileSync(rcPath, 'utf8');
|
||||
rc = JSON.parse(rc);
|
||||
rc.packageRoot = __dirname;
|
||||
}
|
||||
// where to find .greenlockrc and set default paths
|
||||
packageRoot: __dirname
|
||||
});
|
||||
|
|
|
@ -2,21 +2,12 @@
|
|||
|
||||
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;
|
||||
return {
|
||||
greenlock: require('./greenlock.js'),
|
||||
|
||||
// whether or not to run at cloudscale
|
||||
options.cluster = false;
|
||||
|
||||
return options;
|
||||
cluster: false
|
||||
};
|
||||
})
|
||||
.ready(function(glx) {
|
||||
var app = require('./app.js');
|
||||
|
@ -25,14 +16,3 @@ require('greenlock-express')
|
|||
// 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 path = require('path');
|
||||
var rcPath = path.join(__dirname, '.greenlockrc');
|
||||
var rc = fs.readFileSync(rcPath, 'utf8');
|
||||
rc = JSON.parse(rc);
|
||||
rc.packageRoot = __dirname;
|
||||
}
|
||||
|
|
|
@ -127,7 +127,10 @@ C._rawOrder = function(gnlck, mconf, db, acme, chs, acc, email, args) {
|
|||
var query = {
|
||||
subject: args.subject,
|
||||
certificate: args.certificate || {},
|
||||
directoryUrl: args.directoryUrl || gnlck._defaults.directoryUrl
|
||||
directoryUrl:
|
||||
args.directoryUrl ||
|
||||
mconf.directoryUrl ||
|
||||
gnlck._defaults.directoryUrl
|
||||
};
|
||||
rawPending[id] = U._getOrCreateKeypair(db, args.subject, query, keyType)
|
||||
.then(function(kresult) {
|
||||
|
@ -208,7 +211,10 @@ C._check = function(gnlck, mconf, db, args) {
|
|||
subject: args.subject,
|
||||
// may contain certificate.id
|
||||
certificate: args.certificate,
|
||||
directoryUrl: args.directoryUrl || gnlck._defaults.directoryUrl
|
||||
directoryUrl:
|
||||
args.directoryUrl ||
|
||||
mconf.directoryUrl ||
|
||||
gnlck._defaults.directoryUrl
|
||||
};
|
||||
return db.check(query).then(function(pems) {
|
||||
if (!pems) {
|
||||
|
|
77
greenlock.js
77
greenlock.js
|
@ -13,6 +13,7 @@ var P = require('./plugins.js');
|
|||
var A = require('./accounts.js');
|
||||
var C = require('./certificates.js');
|
||||
var UserEvents = require('./user-events.js');
|
||||
var GreenlockRc = require('./greenlockrc.js');
|
||||
|
||||
var caches = {};
|
||||
|
||||
|
@ -42,27 +43,21 @@ G.create = function(gconf) {
|
|||
});
|
||||
}
|
||||
|
||||
if (!gconf.packageRoot) {
|
||||
gconf.packageRoot = process.cwd();
|
||||
console.warn(
|
||||
'`packageRoot` not defined, trying ' + gconf.packageRoot
|
||||
);
|
||||
}
|
||||
|
||||
if ('function' === typeof gconf.notify) {
|
||||
gdefaults.notify = gconf.notify;
|
||||
} else {
|
||||
gdefaults.notify = _notify;
|
||||
}
|
||||
|
||||
if (gconf.directoryUrl) {
|
||||
gdefaults = gconf.directoryUrl;
|
||||
if (gconf.staging) {
|
||||
throw new Error(
|
||||
'supply `directoryUrl` or `staging`, but not both'
|
||||
);
|
||||
}
|
||||
} else if (gconf.staging) {
|
||||
gdefaults.directoryUrl =
|
||||
'https://acme-staging-v02.api.letsencrypt.org/directory';
|
||||
} else {
|
||||
gdefaults.directoryUrl =
|
||||
'https://acme-v02.api.letsencrypt.org/directory';
|
||||
}
|
||||
console.info('ACME Directory URL:', gdefaults.directoryUrl);
|
||||
var rc = GreenlockRc.resolve(gconf);
|
||||
gconf = Object.assign(rc, gconf);
|
||||
|
||||
// Wraps each of the following with appropriate error checking
|
||||
// greenlock.manager.defaults
|
||||
|
@ -83,10 +78,31 @@ G.create = function(gconf) {
|
|||
// greenlock.challenges.get
|
||||
require('./challenges-underlay.js').wrap(greenlock);
|
||||
|
||||
if (gconf.directoryUrl) {
|
||||
gdefaults.directoryUrl = gconf.directoryUrl;
|
||||
if (gconf.staging) {
|
||||
throw new Error(
|
||||
'supply `directoryUrl` or `staging`, but not both'
|
||||
);
|
||||
}
|
||||
} else if (
|
||||
gconf.staging ||
|
||||
process.argv.includes('--staging') ||
|
||||
/DEV|STAG/i.test(process.env.ENV)
|
||||
) {
|
||||
greenlock.staging = true;
|
||||
gdefaults.directoryUrl =
|
||||
'https://acme-staging-v02.api.letsencrypt.org/directory';
|
||||
} else {
|
||||
greenlock.live = true;
|
||||
gdefaults.directoryUrl =
|
||||
'https://acme-v02.api.letsencrypt.org/directory';
|
||||
}
|
||||
|
||||
greenlock._defaults = gdefaults;
|
||||
greenlock._defaults.debug = gconf.debug;
|
||||
|
||||
if (!gconf._bin_mode) {
|
||||
if (!gconf._bin_mode && false !== gconf.renew) {
|
||||
// renew every 90-ish minutes (random for staggering)
|
||||
// the weak setTimeout (unref) means that when run as a CLI process this
|
||||
// will still finish as expected, and not wait on the timeout
|
||||
|
@ -371,7 +387,7 @@ G.create = function(gconf) {
|
|||
});
|
||||
};
|
||||
|
||||
greenlock._acme = function(args) {
|
||||
greenlock._acme = function(mconf, args) {
|
||||
var packageAgent = gconf.packageAgent || '';
|
||||
// because Greenlock_Express/v3.x Greenlock/v3 is redundant
|
||||
if (!/greenlock/i.test(packageAgent)) {
|
||||
|
@ -383,7 +399,15 @@ G.create = function(gconf) {
|
|||
notify: greenlock._notify,
|
||||
debug: greenlock._defaults.debug || args.debug
|
||||
});
|
||||
var dirUrl = args.directoryUrl || greenlock._defaults.directoryUrl;
|
||||
var dirUrl = args.directoryUrl || mconf.directoryUrl;
|
||||
var showDir = false;
|
||||
if (!dirUrl) {
|
||||
showDir = true;
|
||||
dirUrl = greenlock._defaults.directoryUrl;
|
||||
}
|
||||
if (showDir || /staging/.test(dirUrl)) {
|
||||
console.info('ACME Directory URL:', gdefaults.directoryUrl);
|
||||
}
|
||||
|
||||
var dir = caches[dirUrl];
|
||||
|
||||
|
@ -409,17 +433,17 @@ G.create = function(gconf) {
|
|||
});
|
||||
};
|
||||
|
||||
greenlock.order = function(args) {
|
||||
greenlock.order = function(siteConf) {
|
||||
return greenlock._init().then(function() {
|
||||
return greenlock.manager._defaults().then(function(mconf) {
|
||||
return greenlock._order(mconf, args);
|
||||
return greenlock._order(mconf, siteConf);
|
||||
});
|
||||
});
|
||||
};
|
||||
greenlock._order = function(mconf, args) {
|
||||
greenlock._order = function(mconf, siteConf) {
|
||||
// packageAgent, maintainerEmail
|
||||
return greenlock._acme(args).then(function(acme) {
|
||||
var storeConf = args.store || mconf.store;
|
||||
return greenlock._acme(mconf, siteConf).then(function(acme) {
|
||||
var storeConf = siteConf.store || mconf.store;
|
||||
storeConf = JSON.parse(JSON.stringify(storeConf));
|
||||
storeConf.packageRoot = gconf.packageRoot;
|
||||
if (storeConf.basePath) {
|
||||
|
@ -435,9 +459,10 @@ G.create = function(gconf) {
|
|||
mconf,
|
||||
store.accounts,
|
||||
acme,
|
||||
args
|
||||
siteConf
|
||||
).then(function(account) {
|
||||
var challengeConfs = args.challenges || mconf.challenges;
|
||||
var challengeConfs =
|
||||
siteConf.challenges || mconf.challenges;
|
||||
return Promise.all(
|
||||
Object.keys(challengeConfs).map(function(typ01) {
|
||||
return P._loadChallenge(challengeConfs, typ01);
|
||||
|
@ -454,7 +479,7 @@ G.create = function(gconf) {
|
|||
acme,
|
||||
challenges,
|
||||
account,
|
||||
args
|
||||
siteConf
|
||||
).then(function(pems) {
|
||||
if (!pems) {
|
||||
throw new Error('no order result');
|
||||
|
|
|
@ -0,0 +1,191 @@
|
|||
'use strict';
|
||||
|
||||
// TODO how to handle path differences when run from npx vs when required by greenlock?
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
function saveFile(rcpath, data, enc) {
|
||||
// because this may have a database url or some such
|
||||
fs.writeFileSync(rcpath, data, enc);
|
||||
return fs.chmodSync(rcpath, parseInt('0600', 8));
|
||||
}
|
||||
|
||||
var GRC = (module.exports = function(pkgpath, manager, rc) {
|
||||
// TODO when run from package
|
||||
// Run from the package root (assumed) or exit
|
||||
var pkgdir = path.dirname(pkgpath);
|
||||
|
||||
try {
|
||||
require(pkgpath);
|
||||
} catch (e) {
|
||||
console.error(
|
||||
'npx greenlock must be run from the package root (where package.json is)'
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
return module.exports._defaults(pkgdir, manager, rc);
|
||||
} catch (e) {
|
||||
if ('package.json' === e.context) {
|
||||
console.error(e.desc);
|
||||
process.exit(1);
|
||||
}
|
||||
console.error(e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
// Figure out what to do between what's hard-coded,
|
||||
// what's in the config file, and what's left unset
|
||||
module.exports.resolve = function(gconf) {
|
||||
var rc = GRC.read(gconf.packageRoot);
|
||||
if (gconf.configFile) {
|
||||
rc = { configFile: gconf.configFile };
|
||||
}
|
||||
|
||||
var manager;
|
||||
var updates;
|
||||
|
||||
if (rc.manager) {
|
||||
if (gconf.manager && rc.manager !== gconf.manager) {
|
||||
console.warn(
|
||||
'warn: ignoring hard-coded ' +
|
||||
gconf.manager +
|
||||
' in favor of ' +
|
||||
rc.manager
|
||||
);
|
||||
}
|
||||
gconf.manager = rc.manager;
|
||||
} else if (gconf.manager) {
|
||||
manager = gconf.manager;
|
||||
}
|
||||
|
||||
if (rc.configFile) {
|
||||
if (gconf.configFile && rc.configFile !== gconf.configFile) {
|
||||
console.warn(
|
||||
'warn: ignoring hard-coded ' +
|
||||
gconf.configFile +
|
||||
' in favor of ' +
|
||||
rc.configFile
|
||||
);
|
||||
}
|
||||
gconf.configFile = rc.configFile;
|
||||
} else if (gconf.manager) {
|
||||
updates = { configFile: gconf.configFile };
|
||||
}
|
||||
|
||||
return GRC._defaults(gconf.packageRoot, manager, rc);
|
||||
};
|
||||
|
||||
module.exports._defaults = function(pkgdir, manager, rc) {
|
||||
var rcpath = path.join(pkgdir, '.greenlockrc');
|
||||
var _rc;
|
||||
var created = false;
|
||||
|
||||
if (manager) {
|
||||
if ('.' === manager[0]) {
|
||||
manager = path.resolve(pkgdir, manager);
|
||||
}
|
||||
try {
|
||||
require(manager);
|
||||
} catch (e) {
|
||||
console.error('could not load ' + manager + ' from ' + pkgdir);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
var stuff = module.exports._read(pkgdir);
|
||||
_rc = stuff.rc;
|
||||
created = stuff.created;
|
||||
|
||||
var changed;
|
||||
if (manager) {
|
||||
if (!_rc.manager) {
|
||||
_rc.manager = manager;
|
||||
}
|
||||
if (_rc.manager !== manager) {
|
||||
console.info('Switching manager:');
|
||||
var older = _rc.manager;
|
||||
var newer = manager;
|
||||
if ('/' === older[0]) {
|
||||
older = path.relative(pkgdir, older);
|
||||
}
|
||||
if ('/' === newer[0]) {
|
||||
newer = path.relative(pkgdir, newer);
|
||||
}
|
||||
console.info('\told: ' + older);
|
||||
console.info('\tnew: ' + newer);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (rc) {
|
||||
changed = true;
|
||||
Object.keys(rc).forEach(function(k) {
|
||||
_rc[k] = rc[k];
|
||||
});
|
||||
}
|
||||
|
||||
if (['@greenlock/manager', 'greenlock-manager-fs'].includes(_rc.manager)) {
|
||||
if (!_rc.configFile) {
|
||||
changed = true;
|
||||
_rc.configFile = path.join(pkgdir, 'greenlock.json');
|
||||
}
|
||||
}
|
||||
|
||||
if (!changed) {
|
||||
return _rc;
|
||||
}
|
||||
|
||||
var data = JSON.stringify(_rc, null, 2);
|
||||
if (created) {
|
||||
console.info('Wrote ' + rcpath);
|
||||
}
|
||||
saveFile(rcpath, data, 'utf8');
|
||||
return _rc;
|
||||
};
|
||||
|
||||
module.exports.read = function(pkgdir) {
|
||||
return module.exports._read(pkgdir).rc;
|
||||
};
|
||||
|
||||
module.exports._read = function(pkgdir) {
|
||||
var created;
|
||||
var rcpath = path.join(pkgdir, '.greenlockrc');
|
||||
var _data;
|
||||
try {
|
||||
_data = fs.readFileSync(rcpath, 'utf8');
|
||||
} catch (err) {
|
||||
if ('ENOENT' !== err.code) {
|
||||
throw err;
|
||||
}
|
||||
try {
|
||||
require(path.join(pkgdir, 'package.json'));
|
||||
} catch (e) {
|
||||
e.context = 'package.json';
|
||||
e.desc =
|
||||
'run `greenlock` from the same directory as `package.json`, or specify `packageRoot` of `.greenlockrc`';
|
||||
throw e;
|
||||
}
|
||||
console.info('Creating ' + rcpath);
|
||||
created = true;
|
||||
_data = '{}';
|
||||
saveFile(rcpath, _data, 'utf8');
|
||||
}
|
||||
|
||||
var rc;
|
||||
try {
|
||||
rc = JSON.parse(_data);
|
||||
} catch (e) {
|
||||
console.error("couldn't parse " + rcpath, _data);
|
||||
console.error('(perhaps you should just delete it and try again?)');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
return {
|
||||
created: created,
|
||||
rc: rc
|
||||
};
|
||||
};
|
|
@ -94,7 +94,10 @@ module.exports.wrap = function(greenlock, gconf) {
|
|||
return mega.defaults(conf);
|
||||
});
|
||||
};
|
||||
greenlock.manager._defaults = mega.defaults;
|
||||
|
||||
greenlock.manager._defaults = function(opts) {
|
||||
return mega.defaults(opts);
|
||||
};
|
||||
|
||||
greenlock.manager.add = function(args) {
|
||||
if (!args || !Array.isArray(args.altnames) || !args.altnames.length) {
|
||||
|
|
Loading…
Reference in New Issue