Skip to content

Commit f19d27e

Browse files
authored
Merge pull request #4657 from thaJeztah/improve_ValidateIPAddress
opts: ValidateIPAddress: improve error, godoc, and tests
2 parents d9b6481 + b0ee27d commit f19d27e

3 files changed

Lines changed: 77 additions & 21 deletions

File tree

cli/command/service/update_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ func TestUpdateDNSConfig(t *testing.T) {
199199
// IPv6
200200
flags.Set("dns-add", "2001:db8:abc8::1")
201201
// Invalid dns record
202-
assert.ErrorContains(t, flags.Set("dns-add", "x.y.z.w"), "x.y.z.w is not an ip address")
202+
assert.Check(t, is.ErrorContains(flags.Set("dns-add", "x.y.z.w"), "IP address is not correctly formatted: x.y.z.w"))
203203

204204
// domains with duplicates
205205
flags.Set("dns-search-add", "example.com")

opts/opts.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -224,13 +224,17 @@ type ValidatorFctType func(val string) (string, error)
224224
// ValidatorFctListType defines a validator function that returns a validated list of string and/or an error
225225
type ValidatorFctListType func(val string) ([]string, error)
226226

227-
// ValidateIPAddress validates an Ip address.
227+
// ValidateIPAddress validates if the given value is a correctly formatted
228+
// IP address, and returns the value in normalized form. Leading and trailing
229+
// whitespace is allowed, but it does not allow IPv6 addresses surrounded by
230+
// square brackets ("[::1]").
231+
//
232+
// Refer to [net.ParseIP] for accepted formats.
228233
func ValidateIPAddress(val string) (string, error) {
229-
ip := net.ParseIP(strings.TrimSpace(val))
230-
if ip != nil {
234+
if ip := net.ParseIP(strings.TrimSpace(val)); ip != nil {
231235
return ip.String(), nil
232236
}
233-
return "", fmt.Errorf("%s is not an ip address", val)
237+
return "", fmt.Errorf("IP address is not correctly formatted: %s", val)
234238
}
235239

236240
// ValidateMACAddress validates a MAC address.

opts/opts_test.go

Lines changed: 68 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,79 @@ import (
66
"testing"
77

88
"gotest.tools/v3/assert"
9+
is "gotest.tools/v3/assert/cmp"
910
)
1011

1112
func TestValidateIPAddress(t *testing.T) {
12-
if ret, err := ValidateIPAddress(`1.2.3.4`); err != nil || ret == "" {
13-
t.Fatalf("ValidateIPAddress(`1.2.3.4`) got %s %s", ret, err)
14-
}
15-
16-
if ret, err := ValidateIPAddress(`127.0.0.1`); err != nil || ret == "" {
17-
t.Fatalf("ValidateIPAddress(`127.0.0.1`) got %s %s", ret, err)
18-
}
19-
20-
if ret, err := ValidateIPAddress(`::1`); err != nil || ret == "" {
21-
t.Fatalf("ValidateIPAddress(`::1`) got %s %s", ret, err)
22-
}
23-
24-
if ret, err := ValidateIPAddress(`127`); err == nil || ret != "" {
25-
t.Fatalf("ValidateIPAddress(`127`) got %s %s", ret, err)
13+
tests := []struct {
14+
doc string
15+
input string
16+
expectedOut string
17+
expectedErr string
18+
}{
19+
{
20+
doc: "IPv4 loopback",
21+
input: `127.0.0.1`,
22+
expectedOut: `127.0.0.1`,
23+
},
24+
{
25+
doc: "IPv4 loopback with whitespace",
26+
input: ` 127.0.0.1 `,
27+
expectedOut: `127.0.0.1`,
28+
},
29+
{
30+
doc: "IPv6 loopback long form",
31+
input: `0:0:0:0:0:0:0:1`,
32+
expectedOut: `::1`,
33+
},
34+
{
35+
doc: "IPv6 loopback",
36+
input: `::1`,
37+
expectedOut: `::1`,
38+
},
39+
{
40+
doc: "IPv6 loopback with whitespace",
41+
input: ` ::1 `,
42+
expectedOut: `::1`,
43+
},
44+
{
45+
doc: "IPv6 lowercase",
46+
input: `2001:db8::68`,
47+
expectedOut: `2001:db8::68`,
48+
},
49+
{
50+
doc: "IPv6 uppercase",
51+
input: `2001:DB8::68`,
52+
expectedOut: `2001:db8::68`,
53+
},
54+
{
55+
doc: "IPv6 with brackets",
56+
input: `[::1]`,
57+
expectedErr: `IP address is not correctly formatted: [::1]`,
58+
},
59+
{
60+
doc: "IPv4 partial",
61+
input: `127`,
62+
expectedErr: `IP address is not correctly formatted: 127`,
63+
},
64+
{
65+
doc: "random invalid string",
66+
input: `random invalid string`,
67+
expectedErr: `IP address is not correctly formatted: random invalid string`,
68+
},
2669
}
2770

28-
if ret, err := ValidateIPAddress(`random invalid string`); err == nil || ret != "" {
29-
t.Fatalf("ValidateIPAddress(`random invalid string`) got %s %s", ret, err)
71+
for _, tc := range tests {
72+
tc := tc
73+
t.Run(tc.input, func(t *testing.T) {
74+
actualOut, actualErr := ValidateIPAddress(tc.input)
75+
assert.Check(t, is.Equal(tc.expectedOut, actualOut))
76+
if tc.expectedErr == "" {
77+
assert.Check(t, actualErr)
78+
} else {
79+
assert.Check(t, is.Error(actualErr, tc.expectedErr))
80+
}
81+
})
3082
}
3183
}
3284

0 commit comments

Comments
 (0)