This repository has been archived by the owner on Oct 23, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 137
/
Copy pathvalidation.go
161 lines (144 loc) · 4.32 KB
/
validation.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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package records
import (
"fmt"
"net"
"regexp"
"strconv"
"strings"
)
var dnsValidationRegex = regexp.MustCompile(`^[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*$`)
func validateEnabledServices(c *Config) error {
if !c.DNSOn && !c.HTTPOn {
return fmt.Errorf("either DNS or HTTP server should be on")
}
if len(c.Masters) == 0 && c.Zk == "" {
return fmt.Errorf("specify Mesos masters or Zookeeper in config.json")
}
return nil
}
// validateMasters checks that each master in the list is a properly formatted host:port or IP:port pair.
// duplicate masters in the list are not allowed.
// returns nil if the masters list is empty, or else all masters in the list are valid.
func validateMasters(ms []string) error {
if err := validateUniqueStrings(ms, normalizeMaster); err != nil {
return fmt.Errorf("error validating masters: %v", err)
}
return nil
}
func normalizeMaster(hostPort string) (string, error) {
host, port, err := net.SplitHostPort(hostPort)
if err != nil {
return "", fmt.Errorf("illegal host:port specified: %v. Error: %v", hostPort, err)
}
if ip := net.ParseIP(host); ip != nil {
//TODO(jdef) distinguish between intended hostnames and invalid ip addresses
host = ip.String()
}
if !validPortString(port) {
return "", fmt.Errorf("illegal host:port specified: %v", hostPort)
}
return net.JoinHostPort(host, port), nil
}
// validateResolvers checks that each resolver in the list is a properly formatted IP or IP:port pair.
// duplicate resolvers in the list are not allowed.
// returns nil if the resolver list is empty, or else all resolvers in the list are valid.
func validateResolvers(rs []string) error {
if err := validateUniqueStrings(rs, normalizeResolver); err != nil {
return fmt.Errorf("error validating resolvers: %v", err)
}
return nil
}
func validateDomainName(domain string) error {
if !dnsValidationRegex.MatchString(domain) {
return fmt.Errorf("invalid domain name: %s", domain)
}
return nil
}
func validateZoneResolvers(zrs map[string][]string, mesosDomain string) (
err error) {
allDomains := make([]string, 0, len(zrs)+1)
for domain, rs := range zrs {
if len(rs) == 0 {
return fmt.Errorf("field ZoneResolver %v is empty", domain)
}
err = validateDomainName(domain)
if err != nil {
return err
}
err = validateResolvers(rs)
if err != nil {
return
}
if domain == mesosDomain {
return fmt.Errorf("can't specify ZoneResolver for Mesos domain (%v)",
mesosDomain)
}
allDomains = append(allDomains, "."+domain)
}
allDomains = append(allDomains, "."+mesosDomain)
for _, a := range allDomains {
for _, b := range allDomains {
if (a != b) &&
strings.HasSuffix(a, b) {
return fmt.Errorf("ambiguous zone resolvers: %v is masked by %v",
a, b)
}
}
}
return
}
func normalizeResolver(hostPort string) (string, error) {
host, port, err := net.SplitHostPort(hostPort)
if err != nil {
host = hostPort
port = "53"
}
if ip := net.ParseIP(host); ip != nil {
host = ip.String()
} else {
return "", fmt.Errorf("illegal ip specified: %v", host)
}
if !validPortString(port) {
return "", fmt.Errorf("illegal host:port specified: %v", hostPort)
}
return net.JoinHostPort(host, port), nil
}
// validateUniqueStrings runs a normalize function on each string in a list and
// retuns an error if any duplicates are found.
func validateUniqueStrings(strings []string, normalize func(string) (string, error)) error {
valid := make(map[string]struct{}, len(strings))
for _, str := range strings {
normalized, err := normalize(str)
if err != nil {
return err
}
if _, found := valid[normalized]; found {
return fmt.Errorf("duplicate found: %v", str)
}
valid[normalized] = struct{}{}
}
return nil
}
// validateIPSources checks validity of ip sources
func validateIPSources(srcs []string) error {
if len(srcs) == 0 {
return fmt.Errorf("empty ip sources")
}
if len(srcs) != len(unique(srcs)) {
return fmt.Errorf("duplicate ip source specified")
}
for _, src := range srcs {
switch src {
case "host", "docker", "mesos", "netinfo":
default:
return fmt.Errorf("invalid ip source %q", src)
}
}
return nil
}
// validPortString retuns true if the given port string is
// an integer between 1 and 65535, false otherwise.
func validPortString(portString string) bool {
port, err := strconv.Atoi(portString)
return err == nil && port > 0 && port <= 65535
}