-
Notifications
You must be signed in to change notification settings - Fork 452
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
r/compute_cluster: New resource #487
Merged
Merged
Changes from 11 commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
88b398a
r/compute_cluster: Resource function scaffolding and schema
vancluever 1406a89
r/compute_cluster: Create workflow complete
vancluever d312fc3
r/compute_cluster: Resource flatteners
vancluever 24813cb
r/compute_cluster: Resource finished
vancluever 17c7003
r/compute_cluster: Initial testing
vancluever 6ac6778
r/compute_cluster: Basic test now functional
vancluever de88e9e
r/compute_cluster: DRS/HA test, add force evacuate for testing
vancluever dbfffe1
r/compute_cluster: Tests now complete
vancluever f26558a
r/compute_cluster: Add VM test
vancluever 4faa9aa
r/compute_cluster_resource: Documentation
vancluever 1a29a04
r/compute_cluster: Extra import support
vancluever e91dc4b
helper/folder: Slight grammar correction
vancluever 462e6af
r/compute_cluster: Specify VM restart window unit value
vancluever cead28f
r/compute_cluster: Another grammar fix in docs
vancluever 041e7c0
r/compute_cluster: More doc grammar fixes/rewording
vancluever ace5a9c
r/compute_cluster: Consolidate top-level config expansions
vancluever File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
226 changes: 226 additions & 0 deletions
226
vsphere/internal/helper/clustercomputeresource/cluster_compute_resource_helper.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,226 @@ | ||
package clustercomputeresource | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"log" | ||
"strings" | ||
|
||
"github.com/terraform-providers/terraform-provider-vsphere/vsphere/internal/helper/computeresource" | ||
"github.com/terraform-providers/terraform-provider-vsphere/vsphere/internal/helper/folder" | ||
"github.com/terraform-providers/terraform-provider-vsphere/vsphere/internal/helper/hostsystem" | ||
"github.com/terraform-providers/terraform-provider-vsphere/vsphere/internal/helper/provider" | ||
"github.com/vmware/govmomi" | ||
"github.com/vmware/govmomi/find" | ||
"github.com/vmware/govmomi/object" | ||
"github.com/vmware/govmomi/vim25/methods" | ||
"github.com/vmware/govmomi/vim25/mo" | ||
"github.com/vmware/govmomi/vim25/types" | ||
) | ||
|
||
// FromID locates a cluster by its managed object reference ID. | ||
func FromID(client *govmomi.Client, id string) (*object.ClusterComputeResource, error) { | ||
log.Printf("[DEBUG] Locating compute cluster with ID %q", id) | ||
finder := find.NewFinder(client.Client, false) | ||
|
||
ref := types.ManagedObjectReference{ | ||
Type: "ClusterComputeResource", | ||
Value: id, | ||
} | ||
|
||
ctx, cancel := context.WithTimeout(context.Background(), provider.DefaultAPITimeout) | ||
defer cancel() | ||
r, err := finder.ObjectReference(ctx, ref) | ||
if err != nil { | ||
return nil, err | ||
} | ||
cluster := r.(*object.ClusterComputeResource) | ||
log.Printf("[DEBUG] Compute cluster with ID %q found (%s)", cluster.Reference().Value, cluster.InventoryPath) | ||
return cluster, nil | ||
} | ||
|
||
// FromPath loads a ClusterComputeResource from its path. The datacenter is | ||
// optional if the path is specific enough to not require it. | ||
func FromPath(client *govmomi.Client, name string, dc *object.Datacenter) (*object.ClusterComputeResource, error) { | ||
finder := find.NewFinder(client.Client, false) | ||
if dc != nil { | ||
log.Printf("[DEBUG] Attempting to locate compute cluster %q in datacenter %q", name, dc.InventoryPath) | ||
finder.SetDatacenter(dc) | ||
} else { | ||
log.Printf("[DEBUG] Attempting to locate compute cluster at absolute path %q", name) | ||
} | ||
|
||
ctx, cancel := context.WithTimeout(context.Background(), provider.DefaultAPITimeout) | ||
defer cancel() | ||
return finder.ClusterComputeResource(ctx, name) | ||
} | ||
|
||
// Properties is a convenience method that wraps fetching the | ||
// ClusterComputeResource MO from its higher-level object. | ||
func Properties(cluster *object.ClusterComputeResource) (*mo.ClusterComputeResource, error) { | ||
ctx, cancel := context.WithTimeout(context.Background(), provider.DefaultAPITimeout) | ||
defer cancel() | ||
var props mo.ClusterComputeResource | ||
if err := cluster.Properties(ctx, cluster.Reference(), nil, &props); err != nil { | ||
return nil, err | ||
} | ||
return &props, nil | ||
} | ||
|
||
// Create creates a ClusterComputeResource in a supplied folder. The resulting | ||
// ClusterComputeResource is returned. | ||
func Create(f *object.Folder, name string, spec types.ClusterConfigSpecEx) (*object.ClusterComputeResource, error) { | ||
log.Printf("[DEBUG] Creating compute cluster %q", fmt.Sprintf("%s/%s", f.InventoryPath, name)) | ||
ctx, cancel := context.WithTimeout(context.Background(), provider.DefaultAPITimeout) | ||
defer cancel() | ||
cluster, err := f.CreateCluster(ctx, name, spec) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return cluster, nil | ||
} | ||
|
||
// Rename renames a ClusterComputeResource. | ||
func Rename(cluster *object.ClusterComputeResource, name string) error { | ||
log.Printf("[DEBUG] Renaming compute cluster %q to %s", cluster.InventoryPath, name) | ||
ctx, cancel := context.WithTimeout(context.Background(), provider.DefaultAPITimeout) | ||
defer cancel() | ||
task, err := cluster.Rename(ctx, name) | ||
if err != nil { | ||
return err | ||
} | ||
return task.Wait(ctx) | ||
} | ||
|
||
// MoveToFolder is a complex method that moves a ClusterComputeResource to a given relative | ||
// compute folder path. "Relative" here means relative to a datacenter, which | ||
// is discovered from the current ClusterComputeResource path. | ||
func MoveToFolder(client *govmomi.Client, cluster *object.ClusterComputeResource, relative string) error { | ||
f, err := folder.HostFolderFromObject(client, cluster, relative) | ||
if err != nil { | ||
return err | ||
} | ||
return folder.MoveObjectTo(cluster.Reference(), f) | ||
} | ||
|
||
// HasChildren checks to see if a compute cluster has any child items (hosts | ||
// and virtual machines) and returns true if that is the case. This is useful | ||
// when checking to see if a compute cluster is safe to delete - destroying a | ||
// compute cluster in vSphere destroys *all* children if at all possible | ||
// (including removing hosts and virtual machines), so extra verification is | ||
// necessary to prevent accidental removal. | ||
func HasChildren(cluster *object.ClusterComputeResource) (bool, error) { | ||
return computeresource.HasChildren(cluster) | ||
} | ||
|
||
// Reconfigure reconfigures a cluster. This just gets dispatched to | ||
// computeresource as both methods are the same. | ||
func Reconfigure(cluster *object.ClusterComputeResource, spec *types.ClusterConfigSpecEx) error { | ||
return computeresource.Reconfigure(cluster, spec) | ||
} | ||
|
||
// Delete destroys a ClusterComputeResource. | ||
func Delete(cluster *object.ClusterComputeResource) error { | ||
log.Printf("[DEBUG] Deleting compute cluster %q", cluster.InventoryPath) | ||
ctx, cancel := context.WithTimeout(context.Background(), provider.DefaultAPITimeout) | ||
defer cancel() | ||
task, err := cluster.Destroy(ctx) | ||
if err != nil { | ||
return err | ||
} | ||
return task.Wait(ctx) | ||
} | ||
|
||
// IsMember checks to see if a host is a member of the compute cluster | ||
// in question. | ||
// | ||
// This is a pretty basic operation that checks that the parent of the | ||
// compute is the ClusterComputeResource. | ||
func IsMember(cluster *object.ClusterComputeResource, host *object.HostSystem) (bool, error) { | ||
hprops, err := hostsystem.Properties(host) | ||
if err != nil { | ||
return false, fmt.Errorf("error getting properties for cluster %q: %s", host.Name(), err) | ||
} | ||
if hprops.Parent == nil { | ||
return false, nil | ||
} | ||
if *hprops.Parent != cluster.Reference() { | ||
return false, nil | ||
} | ||
return true, nil | ||
} | ||
|
||
// MoveHostsInto moves all of the supplied hosts into the cluster. All virtual | ||
// machines are moved to the cluster's root resource pool and any resource | ||
// pools on the host itself are deleted. | ||
func MoveHostsInto(cluster *object.ClusterComputeResource, hosts []*object.HostSystem) error { | ||
var hsNames []string | ||
var hsRefs []types.ManagedObjectReference | ||
for _, hs := range hosts { | ||
hsNames = append(hsNames, hs.Name()) | ||
hsRefs = append(hsRefs, hs.Reference()) | ||
} | ||
log.Printf("[DEBUG] Adding hosts into cluster %q: %s", cluster.Name(), strings.Join(hsNames, ", ")) | ||
|
||
req := types.MoveInto_Task{ | ||
This: cluster.Reference(), | ||
Host: hsRefs, | ||
} | ||
|
||
ctx, cancel := context.WithTimeout(context.Background(), provider.DefaultAPITimeout) | ||
defer cancel() | ||
resp, err := methods.MoveInto_Task(ctx, cluster.Client(), &req) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
task := object.NewTask(cluster.Client(), resp.Returnval) | ||
return task.Wait(ctx) | ||
} | ||
|
||
// MoveHostsOutOf moves a supplied list of hosts out of the specified cluster. | ||
// The host is moved to the root host folder for the datacenter that the | ||
// cluster is in. | ||
// | ||
// The host is placed into maintenance mode with evacuate flagged on, ensuring | ||
// that as many VMs as possible are moved out of the host before removing it | ||
// from the cluster. The effectiveness of this operation is dictated by the | ||
// cluster's DRS settings, which also affects if this means that the task will | ||
// block and require manual intervention. The supplied timeout is passed to the | ||
// maintenance mode operations, and represents the timeout in seconds. | ||
// | ||
// Individual hosts are taken out of maintenance mode after its operation is | ||
// complete. | ||
func MoveHostsOutOf(cluster *object.ClusterComputeResource, hosts []*object.HostSystem, timeout int) error { | ||
for _, host := range hosts { | ||
if err := moveHostOutOf(cluster, host, timeout); err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func moveHostOutOf(cluster *object.ClusterComputeResource, host *object.HostSystem, timeout int) error { | ||
// Place the host into maintenance mode. This blocks until the host is ready. | ||
if err := hostsystem.EnterMaintenanceMode(host, timeout, true); err != nil { | ||
return fmt.Errorf("error putting host %q into maintenance mode: %s", host.Name(), err) | ||
} | ||
|
||
// Host should be ready to move out of the cluster now. | ||
f, err := folder.HostFolderFromObject(&govmomi.Client{Client: cluster.Client()}, host, "/") | ||
if err != nil { | ||
return err | ||
} | ||
log.Printf("[DEBUG] Moving host %q out of cluster %q and to folder %q", host.Name(), cluster.Name(), f.InventoryPath) | ||
if err := folder.MoveObjectTo(host.Reference(), f); err != nil { | ||
return fmt.Errorf("error moving host %q out of cluster %q: %s", host.Name(), cluster.Name(), err) | ||
} | ||
|
||
// Move the host out of maintenance mode now that it's out of the cluster. | ||
if err := hostsystem.ExitMaintenanceMode(host, timeout); err != nil { | ||
return fmt.Errorf("error taking host %q out of maintenance mode: %s", host.Name(), err) | ||
} | ||
|
||
log.Printf("[DEBUG] Host %q moved out of cluster %q successfully", host.Name(), cluster.Name()) | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"...found, or if it is not a"