CoolingTower Naming service configuration and usage

The Naming service is a part of the cooling tower api that allows you to register server names for DNS via a simple RESTful api. It is designed to be used internally to cooling tower as part of application deployment - but a RESTful api to a DNS service will probably find other uses so it is documented here.

Configuration

To use the naming service/api, you will need to know an IP/server address of at least one DNS server that will be acting as the primary DNS server for your cloud. You will also need to specify a location where Cooling Tower can store the zone files (DNS data) - CT must be able to write to these files of course. These are set as for example as  config items:

 

dns-primary 8.8.8.8
dns-secondary 8.4.4.4
dns-zone-folder /etc/opt/zones

 

This could be launched (unsecured) as "mvn jetty:run -Ddns-primary=1.2.3.4 -Ddnz-zone-folder=/usr/shared/dns/zones"

Of course, in practice access to the API would need to be secured carefully (as mentioned above). A DNS service such as this MUST be secured so only system accounts/administrators can access it, even via the command line !

 

Usage

The api is RESTful, using the "HATOAS" style - so you should be able to drive this from the command line "curl" tool if you like (really, any client will do), a summary:

 

GET http://server/api/naming/ will return a list of <link href=".../domains"> - which contains the link to the "domains" service.
GET http://server/api/naming/domains/ will return a list of domains registered - each one has a link with a href to its management URL
GET http://server/api/naming/domains/yourdomain.com will return a list of links with href to the subdomain, and the default address etc
GET http://server/api/naming/domains/yourdomain.com/www will return the current address of that subdomain
POST http://server/api/naming/domains/ with form parameters of name=yourdomain.com will create an initial zone entry for that domain
POST http://server/api/naming/domains/yourdomain.com with form parameters of "subdomain" and "address" - will update the obvious values.
DELELE http://server/api/naming/domains/yourdomain.com/www will remove that subdomain mapping

//and for "services" registry (SRV records)
GET http://server/api/naming/domains/yourdomain.com/services return a list of links to "services" this domain offers
POST http://server/api/naming/domains/yourdomain.com/services service=_service._protocol&port=8080&address=www.service.com

 

 

 

 

Example of using curl from command line:

 

curl -d "name=yourdomain.com" http://ct/api/naming/domains/
curl -d "subdomain=www&address=1.2.3.4" http://ct/api/naming/domains/yourdomain.com
curl -d "subdomain=www&address=1.2.3.5" http://ct/api/naming/domains/yourdomain.com
curl -d "subdomain=default&address=www.yourdomain.com" http://ct/api/naming/domains/yourdomain.com

 

 

The first line will setup the "yourdomain.com" domain in the system (but with no details other than the minimum such as serial number, dns servers(s) for the site etc)

The second line maps www.yourdomain.com to 1.2.3.4 - note you can use an IP or another domain name. CT will automatically work out if it is a name, and make it a "CNAME" entry for it (you don't worry about that).

The third line is similar, but updates it to a new address. The last line sets the default - so in that case "youdomain.com" is the same as "www.yourdomain.com".

 

 

Deployment with DNS

CoolilngTower provides the management service - to deploy to a DNS service there are a few options depending on the needs. The simplest way, is to use EagleDNS. As part of CoolingTower, EagleDNS has been enhanced to monitor for zone file changes and reload the DNS cache immediately, thus making it an ideal fast DNS for easy deployment. EagleDNS is a java application and trivially easy to install and run.

 

You can find eagle dns here. And download it here. Eagle DNS has a configuration file - you can use the FileZoneProvider configuration, and point it to the "dnz-zone-folder" path as mentioned above, and it will load the changes dynamically.

 

Other options are to rsync zone files to a BIND or similar DNS service - typically thinking of those servers as "slave/slave" servers (with the "master" being the hidden CT service). Another approach is to use EagleDNS as a hidden "master" DNS, with BIND or other DNS servers using "zone transfers" from the hidden master (so it is "master/slave/slave") - these latter configurations can be most secure - as you are only exposing read-only DNS servers to the outside world (as a general rule all these servers are "authoritative only" - as in they are only containing name data for the cloud domain).

 

<Ed: needs more explanation, scary?>

 

Finally when you register your domain with a domain provider (registrar) - you will need to tell it that the DNS for that domain is the DNS servers set up above (eg EagleDNS) - this applies to public internet apps as well as intranet applications

 

More examples

The following is copied from the test suite:

 

 post("/naming/domains",  "name=samplezone.org")
     get ("/naming/domains/samplezone.org").body shouldContain <link href="/api/naming/domains/samplezone.org/default" rel="address" />
     get ("/naming/domains/samplezone.org").body shouldContain <link href="/api/naming/domains/samplezone.org/zoneFile" rel="file" />
     get ("/naming/domains/samplezone.org/zoneFile").body shouldContain "SOA"

     get ("/naming/domains/samplezone.org/default").body shouldBe ""
     post("/naming/domains/samplezone.org/default", "address=1.2.3.4")
     get ("/naming/domains/samplezone.org/default").body shouldBe "1.2.3.4"
     post("/naming/domains/samplezone.org/default", "address=1.2.3.5")
     post("/naming/domains/samplezone.org/default", "1.2.3.6".getBytes, "test/plain")
     get ("/naming/domains/samplezone.org/default").body shouldBe "1.2.3.6"

     post("/naming/domains/samplezone.org", "subdomain=www&address=2.2.2.2")
     get ("/naming/domains/samplezone.org/www").body shouldBe "2.2.2.2"
     post("/naming/domains/samplezone.org", "subdomain=www&address=2.2.2.3")
     get ("/naming/domains/samplezone.org/www").body shouldBe "2.2.2.3"
     post("/naming/domains/samplezone.org/www", "address=2.2.2.2")
     get ("/naming/domains/samplezone.org/www").body shouldBe "2.2.2.2"

     post("/naming/domains/samplezone.org/www", "2.2.2.9".getBytes, "text/plain")
     get ("/naming/domains/samplezone.org/www").body shouldBe "2.2.2.9"

     get ("/naming/domains/samplezone.org").body shouldContain <link href="/api/naming/domains/samplezone.org/www" rel="address" />
     delete("/naming/domains/samplezone.org/www")
     get ("/naming/domains/samplezone.org").body shouldNotContain <link href="/api/naming/domains/samplezone.org/www" rel="address" />


    //And for DNS registration of services as per http://en.wikipedia.org/wiki/SRV_record
    get ("/naming/domains/samplezone.org").body shouldContain <link href="/api/naming/domains/samplezone.org/services" rel="services" />

    get    ("/naming/domains/samplezone.org/services").body shouldBe <services/>
    post   ("/naming/domains/samplezone.org/services", "service=_infinispan._http&port=8080&address=www.apple.com")
    get    ("/naming/domains/samplezone.org/services").body shouldBe <services><link href="/api/naming/domains/samplezone.org/services/_infinispan._http" rel="service"/></services>
    get    ("/naming/domains/samplezone.org/services/_infinispan._http").body shouldContain "www.apple.com"
    delete ("/naming/domains/samplezone.org/services/_infinispan._http")
    get    ("/naming/domains/samplezone.org/services").body shouldBe <services/>