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 }