diff --git a/tests/domain-service.test.js b/tests/domain-service.test.js index 79ea1d1e2..077aa4ea2 100644 --- a/tests/domain-service.test.js +++ b/tests/domain-service.test.js @@ -263,8 +263,8 @@ describe('Domain service', () => { ]); expect(removeZone).toHaveBeenCalledTimes(2); expect(getRecordCalls(removeZone)).toEqual([ - { line: 2 }, { line: 3 }, + { line: 2 }, ]); }); @@ -277,6 +277,9 @@ describe('Domain service', () => { { line: 5, name: 'c', type: 'MX', address: 'mx1.hello.com', priority: 20 }, { line: 6, name: 'c', type: 'MX', address: 'mx2.hello.com', priority: 21 }, { line: 7, name: 'b', type: 'MX', address: 'foo.bar', priority: 20 }, + { line: 101, name: 'x', type: 'A', address: '1' }, + { line: 99, name: 'y', type: 'A', address: '2' }, + { line: 100, name: 'z', type: 'A', address: '3' }, ]; const redirections = [ { domain: `b.${DOMAIN_DOMAIN}`, destination: 'https://foobar.com' }, @@ -306,8 +309,11 @@ describe('Domain service', () => { { name: 'b', type: 'A', address: '3' }, { name: 'd', type: 'CNAME', address: 'helo.com' }, ]); - expect(removeZone).toHaveBeenCalledTimes(1); + expect(removeZone).toHaveBeenCalledTimes(4); expect(getRecordCalls(removeZone)).toEqual([ + { line: 101 }, + { line: 100 }, + { line: 99 }, { line: 1 }, ]); @@ -317,8 +323,8 @@ describe('Domain service', () => { ]); expect(removeEmail).toHaveBeenCalledTimes(2); expect(getRecordCalls(removeEmail)).toEqual([ - { domain: 'c.is-a.dev', exchanger: 'mx1.hello.com', priority: 20 }, { domain: 'b.is-a.dev', exchanger: 'foo.bar', priority: 20 }, + { domain: 'c.is-a.dev', exchanger: 'mx1.hello.com', priority: 20 }, ]); expect(addRedir).toHaveBeenCalledTimes(3); diff --git a/utils/domain-service.js b/utils/domain-service.js index 81421f7aa..e66099db1 100644 --- a/utils/domain-service.js +++ b/utils/domain-service.js @@ -1,6 +1,6 @@ const R = require('ramda'); const { cpanel } = require('./lib/cpanel'); -const { DOMAIN_DOMAIN } = require('./constants'); +const { DOMAIN_DOMAIN, VALID_RECORD_TYPES } = require('./constants'); const { then, log, print, lazyTask, batchLazyTasks } = require('./helpers'); const BATCH_SIZE = 1; @@ -23,7 +23,7 @@ const recordToZone = ({ name, type, address, id, priority }) => ({ }); const cleanName = name => - name === DOMAIN_DOMAIN ? '@' : `${name}`.replace(new RegExp(`\\.${DOMAIN_DOMAIN}\\.?$`), '').toLowerCase(); + name === DOMAIN_DOMAIN ? '@' : `${name}`.replace(new RegExp(`\\.?${DOMAIN_DOMAIN}\\.?$`), '').toLowerCase(); const zoneToRecord = ({ name, @@ -85,9 +85,21 @@ const executeBatch = (batches) => batches.reduce((promise, batch, index) => { }); }, Promise.resolve()); +const isReserved = (domain) => + !domain.name || + domain.name.startsWith('*') || + !VALID_RECORD_TYPES.includes(domain.type) + const getDomainService = ({ cpanel }) => { - const fetchZoneRecords = R.compose(then(R.map(zoneToRecord)), cpanel.zone.fetch); - const fetchRedirections = R.compose(then(R.map(redirectionToRecord)), cpanel.redirection.fetch); + const fetchZoneRecords = R.compose( + then(R.filter(R.complement(isReserved))), + then(R.map(zoneToRecord)), + cpanel.zone.fetch + ); + const fetchRedirections = R.compose( + then(R.map(redirectionToRecord)), + cpanel.redirection.fetch + ); const addZoneRecord = lazyTask(R.compose( R.ifElse(R.propEq('type', 'MX'), @@ -120,15 +132,20 @@ const getDomainService = ({ cpanel }) => { const getHosts = () => Promise.all([fetchZoneRecords(), fetchRedirections()]).then(R.flatten); - const addRecords = R.compose(batchLazyTasks(BATCH_SIZE), R.filter(Boolean), R.map(R.cond([ - [R.propEq('name', 'www'), R.always(null)], // Ignore www - [R.propEq('type', 'URL'), addRedirection], - [R.T, addZoneRecord], - ]))); - const removeRecords = R.compose(batchLazyTasks(BATCH_SIZE), R.map(R.cond([ - [R.propEq('type', 'URL'), removeRedirection], - [R.T, removeZoneRecord], - ]))); + const addRecords = R.compose( + batchLazyTasks(BATCH_SIZE), + R.filter(Boolean), + R.map(R.cond([ + [R.propEq('name', 'www'), R.always(null)], // Ignore www + [R.propEq('type', 'URL'), addRedirection], + [R.T, addZoneRecord], + ])), + ); + const removeRecords = R.compose( + batchLazyTasks(BATCH_SIZE), + R.map(R.cond([ [ R.propEq('type', 'URL'), removeRedirection ], [ R.T, removeZoneRecord ] ])), + R.sort((a, b) => b.id - a.id) + ); const updateHosts = async hosts => { const remoteHostList = await getHosts(); diff --git a/utils/lib/cpanel.js b/utils/lib/cpanel.js index 5c098f281..e61b15a0f 100644 --- a/utils/lib/cpanel.js +++ b/utils/lib/cpanel.js @@ -37,7 +37,7 @@ const CpanelClient = (options) => { // -> [{ class, ttl, name, line, Line, cname, type, record }] fetch: R.compose( p => p.then(R.pathOr([], ['cpanelresult', 'data'])), - api2('ZoneEdit', 'fetchzone_records', { customonly: 1, domain: options.domain }) + api2('ZoneEdit', 'fetchzone_records', { customonly: 0, domain: options.domain }) ), // { name, type(A|CNAME), cname, address, ttl }