Skip to content

Commit 3b86fd0

Browse files
committed
Re-work TenantManager addition to ServiceContent for older clients
Older (Java/Python/non-Go) clients do not have TenantManaager in vmodl API and will break if they receive TenanatManager entry in ServiceContent. This patch reworks the addition of TenantManager moref entry in ServiceContent, by default the TenantManager morer entry in ServiceContent is kept nil to avoid breaking clients older than 6.9.1 (that version of vmodl does not define TenantManager). To return a valid TenantManager ref in ServiceConent in the response to newer clients (either on RetrieveServiceContent() API call or the property collector call on ServiceInstance object), we would need to handle client vmodl version properly, expecting this as a separate change, this patch keeps the TenantManager unwired and skips the new tests.
1 parent 93d3991 commit 3b86fd0

File tree

3 files changed

+178
-42
lines changed

3 files changed

+178
-42
lines changed

object/tenant_manager.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
Copyright (c) 2021 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 object
18+
19+
import (
20+
"context"
21+
22+
"github.com/vmware/govmomi/vim25"
23+
"github.com/vmware/govmomi/vim25/methods"
24+
"github.com/vmware/govmomi/vim25/types"
25+
)
26+
27+
type TenantManager struct {
28+
Common
29+
}
30+
31+
func NewTenantManager(c *vim25.Client) *TenantManager {
32+
t := TenantManager{
33+
Common: NewCommon(c, *c.ServiceContent.TenantManager),
34+
}
35+
36+
return &t
37+
}
38+
39+
func (t TenantManager) MarkServiceProviderEntities(ctx context.Context, entities []types.ManagedObjectReference) error {
40+
req := types.MarkServiceProviderEntities{
41+
This: t.Reference(),
42+
Entity: entities,
43+
}
44+
45+
_, err := methods.MarkServiceProviderEntities(ctx, t.Client(), &req)
46+
if err != nil {
47+
return err
48+
}
49+
50+
return nil
51+
}
52+
53+
func (t TenantManager) UnmarkServiceProviderEntities(ctx context.Context, entities []types.ManagedObjectReference) error {
54+
req := types.UnmarkServiceProviderEntities{
55+
This: t.Reference(),
56+
Entity: entities,
57+
}
58+
59+
_, err := methods.UnmarkServiceProviderEntities(ctx, t.Client(), &req)
60+
if err != nil {
61+
return err
62+
}
63+
64+
return nil
65+
}
66+
67+
func (t TenantManager) RetrieveServiceProviderEntities(ctx context.Context) ([]types.ManagedObjectReference, error) {
68+
req := types.RetrieveServiceProviderEntities{
69+
This: t.Reference(),
70+
}
71+
72+
res, err := methods.RetrieveServiceProviderEntities(ctx, t.Client(), &req)
73+
if err != nil {
74+
return nil, err
75+
}
76+
77+
return res.Returnval, nil
78+
}

simulator/tenant_manager_test.go

Lines changed: 99 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,16 @@ limitations under the License.
1717
package simulator
1818

1919
import (
20+
"context"
2021
"reflect"
2122
"sort"
2223
"strings"
2324
"testing"
2425

25-
"github.com/vmware/govmomi/simulator/vpx"
26-
"github.com/vmware/govmomi/vim25/methods"
26+
"github.com/vmware/govmomi"
27+
"github.com/vmware/govmomi/object"
28+
"github.com/vmware/govmomi/vim25"
29+
"github.com/vmware/govmomi/vim25/soap"
2730
"github.com/vmware/govmomi/vim25/types"
2831
)
2932

@@ -40,7 +43,70 @@ func sortMoRefSlice(a []types.ManagedObjectReference) {
4043
})
4144
}
4245

