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  }