-
Notifications
You must be signed in to change notification settings - Fork 420
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Craig Peterson
committed
Aug 23, 2016
0 parents
commit ef0bbf5
Showing
359 changed files
with
157,476 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/tmp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
The MIT License (MIT) | ||
|
||
Copyright (c) 2015 Stack Overflow | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
this software and associated documentation files (the "Software"), to deal in | ||
the Software without restriction, including without limitation the rights to | ||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of | ||
the Software, and to permit persons to whom the Software is furnished to do so, | ||
subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS | ||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR | ||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER | ||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,251 @@ | ||
"use strict"; | ||
|
||
var conf = { | ||
registrars: [], | ||
dns_service_providers: [], | ||
domains: [] | ||
}; | ||
|
||
var defaultDsps = []; | ||
|
||
function initialize(){ | ||
conf = { | ||
registrars: [], | ||
dns_service_providers: [], | ||
domains: [] | ||
}; | ||
defaultDsps = []; | ||
} | ||
|
||
function NewRegistrar(name,type,meta) { | ||
if (type) { | ||
type == "MANUAL"; | ||
} | ||
var reg = {name: name, type: type, meta: meta}; | ||
conf.registrars.push(reg); | ||
return name; | ||
} | ||
|
||
function NewDSP(name, type, meta) { | ||
if ((typeof meta === 'object') && ('ip_conversions' in meta)) { | ||
meta.ip_conversions = format_tt(meta.ip_conversions) | ||
} | ||
var dsp = {name: name, type: type, meta: meta}; | ||
conf.dns_service_providers.push(dsp); | ||
return name; | ||
} | ||
|
||
function newDomain(name,registrar) { | ||
return {name: name, registrar: registrar, meta:{}, records:[], dsps: [], defaultTTL: 0, nameservers:[]}; | ||
} | ||
|
||
function processDargs(m, domain) { | ||
// for each modifier, if it is a... | ||
// function: call it with domain | ||
// array: process recursively | ||
// object: merge it into metadata | ||
// string: assume it is a dsp | ||
if (_.isFunction(m)) { | ||
m(domain); | ||
} else if (_.isArray(m)) { | ||
for (var j in m) { | ||
processDargs(m[j], domain) | ||
} | ||
} else if (_.isObject(m)) { | ||
_.extend(domain.meta,m); | ||
} else if (_.isString(m)) { | ||
domain.dsps.push(m); | ||
} else { | ||
console.log("WARNING: domain modifier type unsupported: ", typeof m, " Domain: ", domain) | ||
} | ||
} | ||
|
||
// D(name,registrar): Create a DNS Domain. Use the parameters as records and mods. | ||
function D(name,registrar) { | ||
var domain = newDomain(name,registrar); | ||
for (var i = 2; i<arguments.length; i++) { | ||
var m = arguments[i]; | ||
processDargs(m, domain) | ||
} | ||
var toAdd = _(defaultDsps).difference(domain.dsps); | ||
_(toAdd).each(function(x) { domain.dsps.push(x)}); | ||
conf.domains.push(domain) | ||
} | ||
|
||
// TTL(v): Set the TTL for a DNS record. | ||
function TTL(v) { | ||
return function(r) { | ||
r.ttl = v; | ||
} | ||
} | ||
|
||
// DefaultTTL(v): Set the default TTL for the domain. | ||
function DefaultTTL(v) { | ||
return function(d) { | ||
d.defaultTTL = v; | ||
} | ||
} | ||
|
||
// A(name,ip, recordModifiers...) | ||
function A(name, ip) { | ||
var mods = getModifiers(arguments,2) | ||
return function(d) { | ||
addRecord(d,"A",name,ip,mods) | ||
} | ||
} | ||
|
||
// AAAA(name,ip, recordModifiers...) | ||
function AAAA(name, ip) { | ||
var mods = getModifiers(arguments,2) | ||
return function(d) { | ||
addRecord(d,"AAAA",name,ip,mods) | ||
} | ||
} | ||
|
||
// CNAME(name,target, recordModifiers...) | ||
function CNAME(name, target) { | ||
var mods = getModifiers(arguments,2) | ||
return function(d) { | ||
addRecord(d,"CNAME",name,target,mods) | ||
} | ||
} | ||
|
||
// TXT(name,target, recordModifiers...) | ||
function TXT(name, target) { | ||
var mods = getModifiers(arguments,2) | ||
return function(d) { | ||
addRecord(d,"TXT",name,target,mods) | ||
} | ||
} | ||
|
||
// MX(name,priority,target, recordModifiers...) | ||
function MX(name, priority, target) { | ||
var mods = getModifiers(arguments,3) | ||
return function(d) { | ||
mods.push(priority); | ||
addRecord(d, "MX", name, target, mods) | ||
} | ||
} | ||
|
||
// NS(name,target, recordModifiers...) | ||
function NS(name, target) { | ||
var mods = getModifiers(arguments,2) | ||
return function(d) { | ||
addRecord(d,"NS",name,target,mods) | ||
} | ||
} | ||
|
||
// NAMESERVER(name,target) | ||
function NAMESERVER(name, target) { | ||
return function(d) { | ||
d.nameservers.push({name: name, target: target}) | ||
} | ||
} | ||
|
||
function format_tt(transform_table) { | ||
// Turn [[low: 1, high: 2, newBase: 3], [low: 4, high: 5, newIP: 6]] | ||
// into "1 ~ 2 ~ 3 ~; 4 ~ 5 ~ ~ 6" | ||
var lines = [] | ||
for (var i=0; i < transform_table.length; i++) { | ||
var ip = transform_table[i]; | ||
var newIP = ip.newIP; | ||
if (newIP){ | ||
if(_.isArray(newIP)){ | ||
newIP = _.map(newIP,function(i){return num2dot(i)}).join(",") | ||
}else{ | ||
newIP = num2dot(newIP); | ||
} | ||
} | ||
var row = [ | ||
num2dot(ip.low), | ||
num2dot(ip.high), | ||
num2dot(ip.newBase), | ||
newIP | ||
] | ||
lines.push(row.join(" ~ ")) | ||
} | ||
return lines.join(" ; ") | ||
} | ||
|
||
// IMPORT_TRANSFORM(translation_table, domain) | ||
function IMPORT_TRANSFORM(translation_table, domain) { | ||
return function(d) { | ||
addRecord(d, "IMPORT_TRANSFORM", "@", domain, [ | ||
{'transform_table': format_tt(translation_table)}]) | ||
} | ||
} | ||
|
||
// PURGE() | ||
function PURGE(d) { | ||
d.KeepUnknown = false | ||
} | ||
|
||
// NO_PURGE() | ||
function NO_PURGE(d) { | ||
d.KeepUnknown = true | ||
} | ||
|
||
function getModifiers(args,start) { | ||
var mods = []; | ||
for (var i = start;i<args.length; i++) { | ||
mods.push(args[i]) | ||
} | ||
return mods; | ||
} | ||
|
||
function addRecord(d,type,name,target,mods) { | ||
// if target is number, assume ip address. convert it. | ||
if (_.isNumber(target)) { | ||
target = num2dot(target); | ||
} | ||
var rec = {type: type, name: name, target: target, ttl:d.defaultTTL, priority: 0, meta:{}}; | ||
// for each modifier, decide based on type: | ||
// - Function: call is with the record as the argument | ||
// - Object: merge it into the metadata | ||
// - Number: IF MX record assume it is priority | ||
if (mods) { | ||
for (var i = 0; i< mods.length; i++) { | ||
var m = mods[i] | ||
if (_.isFunction(m)) { | ||
m(rec); | ||
} else if (_.isObject(m)) { | ||
//convert transforms to strings | ||
if (m.transform && _.isArray(m.transform)){ | ||
m.transform = format_tt(m.transform) | ||
} | ||
_.extend(rec.meta,m); | ||
_.extend(rec.meta,m); | ||
} else if (_.isNumber(m) && type == "MX") { | ||
rec.priority = m; | ||
} else { | ||
console.log("WARNING: Modifier type unsupported:", typeof m, "(Skipping!)"); | ||
} | ||
} | ||
} | ||
d.records.push(rec); | ||
} | ||
|
||
//ip conversion functions from http://stackoverflow.com/a/8105740/121660 | ||
// via http://javascript.about.com/library/blipconvert.htm | ||
function IP(dot) | ||
{ | ||
var d = dot.split('.'); | ||
return ((((((+d[0])*256)+(+d[1]))*256)+(+d[2]))*256)+(+d[3]); | ||
} | ||
|
||
function num2dot(num) | ||
{ | ||
if(num === undefined){ | ||
return ""; | ||
} | ||
if (_.isString(num)){ | ||
return num | ||
} | ||
var d = num%256; | ||
for (var i = 3; i > 0; i--) | ||
{ | ||
num = Math.floor(num/256); | ||
d = num%256 + '.' + d; | ||
} | ||
return d; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package js | ||
|
||
import ( | ||
"encoding/json" | ||
|
||
"github.com/StackExchange/dnscontrol/models" | ||
|
||
"github.com/robertkrimen/otto" | ||
//load underscore js into vm by default | ||
_ "github.com/robertkrimen/otto/underscore" | ||
) | ||
|
||
//ExecuteJavascript accepts a javascript string and runs it, returning the resulting dnsConfig. | ||
func ExecuteJavascript(script string, devMode bool) (*models.DNSConfig, error) { | ||
vm := otto.New() | ||
|
||
helperJs := GetHelpers(devMode) | ||
// run helper script to prime vm and initialize variables | ||
if _, err := vm.Run(string(helperJs)); err != nil { | ||
return nil, err | ||
} | ||
|
||
// run user script | ||
if _, err := vm.Run(script); err != nil { | ||
return nil, err | ||
} | ||
|
||
// export conf as string and unmarshal | ||
value, err := vm.Run(`JSON.stringify(conf)`) | ||
if err != nil { | ||
return nil, err | ||
} | ||
str, err := value.ToString() | ||
if err != nil { | ||
return nil, err | ||
} | ||
conf := &models.DNSConfig{} | ||
if err = json.Unmarshal([]byte(str), conf); err != nil { | ||
return nil, err | ||
} | ||
return conf, nil | ||
} | ||
|
||
func GetHelpers(devMode bool) string { | ||
return FSMustString(devMode, "/helpers.js") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package js | ||
|
||
import ( | ||
"encoding/json" | ||
"io/ioutil" | ||
"os" | ||
"path/filepath" | ||
"testing" | ||
|
||
"github.com/StackExchange/dnscontrol/models" | ||
) | ||
|
||
const testDir = "js/parse_tests" | ||
|
||
func TestParsedFiles(t *testing.T) { | ||
os.Chdir("..") // go up a directory so we helpers.js is in a consistent place. | ||
files, err := ioutil.ReadDir(testDir) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
for _, f := range files { | ||
if filepath.Ext(f.Name()) != ".js" { | ||
continue | ||
} | ||
t.Log(f.Name(), "------") | ||
content, err := ioutil.ReadFile(filepath.Join(testDir, f.Name())) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
conf, err := ExecuteJavascript(string(content), true) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
actualJson, err := json.MarshalIndent(conf, "", " ") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
expectedFile := filepath.Join(testDir, f.Name()[:len(f.Name())-3]+".json") | ||
expectedData, err := ioutil.ReadFile(expectedFile) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
conf = &models.DNSConfig{} | ||
err = json.Unmarshal(expectedData, conf) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
expectedJson, err := json.MarshalIndent(conf, "", " ") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
if string(expectedJson) != string(actualJson) { | ||
t.Error("Expected and actual json don't match") | ||
t.Log("Expected:", string(expectedJson)) | ||
t.Log("Actual:", string(actualJson)) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
|
||
var REG = NewRegistrar("Third-Party","NONE"); | ||
var CF = NewDSP("Cloudflare", "CLOUDFLAREAPI") | ||
D("foo.com",REG,CF, | ||
A("@","1.2.3.4") | ||
); |
Oops, something went wrong.