Skip to content

Commit 4538a99

Browse files
Properly group records from a zonefile. (#26)
1 parent 790be7c commit 4538a99

File tree

4 files changed

+95
-31
lines changed

4 files changed

+95
-31
lines changed

packages/google-cloud-dns/package.json

+3
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,10 @@
5656
"dns-zonefile": "0.2.2",
5757
"extend": "^3.0.0",
5858
"is": "^3.0.1",
59+
"lodash.flatten": "^4.4.0",
60+
"lodash.groupby": "^4.6.0",
5961
"methmeth": "^1.0.0",
62+
"propprop": "^0.3.1",
6063
"string-format-obj": "^1.0.0"
6164
},
6265
"devDependencies": {

packages/google-cloud-dns/src/zone.js

+34-5
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@ var arrify = require('arrify');
2020
var common = require('@google-cloud/common');
2121
var exec = require('methmeth');
2222
var extend = require('extend');
23+
var flatten = require('lodash.flatten');
2324
var fs = require('fs');
25+
var groupBy = require('lodash.groupby');
2426
var is = require('is');
27+
var prop = require('propprop');
2528
var util = require('util');
2629
var zonefile = require('dns-zonefile');
2730

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

345-
var body = extend({}, config, {
346-
additions: arrify(config.add).map(exec('toJSON')),
347-
deletions: arrify(config.delete).map(exec('toJSON')),
348-
});
349-
348+
var body = extend(
349+
{
350+
additions: groupByType(arrify(config.add).map(exec('toJSON'))),
351+
deletions: groupByType(arrify(config.delete).map(exec('toJSON'))),
352+
},
353+
config
354+
);
350355
delete body.add;
351356
delete body.delete;
352357

358+
function groupByType(changes) {
359+
changes = groupBy(changes, 'type');
360+
361+
var changesArray = [];
362+
363+
for (var recordType in changes) {
364+
var recordsByName = groupBy(changes[recordType], 'name');
365+
366+
for (var recordName in recordsByName) {
367+
var records = recordsByName[recordName];
368+
var templateRecord = extend({}, records[0]);
369+
370+
if (records.length > 1) {
371+
// Combine the `rrdatas` values from all records of the same type.
372+
templateRecord.rrdatas = flatten(records.map(prop('rrdatas')));
373+
}
374+
375+
changesArray.push(templateRecord);
376+
}
377+
}
378+
379+
return changesArray;
380+
}
381+
353382
this.request(
354383
{
355384
method: 'POST',
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
$TTL 3600
22
{DNS_DOMAIN} 21600 IN SPF "v=spf1" "mx:{DNS_DOMAIN}" "-all"
33
{DNS_DOMAIN} IN TXT "google-site-verification=xxxxxxxxxxxxYYYYYYXXX"
4+
{DNS_DOMAIN} 21600 MX 10 mail.example.com.
5+
{DNS_DOMAIN} 21600 MX 30 mail.example.com.
6+
{DNS_DOMAIN} A 128.9.0.32
7+
A 10.1.0.52
8+
{DNS_DOMAIN} A 10.2.0.27
9+
A 128.9.0.33

packages/google-cloud-dns/test/zone.js

+52-26
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,15 @@
1818

1919
var arrify = require('arrify');
2020
var assert = require('assert');
21+
var exec = require('methmeth');
2122
var extend = require('extend');
23+
var flatten = require('lodash.flatten');
2224
var nodeutil = require('util');
25+
var prop = require('propprop');
2326
var proxyquire = require('proxyquire');
2427
var ServiceObject = require('@google-cloud/common').ServiceObject;
2528
var util = require('@google-cloud/common').util;
29+
var uuid = require('uuid');
2630

2731
var promisified = false;
2832
var fakeUtil = extend({}, util, {
@@ -192,26 +196,33 @@ describe('Zone', function() {
192196
});
193197

194198
describe('createChange', function() {
199+
function generateRecord(recordJson) {
200+
recordJson = extend(
201+
{
202+
name: uuid.v1(),
203+
type: uuid.v1(),
204+
rrdatas: [uuid.v1(), uuid.v1()],
205+
},
206+
recordJson
207+
);
208+
209+
return {
210+
toJSON: function() {
211+
return recordJson;
212+
},
213+
};
214+
}
215+
195216
it('should throw error if add or delete is not provided', function() {
196217
assert.throws(function() {
197218
zone.createChange({}, util.noop);
198219
}, /Cannot create a change with no additions or deletions/);
199220
});
200221

201222
it('should parse and rename add to additions', function(done) {
202-
var recordsToAdd = [
203-
{
204-
toJSON: function() {
205-
return 'a';
206-
},
207-
},
208-
{
209-
toJSON: function() {
210-
return 'a';
211-
},
212-
},
213-
];
214-
var expectedAdditions = ['a', 'a'];
223+
var recordsToAdd = [generateRecord(), generateRecord()];
224+
225+
var expectedAdditions = recordsToAdd.map(exec('toJSON'));
215226

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

225236
it('should parse and rename delete to deletions', function(done) {
226-
var recordsToDelete = [
227-
{
228-
toJSON: function() {
229-
return 'a';
230-
},
231-
},
232-
{
233-
toJSON: function() {
234-
return 'a';
235-
},
236-
},
237-
];
238-
var expectedDeletions = ['a', 'a'];
237+
var recordsToDelete = [generateRecord(), generateRecord()];
238+
239+
var expectedDeletions = recordsToDelete.map(exec('toJSON'));
239240

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

250+
it('should group changes by name and type', function(done) {
251+
var recordsToAdd = [
252+
generateRecord({name: 'name.com.', type: 'mx'}),
253+
generateRecord({name: 'name.com.', type: 'mx'}),
254+
];
255+
256+
zone.request = function(reqOpts) {
257+
var expectedRRDatas = flatten(
258+
recordsToAdd.map(exec('toJSON')).map(prop('rrdatas'))
259+
);
260+
261+
assert.deepStrictEqual(reqOpts.json.additions, [
262+
{
263+
name: 'name.com.',
264+
type: 'mx',
265+
rrdatas: expectedRRDatas,
266+
},
267+
]);
268+
269+
done();
270+
};
271+
272+
zone.createChange({add: recordsToAdd}, assert.ifError);
273+
});
274+
249275
it('should make correct API request', function(done) {
250276
zone.request = function(reqOpts) {
251277
assert.strictEqual(reqOpts.method, 'POST');

0 commit comments

Comments
 (0)