mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-30 06:54:01 +00:00
Split out IP validation functions into their own file
(No code changes.)
This commit is contained in:
parent
5e067b6781
commit
34717000da
61
staging/src/k8s.io/apimachinery/pkg/util/validation/ip.go
Normal file
61
staging/src/k8s.io/apimachinery/pkg/util/validation/ip.go
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
Copyright 2023 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
netutils "k8s.io/utils/net"
|
||||
)
|
||||
|
||||
// IsValidIP tests that the argument is a valid IP address.
|
||||
func IsValidIP(fldPath *field.Path, value string) field.ErrorList {
|
||||
var allErrors field.ErrorList
|
||||
if netutils.ParseIPSloppy(value) == nil {
|
||||
allErrors = append(allErrors, field.Invalid(fldPath, value, "must be a valid IP address, (e.g. 10.9.8.7 or 2001:db8::ffff)").WithOrigin("format=ip-sloppy"))
|
||||
}
|
||||
return allErrors
|
||||
}
|
||||
|
||||
// IsValidIPv4Address tests that the argument is a valid IPv4 address.
|
||||
func IsValidIPv4Address(fldPath *field.Path, value string) field.ErrorList {
|
||||
var allErrors field.ErrorList
|
||||
ip := netutils.ParseIPSloppy(value)
|
||||
if ip == nil || ip.To4() == nil {
|
||||
allErrors = append(allErrors, field.Invalid(fldPath, value, "must be a valid IPv4 address"))
|
||||
}
|
||||
return allErrors
|
||||
}
|
||||
|
||||
// IsValidIPv6Address tests that the argument is a valid IPv6 address.
|
||||
func IsValidIPv6Address(fldPath *field.Path, value string) field.ErrorList {
|
||||
var allErrors field.ErrorList
|
||||
ip := netutils.ParseIPSloppy(value)
|
||||
if ip == nil || ip.To4() != nil {
|
||||
allErrors = append(allErrors, field.Invalid(fldPath, value, "must be a valid IPv6 address"))
|
||||
}
|
||||
return allErrors
|
||||
}
|
||||
|
||||
// IsValidCIDR tests that the argument is a valid CIDR value.
|
||||
func IsValidCIDR(fldPath *field.Path, value string) field.ErrorList {
|
||||
var allErrors field.ErrorList
|
||||
_, _, err := netutils.ParseCIDRSloppy(value)
|
||||
if err != nil {
|
||||
allErrors = append(allErrors, field.Invalid(fldPath, value, "must be a valid CIDR value, (e.g. 10.9.8.0/24 or 2001:db8::/64)"))
|
||||
}
|
||||
return allErrors
|
||||
}
|
320
staging/src/k8s.io/apimachinery/pkg/util/validation/ip_test.go
Normal file
320
staging/src/k8s.io/apimachinery/pkg/util/validation/ip_test.go
Normal file
@ -0,0 +1,320 @@
|
||||
/*
|
||||
Copyright 2023 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
func TestIsValidIP(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
in string
|
||||
family int
|
||||
err string
|
||||
}{
|
||||
// GOOD VALUES
|
||||
{
|
||||
name: "ipv4",
|
||||
in: "1.2.3.4",
|
||||
family: 4,
|
||||
},
|
||||
{
|
||||
name: "ipv4, all zeros",
|
||||
in: "0.0.0.0",
|
||||
family: 4,
|
||||
},
|
||||
{
|
||||
name: "ipv4, max",
|
||||
in: "255.255.255.255",
|
||||
family: 4,
|
||||
},
|
||||
{
|
||||
name: "ipv6",
|
||||
in: "1234::abcd",
|
||||
family: 6,
|
||||
},
|
||||
{
|
||||
name: "ipv6, all zeros, collapsed",
|
||||
in: "::",
|
||||
family: 6,
|
||||
},
|
||||
{
|
||||
name: "ipv6, max",
|
||||
in: "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
|
||||
family: 6,
|
||||
},
|
||||
|
||||
// GOOD, THOUGH NON-CANONICAL, VALUES
|
||||
{
|
||||
name: "ipv6, all zeros, expanded (non-canonical)",
|
||||
in: "0:0:0:0:0:0:0:0",
|
||||
family: 6,
|
||||
},
|
||||
{
|
||||
name: "ipv6, leading 0s (non-canonical)",
|
||||
in: "0001:002:03:4::",
|
||||
family: 6,
|
||||
},
|
||||
{
|
||||
name: "ipv6, capital letters (non-canonical)",
|
||||
in: "1234::ABCD",
|
||||
family: 6,
|
||||
},
|
||||
|
||||
// BAD VALUES WE CURRENTLY CONSIDER GOOD
|
||||
{
|
||||
name: "ipv4 with leading 0s",
|
||||
in: "1.1.1.01",
|
||||
family: 4,
|
||||
},
|
||||
{
|
||||
name: "ipv4-in-ipv6 value",
|
||||
in: "::ffff:1.1.1.1",
|
||||
family: 4,
|
||||
},
|
||||
|
||||
// BAD VALUES
|
||||
{
|
||||
name: "empty string",
|
||||
in: "",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
{
|
||||
name: "junk",
|
||||
in: "aaaaaaa",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
{
|
||||
name: "domain name",
|
||||
in: "myhost.mydomain",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
{
|
||||
name: "cidr",
|
||||
in: "1.2.3.0/24",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
{
|
||||
name: "ipv4 with out-of-range octets",
|
||||
in: "1.2.3.400",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
{
|
||||
name: "ipv4 with negative octets",
|
||||
in: "-1.0.0.0",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
{
|
||||
name: "ipv6 with out-of-range segment",
|
||||
in: "2001:db8::10005",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
{
|
||||
name: "ipv4:port",
|
||||
in: "1.2.3.4:80",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
{
|
||||
name: "ipv6 with brackets",
|
||||
in: "[2001:db8::1]",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
{
|
||||
name: "[ipv6]:port",
|
||||
in: "[2001:db8::1]:80",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
{
|
||||
name: "host:port",
|
||||
in: "example.com:80",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
{
|
||||
name: "ipv6 with zone",
|
||||
in: "1234::abcd%eth0",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
{
|
||||
name: "ipv4 with zone",
|
||||
in: "169.254.0.0%eth0",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
errs := IsValidIP(field.NewPath(""), tc.in)
|
||||
if tc.err == "" {
|
||||
if len(errs) != 0 {
|
||||
t.Errorf("expected %q to be valid but got: %v", tc.in, errs)
|
||||
}
|
||||
} else {
|
||||
if len(errs) != 1 {
|
||||
t.Errorf("expected %q to have 1 error but got: %v", tc.in, errs)
|
||||
} else if !strings.Contains(errs[0].Detail, tc.err) {
|
||||
t.Errorf("expected error for %q to contain %q but got: %q", tc.in, tc.err, errs[0].Detail)
|
||||
}
|
||||
}
|
||||
|
||||
errs = IsValidIPv4Address(field.NewPath(""), tc.in)
|
||||
if tc.family == 4 {
|
||||
if len(errs) != 0 {
|
||||
t.Errorf("expected %q to pass IsValidIPv4Address but got: %v", tc.in, errs)
|
||||
}
|
||||
} else {
|
||||
if len(errs) == 0 {
|
||||
t.Errorf("expected %q to fail IsValidIPv4Address", tc.in)
|
||||
}
|
||||
}
|
||||
|
||||
errs = IsValidIPv6Address(field.NewPath(""), tc.in)
|
||||
if tc.family == 6 {
|
||||
if len(errs) != 0 {
|
||||
t.Errorf("expected %q to pass IsValidIPv6Address but got: %v", tc.in, errs)
|
||||
}
|
||||
} else {
|
||||
if len(errs) == 0 {
|
||||
t.Errorf("expected %q to fail IsValidIPv6Address", tc.in)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsValidCIDR(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
in string
|
||||
err string
|
||||
}{
|
||||
// GOOD VALUES
|
||||
{
|
||||
name: "ipv4",
|
||||
in: "1.0.0.0/8",
|
||||
},
|
||||
{
|
||||
name: "ipv4, all IPs",
|
||||
in: "0.0.0.0/0",
|
||||
},
|
||||
{
|
||||
name: "ipv4, single IP",
|
||||
in: "1.1.1.1/32",
|
||||
},
|
||||
{
|
||||
name: "ipv6",
|
||||
in: "2001:4860:4860::/48",
|
||||
},
|
||||
{
|
||||
name: "ipv6, all IPs",
|
||||
in: "::/0",
|
||||
},
|
||||
{
|
||||
name: "ipv6, single IP",
|
||||
in: "::1/128",
|
||||
},
|
||||
|
||||
// GOOD, THOUGH NON-CANONICAL, VALUES
|
||||
{
|
||||
name: "ipv6, extra 0s (non-canonical)",
|
||||
in: "2a00:79e0:2:0::/64",
|
||||
},
|
||||
{
|
||||
name: "ipv6, capital letters (non-canonical)",
|
||||
in: "2001:DB8::/64",
|
||||
},
|
||||
|
||||
// BAD VALUES WE CURRENTLY CONSIDER GOOD
|
||||
{
|
||||
name: "ipv4 with leading 0s",
|
||||
in: "1.1.01.0/24",
|
||||
},
|
||||
{
|
||||
name: "ipv4-in-ipv6 with ipv4-sized prefix",
|
||||
in: "::ffff:1.1.1.0/24",
|
||||
},
|
||||
{
|
||||
name: "ipv4-in-ipv6 with ipv6-sized prefix",
|
||||
in: "::ffff:1.1.1.0/120",
|
||||
},
|
||||
{
|
||||
name: "ipv4 with bits past prefix",
|
||||
in: "1.2.3.4/24",
|
||||
},
|
||||
{
|
||||
name: "ipv6 with bits past prefix",
|
||||
in: "2001:db8::1/64",
|
||||
},
|
||||
{
|
||||
name: "prefix length with leading 0s",
|
||||
in: "192.168.0.0/016",
|
||||
},
|
||||
|
||||
// BAD VALUES
|
||||
{
|
||||
name: "empty string",
|
||||
in: "",
|
||||
err: "must be a valid CIDR value",
|
||||
},
|
||||
{
|
||||
name: "junk",
|
||||
in: "aaaaaaa",
|
||||
err: "must be a valid CIDR value",
|
||||
},
|
||||
{
|
||||
name: "IP address",
|
||||
in: "1.2.3.4",
|
||||
err: "must be a valid CIDR value",
|
||||
},
|
||||
{
|
||||
name: "partial URL",
|
||||
in: "192.168.0.1/healthz",
|
||||
err: "must be a valid CIDR value",
|
||||
},
|
||||
{
|
||||
name: "partial URL 2",
|
||||
in: "192.168.0.1/0/99",
|
||||
err: "must be a valid CIDR value",
|
||||
},
|
||||
{
|
||||
name: "negative prefix length",
|
||||
in: "192.168.0.0/-16",
|
||||
err: "must be a valid CIDR value",
|
||||
},
|
||||
{
|
||||
name: "prefix length with sign",
|
||||
in: "192.168.0.0/+16",
|
||||
err: "must be a valid CIDR value",
|
||||
},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
errs := IsValidCIDR(field.NewPath(""), tc.in)
|
||||
if tc.err == "" {
|
||||
if len(errs) != 0 {
|
||||
t.Errorf("expected %q to be valid but got: %v", tc.in, errs)
|
||||
}
|
||||
} else {
|
||||
if len(errs) != 1 {
|
||||
t.Errorf("expected %q to have 1 error but got: %v", tc.in, errs)
|
||||
} else if !strings.Contains(errs[0].Detail, tc.err) {
|
||||
t.Errorf("expected error for %q to contain %q but got: %q", tc.in, tc.err, errs[0].Detail)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -24,7 +24,6 @@ import (
|
||||
"unicode"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
netutils "k8s.io/utils/net"
|
||||
)
|
||||
|
||||
const qnameCharFmt string = "[A-Za-z0-9]"
|
||||
@ -369,45 +368,6 @@ func IsValidPortName(port string) []string {
|
||||
return errs
|
||||
}
|
||||
|
||||
// IsValidIP tests that the argument is a valid IP address.
|
||||
func IsValidIP(fldPath *field.Path, value string) field.ErrorList {
|
||||
var allErrors field.ErrorList
|
||||
if netutils.ParseIPSloppy(value) == nil {
|
||||
allErrors = append(allErrors, field.Invalid(fldPath, value, "must be a valid IP address, (e.g. 10.9.8.7 or 2001:db8::ffff)").WithOrigin("format=ip-sloppy"))
|
||||
}
|
||||
return allErrors
|
||||
}
|
||||
|
||||
// IsValidIPv4Address tests that the argument is a valid IPv4 address.
|
||||
func IsValidIPv4Address(fldPath *field.Path, value string) field.ErrorList {
|
||||
var allErrors field.ErrorList
|
||||
ip := netutils.ParseIPSloppy(value)
|
||||
if ip == nil || ip.To4() == nil {
|
||||
allErrors = append(allErrors, field.Invalid(fldPath, value, "must be a valid IPv4 address"))
|
||||
}
|
||||
return allErrors
|
||||
}
|
||||
|
||||
// IsValidIPv6Address tests that the argument is a valid IPv6 address.
|
||||
func IsValidIPv6Address(fldPath *field.Path, value string) field.ErrorList {
|
||||
var allErrors field.ErrorList
|
||||
ip := netutils.ParseIPSloppy(value)
|
||||
if ip == nil || ip.To4() != nil {
|
||||
allErrors = append(allErrors, field.Invalid(fldPath, value, "must be a valid IPv6 address"))
|
||||
}
|
||||
return allErrors
|
||||
}
|
||||
|
||||
// IsValidCIDR tests that the argument is a valid CIDR value.
|
||||
func IsValidCIDR(fldPath *field.Path, value string) field.ErrorList {
|
||||
var allErrors field.ErrorList
|
||||
_, _, err := netutils.ParseCIDRSloppy(value)
|
||||
if err != nil {
|
||||
allErrors = append(allErrors, field.Invalid(fldPath, value, "must be a valid CIDR value, (e.g. 10.9.8.0/24 or 2001:db8::/64)"))
|
||||
}
|
||||
return allErrors
|
||||
}
|
||||
|
||||
const percentFmt string = "[0-9]+%"
|
||||
const percentErrMsg string = "a valid percent string must be a numeric string followed by an ending '%'"
|
||||
|
||||
|
@ -322,302 +322,6 @@ func TestIsValidLabelValue(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsValidIP(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
in string
|
||||
family int
|
||||
err string
|
||||
}{
|
||||
// GOOD VALUES
|
||||
{
|
||||
name: "ipv4",
|
||||
in: "1.2.3.4",
|
||||
family: 4,
|
||||
},
|
||||
{
|
||||
name: "ipv4, all zeros",
|
||||
in: "0.0.0.0",
|
||||
family: 4,
|
||||
},
|
||||
{
|
||||
name: "ipv4, max",
|
||||
in: "255.255.255.255",
|
||||
family: 4,
|
||||
},
|
||||
{
|
||||
name: "ipv6",
|
||||
in: "1234::abcd",
|
||||
family: 6,
|
||||
},
|
||||
{
|
||||
name: "ipv6, all zeros, collapsed",
|
||||
in: "::",
|
||||
family: 6,
|
||||
},
|
||||
{
|
||||
name: "ipv6, max",
|
||||
in: "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
|
||||
family: 6,
|
||||
},
|
||||
|
||||
// GOOD, THOUGH NON-CANONICAL, VALUES
|
||||
{
|
||||
name: "ipv6, all zeros, expanded (non-canonical)",
|
||||
in: "0:0:0:0:0:0:0:0",
|
||||
family: 6,
|
||||
},
|
||||
{
|
||||
name: "ipv6, leading 0s (non-canonical)",
|
||||
in: "0001:002:03:4::",
|
||||
family: 6,
|
||||
},
|
||||
{
|
||||
name: "ipv6, capital letters (non-canonical)",
|
||||
in: "1234::ABCD",
|
||||
family: 6,
|
||||
},
|
||||
|
||||
// BAD VALUES WE CURRENTLY CONSIDER GOOD
|
||||
{
|
||||
name: "ipv4 with leading 0s",
|
||||
in: "1.1.1.01",
|
||||
family: 4,
|
||||
},
|
||||
{
|
||||
name: "ipv4-in-ipv6 value",
|
||||
in: "::ffff:1.1.1.1",
|
||||
family: 4,
|
||||
},
|
||||
|
||||
// BAD VALUES
|
||||
{
|
||||
name: "empty string",
|
||||
in: "",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
{
|
||||
name: "junk",
|
||||
in: "aaaaaaa",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
{
|
||||
name: "domain name",
|
||||
in: "myhost.mydomain",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
{
|
||||
name: "cidr",
|
||||
in: "1.2.3.0/24",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
{
|
||||
name: "ipv4 with out-of-range octets",
|
||||
in: "1.2.3.400",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
{
|
||||
name: "ipv4 with negative octets",
|
||||
in: "-1.0.0.0",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
{
|
||||
name: "ipv6 with out-of-range segment",
|
||||
in: "2001:db8::10005",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
{
|
||||
name: "ipv4:port",
|
||||
in: "1.2.3.4:80",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
{
|
||||
name: "ipv6 with brackets",
|
||||
in: "[2001:db8::1]",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
{
|
||||
name: "[ipv6]:port",
|
||||
in: "[2001:db8::1]:80",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
{
|
||||
name: "host:port",
|
||||
in: "example.com:80",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
{
|
||||
name: "ipv6 with zone",
|
||||
in: "1234::abcd%eth0",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
{
|
||||
name: "ipv4 with zone",
|
||||
in: "169.254.0.0%eth0",
|
||||
err: "must be a valid IP address",
|
||||
},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
errs := IsValidIP(field.NewPath(""), tc.in)
|
||||
if tc.err == "" {
|
||||
if len(errs) != 0 {
|
||||
t.Errorf("expected %q to be valid but got: %v", tc.in, errs)
|
||||
}
|
||||
} else {
|
||||
if len(errs) != 1 {
|
||||
t.Errorf("expected %q to have 1 error but got: %v", tc.in, errs)
|
||||
} else if !strings.Contains(errs[0].Detail, tc.err) {
|
||||
t.Errorf("expected error for %q to contain %q but got: %q", tc.in, tc.err, errs[0].Detail)
|
||||
}
|
||||
}
|
||||
|
||||
errs = IsValidIPv4Address(field.NewPath(""), tc.in)
|
||||
if tc.family == 4 {
|
||||
if len(errs) != 0 {
|
||||
t.Errorf("expected %q to pass IsValidIPv4Address but got: %v", tc.in, errs)
|
||||
}
|
||||
} else {
|
||||
if len(errs) == 0 {
|
||||
t.Errorf("expected %q to fail IsValidIPv4Address", tc.in)
|
||||
}
|
||||
}
|
||||
|
||||
errs = IsValidIPv6Address(field.NewPath(""), tc.in)
|
||||
if tc.family == 6 {
|
||||
if len(errs) != 0 {
|
||||
t.Errorf("expected %q to pass IsValidIPv6Address but got: %v", tc.in, errs)
|
||||
}
|
||||
} else {
|
||||
if len(errs) == 0 {
|
||||
t.Errorf("expected %q to fail IsValidIPv6Address", tc.in)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsValidCIDR(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
in string
|
||||
err string
|
||||
}{
|
||||
// GOOD VALUES
|
||||
{
|
||||
name: "ipv4",
|
||||
in: "1.0.0.0/8",
|
||||
},
|
||||
{
|
||||
name: "ipv4, all IPs",
|
||||
in: "0.0.0.0/0",
|
||||
},
|
||||
{
|
||||
name: "ipv4, single IP",
|
||||
in: "1.1.1.1/32",
|
||||
},
|
||||
{
|
||||
name: "ipv6",
|
||||
in: "2001:4860:4860::/48",
|
||||
},
|
||||
{
|
||||
name: "ipv6, all IPs",
|
||||
in: "::/0",
|
||||
},
|
||||
{
|
||||
name: "ipv6, single IP",
|
||||
in: "::1/128",
|
||||
},
|
||||
|
||||
// GOOD, THOUGH NON-CANONICAL, VALUES
|
||||
{
|
||||
name: "ipv6, extra 0s (non-canonical)",
|
||||
in: "2a00:79e0:2:0::/64",
|
||||
},
|
||||
{
|
||||
name: "ipv6, capital letters (non-canonical)",
|
||||
in: "2001:DB8::/64",
|
||||
},
|
||||
|
||||
// BAD VALUES WE CURRENTLY CONSIDER GOOD
|
||||
{
|
||||
name: "ipv4 with leading 0s",
|
||||
in: "1.1.01.0/24",
|
||||
},
|
||||
{
|
||||
name: "ipv4-in-ipv6 with ipv4-sized prefix",
|
||||
in: "::ffff:1.1.1.0/24",
|
||||
},
|
||||
{
|
||||
name: "ipv4-in-ipv6 with ipv6-sized prefix",
|
||||
in: "::ffff:1.1.1.0/120",
|
||||
},
|
||||
{
|
||||
name: "ipv4 with bits past prefix",
|
||||
in: "1.2.3.4/24",
|
||||
},
|
||||
{
|
||||
name: "ipv6 with bits past prefix",
|
||||
in: "2001:db8::1/64",
|
||||
},
|
||||
{
|
||||
name: "prefix length with leading 0s",
|
||||
in: "192.168.0.0/016",
|
||||
},
|
||||
|
||||
// BAD VALUES
|
||||
{
|
||||
name: "empty string",
|
||||
in: "",
|
||||
err: "must be a valid CIDR value",
|
||||
},
|
||||
{
|
||||
name: "junk",
|
||||
in: "aaaaaaa",
|
||||
err: "must be a valid CIDR value",
|
||||
},
|
||||
{
|
||||
name: "IP address",
|
||||
in: "1.2.3.4",
|
||||
err: "must be a valid CIDR value",
|
||||
},
|
||||
{
|
||||
name: "partial URL",
|
||||
in: "192.168.0.1/healthz",
|
||||
err: "must be a valid CIDR value",
|
||||
},
|
||||
{
|
||||
name: "partial URL 2",
|
||||
in: "192.168.0.1/0/99",
|
||||
err: "must be a valid CIDR value",
|
||||
},
|
||||
{
|
||||
name: "negative prefix length",
|
||||
in: "192.168.0.0/-16",
|
||||
err: "must be a valid CIDR value",
|
||||
},
|
||||
{
|
||||
name: "prefix length with sign",
|
||||
in: "192.168.0.0/+16",
|
||||
err: "must be a valid CIDR value",
|
||||
},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
errs := IsValidCIDR(field.NewPath(""), tc.in)
|
||||
if tc.err == "" {
|
||||
if len(errs) != 0 {
|
||||
t.Errorf("expected %q to be valid but got: %v", tc.in, errs)
|
||||
}
|
||||
} else {
|
||||
if len(errs) != 1 {
|
||||
t.Errorf("expected %q to have 1 error but got: %v", tc.in, errs)
|
||||
} else if !strings.Contains(errs[0].Detail, tc.err) {
|
||||
t.Errorf("expected error for %q to contain %q but got: %q", tc.in, tc.err, errs[0].Detail)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsHTTPHeaderName(t *testing.T) {
|
||||
goodValues := []string{
|
||||
// Common ones
|
||||
|
Loading…
Reference in New Issue
Block a user