forked from StackExchange/dnscontrol
-
Notifications
You must be signed in to change notification settings - Fork 0
/
printIR.go
144 lines (133 loc) · 3.42 KB
/
printIR.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package commands
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"github.com/StackExchange/dnscontrol/models"
"github.com/StackExchange/dnscontrol/pkg/js"
"github.com/StackExchange/dnscontrol/pkg/normalize"
"github.com/pkg/errors"
"github.com/urfave/cli"
)
var _ = cmd(catDebug, func() *cli.Command {
var args PrintIRArgs
return &cli.Command{
Name: "print-ir",
Usage: "Output intermediate representation (IR) after running validation and normalization logic.",
Action: func(c *cli.Context) error {
return exit(PrintIR(args))
},
Flags: args.flags(),
}
}())
var _ = cmd(catDebug, func() *cli.Command {
var args PrintIRArgs
// This is the same as print-ir with the following changes:
// - output defaults to /dev/null.
// - prints "No errors." if there were no errors.
return &cli.Command{
Name: "check",
Usage: "Check and validate dnsconfig.js. Do not access providers.",
Action: func(c *cli.Context) error {
if args.Output == "" {
args.Output = os.DevNull
}
err := exit(PrintIR(args))
if err == nil {
fmt.Fprintf(os.Stderr, "No errors.\n")
}
return err
},
Flags: args.flags(),
}
}())
// PrintIRArgs encapsulates the flags/arguments for the print-ir command.
type PrintIRArgs struct {
GetDNSConfigArgs
PrintJSONArgs
Raw bool
}
func (args *PrintIRArgs) flags() []cli.Flag {
flags := append(args.GetDNSConfigArgs.flags(), args.PrintJSONArgs.flags()...)
flags = append(flags, &cli.BoolFlag{
Name: "raw",
Usage: "Skip validation and normalization. Just print js result.",
Destination: &args.Raw,
})
return flags
}
// PrintIR implements the print-ir subcommand.
func PrintIR(args PrintIRArgs) error {
cfg, err := GetDNSConfig(args.GetDNSConfigArgs)
if err != nil {
return err
}
if !args.Raw {
errs := normalize.NormalizeAndValidateConfig(cfg)
if PrintValidationErrors(errs) {
return errors.Errorf("Exiting due to validation errors")
}
}
return PrintJSON(args.PrintJSONArgs, cfg)
}
// PrintValidationErrors formats and prints the validation errors and warnings.
func PrintValidationErrors(errs []error) (fatal bool) {
if len(errs) == 0 {
return false
}
fmt.Printf("%d Validation errors:\n", len(errs))
for _, err := range errs {
if _, ok := err.(normalize.Warning); ok {
fmt.Printf("WARNING: %s\n", err)
} else {
fatal = true
fmt.Printf("ERROR: %s\n", err)
}
}
return
}
// ExecuteDSL executes the dnsconfig.js contents.
func ExecuteDSL(args ExecuteDSLArgs) (*models.DNSConfig, error) {
if args.JSFile == "" {
return nil, errors.Errorf("No config specified")
}
text, err := ioutil.ReadFile(args.JSFile)
if err != nil {
return nil, errors.Errorf("Reading js file %s: %s", args.JSFile, err)
}
dnsConfig, err := js.ExecuteJavascript(string(text), args.DevMode)
if err != nil {
return nil, errors.Errorf("Executing javascript in %s: %s", args.JSFile, err)
}
return dnsConfig, nil
}
// PrintJSON outputs/prettyprints the IR data.
func PrintJSON(args PrintJSONArgs, config *models.DNSConfig) (err error) {
var dat []byte
if args.Pretty {
dat, err = json.MarshalIndent(config, "", " ")
} else {
dat, err = json.Marshal(config)
}
if err != nil {
return err
}
if args.Output != "" {
f, err := os.Create(args.Output)
if err != nil {
return err
}
defer f.Close()
_, err = f.Write(dat)
return err
}
fmt.Println(string(dat))
return nil
}
func exit(err error) error {
if err == nil {
return nil
}
return cli.NewExitError(err, 1)
}