Compare commits
	
		
			7 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| bb8056acdc | |||
| 0ebb53f563 | |||
| 6a6c9cc88e | |||
| 4b47fb4eb6 | |||
| 40fec526e1 | |||
| 
						 | 
					27bee1b8de | ||
| 
						 | 
					7875d9d0c9 | 
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1,3 +1,5 @@
 | 
				
			|||||||
 | 
					*delete-me*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# ---> Node
 | 
					# ---> Node
 | 
				
			||||||
# Logs
 | 
					# Logs
 | 
				
			||||||
logs
 | 
					logs
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										20
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								README.md
									
									
									
									
									
								
							@ -10,22 +10,28 @@ A simple file-based management strategy for Greenlock v3
 | 
				
			|||||||
npm install --save greenlock-manager-fs@v3
 | 
					npm install --save greenlock-manager-fs@v3
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Use with Greenlock
 | 
					## Usage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```js
 | 
					```js
 | 
				
			||||||
var greenlock = require('greenlock').create({
 | 
					npx greenlock init --manager greenlock-manager-fs --config-dir './greenlock.d'
 | 
				
			||||||
	// ...
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	manager: 'greenlock-manager-fs',
 | 
					Or, place this file in the root of your project:
 | 
				
			||||||
	configFile: '~/.config/greenlock/manager.json'
 | 
					
 | 
				
			||||||
});
 | 
					`.greenlockrc`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```json
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						"manager": { "module": "@greenlock/manager" },
 | 
				
			||||||
 | 
						"configDir": "./greenlock.d"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Example config file
 | 
					## Example config file
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You might start your config file like this:
 | 
					You might start your config file like this:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
`~/.config/greenlock/manager.json`:
 | 
					`./greenlock.d/config.json`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```json
 | 
					```json
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										76
									
								
								manager.js
									
									
									
									
									
								
							
							
						
						
									
										76
									
								
								manager.js
									
									
									
									
									
								
							@ -19,8 +19,13 @@ var mkdirp = promisify(require('@root/mkdirp'));
 | 
				
			|||||||
// and wanting to be fairly sure it works and produces
 | 
					// and wanting to be fairly sure it works and produces
 | 
				
			||||||
// meaningful errors
 | 
					// meaningful errors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IMPORTANT
 | 
				
			||||||
// For your use case you'll probably find a better example
 | 
					// For your use case you'll probably find a better example
 | 
				
			||||||
