Node.js: how to manage a DNS zone on Cloudflare

Node.js: how to manage a DNS zone on Cloudflare

In this article we're going to manage a DNS zone in Cloudflare with Node.js.

In this article we're going to manage a DNS zone in Cloudflare with Node.js.

Cloudflare provides us with a complete API to manage all of the routines behind its services. These APIs make use of a Bearer token that we need to generate in our user area.

The Cloudflare's APIs are RESTful, which means that they use the JSON data format in the HTTP requests and responses.

First we need to write a utility function in order to perform HTTP requests.


    'use strict';

    const https = require('https');
    const TOKEN = 'your API token';
    
    const request = (data = null, method = 'GET', endpoint = '') => {
        const options = {
            hostname: 'api.cloudflare.com',
            port: 443,
            path: '/client/v4/' + endpoint,
            method: method,
            headers: {
                'Content-Type': 'application/json',
                'Authorization': 'Bearer ' + TOKEN
            }
        };
    
        if(method !== 'GET' && data !== null) {
            const json = JSON.stringify(data);
            options.headers['Content-Length'] = json.length;
        }
    
        return new Promise((resolve, reject) => {
            const req = https.request(options, res => {
                let body = '';
                res.on('data', d => {
                    body += d;
                });
                res.on('end', () => {
                   resolve(JSON.parse(body));
                });
            });
    
            req.on('error', err => {
                reject(err);
            });
    
            if(method !== 'GET' && data !== null) {
                req.write(JSON.stringify(data));
            }
    
            req.end();
        });
    };
    

Now we define a class that will take care of handling a DNS zone.


class Cloudflare {
    static async getDNSZones(req, res) {
       try {
           const response = await  request(null, 'GET', 'zones');
           res.json(response);
       } catch(err) {
           res.json(err);
       }
    }
    static async getDNSZoneRecords(req, res) {
        const { id } = req.body;
        try {
            const response = await  request(null, 'GET', `zones/${id}/dns_records`);
            res.json(response);
        } catch(err) {
            res.json(err);
        }
    }

    static async addDNSRecord(req, res) {
        const { id, name, content, priority, ttl, type } = req.body;
        const prior = parseInt(priority, 10);
        const data = { name, content, priority: prior, ttl, type };
        try {
            const response = await  request(data, 'POST', `zones/${id}/dns_records`);
            res.json(response);
        } catch(err) {
            res.json(err);
        }

    }

    static async deleteDNSRecord(req, res) {
        const { zone_id, record_id } = req.body;
        try {
            const response = await  request(null, 'DELETE', `zones/${zone_id}/dns_records/${record_id}`);
            res.json(response);
        } catch(err) {
            res.json(err);
        }
    }
}

module.exports = Cloudflare;

A DNS zone has an unique ID. DNS records have also their unique IDs, so we need to pass these IDs to Cloudflare if we want to add, delete or update DNS records within a zone.

The last thing we need to do is to add our class to our final application.


'use strict';

const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const port = process.env.PORT || 3000;
const app = express();
const Cloudflare = require('./classes/Cloudflare');


app.disable('x-powered-by');

app.use('/public', express.static(path.join(__dirname, '/public'), {
    maxAge: 0,
    dotfiles: 'ignore',
    etag: false
}));

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

app.get('/', (req, res) => {
   res.sendFile(path.join(__dirname) + '/views/index.html');
});

app.get('/api/dns-zones', Cloudflare.getDNSZones);
app.post('/api/zone-records', Cloudflare.getDNSZoneRecords);
app.post('/api/add-record', Cloudflare.addDNSRecord);
app.post('/api/delete-record', Cloudflare.deleteDNSRecord);


if (app.get('env') === 'development') {
    app.use((err, req, res, next) => {
        res.status(err.status || 500);
    });
}

app.use((err, req, res, next) => {
    res.status(err.status || 500);
});

app.listen(port);

Conclusion

The RESTful Cloudflare's API are a more than an effective way to manage DNS zones on the Cloudflare platform.

Source code

GitHub