Skip to content
Permalink
Browse files

Remove moRef & query VMs with providerID

This patch removes the storage of the VM's managed object reference as
part of a VSphereMachine resource's spec. Instead, the provider ID is
used at the beginning of a reconcile request to resolve the VM's managed
object reference.
  • Loading branch information
akutz committed Nov 20, 2019
1 parent 17bf522 commit dbb82fb04723ac5e1cf7a1d5e10f6ae9a597204b
@@ -52,7 +52,7 @@ func (in *Config) DeepCopyInto(out *Config) {
out.Disk = in.Disk
out.Workspace = in.Workspace
out.Labels = in.Labels
out.ProviderConfig = in.ProviderConfig
in.ProviderConfig.DeepCopyInto(&out.ProviderConfig)
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Config.
@@ -133,8 +133,16 @@ func (in *NetworkConfig) DeepCopy() *NetworkConfig {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ProviderConfig) DeepCopyInto(out *ProviderConfig) {
*out = *in
out.Cloud = in.Cloud
out.Storage = in.Storage
if in.Cloud != nil {
in, out := &in.Cloud, &out.Cloud
*out = new(CloudConfig)
**out = **in
}
if in.Storage != nil {
in, out := &in.Storage, &out.Storage
*out = new(StorageConfig)
**out = **in
}
}

// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProviderConfig.
@@ -210,9 +210,6 @@ type VirtualMachine struct {
// BiosUUID is the VM's BIOS UUID.
BiosUUID string `json:"biosUUID"`

// InstanceUUID is the VM's instance UUID.
InstanceUUID string `json:"instanceUUID"`

// State is the VM's state.
State VirtualMachineState `json:"state"`

@@ -36,12 +36,6 @@ type VSphereMachineSpec struct {
// +optional
ProviderID *string `json:"providerID,omitempty"`

// This value is set automatically at runtime and should not be set or
// modified by users.
// MachineRef is used to lookup the VM.
// +optional
MachineRef string `json:"machineRef,omitempty"`

// Template is the name, inventory path, or instance UUID of the template
// used to clone new machines.
Template string `json:"template"`
@@ -174,7 +174,7 @@ func (in *VSphereCluster) DeepCopyObject() runtime.Object {
func (in *VSphereClusterList) DeepCopyInto(out *VSphereClusterList) {
*out = *in
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]VSphereCluster, len(*in))
@@ -274,7 +274,7 @@ func (in *VSphereMachine) DeepCopyObject() runtime.Object {
func (in *VSphereMachineList) DeepCopyInto(out *VSphereMachineList) {
*out = *in
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]VSphereMachine, len(*in))
@@ -406,7 +406,7 @@ func (in *VSphereMachineTemplate) DeepCopyObject() runtime.Object {
func (in *VSphereMachineTemplateList) DeepCopyInto(out *VSphereMachineTemplateList) {
*out = *in
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]VSphereMachineTemplate, len(*in))
@@ -44,10 +44,6 @@ spec:
this machine is cloned.
format: int32
type: integer
machineRef:
description: This value is set automatically at runtime and should not
be set or modified by users. MachineRef is used to lookup the VM.
type: string
memoryMiB:
description: MemoryMiB is the size of a virtual machine's memory, in
MiB. Defaults to the analogue property value in the template from
@@ -159,11 +159,6 @@ spec:
from which this machine is cloned.
format: int32
type: integer
machineRef:
description: This value is set automatically at runtime and
should not be set or modified by users. MachineRef is used
to lookup the VM.
type: string
memoryMiB:
description: MemoryMiB is the size of a virtual machine's memory,
in MiB. Defaults to the analogue property value in the template
@@ -39,6 +39,7 @@ import (
"sigs.k8s.io/cluster-api-provider-vsphere/pkg/context"
"sigs.k8s.io/cluster-api-provider-vsphere/pkg/services"
"sigs.k8s.io/cluster-api-provider-vsphere/pkg/services/govmomi"
infrautilv1 "sigs.k8s.io/cluster-api-provider-vsphere/pkg/util"
)

// VSphereMachineReconciler reconciles a VSphereMachine object
@@ -270,7 +271,10 @@ func (r *VSphereMachineReconciler) reconcileNetwork(ctx *context.MachineContext,
}

func (r *VSphereMachineReconciler) reconcileProviderID(ctx *context.MachineContext, vm infrav1.VirtualMachine, vmService services.VirtualMachineService) error {
providerID := fmt.Sprintf("vsphere://%s", vm.BiosUUID)
providerID := infrautilv1.ConvertUUIDToProviderID(vm.BiosUUID)
if providerID == "" {
return errors.Errorf("invalid BIOS UUID %s for %s", vm.BiosUUID, ctx)
}
if ctx.VSphereMachine.Spec.ProviderID == nil || *ctx.VSphereMachine.Spec.ProviderID != providerID {
ctx.VSphereMachine.Spec.ProviderID = &providerID
ctx.Logger.V(6).Info("updated provider ID", "provider-id", providerID)
@@ -7,37 +7,31 @@ start;
repeat
:Reconcile;

if (Machine has a TaskRef) then (yes)
if (Task exists) then (yes)
if (Task is running/pending) then (yes)
#LightGreen:Requeue;
elseif (Task is success/failed) then (yes)
#edf7de:Remove TaskRef from Machine;
endif
else (no)
#edf7de:Remove TaskRef from Machine;
if (Machine has DeletionTimestamp) then (yes)
if (Machine has in-flight task) then (yes)
#LightGreen:Requeue;
endif
endif
if (Is requeued or in error) then (no)
if (Machine has a MachineRef) then (no)
if (Can find VM by InstanceUUID) then (yes)
#edf7de:Assign MachineRef to Machine;
endif
endif
if (Machine has a MachineRef) then (no)
if (Can find VM by MachineRef) then (no)
#edf7de:Remove MachineRef from Machine;
else (no)
if (Machine has a ProviderID) then (yes)
#edf7de:Find VM by BIOS UUID;
else (no)
#edf7de:Find VM by instance UUID;
endif
endif
if (Machine has DeletionTimestamp) then (yes)
if (Machine has a MachineRef) then (yes)
if (VM exists) then (yes)
#edf7de:Delete VM;
#edf7de:Assign delete TaskRef to Machine;
#LightGreen:Requeue;
endif
endif
else (no)
if (Machine has in-flight task) then (yes)
#LightGreen:Requeue;
else (no)
if (Machine has a MachineRef) then (yes)
if (Machine has a ProviderID) then (yes)
#edf7de:Find VM by BIOS UUID;
else (no)
#edf7de:Find VM by instance UUID;
endif
if (VM exists) then (yes)
if (VM metadata matches calculated metadata) then (no)
#edf7de:Reconfigure VM with calculated metadata;
#edf7de:Assign reconfigure TaskRef to Machine;

Large diffs are not rendered by default.

@@ -95,26 +95,20 @@ func getOrCreateCachedSession(ctx *MachineContext) (*Session, error) {

// FindByInstanceUUID finds an object by its instance UUID.
func (s *Session) FindByInstanceUUID(ctx context.Context, uuid string) (object.Reference, error) {
if s.Client == nil {
return nil, errors.New("vSphere client is not initialized")
}
si := object.NewSearchIndex(s.Client.Client)
findFlag := true
ref, err := si.FindByUuid(ctx, s.datacenter, uuid, true, &findFlag)
if err != nil {
return nil, errors.Wrapf(err, "error finding object by instance uuid %q", uuid)
}
return ref, nil
return s.findByUUID(ctx, uuid, true)
}

// FindByUUID finds an object by its UUID.
// FindByUUID finds an object by its BIOS UUID.
func (s *Session) FindByUUID(ctx context.Context, uuid string) (object.Reference, error) {
return s.findByUUID(ctx, uuid, false)
}

func (s *Session) findByUUID(ctx context.Context, uuid string, findByInstanceUUID bool) (object.Reference, error) {
if s.Client == nil {
return nil, errors.New("vSphere client is not initialized")
}
si := object.NewSearchIndex(s.Client.Client)
findFlag := false
ref, err := si.FindByUuid(ctx, s.datacenter, uuid, true, &findFlag)
ref, err := si.FindByUuid(ctx, s.datacenter, uuid, true, &findByInstanceUUID)
if err != nil {
return nil, errors.Wrapf(err, "error finding object by uuid %q", uuid)
}
@@ -0,0 +1,32 @@
/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package govmomi

import (
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/types"

infrav1 "sigs.k8s.io/cluster-api-provider-vsphere/api/v1alpha2"
"sigs.k8s.io/cluster-api-provider-vsphere/pkg/context"
)

type virtualMachineContext struct {
context.MachineContext
Ref types.ManagedObjectReference
Obj *object.VirtualMachine
State *infrav1.VirtualMachine
}
@@ -0,0 +1,41 @@
/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package govmomi

import "fmt"

// errNotFound is returned by the findVM function when a VM is not found.
type errNotFound struct {
instanceUUID bool
uuid string
}

func (e errNotFound) Error() string {
if e.instanceUUID {
return fmt.Sprintf("vm with instance uuid %s not found", e.uuid)
}
return fmt.Sprintf("vm with bios uuid %s not found", e.uuid)
}

func isNotFound(err error) bool {
switch err.(type) {
case errNotFound, *errNotFound:
return true
default:
return false
}
}

0 comments on commit dbb82fb

Please sign in to comment.
You can’t perform that action at this time.