Programmatically adding DNS entries to DNSimple using Node

Programmatically adding DNS entries to DNSimple using Node

We had a case where each customer would get their own sub-domain. Let's say Nokia would be one of the clients. They would get nokia.ourapp.com and it would point to our front-end service using CNAME record. The nice thing for the user is that when they want to access our software they just need to write their own company to the address bar and the browser will immediately suggest url from the browser history. It's easier to remember where you're working than one of many services used daily.

In the first phase we added each new customer using our DNS service's user-interface. The creation of new customer had other steps, such as create database for the customer, initial data etc. We started from automation of the DNS handling.

DNSimple

Important thing first: I don't have any kind of partnership with DNSimple. I am just a happy customer writing about the experience that I had with DNSimple and using their API. I have a affiliate link at the bottom of the page if you want to support this site. All the other links are free of tracking codes etc.

Back to the point.. After you have created account and transferred/registered a domain you're ready to get a token that is used for authentication. There are two types of tokens: Domain and API.

Domain token is used to identify single domain inside one account. API token is unique for one account. In this example we're modifying single domain which means that domain specific token is enough.

Domain API token can be found from the Domain -> Settings:

Domain -> Settings DNSimple Domain API token

Authentication

Before we can make CRUD operations to our DNS entries we need to authenticate. DNSimple web-site has a comprehensive section for the authentication. You can test your API / Domain token using curl.

curl  -H 'X-DNSimple-Domain-Token: 1234567890' \
  -H 'Accept: application/json' \
  https://api.dnsimple.com/v1/domains/example.com

Let's turn that curl snippet to JavaScript source code.

Before we make any requests..

In the example we're using few libraries: Bluebird for promises, lo-dash for utility functions and Request for .. hmm .. requests.

Let's require those first:

var Promise = require('bluebird');
var request = Promise.promisifyAll(require('request'));
var _ = require('lodash');

Let's make three config objects:

  • information about API caller
  • new DNS record data
  • DNSimple API urls

The objects look like this:

var settings = {
  user: {
    email: ''
  },
  domain: {
    token: '',
    name: ''
  }
};

var recordToCreate = {
  name: '',
  record_type: 'CNAME',
  content: ''
}

var api = {
  getToken: _.template('https://api.dnsimple.com/v1/domains/<%= domain %>'),
  createRecord: _.template('https://api.dnsimple.com/v1/domains/<%= domain %>/records')
};

Now we're ready to make some requests to the API!

Get authentication Token

I lied a little bit when I said that there are two types of tokens. The third one you'll get after authentication and it's part of the response. Bluebird creates asynchronous version of request.get().

request.getAsync({
  url: api.getToken({ domain: settings.domain.name }),
  headers: {
    'X-DNSimple-Domain-Token': settings.domain.token
  }
})    

The url is coming from the api object that contains underscore templates. The template output should look like: https://api.dnsimple.com/v1/domains/my_example_domain.

X-DNSimple-Domain-Token header is set exactly like in the curl example.

getAsync returns a promise, so we need add handler for the response.

.spread(function(response, body) {
  if (response.statusCode >= 400 && response.statusCode < 500) {
    throw new ClientError(response.statusCode);
  }

  var content = JSON.parse(body);
  return content.domain.token;
})

The last two lines inside the function shows you how to get authentication token from successfully parsed response!

Creating new record

Our previous promise returns token. This makes life easy because we can now write simple .then block that receives that token.

.then(function (token) {
  return request.postAsync({
    url: api.createRecord({ domain: settings.domain.name }),
    body: {
      record: recordToCreate
    },
    json: true,
    headers: {
      'Accept': 'application/json',
      'X-DNSimple-Token': settings.user.email + ':' + token
    }
  });
})

POST to the API looks quite similar to our previous GET operation. This time we're not using Domain / API token. We're getting the access token as a function argument and that combined with email address gives us modification rights to the domain.

After successful creation of a record you should get status code 201.

Full source code of the example can be found from here.

If you're interested about DNSimple and want to support this blog use this affiliate link.