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  }