-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
125 lines (110 loc) · 3.93 KB
/
main.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
// Package main defines the dc-template-linter executable entry point.
package main
/*
* This is a Domain Connect template lint tool to validate contents of a
* template file. These templates are usually found from
* https://github.com/domain-connect/templates
*
* Questions about the tool can be sent to <domain-connect@cloudflare.com>
*/
import (
"bufio"
"flag"
"fmt"
"os"
"time"
"github.com/Domain-Connect/dc-template-linter/exitvals"
"github.com/Domain-Connect/dc-template-linter/internal"
"github.com/Domain-Connect/dc-template-linter/libdctlint"
"github.com/mattn/go-isatty"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
func main() {
// Init logging. Essentially colors or no colors?
if isatty.IsTerminal(os.Stderr.Fd()) {
log.Logger = log.Output(
zerolog.ConsoleWriter{
Out: os.Stderr,
TimeFormat: time.RFC3339,
},
)
} else {
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
}
// Command line option handling
flag.Usage = func() {
_, _ = fmt.Fprintf(os.Stderr, "Usage: %s [options] <template.json> [...]\n", os.Args[0])
flag.PrintDefaults()
_, _ = fmt.Fprintf(os.Stderr, "Warning. -inplace and -pretty will remove zero priority MX and SRV fields\n")
_, _ = fmt.Fprintf(os.Stderr, "You can find long DCTL explanations in wiki\n")
_, _ = fmt.Fprintf(os.Stderr, "e.g., https://github.com/Domain-Connect/dc-template-linter/wiki/DCTL1003\n")
}
checkLogos := flag.Bool("logos", false, "check logo urls are reachable (requires network)")
cloudflare := flag.Bool("cloudflare", false, "use Cloudflare specific template rules")
inplace := flag.Bool("inplace", false, "inplace write back pretty-print")
increment := flag.Bool("increment", false, "increment template version, useful when pretty-printing")
prettyPrint := flag.Bool("pretty", false, "pretty-print template json")
loglevel := flag.String("loglevel", "info", "loglevel can be one of: panic fatal error warn info debug trace")
toleration := flag.String("tolerate", "info", "non-zero return loglevel threshold: any error warn info debug none")
ttl := flag.Uint("ttl", 0, "-inplace ttl fix value to be used when template ttl is zero or invalid")
version := flag.Bool("version", false, "output version information and exit")
flag.Parse()
// Did user want to know version
if *version {
_, _ = fmt.Printf("dc-template-linter version %d\n", dcTemplateLinterVersion)
os.Exit(0)
}
// Runtime init
internal.SetLoglevel(*loglevel)
exitVal := exitvals.CheckOK
log.Debug().Uint("version", dcTemplateLinterVersion).Msg("dc-template-linter version")
if libdctlint.MaxTTL < *ttl {
log.Fatal().Uint("ttl", *ttl).Uint("max", libdctlint.MaxTTL).EmbedObject(internal.DCTL1000).Msg("")
}
conf := libdctlint.NewConf().
SetCheckLogos(*checkLogos).
SetPrettyPrint(*prettyPrint).
SetCloudflare(*cloudflare)
if flag.NArg() < 1 {
log.Debug().Msg("reading from stdin")
conf.SetFilename("/dev/stdin")
reader := bufio.NewReader(os.Stdin)
exitVal = conf.CheckTemplate(reader)
} else {
conf.SetInplace(*inplace).
SetTTL(uint32(*ttl)).
SetIncrement(*increment)
for _, arg := range flag.Args() {
conf.SetFilename(arg)
f, err := os.Open(arg)
if err != nil {
log.Error().Err(err).EmbedObject(internal.DCTL0001).Msg("")
exitVal |= exitvals.CheckError
continue
}
log.Debug().Str("template", arg).Msg("processing template")
exitVal |= conf.CheckTemplate(bufio.NewReader(f))
err = f.Close()
if err != nil {
log.Error().Err(err).Msg("could not close file")
exitVal |= exitvals.CheckFatal
}
}
}
switch *toleration {
case "any":
exitVal = exitvals.CheckOK
case "error":
exitVal &= exitvals.CheckFatal
case "warn":
exitVal &= exitvals.CheckFatal | exitvals.CheckError
case "info":
exitVal &= exitvals.CheckFatal | exitvals.CheckError | exitvals.CheckWarn
case "debug":
exitVal &= exitvals.CheckFatal | exitvals.CheckError | exitvals.CheckWarn | exitvals.CheckInfo
default:
// none
}
os.Exit(int(exitVal))
}