Skip to content

Commit

Permalink
Remove hostedZoneID configuration parameter. This is no longer requir…
Browse files Browse the repository at this point in the history
…ed to be set upfront. Instead the hostedZoneID will be discovered in route53 based on the ddnsHostName config param
  • Loading branch information
jmb12686 committed Mar 26, 2019
1 parent aef1317 commit 1eaa92f
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 80 deletions.
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ Modify the following configuration parameters in config.json:

`ddnsHostName` - Domain name, owned in Route 53, that you want to keep updated with a dynamic IP.

`ddnsHostedZoneID` - Route53 hostedZoneID of ddnsHostName referenced above

`notificationTopicARN` - TopicARN, in SNS, that you wish to receive notifications on. Notifications are sent upon a successful DDNS update or failed attempt.


Expand Down Expand Up @@ -50,5 +48,3 @@ POST 'homeIp' JSON to API endpoint with AWS IAM Signature. User api user is cre

## TODO
1) Eliminate topicARN requirement, and instead send to arbitrary email and/or SMS

2) eliminate HostedZoneID requirement and install to search in route53 based on ddnsHostName
1 change: 0 additions & 1 deletion config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{
"apiDomainName": "",
"ddnsHostName": "",
"ddnsHostedZoneID": "",
"notificationTopicARN": ""
}
44 changes: 0 additions & 44 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
"author": "John Belisle",
"license": "ISC",
"devDependencies": {
"serverless-aws-alias": "^1.7.1",
"serverless-domain-manager": "^3.2.1"
}
}
2 changes: 0 additions & 2 deletions serverless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ custom:

plugins:
- serverless-domain-manager
# - serverless-aws-alias

# you can add packaging information here
#package:
Expand All @@ -50,7 +49,6 @@ functions:
memorySize: 128
environment:
DNS_HOST_NAME: ${self:custom.config.ddnsHostName}
HOSTED_ZONE_ID: ${self:custom.config.ddnsHostedZoneID}
TOPIC_ARN: ${self:custom.config.notificationTopicARN}
events:
- http:
Expand Down
68 changes: 59 additions & 9 deletions src/scripts/updateDNSScript.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
'use strict'

class UpdateDNSScript {
constructor(route53, notificationScript, hostedZoneID, hostName) {
constructor(route53, notificationScript, hostName) {
this.route53 = route53;
this.hostedZoneID = hostedZoneID;
this.hostName = hostName;
this.notificationScript = notificationScript;
}


async update(newIP) {
const currentIP = await this.getCurrentIP();
console.log("currentIP in route53 = " + currentIP);
const route53HostedZoneId = await this.getRoute53HostedZoneId();
console.log("found matching hostedZoneId: " + route53HostedZoneId + " for hostName: " + this.hostName);
const currentIP = await this.getCurrentIP(route53HostedZoneId, this.hostName);
console.log("currentIP for hostName: " + this.hostName + " in route53 = " + currentIP);
if (newIP === currentIP) {
console.log("IP has not changed for hostName: [" + this.hostName + "], exiting...");
return "Success - No Change";
} else {
console.log("IP has changed for hostName: [" + this.hostName + "], issuing recordSet UPSERT");
const updateRequest = this.getUpdateRequest(this.hostedZoneID, this.hostName, newIP);
const updateRequest = this.getUpdateRequest(route53HostedZoneId, this.hostName, newIP);
try {
const result = await this.route53.changeResourceRecordSets(updateRequest).promise();
console.log("Successfully changed [" + this.hostName + "] IP to " + newIP + ". Result from route53 changeResourceRecordSets:" + JSON.stringify(result, null, 2));
Expand All @@ -32,11 +33,11 @@ class UpdateDNSScript {
}
}

async getCurrentIP() {
console.log("QUerying route53 for record set with hostName: " + this.hostName);
async getCurrentIP(hostedZoneID, hostName) {
console.log("Querying route53 for record set with hostName: " + hostName);
var params = {
HostedZoneId: this.hostedZoneID,
StartRecordName: this.hostName,
HostedZoneId: hostedZoneID,
StartRecordName: hostName,
MaxItems: '1'
};
var data = await this.route53.listResourceRecordSets(params).promise();
Expand Down Expand Up @@ -65,6 +66,55 @@ class UpdateDNSScript {
}
};
}


/**
* Gets Route53 HostedZoneId from from AWS
*/
async getRoute53HostedZoneId() {
let hostedZoneData;
const givenDomainNameReverse = this.hostName.split(".").reverse();

try {
hostedZoneData = await this.route53.listHostedZones({}).promise();
const targetHostedZone = hostedZoneData.HostedZones
.filter((hostedZone) => {
let hostedZoneName;
if (hostedZone.Name.endsWith(".")) {
hostedZoneName = hostedZone.Name.slice(0, -1);
} else {
hostedZoneName = hostedZone.Name;
}
const hostedZoneNameReverse = hostedZoneName.split(".").reverse();

if (givenDomainNameReverse.length === 1
|| (givenDomainNameReverse.length >= hostedZoneNameReverse.length)) {
for (let i = 0; i < hostedZoneNameReverse.length; i += 1) {
if (givenDomainNameReverse[i] !== hostedZoneNameReverse[i]) {
return false;
}
}
return true;
}
return false;
})
.sort((zone1, zone2) => zone2.Name.length - zone1.Name.length)
.shift();

if (targetHostedZone) {
const hostedZoneId = targetHostedZone.Id;
// Extracts the hostzone Id
const startPos = hostedZoneId.indexOf("e/") + 2;
const endPos = hostedZoneId.length;
return hostedZoneId.substring(startPos, endPos);
}
} catch (err) {
console.log(err, err.stack);
throw new Error(`Error: Unable to list hosted zones in Route53.\n${err}`);
}
throw new Error(`Error: Could not find hosted zone "${this.hostName}"`);
};

}

module.exports = UpdateDNSScript;
20 changes: 1 addition & 19 deletions src/updateHomeDNS.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ const NotificationScript = require('./scripts/notificationScript');
const notificationScript = new NotificationScript(sns, process.env.TOPIC_ARN);

const UpdateDNSScript = require('./scripts/updateDNSScript');
const updateDNSScript = new UpdateDNSScript(route53, notificationScript, process.env.HOSTED_ZONE_ID, process.env.DNS_HOST_NAME);
// const updateDNSScript = require('./scripts/updateDNSScript')(route53, notificationScript, process.env.HOSTED_ZONE_ID, process.env.DNS_HOST_NAME);
const updateDNSScript = new UpdateDNSScript(route53, notificationScript, process.env.DNS_HOST_NAME);



Expand All @@ -41,21 +40,4 @@ async function processRequest(event) {
var homeIp = requestBody['homeIp'];
var responseMsg = await updateDNSScript.update(homeIp);
return responses.success(responseMsg);


}




// return {
// statusCode: 200,
// body: JSON.stringify({
// message: 'Go Serverless v1.0! Your function executed successfully!',
// input: event,
// }),
// };

// Use this code if you don't use the http event with the LAMBDA-PROXY integration
// return { message: 'Go Serverless v1.0! Your function executed successfully!', event };
// };

0 comments on commit 1eaa92f

Please sign in to comment.