Skip to content

Commit

Permalink
Properly group records from a zonefile. (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
stephenplusplus authored Mar 15, 2018
1 parent 790be7c commit 4538a99
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 31 deletions.
3 changes: 3 additions & 0 deletions packages/google-cloud-dns/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@
"dns-zonefile": "0.2.2",
"extend": "^3.0.0",
"is": "^3.0.1",
"lodash.flatten": "^4.4.0",
"lodash.groupby": "^4.6.0",
"methmeth": "^1.0.0",
"propprop": "^0.3.1",
"string-format-obj": "^1.0.0"
},
"devDependencies": {
Expand Down
39 changes: 34 additions & 5 deletions packages/google-cloud-dns/src/zone.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ var arrify = require('arrify');
var common = require('@google-cloud/common');
var exec = require('methmeth');
var extend = require('extend');
var flatten = require('lodash.flatten');
var fs = require('fs');
var groupBy = require('lodash.groupby');
var is = require('is');
var prop = require('propprop');
var util = require('util');
var zonefile = require('dns-zonefile');

Expand Down Expand Up @@ -342,14 +345,40 @@ Zone.prototype.createChange = function(config, callback) {
throw new Error('Cannot create a change with no additions or deletions.');
}

var body = extend({}, config, {
additions: arrify(config.add).map(exec('toJSON')),
deletions: arrify(config.delete).map(exec('toJSON')),
});

var body = extend(
{
additions: groupByType(arrify(config.add).map(exec('toJSON'))),
deletions: groupByType(arrify(config.delete).map(exec('toJSON'))),
},
config
);
delete body.add;
delete body.delete;

function groupByType(changes) {
changes = groupBy(changes, 'type');

var changesArray = [];

for (var recordType in changes) {
var recordsByName = groupBy(changes[recordType], 'name');

for (var recordName in recordsByName) {
var records = recordsByName[recordName];
var templateRecord = extend({}, records[0]);

if (records.length > 1) {
// Combine the `rrdatas` values from all records of the same type.
templateRecord.rrdatas = flatten(records.map(prop('rrdatas')));
}

changesArray.push(templateRecord);
}
}

return changesArray;
}

this.request(
{
method: 'POST',
Expand Down
6 changes: 6 additions & 0 deletions packages/google-cloud-dns/system-test/data/zonefile.zone
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
$TTL 3600
{DNS_DOMAIN} 21600 IN SPF "v=spf1" "mx:{DNS_DOMAIN}" "-all"
{DNS_DOMAIN} IN TXT "google-site-verification=xxxxxxxxxxxxYYYYYYXXX"
{DNS_DOMAIN} 21600 MX 10 mail.example.com.
{DNS_DOMAIN} 21600 MX 30 mail.example.com.
{DNS_DOMAIN} A 128.9.0.32
A 10.1.0.52
{DNS_DOMAIN} A 10.2.0.27
A 128.9.0.33
78 changes: 52 additions & 26 deletions packages/google-cloud-dns/test/zone.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,15 @@

var arrify = require('arrify');
var assert = require('assert');
var exec = require('methmeth');
var extend = require('extend');
var flatten = require('lodash.flatten');
var nodeutil = require('util');
var prop = require('propprop');
var proxyquire = require('proxyquire');
var ServiceObject = require('@google-cloud/common').ServiceObject;
var util = require('@google-cloud/common').util;
var uuid = require('uuid');

var promisified = false;
var fakeUtil = extend({}, util, {
Expand Down Expand Up @@ -192,26 +196,33 @@ describe('Zone', function() {
});

describe('createChange', function() {
function generateRecord(recordJson) {
recordJson = extend(
{
name: uuid.v1(),
type: uuid.v1(),
rrdatas: [uuid.v1(), uuid.v1()],
},
recordJson
);

return {
toJSON: function() {
return recordJson;
},
};
}

it('should throw error if add or delete is not provided', function() {
assert.throws(function() {
zone.createChange({}, util.noop);
}, /Cannot create a change with no additions or deletions/);
});

it('should parse and rename add to additions', function(done) {
var recordsToAdd = [
{
toJSON: function() {
return 'a';
},
},
{
toJSON: function() {
return 'a';
},
},
];
var expectedAdditions = ['a', 'a'];
var recordsToAdd = [generateRecord(), generateRecord()];

var expectedAdditions = recordsToAdd.map(exec('toJSON'));

zone.request = function(reqOpts) {
assert.strictEqual(reqOpts.json.add, undefined);
Expand All @@ -223,19 +234,9 @@ describe('Zone', function() {
});

it('should parse and rename delete to deletions', function(done) {
var recordsToDelete = [
{
toJSON: function() {
return 'a';
},
},
{
toJSON: function() {
return 'a';
},
},
];
var expectedDeletions = ['a', 'a'];
var recordsToDelete = [generateRecord(), generateRecord()];

var expectedDeletions = recordsToDelete.map(exec('toJSON'));

zone.request = function(reqOpts) {
assert.strictEqual(reqOpts.json.delete, undefined);
Expand All @@ -246,6 +247,31 @@ describe('Zone', function() {
zone.createChange({delete: recordsToDelete}, assert.ifError);
});

it('should group changes by name and type', function(done) {
var recordsToAdd = [
generateRecord({name: 'name.com.', type: 'mx'}),
generateRecord({name: 'name.com.', type: 'mx'}),
];

zone.request = function(reqOpts) {
var expectedRRDatas = flatten(
recordsToAdd.map(exec('toJSON')).map(prop('rrdatas'))
);

assert.deepStrictEqual(reqOpts.json.additions, [
{
name: 'name.com.',
type: 'mx',
rrdatas: expectedRRDatas,
},
]);

done();
};

zone.createChange({add: recordsToAdd}, assert.ifError);
});

it('should make correct API request', function(done) {
zone.request = function(reqOpts) {
assert.strictEqual(reqOpts.method, 'POST');
Expand Down

0 comments on commit 4538a99

Please sign in to comment.