From 9fc231e5c00752efd0b665805c4c89dcf04a07db Mon Sep 17 00:00:00 2001 From: Maria Ntalla Date: Tue, 5 Jun 2018 11:25:23 +0100 Subject: [PATCH 01/19] Setup TLS with CA Cert - Extend config to take a path to a CA Certificate - Use the CA Cert when establishing a connection with the SOAP client Testing We provide certs and keys for tests as fixtures, `vclib/fixtures`. Those were created (and can be regenerated) using `vclib/fixtures/createCerts.sh`. At the moment it's possible to configure a CA path and at the same time allow insecure communication between vsphere cloud provider and vcenter. This may change in the future; we might opt for overwriting the insecure communication if a CA is configured / log and transparently pass the arguments to the vcenter command / other. To be discussed. At the moment the CA is a global level configuration. In other words, all vcenter servers need to use certificates signed by the same CA. There might be use cases for different CA per vcenter server; to be discussed. --- .../providers/vsphere/vclib/connection.go | 52 ++++++++ .../vsphere/vclib/connection_test.go | 122 ++++++++++++++++++ .../providers/vsphere/vclib/fixtures/ca.key | 51 ++++++++ .../providers/vsphere/vclib/fixtures/ca.pem | 29 +++++ .../vsphere/vclib/fixtures/createCerts.sh | 61 +++++++++ .../vsphere/vclib/fixtures/invalid.pem | 1 + .../vsphere/vclib/fixtures/server.csr | 28 ++++ .../vsphere/vclib/fixtures/server.key | 51 ++++++++ .../vsphere/vclib/fixtures/server.pem | 30 +++++ .../providers/vsphere/vsphere.go | 5 + .../providers/vsphere/vsphere_test.go | 69 +++++++++- 11 files changed, 496 insertions(+), 3 deletions(-) create mode 100644 pkg/cloudprovider/providers/vsphere/vclib/connection_test.go create mode 100644 pkg/cloudprovider/providers/vsphere/vclib/fixtures/ca.key create mode 100644 pkg/cloudprovider/providers/vsphere/vclib/fixtures/ca.pem create mode 100755 pkg/cloudprovider/providers/vsphere/vclib/fixtures/createCerts.sh create mode 100644 pkg/cloudprovider/providers/vsphere/vclib/fixtures/invalid.pem create mode 100644 pkg/cloudprovider/providers/vsphere/vclib/fixtures/server.csr create mode 100644 pkg/cloudprovider/providers/vsphere/vclib/fixtures/server.key create mode 100644 pkg/cloudprovider/providers/vsphere/vclib/fixtures/server.pem diff --git a/pkg/cloudprovider/providers/vsphere/vclib/connection.go b/pkg/cloudprovider/providers/vsphere/vclib/connection.go index 91f0e8a963a..d8166377ffc 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/connection.go +++ b/pkg/cloudprovider/providers/vsphere/vclib/connection.go @@ -19,8 +19,12 @@ package vclib import ( "context" "crypto/tls" + "crypto/x509" "encoding/pem" + "errors" + "io/ioutil" "net" + "net/http" neturl "net/url" "sync" @@ -38,6 +42,7 @@ type VSphereConnection struct { Password string Hostname string Port string + CACert string Insecure bool RoundTripperCount uint credentialsLock sync.Mutex @@ -130,11 +135,50 @@ func (connection *VSphereConnection) login(ctx context.Context, client *vim25.Cl // Logout calls SessionManager.Logout for the given connection. func (connection *VSphereConnection) Logout(ctx context.Context) { m := session.NewManager(connection.Client) + + hasActiveSession, err := m.SessionIsActive(ctx) + if err != nil { + glog.Errorf("Logout failed: %s", err) + return + } + if !hasActiveSession { + glog.Errorf("No active session, cannot logout") + return + } if err := m.Logout(ctx); err != nil { glog.Errorf("Logout failed: %s", err) } } +var ( + ErrCaCertNotReadable = errors.New("Could not read CA cert file") + ErrCaCertInvalid = errors.New("Could not parse CA cert file") + ErrUnsupportedTransport = errors.New("Only support HTTP transport if configuring TLS") +) + +func (connection *VSphereConnection) ConfigureTransportWithCA(transport http.RoundTripper) error { + caCertBytes, err := ioutil.ReadFile(connection.CACert) + if err != nil { + glog.Errorf("Could not read CA cert file, %s", connection.CACert) + return ErrCaCertNotReadable + } + certPool := x509.NewCertPool() + + if ok := certPool.AppendCertsFromPEM(caCertBytes); !ok { + glog.Errorf("Cannot add CA to cert pool") + return ErrCaCertInvalid + } + httpTransport, ok := transport.(*http.Transport) + if !ok { + glog.Errorf("Failed to http transport") + return ErrUnsupportedTransport + } + + httpTransport.TLSClientConfig.RootCAs = certPool + + return nil +} + // NewClient creates a new govmomi client for the VSphereConnection obj func (connection *VSphereConnection) NewClient(ctx context.Context) (*vim25.Client, error) { url, err := soap.ParseURL(net.JoinHostPort(connection.Hostname, connection.Port)) @@ -144,11 +188,19 @@ func (connection *VSphereConnection) NewClient(ctx context.Context) (*vim25.Clie } sc := soap.NewClient(url, connection.Insecure) + + if connection.CACert != "" { + if err := connection.ConfigureTransportWithCA(sc.Client.Transport); err != nil { + return nil, err + } + } + client, err := vim25.NewClient(ctx, sc) if err != nil { glog.Errorf("Failed to create new client. err: %+v", err) return nil, err } + err = connection.login(ctx, client) if err != nil { return nil, err diff --git a/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go new file mode 100644 index 00000000000..ab76b4cc227 --- /dev/null +++ b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go @@ -0,0 +1,122 @@ +package vclib_test + +import ( + "context" + "crypto/tls" + "crypto/x509" + "io/ioutil" + "net/http" + "net/http/httptest" + "net/url" + "testing" + + "k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vclib" +) + +func createTestServer(t *testing.T, caCertPath, serverCertPath, serverKeyPath string, handler http.HandlerFunc) *httptest.Server { + caCertPEM, err := ioutil.ReadFile(caCertPath) + if err != nil { + t.Fatalf("Could not read ca cert from file") + } + + serverCert, err := tls.LoadX509KeyPair(serverCertPath, serverKeyPath) + if err != nil { + t.Fatalf("Could not load server cert and server key from files: %#v", err) + } + + certPool := x509.NewCertPool() + if ok := certPool.AppendCertsFromPEM(caCertPEM); !ok { + t.Fatalf("Cannot add CA to CAPool") + } + + server := httptest.NewUnstartedServer(http.HandlerFunc(handler)) + server.TLS = &tls.Config{ + Certificates: []tls.Certificate{ + serverCert, + }, + RootCAs: certPool, + } + + return server +} + +func TestSomething(t *testing.T) { + caCertPath := "fixtures/ca.pem" + serverCertPath := "fixtures/server.pem" + serverKeyPath := "fixtures/server.key" + + gotRequest := false + handler := func(w http.ResponseWriter, r *http.Request) { + gotRequest = true + } + + server := createTestServer(t, caCertPath, serverCertPath, serverKeyPath, handler) + server.StartTLS() + + u, err := url.Parse(server.URL) + if err != nil { + t.Fatalf("Cannot parse URL: %v", err) + } + + connection := &vclib.VSphereConnection{ + Hostname: u.Hostname(), + Port: u.Port(), + CACert: "fixtures/ca.pem", + } + + // Ignoring error here, because we only care about the TLS connection + connection.NewClient(context.Background()) + + if !gotRequest { + t.Fatalf("Never saw a request, TLS connection could not be established") + } +} + +func TestWithInvalidCaCertPath(t *testing.T) { + connection := &vclib.VSphereConnection{ + Hostname: "should-not-matter", + Port: "should-not-matter", + CACert: "invalid-path", + } + + _, err := connection.NewClient(context.Background()) + + if err != vclib.ErrCaCertNotReadable { + t.Fatalf("should have occoured") + } +} + +func TestInvalidCaCert(t *testing.T) { + connection := &vclib.VSphereConnection{ + Hostname: "should-not-matter", + Port: "should-not-matter", + CACert: "fixtures/invalid.pem", + } + + _, err := connection.NewClient(context.Background()) + + if err != vclib.ErrCaCertInvalid { + t.Fatalf("should have occoured") + } +} + +func TestUnsupportedTransport(t *testing.T) { + notHttpTransport := new(fakeTransport) + + connection := &vclib.VSphereConnection{ + Hostname: "should-not-matter", + Port: "should-not-matter", + CACert: "fixtures/ca.pem", + } + + err := connection.ConfigureTransportWithCA(notHttpTransport) + if err != vclib.ErrUnsupportedTransport { + t.Fatalf("should have occured") + } +} + +type fakeTransport struct{} + +func (ft fakeTransport) RoundTrip(*http.Request) (*http.Response, error) { + return nil, nil +} diff --git a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/ca.key b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/ca.key new file mode 100644 index 00000000000..7c9848e9ff3 --- /dev/null +++ b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/ca.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/ca.pem b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/ca.pem new file mode 100644 index 00000000000..4359bb5045e --- /dev/null +++ b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/ca.pem @@ -0,0 +1,29 @@ +-----BEGIN CERTIFICATE----- +MIIE/DCCAuQCCQDsqyXMQlDdzzANBgkqhkiG9w0BAQsFADBAMQswCQYDVQQGEwJV +UzELMAkGA1UECAwCQ0ExEzARBgNVBAoMCkFjbWUsIEluYy4xDzANBgNVBAMMBnNv +bWVDQTAeFw0xODA2MDQxNDU3NDZaFw00NjA2MTcxNDU3NDZaMEAxCzAJBgNVBAYT +AlVTMQswCQYDVQQIDAJDQTETMBEGA1UECgwKQWNtZSwgSW5jLjEPMA0GA1UEAwwG +c29tZUNBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsQRltjBKCgsI +C4xGN5OWzJSaIhA1F8l4YO/7yGBj4ehKmEBrjbOFMnUOp7Aq1rj/yrLzHNeKja9P +D3fSsLMgbv34DR4JMXlbh2Cm84XBp1ibrqxmqsz9nAGiDcJKf0QodxzAYcq8CZ0X +os1glgwHBSuf2hflWZoi4L/OAF4lDSmXk5yBA+hcxdnjV3FTW5MuYlLezL1R+OG7 +Wo30D2NYdCXyK+Xa0IbEnD2vtMvoZXid/PuNC18oPLuIjLs5XnCqoznNsbk/S4Hr +Eb8YntosTiaa+Vc/MdVj7rILTueDo0qRNB+RnujALMtp0RP/mTLZ2AoVvpaB+AWX +8DNN+uhf8ZexunFldEStf0yL1vtaszoCAzHVi3Y6SON3YCZiNHGtjKabhg/1J6ib +AwmdugzB7D3CRJfDyaJ0x/qAzdSMWqQfZ2tJReLiK7+I6civo4XpqbSdN3Sul9X0 +qaz2z/gjoacSmAEqKnKEjXbjPU38f+F+KwDslHYAp999DNlhygOnGjam0/UIrdq1 +eFvLbWE7d9iqot0CJlQ4Hv2Sw5rhMibNYFfcw3aHLtWL9OYTQ2a0vLddllupTvxh +Y+OQLOU+EAZ2e4Gm37CQou205cwKRz/4rO81StRukrAyymClebIiii0qGbTGvZ86 +/LTiJtIG8r2mYmdHYcF3EiKitHTCK7kCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEA +b6zjyhxWUFo+cI8K1lMegBTulE1ivCeMtEjvGoU3X42Gr/6y7hz5P4evgzezF+vN +eArqsxQ4qxPSDvmUwKJ7ovoggMi6mZqzZSTSSViIMsJUJ1ukDUsdI6iw49R6T6Cj +MX2SXsj1go7f0Mhw/a9BJfHXbnawnEA4V2Tr6Epm1tW+oAQi5eimOdr36stlLTF0 +uoJTEfckN9AsyYLSx71C8aq/pGTzXGG7aP6yyaHHD1+u3StQB+63DnPsU7zODOpN +cTjpuZy1WYvY5m5+iiEUT9tSBtIjIN2lPwZCCRd/l8bybb/6T3nttHv9ijON1vSF +RG8BxJwYzzXEVYY67ztM6dxp5c9gfegyE1Q/MtF6nwgsZ4WpZQbMDRbAd4yyCLM+ +aKDnDlB+I4e4WegodvTlDaYvtJUQaAlefGmfP+r9I5fPvbGRJDJ7AoirJnv2MCLs +hNbEXk/+/oNWIHAFQTNNzS40U05ytPBrtPoAOL2e+a92rHcWfsZ/ApYSCesZxZNw +1k2siPQ8uKBM10AW0fMU8wZs02LYcR5Xq1Zaj/GWooZaAy6QQfZK6AELpdLSZmMs +tzPz6gxckswJEnZ3w/wyzHmSMSJrr2+dydYA/UN509V/nQQolgE/ZQoMUlu74wCf +HEeQH71L269fQM1RxuAEfBz0RuEZjQc7A9NETm5I0BM= +-----END CERTIFICATE----- diff --git a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/createCerts.sh b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/createCerts.sh new file mode 100755 index 00000000000..0efd8d6ddc7 --- /dev/null +++ b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/createCerts.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash + +set -eu + +# 1. create CA key +# 2. create CA cert +# 3. create CSR with IP SAN +# 4. create server cert with IP SAN + +createKey() { + openssl genrsa -out "$1" 4096 +} + +createCaCert() { + openssl req -x509 \ + -subj "/C=US/ST=CA/O=Acme, Inc./CN=someCA" \ + -new -nodes -key "$2" -sha256 -days 10240 -out "$1" +} + +createCSR() { + openssl req -new -sha256 \ + -key "$2" \ + -subj "/C=US/ST=CA/O=Acme, Inc./CN=localhost" \ + -reqexts SAN \ + -config <( + cat /etc/ssl/openssl.cnf ; \ + printf '\n[SAN]\n' ; \ + getSAN + ) \ + -out "$1" +} + +signCSR() { + openssl x509 -req -in "$2" \ + -CA "$3" \ + -CAkey "$4" \ + -CAcreateserial \ + -days 3650 -sha256 \ + -extfile <( getSAN ) \ + -out "$1" +} + +getSAN() { + printf "subjectAltName=DNS:localhost,IP:127.0.0.1" +} + +main() { + local caCertPath="./ca.pem" + local caKeyPath="./ca.key" + local serverCsrPath="./server.csr" + local serverCertPath="./server.pem" + local serverKeyPath="./server.key" + + createKey "$caKeyPath" + createCaCert "$caCertPath" "$caKeyPath" + createKey "$serverKeyPath" + createCSR "$serverCsrPath" "$serverKeyPath" + signCSR "$serverCertPath" "$serverCsrPath" "$caCertPath" "$caKeyPath" +} + +main "$@" diff --git a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/invalid.pem b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/invalid.pem new file mode 100644 index 00000000000..253d11958ad --- /dev/null +++ b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/invalid.pem @@ -0,0 +1 @@ +this is some invalid content diff --git a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/server.csr b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/server.csr new file mode 100644 index 00000000000..c6998bb632f --- /dev/null +++ b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/server.csr @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIEtTCCAp0CAQAwQzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRMwEQYDVQQK +DApBY21lLCBJbmMuMRIwEAYDVQQDDAlsb2NhbGhvc3QwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQDRtnbdQFkM8IgTx2KU2lyZitrgqhcxRVGaMrw+d+Q0 +3IZ9y8L4sVFjBqAXUIkCndfQSVyzAnSgrvJqpFk43TIbg7TY/ZpLdN+tHn+PT3qN +MYjOIMR+BVpT8Fi23Ds5ghVw26Av4ZfT6a3R2e4ndsdvwM7nf+8YwU2qPwu48cDN +OLCGoV9JUZADoHHVQOC9LZfUWtSxU0zhnnEWyu33OInzBtwTSdrxQui287svcJBT +XkMlRzj5adAZBJ8zhxsNxs6lPQX/C7V3yjTEdSvnYAtoGbFPqh5D4aHw7Vjrax7Z +ihUCpIJ+Nf01UzzxqkXhlf08qcMxA8MIRDujwsY2DKu1TpZqn+fDP0nfWUe/PJ7d +7hUHkdvH09D8csP72Ryu+Nmgbx1gPgv+srGHCwVCFa1Hg+oq6u2Uq2eW6Vt3LcRc +8S1zG6CjvFthU7Eurh6a2dsDvWDSst3JNnkOFeSLjOqa5tDSNh5SZIbZ17BiiiD6 +MIqRDBiK4jGh20E0m1cVk1e1QRpD33ViLDGqD628bCcOtD86eUhrv1k+fqPr1gF0 +fdbQXJoYonPvfHlEzQPXprPNdv8JSQ/aKQqWO7yC8H/V+bpbRwL+vDMkQ3YMC3zf +bj7z8bJvQ7DOf0Ogy0wyP5FG1Jm47FE66ckKTZdLCf8VrxO8cnrXFGZ0CQIEu4Rn +PQIDAQABoC0wKwYJKoZIhvcNAQkOMR4wHDAaBgNVHREEEzARgglsb2NhbGhvc3SH +BH8AAAEwDQYJKoZIhvcNAQELBQADggIBADh1KvKchPJTEDX9oonipCyvHLzysJpI +Li1ZWDSu0v4ASlYMJrAxQNphHYDu/FZdqvDvqQ0M8naM9sNdq0UkgiAdOtjtDB9J +k18/sOOjXCqAWIcFr9vdwbs0bKD1x2sBBVN2O3G+YX7w8YwWX1VQdBoObmJiSAmw +V6l1yltaiw6fb1RpO71JFjL19QvRuSs7pVhDjuI1gu/bggebxh6AIpAHXq3lukMS +a3mOyeiik5PlsDwxMMJNCKzqf+DYLzslMKq3IaVDyyqPxaZeVCb80525W4W+2/eV +kmcMpqUJaG+iqYfuaX1S+7jZRri0lhkejE8HJ1xT8JWaovZ7G2WzWDEqUPVvVoX4 +g2MgLVtcb6WcstQpsQ+AY0rKPq8K4T5t420JtRLI9oUt5eQm7yWGFF1p4URWzuYq +/TOTPxIrufeFfqBsH8XAOydmuwUGunpefoxvD0tp9SFpRm6NWliYyunFZP82xtOK +eP3aW3A1KnPdLgAyi9/iwi9VzGQTu1iWAc9si9xTyqTNOtvgYUzy2wmic2HgWfEs +NEv+wW6CNh1qR1Vq7j0zkl327CFrGBvKbR1d5cleNx8EiWZ1QNmickMaCHBiwkql +yIbSPtlmzme8y8N73bUaV74DbKExZvu2CnUzdIHOt0Dpax6TkBHc1HI530v58eN/ +VDP7+tBBVo+c +-----END CERTIFICATE REQUEST----- diff --git a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/server.key b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/server.key new file mode 100644 index 00000000000..b08afaaee01 --- /dev/null +++ b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/server.key @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/server.pem b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/server.pem new file mode 100644 index 00000000000..a43b6366e13 --- /dev/null +++ b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/server.pem @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFJDCCAwygAwIBAgIJAOcEAbv8NslcMA0GCSqGSIb3DQEBCwUAMEAxCzAJBgNV +BAYTAlVTMQswCQYDVQQIDAJDQTETMBEGA1UECgwKQWNtZSwgSW5jLjEPMA0GA1UE +AwwGc29tZUNBMB4XDTE4MDYwNDE0NTgwNloXDTI4MDYwMTE0NTgwNlowQzELMAkG +A1UEBhMCVVMxCzAJBgNVBAgMAkNBMRMwEQYDVQQKDApBY21lLCBJbmMuMRIwEAYD +VQQDDAlsb2NhbGhvc3QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDR +tnbdQFkM8IgTx2KU2lyZitrgqhcxRVGaMrw+d+Q03IZ9y8L4sVFjBqAXUIkCndfQ +SVyzAnSgrvJqpFk43TIbg7TY/ZpLdN+tHn+PT3qNMYjOIMR+BVpT8Fi23Ds5ghVw +26Av4ZfT6a3R2e4ndsdvwM7nf+8YwU2qPwu48cDNOLCGoV9JUZADoHHVQOC9LZfU +WtSxU0zhnnEWyu33OInzBtwTSdrxQui287svcJBTXkMlRzj5adAZBJ8zhxsNxs6l +PQX/C7V3yjTEdSvnYAtoGbFPqh5D4aHw7Vjrax7ZihUCpIJ+Nf01UzzxqkXhlf08 +qcMxA8MIRDujwsY2DKu1TpZqn+fDP0nfWUe/PJ7d7hUHkdvH09D8csP72Ryu+Nmg +bx1gPgv+srGHCwVCFa1Hg+oq6u2Uq2eW6Vt3LcRc8S1zG6CjvFthU7Eurh6a2dsD +vWDSst3JNnkOFeSLjOqa5tDSNh5SZIbZ17BiiiD6MIqRDBiK4jGh20E0m1cVk1e1 +QRpD33ViLDGqD628bCcOtD86eUhrv1k+fqPr1gF0fdbQXJoYonPvfHlEzQPXprPN +dv8JSQ/aKQqWO7yC8H/V+bpbRwL+vDMkQ3YMC3zfbj7z8bJvQ7DOf0Ogy0wyP5FG +1Jm47FE66ckKTZdLCf8VrxO8cnrXFGZ0CQIEu4RnPQIDAQABox4wHDAaBgNVHREE +EzARgglsb2NhbGhvc3SHBH8AAAEwDQYJKoZIhvcNAQELBQADggIBAJkQELAVTJSS +1Rfmn9aRXOd6Uap7+3oE3ZOuUU2XxBJKXClVhKcCJ8nToDHsSV6D7fMcgJvg4fOt +pkQldEi845mUx0t8F/uKqwO1fx+Cjnr8meArGpwn2bma+4cpZyLbFgAZH7Cst+er +FbewtoPbfnADZlZzK35jcSzGf+oYJU11QJjTyRRXBp9eC73Fa9fM53GrA5GkJiSc +u7+mRlAKKEMmNNdnZa48X/cKI7UXp+qHSdkE9zDZ/LrbZPV8OuJY/RpwLT1A59pM +wkvC1AaGIa+ysfLw7s+0K2B1xmquAdopzcwGmK5CGJQmoF3YEFc+QN5fkC4UbizM +XiXZ3Uu0bbg9qNjR99Z0N/knVce+KpAeJg9cEFSsdTM2oaz/53KsalxOWsDkxvuI +HGwjSMPO22JWPs9zs06/1CsiQvn7O/Kx4xjwuSzxjKOJaolynF0lUsNXljOnF6FC +cQCBsY3TFdJFAtjYouiUu5UI4tvQ6pFmCDfj2Ioj+XhF0pd5G/bM3Hmb+WL9We4s +ajoaB85yAy5YdxBuLW5/TdeRqWZHB3AXbAXY8KoOPaOv9NCRWwwaGsiBSUSPdUzT +UkqWjMhcZnmHFeKVDQWpVIy1zrVojR17B8/xY9uypg5yZxGpssUwbfi9m/TnPH/A +a6U8cIpiDSFdeNYPGwKm8O06pY67+w1I +-----END CERTIFICATE----- diff --git a/pkg/cloudprovider/providers/vsphere/vsphere.go b/pkg/cloudprovider/providers/vsphere/vsphere.go index fbe5d50e98c..af1408a4eed 100644 --- a/pkg/cloudprovider/providers/vsphere/vsphere.go +++ b/pkg/cloudprovider/providers/vsphere/vsphere.go @@ -121,6 +121,9 @@ type VSphereConfig struct { VCenterPort string `gcfg:"port"` // True if vCenter uses self-signed cert. InsecureFlag bool `gcfg:"insecure-flag"` + // Specifies the path to a CA certificate in PEM format. Optional; if not + // configured, the system's CA certificates will be used. + CAFile string `gcfg:"ca-file"` // Datacenter in which VMs are located. // Deprecated. Use "datacenters" instead. Datacenter string `gcfg:"datacenter"` @@ -345,7 +348,9 @@ func populateVsphereInstanceMap(cfg *VSphereConfig) (map[string]*VSphereInstance Insecure: cfg.Global.InsecureFlag, RoundTripperCount: vcConfig.RoundTripperCount, Port: vcConfig.VCenterPort, + CACert: cfg.Global.CAFile, } + vsphereIns := VSphereInstance{ conn: &vSphereConn, cfg: &vcConfig, diff --git a/pkg/cloudprovider/providers/vsphere/vsphere_test.go b/pkg/cloudprovider/providers/vsphere/vsphere_test.go index 0533405b190..aa13921a117 100644 --- a/pkg/cloudprovider/providers/vsphere/vsphere_test.go +++ b/pkg/cloudprovider/providers/vsphere/vsphere_test.go @@ -19,6 +19,8 @@ package vsphere import ( "context" "crypto/tls" + "crypto/x509" + "io/ioutil" "log" "os" "strconv" @@ -89,8 +91,12 @@ func configFromEnv() (cfg VSphereConfig, ok bool) { return } -// configFromSim starts a vcsim instance and returns config for use against the vcsim instance. func configFromSim() (VSphereConfig, func()) { + return configFromSimWithTLS(new(tls.Config), true) +} + +// configFromSim starts a vcsim instance and returns config for use against the vcsim instance. +func configFromSimWithTLS(tlsConfig *tls.Config, insecureAllowed bool) (VSphereConfig, func()) { var cfg VSphereConfig model := simulator.VPX() @@ -99,7 +105,7 @@ func configFromSim() (VSphereConfig, func()) { log.Fatal(err) } - model.Service.TLS = new(tls.Config) + model.Service.TLS = tlsConfig s := model.Service.NewServer() // STS simulator @@ -109,7 +115,8 @@ func configFromSim() (VSphereConfig, func()) { // Lookup Service simulator model.Service.RegisterSDK(lookup.New()) - cfg.Global.InsecureFlag = true + cfg.Global.InsecureFlag = insecureAllowed + cfg.Global.VCenterIP = s.URL.Hostname() cfg.Global.VCenterPort = s.URL.Port() cfg.Global.User = s.URL.User.Username() @@ -160,6 +167,7 @@ insecure-flag = true datacenter = us-west vm-uuid = 1234 vm-name = vmname +ca-file = /some/path/to/a/ca.pem `)) if err != nil { t.Fatalf("Should succeed when a valid config is provided: %s", err) @@ -180,6 +188,10 @@ vm-name = vmname if cfg.Global.VMName != "vmname" { t.Errorf("incorrect vm-name: %s", cfg.Global.VMName) } + + if cfg.Global.CAFile != "/some/path/to/a/ca.pem" { + t.Errorf("incorrect ca-file: %s", cfg.Global.CAFile) + } } func TestNewVSphere(t *testing.T) { @@ -250,6 +262,57 @@ func TestVSphereLoginByToken(t *testing.T) { vcInstance.conn.Logout(ctx) } +func TestVSphereLoginWithCaCert(t *testing.T) { + caCertPath := "./vclib/fixtures/ca.pem" + serverCertPath := "./vclib/fixtures/server.pem" + serverKeyPath := "./vclib/fixtures/server.key" + + caCertPEM, err := ioutil.ReadFile(caCertPath) + if err != nil { + t.Fatalf("Could not read ca cert from file") + } + + serverCert, err := tls.LoadX509KeyPair(serverCertPath, serverKeyPath) + if err != nil { + t.Fatalf("Could not load server cert and server key from files: %#v", err) + } + + certPool := x509.NewCertPool() + if ok := certPool.AppendCertsFromPEM(caCertPEM); !ok { + t.Fatalf("Cannot add CA to CAPool") + } + + tlsConfig := tls.Config{ + Certificates: []tls.Certificate{serverCert}, + RootCAs: certPool, + } + + cfg, cleanup := configFromSimWithTLS(&tlsConfig, false) + defer cleanup() + + cfg.Global.CAFile = caCertPath + + // Create vSphere configuration object + vs, err := newControllerNode(cfg) + if err != nil { + t.Fatalf("Failed to construct/authenticate vSphere: %s", err) + } + + ctx := context.Background() + + // Create vSphere client + vcInstance, ok := vs.vsphereInstanceMap[cfg.Global.VCenterIP] + if !ok { + t.Fatalf("Couldn't get vSphere instance: %s", cfg.Global.VCenterIP) + } + + err = vcInstance.conn.Connect(ctx) + if err != nil { + t.Errorf("Failed to connect to vSphere: %s", err) + } + vcInstance.conn.Logout(ctx) +} + func TestZones(t *testing.T) { cfg := VSphereConfig{} cfg.Global.Datacenter = "myDatacenter" From b3a1750afeae21bbd4d259235a05a118d9a35e75 Mon Sep 17 00:00:00 2001 From: Maria Ntalla Date: Tue, 5 Jun 2018 11:45:40 +0100 Subject: [PATCH 02/19] Make bazel happy ./hack/update-bazel.sh --- pkg/cloudprovider/providers/vsphere/vclib/BUILD | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/cloudprovider/providers/vsphere/vclib/BUILD b/pkg/cloudprovider/providers/vsphere/vclib/BUILD index 9bb59c3ab16..075f477f94b 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/BUILD +++ b/pkg/cloudprovider/providers/vsphere/vclib/BUILD @@ -72,3 +72,9 @@ go_test( "//vendor/github.com/vmware/govmomi/simulator:go_default_library", ], ) + +go_test( + name = "go_default_xtest", + srcs = ["connection_test.go"], + deps = [":go_default_library"], +) From 64f13c265cfa7d0b658053db75b9177ab07ef92e Mon Sep 17 00:00:00 2001 From: Maria Ntalla Date: Tue, 5 Jun 2018 11:48:38 +0100 Subject: [PATCH 03/19] Add LICENSE header --- .../providers/vsphere/vclib/connection_test.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go index ab76b4cc227..0afdfafccae 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go +++ b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go @@ -1,3 +1,19 @@ +/* +Copyright 2016 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 vclib_test import ( From b85d7600112c92a0edd0841754d003c8cafde9cc Mon Sep 17 00:00:00 2001 From: Maria Ntalla Date: Tue, 5 Jun 2018 11:58:16 +0100 Subject: [PATCH 04/19] Improve godocs and testcase naming --- .../providers/vsphere/vclib/connection_test.go | 2 +- pkg/cloudprovider/providers/vsphere/vsphere_test.go | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go index 0afdfafccae..f2f4b9646b0 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go +++ b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go @@ -56,7 +56,7 @@ func createTestServer(t *testing.T, caCertPath, serverCertPath, serverKeyPath st return server } -func TestSomething(t *testing.T) { +func TestWithValidCaCert(t *testing.T) { caCertPath := "fixtures/ca.pem" serverCertPath := "fixtures/server.pem" serverKeyPath := "fixtures/server.key" diff --git a/pkg/cloudprovider/providers/vsphere/vsphere_test.go b/pkg/cloudprovider/providers/vsphere/vsphere_test.go index aa13921a117..7a13d6ef44b 100644 --- a/pkg/cloudprovider/providers/vsphere/vsphere_test.go +++ b/pkg/cloudprovider/providers/vsphere/vsphere_test.go @@ -91,11 +91,15 @@ func configFromEnv() (cfg VSphereConfig, ok bool) { return } +// configFromSim starts a vcsim instance and returns config for use against the vcsim instance. +// The vcsim instance is configured with an empty tls.Config. func configFromSim() (VSphereConfig, func()) { return configFromSimWithTLS(new(tls.Config), true) } -// configFromSim starts a vcsim instance and returns config for use against the vcsim instance. +// configFromSimWithTLS starts a vcsim instance and returns config for use against the vcsim instance. +// The vcsim instance is configured with a tls.Config. The returned client +// config can be configured to allow/decline insecure connections. func configFromSimWithTLS(tlsConfig *tls.Config, insecureAllowed bool) (VSphereConfig, func()) { var cfg VSphereConfig model := simulator.VPX() From f7e9b6a474d5bf727d61180b2489291caa735b9d Mon Sep 17 00:00:00 2001 From: Maria Ntalla Date: Tue, 5 Jun 2018 12:24:24 +0100 Subject: [PATCH 05/19] Add LICENCE header to createCerts.sh Also remove comments that are not useful anymore. --- .../vsphere/vclib/fixtures/createCerts.sh | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/createCerts.sh b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/createCerts.sh index 0efd8d6ddc7..dd22d458d61 100755 --- a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/createCerts.sh +++ b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/createCerts.sh @@ -1,11 +1,20 @@ #!/usr/bin/env bash -set -eu +# Copyright 2018 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. -# 1. create CA key -# 2. create CA cert -# 3. create CSR with IP SAN -# 4. create server cert with IP SAN +set -eu createKey() { openssl genrsa -out "$1" 4096 From 90012e513accd3e133a1723b6bad17b5c4c17958 Mon Sep 17 00:00:00 2001 From: Maria Ntalla Date: Tue, 5 Jun 2018 14:03:12 +0100 Subject: [PATCH 06/19] Fix spelling --- .../providers/vsphere/vclib/connection_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go index f2f4b9646b0..54adcf899ec 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go +++ b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go @@ -98,7 +98,7 @@ func TestWithInvalidCaCertPath(t *testing.T) { _, err := connection.NewClient(context.Background()) if err != vclib.ErrCaCertNotReadable { - t.Fatalf("should have occoured") + t.Fatalf("should have occurred") } } @@ -112,7 +112,7 @@ func TestInvalidCaCert(t *testing.T) { _, err := connection.NewClient(context.Background()) if err != vclib.ErrCaCertInvalid { - t.Fatalf("should have occoured") + t.Fatalf("should have occurred") } } @@ -127,7 +127,7 @@ func TestUnsupportedTransport(t *testing.T) { err := connection.ConfigureTransportWithCA(notHttpTransport) if err != vclib.ErrUnsupportedTransport { - t.Fatalf("should have occured") + t.Fatalf("should have occurred") } } From 0cbe25436d500a45c34c72a81d14a1be4b88f8ff Mon Sep 17 00:00:00 2001 From: Maria Ntalla Date: Tue, 5 Jun 2018 14:37:44 +0100 Subject: [PATCH 07/19] Resolve paths of test fixtures at runtime This will help with bazel tests, which seem to use a different working directory from local test runs. --- pkg/cloudprovider/providers/vsphere/BUILD | 1 + .../providers/vsphere/vclib/BUILD | 6 +- .../vsphere/vclib/connection_test.go | 13 ++--- .../providers/vsphere/vclib/fixtures/BUILD | 26 +++++++++ .../vsphere/vclib/fixtures/fixtures.go | 58 +++++++++++++++++++ .../providers/vsphere/vsphere_test.go | 11 ++-- 6 files changed, 99 insertions(+), 16 deletions(-) create mode 100644 pkg/cloudprovider/providers/vsphere/vclib/fixtures/BUILD create mode 100644 pkg/cloudprovider/providers/vsphere/vclib/fixtures/fixtures.go diff --git a/pkg/cloudprovider/providers/vsphere/BUILD b/pkg/cloudprovider/providers/vsphere/BUILD index d6309bd52a9..8c0be034f9c 100644 --- a/pkg/cloudprovider/providers/vsphere/BUILD +++ b/pkg/cloudprovider/providers/vsphere/BUILD @@ -45,6 +45,7 @@ go_test( deps = [ "//pkg/cloudprovider:go_default_library", "//pkg/cloudprovider/providers/vsphere/vclib:go_default_library", + "//pkg/cloudprovider/providers/vsphere/vclib/fixtures:go_default_library", "//pkg/controller:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", diff --git a/pkg/cloudprovider/providers/vsphere/vclib/BUILD b/pkg/cloudprovider/providers/vsphere/vclib/BUILD index 075f477f94b..94dafba45f9 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/BUILD +++ b/pkg/cloudprovider/providers/vsphere/vclib/BUILD @@ -52,6 +52,7 @@ filegroup( srcs = [ ":package-srcs", "//pkg/cloudprovider/providers/vsphere/vclib/diskmanagers:all-srcs", + "//pkg/cloudprovider/providers/vsphere/vclib/fixtures:all-srcs", ], tags = ["automanaged"], ) @@ -76,5 +77,8 @@ go_test( go_test( name = "go_default_xtest", srcs = ["connection_test.go"], - deps = [":go_default_library"], + deps = [ + ":go_default_library", + "//pkg/cloudprovider/providers/vsphere/vclib/fixtures:go_default_library", + ], ) diff --git a/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go index 54adcf899ec..93f9bc08c8e 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go +++ b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go @@ -27,6 +27,7 @@ import ( "testing" "k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vclib" + "k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vclib/fixtures" ) func createTestServer(t *testing.T, caCertPath, serverCertPath, serverKeyPath string, handler http.HandlerFunc) *httptest.Server { @@ -57,16 +58,12 @@ func createTestServer(t *testing.T, caCertPath, serverCertPath, serverKeyPath st } func TestWithValidCaCert(t *testing.T) { - caCertPath := "fixtures/ca.pem" - serverCertPath := "fixtures/server.pem" - serverKeyPath := "fixtures/server.key" - gotRequest := false handler := func(w http.ResponseWriter, r *http.Request) { gotRequest = true } - server := createTestServer(t, caCertPath, serverCertPath, serverKeyPath, handler) + server := createTestServer(t, fixtures.CaCertPath, fixtures.ServerCertPath, fixtures.ServerKeyPath, handler) server.StartTLS() u, err := url.Parse(server.URL) @@ -77,7 +74,7 @@ func TestWithValidCaCert(t *testing.T) { connection := &vclib.VSphereConnection{ Hostname: u.Hostname(), Port: u.Port(), - CACert: "fixtures/ca.pem", + CACert: fixtures.CaCertPath, } // Ignoring error here, because we only care about the TLS connection @@ -106,7 +103,7 @@ func TestInvalidCaCert(t *testing.T) { connection := &vclib.VSphereConnection{ Hostname: "should-not-matter", Port: "should-not-matter", - CACert: "fixtures/invalid.pem", + CACert: fixtures.InvalidCaCertPath, } _, err := connection.NewClient(context.Background()) @@ -122,7 +119,7 @@ func TestUnsupportedTransport(t *testing.T) { connection := &vclib.VSphereConnection{ Hostname: "should-not-matter", Port: "should-not-matter", - CACert: "fixtures/ca.pem", + CACert: fixtures.CaCertPath, } err := connection.ConfigureTransportWithCA(notHttpTransport) diff --git a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/BUILD b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/BUILD new file mode 100644 index 00000000000..026ee7bd229 --- /dev/null +++ b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/BUILD @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "go_default_library", + srcs = ["fixtures.go"], + data = glob([ + "*.pem", + "*.key", + ]), + importpath = "k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vclib/fixtures", + visibility = ["//visibility:public"], +) + +filegroup( + name = "package-srcs", + srcs = glob(["**"]), + tags = ["automanaged"], + visibility = ["//visibility:private"], +) + +filegroup( + name = "all-srcs", + srcs = [":package-srcs"], + tags = ["automanaged"], + visibility = ["//visibility:public"], +) diff --git a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/fixtures.go b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/fixtures.go new file mode 100644 index 00000000000..a0838224bae --- /dev/null +++ b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/fixtures.go @@ -0,0 +1,58 @@ +/* +Copyright 2016 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 fixtures + +import ( + "os" + "path/filepath" + "runtime" + "strings" +) + +var ( + CaCertPath string + ServerCertPath string + ServerKeyPath string + InvalidCaCertPath string +) + +func init() { + _, thisFile, _, ok := runtime.Caller(0) + if !ok { + panic("Cannot get path to the fixtures") + } + + fixturesDir := filepath.Dir(thisFile) + + cwd, err := os.Getwd() + if err != nil { + panic("Cannot get CWD: " + err.Error()) + } + + // When tests run in a bazel sandbox `runtime.Caller()` + // returns a relative path, when run with plain `go test` the path + // returned is absolute. To make those fixtures work in both those cases, + // we prepend the CWD iff the CWD is not yet part of the path to the fixtures. + if !strings.HasPrefix(fixturesDir, cwd) { + fixturesDir = filepath.Join(cwd, fixturesDir) + } + + CaCertPath = filepath.Join(fixturesDir, "ca.pem") + ServerCertPath = filepath.Join(fixturesDir, "server.pem") + ServerKeyPath = filepath.Join(fixturesDir, "server.key") + InvalidCaCertPath = filepath.Join(fixturesDir, "invalid.pem") +} diff --git a/pkg/cloudprovider/providers/vsphere/vsphere_test.go b/pkg/cloudprovider/providers/vsphere/vsphere_test.go index 7a13d6ef44b..e2b391fddd4 100644 --- a/pkg/cloudprovider/providers/vsphere/vsphere_test.go +++ b/pkg/cloudprovider/providers/vsphere/vsphere_test.go @@ -35,6 +35,7 @@ import ( "k8s.io/apimachinery/pkg/util/rand" "k8s.io/kubernetes/pkg/cloudprovider" "k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vclib" + "k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vclib/fixtures" ) // localhostCert was generated from crypto/tls/generate_cert.go with the following command: @@ -267,16 +268,12 @@ func TestVSphereLoginByToken(t *testing.T) { } func TestVSphereLoginWithCaCert(t *testing.T) { - caCertPath := "./vclib/fixtures/ca.pem" - serverCertPath := "./vclib/fixtures/server.pem" - serverKeyPath := "./vclib/fixtures/server.key" - - caCertPEM, err := ioutil.ReadFile(caCertPath) + caCertPEM, err := ioutil.ReadFile(fixtures.CaCertPath) if err != nil { t.Fatalf("Could not read ca cert from file") } - serverCert, err := tls.LoadX509KeyPair(serverCertPath, serverKeyPath) + serverCert, err := tls.LoadX509KeyPair(fixtures.ServerCertPath, fixtures.ServerKeyPath) if err != nil { t.Fatalf("Could not load server cert and server key from files: %#v", err) } @@ -294,7 +291,7 @@ func TestVSphereLoginWithCaCert(t *testing.T) { cfg, cleanup := configFromSimWithTLS(&tlsConfig, false) defer cleanup() - cfg.Global.CAFile = caCertPath + cfg.Global.CAFile = fixtures.CaCertPath // Create vSphere configuration object vs, err := newControllerNode(cfg) From 795e4c42541cb3771c40a7ee82f6452e210a0ccc Mon Sep 17 00:00:00 2001 From: Maria Ntalla Date: Wed, 6 Jun 2018 13:12:56 +0100 Subject: [PATCH 08/19] Add godocs for fixtures ... and rename `InvalidCaCertPath` to `InvalidCertPath`. --- .../providers/vsphere/vclib/connection_test.go | 2 +- .../vsphere/vclib/fixtures/fixtures.go | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go index 93f9bc08c8e..1af398990a9 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go +++ b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go @@ -103,7 +103,7 @@ func TestInvalidCaCert(t *testing.T) { connection := &vclib.VSphereConnection{ Hostname: "should-not-matter", Port: "should-not-matter", - CACert: fixtures.InvalidCaCertPath, + CACert: fixtures.InvalidCertPath, } _, err := connection.NewClient(context.Background()) diff --git a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/fixtures.go b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/fixtures.go index a0838224bae..ebd64d58f9a 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/fixtures.go +++ b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/fixtures.go @@ -24,10 +24,17 @@ import ( ) var ( - CaCertPath string - ServerCertPath string - ServerKeyPath string - InvalidCaCertPath string + // CaCertPath is the filepath to a certificate that can be used as a CA + // certificate. + CaCertPath string + // ServerCertPath is the filepath to a leaf certifiacte signed by the CA at + // `CaCertPath`. + ServerCertPath string + // ServerKeyPath is the filepath to the private key for the ceritifiacte at + // `ServerCertPath`. + ServerKeyPath string + // InvalidCertPath is the filepath to an invalid certificate. + InvalidCertPath string ) func init() { @@ -54,5 +61,5 @@ func init() { CaCertPath = filepath.Join(fixturesDir, "ca.pem") ServerCertPath = filepath.Join(fixturesDir, "server.pem") ServerKeyPath = filepath.Join(fixturesDir, "server.key") - InvalidCaCertPath = filepath.Join(fixturesDir, "invalid.pem") + InvalidCertPath = filepath.Join(fixturesDir, "invalid.pem") } From b83028325c166a28eea8c87eeb2d11fcaab1342d Mon Sep 17 00:00:00 2001 From: Maria Ntalla Date: Wed, 6 Jun 2018 14:26:46 +0100 Subject: [PATCH 09/19] Introduce thumbprints per vcenter --- .../providers/vsphere/vclib/connection.go | 1 + .../providers/vsphere/vsphere.go | 7 +++ .../providers/vsphere/vsphere_test.go | 56 ++++++++++++++++++- 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/pkg/cloudprovider/providers/vsphere/vclib/connection.go b/pkg/cloudprovider/providers/vsphere/vclib/connection.go index d8166377ffc..e56aaa41b16 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/connection.go +++ b/pkg/cloudprovider/providers/vsphere/vclib/connection.go @@ -43,6 +43,7 @@ type VSphereConnection struct { Hostname string Port string CACert string + Thumbprint string Insecure bool RoundTripperCount uint credentialsLock sync.Mutex diff --git a/pkg/cloudprovider/providers/vsphere/vsphere.go b/pkg/cloudprovider/providers/vsphere/vsphere.go index af1408a4eed..a8490555ba8 100644 --- a/pkg/cloudprovider/providers/vsphere/vsphere.go +++ b/pkg/cloudprovider/providers/vsphere/vsphere.go @@ -103,6 +103,8 @@ type VirtualCenterConfig struct { Datacenters string `gcfg:"datacenters"` // Soap round tripper count (retries = RoundTripper - 1) RoundTripperCount uint `gcfg:"soap-roundtrip-count"` + // Thumbprint of the VCenter's certificate thumbprint + Thumbprint string `gcfg:"thumbprint"` } // Structure that represents the content of vsphere.conf file. @@ -124,6 +126,8 @@ type VSphereConfig struct { // Specifies the path to a CA certificate in PEM format. Optional; if not // configured, the system's CA certificates will be used. CAFile string `gcfg:"ca-file"` + // Thumbprint of the VCenter's certificate thumbprint + Thumbprint string `gcfg:"thumbprint"` // Datacenter in which VMs are located. // Deprecated. Use "datacenters" instead. Datacenter string `gcfg:"datacenter"` @@ -337,6 +341,7 @@ func populateVsphereInstanceMap(cfg *VSphereConfig) (map[string]*VSphereInstance VCenterPort: cfg.Global.VCenterPort, Datacenters: cfg.Global.Datacenter, RoundTripperCount: cfg.Global.RoundTripperCount, + Thumbprint: cfg.Global.Thumbprint, } // Note: If secrets info is provided username and password will be populated @@ -349,6 +354,7 @@ func populateVsphereInstanceMap(cfg *VSphereConfig) (map[string]*VSphereInstance RoundTripperCount: vcConfig.RoundTripperCount, Port: vcConfig.VCenterPort, CACert: cfg.Global.CAFile, + Thumbprint: cfg.Global.Thumbprint, } vsphereIns := VSphereInstance{ @@ -422,6 +428,7 @@ func populateVsphereInstanceMap(cfg *VSphereConfig) (map[string]*VSphereInstance Insecure: cfg.Global.InsecureFlag, RoundTripperCount: vcConfig.RoundTripperCount, Port: vcConfig.VCenterPort, + Thumbprint: vcConfig.Thumbprint, } vsphereIns := VSphereInstance{ conn: &vSphereConn, diff --git a/pkg/cloudprovider/providers/vsphere/vsphere_test.go b/pkg/cloudprovider/providers/vsphere/vsphere_test.go index e2b391fddd4..85d48caea00 100644 --- a/pkg/cloudprovider/providers/vsphere/vsphere_test.go +++ b/pkg/cloudprovider/providers/vsphere/vsphere_test.go @@ -430,6 +430,7 @@ func TestSecretVSphereConfig(t *testing.T) { expectedUsername string expectedPassword string expectedError error + expectedThumbprints map[string]string }{ { testName: "Username and password with old configuration", @@ -599,6 +600,47 @@ func TestSecretVSphereConfig(t *testing.T) { expectedIsSecretProvided: true, expectedError: nil, }, + { + testName: "virtual centers with a thumbprint", + conf: `[Global] + server = global + user = user + password = password + datacenter = us-west + thumbprint = "thumbprint:global" + working-dir = kubernetes + `, + expectedUsername: username, + expectedPassword: password, + expectedError: nil, + expectedThumbprints: map[string]string{ + "global": "thumbprint:global", + }, + }, + { + testName: "Multiple virtual centers with different thumbprints", + conf: `[Global] + user = user + password = password + datacenter = us-west + [VirtualCenter "0.0.0.0"] + thumbprint = thumbprint:0 + [VirtualCenter "no_thumbprint"] + [VirtualCenter "1.1.1.1"] + thumbprint = thumbprint:1 + [Workspace] + server = 0.0.0.0 + datacenter = us-west + folder = kubernetes + `, + expectedUsername: username, + expectedPassword: password, + expectedError: nil, + expectedThumbprints: map[string]string{ + "0.0.0.0": "thumbprint:0", + "1.1.1.1": "thumbprint:1", + }, + }, } for _, testcase := range testcases { @@ -628,9 +670,19 @@ func TestSecretVSphereConfig(t *testing.T) { t.Fatalf("Expected password %s doesn't match actual password %s in config %s. error: %s", testcase.expectedPassword, vsInstance.conn.Password, testcase.conf, err) } - } } - + for instanceName, expectedThumbprint := range testcase.expectedThumbprints { + instanceConfig, ok := vs.vsphereInstanceMap[instanceName] + if !ok { + t.Fatalf("Could not find configuration for instance %s", instanceName) + } + if actualThumbprint := instanceConfig.conn.Thumbprint; actualThumbprint != expectedThumbprint { + t.Fatalf( + "Expected thumbprint for instance '%s' to be '%s', got '%s'", + instanceName, expectedThumbprint, actualThumbprint, + ) + } + } } } From 7ade8261f65a06484a96172e04ce29834dab9d23 Mon Sep 17 00:00:00 2001 From: Maria Ntalla Date: Wed, 6 Jun 2018 15:29:39 +0100 Subject: [PATCH 10/19] Pass through CA cert file to the connection when multiple vcenters are configured --- .../providers/vsphere/vsphere.go | 1 + .../providers/vsphere/vsphere_test.go | 34 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/pkg/cloudprovider/providers/vsphere/vsphere.go b/pkg/cloudprovider/providers/vsphere/vsphere.go index a8490555ba8..742fb3a1f09 100644 --- a/pkg/cloudprovider/providers/vsphere/vsphere.go +++ b/pkg/cloudprovider/providers/vsphere/vsphere.go @@ -428,6 +428,7 @@ func populateVsphereInstanceMap(cfg *VSphereConfig) (map[string]*VSphereInstance Insecure: cfg.Global.InsecureFlag, RoundTripperCount: vcConfig.RoundTripperCount, Port: vcConfig.VCenterPort, + CACert: cfg.Global.CAFile, Thumbprint: vcConfig.Thumbprint, } vsphereIns := VSphereInstance{ diff --git a/pkg/cloudprovider/providers/vsphere/vsphere_test.go b/pkg/cloudprovider/providers/vsphere/vsphere_test.go index 85d48caea00..87ae5af823f 100644 --- a/pkg/cloudprovider/providers/vsphere/vsphere_test.go +++ b/pkg/cloudprovider/providers/vsphere/vsphere_test.go @@ -641,6 +641,28 @@ func TestSecretVSphereConfig(t *testing.T) { "1.1.1.1": "thumbprint:1", }, }, + { + testName: "Multiple virtual centers use the global CA cert", + conf: `[Global] + user = user + password = password + datacenter = us-west + ca-file = /some/path/to/my/trusted/ca.pem + [VirtualCenter "0.0.0.0"] + user = user + password = password + [VirtualCenter "1.1.1.1"] + user = user + password = password + [Workspace] + server = 0.0.0.0 + datacenter = us-west + folder = kubernetes + `, + expectedUsername: username, + expectedPassword: password, + expectedError: nil, + }, } for _, testcase := range testcases { @@ -672,6 +694,7 @@ func TestSecretVSphereConfig(t *testing.T) { } } } + // Check, if all the expected thumbprints are configured for instanceName, expectedThumbprint := range testcase.expectedThumbprints { instanceConfig, ok := vs.vsphereInstanceMap[instanceName] if !ok { @@ -684,5 +707,16 @@ func TestSecretVSphereConfig(t *testing.T) { ) } } + // Check, if all all connections are configured with the global CA certificate + if expectedCaPath := cfg.Global.CAFile; expectedCaPath != "" { + for name, instance := range vs.vsphereInstanceMap { + if actualCaPath := instance.conn.CACert; actualCaPath != expectedCaPath { + t.Fatalf( + "Expected CA certificate path for instance '%s' to be the globally configured one ('%s'), got '%s'", + name, expectedCaPath, actualCaPath, + ) + } + } + } } } From 64bc96baf9b711ce8b58f70b7f569c8324382523 Mon Sep 17 00:00:00 2001 From: Maria Ntalla Date: Wed, 6 Jun 2018 16:22:29 +0100 Subject: [PATCH 11/19] Setup test for verifying by checking certificate fingerprints --- .../vsphere/vclib/connection_test.go | 69 +++++++++++++++---- 1 file changed, 55 insertions(+), 14 deletions(-) diff --git a/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go index 1af398990a9..3fc7f52eace 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go +++ b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go @@ -18,8 +18,10 @@ package vclib_test import ( "context" + "crypto/sha1" "crypto/tls" "crypto/x509" + "fmt" "io/ioutil" "net/http" "net/http/httptest" @@ -30,7 +32,7 @@ import ( "k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vclib/fixtures" ) -func createTestServer(t *testing.T, caCertPath, serverCertPath, serverKeyPath string, handler http.HandlerFunc) *httptest.Server { +func createTestServer(t *testing.T, caCertPath, serverCertPath, serverKeyPath string, handler http.HandlerFunc) (*httptest.Server, string) { caCertPEM, err := ioutil.ReadFile(caCertPath) if err != nil { t.Fatalf("Could not read ca cert from file") @@ -54,22 +56,20 @@ func createTestServer(t *testing.T, caCertPath, serverCertPath, serverKeyPath st RootCAs: certPool, } - return server + // calculate the leaf certificate's fingerprint + x509LeafCert := server.TLS.Certificates[0].Certificate[0] + tpBytes := sha1.Sum(x509LeafCert) + tpString := fmt.Sprintf("%x", tpBytes) + + return server, tpString } func TestWithValidCaCert(t *testing.T) { - gotRequest := false - handler := func(w http.ResponseWriter, r *http.Request) { - gotRequest = true - } + handler, verify := getRequestVerifier(t) - server := createTestServer(t, fixtures.CaCertPath, fixtures.ServerCertPath, fixtures.ServerKeyPath, handler) + server, _ := createTestServer(t, fixtures.CaCertPath, fixtures.ServerCertPath, fixtures.ServerKeyPath, handler) server.StartTLS() - - u, err := url.Parse(server.URL) - if err != nil { - t.Fatalf("Cannot parse URL: %v", err) - } + u := mustParseUrl(t, server.URL) connection := &vclib.VSphereConnection{ Hostname: u.Hostname(), @@ -80,9 +80,26 @@ func TestWithValidCaCert(t *testing.T) { // Ignoring error here, because we only care about the TLS connection connection.NewClient(context.Background()) - if !gotRequest { - t.Fatalf("Never saw a request, TLS connection could not be established") + verify() +} + +func TestWithValidThumbprint(t *testing.T) { + handler, verify := getRequestVerifier(t) + + server, serverThumbprint := createTestServer(t, fixtures.CaCertPath, fixtures.ServerCertPath, fixtures.ServerKeyPath, handler) + server.StartTLS() + u := mustParseUrl(t, server.URL) + + connection := &vclib.VSphereConnection{ + Hostname: u.Hostname(), + Port: u.Port(), + Thumbprint: serverThumbprint, } + + // Ignoring error here, because we only care about the TLS connection + connection.NewClient(context.Background()) + + verify() } func TestWithInvalidCaCertPath(t *testing.T) { @@ -133,3 +150,27 @@ type fakeTransport struct{} func (ft fakeTransport) RoundTrip(*http.Request) (*http.Response, error) { return nil, nil } + +func getRequestVerifier(t *testing.T) (http.HandlerFunc, func()) { + gotRequest := false + + handler := func(w http.ResponseWriter, r *http.Request) { + gotRequest = true + } + + checker := func() { + if !gotRequest { + t.Fatalf("Never saw a request, maybe TLS connection could not be established?") + } + } + + return handler, checker +} + +func mustParseUrl(t *testing.T, i string) *url.URL { + u, err := url.Parse(i) + if err != nil { + t.Fatalf("Cannot parse URL: %v", err) + } + return u +} From 9deaba0aa0f12ea40b5bb0823ca95254bdb502fe Mon Sep 17 00:00:00 2001 From: Maria Ntalla Date: Thu, 7 Jun 2018 16:14:47 +0100 Subject: [PATCH 12/19] Use soap clients method to load root CAs --- .../providers/vsphere/vclib/connection.go | 35 +------- .../vsphere/vclib/connection_test.go | 83 +++++++------------ 2 files changed, 35 insertions(+), 83 deletions(-) diff --git a/pkg/cloudprovider/providers/vsphere/vclib/connection.go b/pkg/cloudprovider/providers/vsphere/vclib/connection.go index e56aaa41b16..fd82370e4ba 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/connection.go +++ b/pkg/cloudprovider/providers/vsphere/vclib/connection.go @@ -19,12 +19,9 @@ package vclib import ( "context" "crypto/tls" - "crypto/x509" "encoding/pem" "errors" - "io/ioutil" "net" - "net/http" neturl "net/url" "sync" @@ -152,34 +149,10 @@ func (connection *VSphereConnection) Logout(ctx context.Context) { } var ( - ErrCaCertNotReadable = errors.New("Could not read CA cert file") - ErrCaCertInvalid = errors.New("Could not parse CA cert file") - ErrUnsupportedTransport = errors.New("Only support HTTP transport if configuring TLS") + ErrCaCertNotReadable = errors.New("Could not read CA cert file") + ErrCaCertInvalid = errors.New("Could not parse CA cert file") ) -func (connection *VSphereConnection) ConfigureTransportWithCA(transport http.RoundTripper) error { - caCertBytes, err := ioutil.ReadFile(connection.CACert) - if err != nil { - glog.Errorf("Could not read CA cert file, %s", connection.CACert) - return ErrCaCertNotReadable - } - certPool := x509.NewCertPool() - - if ok := certPool.AppendCertsFromPEM(caCertBytes); !ok { - glog.Errorf("Cannot add CA to cert pool") - return ErrCaCertInvalid - } - httpTransport, ok := transport.(*http.Transport) - if !ok { - glog.Errorf("Failed to http transport") - return ErrUnsupportedTransport - } - - httpTransport.TLSClientConfig.RootCAs = certPool - - return nil -} - // NewClient creates a new govmomi client for the VSphereConnection obj func (connection *VSphereConnection) NewClient(ctx context.Context) (*vim25.Client, error) { url, err := soap.ParseURL(net.JoinHostPort(connection.Hostname, connection.Port)) @@ -190,8 +163,8 @@ func (connection *VSphereConnection) NewClient(ctx context.Context) (*vim25.Clie sc := soap.NewClient(url, connection.Insecure) - if connection.CACert != "" { - if err := connection.ConfigureTransportWithCA(sc.Client.Transport); err != nil { + if ca := connection.CACert; ca != "" { + if err := sc.SetRootCAs(ca); err != nil { return nil, err } } diff --git a/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go index 3fc7f52eace..9dc31e235ca 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go +++ b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go @@ -18,21 +18,20 @@ package vclib_test import ( "context" - "crypto/sha1" "crypto/tls" "crypto/x509" - "fmt" "io/ioutil" "net/http" "net/http/httptest" "net/url" + "os" "testing" "k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vclib" "k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vclib/fixtures" ) -func createTestServer(t *testing.T, caCertPath, serverCertPath, serverKeyPath string, handler http.HandlerFunc) (*httptest.Server, string) { +func createTestServer(t *testing.T, caCertPath, serverCertPath, serverKeyPath string, handler http.HandlerFunc) *httptest.Server { caCertPEM, err := ioutil.ReadFile(caCertPath) if err != nil { t.Fatalf("Could not read ca cert from file") @@ -56,18 +55,18 @@ func createTestServer(t *testing.T, caCertPath, serverCertPath, serverKeyPath st RootCAs: certPool, } - // calculate the leaf certificate's fingerprint - x509LeafCert := server.TLS.Certificates[0].Certificate[0] - tpBytes := sha1.Sum(x509LeafCert) - tpString := fmt.Sprintf("%x", tpBytes) + // // calculate the leaf certificate's fingerprint + // x509LeafCert := server.TLS.Certificates[0].Certificate[0] + // tpBytes := sha1.Sum(x509LeafCert) + // tpString := fmt.Sprintf("%x", tpBytes) - return server, tpString + return server } func TestWithValidCaCert(t *testing.T) { handler, verify := getRequestVerifier(t) - server, _ := createTestServer(t, fixtures.CaCertPath, fixtures.ServerCertPath, fixtures.ServerKeyPath, handler) + server := createTestServer(t, fixtures.CaCertPath, fixtures.ServerCertPath, fixtures.ServerKeyPath, handler) server.StartTLS() u := mustParseUrl(t, server.URL) @@ -83,24 +82,24 @@ func TestWithValidCaCert(t *testing.T) { verify() } -func TestWithValidThumbprint(t *testing.T) { - handler, verify := getRequestVerifier(t) - - server, serverThumbprint := createTestServer(t, fixtures.CaCertPath, fixtures.ServerCertPath, fixtures.ServerKeyPath, handler) - server.StartTLS() - u := mustParseUrl(t, server.URL) - - connection := &vclib.VSphereConnection{ - Hostname: u.Hostname(), - Port: u.Port(), - Thumbprint: serverThumbprint, - } - - // Ignoring error here, because we only care about the TLS connection - connection.NewClient(context.Background()) - - verify() -} +// func TestWithValidThumbprint(t *testing.T) { +// handler, verify := getRequestVerifier(t) +// +// server, serverThumbprint := createTestServer(t, fixtures.CaCertPath, fixtures.ServerCertPath, fixtures.ServerKeyPath, handler) +// server.StartTLS() +// u := mustParseUrl(t, server.URL) +// +// connection := &vclib.VSphereConnection{ +// Hostname: u.Hostname(), +// Port: u.Port(), +// Thumbprint: serverThumbprint, +// } +// +// // Ignoring error here, because we only care about the TLS connection +// connection.NewClient(context.Background()) +// +// verify() +// } func TestWithInvalidCaCertPath(t *testing.T) { connection := &vclib.VSphereConnection{ @@ -110,13 +109,14 @@ func TestWithInvalidCaCertPath(t *testing.T) { } _, err := connection.NewClient(context.Background()) - - if err != vclib.ErrCaCertNotReadable { - t.Fatalf("should have occurred") + if _, ok := err.(*os.PathError); !ok { + t.Fatalf("Expected an os.PathError, got: '%s' (%#v)", err.Error(), err) } } func TestInvalidCaCert(t *testing.T) { + t.Skip("Waiting for https://github.com/vmware/govmomi/pull/1154") + connection := &vclib.VSphereConnection{ Hostname: "should-not-matter", Port: "should-not-matter", @@ -126,31 +126,10 @@ func TestInvalidCaCert(t *testing.T) { _, err := connection.NewClient(context.Background()) if err != vclib.ErrCaCertInvalid { - t.Fatalf("should have occurred") + t.Fatalf("ErrCaCertInvalid should have occurred, instead got: %v", err) } } -func TestUnsupportedTransport(t *testing.T) { - notHttpTransport := new(fakeTransport) - - connection := &vclib.VSphereConnection{ - Hostname: "should-not-matter", - Port: "should-not-matter", - CACert: fixtures.CaCertPath, - } - - err := connection.ConfigureTransportWithCA(notHttpTransport) - if err != vclib.ErrUnsupportedTransport { - t.Fatalf("should have occurred") - } -} - -type fakeTransport struct{} - -func (ft fakeTransport) RoundTrip(*http.Request) (*http.Response, error) { - return nil, nil -} - func getRequestVerifier(t *testing.T) (http.HandlerFunc, func()) { gotRequest := false From ed4d44535204955188decebeed88c6c54272c94c Mon Sep 17 00:00:00 2001 From: Maria Ntalla Date: Fri, 8 Jun 2018 11:57:15 +0100 Subject: [PATCH 13/19] Check certificate thumbprint when configured --- .../providers/vsphere/vclib/connection.go | 31 ++++ .../vsphere/vclib/connection_test.go | 138 ++++++++++++++---- 2 files changed, 142 insertions(+), 27 deletions(-) diff --git a/pkg/cloudprovider/providers/vsphere/vclib/connection.go b/pkg/cloudprovider/providers/vsphere/vclib/connection.go index fd82370e4ba..8d2e7b27d08 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/connection.go +++ b/pkg/cloudprovider/providers/vsphere/vclib/connection.go @@ -17,6 +17,7 @@ limitations under the License. package vclib import ( + "bytes" "context" "crypto/tls" "encoding/pem" @@ -24,6 +25,7 @@ import ( "net" neturl "net/url" "sync" + "unicode" "github.com/golang/glog" "github.com/vmware/govmomi/session" @@ -169,6 +171,13 @@ func (connection *VSphereConnection) NewClient(ctx context.Context) (*vim25.Clie } } + tpHost := connection.Hostname + ":" + connection.Port + tp, err := normalizeThumbprint(connection.Thumbprint) + if err != nil { + return nil, err + } + sc.SetThumbprint(tpHost, tp) + client, err := vim25.NewClient(ctx, sc) if err != nil { glog.Errorf("Failed to create new client. err: %+v", err) @@ -201,3 +210,25 @@ func (connection *VSphereConnection) UpdateCredentials(username string, password connection.Username = username connection.Password = password } + +func normalizeThumbprint(original string) (string, error) { + buffer := &bytes.Buffer{} + outIdx := 0 + + for _, r := range original { + if outIdx%2 == 0 && outIdx > 0 { + if _, err := buffer.WriteRune(':'); err != nil { + return "", err + } + } + if r == ':' { + continue + } + if _, err := buffer.WriteRune(unicode.ToUpper(r)); err != nil { + return "", err + } + outIdx++ + } + + return buffer.String(), nil +} diff --git a/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go index 9dc31e235ca..dcf9f9adaa1 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go +++ b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go @@ -18,20 +18,29 @@ package vclib_test import ( "context" + "crypto/sha1" "crypto/tls" "crypto/x509" + "fmt" "io/ioutil" "net/http" "net/http/httptest" "net/url" "os" + "strings" "testing" "k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vclib" "k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vclib/fixtures" ) -func createTestServer(t *testing.T, caCertPath, serverCertPath, serverKeyPath string, handler http.HandlerFunc) *httptest.Server { +func createTestServer( + t *testing.T, + caCertPath string, + serverCertPath string, + serverKeyPath string, + handler http.HandlerFunc, +) (*httptest.Server, string) { caCertPEM, err := ioutil.ReadFile(caCertPath) if err != nil { t.Fatalf("Could not read ca cert from file") @@ -55,18 +64,18 @@ func createTestServer(t *testing.T, caCertPath, serverCertPath, serverKeyPath st RootCAs: certPool, } - // // calculate the leaf certificate's fingerprint - // x509LeafCert := server.TLS.Certificates[0].Certificate[0] - // tpBytes := sha1.Sum(x509LeafCert) - // tpString := fmt.Sprintf("%x", tpBytes) + // calculate the leaf certificate's fingerprint + x509LeafCert := server.TLS.Certificates[0].Certificate[0] + tpBytes := sha1.Sum(x509LeafCert) + tpString := fmt.Sprintf("%x", tpBytes) - return server + return server, tpString } func TestWithValidCaCert(t *testing.T) { - handler, verify := getRequestVerifier(t) + handler, verifyConnectionWasMade := getRequestVerifier(t) - server := createTestServer(t, fixtures.CaCertPath, fixtures.ServerCertPath, fixtures.ServerKeyPath, handler) + server, _ := createTestServer(t, fixtures.CaCertPath, fixtures.ServerCertPath, fixtures.ServerKeyPath, handler) server.StartTLS() u := mustParseUrl(t, server.URL) @@ -79,27 +88,88 @@ func TestWithValidCaCert(t *testing.T) { // Ignoring error here, because we only care about the TLS connection connection.NewClient(context.Background()) - verify() + verifyConnectionWasMade() } -// func TestWithValidThumbprint(t *testing.T) { -// handler, verify := getRequestVerifier(t) -// -// server, serverThumbprint := createTestServer(t, fixtures.CaCertPath, fixtures.ServerCertPath, fixtures.ServerKeyPath, handler) -// server.StartTLS() -// u := mustParseUrl(t, server.URL) -// -// connection := &vclib.VSphereConnection{ -// Hostname: u.Hostname(), -// Port: u.Port(), -// Thumbprint: serverThumbprint, -// } -// -// // Ignoring error here, because we only care about the TLS connection -// connection.NewClient(context.Background()) -// -// verify() -// } +func TestWithVerificationWithWrongThumbprint(t *testing.T) { + handler, _ := getRequestVerifier(t) + + server, _ := createTestServer(t, fixtures.CaCertPath, fixtures.ServerCertPath, fixtures.ServerKeyPath, handler) + server.StartTLS() + u := mustParseUrl(t, server.URL) + + connection := &vclib.VSphereConnection{ + Hostname: u.Hostname(), + Port: u.Port(), + Thumbprint: "obviously wrong", + } + + _, err := connection.NewClient(context.Background()) + + if msg := err.Error(); !strings.Contains(msg, "thumbprint does not match") { + t.Fatalf("Expected wrong thumbprint error, got '%s'", msg) + } +} + +func TestWithVerificationWithoutCaCertOrThumbprint(t *testing.T) { + handler, _ := getRequestVerifier(t) + + server, _ := createTestServer(t, fixtures.CaCertPath, fixtures.ServerCertPath, fixtures.ServerKeyPath, handler) + server.StartTLS() + u := mustParseUrl(t, server.URL) + + connection := &vclib.VSphereConnection{ + Hostname: u.Hostname(), + Port: u.Port(), + } + + _, err := connection.NewClient(context.Background()) + + verifyWrappedX509UnkownAuthorityErr(t, err) +} + +func TestWithValidThumbprint(t *testing.T) { + handler, verifyConnectionWasMade := getRequestVerifier(t) + + server, thumbprint := + createTestServer(t, fixtures.CaCertPath, fixtures.ServerCertPath, fixtures.ServerKeyPath, handler) + server.StartTLS() + u := mustParseUrl(t, server.URL) + + connection := &vclib.VSphereConnection{ + Hostname: u.Hostname(), + Port: u.Port(), + Thumbprint: thumbprint, + } + + // Ignoring error here, because we only care about the TLS connection + connection.NewClient(context.Background()) + + verifyConnectionWasMade() +} + +func TestWithValidThumbprintAlternativeFormat(t *testing.T) { + handler, verifyConnectionWasMade := getRequestVerifier(t) + + server, thumbprint := + createTestServer(t, fixtures.CaCertPath, fixtures.ServerCertPath, fixtures.ServerKeyPath, handler) + server.StartTLS() + u := mustParseUrl(t, server.URL) + + // lowercase, remove the ':' + tpDifferentFormat := strings.Replace(strings.ToLower(thumbprint), ":", "", -1) + + connection := &vclib.VSphereConnection{ + Hostname: u.Hostname(), + Port: u.Port(), + Thumbprint: tpDifferentFormat, + } + + // Ignoring error here, because we only care about the TLS connection + connection.NewClient(context.Background()) + + verifyConnectionWasMade() +} func TestWithInvalidCaCertPath(t *testing.T) { connection := &vclib.VSphereConnection{ @@ -130,6 +200,20 @@ func TestInvalidCaCert(t *testing.T) { } } +func verifyWrappedX509UnkownAuthorityErr(t *testing.T, err error) { + urlErr, ok := err.(*url.Error) + if !ok { + t.Fatalf("Expected to receive an url.Error, got '%s' (%#v)", err.Error(), err) + } + x509Err, ok := urlErr.Err.(x509.UnknownAuthorityError) + if !ok { + t.Fatalf("Expected to receive a wrapped x509.UnknownAuthorityError, got: '%s' (%#v)", urlErr.Error(), urlErr) + } + if msg := x509Err.Error(); msg != "x509: certificate signed by unknown authority" { + t.Fatalf("Expected 'signed by unknown authority' error, got: '%s'", msg) + } +} + func getRequestVerifier(t *testing.T) (http.HandlerFunc, func()) { gotRequest := false From bec497765af84fd132ee733e10419e0370add75f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20H=C3=B6rl?= Date: Fri, 8 Jun 2018 14:42:54 +0100 Subject: [PATCH 14/19] Create new certs & cleanup cert generation The test certificates are now valid for 200 years. The generation script has been cleaned up a bit. --- .../providers/vsphere/vclib/fixtures/ca.key | 98 +++++++++---------- .../providers/vsphere/vclib/fixtures/ca.pem | 52 +++++----- .../vsphere/vclib/fixtures/createCerts.sh | 49 +++++++--- .../vsphere/vclib/fixtures/server.csr | 48 ++++----- .../vsphere/vclib/fixtures/server.key | 98 +++++++++---------- .../vsphere/vclib/fixtures/server.pem | 54 +++++----- 6 files changed, 211 insertions(+), 188 deletions(-) diff --git a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/ca.key b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/ca.key index 7c9848e9ff3..84b4d3266df 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/ca.key +++ b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/ca.key @@ -1,51 +1,51 @@ -----BEGIN RSA PRIVATE KEY----- -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 -----END RSA PRIVATE KEY----- diff --git a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/ca.pem b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/ca.pem index 4359bb5045e..9e03ae78762 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/ca.pem +++ b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/ca.pem @@ -1,29 +1,29 @@ -----BEGIN CERTIFICATE----- -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 -----END CERTIFICATE----- diff --git a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/createCerts.sh b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/createCerts.sh index dd22d458d61..913c7f9e400 100755 --- a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/createCerts.sh +++ b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/createCerts.sh @@ -16,43 +16,66 @@ set -eu +readonly VALID_DAYS='73000' +readonly RSA_KEY_SIZE='4096' + createKey() { - openssl genrsa -out "$1" 4096 + openssl genrsa \ + -out "$1" \ + "$RSA_KEY_SIZE" } createCaCert() { - openssl req -x509 \ - -subj "/C=US/ST=CA/O=Acme, Inc./CN=someCA" \ - -new -nodes -key "$2" -sha256 -days 10240 -out "$1" + openssl req \ + -x509 \ + -subj "$( getSubj 'someCA' )" \ + -new \ + -nodes \ + -key "$2" \ + -sha256 \ + -days "$VALID_DAYS" \ + -out "$1" } createCSR() { - openssl req -new -sha256 \ + openssl req \ + -new \ + -sha256 \ -key "$2" \ - -subj "/C=US/ST=CA/O=Acme, Inc./CN=localhost" \ + -subj "$( getSubj 'localhost' )" \ -reqexts SAN \ - -config <( - cat /etc/ssl/openssl.cnf ; \ - printf '\n[SAN]\n' ; \ - getSAN - ) \ + -config <( getSANConfig ) \ -out "$1" } signCSR() { - openssl x509 -req -in "$2" \ + openssl x509 \ + -req \ + -in "$2" \ -CA "$3" \ -CAkey "$4" \ -CAcreateserial \ - -days 3650 -sha256 \ + -days "$VALID_DAYS" \ + -sha256 \ -extfile <( getSAN ) \ -out "$1" } +getSubj() { + local cn="${1:-someRandomCN}" + echo "/C=US/ST=CA/O=Acme, Inc./CN=${cn}" +} + getSAN() { printf "subjectAltName=DNS:localhost,IP:127.0.0.1" } +getSANConfig() { + cat /etc/ssl/openssl.cnf + printf '\n[SAN]\n' + getSAN +} + main() { local caCertPath="./ca.pem" local caKeyPath="./ca.key" diff --git a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/server.csr b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/server.csr index c6998bb632f..fb91630515b 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/server.csr +++ b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/server.csr @@ -1,28 +1,28 @@ -----BEGIN CERTIFICATE REQUEST----- MIIEtTCCAp0CAQAwQzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRMwEQYDVQQK DApBY21lLCBJbmMuMRIwEAYDVQQDDAlsb2NhbGhvc3QwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQDRtnbdQFkM8IgTx2KU2lyZitrgqhcxRVGaMrw+d+Q0 -3IZ9y8L4sVFjBqAXUIkCndfQSVyzAnSgrvJqpFk43TIbg7TY/ZpLdN+tHn+PT3qN -MYjOIMR+BVpT8Fi23Ds5ghVw26Av4ZfT6a3R2e4ndsdvwM7nf+8YwU2qPwu48cDN -OLCGoV9JUZADoHHVQOC9LZfUWtSxU0zhnnEWyu33OInzBtwTSdrxQui287svcJBT -XkMlRzj5adAZBJ8zhxsNxs6lPQX/C7V3yjTEdSvnYAtoGbFPqh5D4aHw7Vjrax7Z -ihUCpIJ+Nf01UzzxqkXhlf08qcMxA8MIRDujwsY2DKu1TpZqn+fDP0nfWUe/PJ7d -7hUHkdvH09D8csP72Ryu+Nmgbx1gPgv+srGHCwVCFa1Hg+oq6u2Uq2eW6Vt3LcRc -8S1zG6CjvFthU7Eurh6a2dsDvWDSst3JNnkOFeSLjOqa5tDSNh5SZIbZ17BiiiD6 -MIqRDBiK4jGh20E0m1cVk1e1QRpD33ViLDGqD628bCcOtD86eUhrv1k+fqPr1gF0 -fdbQXJoYonPvfHlEzQPXprPNdv8JSQ/aKQqWO7yC8H/V+bpbRwL+vDMkQ3YMC3zf -bj7z8bJvQ7DOf0Ogy0wyP5FG1Jm47FE66ckKTZdLCf8VrxO8cnrXFGZ0CQIEu4Rn -PQIDAQABoC0wKwYJKoZIhvcNAQkOMR4wHDAaBgNVHREEEzARgglsb2NhbGhvc3SH -BH8AAAEwDQYJKoZIhvcNAQELBQADggIBADh1KvKchPJTEDX9oonipCyvHLzysJpI -Li1ZWDSu0v4ASlYMJrAxQNphHYDu/FZdqvDvqQ0M8naM9sNdq0UkgiAdOtjtDB9J -k18/sOOjXCqAWIcFr9vdwbs0bKD1x2sBBVN2O3G+YX7w8YwWX1VQdBoObmJiSAmw -V6l1yltaiw6fb1RpO71JFjL19QvRuSs7pVhDjuI1gu/bggebxh6AIpAHXq3lukMS -a3mOyeiik5PlsDwxMMJNCKzqf+DYLzslMKq3IaVDyyqPxaZeVCb80525W4W+2/eV -kmcMpqUJaG+iqYfuaX1S+7jZRri0lhkejE8HJ1xT8JWaovZ7G2WzWDEqUPVvVoX4 -g2MgLVtcb6WcstQpsQ+AY0rKPq8K4T5t420JtRLI9oUt5eQm7yWGFF1p4URWzuYq -/TOTPxIrufeFfqBsH8XAOydmuwUGunpefoxvD0tp9SFpRm6NWliYyunFZP82xtOK -eP3aW3A1KnPdLgAyi9/iwi9VzGQTu1iWAc9si9xTyqTNOtvgYUzy2wmic2HgWfEs -NEv+wW6CNh1qR1Vq7j0zkl327CFrGBvKbR1d5cleNx8EiWZ1QNmickMaCHBiwkql -yIbSPtlmzme8y8N73bUaV74DbKExZvu2CnUzdIHOt0Dpax6TkBHc1HI530v58eN/ -VDP7+tBBVo+c +AQUAA4ICDwAwggIKAoICAQCVkk5HMKNvMXVJoJcUfKK252UT6rdnlsaFLZOlcbp3 +otqiq3A2jhQLeL5Ocyd22s/ak2RX9liK+ynV8fP3YWoUBP5elhwbykubiIvSTRS5 +85Z0s9NfzscImMpnivt+bOy3KOoriy/0jfJ7WMqLRUTUEusXUpW8QT/U9cK6DrwQ +E/9oXTr669yvqjyFsxjOB0pLOFFib0LeQZxrA2h+oAP8qT/Of6kyTgGWjLhSC1cV +eCPZsSeZUT61FbIu/b5M42WYuddoFbf8y9m0oLeYizYob7poE25jw91bNa8y2nfS +v+JuCcfO4wq29cnldGFNpJPhBhc1sbBvVshXXKWdfzN1c8RCS5hNANy1phAJ7RFe +3Uj0WneBVBHHJMz7Qh61uxTST1W8HBDTuaBTxGKTcPFWd9u4lj/BEScRFOSC/qiO +1HCKzOsYhjnHfql5GzfQKpEy/e4m2oL8VTqcJBsfHCyxDIH+6Y3ovttymxAUPJ14 +r3mG9FDLq1va/+8xzDswyjmRIVQeOgvllzgM5vCKqz6nsXtLRYgkwHMk5yOaAIzO +BnsmZztsyaubjcYvM5pUsiO49VWk6ntiAn+WpF/sreFlesx1peQKbTVovwvn137d +V92Oncce+ZikKHxtz4qOz+dH1Fz7Ykor8fXcsfdbkKvwWdz8U/pOBu+83CxBXTWA +bwIDAQABoC0wKwYJKoZIhvcNAQkOMR4wHDAaBgNVHREEEzARgglsb2NhbGhvc3SH +BH8AAAEwDQYJKoZIhvcNAQELBQADggIBADgJfI3xRKlOInZQjg+afz+L477IiFmP +Pf0qwO/EqBkCmbDbmvXpXi/y9Ffh6bMx2naN873nW3k1uVG2W0O4Bl7di9PkmRxY +ktcWY+CaxDT5+Y3LmrqICgrZmELTuV5G8xX2/7bpdEtY4sWpoOeOun+CeGTCeUGx +sGxOWrhydYwrkowupPthYreIIBBPHWl2gEw/m+Y7aJZGtKnDD9eCbF6RxmXRWHDu +0Ly+F3veXbht9LjKPFsgfsogo33Nl8+W1LCActKNY7NMDdGkc+RqaTyxhYEwomui +N1NDOW1qHqSyp2RC13cXokfLL58WGXS6PpNhSln9u4ZG9a+TY+vw1qC//1CyTicY +ylyEn2qfqTSG3W7T/u6ZTL0MpMjFv8VigpffJcFDjq6lVH8LyTniSXdCREy78jAo +8O/2tzJtWrar8bbeN7KCwVcJVaK15a1GWZmo5Ei33U/2Tm+UyRbWL8eISO2Hs3WM +90aFPaHfqKpiPsJrnnOm270lZclgqEtpsyuLsAClqxytCYPw4zTa6WOfDJtmVUrT +1fvMjqwzvs7jbNrgfkwSxXiABwTMQQWeAtuSO+zZH4Ms10qyANoh4FFi/oS3dRKQ +0kdu7AsJqnou9q9HWq1WCTqMcyNE0KPHuo4xhtOlWoGbsugTs7XBml30D7bKJVfG +PazsY1b0/cx7 -----END CERTIFICATE REQUEST----- diff --git a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/server.key b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/server.key index b08afaaee01..643d5463874 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/server.key +++ b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/server.key @@ -1,51 +1,51 @@ -----BEGIN RSA PRIVATE KEY----- -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 -----END RSA PRIVATE KEY----- diff --git a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/server.pem b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/server.pem index a43b6366e13..dbebde6a803 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/server.pem +++ b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/server.pem @@ -1,30 +1,30 @@ -----BEGIN CERTIFICATE----- -MIIFJDCCAwygAwIBAgIJAOcEAbv8NslcMA0GCSqGSIb3DQEBCwUAMEAxCzAJBgNV +MIIFJjCCAw6gAwIBAgIJAOcEAbv8NslfMA0GCSqGSIb3DQEBCwUAMEAxCzAJBgNV BAYTAlVTMQswCQYDVQQIDAJDQTETMBEGA1UECgwKQWNtZSwgSW5jLjEPMA0GA1UE -AwwGc29tZUNBMB4XDTE4MDYwNDE0NTgwNloXDTI4MDYwMTE0NTgwNlowQzELMAkG -A1UEBhMCVVMxCzAJBgNVBAgMAkNBMRMwEQYDVQQKDApBY21lLCBJbmMuMRIwEAYD -VQQDDAlsb2NhbGhvc3QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDR -tnbdQFkM8IgTx2KU2lyZitrgqhcxRVGaMrw+d+Q03IZ9y8L4sVFjBqAXUIkCndfQ -SVyzAnSgrvJqpFk43TIbg7TY/ZpLdN+tHn+PT3qNMYjOIMR+BVpT8Fi23Ds5ghVw -26Av4ZfT6a3R2e4ndsdvwM7nf+8YwU2qPwu48cDNOLCGoV9JUZADoHHVQOC9LZfU -WtSxU0zhnnEWyu33OInzBtwTSdrxQui287svcJBTXkMlRzj5adAZBJ8zhxsNxs6l -PQX/C7V3yjTEdSvnYAtoGbFPqh5D4aHw7Vjrax7ZihUCpIJ+Nf01UzzxqkXhlf08 -qcMxA8MIRDujwsY2DKu1TpZqn+fDP0nfWUe/PJ7d7hUHkdvH09D8csP72Ryu+Nmg -bx1gPgv+srGHCwVCFa1Hg+oq6u2Uq2eW6Vt3LcRc8S1zG6CjvFthU7Eurh6a2dsD -vWDSst3JNnkOFeSLjOqa5tDSNh5SZIbZ17BiiiD6MIqRDBiK4jGh20E0m1cVk1e1 -QRpD33ViLDGqD628bCcOtD86eUhrv1k+fqPr1gF0fdbQXJoYonPvfHlEzQPXprPN -dv8JSQ/aKQqWO7yC8H/V+bpbRwL+vDMkQ3YMC3zfbj7z8bJvQ7DOf0Ogy0wyP5FG -1Jm47FE66ckKTZdLCf8VrxO8cnrXFGZ0CQIEu4RnPQIDAQABox4wHDAaBgNVHREE -EzARgglsb2NhbGhvc3SHBH8AAAEwDQYJKoZIhvcNAQELBQADggIBAJkQELAVTJSS -1Rfmn9aRXOd6Uap7+3oE3ZOuUU2XxBJKXClVhKcCJ8nToDHsSV6D7fMcgJvg4fOt -pkQldEi845mUx0t8F/uKqwO1fx+Cjnr8meArGpwn2bma+4cpZyLbFgAZH7Cst+er -FbewtoPbfnADZlZzK35jcSzGf+oYJU11QJjTyRRXBp9eC73Fa9fM53GrA5GkJiSc -u7+mRlAKKEMmNNdnZa48X/cKI7UXp+qHSdkE9zDZ/LrbZPV8OuJY/RpwLT1A59pM -wkvC1AaGIa+ysfLw7s+0K2B1xmquAdopzcwGmK5CGJQmoF3YEFc+QN5fkC4UbizM -XiXZ3Uu0bbg9qNjR99Z0N/knVce+KpAeJg9cEFSsdTM2oaz/53KsalxOWsDkxvuI -HGwjSMPO22JWPs9zs06/1CsiQvn7O/Kx4xjwuSzxjKOJaolynF0lUsNXljOnF6FC -cQCBsY3TFdJFAtjYouiUu5UI4tvQ6pFmCDfj2Ioj+XhF0pd5G/bM3Hmb+WL9We4s -ajoaB85yAy5YdxBuLW5/TdeRqWZHB3AXbAXY8KoOPaOv9NCRWwwaGsiBSUSPdUzT -UkqWjMhcZnmHFeKVDQWpVIy1zrVojR17B8/xY9uypg5yZxGpssUwbfi9m/TnPH/A -a6U8cIpiDSFdeNYPGwKm8O06pY67+w1I +AwwGc29tZUNBMCAXDTE4MDYwODEzMzkyNFoYDzIyMTgwNDIxMTMzOTI0WjBDMQsw +CQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExEzARBgNVBAoMCkFjbWUsIEluYy4xEjAQ +BgNVBAMMCWxvY2FsaG9zdDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +AJWSTkcwo28xdUmglxR8orbnZRPqt2eWxoUtk6Vxunei2qKrcDaOFAt4vk5zJ3ba +z9qTZFf2WIr7KdXx8/dhahQE/l6WHBvKS5uIi9JNFLnzlnSz01/OxwiYymeK+35s +7Lco6iuLL/SN8ntYyotFRNQS6xdSlbxBP9T1wroOvBAT/2hdOvrr3K+qPIWzGM4H +Sks4UWJvQt5BnGsDaH6gA/ypP85/qTJOAZaMuFILVxV4I9mxJ5lRPrUVsi79vkzj +ZZi512gVt/zL2bSgt5iLNihvumgTbmPD3Vs1rzLad9K/4m4Jx87jCrb1yeV0YU2k +k+EGFzWxsG9WyFdcpZ1/M3VzxEJLmE0A3LWmEAntEV7dSPRad4FUEcckzPtCHrW7 +FNJPVbwcENO5oFPEYpNw8VZ327iWP8ERJxEU5IL+qI7UcIrM6xiGOcd+qXkbN9Aq +kTL97ibagvxVOpwkGx8cLLEMgf7pjei+23KbEBQ8nXiveYb0UMurW9r/7zHMOzDK +OZEhVB46C+WXOAzm8IqrPqexe0tFiCTAcyTnI5oAjM4GeyZnO2zJq5uNxi8zmlSy +I7j1VaTqe2ICf5akX+yt4WV6zHWl5AptNWi/C+fXft1X3Y6dxx75mKQofG3Pio7P +50fUXPtiSivx9dyx91uQq/BZ3PxT+k4G77zcLEFdNYBvAgMBAAGjHjAcMBoGA1Ud +EQQTMBGCCWxvY2FsaG9zdIcEfwAAATANBgkqhkiG9w0BAQsFAAOCAgEABL8kffi7 +48qSD+/l/UwCYdmqta1vAbOkvLnPtfXe1XlDpJipNuPxUBc8nNTemtrbg0erNJnC +jQHodqmdKBJJOdaEKTwAGp5pYvvjlU3WasmhfJy+QwOWgeqjJcTUo3+DEaHRls16 +AZXlsp3hB6z0gzR/qzUuZwpMbL477JpuZtAcwLYeVvLG8bQRyWyEy8JgGDoYSn8s +Z16s+r6AX+cnL/2GHkZ+oc3iuXJbnac4xfWTKDiYnyzK6RWRnoyro7X0jiPz6XX3 +wyoWzB1uMSCXscrW6ZcKyKqz75lySLuwGxOMhX4nGOoYHY0ZtrYn5WK2ZAJxsQnn +8QcjPB0nq37U7ifk1uebmuXe99iqyKnWaLvlcpe+HnO5pVxFkSQEf7Zh+hEnRDkN +IBzLFnqwDS1ug/oQ1aSvc8oBh2ylKDJuGtPNqGKibNJyb2diXO/aEUOKRUKPAxKa +dbKsc4Y1bhZNN3/MICMoyghwAOiuwUQMR5uhxTkQmZUwNrPFa+eW6GvyoYLFUsZs +hZfWLNGD5mLADElxs0HF7F9Zk6pSocTDXba4d4lfxsq88SyZZ7PbjJYFRfLQPzd1 +CfvpRPqolEmZo1Y5Q644PELYiJRKpBxmX5GtC5j5eaUD9XdGKvXsGhb0m0gW75rq +iUnnLkZt2ya1cDJDiCnJjo7r5KxMo0XXFDc= -----END CERTIFICATE----- From 012910f76f67a22fc47192ff8af85b958ca9b466 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20H=C3=B6rl?= Date: Mon, 18 Jun 2018 13:37:03 +0100 Subject: [PATCH 15/19] Update copyright header --- pkg/cloudprovider/providers/vsphere/vclib/connection_test.go | 2 +- pkg/cloudprovider/providers/vsphere/vclib/fixtures/fixtures.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go index dcf9f9adaa1..394a6adccaf 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go +++ b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go @@ -1,5 +1,5 @@ /* -Copyright 2016 The Kubernetes Authors. +Copyright 2018 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. diff --git a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/fixtures.go b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/fixtures.go index ebd64d58f9a..610dbf9e10c 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/fixtures/fixtures.go +++ b/pkg/cloudprovider/providers/vsphere/vclib/fixtures/fixtures.go @@ -1,5 +1,5 @@ /* -Copyright 2016 The Kubernetes Authors. +Copyright 2018 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. From 7c27cd08ada3390c3fa710989b33c2940c4a6bcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20H=C3=B6rl?= Date: Mon, 18 Jun 2018 13:49:05 +0100 Subject: [PATCH 16/19] Check if the server actually configured with a certificate --- pkg/cloudprovider/providers/vsphere/vclib/connection_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go index 394a6adccaf..05fe4cd3ed4 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go +++ b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go @@ -65,6 +65,9 @@ func createTestServer( } // calculate the leaf certificate's fingerprint + if len(server.TLS.Certificates) < 1 || len(server.TLS.Certificates[0].Certificate) < 1 { + t.Fatal("Expected server.TLS.Certificates not to be empty") + } x509LeafCert := server.TLS.Certificates[0].Certificate[0] tpBytes := sha1.Sum(x509LeafCert) tpString := fmt.Sprintf("%x", tpBytes) From 37e8c17041faded0b1183e4e1ed3d85f9e2e52b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20H=C3=B6rl?= Date: Sun, 24 Jun 2018 11:07:23 +0100 Subject: [PATCH 17/19] Do not do noramlization of the fingerprint format --- .../providers/vsphere/vclib/connection.go | 30 +---------------- .../vsphere/vclib/connection_test.go | 32 ++++--------------- 2 files changed, 8 insertions(+), 54 deletions(-) diff --git a/pkg/cloudprovider/providers/vsphere/vclib/connection.go b/pkg/cloudprovider/providers/vsphere/vclib/connection.go index 8d2e7b27d08..af56069c94b 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/connection.go +++ b/pkg/cloudprovider/providers/vsphere/vclib/connection.go @@ -17,7 +17,6 @@ limitations under the License. package vclib import ( - "bytes" "context" "crypto/tls" "encoding/pem" @@ -25,7 +24,6 @@ import ( "net" neturl "net/url" "sync" - "unicode" "github.com/golang/glog" "github.com/vmware/govmomi/session" @@ -172,11 +170,7 @@ func (connection *VSphereConnection) NewClient(ctx context.Context) (*vim25.Clie } tpHost := connection.Hostname + ":" + connection.Port - tp, err := normalizeThumbprint(connection.Thumbprint) - if err != nil { - return nil, err - } - sc.SetThumbprint(tpHost, tp) + sc.SetThumbprint(tpHost, connection.Thumbprint) client, err := vim25.NewClient(ctx, sc) if err != nil { @@ -210,25 +204,3 @@ func (connection *VSphereConnection) UpdateCredentials(username string, password connection.Username = username connection.Password = password } - -func normalizeThumbprint(original string) (string, error) { - buffer := &bytes.Buffer{} - outIdx := 0 - - for _, r := range original { - if outIdx%2 == 0 && outIdx > 0 { - if _, err := buffer.WriteRune(':'); err != nil { - return "", err - } - } - if r == ':' { - continue - } - if _, err := buffer.WriteRune(unicode.ToUpper(r)); err != nil { - return "", err - } - outIdx++ - } - - return buffer.String(), nil -} diff --git a/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go index 05fe4cd3ed4..14fd22d8413 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go +++ b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go @@ -69,8 +69,13 @@ func createTestServer( t.Fatal("Expected server.TLS.Certificates not to be empty") } x509LeafCert := server.TLS.Certificates[0].Certificate[0] - tpBytes := sha1.Sum(x509LeafCert) - tpString := fmt.Sprintf("%x", tpBytes) + var tpString string + for i, b := range sha1.Sum(x509LeafCert) { + if i > 0 { + tpString += ":" + } + tpString += fmt.Sprintf("%02X", b) + } return server, tpString } @@ -151,29 +156,6 @@ func TestWithValidThumbprint(t *testing.T) { verifyConnectionWasMade() } -func TestWithValidThumbprintAlternativeFormat(t *testing.T) { - handler, verifyConnectionWasMade := getRequestVerifier(t) - - server, thumbprint := - createTestServer(t, fixtures.CaCertPath, fixtures.ServerCertPath, fixtures.ServerKeyPath, handler) - server.StartTLS() - u := mustParseUrl(t, server.URL) - - // lowercase, remove the ':' - tpDifferentFormat := strings.Replace(strings.ToLower(thumbprint), ":", "", -1) - - connection := &vclib.VSphereConnection{ - Hostname: u.Hostname(), - Port: u.Port(), - Thumbprint: tpDifferentFormat, - } - - // Ignoring error here, because we only care about the TLS connection - connection.NewClient(context.Background()) - - verifyConnectionWasMade() -} - func TestWithInvalidCaCertPath(t *testing.T) { connection := &vclib.VSphereConnection{ Hostname: "should-not-matter", From a536ebc580f5737b5dcfb1a087ceaaa791af26c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20H=C3=B6rl?= Date: Sun, 24 Jun 2018 11:15:13 +0100 Subject: [PATCH 18/19] Remove unused exported errors --- pkg/cloudprovider/providers/vsphere/vclib/connection.go | 6 ------ .../providers/vsphere/vclib/connection_test.go | 4 ++-- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/pkg/cloudprovider/providers/vsphere/vclib/connection.go b/pkg/cloudprovider/providers/vsphere/vclib/connection.go index af56069c94b..63d2cdbdff1 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/connection.go +++ b/pkg/cloudprovider/providers/vsphere/vclib/connection.go @@ -20,7 +20,6 @@ import ( "context" "crypto/tls" "encoding/pem" - "errors" "net" neturl "net/url" "sync" @@ -148,11 +147,6 @@ func (connection *VSphereConnection) Logout(ctx context.Context) { } } -var ( - ErrCaCertNotReadable = errors.New("Could not read CA cert file") - ErrCaCertInvalid = errors.New("Could not parse CA cert file") -) - // NewClient creates a new govmomi client for the VSphereConnection obj func (connection *VSphereConnection) NewClient(ctx context.Context) (*vim25.Client, error) { url, err := soap.ParseURL(net.JoinHostPort(connection.Hostname, connection.Port)) diff --git a/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go index 14fd22d8413..b5569d92ae1 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go +++ b/pkg/cloudprovider/providers/vsphere/vclib/connection_test.go @@ -180,8 +180,8 @@ func TestInvalidCaCert(t *testing.T) { _, err := connection.NewClient(context.Background()) - if err != vclib.ErrCaCertInvalid { - t.Fatalf("ErrCaCertInvalid should have occurred, instead got: %v", err) + if msg := err.Error(); !strings.Contains(msg, "invalid certificate") { + t.Fatalf("Expected invalid certificate error, got '%s'", msg) } } From 7b8efe39c4c2250b1069322d2d013dca856b9aca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20H=C3=B6rl?= Date: Sun, 24 Jun 2018 17:08:40 +0100 Subject: [PATCH 19/19] Update bazel ... after rebase --- pkg/cloudprovider/providers/vsphere/vclib/BUILD | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/pkg/cloudprovider/providers/vsphere/vclib/BUILD b/pkg/cloudprovider/providers/vsphere/vclib/BUILD index 94dafba45f9..dddd496c59d 100644 --- a/pkg/cloudprovider/providers/vsphere/vclib/BUILD +++ b/pkg/cloudprovider/providers/vsphere/vclib/BUILD @@ -60,6 +60,7 @@ filegroup( go_test( name = "go_default_test", srcs = [ + "connection_test.go", "datacenter_test.go", "datastore_test.go", "folder_test.go", @@ -68,17 +69,9 @@ go_test( ], embed = [":go_default_library"], deps = [ + "//pkg/cloudprovider/providers/vsphere/vclib/fixtures:go_default_library", "//vendor/github.com/vmware/govmomi:go_default_library", "//vendor/github.com/vmware/govmomi/object:go_default_library", "//vendor/github.com/vmware/govmomi/simulator:go_default_library", ], ) - -go_test( - name = "go_default_xtest", - srcs = ["connection_test.go"], - deps = [ - ":go_default_library", - "//pkg/cloudprovider/providers/vsphere/vclib/fixtures:go_default_library", - ], -)