46+
func TestTenantManagerForOldClients(t *testing.T) {
47+
// ServiceContent TenantManager field is not present in older (<6.9.1) vmodl
48+
// (e.g. response to RetrieveServiceConent() API or propery collector on
49+
// ServiceInstance object), this field should be set only if the client is newer.
50+
// Currently TenantManager is not set in vpx simulator's ServiceContent, and
51+
// would be added once simulator supports client vmodl versioning properly.
52+
t.Skip("needs vmodl versioning")
53+
54+
ctx := context.Background()
55+
m := VPX()
56+
defer m.Remove()
57+
58+
err := m.Create()
59+
if err != nil {
60+
t.Fatal(err)
61+
}
62+
63+
s := m.Service.NewServer()
64+
defer s.Close()
65+
66+
// Ensure non-nil moref being returned for ServiceContent.TenantManger for newer vim version clients.
67+
newSoapClient := soap.NewClient(s.URL, true)
68+
newSoapClient.Version = "6.9.1"
69+
newVimClient, err := vim25.NewClient(ctx, newSoapClient)
70+
if err != nil {
71+
t.Fatal(err)
72+
}
73+
if newVimClient.ServiceContent.TenantManager == nil {
74+
t.Fatal("Expected retrieved ServiceContent.TenantManager to be non-nil")
75+
}
76+
77+
// Ensure non-nil moref being returned for ServiceContent.TenantManger for default version used in vim25 client.
78+
defaultSoapClient := soap.NewClient(s.URL, true)
79+
// No version being set for soap client
80+
defaultVimClient, err := vim25.NewClient(ctx, defaultSoapClient)
81+
if err != nil {
82+
t.Fatal(err)
83+
}
84+
if defaultVimClient.ServiceContent.TenantManager == nil {
85+
t.Fatal("Expected retrieved ServiceContent.TenantManager to be non-nil")
86+
}
87+
88+
// Ensure nil being returned for ServiceContent.TenantManger for older vim version clients.
89+
oldSoapClient := soap.NewClient(s.URL, true)
90+
oldSoapClient.Version = "6.5"
91+
oldVimClient, err := vim25.NewClient(ctx, oldSoapClient)
92+
if err != nil {
93+
t.Fatal(err)
94+
}
95+
if oldVimClient.ServiceContent.TenantManager != nil {
96+
t.Fatalf("Expected retrieved ServiceContent.TenantManager to be nil but found %v", oldVimClient.ServiceContent.TenantManager)
97+
}
98+
99+
}
100+
43101
func TestTenantManagerVPX(t *testing.T) {
102+
// ServiceContent TenantManager field is not present in older (<6.9.1) vmodl
103+
// (e.g. response to RetrieveServiceConent() API or propery collector on
104+
// ServiceInstance object), this field should be set only if the client is newer.
105+
// Currently TenantManager is not set in vpx simulator's ServiceContent, and
106+
// would be added once simulator supports client vmodl versioning properly.
107+
t.Skip("needs vmodl versioning")
108+
109+
ctx := context.Background()
44110
m := VPX()
45111
defer m.Remove()
46112

@@ -52,77 +118,70 @@ func TestTenantManagerVPX(t *testing.T) {
52118
s := m.Service.NewServer()
53119
defer s.Close()
54120

55-
tenantManager := Map.Get(*vpx.ServiceContent.TenantManager).(*TenantManager)
121+
c, err := govmomi.NewClient(ctx, s.URL, true)
122+
if err != nil {
123+
t.Fatal(err)
124+
}
125+
126+
tenantManager := object.NewTenantManager(c.Client)
56127
serviceProviderEntities := []types.ManagedObjectReference{
57128
{Type: "VirtualMachine", Value: "vm-123"},
58129
{Type: "HostSystem", Value: "host-1"},
59130
}
60131
sortMoRefSlice(serviceProviderEntities)
61132

62133
// "Read your writes", mark entities and verify they are marked.
63-
resBody := tenantManager.MarkServiceProviderEntities(&types.MarkServiceProviderEntities{
64-
Entity: serviceProviderEntities,
65-
})
66-
if f := resBody.Fault(); f != nil {
67-
t.Fatal(f)
134+
err = tenantManager.MarkServiceProviderEntities(ctx, serviceProviderEntities)
135+
if err != nil {
136+
t.Fatal(err)
68137
}
69-
resBody = tenantManager.RetrieveServiceProviderEntities(&types.RetrieveServiceProviderEntities{})
70-
if f := resBody.Fault(); f != nil {
71-
t.Fatal(f)
138+
markedEntities, err := tenantManager.RetrieveServiceProviderEntities(ctx)
139+
if err != nil {
140+
t.Fatal(err)
72141
}
73-
markedEntities := resBody.(*methods.RetrieveServiceProviderEntitiesBody).Res.Returnval
74142
sortMoRefSlice(markedEntities)
75143
if !reflect.DeepEqual(serviceProviderEntities, markedEntities) {
76144
t.Errorf("Requested-to-be-marked entities mismatch with acutally marked: %+v, %+v", serviceProviderEntities, markedEntities)
77145
}
78146

79-
// Repeatedely mark entities and verify they are deduped.
80-
resBody = tenantManager.MarkServiceProviderEntities(&types.MarkServiceProviderEntities{
81-
Entity: serviceProviderEntities,
82-
})
83-
if f := resBody.Fault(); f != nil {
84-
t.Fatal(f)
147+
// Repeatedely mark same entities and verify they are deduped.
148+
err = tenantManager.MarkServiceProviderEntities(ctx, serviceProviderEntities)
149+
if err != nil {
150+
t.Fatal(err)
85151
}
86-
resBody = tenantManager.RetrieveServiceProviderEntities(&types.RetrieveServiceProviderEntities{})
87-
if f := resBody.Fault(); f != nil {
88-
t.Fatal(f)
152+
markedEntities, err = tenantManager.RetrieveServiceProviderEntities(ctx)
153+
if err != nil {
154+
t.Fatal(err)
89155
}
90-
markedEntities = resBody.(*methods.RetrieveServiceProviderEntitiesBody).Res.Returnval
91156
sortMoRefSlice(markedEntities)
92157
if !reflect.DeepEqual(serviceProviderEntities, markedEntities) {
93158
t.Errorf("Requested-to-be-marked entities mismatch with acutally marked: %+v, %+v", serviceProviderEntities, markedEntities)
94159
}
95160

96161
// Unmark not-previously-marked entity and verify no-op.
97162
unknownEntities := []types.ManagedObjectReference{{Type: "Folder", Value: "group-3"}}
98-
resBody = tenantManager.UnmarkServiceProviderEntities(&types.UnmarkServiceProviderEntities{
99-
Entity: unknownEntities,
100-
})
101-
if f := resBody.Fault(); f != nil {
102-
t.Fatal(f)
163+
err = tenantManager.UnmarkServiceProviderEntities(ctx, unknownEntities)
164+
if err != nil {
165+
t.Fatal(err)
103166
}
104-
resBody = tenantManager.RetrieveServiceProviderEntities(&types.RetrieveServiceProviderEntities{})
105-
if f := resBody.Fault(); f != nil {
106-
t.Fatal(f)
167+
markedEntities, err = tenantManager.RetrieveServiceProviderEntities(ctx)
168+
if err != nil {
169+
t.Fatal(err)
107170
}
108-
markedEntities = resBody.(*methods.RetrieveServiceProviderEntitiesBody).Res.Returnval
109171
sortMoRefSlice(markedEntities)
110172
if !reflect.DeepEqual(serviceProviderEntities, markedEntities) {
111173
t.Errorf("Requested-to-be-marked entities mismatch with acutally marked: %+v, %+v", serviceProviderEntities, markedEntities)
112174
}
113175

114176
// Unmark marked entities and verify no longer marked.
115-
resBody = tenantManager.UnmarkServiceProviderEntities(&types.UnmarkServiceProviderEntities{
116-
Entity: serviceProviderEntities,
117-
})
118-
if f := resBody.Fault(); f != nil {
119-
t.Fatal(f)
177+
err = tenantManager.UnmarkServiceProviderEntities(ctx, serviceProviderEntities)
178+
if err != nil {
179+
t.Fatal(err)
120180
}
121-
resBody = tenantManager.RetrieveServiceProviderEntities(&types.RetrieveServiceProviderEntities{})
122-
if f := resBody.Fault(); f != nil {
123-
t.Fatal(f)
181+
markedEntities, err = tenantManager.RetrieveServiceProviderEntities(ctx)
182+
if err != nil {
183+
t.Fatal(err)
124184
}
125-
markedEntities = resBody.(*methods.RetrieveServiceProviderEntitiesBody).Res.Returnval
126185
if len(markedEntities) > 0 {
127186
t.Errorf("Expected all entities to be unmarked but still found marked: %+v", markedEntities)
128187
}

simulator/vpx/service_content.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2017-2021 VMware, Inc. All Rights Reserved.
2+
Copyright (c) 2017 VMware, Inc. All Rights Reserved.
33
44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
@@ -83,5 +83,4 @@ var ServiceContent = types.ServiceContent{
8383
HealthUpdateManager: &types.ManagedObjectReference{Type: "HealthUpdateManager", Value: "HealthUpdateManager"},
8484
FailoverClusterConfigurator: &types.ManagedObjectReference{Type: "FailoverClusterConfigurator", Value: "FailoverClusterConfigurator"},
8585
FailoverClusterManager: &types.ManagedObjectReference{Type: "FailoverClusterManager", Value: "FailoverClusterManager"},
86-
TenantManager: &types.ManagedObjectReference{Type: "TenantTenantManager", Value: "TenantManager"},
8786
}

0 commit comments

Comments
 (0)