Skip to content

Commit 03b6af5

Browse files
authored
Merge pull request #1064 from yastij/storage-policy-capv
support storage policies in CAPV
2 parents edebae5 + 326acad commit 03b6af5

9 files changed

+55
-6
lines changed

api/v1alpha3/types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ type VirtualMachineCloneSpec struct {
100100
// +optional
101101
Datastore string `json:"datastore,omitempty"`
102102

103+
// StoragePolicyName of the storage policy to use with this
104+
// Virtual Machine
105+
// +optional
106+
StoragePolicyName string `json:"storagePolicyName,omitempty"`
107+
103108
// ResourcePool is the name or inventory path of the resource pool in which
104109
// the virtual machine is created/located.
105110
// +optional

api/v1alpha3/vspheremachine_webhook.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ func (r *VSphereMachine) ValidateCreate() error {
5252
}
5353
}
5454
}
55+
56+
if spec.Datastore != "" && spec.StoragePolicyName != "" {
57+
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "Datastore"), spec.Datastore, "cannot be set when spec.StoragePolicyName is also set"))
58+
}
5559
return aggregateObjErrors(r.GroupVersionKind().GroupKind(), r.Name, allErrs)
5660
}
5761

api/v1alpha3/vspheremachinetemplate_webhook.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ func (r *VSphereMachineTemplate) ValidateCreate() error {
5353
allErrs = append(allErrs, field.Forbidden(field.NewPath("spec", "template", "spec", "network", "devices", "ipAddrs"), "cannot be set in templates"))
5454
}
5555
}
56+
57+
if spec.Datastore != "" && spec.StoragePolicyName != "" {
58+
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "Datastore"), spec.Datastore, "cannot be set when spec.StoragePolicyName is also set"))
59+
}
5660
return aggregateObjErrors(r.GroupVersionKind().GroupKind(), r.Name, allErrs)
5761
}
5862

api/v1alpha3/vspherevm_webhook.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ func (r *VSphereVM) ValidateCreate() error {
5252
}
5353
}
5454
}
55+
56+
if spec.Datastore != "" && spec.StoragePolicyName != "" {
57+
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "Datastore"), spec.Datastore, "cannot be set when spec.StoragePolicyName is also set"))
58+
}
5559
return aggregateObjErrors(r.GroupVersionKind().GroupKind(), r.Name, allErrs)
5660
}
5761

config/crd/bases/infrastructure.cluster.x-k8s.io_haproxyloadbalancers.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,10 @@ spec:
250250
create a linked clone. This field is ignored if LinkedClone
251251
is not enabled. Defaults to the source's current snapshot.
252252
type: string
253+
storagePolicyName:
254+
description: StoragePolicyName of the storage policy to use with
255+
this Virtual Machine
256+
type: string
253257
template:
254258
description: Template is the name or inventory path of the template
255259
used to clone the virtual machine.

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,10 @@ spec:
514514
a linked clone. This field is ignored if LinkedClone is not enabled.
515515
Defaults to the source's current snapshot.
516516
type: string
517+
storagePolicyName:
518+
description: StoragePolicyName of the storage policy to use with this
519+
Virtual Machine
520+
type: string
517521
template:
518522
description: Template is the name or inventory path of the template
519523
used to clone the virtual machine.

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,10 @@ spec:
574574
to create a linked clone. This field is ignored if LinkedClone
575575
is not enabled. Defaults to the source's current snapshot.
576576
type: string
577+
storagePolicyName:
578+
description: StoragePolicyName of the storage policy to use
579+
with this Virtual Machine
580+
type: string
577581
template:
578582
description: Template is the name or inventory path of the
579583
template used to clone the virtual machine.

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,10 @@ spec:
272272
a linked clone. This field is ignored if LinkedClone is not enabled.
273273
Defaults to the source's current snapshot.
274274
type: string
275+
storagePolicyName:
276+
description: StoragePolicyName of the storage policy to use with this
277+
Virtual Machine
278+
type: string
275279
template:
276280
description: Template is the name or inventory path of the template
277281
used to clone the virtual machine.

pkg/services/govmomi/vcenter/clone.go

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package vcenter
1919
import (
2020
"github.com/pkg/errors"
2121
"github.com/vmware/govmomi/object"
22+
"github.com/vmware/govmomi/pbm"
2223
"github.com/vmware/govmomi/vim25/mo"
2324
"github.com/vmware/govmomi/vim25/types"
2425

@@ -107,11 +108,6 @@ func Clone(ctx *context.VMContext, bootstrapData []byte) error {
107108
return errors.Wrapf(err, "unable to get folder for %q", ctx)
108109
}
109110

110-
datastore, err := ctx.Session.Finder.DatastoreOrDefault(ctx, ctx.VSphereVM.Spec.Datastore)
111-
if err != nil {
112-
return errors.Wrapf(err, "unable to get datastore for %q", ctx)
113-
}
114-
115111
pool, err := ctx.Session.Finder.ResourcePoolOrDefault(ctx, ctx.VSphereVM.Spec.ResourcePool)
116112
if err != nil {
117113
return errors.Wrapf(err, "unable to get resource pool for %q", ctx)
@@ -167,7 +163,6 @@ func Clone(ctx *context.VMContext, bootstrapData []byte) error {
167163
MemoryMB: memMiB,
168164
},
169165
Location: types.VirtualMachineRelocateSpec{
170-
Datastore: types.NewReference(datastore.Reference()),
171166
DiskMoveType: string(diskMoveType),
172167
Folder: types.NewReference(folder.Reference()),
173168
Pool: types.NewReference(pool.Reference()),
@@ -180,6 +175,27 @@ func Clone(ctx *context.VMContext, bootstrapData []byte) error {
180175
Snapshot: snapshotRef,
181176
}
182177

178+
if ctx.VSphereVM.Spec.StoragePolicyName != "" {
179+
pbmClient, err := pbm.NewClient(ctx, ctx.Session.Client.Client)
180+
if err != nil {
181+
return errors.Wrapf(err, "unable to create pbm client for %q", ctx)
182+
}
183+
184+
storageProfileID, err := pbmClient.ProfileIDByName(ctx, ctx.VSphereVM.Spec.StoragePolicyName)
185+
if err != nil {
186+
return errors.Wrapf(err, "unable to get storageProfileID from name %s for %q", ctx.VSphereVM.Spec.StoragePolicyName, ctx)
187+
}
188+
spec.Location.Profile = []types.BaseVirtualMachineProfileSpec{
189+
&types.VirtualMachineDefinedProfileSpec{ProfileId: storageProfileID},
190+
}
191+
} else {
192+
datastore, err := ctx.Session.Finder.DatastoreOrDefault(ctx, ctx.VSphereVM.Spec.Datastore)
193+
if err != nil {
194+
return errors.Wrapf(err, "unable to get datastore for %q", ctx)
195+
}
196+
spec.Location.Datastore = types.NewReference(datastore.Reference())
197+
}
198+
183199
ctx.Logger.Info("cloning machine", "namespace", ctx.VSphereVM.Namespace, "name", ctx.VSphereVM.Name, "cloneType", ctx.VSphereVM.Status.CloneMode)
184200
task, err := tpl.Clone(ctx, folder, ctx.VSphereVM.Name, spec)
185201
if err != nil {

0 commit comments

Comments
 (0)