Merge pull request #47480 from danehans/kubeadm_certs

Automatic merge from submit-queue (batch tested with PRs 49115, 47480)

Adds IPv6 test cases for kubeadm certs.

**What this PR does / why we need it**:
Adds IPv6 test cases in support of kubeadm certificate and validation functionality. It's needed to ensure test cases cover IPv6 related networking scenarios.

**Which issue this PR fixes**
This PR is in support of Issue #1443

**Special notes for your reviewer**:
Additional PR's will follow to ensure kubeadm supports IPv6.

**Release note**:
```NONE
```
This commit is contained in:
Kubernetes Submit Queue 2017-08-16 06:27:27 -07:00 committed by GitHub
commit 04a6481059
2 changed files with 101 additions and 72 deletions

View File

@ -152,21 +152,26 @@ func TestValidateAPIServerCertSANs(t *testing.T) {
func TestValidateIPFromString(t *testing.T) { func TestValidateIPFromString(t *testing.T) {
var tests = []struct { var tests = []struct {
name string
ip string ip string
expected bool expected bool
}{ }{
{"", false}, // not valid {"invalid missing address", "", false},
{"1234", false}, // not valid {"invalid missing decimal points in IPv4 address", "1234", false},
{"1.2", false}, // not valid {"invalid incomplete IPv4 address", "1.2", false},
{"1.2.3.4/16", false}, // not valid {"invalid IPv4 CIDR provided instead of IPv4 address", "1.2.3.4/16", false},
{"1.2.3.4", true}, // valid {"valid IPv4 address", "1.2.3.4", true},
{"16.0.1.1", true}, // valid {"valid IPv6 address", "2001:db8::1", true},
{"invalid IPv6 CIDR provided instead of IPv6 address", "2001:db8::1/64", false},
{"invalid hex character in IPv6 address", "2001:xb8::", false},
{"invalid use of colons in IPv6 address", "2001::db8::", false},
} }
for _, rt := range tests { for _, rt := range tests {
actual := ValidateIPFromString(rt.ip, nil) actual := ValidateIPFromString(rt.ip, nil)
if (len(actual) == 0) != rt.expected { if (len(actual) == 0) != rt.expected {
t.Errorf( t.Errorf(
"failed ValidateIPFromString:\n\texpected: %t\n\t actual: %t", "%s test case failed:\n\texpected: %t\n\t actual: %t",
rt.name,
rt.expected, rt.expected,
(len(actual) == 0), (len(actual) == 0),
) )
@ -176,22 +181,27 @@ func TestValidateIPFromString(t *testing.T) {
func TestValidateIPNetFromString(t *testing.T) { func TestValidateIPNetFromString(t *testing.T) {
var tests = []struct { var tests = []struct {
name string
subnet string subnet string
minaddrs int64 minaddrs int64
expected bool expected bool
}{ }{
{"", 0, false}, // not valid {"invalid missing CIDR", "", 0, false},
{"1234", 0, false}, // not valid {"invalid CIDR missing decimal points in IPv4 address and / mask", "1234", 0, false},
{"abc", 0, false}, // not valid {"invalid CIDR use of letters instead of numbers and / mask", "abc", 0, false},
{"1.2.3.4", 0, false}, // ip not valid {"invalid IPv4 address provided instead of CIDR representation", "1.2.3.4", 0, false},
{"10.0.0.16/29", 10, false}, // valid, but too small. At least 10 addrs needed {"invalid IPv6 address provided instead of CIDR representation", "2001:db8::1", 0, false},
{"10.0.0.16/12", 10, true}, // valid {"valid, but IPv4 CIDR too small. At least 10 addresses needed", "10.0.0.16/29", 10, false},
{"valid, but IPv6 CIDR too small. At least 10 addresses needed", "2001:db8::/125", 10, false},
{"valid IPv4 CIDR", "10.0.0.16/12", 10, true},
{"valid IPv6 CIDR", "2001:db8::/98", 10, true},
} }
for _, rt := range tests { for _, rt := range tests {
actual := ValidateIPNetFromString(rt.subnet, rt.minaddrs, nil) actual := ValidateIPNetFromString(rt.subnet, rt.minaddrs, nil)
if (len(actual) == 0) != rt.expected { if (len(actual) == 0) != rt.expected {
t.Errorf( t.Errorf(
"failed ValidateIPNetFromString:\n\texpected: %t\n\t actual: %t", "%s test case failed :\n\texpected: %t\n\t actual: %t",
rt.name,
rt.expected, rt.expected,
(len(actual) == 0), (len(actual) == 0),
) )
@ -202,54 +212,71 @@ func TestValidateIPNetFromString(t *testing.T) {
func TestValidateMasterConfiguration(t *testing.T) { func TestValidateMasterConfiguration(t *testing.T) {
nodename := "valid-nodename" nodename := "valid-nodename"
var tests = []struct { var tests = []struct {
name string
s *kubeadm.MasterConfiguration s *kubeadm.MasterConfiguration
expected bool expected bool
}{ }{
{&kubeadm.MasterConfiguration{}, false}, {"invalid missing master configuration",
{&kubeadm.MasterConfiguration{ &kubeadm.MasterConfiguration{}, false},
AuthorizationModes: []string{"Node", "RBAC"}, {"invalid missing token with IPv4 service subnet",
Networking: kubeadm.Networking{ &kubeadm.MasterConfiguration{
ServiceSubnet: "10.96.0.1/12", AuthorizationModes: []string{"Node", "RBAC"},
DNSDomain: "cluster.local", Networking: kubeadm.Networking{
}, ServiceSubnet: "10.96.0.1/12",
CertificatesDir: "/some/cert/dir", DNSDomain: "cluster.local",
NodeName: nodename, },
}, false}, CertificatesDir: "/some/cert/dir",
{&kubeadm.MasterConfiguration{ NodeName: nodename,
AuthorizationModes: []string{"Node", "RBAC"}, }, false},
Networking: kubeadm.Networking{ {"invalid missing token with IPv6 service subnet",
ServiceSubnet: "10.96.0.1/12", &kubeadm.MasterConfiguration{
DNSDomain: "cluster.local", AuthorizationModes: []string{"Node", "RBAC"},
}, Networking: kubeadm.Networking{
CertificatesDir: "/some/other/cert/dir", ServiceSubnet: "2001:db8::1/98",
Token: "abcdef.0123456789abcdef", DNSDomain: "cluster.local",
NodeName: nodename, },
}, true}, CertificatesDir: "/some/cert/dir",
{&kubeadm.MasterConfiguration{ NodeName: nodename,
AuthorizationModes: []string{"Node", "RBAC"}, }, false},
Networking: kubeadm.Networking{ {"invalid missing node name",
ServiceSubnet: "2001:db8::/98", &kubeadm.MasterConfiguration{
DNSDomain: "cluster.local", AuthorizationModes: []string{"Node", "RBAC"},
}, Networking: kubeadm.Networking{
CertificatesDir: "/some/cert/dir", ServiceSubnet: "10.96.0.1/12",
NodeName: nodename, DNSDomain: "cluster.local",
}, false}, },
{&kubeadm.MasterConfiguration{ CertificatesDir: "/some/other/cert/dir",
AuthorizationModes: []string{"Node", "RBAC"}, Token: "abcdef.0123456789abcdef",
Networking: kubeadm.Networking{ }, false},
ServiceSubnet: "2001:db8::/98", {"valid master configuration with IPv4 service subnet",
DNSDomain: "cluster.local", &kubeadm.MasterConfiguration{
}, AuthorizationModes: []string{"Node", "RBAC"},
CertificatesDir: "/some/other/cert/dir", Networking: kubeadm.Networking{
Token: "abcdef.0123456789abcdef", ServiceSubnet: "10.96.0.1/12",
NodeName: nodename, DNSDomain: "cluster.local",
}, true}, },
CertificatesDir: "/some/other/cert/dir",
Token: "abcdef.0123456789abcdef",
NodeName: nodename,
}, true},
{"valid master configuration using IPv6 service subnet",
&kubeadm.MasterConfiguration{
AuthorizationModes: []string{"Node", "RBAC"},
Networking: kubeadm.Networking{
ServiceSubnet: "2001:db8::1/98",
DNSDomain: "cluster.local",
},
CertificatesDir: "/some/other/cert/dir",
Token: "abcdef.0123456789abcdef",
NodeName: nodename,
}, true},
} }
for _, rt := range tests { for _, rt := range tests {
actual := ValidateMasterConfiguration(rt.s) actual := ValidateMasterConfiguration(rt.s)
if (len(actual) == 0) != rt.expected { if (len(actual) == 0) != rt.expected {
t.Errorf( t.Errorf(
"failed ValidateMasterConfiguration:\n\texpected: %t\n\t actual: %t", "%s test case failed:\n\texpected: %t\n\t actual: %t",
rt.name,
rt.expected, rt.expected,
(len(actual) == 0), (len(actual) == 0),
) )

View File

@ -37,27 +37,29 @@ func TestNewCACertAndKey(t *testing.T) {
func TestNewAPIServerCertAndKey(t *testing.T) { func TestNewAPIServerCertAndKey(t *testing.T) {
hostname := "valid-hostname" hostname := "valid-hostname"
advertiseIP := "1.2.3.4" advertiseAddresses := []string{"1.2.3.4", "1:2:3::4"}
cfg := &kubeadmapi.MasterConfiguration{ for _, addr := range advertiseAddresses {
API: kubeadmapi.API{AdvertiseAddress: advertiseIP}, cfg := &kubeadmapi.MasterConfiguration{
Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"}, API: kubeadmapi.API{AdvertiseAddress: addr},
NodeName: "valid-hostname", Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"},
} NodeName: "valid-hostname",
caCert, caKey, err := NewCACertAndKey() }
caCert, caKey, err := NewCACertAndKey()
apiServerCert, _, err := NewAPIServerCertAndKey(cfg, caCert, caKey) apiServerCert, _, err := NewAPIServerCertAndKey(cfg, caCert, caKey)
if err != nil { if err != nil {
t.Fatalf("failed creation of cert and key: %v", err) t.Fatalf("failed creation of cert and key: %v", err)
} }
assertIsSignedByCa(t, apiServerCert, caCert) assertIsSignedByCa(t, apiServerCert, caCert)
assertHasServerAuth(t, apiServerCert) assertHasServerAuth(t, apiServerCert)
for _, DNSName := range []string{hostname, "kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc.cluster.local"} { for _, DNSName := range []string{hostname, "kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc.cluster.local"} {
assertHasDNSNames(t, apiServerCert, DNSName) assertHasDNSNames(t, apiServerCert, DNSName)
} }
for _, IPAddress := range []string{"10.96.0.1", advertiseIP} { for _, IPAddress := range []string{"10.96.0.1", addr} {
assertHasIPAddresses(t, apiServerCert, net.ParseIP(IPAddress)) assertHasIPAddresses(t, apiServerCert, net.ParseIP(IPAddress))
}
} }
} }