From 7820861bb54f698bf69d8be566e23aa9ca763a0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=2E=C3=87a=C4=9Flar=20Onur?= Date: Mon, 23 Oct 2017 15:50:04 -0700 Subject: [PATCH 1/2] [govc] Introduce TLSHandshakeTimeout parameter --- govc/README.md | 2 ++ govc/flags/client.go | 71 +++++++++++++++++++++++--------------- govc/test/cli.bats | 18 ++++++++++ govc/test/test_helper.bash | 1 + 4 files changed, 65 insertions(+), 27 deletions(-) diff --git a/govc/README.md b/govc/README.md index 0703a6b91..8dc08dc2a 100644 --- a/govc/README.md +++ b/govc/README.md @@ -82,6 +82,8 @@ to set defaults: > govc about.cert -u host -k -thumbprint | tee -a $GOVC_TLS_KNOWN_HOSTS > govc about -u user:pass@host +* `GOVC_TLS_HANDSHAKE_TIMEOUT`: Limits the time spent performing the TLS handshake. + * `GOVC_INSECURE`: Disable certificate verification. > This option sets Go's tls.Config.InsecureSkipVerify flag and is false by default. diff --git a/govc/flags/client.go b/govc/flags/client.go index 904df4759..a63ff3519 100644 --- a/govc/flags/client.go +++ b/govc/flags/client.go @@ -25,10 +25,12 @@ import ( "flag" "fmt" "io/ioutil" + "net/http" "net/url" "os" "path/filepath" "strings" + "time" "github.com/vmware/govmomi/session" "github.com/vmware/govmomi/vim25" @@ -37,18 +39,19 @@ import ( ) const ( - envURL = "GOVC_URL" - envUsername = "GOVC_USERNAME" - envPassword = "GOVC_PASSWORD" - envCertificate = "GOVC_CERTIFICATE" - envPrivateKey = "GOVC_PRIVATE_KEY" - envInsecure = "GOVC_INSECURE" - envPersist = "GOVC_PERSIST_SESSION" - envMinAPIVersion = "GOVC_MIN_API_VERSION" - envVimNamespace = "GOVC_VIM_NAMESPACE" - envVimVersion = "GOVC_VIM_VERSION" - envTLSCaCerts = "GOVC_TLS_CA_CERTS" - envTLSKnownHosts = "GOVC_TLS_KNOWN_HOSTS" + envURL = "GOVC_URL" + envUsername = "GOVC_USERNAME" + envPassword = "GOVC_PASSWORD" + envCertificate = "GOVC_CERTIFICATE" + envPrivateKey = "GOVC_PRIVATE_KEY" + envInsecure = "GOVC_INSECURE" + envPersist = "GOVC_PERSIST_SESSION" + envMinAPIVersion = "GOVC_MIN_API_VERSION" + envVimNamespace = "GOVC_VIM_NAMESPACE" + envVimVersion = "GOVC_VIM_VERSION" + envTLSCaCerts = "GOVC_TLS_CA_CERTS" + envTLSKnownHosts = "GOVC_TLS_KNOWN_HOSTS" + envTLSHandshakeTimeout = "GOVC_TLS_HANDSHAKE_TIMEOUT" ) const cDescr = "ESX or vCenter URL" @@ -58,21 +61,21 @@ type ClientFlag struct { *DebugFlag - url *url.URL - username string - password string - cert string - key string - insecure bool - persist bool - minAPIVersion string - vimNamespace string - vimVersion string - tlsCaCerts string - tlsKnownHosts string - tlsHostHash string - - client *vim25.Client + url *url.URL + username string + password string + cert string + key string + insecure bool + persist bool + minAPIVersion string + vimNamespace string + vimVersion string + tlsCaCerts string + tlsKnownHosts string + tlsHostHash string + tlsHandshakeTimeout time.Duration + client *vim25.Client } var ( @@ -215,6 +218,16 @@ func (flag *ClientFlag) Register(ctx context.Context, f *flag.FlagSet) { usage := fmt.Sprintf("TLS known hosts file [%s]", envTLSKnownHosts) f.StringVar(&flag.tlsKnownHosts, "tls-known-hosts", value, usage) } + + { + value, err := time.ParseDuration(os.Getenv(envTLSHandshakeTimeout)) + if err != nil { + value = 10 * time.Second + } + usage := fmt.Sprintf("TLS handshake timeout [%s]", envTLSHandshakeTimeout) + f.DurationVar(&flag.tlsHandshakeTimeout, "tls-handshake-timeout", value, usage) + } + }) } @@ -275,6 +288,10 @@ func (flag *ClientFlag) configure(sc *soap.Client) (soap.RoundTripper, error) { return nil, err } + if t, ok := sc.Transport.(*http.Transport); ok { + t.TLSHandshakeTimeout = flag.tlsHandshakeTimeout + } + // Retry twice when a temporary I/O error occurs. // This means a maximum of 3 attempts. return vim25.Retry(sc, vim25.TemporaryNetworkError(3)), nil diff --git a/govc/test/cli.bats b/govc/test/cli.bats index f7f222225..f12a5e46f 100755 --- a/govc/test/cli.bats +++ b/govc/test/cli.bats @@ -9,6 +9,24 @@ load test_helper assert_success assert_line "Vendor: VMware, Inc." + run govc about --tls-handshake-timeout=10s + assert_success + assert_line "Vendor: VMware, Inc." + + run env GOVC_TLS_HANDSHAKE_TIMEOUT=10s govc about + assert_success + assert_line "Vendor: VMware, Inc." + + run env GOVC_TLS_HANDSHAKE_TIMEOUT=NOT_A_DURATION govc about + assert_success + assert_line "Vendor: VMware, Inc." + + run govc about --tls-handshake-timeout=1ns + assert_failure + + run env GOVC_TLS_HANDSHAKE_TIMEOUT=1ns govc about + assert_failure + run govc about -json assert_success diff --git a/govc/test/test_helper.bash b/govc/test/test_helper.bash index c9faa7c30..ea8d5306f 100644 --- a/govc/test/test_helper.bash +++ b/govc/test/test_helper.bash @@ -7,6 +7,7 @@ export GOVC_PERSIST_SESSION=false unset GOVC_URL unset GOVC_DEBUG unset GOVC_TLS_KNOWN_HOSTS +unset GOVC_TLS_HANDSHAKE_TIMEOUT unset GOVC_DATACENTER unset GOVC_HOST unset GOVC_USERNAME From b1fdd6e0f4f7f1916d7bfa69ccc158971879f8c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=2E=C3=87a=C4=9Flar=20Onur?= Date: Mon, 23 Oct 2017 16:14:40 -0700 Subject: [PATCH 2/2] Wat? There is no blank here --- govc/flags/client.go | 1 - 1 file changed, 1 deletion(-) diff --git a/govc/flags/client.go b/govc/flags/client.go index a63ff3519..f0fe5ee0a 100644 --- a/govc/flags/client.go +++ b/govc/flags/client.go @@ -227,7 +227,6 @@ func (flag *ClientFlag) Register(ctx context.Context, f *flag.FlagSet) { usage := fmt.Sprintf("TLS handshake timeout [%s]", envTLSHandshakeTimeout) f.DurationVar(&flag.tlsHandshakeTimeout, "tls-handshake-timeout", value, usage) } - }) }