github.com/vmware/govmomi@v0.51.0/vapi/vcenter/vcenter_ovf.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 vcenter 6 7 import ( 8 "context" 9 "fmt" 10 "net/http" 11 12 "github.com/vmware/govmomi/vapi/internal" 13 "github.com/vmware/govmomi/vapi/rest" 14 "github.com/vmware/govmomi/vim25/types" 15 ) 16 17 // AdditionalParams are additional OVF parameters which can be specified for a deployment target. 18 // This structure is a union where based on Type, only one of each commented section will be set. 19 type AdditionalParams struct { 20 Class string `json:"@class"` 21 Type string `json:"type"` 22 23 // DeploymentOptionParams 24 SelectedKey string `json:"selected_key,omitempty"` 25 DeploymentOptions []DeploymentOption `json:"deployment_options,omitempty"` 26 27 // ExtraConfigs 28 ExtraConfig []ExtraConfig `json:"extra_configs,omitempty"` 29 30 // PropertyParams 31 Properties []Property `json:"properties,omitempty"` 32 33 // SizeParams 34 ApproximateSparseDeploymentSize int64 `json:"approximate_sparse_deployment_size,omitempty"` 35 VariableDiskSize bool `json:"variable_disk_size,omitempty"` 36 ApproximateDownloadSize int64 `json:"approximate_download_size,omitempty"` 37 ApproximateFlatDeploymentSize int64 `json:"approximate_flat_deployment_size,omitempty"` 38 39 // IpAllocationParams 40 SupportedAllocationScheme []string `json:"supported_allocation_scheme,omitempty"` 41 SupportedIPProtocol []string `json:"supported_ip_protocol,omitempty"` 42 SupportedIPAllocationPolicy []string `json:"supported_ip_allocation_policy,omitempty"` 43 IPAllocationPolicy string `json:"ip_allocation_policy,omitempty"` 44 IPProtocol string `json:"ip_protocol,omitempty"` 45 46 // UnknownSections 47 UnknownSections []UnknownSection `json:"unknown_sections,omitempty"` 48 } 49 50 const ( 51 ClassDeploymentOptionParams = "com.vmware.vcenter.ovf.deployment_option_params" 52 ClassPropertyParams = "com.vmware.vcenter.ovf.property_params" 53 TypeDeploymentOptionParams = "DeploymentOptionParams" 54 TypeExtraConfigParams = "ExtraConfigParams" 55 TypeIPAllocationParams = "IpAllocationParams" 56 TypePropertyParams = "PropertyParams" 57 TypeSizeParams = "SizeParams" 58 ) 59 60 // DeploymentOption contains the information about a deployment option as defined in the OVF specification 61 type DeploymentOption struct { 62 Key string `json:"key,omitempty"` 63 Label string `json:"label,omitempty"` 64 Description string `json:"description,omitempty"` 65 DefaultChoice bool `json:"default_choice,omitempty"` 66 } 67 68 // ExtraConfig contains information about a vmw:ExtraConfig OVF element 69 type ExtraConfig struct { 70 Key string `json:"key,omitempty"` 71 Value string `json:"value,omitempty"` 72 VirtualSystemID string `json:"virtual_system_id,omitempty"` 73 } 74 75 // Property contains information about a property in an OVF package 76 type Property struct { 77 Category string `json:"category,omitempty"` 78 ClassID string `json:"class_id,omitempty"` 79 Description string `json:"description,omitempty"` 80 ID string `json:"id,omitempty"` 81 InstanceID string `json:"instance_id,omitempty"` 82 Label string `json:"label,omitempty"` 83 Type string `json:"type,omitempty"` 84 UIOptional bool `json:"ui_optional,omitempty"` 85 Value string `json:"value,omitempty"` 86 } 87 88 // UnknownSection contains information about an unknown section in an OVF package 89 type UnknownSection struct { 90 Tag string `json:"tag,omitempty"` 91 Info string `json:"info,omitempty"` 92 } 93 94 // NetworkMapping specifies the target network to use for sections of type ovf:NetworkSection in the OVF descriptor 95 type NetworkMapping struct { 96 Key string `json:"key"` 97 Value string `json:"value"` 98 } 99 100 // StorageGroupMapping defines the storage deployment target and storage provisioning type for a section of type vmw:StorageGroupSection in the OVF descriptor 101 type StorageGroupMapping struct { 102 Type string `json:"type"` 103 StorageProfileID string `json:"storage_profile_id,omitempty"` 104 DatastoreID string `json:"datastore_id,omitempty"` 105 Provisioning string `json:"provisioning,omitempty"` 106 } 107 108 // StorageMapping specifies the target storage to use for sections of type vmw:StorageGroupSection in the OVF descriptor 109 type StorageMapping struct { 110 Key string `json:"key"` 111 Value StorageGroupMapping `json:"value"` 112 } 113 114 // VmConfigSpec defines the optional virtual machine configuration settings used when deploying an OVF template 115 type VmConfigSpec struct { 116 Provider string `json:"provider"` 117 XML string `json:"xml"` 118 } 119 120 // DeploymentSpec is the deployment specification for the deployment 121 type DeploymentSpec struct { 122 Name string `json:"name,omitempty"` 123 Annotation string `json:"annotation,omitempty"` 124 AcceptAllEULA bool `json:"accept_all_EULA,omitempty"` 125 NetworkMappings []NetworkMapping `json:"network_mappings,omitempty"` 126 StorageMappings []StorageMapping `json:"storage_mappings,omitempty"` 127 StorageProvisioning string `json:"storage_provisioning,omitempty"` 128 StorageProfileID string `json:"storage_profile_id,omitempty"` 129 Locale string `json:"locale,omitempty"` 130 Flags []string `json:"flags,omitempty"` 131 AdditionalParams []AdditionalParams `json:"additional_parameters,omitempty"` 132 DefaultDatastoreID string `json:"default_datastore_id,omitempty"` 133 VmConfigSpec *VmConfigSpec `json:"vm_config_spec,omitempty"` 134 } 135 136 // Target is the target for the deployment 137 type Target struct { 138 ResourcePoolID string `json:"resource_pool_id,omitempty"` 139 HostID string `json:"host_id,omitempty"` 140 FolderID string `json:"folder_id,omitempty"` 141 } 142 143 // Deploy contains the information to start the deployment of a library OVF 144 type Deploy struct { 145 DeploymentSpec `json:"deployment_spec,omitempty"` 146 Target `json:"target,omitempty"` 147 } 148 149 // Error is a SERVER error 150 type Error struct { 151 Class string `json:"@class,omitempty"` 152 Messages []rest.LocalizableMessage `json:"messages,omitempty"` 153 } 154 155 // ParseIssue is a parse issue struct 156 type ParseIssue struct { 157 Category string `json:"@classcategory,omitempty"` 158 File string `json:"file,omitempty"` 159 LineNumber int64 `json:"line_number,omitempty"` 160 ColumnNumber int64 `json:"column_number,omitempty"` 161 Message rest.LocalizableMessage `json:"message,omitempty"` 162 } 163 164 // OVFError is a list of errors from create or deploy 165 type OVFError struct { 166 Category string `json:"category,omitempty"` 167 Error *Error `json:"error,omitempty"` 168 Issues []ParseIssue `json:"issues,omitempty"` 169 Message *rest.LocalizableMessage `json:"message,omitempty"` 170 } 171 172 // ResourceID is a managed object reference for a deployed resource. 173 type ResourceID struct { 174 Type string `json:"type,omitempty"` 175 Value string `json:"id,omitempty"` 176 } 177 178 // DeploymentError is an error that occurs when deploying and OVF from 179 // a library item. 180 type DeploymentError struct { 181 Errors []OVFError `json:"errors,omitempty"` 182 } 183 184 // Error implements the error interface 185 func (e *DeploymentError) Error() string { 186 msg := "" 187 if len(e.Errors) != 0 { 188 err := e.Errors[0] 189 if err.Message != nil { 190 msg = err.Message.DefaultMessage 191 } else if err.Error != nil && len(err.Error.Messages) != 0 { 192 msg = err.Error.Messages[0].DefaultMessage 193 } 194 } 195 if msg == "" { 196 msg = fmt.Sprintf("%#v", e) 197 } 198 return "deploy error: " + msg 199 } 200 201 // LibraryTarget specifies a Library or Library item 202 type LibraryTarget struct { 203 LibraryID string `json:"library_id,omitempty"` 204 LibraryItemID string `json:"library_item_id,omitempty"` 205 } 206 207 // CreateSpec info used to create an OVF package from a VM 208 type CreateSpec struct { 209 Description string `json:"description,omitempty"` 210 Name string `json:"name,omitempty"` 211 Flags []string `json:"flags,omitempty"` 212 } 213 214 // OVF data used by CreateOVF 215 type OVF struct { 216 Spec CreateSpec `json:"create_spec"` 217 Source ResourceID `json:"source"` 218 Target LibraryTarget `json:"target"` 219 } 220 221 // CreateResult used for decoded a CreateOVF response 222 type CreateResult struct { 223 Succeeded bool `json:"succeeded,omitempty"` 224 ID string `json:"ovf_library_item_id,omitempty"` 225 Error *DeploymentError `json:"error,omitempty"` 226 } 227 228 // Deployment is the results from issuing a library OVF deployment 229 type Deployment struct { 230 Succeeded bool `json:"succeeded,omitempty"` 231 ResourceID *ResourceID `json:"resource_id,omitempty"` 232 Error *DeploymentError `json:"error,omitempty"` 233 } 234 235 // FilterRequest contains the information to start a vcenter filter call 236 type FilterRequest struct { 237 Target `json:"target,omitempty"` 238 } 239 240 // FilterResponse returns information from the vcenter filter call 241 type FilterResponse struct { 242 EULAs []string `json:"EULAs,omitempty"` 243 AdditionalParams []AdditionalParams `json:"additional_params,omitempty"` 244 Annotation string `json:"Annotation,omitempty"` 245 Name string `json:"name,omitempty"` 246 Networks []string `json:"Networks,omitempty"` 247 StorageGroups []string `json:"storage_groups,omitempty"` 248 } 249 250 // Manager extends rest.Client, adding content library related methods. 251 type Manager struct { 252 *rest.Client 253 } 254 255 // NewManager creates a new Manager instance with the given client. 256 func NewManager(client *rest.Client) *Manager { 257 return &Manager{ 258 Client: client, 259 } 260 } 261 262 // CreateOVF creates a library OVF item in content library from an existing VM 263 func (c *Manager) CreateOVF(ctx context.Context, ovf OVF) (string, error) { 264 if ovf.Source.Type == "" { 265 ovf.Source.Type = "VirtualMachine" 266 } 267 url := c.Resource(internal.VCenterOVFLibraryItem) 268 var res CreateResult 269 err := c.Do(ctx, url.Request(http.MethodPost, ovf), &res) 270 if err != nil { 271 return "", err 272 } 273 if res.Succeeded { 274 return res.ID, nil 275 } 276 return "", res.Error 277 } 278 279 // DeployLibraryItem deploys a library OVF 280 func (c *Manager) DeployLibraryItem(ctx context.Context, libraryItemID string, deploy Deploy) (*types.ManagedObjectReference, error) { 281 url := c.Resource(internal.VCenterOVFLibraryItem).WithID(libraryItemID).WithAction("deploy") 282 var res Deployment 283 err := c.Do(ctx, url.Request(http.MethodPost, deploy), &res) 284 if err != nil { 285 return nil, err 286 } 287 if res.Succeeded { 288 return &types.ManagedObjectReference{ 289 Type: res.ResourceID.Type, 290 Value: res.ResourceID.Value, 291 }, nil 292 } 293 return nil, res.Error 294 } 295 296 // FilterLibraryItem deploys a library OVF 297 func (c *Manager) FilterLibraryItem(ctx context.Context, libraryItemID string, filter FilterRequest) (FilterResponse, error) { 298 url := c.Resource(internal.VCenterOVFLibraryItem).WithID(libraryItemID).WithAction("filter") 299 var res FilterResponse 300 return res, c.Do(ctx, url.Request(http.MethodPost, filter), &res) 301 }