Last active
May 24, 2017 18:57
-
-
Save halilim/db9eea2210f0f2ebddb5a2963a378822 to your computer and use it in GitHub Desktop.
Simple AWS Lambda script to notify by SNS if a domain is expiring within 3 days
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Simple AWS Lambda function to notify if the domain halil.im is expiring within 3 days. | |
// Tested on Node.js 6.10 runtime. | |
// * Create an SNS topic and an SNS subscription with the email you want to be notified | |
// * Create the function with a trigger of "CloudWatch Events - Schedule" with rate: 1 day | |
// * Provide the SNS topic ARN to the function as an environment variable | |
// * Create and attach a policy to the role of this function with sns:Publish on the SNS topic ARN | |
// (logs:CreateLogGroup, logs:CreateLogStream & logs:PutLogEvents on a logs ARN should already be there) | |
/* eslint-env node,es6 */ | |
/* eslint no-console: "off" */ | |
'use strict'; | |
const WHOIS_HOST = 'whois.nic.im'; | |
const WHOIS_PORT = 43; | |
const DOMAIN = 'halil.im'; | |
const SNS_TOPIC_ARN = process.env.sns_topic_arn; | |
const net = require('net'); | |
const AWS = require('aws-sdk'); | |
const SNS = new AWS.SNS({ apiVersion: '2010-03-31' }); | |
function SNSpublish(subject, message, errorPrefix) { | |
SNS.publish( | |
{ | |
Subject: subject, | |
Message: message, | |
TopicArn: SNS_TOPIC_ARN, | |
}, | |
(err) => { | |
if (errorPrefix && err) { | |
console.error(`${errorPrefix}: ${err}`); | |
} | |
} | |
); | |
} | |
exports.handler = () => { | |
let socket = new net.Socket(); | |
socket.setTimeout(10000); | |
socket.connect(WHOIS_PORT, WHOIS_HOST, () => { | |
socket.write(`${DOMAIN}\r\n`); | |
}); | |
let received = ''; | |
socket.on('data', (chunk) => { | |
received += chunk; | |
}); | |
socket.on('timeout', () => { | |
socket.destroy(); | |
console.error('The socket timed out'); | |
}); | |
socket.on ('error', (err) => { | |
console.error(`Socket error: ${err}`); | |
}); | |
socket.on('close', () => { | |
if (!received) { | |
console.error('No data received'); | |
SNSpublish('No data received', `No data received querying the domain ${DOMAIN}`); | |
return; | |
} | |
// .im specific | |
let matched = received.match(/Expiry Date: 0?(\d+)\/0?(\d+)\/(\d+)/mi); | |
if (!matched) { | |
const errTitle = "Couldn't detect the expiry date"; | |
const errMsg = `${errTitle}, the format might have changed. Received data:\n${received}`; | |
console.error(errMsg); | |
SNSpublish(errTitle, errMsg); | |
return; | |
} | |
let [, day, month, year] = matched; | |
let expiryDate = new Date(year, month - 1, day); | |
let daysRemaining = Math.round((expiryDate.getTime() - Date.now()) / 86400000); | |
if (daysRemaining <= 3) { | |
SNSpublish( | |
`${DOMAIN} is expiring in ${daysRemaining} days`, | |
`The domain ${DOMAIN} is expiring in ${daysRemaining} days`, | |
"Couldn't publish expiry notification" | |
); | |
} | |
}); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment