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() { console.log(`[CFDNS] Fetching IP from https://api.ipify.org`) const res = await request('https://api.ipify.org?format=json') const { ip } = JSON.parse(res) return ip } async function getRecord(zone_id, domain, opts) { const params = new URLSearchParams() params.set('type', 'A') params.set('name', domain) const parts = await request(gurl(`zones/${ zone_id }/dns_records?${ params.toString() }`), opts) const json = JSON.parse(parts) return json.result[0] } async function setRecordIp(zone_id, record, ip, opts, ctx = {}) { 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, } return request(url, { method, json, ...opts, }) } async function createRecord(zone_id, domain, ip, opts, ctx = {}) { const url = gurl(`zones/${ zone_id }/dns_records`) const method = 'POST' const json = { type: 'A', name: domain, content: ip, proxies: true, ...ctx, } return request(url, { method, json, ...opts, }) } async function main() { const config = await fs.readAsync('./config.json', 'json') const { zone_id, token, hosts } = config const requestOpts = { headers: { "Authorization": `Bearer ${ token }`, }, } const ip = await getIp() console.log('[CFDNS] Using IP %s for all domains', ip) for (const entry of hosts) { const { name } = entry const record = await getRecord(zone_id, name, requestOpts) if (record) { if (record.content === ip) { console.log('[CFDNS] Skipping %s', name) continue } console.log('[CFDNS] Updating record for %s', name) await setRecordIp(zone_id, record, ip, requestOpts, entry) } else { console.log('[CFDNS] Creating new record for %s', name) await createRecord(zone_id, name, ip, requestOpts, entry) } } } main()