Repository: vmware/govmomi
Pull request #3409 (2024-04-12 00:04:08)

fix: make cns.Client independent of vim25.Client


Patch:
diff --git a/.goreleaser.yml b/.goreleaser.yml
index 3c78e4a4..5da5cd64 100644
--- a/.goreleaser.yml
+++ b/.goreleaser.yml
@@ -3,7 +3,6 @@ project_name: govmomi
 
 builds:
   - id: govc
-    no_main_check: true
     goos: &goos-defs
       - linux
       - darwin
@@ -14,7 +13,6 @@ builds:
       - arm
       - arm64
       - mips64le
-      - s390x
     env:
       - CGO_ENABLED=0
       - PKGPATH=github.com/vmware/govmomi/govc/flags
@@ -23,7 +21,6 @@ builds:
     ldflags:
       - "-X {{.Env.PKGPATH}}.BuildVersion={{.Version}} -X {{.Env.PKGPATH}}.BuildCommit={{.ShortCommit}} -X {{.Env.PKGPATH}}.BuildDate={{.Date}}"
   - id: vcsim
-    no_main_check: true
     goos: *goos-defs
     goarch: *goarch-defs
     env:
@@ -33,17 +30,6 @@ builds:
     ldflags:
       - "-X main.buildVersion={{.Version}} -X main.buildCommit={{.ShortCommit}} -X main.buildDate={{.Date}}"
 
-nfpms:
-  - package_name: govmomi
-    builds:
-      - govc
-    homepage: https://github.com/vmware/govmomi
-    maintainer: Doug MacEachern <dougm@vmware.com>
-    description: |-
-      vSphere CLI
-    formats:
-      - rpm
-
 archives:
   - id: govcbuild
     builds:
@@ -104,7 +90,7 @@ brews:
     commit_author:
       name: Alfred the Narwhal
       email: cna-alfred@vmware.com
-    directory: Formula
+    folder: Formula
     homepage: "https://github.com/vmware/govmomi/blob/main/govc/README.md"
     description: "govc is a vSphere CLI built on top of govmomi."
     test: |
@@ -124,7 +110,7 @@ brews:
     commit_author:
       name: Alfred the Narwhal
       email: cna-alfred@vmware.com
-    directory: Formula
+    folder: Formula
     homepage: "https://github.com/vmware/govmomi/blob/main/vcsim/README.md"
     description: "vcsim is a vSphere API simulator built on top of govmomi."
     test: |
diff --git a/cns/client.go b/cns/client.go
index a526ff46..c69fcf09 100644
--- a/cns/client.go
+++ b/cns/client.go
@@ -61,9 +61,25 @@ type Client struct {
 // NewClient creates a new CNS client
 func NewClient(ctx context.Context, c *vim25.Client) (*Client, error) {
 	sc := c.Client.NewServiceClient(Path, Namespace)
-	sc.Namespace = c.Namespace
-	sc.Version = c.Version
-	return &Client{sc, sc, c}, nil
+
+	// Use current vCenter vsan version by default
+	err := sc.UseServiceVersion(Namespace)
+	if err != nil {
+		return nil, err
+	}
+
+	// PropertyCollector related methods (task.Wait) need to send requests to vim25.Path (/sdk).
+	// This vim25.Client shares the same http.Transport and Namespace/Version, but requests to '/sdk'
+	rt := sc.NewServiceClient(vim25.Path, Namespace)
+	rt.Version = sc.Version
+
+	vc := &vim25.Client{
+		ServiceContent: c.ServiceContent,
+		Client:         rt,
+		RoundTripper:   rt,
+	}
+
+	return &Client{sc, sc, vc}, nil
 }
 
 // RoundTrip dispatches to the RoundTripper field.
diff --git a/govc/flags/client.go b/govc/flags/client.go
index 9b04882c..b36ebdf9 100644
--- a/govc/flags/client.go
+++ b/govc/flags/client.go
@@ -430,7 +430,6 @@ func (flag *ClientFlag) CnsClient() (*cns.Client, error) {
 	if err != nil {
 		return nil, err
 	}
-	_ = vc.UseServiceVersion("vsan")
 
 	c, err := cns.NewClient(context.Background(), vc)
 	if err != nil {
diff --git a/simulator/simulator.go b/simulator/simulator.go
index 0932a23a..31fd0eb7 100644
--- a/simulator/simulator.go
+++ b/simulator/simulator.go
@@ -630,6 +630,22 @@ func (s *Service) ServiceVersions(w http.ResponseWriter, r *http.Request) {
 	fmt.Fprintf(w, versions, s.client.ServiceContent.About.ApiVersion)
 }
 
+// ServiceVersionsVsan handler for the /sdk/vsanServiceVersions.xml path.
+func (s *Service) ServiceVersionsVsan(w http.ResponseWriter, r *http.Request) {
+	const versions = xml.Header + `<namespaces version="1.0">
+ <namespace>
+  <name>urn:vsan</name>
+  <version>%s</version>
+  <priorVersions>
+   <version>6.7</version>
+   <version>6.6</version>
+  </priorVersions>
+ </namespace>
+</namespaces>
+`
+	fmt.Fprintf(w, versions, s.client.ServiceContent.About.ApiVersion)
+}
+
 // defaultIP returns addr.IP if specified, otherwise attempts to find a non-loopback ipv4 IP
 func defaultIP(addr *net.TCPAddr) string {
 	if !addr.IP.IsUnspecified() {
@@ -667,6 +683,7 @@ func (s *Service) NewServer() *Server {
 
 	mux := s.ServeMux
 	mux.HandleFunc(Map.Path+"/vimServiceVersions.xml", s.ServiceVersions)
+	mux.HandleFunc(Map.Path+"/vsanServiceVersions.xml", s.ServiceVersionsVsan)
 	mux.HandleFunc(folderPrefix, s.ServeDatastore)
 	mux.HandleFunc(guestPrefix, ServeGuest)
 	mux.HandleFunc(nfcPrefix, ServeNFC)
diff --git a/vim25/soap/client.go b/vim25/soap/client.go
index 7a4d9b30..d6c81081 100644
--- a/vim25/soap/client.go
+++ b/vim25/soap/client.go
@@ -494,7 +494,7 @@ func (c *Client) UseServiceVersion(kind ...string) error {
 	}
 
 	if res.StatusCode != http.StatusOK {
-		return fmt.Errorf("http.Get(%s): %s", u.Path, err)
+		return fmt.Errorf("http.Get(%s): %s", u.Path, res.Status)
 	}
 
 	v := struct {


Test patch:
diff --git a/cns/client_test.go b/cns/client_test.go
index bb72f4ee..8fe07e35 100644
--- a/cns/client_test.go
+++ b/cns/client_test.go
@@ -100,8 +100,6 @@ func TestClient(t *testing.T) {
 	if err != nil {
 		t.Fatal(err)
 	}
-	// UseServiceVersion sets soap.Client.Version to the current version of the service endpoint via /sdk/vsanServiceVersions.xml
-	c.UseServiceVersion("vsan")
 	cnsClient, err := NewClient(ctx, c.Client)
 	if err != nil {
 		t.Fatal(err)
@@ -561,8 +559,6 @@ func TestClient(t *testing.T) {
 			if err != nil {
 				t.Fatal(err)
 			}
-			// UseServiceVersion sets soap.Client.Version to the current version of the service endpoint via /sdk/vsanServiceVersions.xml
-			remoteVcClient.UseServiceVersion("vsan")
 			remoteCnsClient, err := NewClient(ctx, remoteVcClient.Client)
 			if err != nil {
 				t.Fatal(err)