@linkedmink/node-route53-dynamic-dns
Version:
Background process that updates AWS Route 53 DNS address records whenever the public IP of the hosting environment changes
62 lines • 2.7 kB
JavaScript
import EventEmitter from "events";
import { DnsRecordsEvent } from "../constants/events.mjs";
import { loggerForModuleUrl } from "../environment/logger.mjs";
import { validateNormalizeDnsRecord } from "../functions/validate.mjs";
export class Route53DnsRecordSetStore extends EventEmitter {
client;
isRecordsCached;
logger = loggerForModuleUrl(import.meta.url);
dnsRecordsToUpdate;
zoneRecordSets = [];
hasRetrievedFirstRecordSets = false;
constructor(client, isRecordsCached, hostnames) {
super();
this.client = client;
this.isRecordsCached = isRecordsCached;
this.dnsRecordsToUpdate = hostnames.map(validateNormalizeDnsRecord);
}
getRecords = async () => {
if (this.isRecordsCached && this.hasRetrievedFirstRecordSets) {
return this.zoneRecordSets;
}
this.zoneRecordSets = await this.client.getZoneRecords(this.dnsRecordsToUpdate);
if (this.zoneRecordSets.length <= 0) {
// Only throw an error when this is the first record set since that probably indicates a misconfiguration.
// During operations the records may change, and we want to keep the service running to recover on the next update.
const message = `No zones were found matching the input record: ${this.dnsRecordsToUpdate.toString()}`;
if (!this.hasRetrievedFirstRecordSets) {
throw new Error(message);
}
this.logger.error(message);
}
this.hasRetrievedFirstRecordSets = true;
this.emitDnsRecordState(DnsRecordsEvent.Retrieved);
return this.zoneRecordSets;
};
updateRecordsAfterSync = (updatedRecordsSets, updateStatuses) => {
this.zoneRecordSets = this.zoneRecordSets.map(z => {
const hasSucceeded = updateStatuses.get(z.zoneId);
if (hasSucceeded) {
const updated = updatedRecordsSets.find(u => u.zoneId === z.zoneId);
if (updated) {
return { ...updated };
}
}
return { ...z };
});
this.emitDnsRecordState(DnsRecordsEvent.Updated);
};
emitDnsRecordState = (event) => {
const dnsRecordsEvent = {
dnsRecords: this.zoneRecordSets.flatMap(z => z.records.map(r => ({
name: r.Name,
type: r.Type,
value: r.ResourceRecords[0].Value,
}))),
lastChangeDateTime: new Date(),
};
this.logger.verbose(`${event}: #zones=${this.zoneRecordSets.length}`);
this.emit(event, dnsRecordsEvent);
};
}
//# sourceMappingURL=dns-record-set-source.mjs.map