mirror of
https://github.com/openshift/installer.git
synced 2026-02-05 06:46:36 +01:00
* azure: validate cluster name against Azure reserved words Azure prohibits the use of certain reserved words and trademarks in resource names. This change adds validation to reject cluster names containing any of the 43 reserved words documented by Azure, preventing deployment failures with ReservedResourceName errors. Reserved words checked include: - Complete reserved words (40): AZURE, OFFICE, EXCHANGE, etc. - Substring forbidden (2): MICROSOFT, WINDOWS - Prefix forbidden (1): LOGIN * update the checking logic on reserved words * fix the gofmt issues
834 lines
25 KiB
Go
834 lines
25 KiB
Go
package validate
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestClusterName(t *testing.T) {
|
|
maxSizeName := strings.Repeat("123456789.", 5) + "1234"
|
|
|
|
cases := []struct {
|
|
name string
|
|
clusterName string
|
|
valid bool
|
|
}{
|
|
{"empty", "", false},
|
|
{"only whitespace", " ", false},
|
|
{"single lowercase", "a", true},
|
|
{"single uppercase", "A", false},
|
|
{"contains whitespace", "abc D", false},
|
|
{"single number", "1", true},
|
|
{"single dot", ".", false},
|
|
{"ends with dot", "a.", false},
|
|
{"starts with dot", ".a", false},
|
|
{"multiple labels", "a.a", true},
|
|
{"starts with dash", "-a", false},
|
|
{"ends with dash", "a-", false},
|
|
{"label starts with dash", "a.-a", false},
|
|
{"label ends with dash", "a-.a", false},
|
|
{"invalid percent", "a%a", false},
|
|
{"only non-ascii", "日本語", false},
|
|
{"contains non-ascii", "a日本語a", false},
|
|
{"max size", maxSizeName, true},
|
|
{"too long", maxSizeName + "a", false},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := ClusterName(tc.clusterName)
|
|
if tc.valid {
|
|
assert.NoError(t, err)
|
|
} else {
|
|
assert.Error(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestOnPremClusterName(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
clusterName string
|
|
valid bool
|
|
}{
|
|
{"single lowercase", "a", true},
|
|
{"has a dot", "a.a", false},
|
|
{"valid name", "abcde", true},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := OnPremClusterName(tc.clusterName)
|
|
if tc.valid {
|
|
assert.NoError(t, err)
|
|
} else {
|
|
assert.Error(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestClusterName1035(t *testing.T) {
|
|
maxSizeName := "a" + strings.Repeat("123456789.", 5) + "123"
|
|
|
|
cases := []struct {
|
|
name string
|
|
clusterName string
|
|
valid bool
|
|
}{
|
|
{"empty", "", false},
|
|
{"only whitespace", " ", false},
|
|
{"single lowercase", "a", true},
|
|
{"single uppercase", "A", false},
|
|
{"contains whitespace", "abc D", false},
|
|
{"single number", "1", false},
|
|
{"single dot", ".", false},
|
|
{"ends with dot", "a.", false},
|
|
{"starts with dot", ".a", false},
|
|
{"multiple labels", "a.a", true},
|
|
{"starts with dash", "-a", false},
|
|
{"ends with dash", "a-", false},
|
|
{"label starts with dash", "a.-a", false},
|
|
{"label ends with dash", "a-.a", false},
|
|
{"invalid percent", "a%a", false},
|
|
{"only non-ascii", "日本語", false},
|
|
{"contains non-ascii", "a日本語a", false},
|
|
{"max size", maxSizeName, true},
|
|
{"too long", maxSizeName + "a", false},
|
|
{"URLs", "https://hello.openshift.org", false},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := ClusterName1035(tc.clusterName)
|
|
if tc.valid {
|
|
assert.NoError(t, err)
|
|
} else {
|
|
assert.Error(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestVCenter(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
clusterName string
|
|
valid bool
|
|
}{
|
|
{"empty", "", false},
|
|
{"only whitespace", " ", false},
|
|
{"single lowercase", "a", true},
|
|
{"single uppercase", "A", false},
|
|
{"contains whitespace", "abc D", false},
|
|
{"single number", "1", true},
|
|
{"single dot", ".", false},
|
|
{"ends with dot", "a.", false},
|
|
{"starts with dot", ".a", false},
|
|
{"multiple labels", "a.a", true},
|
|
{"starts with dash", "-a", false},
|
|
{"ends with dash", "a-", false},
|
|
{"label starts with dash", "a.-a", false},
|
|
{"label ends with dash", "a-.a", false},
|
|
{"invalid percent", "a%a", false},
|
|
{"only non-ascii", "日本語", false},
|
|
{"contains non-ascii", "a日本語a", false},
|
|
{"URLs", "https://hello.openshift.org", false},
|
|
{"IP", "192.168.1.1", true},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := Host(tc.clusterName)
|
|
if tc.valid {
|
|
assert.NoError(t, err)
|
|
} else {
|
|
assert.Error(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSubnetCIDR(t *testing.T) {
|
|
cases := []struct {
|
|
cidr string
|
|
expErr string
|
|
}{
|
|
{"0.0.0.0/32", "address must be specified"},
|
|
{"1.2.3.4/0", "invalid network address. got 1.2.3.4/0, expecting 0.0.0.0/0"},
|
|
{"1.2.3.4/1", "invalid network address. got 1.2.3.4/1, expecting 0.0.0.0/1"},
|
|
{"1.2.3.4/31", ""},
|
|
{"1.2.3.4/32", ""},
|
|
{"0:0:0:0:0:1:102:304/116", "invalid network address. got ::1:102:304/116, expecting ::1:102:0/116"},
|
|
{"0:0:0:0:0:ffff:102:304/116", "invalid network address. got 1.2.3.4/20, expecting 1.2.0.0/20"},
|
|
{"255.255.255.255/1", "invalid network address. got 255.255.255.255/1, expecting 128.0.0.0/1"},
|
|
{"255.255.255.255/32", ""},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.cidr, func(t *testing.T) {
|
|
ip, cidr, err := net.ParseCIDR(tc.cidr)
|
|
if err != nil {
|
|
t.Fatalf("could not parse cidr: %v", err)
|
|
}
|
|
err = SubnetCIDR(&net.IPNet{IP: ip, Mask: cidr.Mask})
|
|
if tc.expErr != "" {
|
|
assert.EqualError(t, err, tc.expErr)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDomainName_AcceptingTrailingDot(t *testing.T) {
|
|
cases := []struct {
|
|
domain string
|
|
valid bool
|
|
}{
|
|
{"", false},
|
|
{" ", false},
|
|
{"a", true},
|
|
{".", false},
|
|
{"日本語", false},
|
|
{"日本語.com", false},
|
|
{"abc.日本語.com", false},
|
|
{"a日本語a.com", false},
|
|
{"abc", true},
|
|
{"ABC", false},
|
|
{"ABC123", false},
|
|
{"ABC123.COM123", false},
|
|
{"1", true},
|
|
{"0.0", true},
|
|
{"1.2.3.4", true},
|
|
{"1.2.3.4.", true},
|
|
{"abc.", true},
|
|
{"abc.com", true},
|
|
{"abc.com.", true},
|
|
{"a.b.c.d.e.f", true},
|
|
{".abc", false},
|
|
{".abc.com", false},
|
|
{".abc.com", false},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.domain, func(t *testing.T) {
|
|
err := DomainName(tc.domain, true)
|
|
if tc.valid {
|
|
assert.NoError(t, err)
|
|
} else {
|
|
assert.Error(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDomainName_RejectingTrailingDot(t *testing.T) {
|
|
cases := []struct {
|
|
domain string
|
|
valid bool
|
|
}{
|
|
{"", false},
|
|
{" ", false},
|
|
{"a", true},
|
|
{".", false},
|
|
{"日本語", false},
|
|
{"日本語.com", false},
|
|
{"abc.日本語.com", false},
|
|
{"a日本語a.com", false},
|
|
{"abc", true},
|
|
{"ABC", false},
|
|
{"ABC123", false},
|
|
{"ABC123.COM123", false},
|
|
{"1", true},
|
|
{"0.0", true},
|
|
{"1.2.3.4", true},
|
|
{"1.2.3.4.", false},
|
|
{"abc.", false},
|
|
{"abc.com", true},
|
|
{"abc.com.", false},
|
|
{"a.b.c.d.e.f", true},
|
|
{".abc", false},
|
|
{".abc.com", false},
|
|
{".abc.com", false},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.domain, func(t *testing.T) {
|
|
err := DomainName(tc.domain, false)
|
|
if tc.valid {
|
|
assert.NoError(t, err)
|
|
} else {
|
|
assert.Error(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestNoProxyDomainName(t *testing.T) {
|
|
cases := []struct {
|
|
domain string
|
|
valid bool
|
|
}{
|
|
{"", false},
|
|
{" ", false},
|
|
{"a", true},
|
|
{".", false},
|
|
{"日本語", false},
|
|
{"日本語.com", false},
|
|
{"abc.日本語.com", false},
|
|
{"a日本語a.com", false},
|
|
{"abc", true},
|
|
{"ABC", false},
|
|
{"ABC123", false},
|
|
{"ABC123.COM123", false},
|
|
{"1", true},
|
|
{"0.0", true},
|
|
{"1.2.3.4", true},
|
|
{"1.2.3.4.", true},
|
|
{"abc.", true},
|
|
{"abc.com", true},
|
|
{"abc.com.", true},
|
|
{"a.b.c.d.e.f", true},
|
|
{".abc", true},
|
|
{".abc.com", true},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.domain, func(t *testing.T) {
|
|
err := NoProxyDomainName(tc.domain)
|
|
if tc.valid {
|
|
assert.NoError(t, err)
|
|
} else {
|
|
assert.Error(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDoCIDRsOverlap(t *testing.T) {
|
|
cases := []struct {
|
|
a string
|
|
b string
|
|
overlap bool
|
|
}{
|
|
{
|
|
a: "192.168.0.0/30",
|
|
b: "192.168.0.3/30",
|
|
overlap: true,
|
|
},
|
|
{
|
|
a: "192.168.0.0/30",
|
|
b: "192.168.0.4/30",
|
|
overlap: false,
|
|
},
|
|
{
|
|
a: "192.168.0.0/29",
|
|
b: "192.168.0.4/30",
|
|
overlap: true,
|
|
},
|
|
{
|
|
a: "0.0.0.0/0",
|
|
b: "192.168.0.0/24",
|
|
overlap: true,
|
|
},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(fmt.Sprintf("%s %s", tc.a, tc.b), func(t *testing.T) {
|
|
_, a, err := net.ParseCIDR(tc.a)
|
|
if err != nil {
|
|
t.Fatalf("could not parse cidr %q: %v", tc.a, err)
|
|
}
|
|
_, b, err := net.ParseCIDR(tc.b)
|
|
if err != nil {
|
|
t.Fatalf("could not parse cidr %q: %v", tc.b, err)
|
|
}
|
|
actual := DoCIDRsOverlap(a, b)
|
|
assert.Equal(t, tc.overlap, actual)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestImagePullSecret(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
secret string
|
|
valid bool
|
|
}{
|
|
{
|
|
name: "single entry with auth",
|
|
secret: `{"auths":{"example.com":{"auth":"authorization value"}}}`,
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "single entry with credsStore",
|
|
secret: `{"auths":{"example.com":{"credsStore":"creds store value"}}}`,
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "empty",
|
|
secret: `{}`,
|
|
valid: false,
|
|
},
|
|
{
|
|
name: "no auths",
|
|
secret: `{"not-auths":{"example.com":{"auth":"authorization value"}}}`,
|
|
valid: false,
|
|
},
|
|
{
|
|
name: "no auth or credsStore",
|
|
secret: `{"auths":{"example.com":{"unrequired-field":"value"}}}`,
|
|
valid: false,
|
|
},
|
|
{
|
|
name: "additional fields",
|
|
secret: `{"auths":{"example.com":{"auth":"authorization value","other-field":"other field value"}}}`,
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "no entries",
|
|
secret: `{"auths":{}}`,
|
|
valid: false,
|
|
},
|
|
{
|
|
name: "multiple valid entries",
|
|
secret: `{"auths":{"example.com":{"auth":"authorization value"},"other-example.com":{"auth":"other auth value"}}}`,
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "mix of valid and invalid entries",
|
|
secret: `{"auths":{"example.com":{"auth":"authorization value"},"other-example.com":{"unrequired-field":"value"}}}`,
|
|
valid: false,
|
|
},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := ImagePullSecret(tc.secret)
|
|
if tc.valid {
|
|
assert.NoError(t, err)
|
|
} else {
|
|
assert.Error(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
const invalidFormatCertificate = `-----INVALID FORMAT-----
|
|
MIIF2zCCA8OgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgYExCzAJBgNVBAYTAlVT
|
|
MRcwFQYDVQQIDA5Ob3J0aCBDYXJvbGluYTEQMA4GA1UEBwwHUmFsZWlnaDEUMBIG
|
|
A1UECgwLUmVkIEhhdCBJbmMxHzAdBgNVBAsMFk9wZW5TaGlmdCBJbnN0YWxsIFRl
|
|
c3QxEDAOBgNVBAMMB1Jvb3QgQ0EwHhcNMTkwNzIyMjAwNzUxWhcNMjkwNzE5MjAw
|
|
NzUxWjB3MQswCQYDVQQGEwJVUzEXMBUGA1UECAwOTm9ydGggQ2Fyb2xpbmExFDAS
|
|
BgNVBAoMC1JlZCBIYXQgSW5jMR8wHQYDVQQLDBZPcGVuU2hpZnQgSW5zdGFsbCBU
|
|
ZXN0MRgwFgYDVQQDDA9JbnRlcm1lZGlhdGUgQ0EwggIiMA0GCSqGSIb3DQEBAQUA
|
|
A4ICDwAwggIKAoICAQDZhc69vEq9XyG+vcOW4rPx9aYJgn7NFXaE88xrKajFyu2v
|
|
kD5Mz7geQV/RQKp1RMvj/1JCW5Npw8QwoPXNGQ8M+d+ajGgSkUZNVBQRXiR/hpfK
|
|
ohox9gJRsOVCAvhyE15iZHkEVFFcchiWbsTM9QllLsiiI0qZ/QpkUmJmDyXUV4Hq
|
|
hoAGXsojp0xaEQhrl+Hayiwao7qZkbKFCbNIDFU++ZDNT41qqDwcYmbkBJgYoGdS
|
|
IAk4Mjf7+rLJPXWNYtYB3g1cuN4pH8FkFT9zocNr0xrsx2itY4gvXgIe/vzts8aw
|
|
sHx1h2HcZK7iJEHs25QGrsZhiADeb0i5pN1kaPqpY0qgQUCIaqZAtMMeHXQ0k3PB
|
|
xTz8vk0388oFLaJFuI0P9Q6CRf5+4rc9O201aUIuue3Y4IS6zAcd8yL5d5vxvCiN
|
|
Dbl7YenBS4C9xSEEiVZwN7AtIdKFq5pGrlptmhVbGFW1CLQNsVWpetCY12Sh9FOq
|
|
2IBaAup+XgRgO4kHs3t7euVaS2viH3MplPsOUim8NZPZBdZkTtS3W9SynBDriy1d
|
|
KtrYgz0zrgEAa82mq4INaR+7Utct97zhKa1zM47KlHgkauiTPkUcqVhoNWxdM5tI
|
|
nSWym/9pPHUmzt8v/F8COA/8Xv+db2QX14S3fStI+8mp084RWuevtbh5WcoypQID
|
|
AQABo2YwZDAdBgNVHQ4EFgQUPUqJPYDZeUXbBlR0xXA/F+DYYagwHwYDVR0jBBgw
|
|
FoAUjWflPh3KYZ5o3BP3Po4v2ZBshVkwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNV
|
|
HQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBAH665ntrBhyf+MPFnkY+1VUr
|
|
VrfRlP4SccoujdLB/sUKqydYsED+mDJ+V8uFOgoi7PHqwvsRS+yR/bB0bNNYSfKY
|
|
slCMQA3sJ7SNDPBsec955ehYPNdquhem+oICzgFaQwL9ULDG87fKZjmaKO25dIYX
|
|
ttLqn+0b0GjpfQRuZ3NpAnCTWevodc5A3aYQm6vYeCyeIHGPpmtLE6oPRFib7wtD
|
|
n4DFVM57F34ClnnF4m8jq9HoTcM1Y3qOFyslK/4FRyx3HXbEVsm5L289l0AS866U
|
|
WEVM9DCqpFNLTwRk0mn4mspNcRxTDUTiHAxMhKxHGgbPcFzCJXqZzkW56bDcAGA5
|
|
sQr+MOfa1P/K7pVcFtOAhsBi5ff1G4t1G1+amqXEDalL+qKRGFugGVf+poyb2C3g
|
|
sfxkPBp9jPPMgMzXULQglwU4IUm8GtBb9Lh6AFPvt78XAWvNvHLP1Rf8JNZ9prx5
|
|
N9RzIKSWKm6CVEjSDvQ42j4OpW0eecHAoluZFMrykVl+KmapWUwQF6v0xz1RJdQ+
|
|
q3vGJ6shhiFd6y0ygxPwMaEjhhpbRy4tK9iDBj5yRpo+HE5X+FQSN6NHOYWMeDoZ
|
|
uzd86/huEH5qIAL4unM9YFTzJ4CFOC8EJMDW6ul0uKjOwGPP3R1Vss6sC7kR0gXI
|
|
rLWYdt40z0pjcR3FDVzh
|
|
-----INVALID FORMAT-----
|
|
`
|
|
const validCACertificate = `-----BEGIN CERTIFICATE-----
|
|
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
|
|
rLWYdt40z0pjcR3FDVzh
|
|
-----END CERTIFICATE-----
|
|
`
|
|
|
|
const validCertificate = `-----BEGIN CERTIFICATE-----
|
|
MIIF0TCCA7mgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwdzELMAkGA1UEBhMCVVMx
|
|
FzAVBgNVBAgMDk5vcnRoIENhcm9saW5hMRQwEgYDVQQKDAtSZWQgSGF0IEluYzEf
|
|
MB0GA1UECwwWT3BlblNoaWZ0IEluc3RhbGwgVGVzdDEYMBYGA1UEAwwPSW50ZXJt
|
|
ZWRpYXRlIENBMB4XDTE5MDcyMjIwMTMwMloXDTIwMDczMTIwMTMwMlowgY4xCzAJ
|
|
BgNVBAYTAlVTMRcwFQYDVQQIDA5Ob3J0aCBDYXJvbGluYTEQMA4GA1UEBwwHUmFs
|
|
ZWlnaDEUMBIGA1UECgwLUmVkIEhhdCBJbmMxHzAdBgNVBAsMFk9wZW5TaGlmdCBJ
|
|
bnN0YWxsIFRlc3QxHTAbBgNVBAMMFHJlZ2lzdHJ5LmV4YW1wbGUuY29tMIIBIjAN
|
|
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyCT3n3zYL7PkLtnzBU9WUyZBz1Q+
|
|
SXUP739DjT+xmRunE1ViD2wfkVIhTHowlw6B7+23tSRQngEu5i4+lglzqouYY5jE
|
|
sqWUXaPMa5FeeDstI6LIUxqk9/2yWRBrrdJlVWor57F310aTzkYtkmkCJTDy3k9R
|
|
Le8jma8fnchaVpttbHgN/F+CiS+OV8u9PtALGuJ4DfHy2hM4pxhiKMxFpYOaxBuq
|
|
41Y0ts8CXyEiVWwZB7+fFrAjog8uJuhAdya1rAWvSDo+GQr2CDY2/PJcAVHO1n9F
|
|
h1LkjqIOd4OOqOy9gIYDc5bvZvWGuzeCN8icrdH8KM53witq5yhZHRL4EQIDAQAB
|
|
o4IBTTCCAUkwCQYDVR0TBAIwADARBglghkgBhvhCAQEEBAMCBkAwMwYJYIZIAYb4
|
|
QgENBCYWJE9wZW5TU0wgR2VuZXJhdGVkIFNlcnZlciBDZXJ0aWZpY2F0ZTAdBgNV
|
|
HQ4EFgQUxzJ/lMs83RIoGheipNbag+SZr4wwga8GA1UdIwSBpzCBpIAUPUqJPYDZ
|
|
eUXbBlR0xXA/F+DYYaihgYekgYQwgYExCzAJBgNVBAYTAlVTMRcwFQYDVQQIDA5O
|
|
b3J0aCBDYXJvbGluYTEQMA4GA1UEBwwHUmFsZWlnaDEUMBIGA1UECgwLUmVkIEhh
|
|
dCBJbmMxHzAdBgNVBAsMFk9wZW5TaGlmdCBJbnN0YWxsIFRlc3QxEDAOBgNVBAMM
|
|
B1Jvb3QgQ0GCAhAAMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcD
|
|
ATANBgkqhkiG9w0BAQsFAAOCAgEALXbZyIAXZPBBe+uWBscUFpmXvfQR9CQRbnYi
|
|
X4453dLKZqEsWNVcUQihrfaNyHCrkG7dSgT64JWWJcyXLXe9TfVR9FLGjzt4p0P2
|
|
V9T+PFjp3JN+Elh6XDeNisZ7fHzYs2yYnugZELdWkLOcUwkvUHhSQ5aSWYFrngn7
|
|
J3mT3GS3WSpLUvVQDn3RBDbS0ossnF1tq9n6Nhs4Xvhdso6gEZU9SeztbnSK9N/k
|
|
zWLV5PjgwpevJ17jzpxm7ZIAlcp31i4SIircJtGwgUS3cJZXPPWMdK72qnLQjFMF
|
|
BNEc11EBilMK8tn/K4Dn06BBJMRtOCkq0KhopeZX0HmtQE29z6hy9fcTBklCwLXQ
|
|
NMSOKemXsOiGTwghosa0xw0H2e9R8z9KTX5xBGgHbHbWu7e/oDVY9+XTnfQ0ZqFi
|
|
aBa/U/WWLMQQDNvQQGsllxBHC+pOpDD8YhycPmbpsFfhNo58U9VQ6mqtX3o7j5nP
|
|
imNTY4B5RmZUILe+C0XhON6VL5RCa+s6YngIUcfeylTSB8BTeVBxIAInubKzrgZM
|
|
4ThJWLbaiTkRqaT/viDfxsmgzJsrDm3ZWzYXwF/a5o6NHK4lqCYf/1nvbjgE5PAm
|
|
69R88P32rKeiRJ8AoC4N/5YR++NkB11gsW9ooU2nV90owi6eMhQ6+qGLTrq0mTtv
|
|
CNA1OOo=
|
|
-----END CERTIFICATE-----
|
|
`
|
|
const invalidStringWithCertificate = `-----BEGIN CERTIFICATE-----
|
|
MIIF0TCCA7mgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwdzELMAkGA1UEBhMCVVMx
|
|
FzAVBgNVBAgMDk5vcnRoIENhcm9saW5hMRQwEgYDVQQKDAtSZWQgSGF0IEluYzEf
|
|
MB0GA1UECwwWT3BlblNoaWZ0IEluc3RhbGwgVGVzdDEYMBYGA1UEAwwPSW50ZXJt
|
|
ZWRpYXRlIENBMB4XDTE5MDcyMjIwMTMwMloXDTIwMDczMTIwMTMwMlowgY4xCzAJ
|
|
BgNVBAYTAlVTMRcwFQYDVQQIDA5Ob3J0aCBDYXJvbGluYTEQMA4GA1UEBwwHUmFs
|
|
ZWlnaDEUMBIGA1UECgwLUmVkIEhhdCBJbmMxHzAdBgNVBAsMFk9wZW5TaGlmdCBJ
|
|
bnN0YWxsIFRlc3QxHTAbBgNVBAMMFHJlZ2lzdHJ5LmV4YW1wbGUuY29tMIIBIjAN
|
|
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyCT3n3zYL7PkLtnzBU9WUyZBz1Q+
|
|
SXUP739DjT+xmRunE1ViD2wfkVIhTHowlw6B7+23tSRQngEu5i4+lglzqouYY5jE
|
|
sqWUXaPMa5FeeDstI6LIUxqk9/2yWRBrrdJlVWor57F310aTzkYtkmkCJTDy3k9R
|
|
Le8jma8fnchaVpttbHgN/F+CiS+OV8u9PtALGuJ4DfHy2hM4pxhiKMxFpYOaxBuq
|
|
41Y0ts8CXyEiVWwZB7+fFrAjog8uJuhAdya1rAWvSDo+GQr2CDY2/PJcAVHO1n9F
|
|
h1LkjqIOd4OOqOy9gIYDc5bvZvWGuzeCN8icrdH8KM53witq5yhZHRL4EQIDAQAB
|
|
o4IBTTCCAUkwCQYDVR0TBAIwADARBglghkgBhvhCAQEEBAMCBkAwMwYJYIZIAYb4
|
|
QgENBCYWJE9wZW5TU0wgR2VuZXJhdGVkIFNlcnZlciBDZXJ0aWZpY2F0ZTAdBgNV
|
|
HQ4EFgQUxzJ/lMs83RIoGheipNbag+SZr4wwga8GA1UdIwSBpzCBpIAUPUqJPYDZ
|
|
eUXbBlR0xXA/F+DYYaihgYekgYQwgYExCzAJBgNVBAYTAlVTMRcwFQYDVQQIDA5O
|
|
b3J0aCBDYXJvbGluYTEQMA4GA1UEBwwHUmFsZWlnaDEUMBIGA1UECgwLUmVkIEhh
|
|
dCBJbmMxHzAdBgNVBAsMFk9wZW5TaGlmdCBJbnN0YWxsIFRlc3QxEDAOBgNVBAMM
|
|
B1Jvb3QgQ0GCAhAAMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcD
|
|
ATANBgkqhkiG9w0BAQsFAAOCAgEALXbZyIAXZPBBe+uWBscUFpmXvfQR9CQRbnYi
|
|
X4453dLKZqEsWNVcUQihrfaNyHCrkG7dSgT64JWWJcyXLXe9TfVR9FLGjzt4p0P2
|
|
V9T+PFjp3JN+Elh6XDeNisZ7fHzYs2yYnugZELdWkLOcUwkvUHhSQ5aSWYFrngn7
|
|
J3mT3GS3WSpLUvVQDn3RBDbS0ossnF1tq9n6Nhs4Xvhdso6gEZU9SeztbnSK9N/k
|
|
zWLV5PjgwpevJ17jzpxm7ZIAlcp31i4SIircJtGwgUS3cJZXPPWMdK72qnLQjFMF
|
|
BNEc11EBilMK8tn/K4Dn06BBJMRtOCkq0KhopeZX0HmtQE29z6hy9fcTBklCwLXQ
|
|
NMSOKemXsOiGTwghosa0xw0H2e9R8z9KTX5xBGgHbHbWu7e/oDVY9+XTnfQ0ZqFi
|
|
aBa/U/WWLMQQDNvQQGsllxBHC+pOpDD8YhycPmbpsFfhNo58U9VQ6mqtX3o7j5nP
|
|
imNTY4B5RmZUILe+C0XhON6VL5RCa+s6YngIUcfeylTSB8BTeVBxIAInubKzrgZM
|
|
4ThJWLbaiTkRqaT/viDfxsmgzJsrDm3ZWzYXwF/a5o6NHK4lqCYf/1nvbjgE5PAm
|
|
69R88P32rKeiRJ8AoC4N/5YR++NkB11gsW9ooU2nV90owi6eMhQ6+qGLTrq0mTtv
|
|
CNA1OOo=
|
|
-----END CERTIFICATE-----
|
|
Invalid data here
|
|
`
|
|
|
|
func TestAdditionalTrustBundle(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
certificate string
|
|
valid bool
|
|
}{
|
|
{
|
|
name: "valid ca certificate",
|
|
certificate: validCACertificate,
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "valid certificate",
|
|
certificate: validCertificate,
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "invalid format",
|
|
certificate: invalidFormatCertificate,
|
|
valid: false,
|
|
},
|
|
{
|
|
name: "invalid certificate",
|
|
certificate: invalidFormatCertificate,
|
|
valid: false,
|
|
},
|
|
{
|
|
name: "valid certificate with extra invalid string",
|
|
certificate: invalidStringWithCertificate,
|
|
valid: false,
|
|
},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := CABundle(tc.certificate)
|
|
if tc.valid {
|
|
assert.NoError(t, err)
|
|
} else {
|
|
assert.Error(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSSHPublicKey(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
key string
|
|
valid bool
|
|
}{
|
|
{
|
|
name: "valid",
|
|
key: "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSUGPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XAt3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/EnmZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbxNrRFi9wrf+M7Q==",
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "valid with email",
|
|
key: "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSUGPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XAt3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/EnmZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbxNrRFi9wrf+M7Q== name@example.com",
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "invalid format",
|
|
key: "bad-format AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSUGPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XAt3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/EnmZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbxNrRFi9wrf+M7Q==",
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "invalid key",
|
|
key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDxL",
|
|
valid: false,
|
|
},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := SSHPublicKey(tc.key)
|
|
if tc.valid {
|
|
assert.NoError(t, err)
|
|
} else {
|
|
assert.Error(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestURI(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
uri string
|
|
valid bool
|
|
}{
|
|
{
|
|
name: "valid",
|
|
uri: "https://example.com",
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "missing scheme",
|
|
uri: "example.com",
|
|
valid: false,
|
|
},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := URI(tc.uri)
|
|
if tc.valid {
|
|
assert.NoError(t, err)
|
|
} else {
|
|
assert.Error(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMAC(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
addr string
|
|
expected string
|
|
}{
|
|
{
|
|
name: "valid_mac",
|
|
addr: "7A:CE:E3:29:35:6F",
|
|
},
|
|
{
|
|
name: "invalid_multicast",
|
|
addr: "7D:CE:E3:29:35:6F",
|
|
expected: "expected unicast mac address",
|
|
},
|
|
{
|
|
name: "invalid_infiniband",
|
|
addr: "00-00-00-00-fe-80-00-00-00-00-00-00-02-00-5e-10-00-00-00-01",
|
|
expected: "invalid MAC address",
|
|
},
|
|
{
|
|
name: "invalid_mac",
|
|
addr: "this is a bad mac",
|
|
expected: "invalid MAC address",
|
|
},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := MAC(tc.addr)
|
|
if tc.expected == "" {
|
|
assert.NoError(t, err)
|
|
} else {
|
|
assert.Regexp(t, tc.expected, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAzureClusterName(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
clusterName string
|
|
valid bool
|
|
expected string
|
|
}{
|
|
{
|
|
name: "valid cluster name",
|
|
clusterName: "test-cluster",
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "valid cluster name with numbers",
|
|
clusterName: "test-cluster-123",
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "cluster name containing microsoft",
|
|
clusterName: "amicrosoft-test",
|
|
valid: false,
|
|
expected: `cluster name must not contain the reserved word "microsoft"`,
|
|
},
|
|
{
|
|
name: "cluster name containing MICROSOFT uppercase",
|
|
clusterName: "aMICROSOFT-test",
|
|
valid: false,
|
|
expected: `cluster name must not contain the reserved word "microsoft"`,
|
|
},
|
|
{
|
|
name: "cluster name containing windows",
|
|
clusterName: "windows-cluster",
|
|
valid: false,
|
|
expected: `cluster name must not contain the reserved word "windows"`,
|
|
},
|
|
{
|
|
name: "cluster name containing WINDOWS uppercase",
|
|
clusterName: "myWINDOWS",
|
|
valid: false,
|
|
expected: `cluster name must not contain the reserved word "windows"`,
|
|
},
|
|
{
|
|
name: "cluster name starting with login",
|
|
clusterName: "login-cluster",
|
|
valid: false,
|
|
expected: `cluster name must not start with the reserved word "login"`,
|
|
},
|
|
{
|
|
name: "cluster name starting with LOGIN uppercase",
|
|
clusterName: "LOGIN",
|
|
valid: false,
|
|
expected: `cluster name must not start with the reserved word "login"`,
|
|
},
|
|
{
|
|
name: "cluster name with login not at start",
|
|
clusterName: "bloginsystem",
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "cluster name is exactly azure",
|
|
clusterName: "azure",
|
|
valid: false,
|
|
expected: `cluster name must not be the reserved word "azure"`,
|
|
},
|
|
{
|
|
name: "cluster name containing azure as substring",
|
|
clusterName: "myazure-cluster",
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "cluster name is exactly office",
|
|
clusterName: "office",
|
|
valid: false,
|
|
expected: `cluster name must not be the reserved word "office"`,
|
|
},
|
|
{
|
|
name: "cluster name containing office as substring",
|
|
clusterName: "office-test",
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "cluster name is exactly office365",
|
|
clusterName: "office365",
|
|
valid: false,
|
|
expected: `cluster name must not be the reserved word "office365"`,
|
|
},
|
|
{
|
|
name: "cluster name containing office365 as substring",
|
|
clusterName: "office365-app",
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "cluster name is exactly access",
|
|
clusterName: "access",
|
|
valid: false,
|
|
expected: `cluster name must not be the reserved word "access"`,
|
|
},
|
|
{
|
|
name: "cluster name containing access as substring",
|
|
clusterName: "myaccess-portal",
|
|
valid: true,
|
|
},
|
|
{
|
|
name: "cluster name is exactly xbox",
|
|
clusterName: "xbox",
|
|
valid: false,
|
|
expected: `cluster name must not be the reserved word "xbox"`,
|
|
},
|
|
{
|
|
name: "cluster name containing xbox as substring",
|
|
clusterName: "xbox-gaming",
|
|
valid: true,
|
|
},
|
|
}
|
|
for _, tc := range cases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
err := AzureClusterName(tc.clusterName)
|
|
if tc.valid {
|
|
assert.NoError(t, err)
|
|
} else {
|
|
assert.Error(t, err)
|
|
if tc.expected != "" {
|
|
assert.Regexp(t, tc.expected, err.Error())
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|