github.com/vmware/govmomi@v0.43.0/internal/helpers_test.go (about) 1 /* 2 Copyright (c) 2021 VMware, Inc. All Rights Reserved. 3 Licensed under the Apache License, Version 2.0 (the "License"); 4 you may not use this file except in compliance with the License. 5 You may obtain a copy of the License at 6 http://www.apache.org/licenses/LICENSE-2.0 7 Unless required by applicable law or agreed to in writing, software 8 distributed under the License is distributed on an "AS IS" BASIS, 9 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 See the License for the specific language governing permissions and 11 limitations under the License. 12 */ 13 14 package internal_test 15 16 import ( 17 "crypto/rand" 18 "encoding/hex" 19 "fmt" 20 "io" 21 "net" 22 "net/http" 23 "net/url" 24 "os" 25 "path/filepath" 26 "testing" 27 "time" 28 29 "github.com/stretchr/testify/require" 30 31 "github.com/vmware/govmomi/internal" 32 "github.com/vmware/govmomi/simulator/esx" 33 "github.com/vmware/govmomi/vim25" 34 "github.com/vmware/govmomi/vim25/soap" 35 "github.com/vmware/govmomi/vim25/types" 36 ) 37 38 func TestHostSystemManagementIPs(t *testing.T) { 39 ips := internal.HostSystemManagementIPs(esx.HostSystem.Config.VirtualNicManagerInfo.NetConfig) 40 41 if len(ips) != 1 { 42 t.Fatalf("no mgmt ip found") 43 } 44 if ips[0].String() != "127.0.0.1" { 45 t.Fatalf("Expected management ip %s, got %s", "127.0.0.1", ips[0].String()) 46 } 47 } 48 49 func TestUsingVCEnvoySidecar(t *testing.T) { 50 t.Run("VC HTTPS port", func(t *testing.T) { 51 scheme := "https" 52 hostname := "my-vcenter" 53 port := 443 54 u := &url.URL{Scheme: scheme, Host: fmt.Sprintf("%s:%d", hostname, port)} 55 client := &vim25.Client{Client: soap.NewClient(u, true)} 56 usingSidecar := internal.UsingEnvoySidecar(client) 57 require.False(t, usingSidecar) 58 }) 59 t.Run("Envoy sidecar", func(t *testing.T) { 60 scheme := "http" 61 hostname := "localhost" 62 port := 1080 63 u := &url.URL{Scheme: scheme, Host: fmt.Sprintf("%s:%d", hostname, port)} 64 client := &vim25.Client{Client: soap.NewClient(u, true)} 65 usingSidecar := internal.UsingEnvoySidecar(client) 66 require.True(t, usingSidecar) 67 }) 68 } 69 70 func TestClientUsingEnvoyHostGateway(t *testing.T) { 71 prefix := "hgw" 72 suffix := ".sock" 73 randBytes := make([]byte, 16) 74 _, err := rand.Read(randBytes) 75 require.NoError(t, err) 76 77 testSocketPath := filepath.Join(os.TempDir(), prefix+hex.EncodeToString(randBytes)+suffix) 78 79 l, err := net.Listen("unix", testSocketPath) 80 require.NoError(t, err) 81 handler := &testHTTPServer{ 82 expectedURL: "http://localhost/foo", 83 response: "Hello, Unix socket!", 84 t: t, 85 } 86 server := http.Server{ 87 Handler: handler, 88 } 89 go server.Serve(l) 90 defer server.Close() 91 defer l.Close() 92 93 // First make sure the test server works fine, since we're starting a goroutine. 94 unixDialer := func(proto, addr string) (conn net.Conn, err error) { 95 return net.Dial("unix", testSocketPath) 96 } 97 tr := &http.Transport{ 98 Dial: unixDialer, 99 } 100 client := &http.Client{Transport: tr} 101 102 require.Eventually(t, func() bool { 103 _, err := client.Get(handler.expectedURL) 104 return err == nil 105 }, 15*time.Second, 1*time.Second, "Expected test HTTP server to be up") 106 107 envVar := "VCENTER_ENVOY_HOST_GATEWAY" 108 oldValue := os.Getenv(envVar) 109 defer os.Setenv(envVar, oldValue) 110 os.Setenv(envVar, testSocketPath) 111 112 // Build a new client using the test unix socket. 113 vc := &vim25.Client{Client: soap.NewClient(&url.URL{}, true)} 114 newClient := internal.ClientWithEnvoyHostGateway(vc) 115 116 // An HTTP request made using the new client should hit the server listening on the Unix socket. 117 resp, err := newClient.Get(handler.expectedURL) 118 119 // ...but should successfully connect to the Unix socket set up for testing. 120 require.NoError(t, err) 121 response, err := io.ReadAll(resp.Body) 122 require.NoError(t, err) 123 124 require.Equal(t, response, []byte(handler.response)) 125 } 126 127 type testHTTPServer struct { 128 expectedURL string 129 response string 130 t *testing.T 131 } 132 133 func (t *testHTTPServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) { 134 require.Equal(t.t, "/foo", req.URL.Path) 135 resp.Write([]byte(t.response)) 136 } 137 138 func TestRewriteURLForHostGateway(t *testing.T) { 139 testURL, err := url.Parse("https://foo.bar/baz?query_param=1") 140 require.NoError(t, err) 141 142 hostMoref := types.ManagedObjectReference{ 143 Type: "HostSystem", 144 Value: "host-123", 145 } 146 result := internal.HostGatewayTransferURL(testURL, hostMoref) 147 require.Equal(t, "localhost", result.Host) 148 require.Equal(t, "/hgw/host-123/baz", result.Path) 149 values := url.Values{"query_param": []string{"1"}} 150 require.Equal(t, values, result.Query()) 151 }