// in greenlock-manager-test
 | 
					// in greenlock-manager-test:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//    npm install --save greenlock-manager-test
 | 
				
			||||||
 | 
					//    npx greenlock-manager-init
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Manage.create = function(CONF) {
 | 
					Manage.create = function(CONF) {
 | 
				
			||||||
	if (!CONF) {
 | 
						if (!CONF) {
 | 
				
			||||||
@ -75,6 +80,31 @@ Manage.create = function(CONF) {
 | 
				
			|||||||
		return manage._txPromise;
 | 
							return manage._txPromise;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						manage.get = async function(args) {
 | 
				
			||||||
 | 
							manage._txPromise = manage._txPromise.then(async function() {
 | 
				
			||||||
 | 
								var config = await Manage._getLatest(manage, CONF);
 | 
				
			||||||
 | 
								var site;
 | 
				
			||||||
 | 
								Object.keys(config.sites).some(function(k) {
 | 
				
			||||||
 | 
									// if subject is specified, don't return anything else
 | 
				
			||||||
 | 
									var _site = config.sites[k];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// altnames, servername, and wildname all get rolled into one
 | 
				
			||||||
 | 
									return _site.altnames.some(function(altname) {
 | 
				
			||||||
 | 
										if ([args.servername, args.wildname].includes(altname)) {
 | 
				
			||||||
 | 
											site = _site;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									});
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (site && !site.deletedAt) {
 | 
				
			||||||
 | 
									return doctor.site(config.sites, site.subject);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return null;
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return manage._txPromise;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	manage._merge = function(config, current, args) {
 | 
						manage._merge = function(config, current, args) {
 | 
				
			||||||
		if (!current || current.deletedAt) {
 | 
							if (!current || current.deletedAt) {
 | 
				
			||||||
			current = config.sites[args.subject] = {
 | 
								current = config.sites[args.subject] = {
 | 
				
			||||||
@ -95,10 +125,15 @@ Manage.create = function(CONF) {
 | 
				
			|||||||
			if (newAlts.join() !== oldAlts.join()) {
 | 
								if (newAlts.join() !== oldAlts.join()) {
 | 
				
			||||||
				// this will cause immediate renewal
 | 
									// this will cause immediate renewal
 | 
				
			||||||
				args.renewAt = 1;
 | 
									args.renewAt = 1;
 | 
				
			||||||
				current.renewAt = 1;
 | 
					 | 
				
			||||||
				current.altnames = args.altnames.slice(0);
 | 
									current.altnames = args.altnames.slice(0);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							Object.keys(args).forEach(function(k) {
 | 
				
			||||||
 | 
								if ('altnames' === k) {
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								current[k] = args[k];
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// no transaction promise here because it calls set
 | 
						// no transaction promise here because it calls set
 | 
				
			||||||
@ -112,7 +147,8 @@ Manage.create = function(CONF) {
 | 
				
			|||||||
		// between the managed state and the overlay, and choose
 | 
							// between the managed state and the overlay, and choose
 | 
				
			||||||
		// what was found.
 | 
							// what was found.
 | 
				
			||||||
		var theirs = await CONF.find(args);
 | 
							var theirs = await CONF.find(args);
 | 
				
			||||||
		return _mergeFind(ours, theirs);
 | 
							var config = await Manage._getLatest(manage, CONF);
 | 
				
			||||||
 | 
							return _mergeFind(config, ours, theirs);
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	function _find(args) {
 | 
						function _find(args) {
 | 
				
			||||||
@ -178,7 +214,7 @@ Manage.create = function(CONF) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	function _mergeFind(config, ours, theirs) {
 | 
						function _mergeFind(config, ours, theirs) {
 | 
				
			||||||
		theirs.forEach(function(_newer) {
 | 
							theirs.forEach(function(_newer) {
 | 
				
			||||||
			ours.some(function(_older) {
 | 
								var hasCurrent = ours.some(function(_older) {
 | 
				
			||||||
				if (_newer.subject !== _older.subject) {
 | 
									if (_newer.subject !== _older.subject) {
 | 
				
			||||||
					return false;
 | 
										return false;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@ -192,6 +228,9 @@ Manage.create = function(CONF) {
 | 
				
			|||||||
				// handled the (only) match
 | 
									// handled the (only) match
 | 
				
			||||||
				return true;
 | 
									return true;
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
 | 
								if (hasCurrent) {
 | 
				
			||||||
 | 
									manage._merge(config, null, _newer);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// delete the things that are gone
 | 
							// delete the things that are gone
 | 
				
			||||||
@ -208,7 +247,10 @@ Manage.create = function(CONF) {
 | 
				
			|||||||
			await manage._save(config);
 | 
								await manage._save(config);
 | 
				
			||||||
			// everything was either added, updated, or not different
 | 
								// everything was either added, updated, or not different
 | 
				
			||||||
			// hence, this is everything
 | 
								// hence, this is everything
 | 
				
			||||||
			return JSON.parse(JSON.stringify(config.sites));
 | 
								var copy = JSON.parse(JSON.stringify(config.sites));
 | 
				
			||||||
 | 
								return Object.keys(copy).map(function(k) {
 | 
				
			||||||
 | 
									return copy[k];
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return manage._txPromise;
 | 
							return manage._txPromise;
 | 
				
			||||||
@ -221,7 +263,7 @@ Manage.create = function(CONF) {
 | 
				
			|||||||
		manage._txPromise = manage._txPromise.then(async function() {
 | 
							manage._txPromise = manage._txPromise.then(async function() {
 | 
				
			||||||
			var config = await Manage._getLatest(manage, CONF);
 | 
								var config = await Manage._getLatest(manage, CONF);
 | 
				
			||||||
			var site = config.sites[args.subject];
 | 
								var site = config.sites[args.subject];
 | 
				
			||||||
			if (!site) {
 | 
								if (!site || site.deletedAt) {
 | 
				
			||||||
				return null;
 | 
									return null;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			site.deletedAt = Date.now();
 | 
								site.deletedAt = Date.now();
 | 
				
			||||||
@ -238,8 +280,16 @@ Manage.create = function(CONF) {
 | 
				
			|||||||
	manage._save = async function(config) {
 | 
						manage._save = async function(config) {
 | 
				
			||||||
		await mkdirp(path.dirname(CONF.configFile));
 | 
							await mkdirp(path.dirname(CONF.configFile));
 | 
				
			||||||
		// pretty-print the config file
 | 
							// pretty-print the config file
 | 
				
			||||||
		var data = JSON.stringify(config, null, 2);
 | 
							var data = JSON.parse(JSON.stringify(config));
 | 
				
			||||||
		await sfs.writeFileAsync(CONF.configFile, data, 'utf8');
 | 
							var sites = data.sites || {};
 | 
				
			||||||
 | 
							data.sites = Object.keys(sites).map(function(k) {
 | 
				
			||||||
 | 
								return sites[k];
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
							await sfs.writeFileAsync(
 | 
				
			||||||
 | 
								CONF.configFile,
 | 
				
			||||||
 | 
								JSON.stringify(data, null, 2),
 | 
				
			||||||
 | 
								'utf8'
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// this file may contain secrets, so keep it safe
 | 
							// this file may contain secrets, so keep it safe
 | 
				
			||||||
		return chmodFile(CONF.configFile, parseInt('0600', 8))
 | 
							return chmodFile(CONF.configFile, parseInt('0600', 8))
 | 
				
			||||||
@ -254,8 +304,9 @@ Manage.create = function(CONF) {
 | 
				
			|||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	manage.init = async function(deps) {
 | 
						manage.init = async function(deps) {
 | 
				
			||||||
		var request = deps.request;
 | 
							// even though we don't need it
 | 
				
			||||||
		// how nice...
 | 
							manage.request = deps.request;
 | 
				
			||||||
 | 
							return null;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return manage;
 | 
						return manage;
 | 
				
			||||||
@ -298,7 +349,10 @@ doctor.config = function(config) {
 | 
				
			|||||||
	doctor.sites(config);
 | 
						doctor.sites(config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Object.keys(config).forEach(function(key) {
 | 
						Object.keys(config).forEach(function(key) {
 | 
				
			||||||
		if (['defaults', 'routes', 'sites'].includes(key)) {
 | 
							// .greenlockrc and greenlock.json shall merge as one
 | 
				
			||||||
 | 
							// and be called greenlock.json because calling it
 | 
				
			||||||
 | 
							// .greenlockrc seems to rub people the wrong way
 | 
				
			||||||
 | 
							if (['manager', 'defaults', 'routes', 'sites'].includes(key)) {
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		config.defaults[key] = config[key];
 | 
							config.defaults[key] = config[key];
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										28
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										28
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	"name": "greenlock-manager-fs",
 | 
						"name": "greenlock-manager-fs",
 | 
				
			||||||
	"version": "0.7.0",
 | 
						"version": "3.1.1",
 | 
				
			||||||
	"lockfileVersion": 1,
 | 
						"lockfileVersion": 1,
 | 
				
			||||||
	"requires": true,
 | 
						"requires": true,
 | 
				
			||||||
	"dependencies": {
 | 
						"dependencies": {
 | 
				
			||||||
@ -9,6 +9,32 @@
 | 
				
			|||||||
			"resolved": "https://registry.npmjs.org/@root/mkdirp/-/mkdirp-1.0.0.tgz",
 | 
								"resolved": "https://registry.npmjs.org/@root/mkdirp/-/mkdirp-1.0.0.tgz",
 | 
				
			||||||
			"integrity": "sha512-hxGAYUx5029VggfG+U9naAhQkoMSXtOeXtbql97m3Hi6/sQSRL/4khKZPyOF6w11glyCOU38WCNLu9nUcSjOfA=="
 | 
								"integrity": "sha512-hxGAYUx5029VggfG+U9naAhQkoMSXtOeXtbql97m3Hi6/sQSRL/4khKZPyOF6w11glyCOU38WCNLu9nUcSjOfA=="
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							"@root/request": {
 | 
				
			||||||
 | 
								"version": "1.4.2",
 | 
				
			||||||
 | 
								"resolved": "https://registry.npmjs.org/@root/request/-/request-1.4.2.tgz",
 | 
				
			||||||
 | 
								"integrity": "sha512-J8FM4+SJuc7WRC+Jz17m+VT2lgI7HtatHhxN1F2ck5aIKUAxJEaR4u/gLBsgT60mVHevKCjKN0O8115UtJjwLw==",
 | 
				
			||||||
 | 
								"dev": true
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"greenlock-manager-fs": {
 | 
				
			||||||
 | 
								"version": "3.0.5",
 | 
				
			||||||
 | 
								"resolved": "https://registry.npmjs.org/greenlock-manager-fs/-/greenlock-manager-fs-3.0.5.tgz",
 | 
				
			||||||
 | 
								"integrity": "sha512-r/q+tEFuDwklfzPfiGhcIrHuJxMrppC+EseESpu5f0DMokh+1iZVm9nGC/VE7/7GETdOYfEYhhQkmspsi8Gr/A==",
 | 
				
			||||||
 | 
								"dev": true,
 | 
				
			||||||
 | 
								"requires": {
 | 
				
			||||||
 | 
									"@root/mkdirp": "^1.0.0",
 | 
				
			||||||
 | 
									"safe-replace": "^1.1.0"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"greenlock-manager-test": {
 | 
				
			||||||
 | 
								"version": "3.1.1",
 | 
				
			||||||
 | 
								"resolved": "https://registry.npmjs.org/greenlock-manager-test/-/greenlock-manager-test-3.1.1.tgz",
 | 
				
			||||||
 | 
								"integrity": "sha512-wZ+Oxn5qTEoN+VDd3Y+kBYZ8MlaLlhm40KwIwfyR90bj08IZpfzE7zGY8SwBEbIx0wNSo6ztDku4Y0gVgxxwCA==",
 | 
				
			||||||
 | 
								"dev": true,
 | 
				
			||||||
 | 
								"requires": {
 | 
				
			||||||
 | 
									"@root/request": "^1.4.1",
 | 
				
			||||||
 | 
									"greenlock-manager-fs": "^3.0.0"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		"safe-replace": {
 | 
							"safe-replace": {
 | 
				
			||||||
			"version": "1.1.0",
 | 
								"version": "1.1.0",
 | 
				
			||||||
			"resolved": "https://registry.npmjs.org/safe-replace/-/safe-replace-1.1.0.tgz",
 | 
								"resolved": "https://registry.npmjs.org/safe-replace/-/safe-replace-1.1.0.tgz",
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	"name": "greenlock-manager-fs",
 | 
						"name": "greenlock-manager-fs",
 | 
				
			||||||
	"version": "3.0.1",
 | 
						"version": "3.1.1",
 | 
				
			||||||
	"description": "A simple file-based management strategy for Greenlock",
 | 
						"description": "A simple file-based management strategy for Greenlock",
 | 
				
			||||||
	"main": "manager.js",
 | 
						"main": "manager.js",
 | 
				
			||||||
	"scripts": {
 | 
						"scripts": {
 | 
				
			||||||
@ -27,6 +27,6 @@
 | 
				
			|||||||
		"safe-replace": "^1.1.0"
 | 
							"safe-replace": "^1.1.0"
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	"devDependencies": {
 | 
						"devDependencies": {
 | 
				
			||||||
		"greenlock-manager-test": "^3.0.0"
 | 
							"greenlock-manager-test": "^3.1.1"
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,19 +1,25 @@
 | 
				
			|||||||
'use strict';
 | 
					"use strict";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var Tester = require('greenlock-manager-test');
 | 
					var Tester = require("greenlock-manager-test");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var Manager = require('../');
 | 
					var Manager = require("../manager.js");
 | 
				
			||||||
var config = {
 | 
					var config = {
 | 
				
			||||||
	configFile: 'greenlock-manager-test.delete-me.json'
 | 
					    configFile: "greenlock-manager-test.delete-me.json"
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Tester.test(Manager, config)
 | 
					Tester.test(Manager, config)
 | 
				
			||||||
	.then(function() {
 | 
					    .then(function(features) {
 | 
				
			||||||
		console.log('PASS: Known-good test module passes');
 | 
					        console.info("PASS");
 | 
				
			||||||
	})
 | 
					        console.info();
 | 
				
			||||||
	.catch(function(err) {
 | 
					        console.info("Optional Feature Support:");
 | 
				
			||||||
		console.error('Oops, you broke it. Here are the details:');
 | 
					        features.forEach(function(feature) {
 | 
				
			||||||
		console.error(err.stack);
 | 
					            console.info(feature.supported ? "✓ (YES)" : "✘ (NO) ", feature.description);
 | 
				
			||||||
		console.error();
 | 
					        });
 | 
				
			||||||
		console.error("That's all I know.");
 | 
					        console.info();
 | 
				
			||||||
	});
 | 
					    })
 | 
				
			||||||
 | 
					    .catch(function(err) {
 | 
				
			||||||
 | 
					        console.error("Oops, you broke it. Here are the details:");
 | 
				
			||||||
 | 
					        console.error(err.stack);
 | 
				
			||||||
 | 
					        console.error();
 | 
				
			||||||
 | 
					        console.error("That's all I know.");
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user