Permalink
Browse files

Initial Commit

  • Loading branch information...
0 parents commit 167d573efc1e11a623f4b4dc807c83d40e5dcc77 @bahamas10 committed Aug 18, 2012
Showing with 459 additions and 0 deletions.
  1. +3 −0 .gitignore
  2. +147 −0 README.md
  3. +78 −0 bin/dnsgen.js
  4. +27 −0 example.json
  5. +11 −0 index.js
  6. +77 −0 lib/bind.js
  7. +8 −0 lib/defaults.js
  8. +17 −0 lib/lib.js
  9. +53 −0 lib/tinydns.js
  10. +26 −0 package.json
  11. +4 −0 tests/bind.js
  12. +4 −0 tests/bind_reverse.js
  13. +4 −0 tests/tinydns.js
3 .gitignore
@@ -0,0 +1,3 @@
+npm-debug.log
+node_modules
+tests/config.json
147 README.md
@@ -0,0 +1,147 @@
+DNS Generator
+=============
+
+Generate DNS files using json
+
+Install
+------
+
+Install the command line tool `dnsgen`
+
+ npm install -g dnsgen
+
+Install locally to use as a module
+
+ npm install dnsgen
+
+Usage
+-----
+
+Command line
+
+ dnsgen bind reverse < example.json
+
+As a module
+
+``` js
+var dnsgen = require('dnsgen');
+```
+
+Example
+-------
+
+### Command line tool
+
+The command line tool reads json from stdin, and pipes the output to stdout
+
+ $ dnsgen bind < example.json
+ ; Bind file for example.com (10.0.0.0/23)
+ @ IN SOA ns1.example.com. admin.example.com. (
+ 2012081701 ; serial
+ 28800 ; refresh
+ 7200 ; retry
+ 864000 ; expire
+ 86400 ; ttl
+ )
+ example.com. IN NS ns1.example.com.
+ example.com. IN NS ns2.example.com.
+ gw IN A 10.0.0.1
+ zelda IN A 10.0.0.2 ; Testing Box
+ link IN A 10.0.0.3 ; Another box for testing
+ gw2 IN A 10.0.1.1
+
+You can also generate reverse lookup files
+
+ $ dnsgen bind reverse < example.json
+ ; Bind file for example.com (10.0.0.0/23)
+ @ IN SOA ns1.example.com. admin.example.com. (
+ 2012081701 ; serial
+ 28800 ; refresh
+ 7200 ; retry
+ 864000 ; expire
+ 86400 ; ttl
+ )
+ IN NS ns1.example.com.
+ IN NS ns2.example.com.
+ 0.1 IN PTR gw.example.com.
+ 0.2 IN PTR zelda.example.com. ; Testing Box
+ 0.3 IN PTR link.example.com. ; Another box for testing
+ 1.1 IN PTR gw2.example.com.
+
+Tiny dns is also cool
+
+ $ dnsgen tinydns < example.json
+ # tinydns file for example.com (10.0.0.0/23)
+ Zexample.com:ns1.example.com:admin.example.com:2012081701:28800:7200:864000
+ &example.com::ns1.example.com:86400
+ &example.com::ns2.example.com:86400
+ =gw:10.0.0.1
+ =zelda:10.0.0.2 # Testing Box
+ =link:10.0.0.3 # Another box for testing
+ =gw2:10.0.1.1
+
+### Node Module
+
+The exports of dnsgen return a stream that you can pipe anywhere you want
+
+``` js
+var dnsgen = require('dnsgen'),
+ json = require('./example.json');
+
+// Generate forward lookup file
+dnsgen.bind(json).pipe(process.stdout);
+
+// Generate reverse lookup file
+dnsgen.bindReverse(json).pipe(process.stdout);
+
+// Generate tinydns config
+dnsgen.tinydns(json).pipe(process.stdout);
+```
+
+### example.json
+
+``` json
+{
+ "domain": "example.com",
+ "admin": "admin.example.com",
+ "time": {
+ "refresh": 28800,
+ "retry": 7200,
+ "expire": 864000,
+ "ttl": 86400
+ },
+ "ns": [
+ "ns1.example.com",
+ "ns2.example.com"
+ ],
+ "netmask": "10.0.0.0/23",
+ "hosts": {
+ "10.0.0.1": "gw",
+ "10.0.0.2": {
+ "name": "zelda",
+ "comment": "Testing Box"
+ },
+ "10.0.0.3": {
+ "name": "link",
+ "comment": "Another box for testing"
+ },
+ "10.0.1.1": "gw2"
+ }
+}
+```
+
+Tests
+-----
+
+ npm test
+
+Known Limitations
+-----------------
+
+* This module only supports outputting files suitable for BIND and tiny DNS servers.
+* Only A, NS and PTR records can be generated
+
+License
+-------
+
+MIT Licensed
78 bin/dnsgen.js
@@ -0,0 +1,78 @@
+#!/usr/bin/env node
+
+var dnsgen = require('../'),
+ path = require('path'),
+ util = require('util'),
+ version = require('../package.json').version,
+ supported_types = ['bind', 'tinydns'];
+
+/**
+ * Usage
+ *
+ * return the usage message
+ */
+function usage() {
+ return util.format([
+ 'Usage: %s type [ reverse ]',
+ '',
+ 'Generate DNS files using json',
+ '',
+ 'Options',
+ ' --help | -h: Print this help message and exit',
+ ' --version | -v: Print the version number and exit',
+ '',
+ 'Example',
+ ' dnsgen bind reverse < dns.json',
+ '',
+ 'Supported Types',
+ ' [%s]'
+ ].join('\n'), path.basename(process.argv[1]), supported_types);
+}
+
+// Command line arguments
+switch (process.argv[2]) {
+ case '-h': case '--help':
+ console.log(usage());
+ process.exit(0);
+ break;
+ case '-v': case '--version':
+ console.log(version);
+ process.exit(0);
+ break;
+}
+
+var type = process.argv[2],
+ reverse = process.argv[3];
+
+// Get the json from stdin
+process.stdin.resume();
+process.stdin.setEncoding('utf8');
+var body = '';
+process.stdin.on('data', function(chunk) {
+ body += chunk;
+});
+process.stdin.on('end', function() {
+ // Parse it
+ try {
+ var j = JSON.parse(body);
+ } catch (e) {
+ console.error('Failed to parse input JSON');
+ console.error(e.stack);
+ process.exit(1);
+ }
+ // Generate the correct format
+ switch (type) {
+ case 'bind':
+ var func = (reverse === 'reverse') ? dnsgen.bindReverse : dnsgen.bind;
+ func.call(dnsgen, j).pipe(process.stdout);
+ break;
+ case 'tiny': case 'tinydns':
+ dnsgen.tinydns(j).pipe(process.stdout);
+ break;
+ default:
+ console.error('Type not supported\n');
+ console.error(usage());
+ process.exit(2);
+ break;
+ }
+});
27 example.json
@@ -0,0 +1,27 @@
+{
+ "domain": "example.com",
+ "admin": "admin.example.com",
+ "time": {
+ "refresh": 28800,
+ "retry": 7200,
+ "expire": 864000,
+ "ttl": 86400
+ },
+ "ns": [
+ "ns1.example.com",
+ "ns2.example.com"
+ ],
+ "netmask": "10.0.0.0/23",
+ "hosts": {
+ "10.0.0.1": "gw",
+ "10.0.0.2": {
+ "name": "zelda",
+ "comment": "Testing Box"
+ },
+ "10.0.0.3": {
+ "name": "link",
+ "comment": "Another box for testing"
+ },
+ "10.0.1.1": "gw2"
+ }
+}
11 index.js
@@ -0,0 +1,11 @@
+var bind = require('./lib/bind'),
+ tinydns = require('./lib/tinydns');
+
+module.exports.bindReverse = function(j) {
+ return bind(j, true);
+};
+module.exports.bind = function(j) {
+ return bind(j, false);
+};
+
+module.exports.tinydns = tinydns;
77 lib/bind.js
@@ -0,0 +1,77 @@
+var util = require('util'),
+ Netmask = require('netmask').Netmask,
+ Stream = require('stream').Stream,
+ lib = require('./lib'),
+ defaults = require('./defaults');
+
+// Create the stream for the DNS file to be created
+module.exports = function(j, reverse) {
+ var emitter = new Stream();
+ process.nextTick(function() {
+ gen_bind_header(j, emitter);
+ gen_bind_lines(j, reverse, emitter);
+ emitter.emit('end');
+ });
+ return emitter;
+}
+
+// Generate the lines for the bind file
+function gen_bind_lines(j, reverse, emitter) {
+ var d = (reverse) ? '' : j.domain + '.';
+
+ // Load the name server lines first
+ j.ns.forEach(function(ns) {
+ var s = util.format('%s\tIN\tNS\t%s.\n', d, ns);
+ emitter.emit('data', s);
+ });
+
+ // Make the ptrs or A records
+ Object.keys(j.hosts).forEach(function(ip) {
+ var host = j.hosts[ip],
+ name = (typeof host === 'string') ? host : host.name,
+ comment = (host.comment) ? util.format('\t; %s', host.comment) : '',
+ s;
+ if (reverse) {
+ // PTR records
+ var mask = new Netmask(j.netmask),
+ s_ip = mask.base.split('.'),
+ num = Math.floor(mask.bitmask / 8),
+ sl_ip = ip.split('.').slice(4 - num).join('.');
+ s = util.format('%s\tIN\tPTR\t%s.%s.%s\n', sl_ip, name, j.domain, comment);
+ emitter.emit('data', s);
+ } else {
+ // A Records
+ s = util.format('%s\tIN\tA\t%s%s\n', name, ip, comment);
+ emitter.emit('data', s);
+ }
+ });
+ return emitter;
+};
+
+// Generate the header line
+function gen_bind_header(j, emitter) {
+ var date_fmt = lib.serial(),
+ s = util.format([
+ '; Bind file for %s (%s)',
+ '@\tIN\tSOA\t%s.\t%s. (',
+ '\t%s\t; serial',
+ '\t%s\t; refresh',
+ '\t%s\t; retry',
+ '\t%s\t; expire',
+ '\t%s\t; ttl',
+ ')',
+ ''
+ ].join('\n'),
+ j.domain,
+ j.netmask,
+ j.ns[0],
+ j.admin,
+ date_fmt,
+ j.time.refresh || defaults.time.refresh,
+ j.time.retry || defaults.time.retry,
+ j.time.expire || defaults.time.expire,
+ j.time.ttl || defaults.time.ttl
+ );
+ emitter.emit('data', s);
+ return emitter;
+}
8 lib/defaults.js
@@ -0,0 +1,8 @@
+module.exports = {
+ 'time': {
+ 'refresh': 28800,
+ 'retry': 7200,
+ 'expire': 864000,
+ 'ttl': 86400
+ }
+};
17 lib/lib.js
@@ -0,0 +1,17 @@
+var util = require('util');
+
+/**
+ * return a serial string
+ */
+module.exports.serial = function(d) {
+ var currentTime = d || new Date(),
+ month = currentTime.getMonth() + 1,
+ day = currentTime.getDate(),
+ year = currentTime.getFullYear(),
+ date_fmt = util.format('%s%s%s01',
+ (year >= 10) ? year : '0' + year,
+ (month >= 10) ? month : '0' + month,
+ (day >= 10) ? day : '0' + day
+ );
+ return date_fmt;
+};
53 lib/tinydns.js
@@ -0,0 +1,53 @@
+var util = require('util'),
+ Stream = require('stream').Stream,
+ lib = require('./lib'),
+ defaults = require('./defaults');
+
+// Create the stream for the DNS file to be created
+module.exports = function(j) {
+ var emitter = new Stream();
+ process.nextTick(function() {
+ gen_header(j, emitter);
+ gen_records(j, emitter);
+ emitter.emit('end');
+ });
+ return emitter;
+}
+
+// Generate the header line
+function gen_header(j, emitter) {
+ var s = util.format([
+ '# tinydns file for %s (%s)',
+ 'Z%s:%s:%s:%s:%s:%s:%s',
+ ''
+ ].join('\n'),
+ j.domain,
+ j.netmask,
+ j.domain,
+ j.ns[0],
+ j.admin,
+ lib.serial(),
+ j.time.refresh || defaults.time.refresh,
+ j.time.retry || defaults.time.retry,
+ j.time.expire || defaults.time.expire
+ );
+ emitter.emit('data', s);
+ // Loop the ns servers
+ j.ns.forEach(function(ns) {
+ s = util.format('&%s::%s:%s\n', j.domain, ns, j.time.ttl);
+ emitter.emit('data', s);
+ });
+ return emitter;
+}
+
+function gen_records(j, emitter) {
+ // Create PTR and A records
+ Object.keys(j.hosts).forEach(function(ip) {
+ var host = j.hosts[ip],
+ name = (typeof host === 'string') ? host : host.name,
+ comment = (host.comment) ? util.format('\t# %s', host.comment) : '';
+ s = util.format('=%s:%s%s\n', name, ip, comment);
+ emitter.emit('data', s);
+ });
+ return emitter;
+}
26 package.json
@@ -0,0 +1,26 @@
+{
+ "name": "dnsgen",
+ "description": "Generate DNS files using json",
+ "version": "0.0.0",
+ "author": "Dave Eddy <dave@daveeddy.com> (http://www.daveeddy.com)",
+ "contributors": [],
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/bahamas10/node-dnsgen.git"
+ },
+ "scripts": {
+ "test": "for f in tests/*.js; do echo \"$f\"; node \"$f\" || exit 1; done; echo 'Passed!'; exit 0"
+ },
+ "dependencies": {
+ "netmask": "~ 0.0.2"
+ },
+ "bin": {
+ "dnsgen": "./bin/dnsgen.js"
+ },
+ "devDependencies": {},
+ "optionalDependencies": {},
+ "engines": {
+ "node": "*"
+ },
+ "keywords": [ "dns", "bind", "djbdns", "tinydns" ]
+}
4 tests/bind.js
@@ -0,0 +1,4 @@
+var dnsgen = require('../'),
+ j = require('../example.json');
+
+dnsgen.bind(j).pipe(process.stdout);
4 tests/bind_reverse.js
@@ -0,0 +1,4 @@
+var dnsgen = require('../'),
+ j = require('../example.json');
+
+dnsgen.bindReverse(j).pipe(process.stdout);
4 tests/tinydns.js
@@ -0,0 +1,4 @@
+var dnsgen = require('../'),
+ j = require('../example.json');
+
+dnsgen.tinydns(j).pipe(process.stdout);

0 comments on commit 167d573

Please sign in to comment.