Skip to content

Commit 147316c

Browse files
author
Ricardo Katz
committed
Add support for template moid
1 parent 2f0e18d commit 147316c

File tree

9 files changed

+70
-143
lines changed

9 files changed

+70
-143
lines changed

apis/v1beta1/types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ const (
9393

9494
// VirtualMachineCloneSpec is information used to clone a virtual machine.
9595
type VirtualMachineCloneSpec struct {
96-
// Template is the name or inventory path of the template used to clone
96+
// Template is the name, inventory path or the MOID of the template used to clone
9797
// the virtual machine.
9898
// +kubebuilder:validation:MinLength=1
9999
Template string `json:"template"`

config/default/crd/bases/infrastructure.cluster.x-k8s.io_vspheremachines.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1428,7 +1428,7 @@ spec:
14281428
type: array
14291429
template:
14301430
description: |-
1431-
Template is the name or inventory path of the template used to clone
1431+
Template is the name, inventory path or the MOID of the template used to clone
14321432
the virtual machine.
14331433
minLength: 1
14341434
type: string

config/default/crd/bases/infrastructure.cluster.x-k8s.io_vspheremachinetemplates.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1304,7 +1304,7 @@ spec:
13041304
type: array
13051305
template:
13061306
description: |-
1307-
Template is the name or inventory path of the template used to clone
1307+
Template is the name, inventory path or the MOID of the template used to clone
13081308
the virtual machine.
13091309
minLength: 1
13101310
type: string

config/default/crd/bases/infrastructure.cluster.x-k8s.io_vspherevms.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1508,7 +1508,7 @@ spec:
15081508
type: array
15091509
template:
15101510
description: |-
1511-
Template is the name or inventory path of the template used to clone
1511+
Template is the name, inventory path or the MOID of the template used to clone
15121512
the virtual machine.
15131513
minLength: 1
15141514
type: string

pkg/context/fake/fake_vm_context.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ func newVSphereVM() infrav1.VSphereVM {
5454
ObjectMeta: metav1.ObjectMeta{
5555
Namespace: Namespace,
5656
Name: VSphereVMName,
57-
UID: VSphereVMUUID,
5857
},
5958
Spec: infrav1.VSphereVMSpec{
6059
VirtualMachineCloneSpec: infrav1.VirtualMachineCloneSpec{

pkg/services/govmomi/create_test.go

Lines changed: 43 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -26,47 +26,53 @@ import (
2626
"github.com/vmware/govmomi/vim25/types"
2727

2828
"sigs.k8s.io/cluster-api-provider-vsphere/internal/test/helpers/vcsim"
29+
vmcontext "sigs.k8s.io/cluster-api-provider-vsphere/pkg/context"
2930
"sigs.k8s.io/cluster-api-provider-vsphere/pkg/context/fake"
3031
"sigs.k8s.io/cluster-api-provider-vsphere/pkg/session"
3132
)
3233

3334
func TestCreate(t *testing.T) {
3435
ctx := context.Background()
3536

36-
t.Run("Should create using canonical names", func(t *testing.T) {
37-
model := simulator.VPX()
38-
model.Host = 0 // ClusterHost only
39-
40-
simr, err := vcsim.NewBuilder().WithModel(model).Build()
41-
if err != nil {
42-
t.Fatalf("unable to create simulator: %s", err)
43-
}
44-
defer simr.Destroy()
45-
37+
model := simulator.VPX()
38+
model.Host = 0 // ClusterHost only
39+
40+
simr, err := vcsim.NewBuilder().WithModel(model).Build()
41+
if err != nil {
42+
t.Fatalf("unable to create simulator: %s", err)
43+
}
44+
defer simr.Destroy()
45+
vmRef := simulator.Map.Any("VirtualMachine")
46+
vm, ok := vmRef.(*simulator.VirtualMachine)
47+
if !ok {
48+
t.Fatal("failed to get reference to an existing VM on the vcsim instance")
49+
}
50+
51+
executeTest := func(vmname, dc string, replaceFunc func(vmContext *vmcontext.VMContext)) {
4652
vmContext := fake.NewVMContext(ctx, fake.NewControllerManagerContext())
4753
vmContext.VSphereVM.Spec.Server = simr.ServerURL().Host
54+
vmContext.VSphereVM.SetName(vmname)
4855

4956
authSession, err := session.GetOrCreate(
5057
ctx,
5158
session.NewParams().
5259
WithServer(vmContext.VSphereVM.Spec.Server).
5360
WithUserInfo(simr.Username(), simr.Password()).
54-
WithDatacenter("*"))
61+
WithDatacenter(dc))
5562
if err != nil {
5663
t.Fatal(err)
5764
}
5865
vmContext.Session = authSession
5966

60-
vmRef := simulator.Map.Any("VirtualMachine")
61-
vm, ok := vmRef.(*simulator.VirtualMachine)
62-
if !ok {
63-
t.Fatal("failed to get reference to an existing VM on the vcsim instance")
64-
}
6567
vmContext.VSphereVM.Spec.Template = vm.Name
6668

6769
disk := object.VirtualDeviceList(vm.Config.Hardware.Device).SelectByType((*types.VirtualDisk)(nil))[0].(*types.VirtualDisk)
6870
disk.CapacityInKB = int64(vmContext.VSphereVM.Spec.DiskGiB) * 1024 * 1024
6971

72+
if replaceFunc != nil {
73+
replaceFunc(vmContext)
74+
}
75+
7076
if err := createVM(ctx, vmContext, []byte(""), ""); err != nil {
7177
t.Fatal(err)
7278
}
@@ -84,43 +90,16 @@ func TestCreate(t *testing.T) {
8490
if err != nil {
8591
t.Fatal("error waiting for task:", err)
8692
}
93+
}
8794

88-
if model.Machine+1 != model.Count().Machine {
89-
t.Error("failed to clone vm")
90-
}
91-
})
92-
93-
t.Run("Should create using MOID", func(t *testing.T) {
94-
model := simulator.VPX()
95-
model.Host = 0 // ClusterHost only
96-
97-
simr, err := vcsim.NewBuilder().WithModel(model).Build()
98-
if err != nil {
99-
t.Fatalf("unable to create simulator: %s", err)
100-
}
101-
defer simr.Destroy()
102-
vmContext := fake.NewVMContext(ctx, fake.NewControllerManagerContext())
103-
vmContext.VSphereVM.Spec.Server = simr.ServerURL().Host
104-
vmContext.VSphereVM.SetName("otherthing")
105-
106-
authSession, err := session.GetOrCreate(
107-
ctx,
108-
session.NewParams().
109-
WithServer(vmContext.VSphereVM.Spec.Server).
110-
WithUserInfo(simr.Username(), simr.Password()).
111-
WithDatacenter(simulator.Map.Any("Datacenter").Reference().String()))
112-
if err != nil {
113-
t.Fatal(err)
114-
}
115-
vmContext.Session = authSession
116-
117-
vmRef := simulator.Map.Any("VirtualMachine")
118-
vm, ok := vmRef.(*simulator.VirtualMachine)
119-
if !ok {
120-
t.Fatal("failed to get reference to an existing VM on the vcsim instance")
121-
}
122-
vmContext.VSphereVM.Spec.Template = vm.Name
95+
t.Log("executing with canonical name")
96+
executeTest("canonical", "*", nil)
97+
if model.Machine+1 != model.Count().Machine {
98+
t.Error("failed to clone vm")
99+
}
123100

101+
t.Log("executing with moid")
102+
replaceFuncMOID := func(vmContext *vmcontext.VMContext) {
124103
vmContext.VSphereVM.Spec.Datacenter = simulator.Map.Any("Datacenter").Reference().String()
125104
vmContext.VSphereVM.Spec.Datastore = simulator.Map.Any("Datastore").Reference().String()
126105
vmContext.VSphereVM.Spec.Folder = simulator.Map.Any("Folder").Reference().String()
@@ -131,63 +110,14 @@ func TestCreate(t *testing.T) {
131110
vmContext.VSphereVM.Spec.Datastore,
132111
vmContext.VSphereVM.Spec.Folder,
133112
vmContext.VSphereVM.Spec.ResourcePool)
134-
135-
disk := object.VirtualDeviceList(vm.Config.Hardware.Device).SelectByType((*types.VirtualDisk)(nil))[0].(*types.VirtualDisk)
136-
disk.CapacityInKB = int64(vmContext.VSphereVM.Spec.DiskGiB) * 1024 * 1024
137-
138-
if err := createVM(ctx, vmContext, []byte(""), ""); err != nil {
139-
t.Fatal(err)
140-
}
141-
142-
taskRef := types.ManagedObjectReference{
143-
Type: morefTypeTask,
144-
Value: vmContext.VSphereVM.Status.TaskRef,
145-
}
146-
vimClient, err := vim25.NewClient(ctx, vmContext.Session.RoundTripper)
147-
if err != nil {
148-
t.Fatal("could not make vim25 client")
149-
}
150-
task := object.NewTask(vimClient, taskRef)
151-
err = task.Wait(ctx)
152-
if err != nil {
153-
t.Fatal("error waiting for task:", err)
154-
}
155-
156-
if model.Machine+1 != model.Count().Machine {
157-
t.Error("failed to clone vm")
158-
}
159-
})
160-
161-
t.Run("should create using mixed moid and canonical names", func(t *testing.T) {
162-
model := simulator.VPX()
163-
model.Host = 0 // ClusterHost only
164-
165-
simr, err := vcsim.NewBuilder().WithModel(model).Build()
166-
if err != nil {
167-
t.Fatalf("unable to create simulator: %s", err)
168-
}
169-
defer simr.Destroy()
170-
vmContext := fake.NewVMContext(ctx, fake.NewControllerManagerContext())
171-
vmContext.VSphereVM.Spec.Server = simr.ServerURL().Host
172-
173-
authSession, err := session.GetOrCreate(
174-
ctx,
175-
session.NewParams().
176-
WithServer(vmContext.VSphereVM.Spec.Server).
177-
WithUserInfo(simr.Username(), simr.Password()).
178-
WithDatacenter(simulator.Map.Any("Datacenter").Reference().String()))
179-
if err != nil {
180-
t.Fatal(err)
181-
}
182-
vmContext.Session = authSession
183-
184-
vmRef := simulator.Map.Any("VirtualMachine")
185-
vm, ok := vmRef.(*simulator.VirtualMachine)
186-
if !ok {
187-
t.Fatal("failed to get reference to an existing VM on the vcsim instance")
188-
}
189-
vmContext.VSphereVM.Spec.Template = vm.Name
190-
113+
}
114+
executeTest("moid", simulator.Map.Any("Datacenter").Reference().String(), replaceFuncMOID)
115+
if model.Machine+2 != model.Count().Machine {
116+
t.Error("failed to clone vm")
117+
}
118+
119+
t.Log("executing with mixed")
120+
replaceFuncMixed := func(vmContext *vmcontext.VMContext) {
191121
vmContext.VSphereVM.Spec.Datacenter = simulator.Map.Any("Datacenter").Reference().String()
192122
vmContext.VSphereVM.Spec.Datastore = simulator.Map.Any("Datastore").Entity().Name
193123
vmContext.VSphereVM.Spec.Folder = simulator.Map.Any("Folder").Reference().String()
@@ -198,30 +128,9 @@ func TestCreate(t *testing.T) {
198128
vmContext.VSphereVM.Spec.Datastore,
199129
vmContext.VSphereVM.Spec.Folder,
200130
vmContext.VSphereVM.Spec.ResourcePool)
201-
202-
disk := object.VirtualDeviceList(vm.Config.Hardware.Device).SelectByType((*types.VirtualDisk)(nil))[0].(*types.VirtualDisk)
203-
disk.CapacityInKB = int64(vmContext.VSphereVM.Spec.DiskGiB) * 1024 * 1024
204-
205-
if err := createVM(ctx, vmContext, []byte(""), ""); err != nil {
206-
t.Fatal(err)
207-
}
208-
209-
taskRef := types.ManagedObjectReference{
210-
Type: morefTypeTask,
211-
Value: vmContext.VSphereVM.Status.TaskRef,
212-
}
213-
vimClient, err := vim25.NewClient(ctx, vmContext.Session.RoundTripper)
214-
if err != nil {
215-
t.Fatal("could not make vim25 client")
216-
}
217-
task := object.NewTask(vimClient, taskRef)
218-
err = task.Wait(ctx)
219-
if err != nil {
220-
t.Fatalf("error waiting for task: %v", err)
221-
}
222-
223-
if model.Machine+1 != model.Count().Machine {
224-
t.Error("failed to clone VM")
225-
}
226-
})
131+
}
132+
executeTest("mixed", simulator.Map.Any("Datacenter").Reference().String(), replaceFuncMixed)
133+
if model.Machine+3 != model.Count().Machine {
134+
t.Error("failed to clone vm")
135+
}
227136
}

pkg/services/govmomi/template/template.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,19 @@ func findTemplateByInstanceUUID(ctx context.Context, session *session.Session, t
5959

6060
func findTemplateByName(ctx context.Context, session *session.Session, templateID string) (*object.VirtualMachine, error) {
6161
log := ctrl.LoggerFrom(ctx)
62+
63+
vmRef := object.ReferenceFromString(templateID)
64+
if vmRef != nil {
65+
log.V(5).Info("Finding template by moid", "moid", templateID)
66+
tpl := object.NewVirtualMachine(session.Client.Client, *vmRef)
67+
name, err := tpl.ObjectName(ctx)
68+
if err != nil {
69+
return nil, errors.Wrapf(err, "unable to find template by moid %q", templateID)
70+
}
71+
log.V(5).Info("Found template by moid", "moid", templateID, "name", name)
72+
return tpl, nil
73+
}
74+
6275
log.V(5).Info("Find template by name", "name", templateID)
6376
tpl, err := session.Finder.VirtualMachine(ctx, templateID)
6477
if err != nil {

pkg/session/session.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,17 +208,16 @@ func GetOrCreate(ctx context.Context, params *Params) (*Session, error) {
208208
if params.datacenter != "" {
209209
var dc *object.Datacenter
210210
dcRef := object.ReferenceFromString(params.datacenter)
211-
var dcName string
212211
if dcRef != nil {
212+
var dcName string
213213
dc = object.NewDatacenter(client.Client, *dcRef)
214214
dcName, err = dc.ObjectName(ctx)
215215
log.Info("retrieving datacenter name via MOID", "datacenter", dcName)
216216
} else {
217217
dc, err = session.Finder.Datacenter(ctx, params.datacenter)
218218
if dc != nil {
219-
dcName = dc.Name()
219+
log.Info("retrieved datacenter name via name", "datacenter", dc.Name())
220220
}
221-
log.Info("retrieved datacenter name via name", "datacenter", dcName)
222221
}
223222
if err != nil {
224223
log.Error(err, "Failed to get datacenter, will logout")

test/infrastructure/vcsim/controllers/envvar_controller.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,14 +295,15 @@ func clusterEnvVarSpecGovmomiVariables(ctx context.Context, c *vcsimv1.ClusterEn
295295
// NOTE: omitting cluster Name intentionally because E2E tests provide this value in other ways
296296
// Vars below can be named only so they should be used as is
297297
vars["VSPHERE_COMPUTE_CLUSTER"] = vcsimhelpers.ClusterName(datacenter, cluster)
298-
vars["VSPHERE_TEMPLATE"] = vcsimhelpers.VMPath(datacenter, template)
299298

300299
if !moid {
301300
vars["VSPHERE_DATACENTER"] = vcsimhelpers.DatacenterName(datacenter)
302301
vars["VSPHERE_DATASTORE"] = vcsimhelpers.DatastoreName(datastore)
303302
vars["VSPHERE_FOLDER"] = vcsimhelpers.VMFolderName(datacenter)
304303
vars["VSPHERE_RESOURCE_POOL"] = vcsimhelpers.ResourcePoolPath(datacenter, cluster)
305304
vars["VSPHERE_NETWORK"] = vcsimhelpers.NetworkPath(datacenter, vcsimhelpers.DefaultNetworkName)
305+
vars["VSPHERE_TEMPLATE"] = vcsimhelpers.VMPath(datacenter, template)
306+
306307
return vars, nil
307308
}
308309

@@ -353,6 +354,12 @@ func clusterEnvVarSpecGovmomiVariables(ctx context.Context, c *vcsimv1.ClusterEn
353354
}
354355
vars["VSPHERE_NETWORK"] = networkRef.Reference().String()
355356

357+
templateRef, err := s.Finder.VirtualMachine(ctx, vcsimhelpers.VMPath(datacenter, template))
358+
if err != nil {
359+
return vars, fmt.Errorf("failed to locate template reference: %w", err)
360+
}
361+
vars["VSPHERE_TEMPLATE"] = templateRef.Reference().String()
362+
356363
return vars, nil
357364
}
358365

0 commit comments

Comments
 (0)