Skip to content

Commit 208d532

Browse files
committed
api: convert vSAN directory name to uuid in ResolveLibraryItemStorage
1 parent 0633de5 commit 208d532

File tree

2 files changed

+132
-4
lines changed

2 files changed

+132
-4
lines changed

vapi/library/finder/path.go

+38-4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"path"
2424
"strings"
2525

26+
"github.com/vmware/govmomi/internal"
2627
"github.com/vmware/govmomi/object"
2728
"github.com/vmware/govmomi/property"
2829
"github.com/vmware/govmomi/vapi/library"
@@ -134,6 +135,29 @@ func (f *PathFinder) datastoreName(ctx context.Context, id string) (string, erro
134135
return name, nil
135136
}
136137

138+
func (f *PathFinder) convertPath(ctx context.Context, b *mo.Datastore, path string) (string, error) {
139+
if !internal.IsDatastoreVSAN(*b) {
140+
return path, nil
141+
}
142+
143+
var dc *object.Datacenter
144+
145+
entities, err := mo.Ancestors(ctx, f.c, f.c.ServiceContent.PropertyCollector, b.Self)
146+
if err != nil {
147+
return "", err
148+
}
149+
150+
for _, entity := range entities {
151+
if entity.Self.Type == "Datacenter" {
152+
dc = object.NewDatacenter(f.c, entity.Self)
153+
break
154+
}
155+
}
156+
157+
m := object.NewDatastoreNamespaceManager(f.c)
158+
return m.ConvertNamespacePathToUuidPath(ctx, dc, path)
159+
}
160+
137161
// ResolveLibraryItemStorage transforms StorageURIs Datastore url (uuid) to Datastore name.
138162
func (f *PathFinder) ResolveLibraryItemStorage(ctx context.Context, storage []library.Storage) error {
139163
// TODO:
@@ -154,7 +178,8 @@ func (f *PathFinder) ResolveLibraryItemStorage(ctx context.Context, storage []li
154178

155179
var ds []mo.Datastore
156180
pc := property.DefaultCollector(f.c)
157-
if err := pc.Retrieve(ctx, ids, []string{"name", "info.url"}, &ds); err != nil {
181+
props := []string{"name", "summary.url", "summary.type"}
182+
if err := pc.Retrieve(ctx, ids, props, &ds); err != nil {
158183
return err
159184
}
160185

@@ -164,12 +189,21 @@ func (f *PathFinder) ResolveLibraryItemStorage(ctx context.Context, storage []li
164189

165190
for _, item := range storage {
166191
b := backing[item.StorageBacking.DatastoreID]
167-
dsurl := b.Info.GetDatastoreInfo().Url
192+
dsurl := b.Summary.Url
168193

169194
for i := range item.StorageURIs {
170-
u := strings.TrimPrefix(item.StorageURIs[i], dsurl)
195+
uri, err := url.Parse(item.StorageURIs[i])
196+
if err != nil {
197+
return err
198+
}
199+
uri.Path = path.Clean(uri.Path) // required for ConvertNamespacePathToUuidPath()
200+
uri.RawQuery = ""
201+
u, err := f.convertPath(ctx, b, uri.String())
202+
if err != nil {
203+
return err
204+
}
205+
u = strings.TrimPrefix(u, dsurl)
171206
u = strings.TrimPrefix(u, "/")
172-
u = strings.SplitN(u, "?", 2)[0] // strip query, if any
173207

174208
item.StorageURIs[i] = (&object.DatastorePath{
175209
Datastore: b.Name,

vapi/library/finder/path_test.go

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
Copyright (c) 2024-2024 VMware, Inc. All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package finder_test
18+
19+
import (
20+
"context"
21+
"fmt"
22+
"strings"
23+
"testing"
24+
25+
"github.com/vmware/govmomi/find"
26+
"github.com/vmware/govmomi/object"
27+
"github.com/vmware/govmomi/simulator"
28+
"github.com/vmware/govmomi/vapi/library"
29+
"github.com/vmware/govmomi/vapi/library/finder"
30+
"github.com/vmware/govmomi/vapi/rest"
31+
_ "github.com/vmware/govmomi/vapi/simulator"
32+
"github.com/vmware/govmomi/vim25"
33+
"github.com/vmware/govmomi/vim25/mo"
34+
"github.com/vmware/govmomi/vim25/types"
35+
)
36+
37+
func TestResolveLibraryItemStorage(t *testing.T) {
38+
simulator.Test(func(ctx context.Context, vc *vim25.Client) {
39+
rc := rest.NewClient(vc)
40+
41+
ds, err := find.NewFinder(vc).Datastore(ctx, "*")
42+
if err != nil {
43+
t.Fatal(err)
44+
}
45+
46+
var props mo.Datastore
47+
err = ds.Properties(ctx, ds.Reference(), []string{"name", "summary"}, &props)
48+
if err != nil {
49+
t.Fatal(err)
50+
}
51+
52+
fsTypes := []string{
53+
string(types.HostFileSystemVolumeFileSystemTypeOTHER),
54+
string(types.HostFileSystemVolumeFileSystemTypeVsan),
55+
}
56+
57+
for _, fs := range fsTypes {
58+
// client uses DatastoreNamespaceManager only when datastore fs is vsan/vvol
59+
simulator.Map.Get(ds.Reference()).(*simulator.Datastore).Summary.Type = fs
60+
61+
u := props.Summary.Url
62+
63+
storage := []library.Storage{
64+
{
65+
StorageBacking: library.StorageBacking{DatastoreID: ds.Reference().Value, Type: "DATASTORE"},
66+
StorageURIs: []string{
67+
fmt.Sprintf("%s/contentlib-${lib_id}/${item_id}/${file_name}_${file_id}.iso", u),
68+
fmt.Sprintf("%s/contentlib-${lib_id}/${item_id}/${file_name}_${file_id}.iso?serverId=${server_id}", u),
69+
},
70+
},
71+
}
72+
73+
f := finder.NewPathFinder(library.NewManager(rc), vc)
74+
75+
err = f.ResolveLibraryItemStorage(ctx, storage)
76+
if err != nil {
77+
t.Fatal(err)
78+
}
79+
80+
var path object.DatastorePath
81+
for _, s := range storage {
82+
for _, u := range s.StorageURIs {
83+
path.FromString(u)
84+
if path.Datastore != props.Name {
85+
t.Errorf("failed to parse %s", u)
86+
}
87+
if strings.Contains(u, "?") {
88+
t.Errorf("includes query: %s", u)
89+
}
90+
}
91+
}
92+
}
93+
})
94+
}

0 commit comments

Comments
 (0)