mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-05-11 05:55:12 +00:00
New feature: FETCH() permits http gets in dnsconfig.js (#1007)
add PANIC() and error-handled FETCH()
This commit is contained in:
47
pkg/js/js.go
47
pkg/js/js.go
@@ -11,6 +11,11 @@ import (
|
||||
"github.com/robertkrimen/otto" // load underscore js into vm by default
|
||||
_ "github.com/robertkrimen/otto/underscore" // required by otto
|
||||
|
||||
"github.com/xddxdd/ottoext/fetch"
|
||||
"github.com/xddxdd/ottoext/loop"
|
||||
"github.com/xddxdd/ottoext/promise"
|
||||
"github.com/xddxdd/ottoext/timers"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v3/models"
|
||||
"github.com/StackExchange/dnscontrol/v3/pkg/printer"
|
||||
"github.com/StackExchange/dnscontrol/v3/pkg/transform"
|
||||
@@ -24,6 +29,9 @@ import (
|
||||
// far as require() is concerned, not the actual os.Getwd().
|
||||
var currentDirectory string
|
||||
|
||||
// EnableFetch sets whether to enable fetch() in JS execution environment
|
||||
var EnableFetch bool = false
|
||||
|
||||
// ExecuteJavascript accepts a javascript string and runs it, returning the resulting dnsConfig.
|
||||
func ExecuteJavascript(file string, devMode bool, variables map[string]string) (*models.DNSConfig, error) {
|
||||
script, err := ioutil.ReadFile(file)
|
||||
@@ -35,10 +43,26 @@ func ExecuteJavascript(file string, devMode bool, variables map[string]string) (
|
||||
currentDirectory = filepath.Dir(file)
|
||||
|
||||
vm := otto.New()
|
||||
l := loop.New(vm)
|
||||
|
||||
if err := timers.Define(vm, l); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := promise.Define(vm, l); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// only define fetch() when explicitly enabled
|
||||
if EnableFetch {
|
||||
if err := fetch.Define(vm, l); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
vm.Set("require", require)
|
||||
vm.Set("REV", reverse)
|
||||
vm.Set("glob", listFiles) // used for require_glob()
|
||||
vm.Set("PANIC", jsPanic)
|
||||
|
||||
// add cli variables to otto
|
||||
for key, value := range variables {
|
||||
@@ -47,12 +71,17 @@ func ExecuteJavascript(file string, devMode bool, variables map[string]string) (
|
||||
|
||||
helperJs := GetHelpers(devMode)
|
||||
// run helper script to prime vm and initialize variables
|
||||
if _, err := vm.Run(helperJs); err != nil {
|
||||
if err := l.Eval(helperJs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// run user script
|
||||
if _, err := vm.Run(script); err != nil {
|
||||
if err := l.Eval(script); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// wait for event loop to finish
|
||||
if err := l.Run(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -212,6 +241,20 @@ func listFiles(call otto.FunctionCall) otto.Value {
|
||||
return value
|
||||
}
|
||||
|
||||
func jsPanic(call otto.FunctionCall) otto.Value {
|
||||
if len(call.ArgumentList) != 1 {
|
||||
throw(call.Otto, "PANIC takes exactly one argument")
|
||||
}
|
||||
|
||||
message := call.Argument(0).String() // The filename as given by the user
|
||||
fmt.Fprintln(os.Stderr, message)
|
||||
os.Exit(1)
|
||||
|
||||
// Won't be actually executed
|
||||
v, _ := otto.ToValue(0)
|
||||
return v
|
||||
}
|
||||
|
||||
func throw(vm *otto.Otto, str string) {
|
||||
panic(vm.MakeCustomError("Error", str))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user