github.com/vmware/govmomi@v0.51.0/internal/helpers_test.go (about) 1 // © Broadcom. All Rights Reserved. 2 // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 // SPDX-License-Identifier: Apache-2.0 4 5 package internal_test 6 7 import ( 8 "crypto/rand" 9 "encoding/hex" 10 "fmt" 11 "io" 12 "net" 13 "net/http" 14 "net/url" 15 "os" 16 "path/filepath" 17 "testing" 18 "time" 19 20 "github.com/stretchr/testify/require" 21 22 "github.com/vmware/govmomi/internal" 23 "github.com/vmware/govmomi/simulator/esx" 24 "github.com/vmware/govmomi/vim25" 25 "github.com/vmware/govmomi/vim25/soap" 26 "github.com/vmware/govmomi/vim25/types" 27 ) 28 29 func TestHostSystemManagementIPs(t *testing.T) { 30 ips := internal.HostSystemManagementIPs(esx.HostSystem.Config.VirtualNicManagerInfo.NetConfig) 31 32 if len(ips) != 1 { 33 t.Fatalf("no mgmt ip found") 34 } 35 if ips[0].String() != "127.0.0.1" { 36 t.Fatalf("Expected management ip %s, got %s", "127.0.0.1", ips[0].String()) 37 } 38 } 39 40 func TestUsingVCEnvoySidecar(t *testing.T) { 41 t.Run("VC HTTPS port", func(t *testing.T) { 42 scheme := "https" 43 hostname := "my-vcenter" 44 port := 443 45 u := &url.URL{Scheme: scheme, Host: fmt.Sprintf("%s:%d", hostname, port)} 46 client := &vim25.Client{Client: soap.NewClient(u, true)} 47 usingSidecar := internal.UsingEnvoySidecar(client) 48 require.False(t, usingSidecar) 49 }) 50 t.Run("Envoy sidecar", func(t *testing.T) { 51 scheme := "http" 52 hostname := "localhost" 53 port := 1080 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.True(t, usingSidecar) 58 }) 59 } 60 61 func TestClientUsingEnvoyHostGateway(t *testing.T) { 62 prefix := "hgw" 63 suffix := ".sock" 64 randBytes := make([]byte, 16) 65 _, err := rand.Read(randBytes) 66 require.NoError(t, err) 67 68 testSocketPath := filepath.Join(os.TempDir(), prefix+hex.EncodeToString(randBytes)+suffix) 69 70 l, err := net.Listen("unix", testSocketPath) 71 require.NoError(t, err) 72 handler := &testHTTPServer{ 73 expectedURL: "http://localhost/foo", 74 response: "Hello, Unix socket!", 75 t: t, 76 } 77 server := http.Server{ 78 Handler: handler, 79 } 80 go server.Serve(l) 81 defer server.Close() 82 defer l.Close() 83 84 // First make sure the test server works fine, since we're starting a goroutine. 85 unixDialer := func(proto, addr string) (conn net.Conn, err error) { 86 return net.Dial("unix", testSocketPath) 87 } 88 tr := &http.Transport{ 89 Dial: unixDialer, 90 } 91 client := &http.Client{Transport: tr} 92 93 require.Eventually(t, func() bool { 94 _, err := client.Get(handler.expectedURL) 95 return err == nil 96 }, 15*time.Second, 1*time.Second, "Expected test HTTP server to be up") 97 98 envVar := "VCENTER_ENVOY_HOST_GATEWAY" 99 oldValue := os.Getenv(envVar) 100 defer os.Setenv(envVar, oldValue) 101 os.Setenv(envVar, testSocketPath) 102 103 // Build a new client using the test unix socket. 104 vc := &vim25.Client{Client: soap.NewClient(&url.URL{}, true)} 105 newClient := internal.ClientWithEnvoyHostGateway(vc) 106 107 // An HTTP request made using the new client should hit the server listening on the Unix socket. 108 resp, err := newClient.Get(handler.expectedURL) 109 110 // ...but should successfully connect to the Unix socket set up for testing. 111 require.NoError(t, err) 112 response, err := io.ReadAll(resp.Body) 113 require.NoError(t, err) 114 115 require.Equal(t, response, []byte(handler.response)) 116 } 117 118 type testHTTPServer struct { 119 expectedURL string 120 response string 121 t *testing.T 122 } 123 124 func (t *testHTTPServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) { 125 require.Equal(t.t, "/foo", req.URL.Path) 126 resp.Write([]byte(t.response)) 127 } 128 129 func TestRewriteURLForHostGateway(t *testing.T) { 130 testURL, err := url.Parse("https://foo.bar/baz?query_param=1") 131 require.NoError(t, err) 132 133 hostMoref := types.ManagedObjectReference{ 134 Type: "HostSystem", 135 Value: "host-123", 136 } 137 result := internal.HostGatewayTransferURL(testURL, hostMoref) 138 require.Equal(t, "localhost", result.Host) 139 require.Equal(t, "/hgw/host-123/baz", result.Path) 140 values := url.Values{"query_param": []string{"1"}} 141 require.Equal(t, values, result.Query()) 142 } 143 144 func TestSoapArgument(t *testing.T) { 145 arg := internal.ReflectManagedMethodExecuterSoapArgument{ 146 Name: "vibname", 147 Val: "<vibname>crx</vibname>", 148 } 149 150 val := arg.Value() 151 if len(val) != 1 || val[0] != "crx" { 152 t.Errorf("val=%s", val) 153 } 154 } 155 156 func TestEsxcliName(t *testing.T) { 157 name := internal.EsxcliName("vim.EsxCLI.software.vib.get") 158 if name != "VimEsxCLISoftwareVibGet" { 159 t.Errorf("name=%s", name) 160 } 161 }