Blame vendor/github.com/vmware/govmomi/govc/flags/cluster.go

Packit Service 4d2de5
/*
Packit Service 4d2de5
Copyright (c) 2017 VMware, Inc. All Rights Reserved.
Packit Service 4d2de5
Packit Service 4d2de5
Licensed under the Apache License, Version 2.0 (the "License");
Packit Service 4d2de5
you may not use this file except in compliance with the License.
Packit Service 4d2de5
You may obtain a copy of the License at
Packit Service 4d2de5
Packit Service 4d2de5
    http://www.apache.org/licenses/LICENSE-2.0
Packit Service 4d2de5
Packit Service 4d2de5
Unless required by applicable law or agreed to in writing, software
Packit Service 4d2de5
distributed under the License is distributed on an "AS IS" BASIS,
Packit Service 4d2de5
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit Service 4d2de5
See the License for the specific language governing permissions and
Packit Service 4d2de5
limitations under the License.
Packit Service 4d2de5
*/
Packit Service 4d2de5
Packit Service 4d2de5
package flags
Packit Service 4d2de5
Packit Service 4d2de5
import (
Packit Service 4d2de5
	"context"
Packit Service 4d2de5
	"flag"
Packit Service 4d2de5
	"fmt"
Packit Service 4d2de5
	"os"
Packit Service 4d2de5
Packit Service 4d2de5
	"github.com/vmware/govmomi/object"
Packit Service 4d2de5
	"github.com/vmware/govmomi/property"
Packit Service 4d2de5
	"github.com/vmware/govmomi/view"
Packit Service 4d2de5
	"github.com/vmware/govmomi/vim25/mo"
Packit Service 4d2de5
	"github.com/vmware/govmomi/vim25/types"
Packit Service 4d2de5
)
Packit Service 4d2de5
Packit Service 4d2de5
type ClusterFlag struct {
Packit Service 4d2de5
	common
Packit Service 4d2de5
Packit Service 4d2de5
	*DatacenterFlag
Packit Service 4d2de5
Packit Service 4d2de5
	Name string
Packit Service 4d2de5
Packit Service 4d2de5
	cluster *object.ClusterComputeResource
Packit Service 4d2de5
	pc      *property.Collector
Packit Service 4d2de5
}
Packit Service 4d2de5
Packit Service 4d2de5
var clusterFlagKey = flagKey("cluster")
Packit Service 4d2de5
Packit Service 4d2de5
func NewClusterFlag(ctx context.Context) (*ClusterFlag, context.Context) {
Packit Service 4d2de5
	if v := ctx.Value(clusterFlagKey); v != nil {
Packit Service 4d2de5
		return v.(*ClusterFlag), ctx
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	v := &ClusterFlag{}
Packit Service 4d2de5
	v.DatacenterFlag, ctx = NewDatacenterFlag(ctx)
Packit Service 4d2de5
	ctx = context.WithValue(ctx, clusterFlagKey, v)
Packit Service 4d2de5
	return v, ctx
Packit Service 4d2de5
}
Packit Service 4d2de5
Packit Service 4d2de5
func (f *ClusterFlag) Register(ctx context.Context, fs *flag.FlagSet) {
Packit Service 4d2de5
	f.RegisterOnce(func() {
Packit Service 4d2de5
		f.DatacenterFlag.Register(ctx, fs)
Packit Service 4d2de5
Packit Service 4d2de5
		env := "GOVC_CLUSTER"
Packit Service 4d2de5
		value := os.Getenv(env)
Packit Service 4d2de5
		usage := fmt.Sprintf("Cluster [%s]", env)
Packit Service 4d2de5
		fs.StringVar(&f.Name, "cluster", value, usage)
Packit Service 4d2de5
	})
Packit Service 4d2de5
}
Packit Service 4d2de5
Packit Service 4d2de5
// RegisterPlacement registers the -cluster flag without using GOVC_CLUSTER env as the default value,
Packit Service 4d2de5
// usage is specific to VM placement.
Packit Service 4d2de5
func (f *ClusterFlag) RegisterPlacement(ctx context.Context, fs *flag.FlagSet) {
Packit Service 4d2de5
	f.RegisterOnce(func() {
Packit Service 4d2de5
		f.DatacenterFlag.Register(ctx, fs)
Packit Service 4d2de5
Packit Service 4d2de5
		fs.StringVar(&f.Name, "cluster", "", "Use cluster for VM placement via DRS")
Packit Service 4d2de5
	})
Packit Service 4d2de5
}
Packit Service 4d2de5
Packit Service 4d2de5
func (f *ClusterFlag) Process(ctx context.Context) error {
Packit Service 4d2de5
	return f.ProcessOnce(func() error {
Packit Service 4d2de5
		if err := f.DatacenterFlag.Process(ctx); err != nil {
Packit Service 4d2de5
			return err
Packit Service 4d2de5
		}
Packit Service 4d2de5
		return nil
Packit Service 4d2de5
	})
Packit Service 4d2de5
}
Packit Service 4d2de5
Packit Service 4d2de5
func (f *ClusterFlag) Cluster() (*object.ClusterComputeResource, error) {
Packit Service 4d2de5
	if f.cluster != nil {
Packit Service 4d2de5
		return f.cluster, nil
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	finder, err := f.Finder()
Packit Service 4d2de5
	if err != nil {
Packit Service 4d2de5
		return nil, err
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	if f.cluster, err = finder.ClusterComputeResourceOrDefault(context.TODO(), f.Name); err != nil {
Packit Service 4d2de5
		return nil, err
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	f.pc = property.DefaultCollector(f.cluster.Client())
Packit Service 4d2de5
Packit Service 4d2de5
	return f.cluster, nil
Packit Service 4d2de5
}
Packit Service 4d2de5
Packit Service 4d2de5
func (f *ClusterFlag) ClusterIfSpecified() (*object.ClusterComputeResource, error) {
Packit Service 4d2de5
	if f.Name == "" {
Packit Service 4d2de5
		return nil, nil
Packit Service 4d2de5
	}
Packit Service 4d2de5
	return f.Cluster()
Packit Service 4d2de5
}
Packit Service 4d2de5
Packit Service 4d2de5
func (f *ClusterFlag) Reconfigure(ctx context.Context, spec types.BaseComputeResourceConfigSpec) error {
Packit Service 4d2de5
	cluster, err := f.Cluster()
Packit Service 4d2de5
	if err != nil {
Packit Service 4d2de5
		return err
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	task, err := cluster.Reconfigure(ctx, spec, true)
Packit Service 4d2de5
	if err != nil {
Packit Service 4d2de5
		return err
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	logger := f.ProgressLogger(fmt.Sprintf("Reconfigure %s...", cluster.InventoryPath))
Packit Service 4d2de5
	defer logger.Wait()
Packit Service 4d2de5
Packit Service 4d2de5
	_, err = task.WaitForResult(ctx, logger)
Packit Service 4d2de5
	return err
Packit Service 4d2de5
}
Packit Service 4d2de5
Packit Service 4d2de5
func (f *ClusterFlag) objectMap(ctx context.Context, kind string, names []string) (map[string]types.ManagedObjectReference, error) {
Packit Service 4d2de5
	cluster, err := f.Cluster()
Packit Service 4d2de5
	if err != nil {
Packit Service 4d2de5
		return nil, err
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	objects := make(map[string]types.ManagedObjectReference, len(names))
Packit Service 4d2de5
	for _, name := range names {
Packit Service 4d2de5
		objects[name] = types.ManagedObjectReference{}
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	m := view.NewManager(cluster.Client())
Packit Service 4d2de5
	v, err := m.CreateContainerView(ctx, cluster.Reference(), []string{kind}, true)
Packit Service 4d2de5
	if err != nil {
Packit Service 4d2de5
		return nil, err
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	defer func() {
Packit Service 4d2de5
		_ = v.Destroy(ctx)
Packit Service 4d2de5
	}()
Packit Service 4d2de5
Packit Service 4d2de5
	var entities []mo.ManagedEntity
Packit Service 4d2de5
Packit Service 4d2de5
	err = v.Retrieve(ctx, []string{"ManagedEntity"}, []string{"name"}, &entities)
Packit Service 4d2de5
	if err != nil {
Packit Service 4d2de5
		return nil, err
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	for _, e := range entities {
Packit Service 4d2de5
		if _, ok := objects[e.Name]; ok {
Packit Service 4d2de5
			objects[e.Name] = e.Self
Packit Service 4d2de5
		}
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	for name, ref := range objects {
Packit Service 4d2de5
		if ref.Value == "" {
Packit Service 4d2de5
			return nil, fmt.Errorf("%s %q not found", kind, name)
Packit Service 4d2de5
		}
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	return objects, nil
Packit Service 4d2de5
}
Packit Service 4d2de5
Packit Service 4d2de5
func (f *ClusterFlag) ObjectList(ctx context.Context, kind string, names []string) ([]types.ManagedObjectReference, error) {
Packit Service 4d2de5
	objs, err := f.objectMap(ctx, kind, names)
Packit Service 4d2de5
	if err != nil {
Packit Service 4d2de5
		return nil, err
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	var refs []types.ManagedObjectReference
Packit Service 4d2de5
Packit Service 4d2de5
	for _, name := range names { // preserve order
Packit Service 4d2de5
		refs = append(refs, objs[name])
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	return refs, nil
Packit Service 4d2de5
}
Packit Service 4d2de5
Packit Service 4d2de5
func (f *ClusterFlag) Names(ctx context.Context, refs []types.ManagedObjectReference) (map[types.ManagedObjectReference]string, error) {
Packit Service 4d2de5
	names := make(map[types.ManagedObjectReference]string, len(refs))
Packit Service 4d2de5
Packit Service 4d2de5
	if len(refs) != 0 {
Packit Service 4d2de5
		var objs []mo.ManagedEntity
Packit Service 4d2de5
		err := f.pc.Retrieve(ctx, refs, []string{"name"}, &objs)
Packit Service 4d2de5
		if err != nil {
Packit Service 4d2de5
			return nil, err
Packit Service 4d2de5
		}
Packit Service 4d2de5
Packit Service 4d2de5
		for _, obj := range objs {
Packit Service 4d2de5
			names[obj.Self] = obj.Name
Packit Service 4d2de5
		}
Packit Service 4d2de5
	}
Packit Service 4d2de5
Packit Service 4d2de5
	return names, nil
Packit Service 4d2de5
}