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.
This commit is contained in:
parent
ec37c0f643
commit
9fc231e5c0
@ -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
|
||||
|
122
pkg/cloudprovider/providers/vsphere/vclib/connection_test.go
Normal file
122
pkg/cloudprovider/providers/vsphere/vclib/connection_test.go
Normal file
@ -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
|
||||
}
|
51
pkg/cloudprovider/providers/vsphere/vclib/fixtures/ca.key
Normal file
51
pkg/cloudprovider/providers/vsphere/vclib/fixtures/ca.key
Normal file
@ -0,0 +1,51 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
29
pkg/cloudprovider/providers/vsphere/vclib/fixtures/ca.pem
Normal file
29
pkg/cloudprovider/providers/vsphere/vclib/fixtures/ca.pem
Normal file
@ -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-----
|
61
pkg/cloudprovider/providers/vsphere/vclib/fixtures/createCerts.sh
Executable file
61
pkg/cloudprovider/providers/vsphere/vclib/fixtures/createCerts.sh
Executable file
@ -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 "$@"
|
@ -0,0 +1 @@
|
||||
this is some invalid content
|
@ -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-----
|
@ -0,0 +1,51 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
@ -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-----
|
@ -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,
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user