github.com/vmware/govmomi@v0.51.0/cli/library/deploy.go (about)

     1  // © Broadcom. All Rights Reserved.
     2  // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
     3  // SPDX-License-Identifier: Apache-2.0
     4  
     5  package library
     6  
     7  import (
     8  	"context"
     9  	"flag"
    10  	"fmt"
    11  
    12  	"github.com/vmware/govmomi/cli"
    13  	"github.com/vmware/govmomi/cli/flags"
    14  	"github.com/vmware/govmomi/cli/importx"
    15  	"github.com/vmware/govmomi/object"
    16  	"github.com/vmware/govmomi/vapi/library"
    17  	"github.com/vmware/govmomi/vapi/vcenter"
    18  	"github.com/vmware/govmomi/vim25/types"
    19  )
    20  
    21  type deploy struct {
    22  	*flags.DatastoreFlag
    23  	*flags.ResourcePoolFlag
    24  	*flags.HostSystemFlag
    25  	*flags.FolderFlag
    26  	*flags.StorageProfileFlag
    27  	*importx.OptionsFlag
    28  
    29  	config string
    30  }
    31  
    32  func init() {
    33  	cli.Register("library.deploy", &deploy{})
    34  }
    35  
    36  func (cmd *deploy) Register(ctx context.Context, f *flag.FlagSet) {
    37  	cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
    38  	cmd.DatastoreFlag.Register(ctx, f)
    39  
    40  	cmd.ResourcePoolFlag, ctx = flags.NewResourcePoolFlag(ctx)
    41  	cmd.ResourcePoolFlag.Register(ctx, f)
    42  
    43  	cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx)
    44  	cmd.HostSystemFlag.Register(ctx, f)
    45  
    46  	cmd.FolderFlag, ctx = flags.NewFolderFlag(ctx)
    47  	cmd.FolderFlag.Register(ctx, f)
    48  
    49  	cmd.StorageProfileFlag, ctx = flags.NewStorageProfileFlag(ctx)
    50  	cmd.StorageProfileFlag.Register(ctx, f)
    51  
    52  	cmd.OptionsFlag = new(importx.OptionsFlag)
    53  	cmd.OptionsFlag.Register(ctx, f)
    54  
    55  	if cli.ShowUnreleased() {
    56  		f.StringVar(&cmd.config, "config", "", "VM config spec")
    57  	}
    58  }
    59  
    60  func (cmd *deploy) Process(ctx context.Context) error {
    61  	if err := cmd.DatastoreFlag.Process(ctx); err != nil {
    62  		return err
    63  	}
    64  	if err := cmd.ResourcePoolFlag.Process(ctx); err != nil {
    65  		return err
    66  	}
    67  	if err := cmd.HostSystemFlag.Process(ctx); err != nil {
    68  		return err
    69  	}
    70  	if err := cmd.FolderFlag.Process(ctx); err != nil {
    71  		return err
    72  	}
    73  	if err := cmd.StorageProfileFlag.Process(ctx); err != nil {
    74  		return err
    75  	}
    76  	return cmd.OptionsFlag.Process(ctx)
    77  }
    78  
    79  func (cmd *deploy) Usage() string {
    80  	return "TEMPLATE [NAME]"
    81  }
    82  
    83  func (cmd *deploy) Description() string {
    84  	return `Deploy library OVF template.
    85  
    86  Examples:
    87    govc library.deploy /library_name/ovf_template vm_name
    88    govc library.export /library_name/ovf_template/*.ovf # save local copy of .ovf
    89    govc import.spec *.ovf > deploy.json # generate options from .ovf
    90    # edit deploy.json as needed
    91    govc library.deploy -options deploy.json /library_name/ovf_template`
    92  }
    93  
    94  func (cmd *deploy) Run(ctx context.Context, f *flag.FlagSet) error {
    95  	if f.NArg() > 2 {
    96  		return flag.ErrHelp
    97  	}
    98  	path := f.Arg(0)
    99  	name := f.Arg(1)
   100  
   101  	if name == "" && cmd.Options.Name != nil {
   102  		name = *cmd.Options.Name
   103  	}
   104  
   105  	vc, err := cmd.DatastoreFlag.Client()
   106  	if err != nil {
   107  		return err
   108  	}
   109  	cmd.FolderFlag.KeepAlive(vc)
   110  
   111  	c, err := cmd.DatastoreFlag.RestClient()
   112  	if err != nil {
   113  		return err
   114  	}
   115  	cmd.FolderFlag.KeepAlive(c)
   116  
   117  	m := vcenter.NewManager(c)
   118  
   119  	item, err := flags.ContentLibraryItem(ctx, c, path)
   120  	if err != nil {
   121  		return err
   122  	}
   123  
   124  	ds, err := cmd.DatastoreIfSpecified()
   125  	if err != nil {
   126  		return err
   127  	}
   128  	rp, err := cmd.ResourcePoolIfSpecified()
   129  	if err != nil {
   130  		return err
   131  	}
   132  	host, err := cmd.HostSystemIfSpecified()
   133  	if err != nil {
   134  		return err
   135  	}
   136  	hostID := ""
   137  	if rp == nil {
   138  		if host == nil {
   139  			rp, err = cmd.ResourcePoolFlag.ResourcePool()
   140  		} else {
   141  			rp, err = host.ResourcePool(ctx)
   142  			hostID = host.Reference().Value
   143  		}
   144  		if err != nil {
   145  			return err
   146  		}
   147  	}
   148  	folder, err := cmd.Folder()
   149  	if err != nil {
   150  		return err
   151  	}
   152  	finder, err := cmd.FolderFlag.Finder(false)
   153  	if err != nil {
   154  		return err
   155  	}
   156  
   157  	var networks []vcenter.NetworkMapping
   158  	for _, net := range cmd.Options.NetworkMapping {
   159  		if net.Network == "" {
   160  			continue
   161  		}
   162  		obj, err := finder.Network(ctx, net.Network)
   163  		if err != nil {
   164  			return err
   165  		}
   166  		networks = append(networks, vcenter.NetworkMapping{
   167  			Key:   net.Name,
   168  			Value: obj.Reference().Value,
   169  		})
   170  	}
   171  
   172  	var properties []vcenter.Property
   173  	for _, prop := range cmd.Options.PropertyMapping {
   174  		properties = append(properties, vcenter.Property{
   175  			ID:    prop.Key,
   176  			Value: prop.Value,
   177  		})
   178  	}
   179  
   180  	dsID := ""
   181  	if ds != nil {
   182  		dsID = ds.Reference().Value
   183  	}
   184  
   185  	cmd.FolderFlag.Log("Deploying library item...\n")
   186  
   187  	var ref *types.ManagedObjectReference
   188  
   189  	profile, err := cmd.StorageProfile(ctx)
   190  	if err != nil {
   191  		return err
   192  	}
   193  
   194  	switch item.Type {
   195  	case library.ItemTypeOVF:
   196  		deploy := vcenter.Deploy{
   197  			DeploymentSpec: vcenter.DeploymentSpec{
   198  				Name:               name,
   199  				DefaultDatastoreID: dsID,
   200  				AcceptAllEULA:      true,
   201  				Annotation:         cmd.Options.Annotation,
   202  				AdditionalParams: []vcenter.AdditionalParams{
   203  					{
   204  						Class:       vcenter.ClassDeploymentOptionParams,
   205  						Type:        vcenter.TypeDeploymentOptionParams,
   206  						SelectedKey: cmd.Options.Deployment,
   207  					},
   208  					{
   209  						Class:       vcenter.ClassPropertyParams,
   210  						Type:        vcenter.TypePropertyParams,
   211  						SelectedKey: cmd.Options.Deployment,
   212  						Properties:  properties,
   213  					},
   214  				},
   215  				NetworkMappings:     networks,
   216  				StorageProvisioning: cmd.Options.DiskProvisioning,
   217  				StorageProfileID:    profile,
   218  			},
   219  			Target: vcenter.Target{
   220  				ResourcePoolID: rp.Reference().Value,
   221  				HostID:         hostID,
   222  				FolderID:       folder.Reference().Value,
   223  			},
   224  		}
   225  
   226  		if cmd.config != "" {
   227  			deploy.VmConfigSpec = &vcenter.VmConfigSpec{
   228  				Provider: "XML",
   229  				XML:      cmd.config,
   230  			}
   231  		}
   232  
   233  		ref, err = m.DeployLibraryItem(ctx, item.ID, deploy)
   234  		if err != nil {
   235  			return err
   236  		}
   237  	case library.ItemTypeVMTX:
   238  		storage := &vcenter.DiskStorage{
   239  			Datastore: dsID,
   240  			StoragePolicy: &vcenter.StoragePolicy{
   241  				Policy: profile,
   242  				Type:   "USE_SOURCE_POLICY",
   243  			},
   244  		}
   245  		if profile != "" {
   246  			storage.StoragePolicy.Type = "USE_SPECIFIED_POLICY"
   247  		}
   248  
   249  		deploy := vcenter.DeployTemplate{
   250  			Name:          name,
   251  			Description:   cmd.Options.Annotation,
   252  			DiskStorage:   storage,
   253  			VMHomeStorage: storage,
   254  			Placement: &vcenter.Placement{
   255  				ResourcePool: rp.Reference().Value,
   256  				Host:         hostID,
   257  				Folder:       folder.Reference().Value,
   258  			},
   259  		}
   260  		ref, err = m.DeployTemplateLibraryItem(ctx, item.ID, deploy)
   261  		if err != nil {
   262  			return err
   263  		}
   264  	default:
   265  		return fmt.Errorf("unsupported library item type: %s", item.Type)
   266  	}
   267  
   268  	obj, err := finder.ObjectReference(ctx, *ref)
   269  	if err != nil {
   270  		return err
   271  	}
   272  
   273  	vm := obj.(*object.VirtualMachine)
   274  
   275  	return cmd.Deploy(vm, cmd.FolderFlag.OutputFlag)
   276  }