1
0
mirror of https://github.com/openshift/installer.git synced 2026-02-05 06:46:36 +01:00
Files
installer/pkg/validate/validate_test.go
Gaoyun Pei 15d1d85a87 OCPBUGS-66943: Validate cluster name against Azure reserved words (#10221)
* 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
2026-01-15 04:17:16 +00:00

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())
}
}
})
}
}