Skip to content
Snippets Groups Projects
index.js 2.01 KiB
Newer Older
Louis's avatar
Louis committed
const fs = require('fs-jetpack')
const request = require('request-promise-native')

const base = 'https://api.cloudflare.com/client/v4/'
const gurl = ep => `${ base }${ ep }`

async function getIp() {
Louis's avatar
Louis committed
	console.log(`[CFDNS] Fetching IP from https://api.ipify.org`)
Louis's avatar
Louis committed
	const res = await request('https://api.ipify.org?format=json')
	const { ip } = JSON.parse(res)
	return ip
}

async function getRecord(zone_id, domain, opts) {
Louis's avatar
Louis committed
	const params = new URLSearchParams()
	params.set('type', 'A')
	params.set('name', domain)
Louis's avatar
Louis committed

Louis's avatar
Louis committed
	const parts = await request(gurl(`zones/${ zone_id }/dns_records?${ params.toString() }`), opts)
Louis's avatar
Louis committed
	const json = JSON.parse(parts)
	return json.result[0]
}

async function setRecordIp(zone_id, record, ip, opts, ctx = {}) {
Louis's avatar
Louis committed
	const url = gurl(`zones/${ zone_id }/dns_records/${ record.id }`)
	const method = 'PUT'
	const json = {
		type: 'A',
		name: record.name,
		content: ip,
		proxied: true,
		...ctx,
Louis's avatar
Louis committed
	}
Louis's avatar
Louis committed

Louis's avatar
Louis committed
	return request(url, {
		method,
		json,
		...opts,
	})
async function createRecord(zone_id, domain, ip, opts, ctx = {}) {
Louis's avatar
Louis committed
	const url = gurl(`zones/${ zone_id }/dns_records`)
	const method = 'POST'
	const json = {
		type: 'A',
		name: domain,
		content: ip,
		proxies: true,
		...ctx,
Louis's avatar
Louis committed
	}
Louis's avatar
Louis committed

Louis's avatar
Louis committed
	return request(url, {
		method,
		json,
		...opts,
	})
Louis's avatar
Louis committed
}

async function main() {
Louis's avatar
Louis committed
	const config = await fs.readAsync('./config.json', 'json')
	const { zone_id, token, hosts } = config
Louis's avatar
Louis committed

Louis's avatar
Louis committed
	const requestOpts = {
		headers: {
			"Authorization": `Bearer ${ token }`,
		},
	}
Louis's avatar
Louis committed

Louis's avatar
Louis committed
	const ip = await getIp()
Louis's avatar
Louis committed

Louis's avatar
Louis committed
	console.log('[CFDNS] Using IP %s for all domains', ip)
Louis's avatar
Louis committed

Louis's avatar
Louis committed
	for (const entry of hosts) {
		const { name } = entry
		const record = await getRecord(zone_id, name, requestOpts)
Louis's avatar
Louis committed
		if (record) {
			if (record.content === ip) {
				console.log('[CFDNS] Skipping %s', name)
Louis's avatar
Louis committed
				continue
			}
			console.log('[CFDNS] Updating record for %s', name)
			await setRecordIp(zone_id, record, ip, requestOpts, entry)
Louis's avatar
Louis committed
		} else {
			console.log('[CFDNS] Creating new record for %s', name)
			await createRecord(zone_id, name, ip, requestOpts, entry)
Louis's avatar
Louis committed
		}
	}
Louis's avatar
Louis committed
}

main()