github.com/vmware/govmomi@v0.37.1/vapi/vcenter/vcenter_ovf.go (about)

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