mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-07 03:03:59 +00:00
Merge pull request #64758 from pivotal-k8s/64222-vcp-ca-cert
Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Setup TLS with CA Cert for vsphere cloud provider - 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. **What this PR does / why we need it**: This PR adds the option of configuring a trusted CA for the communication between the vsphere cloud provider and the vcenter control plane. **Which issue(s) this PR fixes**: Fixes #64222 **Special notes for your reviewer**: **Release note**: ```release-note - Can configure the vsphere cloud provider with a trusted Root-CA ```
This commit is contained in:
commit
64243d4806
@ -45,6 +45,7 @@ go_test(
|
|||||||
deps = [
|
deps = [
|
||||||
"//pkg/cloudprovider:go_default_library",
|
"//pkg/cloudprovider:go_default_library",
|
||||||
"//pkg/cloudprovider/providers/vsphere/vclib: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",
|
"//pkg/controller:go_default_library",
|
||||||
"//staging/src/k8s.io/api/core/v1: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",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
|
@ -52,6 +52,7 @@ filegroup(
|
|||||||
srcs = [
|
srcs = [
|
||||||
":package-srcs",
|
":package-srcs",
|
||||||
"//pkg/cloudprovider/providers/vsphere/vclib/diskmanagers:all-srcs",
|
"//pkg/cloudprovider/providers/vsphere/vclib/diskmanagers:all-srcs",
|
||||||
|
"//pkg/cloudprovider/providers/vsphere/vclib/fixtures:all-srcs",
|
||||||
],
|
],
|
||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
)
|
)
|
||||||
@ -59,6 +60,7 @@ filegroup(
|
|||||||
go_test(
|
go_test(
|
||||||
name = "go_default_test",
|
name = "go_default_test",
|
||||||
srcs = [
|
srcs = [
|
||||||
|
"connection_test.go",
|
||||||
"datacenter_test.go",
|
"datacenter_test.go",
|
||||||
"datastore_test.go",
|
"datastore_test.go",
|
||||||
"folder_test.go",
|
"folder_test.go",
|
||||||
@ -67,6 +69,7 @@ go_test(
|
|||||||
],
|
],
|
||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//pkg/cloudprovider/providers/vsphere/vclib/fixtures:go_default_library",
|
||||||
"//vendor/github.com/vmware/govmomi: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/object:go_default_library",
|
||||||
"//vendor/github.com/vmware/govmomi/simulator:go_default_library",
|
"//vendor/github.com/vmware/govmomi/simulator:go_default_library",
|
||||||
|
@ -38,6 +38,8 @@ type VSphereConnection struct {
|
|||||||
Password string
|
Password string
|
||||||
Hostname string
|
Hostname string
|
||||||
Port string
|
Port string
|
||||||
|
CACert string
|
||||||
|
Thumbprint string
|
||||||
Insecure bool
|
Insecure bool
|
||||||
RoundTripperCount uint
|
RoundTripperCount uint
|
||||||
credentialsLock sync.Mutex
|
credentialsLock sync.Mutex
|
||||||
@ -130,6 +132,16 @@ func (connection *VSphereConnection) login(ctx context.Context, client *vim25.Cl
|
|||||||
// Logout calls SessionManager.Logout for the given connection.
|
// Logout calls SessionManager.Logout for the given connection.
|
||||||
func (connection *VSphereConnection) Logout(ctx context.Context) {
|
func (connection *VSphereConnection) Logout(ctx context.Context) {
|
||||||
m := session.NewManager(connection.Client)
|
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 {
|
if err := m.Logout(ctx); err != nil {
|
||||||
glog.Errorf("Logout failed: %s", err)
|
glog.Errorf("Logout failed: %s", err)
|
||||||
}
|
}
|
||||||
@ -144,11 +156,22 @@ func (connection *VSphereConnection) NewClient(ctx context.Context) (*vim25.Clie
|
|||||||
}
|
}
|
||||||
|
|
||||||
sc := soap.NewClient(url, connection.Insecure)
|
sc := soap.NewClient(url, connection.Insecure)
|
||||||
|
|
||||||
|
if ca := connection.CACert; ca != "" {
|
||||||
|
if err := sc.SetRootCAs(ca); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tpHost := connection.Hostname + ":" + connection.Port
|
||||||
|
sc.SetThumbprint(tpHost, connection.Thumbprint)
|
||||||
|
|
||||||
client, err := vim25.NewClient(ctx, sc)
|
client, err := vim25.NewClient(ctx, sc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("Failed to create new client. err: %+v", err)
|
glog.Errorf("Failed to create new client. err: %+v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = connection.login(ctx, client)
|
err = connection.login(ctx, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
224
pkg/cloudprovider/providers/vsphere/vclib/connection_test.go
Normal file
224
pkg/cloudprovider/providers/vsphere/vclib/connection_test.go
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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 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")
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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]
|
||||||
|
var tpString string
|
||||||
|
for i, b := range sha1.Sum(x509LeafCert) {
|
||||||
|
if i > 0 {
|
||||||
|
tpString += ":"
|
||||||
|
}
|
||||||
|
tpString += fmt.Sprintf("%02X", b)
|
||||||
|
}
|
||||||
|
|
||||||
|
return server, tpString
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWithValidCaCert(t *testing.T) {
|
||||||
|
handler, verifyConnectionWasMade := 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(),
|
||||||
|
CACert: fixtures.CaCertPath,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignoring error here, because we only care about the TLS connection
|
||||||
|
connection.NewClient(context.Background())
|
||||||
|
|
||||||
|
verifyConnectionWasMade()
|
||||||
|
}
|
||||||
|
|
||||||
|
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 TestWithInvalidCaCertPath(t *testing.T) {
|
||||||
|
connection := &vclib.VSphereConnection{
|
||||||
|
Hostname: "should-not-matter",
|
||||||
|
Port: "should-not-matter",
|
||||||
|
CACert: "invalid-path",
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := connection.NewClient(context.Background())
|
||||||
|
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",
|
||||||
|
CACert: fixtures.InvalidCertPath,
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := connection.NewClient(context.Background())
|
||||||
|
|
||||||
|
if msg := err.Error(); !strings.Contains(msg, "invalid certificate") {
|
||||||
|
t.Fatalf("Expected invalid certificate error, got '%s'", msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
26
pkg/cloudprovider/providers/vsphere/vclib/fixtures/BUILD
Normal file
26
pkg/cloudprovider/providers/vsphere/vclib/fixtures/BUILD
Normal file
@ -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"],
|
||||||
|
)
|
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/jCCAuYCCQDRJ2qPhdmG0DANBgkqhkiG9w0BAQsFADBAMQswCQYDVQQGEwJV
|
||||||
|
UzELMAkGA1UECAwCQ0ExEzARBgNVBAoMCkFjbWUsIEluYy4xDzANBgNVBAMMBnNv
|
||||||
|
bWVDQTAgFw0xODA2MDgxMzM5MjFaGA8yMjE4MDQyMTEzMzkyMVowQDELMAkGA1UE
|
||||||
|
BhMCVVMxCzAJBgNVBAgMAkNBMRMwEQYDVQQKDApBY21lLCBJbmMuMQ8wDQYDVQQD
|
||||||
|
DAZzb21lQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDgIovAI/Ax
|
||||||
|
QhVoaG9nEuZcTMN+UgtVoYJlFEFt9i5x/KzKVP8ko8yUqzc5E1VbVx2JbXP9lSUC
|
||||||
|
U356qrjRZJVAmotR5eW2x9nB6Z0WZ/dIBYi72/3AjmaEtAkyHZc8o0gsIGGsRP8A
|
||||||
|
0tU9s5slQW8Zq+lH1dVdNewtS+4JH6hKkO9BjKdYonl0DCopoXHcYIQUCbR02dLO
|
||||||
|
WJCvMoU4TQNQzEVAfku3YRgsevJr4rhm1htfmcpf75P1HmlmzSemqZNBL+sh9+/a
|
||||||
|
FPz20p2o/P8wK3nHCaOwA7a6uLk75ZotQiR/wF1+ZUC6wT/m/anfHcwfStRdo0+D
|
||||||
|
sWouPVydtzAeqq3c+ZWX1Vkg2Q9ucceK5rbUY2oMBn8b+8/z+GVfAh4Tx3pg+xI+
|
||||||
|
bg0QfQq77KTRMQvpCQYUxhinILDUE1gZd37O9/XGNm0atxWIeF6zG6/vWcZ0ls1K
|
||||||
|
LvPCRhfJ1IoI2eMn46rKKnm5QL4ObJ2pwlNAtxlbk5s194Hw8vPpS5WJ0x9+Hx68
|
||||||
|
TXcvrRxLnBnJlaF6syoH4j+5ES3TmCKQK2UlU6iyG4tLRCNsr8g1gJIUEmO3TGvB
|
||||||
|
NvDXdJCwSGS1Bh2pMdoMFaLq6H6lxj2awXWNkn4YAQ9hwvMrejb+QTqDT1NndAN4
|
||||||
|
/1sQNOWUv6YizgkaJYY0L94aMZ/LICd+YQIDAQABMA0GCSqGSIb3DQEBCwUAA4IC
|
||||||
|
AQBYBRH/q3gB4gEiOAUl9HbnoUb7MznZ0uQTH7fUYqr66ceZkg9w1McbwiAeZAaY
|
||||||
|
qQWwr3u4A8/Bg8csE2yQTsXeA33FP3Q6obyuYn4q7e++4+9SLkbSSQfbB67pGUK5
|
||||||
|
/pal6ULrLGzs69fbL1tOaA/VKQJndg3N9cftyiIUWTzHDop8SLmIobWVRtPQHf00
|
||||||
|
oKq8loakyluQdxQxnGdl7vMXwSpSpIH84TOdy2JN90MzVLgOz55sb/wRYfhClNFD
|
||||||
|
+1sb2V4nL2w1kXaO2UVPzk7qpG5FE54JPvvN67Ec4JjMSnGo8l3dJ9jGEmgBIML3
|
||||||
|
l1onrti2HStSs1vR4Ax0xok08okRlrGA4FqQiSx853T5uLa/JLmWfLKg9ixR4ZV+
|
||||||
|
dF+2ZrFwDLZUr4VeaDd2v2mQFBNLvdZrqp1OZ4B/1+H5S8ucb+oVhGqzDkEvRCc+
|
||||||
|
WYpNxx7kpwZPTLmMYTXXKdTWfpgz9GL0LSkY8d1rxLwHxtV8EzAkV+zIWix4h/IE
|
||||||
|
0FG4WvhrttMCu8ulZhGGoVqy7gdb4+ViWnUYNuCCjIcRJj7SeZaDawBASa/jZwik
|
||||||
|
Hxrwn0osGUqEUBmvjDdXJpTaKCr2GFOvhCM2pG6AXa14b5hS2DgbX+NZYcScYtVC
|
||||||
|
vn2HMDjnIEF4uOfDJU5eLok4jli5+VwzOQ7hOHs3DIm4+g==
|
||||||
|
-----END CERTIFICATE-----
|
93
pkg/cloudprovider/providers/vsphere/vclib/fixtures/createCerts.sh
Executable file
93
pkg/cloudprovider/providers/vsphere/vclib/fixtures/createCerts.sh
Executable file
@ -0,0 +1,93 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
readonly VALID_DAYS='73000'
|
||||||
|
readonly RSA_KEY_SIZE='4096'
|
||||||
|
|
||||||
|
createKey() {
|
||||||
|
openssl genrsa \
|
||||||
|
-out "$1" \
|
||||||
|
"$RSA_KEY_SIZE"
|
||||||
|
}
|
||||||
|
|
||||||
|
createCaCert() {
|
||||||
|
openssl req \
|
||||||
|
-x509 \
|
||||||
|
-subj "$( getSubj 'someCA' )" \
|
||||||
|
-new \
|
||||||
|
-nodes \
|
||||||
|
-key "$2" \
|
||||||
|
-sha256 \
|
||||||
|
-days "$VALID_DAYS" \
|
||||||
|
-out "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
createCSR() {
|
||||||
|
openssl req \
|
||||||
|
-new \
|
||||||
|
-sha256 \
|
||||||
|
-key "$2" \
|
||||||
|
-subj "$( getSubj 'localhost' )" \
|
||||||
|
-reqexts SAN \
|
||||||
|
-config <( getSANConfig ) \
|
||||||
|
-out "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
signCSR() {
|
||||||
|
openssl x509 \
|
||||||
|
-req \
|
||||||
|
-in "$2" \
|
||||||
|
-CA "$3" \
|
||||||
|
-CAkey "$4" \
|
||||||
|
-CAcreateserial \
|
||||||
|
-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"
|
||||||
|
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,65 @@
|
|||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package fixtures
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// 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() {
|
||||||
|
_, 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")
|
||||||
|
InvalidCertPath = filepath.Join(fixturesDir, "invalid.pem")
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
this is some invalid content
|
@ -0,0 +1,28 @@
|
|||||||
|
-----BEGIN CERTIFICATE REQUEST-----
|
||||||
|
MIIEtTCCAp0CAQAwQzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMRMwEQYDVQQK
|
||||||
|
DApBY21lLCBJbmMuMRIwEAYDVQQDDAlsb2NhbGhvc3QwggIiMA0GCSqGSIb3DQEB
|
||||||
|
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-----
|
@ -0,0 +1,51 @@
|
|||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
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
|
||||||
|
-----END RSA PRIVATE KEY-----
|
@ -0,0 +1,30 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
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
|
||||||
|
iUnnLkZt2ya1cDJDiCnJjo7r5KxMo0XXFDc=
|
||||||
|
-----END CERTIFICATE-----
|
@ -103,6 +103,8 @@ type VirtualCenterConfig struct {
|
|||||||
Datacenters string `gcfg:"datacenters"`
|
Datacenters string `gcfg:"datacenters"`
|
||||||
// Soap round tripper count (retries = RoundTripper - 1)
|
// Soap round tripper count (retries = RoundTripper - 1)
|
||||||
RoundTripperCount uint `gcfg:"soap-roundtrip-count"`
|
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.
|
// Structure that represents the content of vsphere.conf file.
|
||||||
@ -121,6 +123,11 @@ type VSphereConfig struct {
|
|||||||
VCenterPort string `gcfg:"port"`
|
VCenterPort string `gcfg:"port"`
|
||||||
// True if vCenter uses self-signed cert.
|
// True if vCenter uses self-signed cert.
|
||||||
InsecureFlag bool `gcfg:"insecure-flag"`
|
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"`
|
||||||
|
// Thumbprint of the VCenter's certificate thumbprint
|
||||||
|
Thumbprint string `gcfg:"thumbprint"`
|
||||||
// Datacenter in which VMs are located.
|
// Datacenter in which VMs are located.
|
||||||
// Deprecated. Use "datacenters" instead.
|
// Deprecated. Use "datacenters" instead.
|
||||||
Datacenter string `gcfg:"datacenter"`
|
Datacenter string `gcfg:"datacenter"`
|
||||||
@ -334,6 +341,7 @@ func populateVsphereInstanceMap(cfg *VSphereConfig) (map[string]*VSphereInstance
|
|||||||
VCenterPort: cfg.Global.VCenterPort,
|
VCenterPort: cfg.Global.VCenterPort,
|
||||||
Datacenters: cfg.Global.Datacenter,
|
Datacenters: cfg.Global.Datacenter,
|
||||||
RoundTripperCount: cfg.Global.RoundTripperCount,
|
RoundTripperCount: cfg.Global.RoundTripperCount,
|
||||||
|
Thumbprint: cfg.Global.Thumbprint,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: If secrets info is provided username and password will be populated
|
// Note: If secrets info is provided username and password will be populated
|
||||||
@ -345,7 +353,10 @@ func populateVsphereInstanceMap(cfg *VSphereConfig) (map[string]*VSphereInstance
|
|||||||
Insecure: cfg.Global.InsecureFlag,
|
Insecure: cfg.Global.InsecureFlag,
|
||||||
RoundTripperCount: vcConfig.RoundTripperCount,
|
RoundTripperCount: vcConfig.RoundTripperCount,
|
||||||
Port: vcConfig.VCenterPort,
|
Port: vcConfig.VCenterPort,
|
||||||
|
CACert: cfg.Global.CAFile,
|
||||||
|
Thumbprint: cfg.Global.Thumbprint,
|
||||||
}
|
}
|
||||||
|
|
||||||
vsphereIns := VSphereInstance{
|
vsphereIns := VSphereInstance{
|
||||||
conn: &vSphereConn,
|
conn: &vSphereConn,
|
||||||
cfg: &vcConfig,
|
cfg: &vcConfig,
|
||||||
@ -417,6 +428,8 @@ func populateVsphereInstanceMap(cfg *VSphereConfig) (map[string]*VSphereInstance
|
|||||||
Insecure: cfg.Global.InsecureFlag,
|
Insecure: cfg.Global.InsecureFlag,
|
||||||
RoundTripperCount: vcConfig.RoundTripperCount,
|
RoundTripperCount: vcConfig.RoundTripperCount,
|
||||||
Port: vcConfig.VCenterPort,
|
Port: vcConfig.VCenterPort,
|
||||||
|
CACert: cfg.Global.CAFile,
|
||||||
|
Thumbprint: vcConfig.Thumbprint,
|
||||||
}
|
}
|
||||||
vsphereIns := VSphereInstance{
|
vsphereIns := VSphereInstance{
|
||||||
conn: &vSphereConn,
|
conn: &vSphereConn,
|
||||||
|
@ -19,6 +19,8 @@ package vsphere
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -33,6 +35,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/rand"
|
"k8s.io/apimachinery/pkg/util/rand"
|
||||||
"k8s.io/kubernetes/pkg/cloudprovider"
|
"k8s.io/kubernetes/pkg/cloudprovider"
|
||||||
"k8s.io/kubernetes/pkg/cloudprovider/providers/vsphere/vclib"
|
"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:
|
// localhostCert was generated from crypto/tls/generate_cert.go with the following command:
|
||||||
@ -90,7 +93,15 @@ func configFromEnv() (cfg VSphereConfig, ok bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// configFromSim starts a vcsim instance and returns config for use against the vcsim instance.
|
// 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()) {
|
func configFromSim() (VSphereConfig, func()) {
|
||||||
|
return configFromSimWithTLS(new(tls.Config), true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
var cfg VSphereConfig
|
||||||
model := simulator.VPX()
|
model := simulator.VPX()
|
||||||
|
|
||||||
@ -99,7 +110,7 @@ func configFromSim() (VSphereConfig, func()) {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
model.Service.TLS = new(tls.Config)
|
model.Service.TLS = tlsConfig
|
||||||
s := model.Service.NewServer()
|
s := model.Service.NewServer()
|
||||||
|
|
||||||
// STS simulator
|
// STS simulator
|
||||||
@ -109,7 +120,8 @@ func configFromSim() (VSphereConfig, func()) {
|
|||||||
// Lookup Service simulator
|
// Lookup Service simulator
|
||||||
model.Service.RegisterSDK(lookup.New())
|
model.Service.RegisterSDK(lookup.New())
|
||||||
|
|
||||||
cfg.Global.InsecureFlag = true
|
cfg.Global.InsecureFlag = insecureAllowed
|
||||||
|
|
||||||
cfg.Global.VCenterIP = s.URL.Hostname()
|
cfg.Global.VCenterIP = s.URL.Hostname()
|
||||||
cfg.Global.VCenterPort = s.URL.Port()
|
cfg.Global.VCenterPort = s.URL.Port()
|
||||||
cfg.Global.User = s.URL.User.Username()
|
cfg.Global.User = s.URL.User.Username()
|
||||||
@ -160,6 +172,7 @@ insecure-flag = true
|
|||||||
datacenter = us-west
|
datacenter = us-west
|
||||||
vm-uuid = 1234
|
vm-uuid = 1234
|
||||||
vm-name = vmname
|
vm-name = vmname
|
||||||
|
ca-file = /some/path/to/a/ca.pem
|
||||||
`))
|
`))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Should succeed when a valid config is provided: %s", err)
|
t.Fatalf("Should succeed when a valid config is provided: %s", err)
|
||||||
@ -180,6 +193,10 @@ vm-name = vmname
|
|||||||
if cfg.Global.VMName != "vmname" {
|
if cfg.Global.VMName != "vmname" {
|
||||||
t.Errorf("incorrect vm-name: %s", cfg.Global.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) {
|
func TestNewVSphere(t *testing.T) {
|
||||||
@ -250,6 +267,53 @@ func TestVSphereLoginByToken(t *testing.T) {
|
|||||||
vcInstance.conn.Logout(ctx)
|
vcInstance.conn.Logout(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestVSphereLoginWithCaCert(t *testing.T) {
|
||||||
|
caCertPEM, err := ioutil.ReadFile(fixtures.CaCertPath)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Could not read ca cert from file")
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = fixtures.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) {
|
func TestZones(t *testing.T) {
|
||||||
cfg := VSphereConfig{}
|
cfg := VSphereConfig{}
|
||||||
cfg.Global.Datacenter = "myDatacenter"
|
cfg.Global.Datacenter = "myDatacenter"
|
||||||
@ -366,6 +430,7 @@ func TestSecretVSphereConfig(t *testing.T) {
|
|||||||
expectedUsername string
|
expectedUsername string
|
||||||
expectedPassword string
|
expectedPassword string
|
||||||
expectedError error
|
expectedError error
|
||||||
|
expectedThumbprints map[string]string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
testName: "Username and password with old configuration",
|
testName: "Username and password with old configuration",
|
||||||
@ -535,6 +600,69 @@ func TestSecretVSphereConfig(t *testing.T) {
|
|||||||
expectedIsSecretProvided: true,
|
expectedIsSecretProvided: true,
|
||||||
expectedError: nil,
|
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",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
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 {
|
for _, testcase := range testcases {
|
||||||
@ -564,9 +692,31 @@ func TestSecretVSphereConfig(t *testing.T) {
|
|||||||
t.Fatalf("Expected password %s doesn't match actual password %s in config %s. error: %s",
|
t.Fatalf("Expected password %s doesn't match actual password %s in config %s. error: %s",
|
||||||
testcase.expectedPassword, vsInstance.conn.Password, testcase.conf, err)
|
testcase.expectedPassword, vsInstance.conn.Password, testcase.conf, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Check, if all the expected thumbprints are configured
|
||||||
|
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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user