add template, implement auth and zones
This commit is contained in:
vanhempi
3e67322d69
commit
22c1e761e0
|
@ -1,3 +1,7 @@
|
||||||
|
*.json
|
||||||
|
service_account.json
|
||||||
|
credentials.json
|
||||||
|
|
||||||
# ---> Node
|
# ---> Node
|
||||||
# Logs
|
# Logs
|
||||||
logs
|
logs
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)
|
28
README.md
28
README.md
|
@ -1,3 +1,29 @@
|
||||||
# acme-dns-01-googlecloud.js
|
# acme-dns-01-googlecloud.js
|
||||||
|
|
||||||
Google Cloud DNS for Let's Encrypt / ACME dns-01 challenges with ACME.js and Greenlock.js
|
Google Domains + Let's Encrypt for Node.js - ACME dns-01 challenges w/ ACME.js and Greenlock.js
|
||||||
|
|
||||||
|
In Progress. Would love help. Please contact @coolaj86 on Keybase.
|
||||||
|
|
||||||
|
- [x] zones
|
||||||
|
- [ ] set
|
||||||
|
- [ ] get
|
||||||
|
- [ ] remove
|
||||||
|
|
||||||
|
Implementation Details
|
||||||
|
|
||||||
|
- https://cloud.google.com/dns/docs/reference/v1/
|
||||||
|
- https://cloud.google.com/service-usage/docs/getting-started#api
|
||||||
|
- https://github.com/google/oauth2l
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
First you create an instance with your credentials:
|
||||||
|
|
||||||
|
```js
|
||||||
|
var dns01 = require('acme-dns-01-googlecloud').create({
|
||||||
|
baseUrl: 'https://www.googleapis.com/dns/v1/', // default
|
||||||
|
|
||||||
|
// contains private_key, private_key_id, project_id, and client_email
|
||||||
|
serviceAccountPath: __dirname + '/service_account.json'
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
# NOT credentials.json
|
||||||
|
GOOGLE_APPLICATION_CREDENTIALS=/Users/me/service_account.json
|
||||||
|
ZONE=example.co.uk
|
|
@ -0,0 +1,3 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = require('./lib/index.js');
|
|
@ -0,0 +1,36 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var Keypairs = require('keypairs');
|
||||||
|
|
||||||
|
module.exports.getToken = function(serviceAccount) {
|
||||||
|
var jwt = '';
|
||||||
|
var exp = 0;
|
||||||
|
|
||||||
|
if (exp - Date.now() > 0) {
|
||||||
|
return Promise.resolve(jwt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return module.exports.generateToken(serviceAccount).then(function(_jwt) {
|
||||||
|
jwt = _jwt;
|
||||||
|
exp = Math.round(Date.now()) - 15 * 60 * 60 * 1000;
|
||||||
|
return jwt;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.generateToken = function(serviceAccount) {
|
||||||
|
var sa = serviceAccount;
|
||||||
|
return Keypairs.import({ pem: sa.private_key }).then(function(key) {
|
||||||
|
return Keypairs.signJwt({
|
||||||
|
jwk: key,
|
||||||
|
iss: sa.client_email,
|
||||||
|
exp: '1h',
|
||||||
|
header: {
|
||||||
|
kid: sa.private_key_id
|
||||||
|
},
|
||||||
|
claims: {
|
||||||
|
aud: 'ndev.clouddns.readwrite',
|
||||||
|
sub: sa.client_email
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
|
@ -0,0 +1,74 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var auth = require('./auth.js');
|
||||||
|
var defaults = {
|
||||||
|
baseUrl: 'https://www.googleapis.com/dns/v1/'
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.create = function(config) {
|
||||||
|
var request;
|
||||||
|
var baseUrl = (config.baseUrl || defaults.baseUrl).replace(/\/$/, '');
|
||||||
|
var sa = getServiceAccount(config);
|
||||||
|
|
||||||
|
return {
|
||||||
|
init: function(opts) {
|
||||||
|
request = opts.request;
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
zones: function(data) {
|
||||||
|
//console.info('List Zones', data);
|
||||||
|
return api({
|
||||||
|
url: baseUrl + '/projects/' + sa.project_id + '/managedZones',
|
||||||
|
json: true
|
||||||
|
}).then(function(resp) {
|
||||||
|
return resp.body.managedZones.map(function(zone) {
|
||||||
|
// slice out the leading and trailing single quotes, and the trailing dot
|
||||||
|
// (assuming that all 'dnsName's probably look the same)
|
||||||
|
return zone.dnsName.slice(1, zone.dnsName.length - 2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
set: function(data) {
|
||||||
|
// console.info('Add TXT', data);
|
||||||
|
throw Error('setting TXT not implemented');
|
||||||
|
},
|
||||||
|
remove: function(data) {
|
||||||
|
// console.info('Remove TXT', data);
|
||||||
|
throw Error('removing TXT not implemented');
|
||||||
|
},
|
||||||
|
get: function(data) {
|
||||||
|
// console.info('List TXT', data);
|
||||||
|
throw Error('listing TXTs not implemented');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function api(opts) {
|
||||||
|
return auth.getToken(sa).then(function(token) {
|
||||||
|
opts.headers = opts.headers || {};
|
||||||
|
opts.headers.Authorization = 'Bearer ' + token;
|
||||||
|
return request(opts);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getServiceAccount(config) {
|
||||||
|
var saPath =
|
||||||
|
config.serviceAccountPath ||
|
||||||
|
process.env.GOOGLE_APPLICATION_CREDENTIALS;
|
||||||
|
var sa = config.serviceAccount || require(saPath);
|
||||||
|
|
||||||
|
if (
|
||||||
|
!sa ||
|
||||||
|
!(
|
||||||
|
sa.private_key &&
|
||||||
|
sa.private_key_id &&
|
||||||
|
sa.client_email &&
|
||||||
|
sa.project_id
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
throw new Error(
|
||||||
|
'missing or incomplete service_account.json: set serviceAccount serviceAccountPath'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return sa;
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,37 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// See https://git.coolaj86.com/coolaj86/acme-challenge-test.js
|
||||||
|
var tester = require('acme-challenge-test');
|
||||||
|
require('dotenv').config();
|
||||||
|
|
||||||
|
// Usage: node ./test.js example.com xxxxxxxxx
|
||||||
|
var zone = process.argv[2] || process.env.ZONE;
|
||||||
|
var config = {
|
||||||
|
serviceAccountPath:
|
||||||
|
process.argv[3] || process.env.GOOGLE_APPLICATION_CREDENTIALS
|
||||||
|
};
|
||||||
|
var challenger = require('./index.js').create(config);
|
||||||
|
|
||||||
|
// Google has its own special authentication
|
||||||
|
var sa = require(config.serviceAccountPath);
|
||||||
|
require('./lib/auth.js')
|
||||||
|
.getToken(sa)
|
||||||
|
.then(function(jwt) {
|
||||||
|
console.info('\nAuthorization: Bearer ' + jwt + '\n');
|
||||||
|
|
||||||
|
// The dry-run tests can pass on, literally, 'example.com'
|
||||||
|
// but the integration tests require that you have control over the domain
|
||||||
|
return tester
|
||||||
|
.testZone('dns-01', zone, challenger)
|
||||||
|
.then(function() {
|
||||||
|
console.info('PASS', zone);
|
||||||
|
})
|
||||||
|
.catch(function(e) {
|
||||||
|
console.error(e.message);
|
||||||
|
console.error(e.stack);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
console.error(err.stack);
|
||||||
|
});
|
Ladataan…
Viittaa uudesa ongelmassa