Add option to also import OVF templates to the Content Library (#9755)
This commit is contained in:
parent
01d45d67c8
commit
a1524bf96a
|
@ -36,8 +36,8 @@ type Config struct {
|
|||
// Configuration for exporting VM to an ovf file.
|
||||
// The VM will not be exported if no [Export Configuration](#export-configuration) is specified.
|
||||
Export *common.ExportConfig `mapstructure:"export"`
|
||||
// Configuration for importing the VM template to a Content Library.
|
||||
// The VM template will not be imported if no [Content Library Import Configuration](#content-library-import-configuration) is specified.
|
||||
// Configuration for importing a VM template or OVF template to a Content Library.
|
||||
// The template will not be imported if no [Content Library Import Configuration](#content-library-import-configuration) is specified.
|
||||
// The import doesn't work if [convert_to_template](#convert_to_template) is set to true.
|
||||
ContentLibraryDestinationConfig *common.ContentLibraryDestinationConfig `mapstructure:"content_library_destination"`
|
||||
// Customize the cloned VM to configure host, network, or licensing settings. See the [customization options](#customization).
|
||||
|
|
|
@ -13,28 +13,41 @@ import (
|
|||
"github.com/vmware/govmomi/vapi/vcenter"
|
||||
)
|
||||
|
||||
// With this configuration Packer creates a library item in a content library whose content is a virtual machine template created from the just built VM.
|
||||
// The virtual machine template is stored in a newly created library item.
|
||||
// With this configuration Packer creates a library item in a content library whose content is a VM template
|
||||
// or an OVF template created from the just built VM.
|
||||
// The template is stored in a existing or newly created library item.
|
||||
type ContentLibraryDestinationConfig struct {
|
||||
// Name of the library in which the new library item containing the VM template should be created.
|
||||
// Name of the library in which the new library item containing the template should be created/updated.
|
||||
// The Content Library should be of type Local to allow deploying virtual machines.
|
||||
Library string `mapstructure:"library"`
|
||||
// Name of the library item that will be created. The name of the item should be different from [vm_name](#vm_name).
|
||||
// Defaults to [vm_name](#vm_name) + timestamp.
|
||||
// Name of the library item that will be created or updated.
|
||||
// For VM templates, the name of the item should be different from [vm_name](#vm_name) and
|
||||
// the default is [vm_name](#vm_name) + timestamp when not set. VM templates will be always imported to a new library item.
|
||||
// For OVF templates, the name defaults to [vm_name](#vm_name) when not set, and if an item with the same name already
|
||||
// exists it will be then updated with the new OVF template, otherwise a new item will be created.
|
||||
//
|
||||
// ~> **Note**: It's not possible to update existing library items with a new VM template. If updating an existing library
|
||||
// item is necessary, use an OVF template instead by setting the [ovf](#ovf) option as `true`.
|
||||
//
|
||||
Name string `mapstructure:"name"`
|
||||
// Description of the library item that will be created. Defaults to "Packer imported [vm_name](#vm_name) VM template".
|
||||
// Description of the library item that will be created.
|
||||
// This option is not used when importing OVF templates.
|
||||
// Defaults to "Packer imported [vm_name](#vm_name) VM template".
|
||||
Description string `mapstructure:"description"`
|
||||
// Cluster onto which the virtual machine template should be placed.
|
||||
// If cluster and resource_pool are both specified, resource_pool must belong to cluster.
|
||||
// If cluster and host are both specified, host must be a member of cluster.
|
||||
// This option is not used when importing OVF templates.
|
||||
// Defaults to [cluster](#cluster).
|
||||
Cluster string `mapstructure:"cluster"`
|
||||
// Virtual machine folder into which the virtual machine template should be placed.
|
||||
// This option is not used when importing OVF templates.
|
||||
// Defaults to the same folder as the source virtual machine.
|
||||
Folder string `mapstructure:"folder"`
|
||||
// Host onto which the virtual machine template should be placed.
|
||||
// If host and resource_pool are both specified, resource_pool must belong to host.
|
||||
// If host and cluster are both specified, host must be a member of cluster.
|
||||
// This option is not used when importing OVF templates.
|
||||
// Defaults to [host](#host).
|
||||
Host string `mapstructure:"host"`
|
||||
// Resource pool into which the virtual machine template should be placed.
|
||||
|
@ -42,10 +55,14 @@ type ContentLibraryDestinationConfig struct {
|
|||
// the system will attempt to choose a suitable resource pool for the virtual machine template.
|
||||
ResourcePool string `mapstructure:"resource_pool"`
|
||||
// The datastore for the virtual machine template's configuration and log files.
|
||||
// This option is not used when importing OVF templates.
|
||||
// Defaults to the storage backing associated with the library specified by library.
|
||||
Datastore string `mapstructure:"datastore"`
|
||||
// If set to true, the VM will be destroyed after deploying the template to the Content Library. Defaults to `false`.
|
||||
// If set to true, the VM will be destroyed after deploying the template to the Content Library.
|
||||
// Defaults to `false`.
|
||||
Destroy bool `mapstructure:"destroy"`
|
||||
// When set to true, Packer will import and OVF template to the content library item. Defaults to `false`.
|
||||
Ovf bool `mapstructure:"ovf"`
|
||||
}
|
||||
|
||||
func (c *ContentLibraryDestinationConfig) Prepare(lc *LocationConfig) []error {
|
||||
|
@ -54,31 +71,38 @@ func (c *ContentLibraryDestinationConfig) Prepare(lc *LocationConfig) []error {
|
|||
if c.Library == "" {
|
||||
errs = packer.MultiErrorAppend(errs, fmt.Errorf("a library name must be provided"))
|
||||
}
|
||||
if c.Name == lc.VMName {
|
||||
errs = packer.MultiErrorAppend(errs, fmt.Errorf("the content library destination name must be different from the VM name"))
|
||||
}
|
||||
|
||||
if c.Name == "" {
|
||||
// Add timestamp to the the name to differentiate from the original VM
|
||||
// otherwise vSphere won't be able to create the template which will be imported
|
||||
name, err := interpolate.Render(lc.VMName+"{{timestamp}}", nil)
|
||||
if err != nil {
|
||||
errs = packer.MultiErrorAppend(errs,
|
||||
fmt.Errorf("unable to parse content library VM template name: %s", err))
|
||||
if c.Ovf {
|
||||
if c.Name == "" {
|
||||
c.Name = lc.VMName
|
||||
}
|
||||
} else {
|
||||
if c.Name == lc.VMName {
|
||||
errs = packer.MultiErrorAppend(errs, fmt.Errorf("the content library destination name must be different from the VM name"))
|
||||
}
|
||||
|
||||
if c.Name == "" {
|
||||
// Add timestamp to the name to differentiate from the original VM
|
||||
// otherwise vSphere won't be able to create the template which will be imported
|
||||
name, err := interpolate.Render(lc.VMName+"{{timestamp}}", nil)
|
||||
if err != nil {
|
||||
errs = packer.MultiErrorAppend(errs,
|
||||
fmt.Errorf("unable to parse content library VM template name: %s", err))
|
||||
}
|
||||
c.Name = name
|
||||
}
|
||||
if c.Cluster == "" {
|
||||
c.Cluster = lc.Cluster
|
||||
}
|
||||
if c.Host == "" {
|
||||
c.Host = lc.Host
|
||||
}
|
||||
if c.ResourcePool == "" {
|
||||
c.ResourcePool = lc.ResourcePool
|
||||
}
|
||||
if c.Description == "" {
|
||||
c.Description = fmt.Sprintf("Packer imported %s VM template", lc.VMName)
|
||||
}
|
||||
c.Name = name
|
||||
}
|
||||
if c.Cluster == "" {
|
||||
c.Cluster = lc.Cluster
|
||||
}
|
||||
if c.Host == "" {
|
||||
c.Host = lc.Host
|
||||
}
|
||||
if c.ResourcePool == "" {
|
||||
c.ResourcePool = lc.ResourcePool
|
||||
}
|
||||
if c.Description == "" {
|
||||
c.Description = fmt.Sprintf("Packer imported %s VM template", lc.VMName)
|
||||
}
|
||||
|
||||
if errs != nil && len(errs.Errors) > 0 {
|
||||
|
@ -95,7 +119,42 @@ type StepImportToContentLibrary struct {
|
|||
func (s *StepImportToContentLibrary) Run(_ context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
vm := state.Get("vm").(*driver.VirtualMachine)
|
||||
var err error
|
||||
|
||||
if s.ContentLibConfig.Ovf {
|
||||
ui.Say(fmt.Sprintf("Importing VM OVF template %s to Content Library...", s.ContentLibConfig.Name))
|
||||
err = s.importOvfTemplate(vm)
|
||||
} else {
|
||||
ui.Say(fmt.Sprintf("Importing VM template %s to Content Library...", s.ContentLibConfig.Name))
|
||||
err = s.importVmTemplate(vm)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Failed to import template %s: %s", s.ContentLibConfig.Name, err.Error()))
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
if s.ContentLibConfig.Destroy {
|
||||
state.Put("destroy_vm", s.ContentLibConfig.Destroy)
|
||||
}
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (s *StepImportToContentLibrary) importOvfTemplate(vm *driver.VirtualMachine) error {
|
||||
ovf := vcenter.OVF{
|
||||
Spec: vcenter.CreateSpec{
|
||||
Name: s.ContentLibConfig.Name,
|
||||
},
|
||||
Target: vcenter.LibraryTarget{
|
||||
LibraryID: s.ContentLibConfig.Library,
|
||||
},
|
||||
}
|
||||
return vm.ImportOvfToContentLibrary(ovf)
|
||||
}
|
||||
|
||||
func (s *StepImportToContentLibrary) importVmTemplate(vm *driver.VirtualMachine) error {
|
||||
template := vcenter.Template{
|
||||
Name: s.ContentLibConfig.Name,
|
||||
Description: s.ContentLibConfig.Description,
|
||||
|
@ -114,19 +173,7 @@ func (s *StepImportToContentLibrary) Run(_ context.Context, state multistep.Stat
|
|||
}
|
||||
}
|
||||
|
||||
ui.Say(fmt.Sprintf("Importing VM template %s to Content Library...", s.ContentLibConfig.Name))
|
||||
err := vm.ImportToContentLibrary(template)
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Failed to import VM template %s: %s", s.ContentLibConfig.Name, err.Error()))
|
||||
state.Put("error", err)
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
if s.ContentLibConfig.Destroy {
|
||||
state.Put("destroy_vm", s.ContentLibConfig.Destroy)
|
||||
}
|
||||
|
||||
return multistep.ActionContinue
|
||||
return vm.ImportToContentLibrary(template)
|
||||
}
|
||||
|
||||
func (s *StepImportToContentLibrary) Cleanup(multistep.StateBag) {
|
||||
|
|
|
@ -18,6 +18,7 @@ type FlatContentLibraryDestinationConfig struct {
|
|||
ResourcePool *string `mapstructure:"resource_pool" cty:"resource_pool" hcl:"resource_pool"`
|
||||
Datastore *string `mapstructure:"datastore" cty:"datastore" hcl:"datastore"`
|
||||
Destroy *bool `mapstructure:"destroy" cty:"destroy" hcl:"destroy"`
|
||||
Ovf *bool `mapstructure:"ovf" cty:"ovf" hcl:"ovf"`
|
||||
}
|
||||
|
||||
// FlatMapstructure returns a new FlatContentLibraryDestinationConfig.
|
||||
|
@ -41,6 +42,7 @@ func (*FlatContentLibraryDestinationConfig) HCL2Spec() map[string]hcldec.Spec {
|
|||
"resource_pool": &hcldec.AttrSpec{Name: "resource_pool", Type: cty.String, Required: false},
|
||||
"datastore": &hcldec.AttrSpec{Name: "datastore", Type: cty.String, Required: false},
|
||||
"destroy": &hcldec.AttrSpec{Name: "destroy", Type: cty.Bool, Required: false},
|
||||
"ovf": &hcldec.AttrSpec{Name: "ovf", Type: cty.Bool, Required: false},
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package driver
|
||||
|
||||
import "github.com/vmware/govmomi/vapi/library"
|
||||
import (
|
||||
"github.com/vmware/govmomi/vapi/library"
|
||||
)
|
||||
|
||||
type Library struct {
|
||||
driver *Driver
|
||||
|
@ -18,3 +20,17 @@ func (d *Driver) FindContentLibrary(name string) (*Library, error) {
|
|||
driver: d,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *Driver) FindContentLibraryItem(libraryId string, name string) (*library.Item, error) {
|
||||
lm := library.NewManager(d.restClient)
|
||||
items, err := lm.GetLibraryItems(d.ctx, libraryId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, item := range items {
|
||||
if item.Name == name {
|
||||
return &item, nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
@ -683,17 +683,46 @@ func (vm *VirtualMachine) ConvertToTemplate() error {
|
|||
return vm.vm.MarkAsTemplate(vm.driver.ctx)
|
||||
}
|
||||
|
||||
func (vm *VirtualMachine) ImportToContentLibrary(template vcenter.Template) error {
|
||||
template.SourceVM = vm.vm.Reference().Value
|
||||
func (vm *VirtualMachine) ImportOvfToContentLibrary(ovf vcenter.OVF) error {
|
||||
l, err := vm.driver.FindContentLibrary(ovf.Target.LibraryID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if l.library.Type != "LOCAL" {
|
||||
return fmt.Errorf("can not deploy a VM to the content library %s of type %s; "+
|
||||
"the content library must be of type LOCAL", ovf.Target.LibraryID, l.library.Type)
|
||||
}
|
||||
|
||||
item, err := vm.driver.FindContentLibraryItem(l.library.ID, ovf.Spec.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if item != nil {
|
||||
// Updates existing library item
|
||||
ovf.Target.LibraryItemID = item.ID
|
||||
}
|
||||
|
||||
ovf.Target.LibraryID = l.library.ID
|
||||
ovf.Source.Value = vm.vm.Reference().Value
|
||||
ovf.Source.Type = "VirtualMachine"
|
||||
|
||||
vcm := vcenter.NewManager(vm.driver.restClient)
|
||||
_, err = vcm.CreateOVF(vm.driver.ctx, ovf)
|
||||
return err
|
||||
}
|
||||
|
||||
func (vm *VirtualMachine) ImportToContentLibrary(template vcenter.Template) error {
|
||||
l, err := vm.driver.FindContentLibrary(template.Library)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if l.library.Type != "LOCAL" {
|
||||
return fmt.Errorf("can not deploy a VM to the content library %s of type %s; the content library must be of type LOCAL", template.Library, l.library.Type)
|
||||
return fmt.Errorf("can not deploy a VM to the content library %s of type %s; "+
|
||||
"the content library must be of type LOCAL", template.Library, l.library.Type)
|
||||
}
|
||||
|
||||
template.Library = l.library.ID
|
||||
template.SourceVM = vm.vm.Reference().Value
|
||||
|
||||
if template.Placement.Cluster != "" {
|
||||
c, err := vm.driver.FindCluster(template.Placement.Cluster)
|
||||
|
|
2
go.mod
2
go.mod
|
@ -130,7 +130,7 @@ require (
|
|||
github.com/ufilesdk-dev/ufile-gosdk v0.0.0-20190830075812-b4dbc4ef43a6
|
||||
github.com/ugorji/go v0.0.0-20151218193438-646ae4a518c1
|
||||
github.com/ulikunitz/xz v0.5.5
|
||||
github.com/vmware/govmomi v0.22.2
|
||||
github.com/vmware/govmomi v0.23.1
|
||||
github.com/xanzy/go-cloudstack v0.0.0-20190526095453-42f262b63ed0
|
||||
github.com/yandex-cloud/go-genproto v0.0.0-20200608085315-d6e7ef5ceb97
|
||||
github.com/yandex-cloud/go-sdk v0.0.0-20200610100221-ae86895efb97
|
||||
|
|
3
go.sum
3
go.sum
|
@ -612,6 +612,9 @@ github.com/vmihailenco/msgpack v3.3.3+incompatible h1:wapg9xDUZDzGCNFlwc5SqI1rvc
|
|||
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
|
||||
github.com/vmware/govmomi v0.22.2 h1:hmLv4f+RMTTseqtJRijjOWzwELiaLMIoHv2D6H3bF4I=
|
||||
github.com/vmware/govmomi v0.22.2/go.mod h1:Y+Wq4lst78L85Ge/F8+ORXIWiKYqaro1vhAulACy9Lc=
|
||||
github.com/vmware/govmomi v0.23.0/go.mod h1:Y+Wq4lst78L85Ge/F8+ORXIWiKYqaro1vhAulACy9Lc=
|
||||
github.com/vmware/govmomi v0.23.1 h1:vU09hxnNR/I7e+4zCJvW+5vHu5dO64Aoe2Lw7Yi/KRg=
|
||||
github.com/vmware/govmomi v0.23.1/go.mod h1:Y+Wq4lst78L85Ge/F8+ORXIWiKYqaro1vhAulACy9Lc=
|
||||
github.com/vmware/vmw-guestinfo v0.0.0-20170707015358-25eff159a728/go.mod h1:x9oS4Wk2s2u4tS29nEaDLdzvuHdB19CvSGJjPgkZJNk=
|
||||
github.com/xanzy/go-cloudstack v0.0.0-20190526095453-42f262b63ed0 h1:NJrcIkdzq0C3I8ypAZwFE9RHtGbfp+mJvqIcoFATZuk=
|
||||
github.com/xanzy/go-cloudstack v0.0.0-20190526095453-42f262b63ed0/go.mod h1:sBh287mCRwCz6zyXHMmw7sSZGPohVpnx+o+OY4M+i3A=
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
Amanda H. L. de Andrade <amanda.andrade@serpro.gov.br> amandahla <amanda.andrade@serpro.gov.br>
|
||||
Amanda H. L. de Andrade <amanda.andrade@serpro.gov.br> Amanda Hager Lopes de Andrade Katz <amanda.katz@serpro.gov.br>
|
||||
Amanda H. L. de Andrade <amanda.andrade@serpro.gov.br> amandahla <amanda.andrade@serpro.gov.br>
|
||||
Amit Bathla <abathla@.vmware.com> <abathla@promb-1s-dhcp216.eng.vmware.com>
|
||||
Andrew Kutz <akutz@vmware.com> akutz <akutz@vmware.com>
|
||||
Andrew Kutz <akutz@vmware.com> <sakutz@gmail.com>
|
||||
Andrew Kutz <akutz@vmware.com> Andrew Kutz <101085+akutz@users.noreply.github.com>
|
||||
Andrew Kutz <akutz@vmware.com> akutz <akutz@vmware.com>
|
||||
Anfernee Yongkun Gui <agui@vmware.com> <anfernee.gui@gmail.com>
|
||||
Anfernee Yongkun Gui <agui@vmware.com> Yongkun Anfernee Gui <agui@vmware.com>
|
||||
Anna Carrigan <anna.carrigan@hpe.com> Anna <anna.carrigan@outlook.com>
|
||||
Balu Dontu <bdontu@vmware.com> BaluDontu <bdontu@vmware.com>
|
||||
Bruce Downs <bruceadowns@gmail.com> <bdowns@vmware.com>
|
||||
Bruce Downs <bruceadowns@gmail.com> <bruce.downs@jivesoftware.com>
|
||||
Bruce Downs <bruceadowns@gmail.com> <bruce.downs@autodesk.com>
|
||||
Bruce Downs <bruceadowns@gmail.com> <bruce.downs@jivesoftware.com>
|
||||
Clint Greenwood <cgreenwood@vmware.com> <clint.greenwood@gmail.com>
|
||||
Cédric Blomart <cblomart@gmail.com> <cedric.blomart@minfin.fed.be>
|
||||
Cédric Blomart <cblomart@gmail.com> cedric <cblomart@gmail.com>
|
||||
|
@ -14,17 +18,18 @@ David Stark <dave@davidstark.name> <david.stark@bskyb.com>
|
|||
Eric Gray <egray@vmware.com> <ericgray@users.noreply.github.com>
|
||||
Eric Yutao <eric.yutao@gmail.com> eric <eric.yutao@gmail.com>
|
||||
Fabio Rapposelli <fabio@vmware.com> <fabio@rapposelli.org>
|
||||
Faiyaz Ahmed <faiyaza@vmware.com> Faiyaz Ahmed <ahmedf@vmware.com>
|
||||
Faiyaz Ahmed <faiyaza@vmware.com> Faiyaz Ahmed <faiyaza@gmail.com>
|
||||
Faiyaz Ahmed <faiyaza@vmware.com> Faiyaz Ahmed <fdawg4l@users.noreply.github.com>
|
||||
Henrik Hodne <henrik@travis-ci.com> <henrik@hodne.io>
|
||||
Jeremy Canady <jcanady@jackhenry.com> <jcanady@gmail.com>
|
||||
Jiatong Wang <wjiatong@vmware.com> jiatongw <wjiatong@vmware.com>
|
||||
Lintong Jiang <lintongj@vmware.com> lintongj <55512168+lintongj@users.noreply.github.com>
|
||||
Pieter Noordhuis <pnoordhuis@vmware.com> <pcnoordhuis@gmail.com>
|
||||
Takaaki Furukawa <takaaki.frkw@gmail.com> takaaki.furukawa <takaaki.furukawa@mail.rakuten.com>
|
||||
Takaaki Furukawa <takaaki.frkw@gmail.com> tkak <takaaki.frkw@gmail.com>
|
||||
Vadim Egorov <vegorov@vmware.com> <egorovv@gmail.com>
|
||||
Anfernee Yongkun Gui <agui@vmware.com> <anfernee.gui@gmail.com>
|
||||
Anfernee Yongkun Gui <agui@vmware.com> Yongkun Anfernee Gui <agui@vmware.com>
|
||||
Zach Tucker <ztucker@vmware.com> <jzt@users.noreply.github.com>
|
||||
Zee Yang <zeey@vmware.com> <zee.yang@gmail.com>
|
||||
Jiatong Wang <wjiatong@vmware.com> jiatongw <wjiatong@vmware.com>
|
||||
Uwe Bessle <Uwe.Bessle@iteratec.de> Uwe Bessle <u.bessle.extern@eos-ts.com>
|
||||
Uwe Bessle <Uwe.Bessle@iteratec.de> Uwe Bessle <uwe.bessle@web.de>
|
||||
Lintong Jiang <lintongj@vmware.com> lintongj <55512168+lintongj@users.noreply.github.com>
|
||||
Vadim Egorov <vegorov@vmware.com> <egorovv@gmail.com>
|
||||
Zach Tucker <ztucker@vmware.com> <jzt@users.noreply.github.com>
|
||||
Zee Yang <zeey@vmware.com> <zee.yang@gmail.com>
|
||||
|
|
|
@ -12,7 +12,7 @@ services: false
|
|||
|
||||
# Set the version of Go.
|
||||
language: go
|
||||
go: 1.13
|
||||
go: 1.14
|
||||
|
||||
# Always set the project's Go import path to ensure that forked
|
||||
# builds get cloned to the correct location.
|
||||
|
|
|
@ -1,5 +1,27 @@
|
|||
# changelog
|
||||
|
||||
### 0.23.0 (2020-06-11)
|
||||
|
||||
* Finder: support DistributedVirtualSwitch traversal
|
||||
|
||||
* Update to vSphere 7 APIs
|
||||
|
||||
* Avoid possible nil pointer dereference in guest TransferURL
|
||||
|
||||
* Refactor govc session persistence into session/cache package
|
||||
|
||||
* Add SetTaskState SetTaskDescription UpdateProgress to object package
|
||||
|
||||
* Add Content Library subscriptions support
|
||||
|
||||
* Add Content Library item copy support
|
||||
|
||||
* Sync vim25/xml with golang 1.13 encoding/xml
|
||||
|
||||
* vapi: Add cluster modules client and simulator
|
||||
|
||||
* Expose soap client default transport
|
||||
|
||||
### 0.22.1 (2020-01-13)
|
||||
|
||||
* Fix SAML token auth using Holder-of-Key with delegated Bearer identity against 6.7 U3b+
|
||||
|
|
|
@ -96,6 +96,9 @@ We follow the conventions on [How to Write a Git Commit Message](http://chris.be
|
|||
|
||||
Be sure to include any related GitHub issue references in the commit message.
|
||||
|
||||
### Running CI checks and tests
|
||||
You can run both `make check` and `make test` from the top level of the repository. While `make check` will catch formatting and import errors, it will not apply any fixes. The developer is expected to do that.
|
||||
|
||||
## Reporting Bugs and Creating Issues
|
||||
|
||||
When opening a new issue, try to roughly follow the commit message format conventions above.
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
Abhijeet Kasurde <akasurde@redhat.com>
|
||||
abrarshivani <abrarshivani@users.noreply.github.com>
|
||||
Adam Shannon <adamkshannon@gmail.com>
|
||||
Al Biheiri <abiheiri@apple.com>
|
||||
Alessandro Cortiana <alessandro.cortiana@gmail.com>
|
||||
Alex Bozhenko <alexbozhenko@fb.com>
|
||||
Alex Ellis (VMware) <alexellis2@gmail.com>
|
||||
|
@ -21,6 +22,8 @@ Andrey Klimentyev <andrey.klimentyev@flant.com>
|
|||
Anfernee Yongkun Gui <agui@vmware.com>
|
||||
angystardust <angystardust@users.noreply.github.com>
|
||||
aniketGslab <aniket.shinde@gslab.com>
|
||||
Ankit Vaidya <vaidyaa@vmware.com>
|
||||
Anna Carrigan <anna.carrigan@hpe.com>
|
||||
Arran Walker <arran.walker@zopa.com>
|
||||
Artem Anisimov <aanisimov@inbox.ru>
|
||||
Aryeh Weinreb <aryehweinreb@gmail.com>
|
||||
|
@ -28,26 +31,33 @@ Austin Parker <aparker@apprenda.com>
|
|||
Balu Dontu <bdontu@vmware.com>
|
||||
bastienbc <bastien.barbe.creuly@gmail.com>
|
||||
Ben Corrie <bcorrie@vmware.com>
|
||||
Benjamin Davini <davinib@vmware.com>
|
||||
Benjamin Peterson <benjamin@python.org>
|
||||
Bob Killen <killen.bob@gmail.com>
|
||||
Brad Fitzpatrick <bradfitz@golang.org>
|
||||
Bruce Downs <bruceadowns@gmail.com>
|
||||
Cédric Blomart <cblomart@gmail.com>
|
||||
Cheng Cheng <chengch@vmware.com>
|
||||
Chethan Venkatesh <chethanv@vmware.com>
|
||||
Chris Marchesi <chrism@vancluevertech.com>
|
||||
Christian Höltje <docwhat@gerf.org>
|
||||
Clint Greenwood <cgreenwood@vmware.com>
|
||||
CuiHaozhi <cuihaozhi@chinacloud.com.cn>
|
||||
Daniel Mueller <deso@posteo.net>
|
||||
Dan Ilan <danilan@google.com>
|
||||
Danny Lockard <danny.lockard@banno.com>
|
||||
Dave Gress <gressd@vmware.com>
|
||||
Dave Smith-Uchida <dsmithuchida@vmware.com>
|
||||
Dave Tucker <dave@dtucker.co.uk>
|
||||
Davide Agnello <dagnello@hp.com>
|
||||
David Gress <gressd@vmware.com>
|
||||
David Stark <dave@davidstark.name>
|
||||
Davinder Kumar <davinderk@vmware.com>
|
||||
demarey <christophe.demarey@inria.fr>
|
||||
dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
|
||||
Deric Crago <deric.crago@gmail.com>
|
||||
Divyen Patel <divyenp@vmware.com>
|
||||
Dnyanesh Gate <dnyanesh.gate@druva.com>
|
||||
Doug MacEachern <dougm@vmware.com>
|
||||
Eloy Coto <eloy.coto@gmail.com>
|
||||
Eric Edens <ericedens@google.com>
|
||||
|
@ -56,8 +66,10 @@ Eric Gray <egray@vmware.com>
|
|||
Eric Yutao <eric.yutao@gmail.com>
|
||||
Erik Hollensbe <github@hollensbe.org>
|
||||
Ethan Kaley <ethan.kaley@emc.com>
|
||||
Evan Chu <echu@vmware.com>
|
||||
Fabio Rapposelli <fabio@vmware.com>
|
||||
Faiyaz Ahmed <ahmedf@vmware.com>
|
||||
Faiyaz Ahmed <faiyaza@vmware.com>
|
||||
Federico Pellegatta <12744504+federico-pellegatta@users.noreply.github.com>
|
||||
forkbomber <forkbomber@users.noreply.github.com>
|
||||
François Rigault <rigault.francois@gmail.com>
|
||||
freebsdly <qinhuajun@outlook.com>
|
||||
|
@ -86,6 +98,7 @@ kayrus <kay.diam@gmail.com>
|
|||
Kevin George <georgek@vmware.com>
|
||||
leslie-qiwa <leslie.qiwa@gmail.com>
|
||||
Lintong Jiang <lintongj@vmware.com>
|
||||
Liping Xue <lipingx@vmware.com>
|
||||
Louie Jiang <jiangl@vmware.com>
|
||||
Luther Monson <luther.monson@gmail.com>
|
||||
maplain <fangyuanl@vmware.com>
|
||||
|
@ -97,6 +110,7 @@ Mario Trangoni <mjtrangoni@gmail.com>
|
|||
Mark Peek <markpeek@vmware.com>
|
||||
Matt Clay <matt@mystile.com>
|
||||
Matthew Cosgrove <matthew.cosgrove@dell.com>
|
||||
Matt Moore <mattmoor@vmware.com>
|
||||
Matt Moriarity <matt@mattmoriarity.com>
|
||||
Mevan Samaratunga <mevansam@gmail.com>
|
||||
Michal Jankowski <mjankowski@vmware.com>
|
||||
|
@ -109,15 +123,20 @@ Pieter Noordhuis <pnoordhuis@vmware.com>
|
|||
prydin <prydin@vmware.com>
|
||||
rHermes <teodor_spaeren@riseup.net>
|
||||
Rowan Jacobs <rojacobs@pivotal.io>
|
||||
rsikdar <rsikdar@berkeley.edu>
|
||||
runner.mei <runner.mei@gmail.com>
|
||||
Sandeep Pissay Srinivasa Rao <ssrinivas@vmware.com>
|
||||
S.Çağlar Onur <conur@vmware.com>
|
||||
Sergey Ignatov <sergey.ignatov@jetbrains.com>
|
||||
serokles <timbo.alexander@gmail.com>
|
||||
Shalini Bhaskara <sbhaskara@vmware.com>
|
||||
Shawn Neal <sneal@sneal.net>
|
||||
shylasrinivas <sshyla@vmware.com>
|
||||
sky-joker <sky.jokerxx@gmail.com>
|
||||
Sten Feldman <exile@chamber.ee>
|
||||
Stepan Mazurov <smazurov@gmail.com>
|
||||
Steve Purcell <steve@sanityinc.com>
|
||||
SUMIT AGRAWAL <asumit@vmware.com>
|
||||
Takaaki Furukawa <takaaki.frkw@gmail.com>
|
||||
Tamas Eger <tamas.eger@bitrise.io>
|
||||
tanishi <tanishi503@gmail.com>
|
||||
|
@ -128,13 +147,19 @@ Tim McNamara <tim.mcnamara@canonical.com>
|
|||
Tjeu Kayim <15987676+TjeuKayim@users.noreply.github.com>
|
||||
Toomas Pelberg <toomas.pelberg@playtech.com>
|
||||
Trevor Dawe <trevor.dawe@gmail.com>
|
||||
tshihad <tshihad9@gmail.com>
|
||||
Uwe Bessle <Uwe.Bessle@iteratec.de>
|
||||
Vadim Egorov <vegorov@vmware.com>
|
||||
Vikram Krishnamurthy <vikramkrishnamu@vmware.com>
|
||||
volanja <volaaanja@gmail.com>
|
||||
Volodymyr Bobyr <pupsua@gmail.com>
|
||||
Waldek Maleska <w.maleska@gmail.com>
|
||||
William Lam <info.virtuallyghetto@gmail.com>
|
||||
Witold Krecicki <wpk@culm.net>
|
||||
xing-yang <xingyang105@gmail.com>
|
||||
yangxi <yangxi@vmware.com>
|
||||
Yang Yang <yangy@vmware.com>
|
||||
Yann Hodique <yhodique@google.com>
|
||||
ykakarap <yuva2811@gmail.com>
|
||||
Yuya Kusakabe <yuya.kusakabe@gmail.com>
|
||||
Zacharias Taubert <zacharias.taubert@gmail.com>
|
||||
|
|
|
@ -9,6 +9,7 @@ goimports:
|
|||
@echo checking go imports...
|
||||
@command -v goimports >/dev/null 2>&1 || $(GO) get golang.org/x/tools/cmd/goimports
|
||||
@! goimports -d . 2>&1 | egrep -v '^$$'
|
||||
@! TERM=xterm git grep encoding/xml -- '*.go' ':!vim25/xml/*.go'
|
||||
|
||||
govet:
|
||||
@echo checking go vet...
|
||||
|
|
|
@ -15,9 +15,9 @@ In addition to the vSphere API client, this repository includes:
|
|||
|
||||
## Compatibility
|
||||
|
||||
This library is built for and tested against ESXi and vCenter 6.0, 6.5 and 6.7.
|
||||
This library is built for and tested against ESXi and vCenter 6.5, 6.7 and 7.0.
|
||||
|
||||
It may work with versions 5.5 and 5.1, but neither are officially supported.
|
||||
It may work with versions 5.1, 5.5 and 6.0, but neither are officially supported.
|
||||
|
||||
## Documentation
|
||||
|
||||
|
@ -28,7 +28,7 @@ The code in the `govmomi` package is a wrapper for the code that is generated fr
|
|||
It primarily provides convenience functions for working with the vSphere API.
|
||||
See [godoc.org][godoc] for documentation.
|
||||
|
||||
[apiref]:https://code.vmware.com/apis/196/vsphere
|
||||
[apiref]:https://code.vmware.com/apis/968/vsphere
|
||||
[godoc]:http://godoc.org/github.com/vmware/govmomi
|
||||
|
||||
## Installation
|
||||
|
@ -85,12 +85,24 @@ Refer to the [CHANGELOG](CHANGELOG.md) for version to version changes.
|
|||
|
||||
* [Juju](https://github.com/juju/juju)
|
||||
|
||||
* [vSphere 7.0](https://docs.vmware.com/en/VMware-vSphere/7.0/rn/vsphere-esxi-vcenter-server-7-vsphere-with-kubernetes-release-notes.html)
|
||||
|
||||
* [OPS](https://github.com/nanovms/ops)
|
||||
|
||||
## Related projects
|
||||
|
||||
* [rbvmomi](https://github.com/vmware/rbvmomi)
|
||||
|
||||
* [pyvmomi](https://github.com/vmware/pyvmomi)
|
||||
|
||||
* [go-vmware-nsxt](https://github.com/vmware/go-vmware-nsxt)
|
||||
|
||||
## License
|
||||
|
||||
govmomi is available under the [Apache 2 license](LICENSE.txt).
|
||||
|
||||
## Name
|
||||
|
||||
Pronounced "go-v-mom-ie"
|
||||
|
||||
Follows pyvmomi and rbvmomi: language prefix + the vSphere acronym "VM Object Management Infrastructure".
|
||||
|
|
|
@ -165,6 +165,8 @@ func (l Lister) List(ctx context.Context) ([]Element, error) {
|
|||
return l.ListHostSystem(ctx)
|
||||
case "VirtualApp":
|
||||
return l.ListVirtualApp(ctx)
|
||||
case "VmwareDistributedVirtualSwitch", "DistributedVirtualSwitch":
|
||||
return l.ListDistributedVirtualSwitch(ctx)
|
||||
default:
|
||||
return nil, fmt.Errorf("cannot traverse type " + l.Reference.Type)
|
||||
}
|
||||
|
@ -497,6 +499,69 @@ func (l Lister) ListHostSystem(ctx context.Context) ([]Element, error) {
|
|||
return es, nil
|
||||
}
|
||||
|
||||
func (l Lister) ListDistributedVirtualSwitch(ctx context.Context) ([]Element, error) {
|
||||
ospec := types.ObjectSpec{
|
||||
Obj: l.Reference,
|
||||
Skip: types.NewBool(true),
|
||||
}
|
||||
|
||||
fields := []string{
|
||||
"portgroup",
|
||||
}
|
||||
|
||||
for _, f := range fields {
|
||||
tspec := types.TraversalSpec{
|
||||
Path: f,
|
||||
Skip: types.NewBool(false),
|
||||
Type: "DistributedVirtualSwitch",
|
||||
}
|
||||
|
||||
ospec.SelectSet = append(ospec.SelectSet, &tspec)
|
||||
}
|
||||
|
||||
childTypes := []string{
|
||||
"DistributedVirtualPortgroup",
|
||||
}
|
||||
|
||||
var pspecs []types.PropertySpec
|
||||
for _, t := range childTypes {
|
||||
pspec := types.PropertySpec{
|
||||
Type: t,
|
||||
}
|
||||
|
||||
if l.All {
|
||||
pspec.All = types.NewBool(true)
|
||||
} else {
|
||||
pspec.PathSet = []string{"name"}
|
||||
}
|
||||
|
||||
pspecs = append(pspecs, pspec)
|
||||
}
|
||||
|
||||
req := types.RetrieveProperties{
|
||||
SpecSet: []types.PropertyFilterSpec{
|
||||
{
|
||||
ObjectSet: []types.ObjectSpec{ospec},
|
||||
PropSet: pspecs,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var dst []interface{}
|
||||
|
||||
err := l.retrieveProperties(ctx, req, &dst)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
es := []Element{}
|
||||
for _, v := range dst {
|
||||
es = append(es, ToElement(v.(mo.Reference), l.Prefix))
|
||||
}
|
||||
|
||||
return es, nil
|
||||
}
|
||||
|
||||
func (l Lister) ListVirtualApp(ctx context.Context) ([]Element, error) {
|
||||
ospec := types.ObjectSpec{
|
||||
Obj: l.Reference,
|
||||
|
|
|
@ -25,7 +25,6 @@ import (
|
|||
"github.com/vmware/govmomi/property"
|
||||
"github.com/vmware/govmomi/vim25"
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
|
@ -75,29 +74,22 @@ func (c *Common) SetInventoryPath(p string) {
|
|||
c.InventoryPath = p
|
||||
}
|
||||
|
||||
// ObjectName returns the base name of the InventoryPath field if set,
|
||||
// otherwise fetches the mo.ManagedEntity.Name field via the property collector.
|
||||
// ObjectName fetches the mo.ManagedEntity.Name field via the property collector.
|
||||
func (c Common) ObjectName(ctx context.Context) (string, error) {
|
||||
var o mo.ManagedEntity
|
||||
var content []types.ObjectContent
|
||||
|
||||
err := c.Properties(ctx, c.Reference(), []string{"name"}, &o)
|
||||
err := c.Properties(ctx, c.Reference(), []string{"name"}, &content)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if o.Name != "" {
|
||||
return o.Name, nil
|
||||
for i := range content {
|
||||
for _, prop := range content[i].PropSet {
|
||||
return prop.Val.(string), nil
|
||||
}
|
||||
}
|
||||
|
||||
// Network has its own "name" field...
|
||||
var n mo.Network
|
||||
|
||||
err = c.Properties(ctx, c.Reference(), []string{"name"}, &n)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return n.Name, nil
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Properties is a wrapper for property.DefaultCollector().RetrieveOne()
|
||||
|
|
|
@ -20,7 +20,6 @@ import (
|
|||
"context"
|
||||
|
||||
"github.com/vmware/govmomi/vim25"
|
||||
"github.com/vmware/govmomi/vim25/mo"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
|
@ -40,19 +39,14 @@ func (n Network) GetInventoryPath() string {
|
|||
|
||||
// EthernetCardBackingInfo returns the VirtualDeviceBackingInfo for this Network
|
||||
func (n Network) EthernetCardBackingInfo(ctx context.Context) (types.BaseVirtualDeviceBackingInfo, error) {
|
||||
var e mo.Network
|
||||
|
||||
// Use Network.Name rather than Common.Name as the latter does not return the complete name if it contains a '/'
|
||||
// We can't use Common.ObjectName here either as we need the ManagedEntity.Name field is not set since mo.Network
|
||||
// has its own Name field.
|
||||
err := n.Properties(ctx, n.Reference(), []string{"name"}, &e)
|
||||
name, err := n.ObjectName(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
backing := &types.VirtualEthernetCardNetworkBackingInfo{
|
||||
VirtualDeviceDeviceBackingInfo: types.VirtualDeviceDeviceBackingInfo{
|
||||
DeviceName: e.Name,
|
||||
DeviceName: name,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -41,17 +41,11 @@ func (n OpaqueNetwork) GetInventoryPath() string {
|
|||
|
||||
// EthernetCardBackingInfo returns the VirtualDeviceBackingInfo for this Network
|
||||
func (n OpaqueNetwork) EthernetCardBackingInfo(ctx context.Context) (types.BaseVirtualDeviceBackingInfo, error) {
|
||||
var net mo.OpaqueNetwork
|
||||
|
||||
if err := n.Properties(ctx, n.Reference(), []string{"summary"}, &net); err != nil {
|
||||
summary, err := n.Summary(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
summary, ok := net.Summary.(*types.OpaqueNetworkSummary)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%s unsupported network type: %T", n, net.Summary)
|
||||
}
|
||||
|
||||
backing := &types.VirtualEthernetCardOpaqueNetworkBackingInfo{
|
||||
OpaqueNetworkId: summary.OpaqueNetworkId,
|
||||
OpaqueNetworkType: summary.OpaqueNetworkType,
|
||||
|
@ -59,3 +53,20 @@ func (n OpaqueNetwork) EthernetCardBackingInfo(ctx context.Context) (types.BaseV
|
|||
|
||||
return backing, nil
|
||||
}
|
||||
|
||||
// Summary returns the mo.OpaqueNetwork.Summary property
|
||||
func (n OpaqueNetwork) Summary(ctx context.Context) (*types.OpaqueNetworkSummary, error) {
|
||||
var props mo.OpaqueNetwork
|
||||
|
||||
err := n.Properties(ctx, n.Reference(), []string{"summary"}, &props)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
summary, ok := props.Summary.(*types.OpaqueNetworkSummary)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%s unsupported network summary type: %T", n, props.Summary)
|
||||
}
|
||||
|
||||
return summary, nil
|
||||
}
|
||||
|
|
|
@ -64,3 +64,37 @@ func (t *Task) Cancel(ctx context.Context) error {
|
|||
|
||||
return err
|
||||
}
|
||||
|
||||
// SetState sets task state and optionally sets results or fault, as appropriate for state.
|
||||
func (t *Task) SetState(ctx context.Context, state types.TaskInfoState, result types.AnyType, fault *types.LocalizedMethodFault) error {
|
||||
req := types.SetTaskState{
|
||||
This: t.Reference(),
|
||||
State: state,
|
||||
Result: result,
|
||||
Fault: fault,
|
||||
}
|
||||
_, err := methods.SetTaskState(ctx, t.Common.Client(), &req)
|
||||
return err
|
||||
}
|
||||
|
||||
// SetDescription updates task description to describe the current phase of the task.
|
||||
func (t *Task) SetDescription(ctx context.Context, description types.LocalizableMessage) error {
|
||||
req := types.SetTaskDescription{
|
||||
This: t.Reference(),
|
||||
Description: description,
|
||||
}
|
||||
_, err := methods.SetTaskDescription(ctx, t.Common.Client(), &req)
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateProgress Sets percentage done for this task and recalculates overall percentage done.
|
||||
// If a percentDone value of less than zero or greater than 100 is specified,
|
||||
// a value of zero or 100 respectively is used.
|
||||
func (t *Task) UpdateProgress(ctx context.Context, percentDone int) error {
|
||||
req := types.UpdateProgress{
|
||||
This: t.Reference(),
|
||||
PercentDone: int32(percentDone),
|
||||
}
|
||||
_, err := methods.UpdateProgress(ctx, t.Common.Client(), &req)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -855,8 +855,10 @@ func (v VirtualMachine) UUID(ctx context.Context) string {
|
|||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return o.Config.Uuid
|
||||
if o.Config != nil {
|
||||
return o.Config.Uuid
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (v VirtualMachine) QueryChangedDiskAreas(ctx context.Context, baseSnapshot, curSnapshot *types.ManagedObjectReference, disk *types.VirtualDisk, offset int64) (types.DiskChangeInfo, error) {
|
||||
|
|
|
@ -143,7 +143,7 @@ func (p *Collector) Retrieve(ctx context.Context, objs []types.ManagedObjectRefe
|
|||
spec := types.PropertySpec{
|
||||
Type: obj.Type,
|
||||
}
|
||||
if ps == nil {
|
||||
if len(ps) == 0 {
|
||||
spec.All = types.NewBool(true)
|
||||
} else {
|
||||
spec.PathSet = ps
|
||||
|
|
|
@ -42,6 +42,9 @@ func (f Filter) Keys() []string {
|
|||
|
||||
// MatchProperty returns true if a Filter entry matches the given prop.
|
||||
func (f Filter) MatchProperty(prop types.DynamicProperty) bool {
|
||||
if prop.Val == nil {
|
||||
return false
|
||||
}
|
||||
match, ok := f[prop.Name]
|
||||
if !ok {
|
||||
return false
|
||||
|
@ -74,7 +77,7 @@ func (f Filter) MatchProperty(prop types.DynamicProperty) bool {
|
|||
}
|
||||
|
||||
// convert if we can
|
||||
switch prop.Val.(type) {
|
||||
switch val := prop.Val.(type) {
|
||||
case bool:
|
||||
match, _ = strconv.ParseBool(s)
|
||||
case int16:
|
||||
|
@ -91,7 +94,9 @@ func (f Filter) MatchProperty(prop types.DynamicProperty) bool {
|
|||
case float64:
|
||||
match, _ = strconv.ParseFloat(s, 64)
|
||||
case fmt.Stringer:
|
||||
prop.Val = prop.Val.(fmt.Stringer).String()
|
||||
prop.Val = val.String()
|
||||
case *types.CustomFieldStringValue:
|
||||
prop.Val = fmt.Sprintf("%d:%s", val.Key, val.Value)
|
||||
default:
|
||||
if ptype.Kind() != reflect.String {
|
||||
return false
|
||||
|
|
|
@ -29,6 +29,7 @@ type WaitFilter struct {
|
|||
types.CreateFilter
|
||||
Options *types.WaitOptions
|
||||
PropagateMissing bool
|
||||
Truncated bool
|
||||
}
|
||||
|
||||
// Add a new ObjectSpec and PropertySpec to the WaitFilter
|
||||
|
@ -127,6 +128,10 @@ func WaitForUpdates(ctx context.Context, c *Collector, filter *WaitFilter, f fun
|
|||
}
|
||||
|
||||
req.Version = set.Version
|
||||
filter.Truncated = false
|
||||
if set.Truncated != nil {
|
||||
filter.Truncated = *set.Truncated
|
||||
}
|
||||
|
||||
for _, fs := range set.FilterSet {
|
||||
if filter.PropagateMissing {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2015,2019 VMware, Inc. All Rights Reserved.
|
||||
Copyright (c) 2015-2020 VMware, Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -17,115 +17,24 @@ limitations under the License.
|
|||
package session
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/session/keepalive"
|
||||
"github.com/vmware/govmomi/vim25/soap"
|
||||
)
|
||||
|
||||
type keepAlive struct {
|
||||
sync.Mutex
|
||||
|
||||
roundTripper soap.RoundTripper
|
||||
idleTime time.Duration
|
||||
notifyRequest chan struct{}
|
||||
notifyStop chan struct{}
|
||||
notifyWaitGroup sync.WaitGroup
|
||||
|
||||
// keepAlive executes a request in the background with the purpose of
|
||||
// keeping the session active. The response for this request is discarded.
|
||||
keepAlive func(soap.RoundTripper) error
|
||||
}
|
||||
|
||||
func defaultKeepAlive(roundTripper soap.RoundTripper) error {
|
||||
_, err := methods.GetCurrentTime(context.Background(), roundTripper)
|
||||
return err
|
||||
}
|
||||
|
||||
// KeepAlive wraps the specified soap.RoundTripper and executes a meaningless
|
||||
// API request in the background after the RoundTripper has been idle for the
|
||||
// specified amount of idle time. The keep alive process only starts once a
|
||||
// user logs in and runs until the user logs out again.
|
||||
// KeepAlive is a backward compatible wrapper around KeepAliveHandler.
|
||||
func KeepAlive(roundTripper soap.RoundTripper, idleTime time.Duration) soap.RoundTripper {
|
||||
return KeepAliveHandler(roundTripper, idleTime, defaultKeepAlive)
|
||||
return KeepAliveHandler(roundTripper, idleTime, nil)
|
||||
}
|
||||
|
||||
// KeepAliveHandler works as KeepAlive() does, but the handler param can decide how to handle errors.
|
||||
// For example, if connectivity to ESX/VC is down long enough for a session to expire, a handler can choose to
|
||||
// Login() on a types.NotAuthenticated error. If handler returns non-nil, the keep alive go routine will be stopped.
|
||||
// KeepAliveHandler is a backward compatible wrapper around keepalive.NewHandlerSOAP.
|
||||
func KeepAliveHandler(roundTripper soap.RoundTripper, idleTime time.Duration, handler func(soap.RoundTripper) error) soap.RoundTripper {
|
||||
k := &keepAlive{
|
||||
roundTripper: roundTripper,
|
||||
idleTime: idleTime,
|
||||
notifyRequest: make(chan struct{}),
|
||||
}
|
||||
|
||||
k.keepAlive = handler
|
||||
|
||||
return k
|
||||
}
|
||||
|
||||
func (k *keepAlive) start() {
|
||||
k.Lock()
|
||||
defer k.Unlock()
|
||||
|
||||
if k.notifyStop != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// This channel must be closed to terminate idle timer.
|
||||
k.notifyStop = make(chan struct{})
|
||||
k.notifyWaitGroup.Add(1)
|
||||
|
||||
go func() {
|
||||
for t := time.NewTimer(k.idleTime); ; {
|
||||
select {
|
||||
case <-k.notifyStop:
|
||||
k.notifyWaitGroup.Done()
|
||||
return
|
||||
case <-k.notifyRequest:
|
||||
t.Reset(k.idleTime)
|
||||
case <-t.C:
|
||||
if err := k.keepAlive(k.roundTripper); err != nil {
|
||||
k.notifyWaitGroup.Done()
|
||||
k.stop()
|
||||
return
|
||||
}
|
||||
t = time.NewTimer(k.idleTime)
|
||||
}
|
||||
var f func() error
|
||||
if handler != nil {
|
||||
f = func() error {
|
||||
return handler(roundTripper)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (k *keepAlive) stop() {
|
||||
k.Lock()
|
||||
defer k.Unlock()
|
||||
|
||||
if k.notifyStop != nil {
|
||||
close(k.notifyStop)
|
||||
k.notifyWaitGroup.Wait()
|
||||
k.notifyStop = nil
|
||||
}
|
||||
}
|
||||
|
||||
func (k *keepAlive) RoundTrip(ctx context.Context, req, res soap.HasFault) error {
|
||||
// Stop ticker on logout.
|
||||
switch req.(type) {
|
||||
case *methods.LogoutBody:
|
||||
k.stop()
|
||||
}
|
||||
|
||||
err := k.roundTripper.RoundTrip(ctx, req, res)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Start ticker on login.
|
||||
switch req.(type) {
|
||||
case *methods.LoginBody, *methods.LoginExtensionByCertificateBody, *methods.LoginByTokenBody:
|
||||
k.start()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
return keepalive.NewHandlerSOAP(roundTripper, idleTime, f)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
Copyright (c) 2020 VMware, Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package keepalive
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/vmware/govmomi/vapi/rest"
|
||||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/soap"
|
||||
)
|
||||
|
||||
// handler contains the generic keep alive settings and logic
|
||||
type handler struct {
|
||||
mu sync.Mutex
|
||||
notifyStop chan struct{}
|
||||
notifyWaitGroup sync.WaitGroup
|
||||
|
||||
idle time.Duration
|
||||
send func() error
|
||||
}
|
||||
|
||||
// NewHandlerSOAP returns a soap.RoundTripper for use with a vim25.Client
|
||||
// The idle time specifies the interval in between send() requests. Defaults to 10 minutes.
|
||||
// The send func is used to keep a session alive. Defaults to calling vim25 GetCurrentTime().
|
||||
// The keep alive goroutine starts when a Login method is called and runs until Logout is called or send returns an error.
|
||||
func NewHandlerSOAP(c soap.RoundTripper, idle time.Duration, send func() error) *HandlerSOAP {
|
||||
h := &handler{
|
||||
idle: idle,
|
||||
send: send,
|
||||
}
|
||||
|
||||
if send == nil {
|
||||
h.send = func() error {
|
||||
return h.keepAliveSOAP(c)
|
||||
}
|
||||
}
|
||||
|
||||
return &HandlerSOAP{h, c}
|
||||
}
|
||||
|
||||
// NewHandlerREST returns an http.RoundTripper for use with a rest.Client
|
||||
// The idle time specifies the interval in between send() requests. Defaults to 10 minutes.
|
||||
// The send func is used to keep a session alive. Defaults to calling the rest.Client.Session() method
|
||||
// The keep alive goroutine starts when a Login method is called and runs until Logout is called or send returns an error.
|
||||
func NewHandlerREST(c *rest.Client, idle time.Duration, send func() error) *HandlerREST {
|
||||
h := &handler{
|
||||
idle: idle,
|
||||
send: send,
|
||||
}
|
||||
|
||||
if send == nil {
|
||||
h.send = func() error {
|
||||
return h.keepAliveREST(c)
|
||||
}
|
||||
}
|
||||
|
||||
return &HandlerREST{h, c.Transport}
|
||||
}
|
||||
|
||||
func (h *handler) keepAliveSOAP(rt soap.RoundTripper) error {
|
||||
ctx := context.Background()
|
||||
_, err := methods.GetCurrentTime(ctx, rt)
|
||||
return err
|
||||
}
|
||||
|
||||
func (h *handler) keepAliveREST(c *rest.Client) error {
|
||||
ctx := context.Background()
|
||||
|
||||
s, err := c.Session(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if s != nil {
|
||||
return nil
|
||||
}
|
||||
return errors.New(http.StatusText(http.StatusUnauthorized))
|
||||
}
|
||||
|
||||
// Start explicitly starts the keep alive go routine.
|
||||
// For use with session cache.Client, as cached sessions may not involve Login/Logout via RoundTripper.
|
||||
func (h *handler) Start() {
|
||||
h.mu.Lock()
|
||||
defer h.mu.Unlock()
|
||||
|
||||
if h.notifyStop != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if h.idle == 0 {
|
||||
h.idle = time.Minute * 10
|
||||
}
|
||||
|
||||
// This channel must be closed to terminate idle timer.
|
||||
h.notifyStop = make(chan struct{})
|
||||
h.notifyWaitGroup.Add(1)
|
||||
|
||||
go func() {
|
||||
for t := time.NewTimer(h.idle); ; {
|
||||
select {
|
||||
case <-h.notifyStop:
|
||||
h.notifyWaitGroup.Done()
|
||||
t.Stop()
|
||||
return
|
||||
case <-t.C:
|
||||
if err := h.send(); err != nil {
|
||||
h.notifyWaitGroup.Done()
|
||||
h.Stop()
|
||||
return
|
||||
}
|
||||
t.Reset(h.idle)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// Stop explicitly stops the keep alive go routine.
|
||||
// For use with session cache.Client, as cached sessions may not involve Login/Logout via RoundTripper.
|
||||
func (h *handler) Stop() {
|
||||
h.mu.Lock()
|
||||
defer h.mu.Unlock()
|
||||
|
||||
if h.notifyStop != nil {
|
||||
close(h.notifyStop)
|
||||
h.notifyWaitGroup.Wait()
|
||||
h.notifyStop = nil
|
||||
}
|
||||
}
|
||||
|
||||
// HandlerSOAP is a keep alive implementation for use with vim25.Client
|
||||
type HandlerSOAP struct {
|
||||
*handler
|
||||
|
||||
roundTripper soap.RoundTripper
|
||||
}
|
||||
|
||||
// RoundTrip implements soap.RoundTripper
|
||||
func (h *HandlerSOAP) RoundTrip(ctx context.Context, req, res soap.HasFault) error {
|
||||
// Stop ticker on logout.
|
||||
switch req.(type) {
|
||||
case *methods.LogoutBody:
|
||||
h.Stop()
|
||||
}
|
||||
|
||||
err := h.roundTripper.RoundTrip(ctx, req, res)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Start ticker on login.
|
||||
switch req.(type) {
|
||||
case *methods.LoginBody, *methods.LoginExtensionByCertificateBody, *methods.LoginByTokenBody:
|
||||
h.Start()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// HandlerREST is a keep alive implementation for use with rest.Client
|
||||
type HandlerREST struct {
|
||||
*handler
|
||||
|
||||
roundTripper http.RoundTripper
|
||||
}
|
||||
|
||||
// RoundTrip implements http.RoundTripper
|
||||
func (h *HandlerREST) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
if req.URL.Path != "/rest/com/vmware/cis/session" {
|
||||
return h.roundTripper.RoundTrip(req)
|
||||
}
|
||||
|
||||
if req.Method == http.MethodDelete { // Logout
|
||||
h.Stop()
|
||||
}
|
||||
|
||||
res, err := h.roundTripper.RoundTrip(req)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
if req.Method == http.MethodPost { // Login
|
||||
h.Start()
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
|
@ -19,7 +19,6 @@ package session
|
|||
import (
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
|
@ -124,7 +123,7 @@ func (sm *Manager) LoginExtensionByCertificate(ctx context.Context, key string)
|
|||
// "Post https://sdkTunnel:8089/sdk: x509: certificate is valid for $vcenter_hostname, not sdkTunnel"
|
||||
// The only easy way around this is to disable verification for the call to LoginExtensionByCertificate().
|
||||
// TODO: find a way to avoid disabling InsecureSkipVerify.
|
||||
c.Transport.(*http.Transport).TLSClientConfig.InsecureSkipVerify = true
|
||||
c.DefaultTransport().TLSClientConfig.InsecureSkipVerify = true
|
||||
}
|
||||
|
||||
req := types.LoginExtensionByCertificate{
|
||||
|
|
|
@ -38,10 +38,12 @@ const (
|
|||
LocalLibraryPath = "/com/vmware/content/local-library"
|
||||
SubscribedLibraryPath = "/com/vmware/content/subscribed-library"
|
||||
SubscribedLibraryItem = "/com/vmware/content/library/subscribed-item"
|
||||
Subscriptions = "/com/vmware/content/library/subscriptions"
|
||||
VCenterOVFLibraryItem = "/com/vmware/vcenter/ovf/library-item"
|
||||
VCenterVMTXLibraryItem = "/vcenter/vm-template/library-items"
|
||||
VCenterVM = "/vcenter/vm"
|
||||
SessionCookieName = "vmware-api-session-id"
|
||||
UseHeaderAuthn = "vmware-use-header-authn"
|
||||
)
|
||||
|
||||
// AssociatedObject is the same structure as types.ManagedObjectReference,
|
||||
|
@ -69,3 +71,16 @@ func NewAssociation(ref mo.Reference) Association {
|
|||
ObjectID: &obj,
|
||||
}
|
||||
}
|
||||
|
||||
type SubscriptionDestination struct {
|
||||
ID string `json:"subscription"`
|
||||
}
|
||||
|
||||
type SubscriptionDestinationSpec struct {
|
||||
Subscriptions []SubscriptionDestination `json:"subscriptions,omitempty"`
|
||||
}
|
||||
|
||||
type SubscriptionItemDestinationSpec struct {
|
||||
Force bool `json:"force_sync_content"`
|
||||
Subscriptions []SubscriptionDestination `json:"subscriptions,omitempty"`
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ type Library struct {
|
|||
Type string `json:"type,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
Subscription *Subscription `json:"subscription_info,omitempty"`
|
||||
Publication *Publication `json:"publish_info,omitempty"`
|
||||
}
|
||||
|
||||
// Subscription info
|
||||
|
@ -59,6 +60,59 @@ type Subscription struct {
|
|||
UserName string `json:"user_name,omitempty"`
|
||||
}
|
||||
|
||||
// Publication info
|
||||
type Publication struct {
|
||||
AuthenticationMethod string `json:"authentication_method"`
|
||||
UserName string `json:"user_name,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
CurrentPassword string `json:"current_password,omitempty"`
|
||||
PersistJSON *bool `json:"persist_json_enabled,omitempty"`
|
||||
Published *bool `json:"published,omitempty"`
|
||||
PublishURL string `json:"publish_url,omitempty"`
|
||||
}
|
||||
|
||||
// SubscriberSummary as returned by ListSubscribers
|
||||
type SubscriberSummary struct {
|
||||
LibraryID string `json:"subscribed_library"`
|
||||
LibraryName string `json:"subscribed_library_name"`
|
||||
SubscriptionID string `json:"subscription"`
|
||||
LibraryVcenterHostname string `json:"subscribed_library_vcenter_hostname,omitempty"`
|
||||
}
|
||||
|
||||
// Placement information used to place a virtual machine template
|
||||
type Placement struct {
|
||||
ResourcePool string `json:"resource_pool,omitempty"`
|
||||
Host string `json:"host,omitempty"`
|
||||
Folder string `json:"folder,omitempty"`
|
||||
Cluster string `json:"cluster,omitempty"`
|
||||
Network string `json:"network,omitempty"`
|
||||
}
|
||||
|
||||
// Vcenter contains information about the vCenter Server instance where a subscribed library associated with a subscription exists.
|
||||
type Vcenter struct {
|
||||
Hostname string `json:"hostname"`
|
||||
Port int `json:"https_port,omitempty"`
|
||||
ServerGUID string `json:"server_guid"`
|
||||
}
|
||||
|
||||
// Subscriber contains the detailed info for a library subscriber.
|
||||
type Subscriber struct {
|
||||
LibraryID string `json:"subscribed_library"`
|
||||
LibraryName string `json:"subscribed_library_name"`
|
||||
LibraryLocation string `json:"subscribed_library_location"`
|
||||
Placement *Placement `json:"subscribed_library_placement,omitempty"`
|
||||
Vcenter *Vcenter `json:"subscribed_library_vcenter,omitempty"`
|
||||
}
|
||||
|
||||
// SubscriberLibrary is the specification for a subscribed library to be associated with a subscription.
|
||||
type SubscriberLibrary struct {
|
||||
Target string `json:"target"`
|
||||
LibraryID string `json:"subscribed_library,omitempty"`
|
||||
Location string `json:"location"`
|
||||
Vcenter *Vcenter `json:"vcenter,omitempty"`
|
||||
Placement *Placement `json:"placement,omitempty"`
|
||||
}
|
||||
|
||||
// Patch merges updates from the given src.
|
||||
func (l *Library) Patch(src *Library) {
|
||||
if src.Name != "" {
|
||||
|
@ -124,7 +178,7 @@ func (c *Manager) CreateLibrary(ctx context.Context, library Library) (string, e
|
|||
if u.Scheme == "https" && sub.SslThumbprint == "" {
|
||||
thumbprint := c.Thumbprint(u.Host)
|
||||
if thumbprint == "" {
|
||||
t := c.Transport.(*http.Transport)
|
||||
t := c.DefaultTransport()
|
||||
if t.TLSClientConfig.InsecureSkipVerify {
|
||||
var info object.HostCertificateInfo
|
||||
_ = info.FromURL(u, t.TLSClientConfig)
|
||||
|
@ -146,6 +200,18 @@ func (c *Manager) SyncLibrary(ctx context.Context, library *Library) error {
|
|||
return c.Do(ctx, url.Request(http.MethodPost), nil)
|
||||
}
|
||||
|
||||
// PublishLibrary publishes the library to specified subscriptions.
|
||||
// If no subscriptions are specified, then publishes the library to all subscriptions.
|
||||
func (c *Manager) PublishLibrary(ctx context.Context, library *Library, subscriptions []string) error {
|
||||
path := internal.LocalLibraryPath
|
||||
var spec internal.SubscriptionDestinationSpec
|
||||
for i := range subscriptions {
|
||||
spec.Subscriptions = append(spec.Subscriptions, internal.SubscriptionDestination{ID: subscriptions[i]})
|
||||
}
|
||||
url := c.Resource(path).WithID(library.ID).WithAction("publish")
|
||||
return c.Do(ctx, url.Request(http.MethodPost, spec), nil)
|
||||
}
|
||||
|
||||
// DeleteLibrary deletes an existing library.
|
||||
func (c *Manager) DeleteLibrary(ctx context.Context, library *Library) error {
|
||||
path := internal.LocalLibraryPath
|
||||
|
@ -204,3 +270,39 @@ func (c *Manager) GetLibraries(ctx context.Context) ([]Library, error) {
|
|||
}
|
||||
return libraries, nil
|
||||
}
|
||||
|
||||
// ListSubscribers lists the subscriptions of the published library.
|
||||
func (c *Manager) ListSubscribers(ctx context.Context, library *Library) ([]SubscriberSummary, error) {
|
||||
url := c.Resource(internal.Subscriptions).WithParam("library", library.ID)
|
||||
var res []SubscriberSummary
|
||||
return res, c.Do(ctx, url.Request(http.MethodGet), &res)
|
||||
}
|
||||
|
||||
// CreateSubscriber creates a subscription of the published library.
|
||||
func (c *Manager) CreateSubscriber(ctx context.Context, library *Library, s SubscriberLibrary) (string, error) {
|
||||
var spec struct {
|
||||
Sub struct {
|
||||
SubscriberLibrary SubscriberLibrary `json:"subscribed_library"`
|
||||
} `json:"spec"`
|
||||
}
|
||||
spec.Sub.SubscriberLibrary = s
|
||||
url := c.Resource(internal.Subscriptions).WithID(library.ID)
|
||||
var res string
|
||||
return res, c.Do(ctx, url.Request(http.MethodPost, &spec), &res)
|
||||
}
|
||||
|
||||
// GetSubscriber returns information about the specified subscriber of the published library.
|
||||
func (c *Manager) GetSubscriber(ctx context.Context, library *Library, subscriber string) (*Subscriber, error) {
|
||||
id := internal.SubscriptionDestination{ID: subscriber}
|
||||
url := c.Resource(internal.Subscriptions).WithID(library.ID).WithAction("get")
|
||||
var res Subscriber
|
||||
return &res, c.Do(ctx, url.Request(http.MethodPost, &id), &res)
|
||||
}
|
||||
|
||||
// DeleteSubscriber deletes the specified subscription of the published library.
|
||||
// The subscribed library associated with the subscription will not be deleted.
|
||||
func (c *Manager) DeleteSubscriber(ctx context.Context, library *Library, subscriber string) error {
|
||||
id := internal.SubscriptionDestination{ID: subscriber}
|
||||
url := c.Resource(internal.Subscriptions).WithID(library.ID).WithAction("delete")
|
||||
return c.Do(ctx, url.Request(http.MethodPost, &id), nil)
|
||||
}
|
||||
|
|
|
@ -88,6 +88,16 @@ func (c *Manager) CreateLibraryItem(ctx context.Context, item Item) (string, err
|
|||
return res, c.Do(ctx, url.Request(http.MethodPost, spec), &res)
|
||||
}
|
||||
|
||||
// CopyLibraryItem copies a library item
|
||||
func (c *Manager) CopyLibraryItem(ctx context.Context, src *Item, dst Item) (string, error) {
|
||||
body := struct {
|
||||
Item `json:"destination_create_spec"`
|
||||
}{dst}
|
||||
url := c.Resource(internal.LibraryItemPath).WithID(src.ID).WithAction("copy")
|
||||
var res string
|
||||
return res, c.Do(ctx, url.Request(http.MethodPost, body), &res)
|
||||
}
|
||||
|
||||
// SyncLibraryItem syncs a subscribed library item
|
||||
func (c *Manager) SyncLibraryItem(ctx context.Context, item *Item, force bool) error {
|
||||
body := struct {
|
||||
|
@ -97,6 +107,19 @@ func (c *Manager) SyncLibraryItem(ctx context.Context, item *Item, force bool) e
|
|||
return c.Do(ctx, url.Request(http.MethodPost, body), nil)
|
||||
}
|
||||
|
||||
// PublishLibraryItem publishes a library item to specified subscriptions.
|
||||
// If no subscriptions are specified, then publishes the library item to all subscriptions.
|
||||
func (c *Manager) PublishLibraryItem(ctx context.Context, item *Item, force bool, subscriptions []string) error {
|
||||
body := internal.SubscriptionItemDestinationSpec{
|
||||
Force: force,
|
||||
}
|
||||
for i := range subscriptions {
|
||||
body.Subscriptions = append(body.Subscriptions, internal.SubscriptionDestination{ID: subscriptions[i]})
|
||||
}
|
||||
url := c.Resource(internal.LibraryItemPath).WithID(item.ID).WithAction("publish")
|
||||
return c.Do(ctx, url.Request(http.MethodPost, body), nil)
|
||||
}
|
||||
|
||||
// DeleteLibraryItem deletes an existing library item.
|
||||
func (c *Manager) DeleteLibraryItem(ctx context.Context, item *Item) error {
|
||||
url := c.Resource(internal.LibraryItemPath).WithID(item.ID)
|
||||
|
|
2
vendor/github.com/vmware/govmomi/vapi/library/library_item_updatesession_file.go
generated
vendored
2
vendor/github.com/vmware/govmomi/vapi/library/library_item_updatesession_file.go
generated
vendored
|
@ -116,7 +116,7 @@ func (c *Manager) getContentLengthAndFingerprint(
|
|||
}
|
||||
fingerprint := c.Thumbprint(resp.Request.URL.Host)
|
||||
if fingerprint == "" {
|
||||
if c.Transport.(*http.Transport).TLSClientConfig.InsecureSkipVerify {
|
||||
if c.DefaultTransport().TLSClientConfig.InsecureSkipVerify {
|
||||
fingerprint = soap.ThumbprintSHA1(resp.TLS.PeerCertificates[0])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/vmware/govmomi/vapi/internal"
|
||||
|
@ -34,7 +35,10 @@ import (
|
|||
|
||||
// Client extends soap.Client to support JSON encoding, while inheriting security features, debug tracing and session persistence.
|
||||
type Client struct {
|
||||
mu sync.Mutex
|
||||
|
||||
*soap.Client
|
||||
sessionID string
|
||||
}
|
||||
|
||||
// Session information
|
||||
|
@ -59,7 +63,47 @@ func (m *LocalizableMessage) Error() string {
|
|||
func NewClient(c *vim25.Client) *Client {
|
||||
sc := c.Client.NewServiceClient(Path, "")
|
||||
|
||||
return &Client{sc}
|
||||
return &Client{Client: sc}
|
||||
}
|
||||
|
||||
// SessionID is set by calling Login() or optionally with the given id param
|
||||
func (c *Client) SessionID(id ...string) string {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
if len(id) != 0 {
|
||||
c.sessionID = id[0]
|
||||
}
|
||||
return c.sessionID
|
||||
}
|
||||
|
||||
type marshaledClient struct {
|
||||
SoapClient *soap.Client
|
||||
SessionID string
|
||||
}
|
||||
|
||||
func (c *Client) MarshalJSON() ([]byte, error) {
|
||||
m := marshaledClient{
|
||||
SoapClient: c.Client,
|
||||
SessionID: c.sessionID,
|
||||
}
|
||||
|
||||
return json.Marshal(m)
|
||||
}
|
||||
|
||||
func (c *Client) UnmarshalJSON(b []byte) error {
|
||||
var m marshaledClient
|
||||
|
||||
err := json.Unmarshal(b, &m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*c = Client{
|
||||
Client: m.SoapClient,
|
||||
sessionID: m.SessionID,
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Resource helper for the given path.
|
||||
|
@ -96,6 +140,10 @@ func (c *Client) Do(ctx context.Context, req *http.Request, resBody interface{})
|
|||
|
||||
req.Header.Set("Accept", "application/json")
|
||||
|
||||
if id := c.SessionID(); id != "" {
|
||||
req.Header.Set(internal.SessionCookieName, id)
|
||||
}
|
||||
|
||||
if s, ok := ctx.Value(signerContext{}).(Signer); ok {
|
||||
if err := s.SignRequest(req); err != nil {
|
||||
return err
|
||||
|
@ -105,6 +153,7 @@ func (c *Client) Do(ctx context.Context, req *http.Request, resBody interface{})
|
|||
return c.Client.Do(ctx, req, func(res *http.Response) error {
|
||||
switch res.StatusCode {
|
||||
case http.StatusOK:
|
||||
case http.StatusNoContent:
|
||||
case http.StatusBadRequest:
|
||||
// TODO: structured error types
|
||||
detail, err := ioutil.ReadAll(res.Body)
|
||||
|
@ -135,17 +184,62 @@ func (c *Client) Do(ctx context.Context, req *http.Request, resBody interface{})
|
|||
})
|
||||
}
|
||||
|
||||
// authHeaders ensures the given map contains a REST auth header
|
||||
func (c *Client) authHeaders(h map[string]string) map[string]string {
|
||||
if _, exists := h[internal.SessionCookieName]; exists {
|
||||
return h
|
||||
}
|
||||
if h == nil {
|
||||
h = make(map[string]string)
|
||||
}
|
||||
|
||||
h[internal.SessionCookieName] = c.SessionID()
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
// Download wraps soap.Client.Download, adding the REST authentication header
|
||||
func (c *Client) Download(ctx context.Context, u *url.URL, param *soap.Download) (io.ReadCloser, int64, error) {
|
||||
p := *param
|
||||
p.Headers = c.authHeaders(p.Headers)
|
||||
return c.Client.Download(ctx, u, &p)
|
||||
}
|
||||
|
||||
// DownloadFile wraps soap.Client.DownloadFile, adding the REST authentication header
|
||||
func (c *Client) DownloadFile(ctx context.Context, file string, u *url.URL, param *soap.Download) error {
|
||||
p := *param
|
||||
p.Headers = c.authHeaders(p.Headers)
|
||||
return c.Client.DownloadFile(ctx, file, u, &p)
|
||||
}
|
||||
|
||||
// Upload wraps soap.Client.Upload, adding the REST authentication header
|
||||
func (c *Client) Upload(ctx context.Context, f io.Reader, u *url.URL, param *soap.Upload) error {
|
||||
p := *param
|
||||
p.Headers = c.authHeaders(p.Headers)
|
||||
return c.Client.Upload(ctx, f, u, &p)
|
||||
}
|
||||
|
||||
// Login creates a new session via Basic Authentication with the given url.Userinfo.
|
||||
func (c *Client) Login(ctx context.Context, user *url.Userinfo) error {
|
||||
req := c.Resource(internal.SessionPath).Request(http.MethodPost)
|
||||
|
||||
req.Header.Set(internal.UseHeaderAuthn, "true")
|
||||
|
||||
if user != nil {
|
||||
if password, ok := user.Password(); ok {
|
||||
req.SetBasicAuth(user.Username(), password)
|
||||
}
|
||||
}
|
||||
|
||||
return c.Do(ctx, req, nil)
|
||||
var id string
|
||||
err := c.Do(ctx, req, &id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.SessionID(id)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) LoginByToken(ctx context.Context) error {
|
||||
|
@ -174,3 +268,22 @@ func (c *Client) Logout(ctx context.Context) error {
|
|||
req := c.Resource(internal.SessionPath).Request(http.MethodDelete)
|
||||
return c.Do(ctx, req, nil)
|
||||
}
|
||||
|
||||
// Valid returns whether or not the client is valid and ready for use.
|
||||
// This should be called after unmarshalling the client.
|
||||
func (c *Client) Valid() bool {
|
||||
if c == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if c.Client == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// Path returns rest.Path (see cache.Client)
|
||||
func (c *Client) Path() string {
|
||||
return Path
|
||||
}
|
||||
|
|
|
@ -60,14 +60,13 @@ type AdditionalParams struct {
|
|||
}
|
||||
|
||||
const (
|
||||
ClassOvfParams = "com.vmware.vcenter.ovf.ovf_params"
|
||||
ClassPropertyParams = "com.vmware.vcenter.ovf.property_params"
|
||||
TypeDeploymentOptionParams = "DeploymentOptionParams"
|
||||
TypeExtraConfigParams = "ExtraConfigParams"
|
||||
TypeExtraConfigs = "ExtraConfigs"
|
||||
TypeIPAllocationParams = "IpAllocationParams"
|
||||
TypePropertyParams = "PropertyParams"
|
||||
TypeSizeParams = "SizeParams"
|
||||
ClassDeploymentOptionParams = "com.vmware.vcenter.ovf.deployment_option_params"
|
||||
ClassPropertyParams = "com.vmware.vcenter.ovf.property_params"
|
||||
TypeDeploymentOptionParams = "DeploymentOptionParams"
|
||||
TypeExtraConfigParams = "ExtraConfigParams"
|
||||
TypeIPAllocationParams = "IpAllocationParams"
|
||||
TypePropertyParams = "PropertyParams"
|
||||
TypeSizeParams = "SizeParams"
|
||||
)
|
||||
|
||||
// DeploymentOption contains the information about a deployment option as defined in the OVF specification
|
||||
|
@ -204,6 +203,33 @@ func (e *DeploymentError) Error() string {
|
|||
return "deploy error: " + msg
|
||||
}
|
||||
|
||||
// LibraryTarget specifies a Library or Library item
|
||||
type LibraryTarget struct {
|
||||
LibraryID string `json:"library_id,omitempty"`
|
||||
LibraryItemID string `json:"library_item_id,omitempty"`
|
||||
}
|
||||
|
||||
// CreateSpec info used to create an OVF package from a VM
|
||||
type CreateSpec struct {
|
||||
Description string `json:"description,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Flags []string `json:"flags,omitempty"`
|
||||
}
|
||||
|
||||
// OVF data used by CreateOVF
|
||||
type OVF struct {
|
||||
Spec CreateSpec `json:"create_spec"`
|
||||
Source ResourceID `json:"source"`
|
||||
Target LibraryTarget `json:"target"`
|
||||
}
|
||||
|
||||
// CreateResult used for decoded a CreateOVF response
|
||||
type CreateResult struct {
|
||||
Succeeded bool `json:"succeeded,omitempty"`
|
||||
ID string `json:"ovf_library_item_id,omitempty"`
|
||||
Error *DeploymentError `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// Deployment is the results from issuing a library OVF deployment
|
||||
type Deployment struct {
|
||||
Succeeded bool `json:"succeeded,omitempty"`
|
||||
|
@ -238,6 +264,23 @@ func NewManager(client *rest.Client) *Manager {
|
|||
}
|
||||
}
|
||||
|
||||
// CreateOVF creates a library OVF item in content library from an existing VM
|
||||
func (c *Manager) CreateOVF(ctx context.Context, ovf OVF) (string, error) {
|
||||
if ovf.Source.Type == "" {
|
||||
ovf.Source.Type = "VirtualMachine"
|
||||
}
|
||||
url := c.Resource(internal.VCenterOVFLibraryItem)
|
||||
var res CreateResult
|
||||
err := c.Do(ctx, url.Request(http.MethodPost, ovf), &res)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if res.Succeeded {
|
||||
return res.ID, nil
|
||||
}
|
||||
return "", res.Error
|
||||
}
|
||||
|
||||
// DeployLibraryItem deploys a library OVF
|
||||
func (c *Manager) DeployLibraryItem(ctx context.Context, libraryItemID string, deploy Deploy) (*types.ManagedObjectReference, error) {
|
||||
url := c.Resource(internal.VCenterOVFLibraryItem).WithID(libraryItemID).WithAction("deploy")
|
||||
|
|
|
@ -53,12 +53,7 @@ type TemplateInfo struct {
|
|||
}
|
||||
|
||||
// Placement information used to place the virtual machine template
|
||||
type Placement struct {
|
||||
ResourcePool string `json:"resource_pool,omitempty"`
|
||||
Host string `json:"host,omitempty"`
|
||||
Folder string `json:"folder,omitempty"`
|
||||
Cluster string `json:"cluster,omitempty"`
|
||||
}
|
||||
type Placement = library.Placement
|
||||
|
||||
// StoragePolicy for DiskStorage
|
||||
type StoragePolicy struct {
|
||||
|
@ -113,7 +108,7 @@ type CheckIn struct {
|
|||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// CreateTemplate creates a library item in content library from an existing VM
|
||||
// CreateTemplate creates a library VMTX item in content library from an existing VM
|
||||
func (c *Manager) CreateTemplate(ctx context.Context, vmtx Template) (string, error) {
|
||||
url := c.Resource(internal.VCenterVMTXLibraryItem)
|
||||
var res string
|
||||
|
|
|
@ -19,7 +19,6 @@ package vim25
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path"
|
||||
|
@ -28,11 +27,12 @@ import (
|
|||
"github.com/vmware/govmomi/vim25/methods"
|
||||
"github.com/vmware/govmomi/vim25/soap"
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
"github.com/vmware/govmomi/vim25/xml"
|
||||
)
|
||||
|
||||
const (
|
||||
Namespace = "vim25"
|
||||
Version = "6.7"
|
||||
Version = "7.0"
|
||||
Path = "/sdk"
|
||||
)
|
||||
|
||||
|
@ -89,9 +89,14 @@ func NewClient(ctx context.Context, rt soap.RoundTripper) (*Client, error) {
|
|||
}
|
||||
|
||||
// UseServiceVersion sets soap.Client.Version to the current version of the service endpoint via /sdk/vimServiceVersions.xml
|
||||
func (c *Client) UseServiceVersion() error {
|
||||
func (c *Client) UseServiceVersion(kind ...string) error {
|
||||
ns := "vim"
|
||||
if len(kind) != 0 {
|
||||
ns = kind[0]
|
||||
}
|
||||
|
||||
u := c.URL()
|
||||
u.Path = path.Join(Path, "vimServiceVersions.xml")
|
||||
u.Path = path.Join(Path, ns+"ServiceVersions.xml")
|
||||
|
||||
res, err := c.Get(u.String())
|
||||
if err != nil {
|
||||
|
@ -103,8 +108,12 @@ func (c *Client) UseServiceVersion() error {
|
|||
}
|
||||
|
||||
v := struct {
|
||||
Version *string `xml:"namespace>version"`
|
||||
}{&c.Version}
|
||||
Namespace *string `xml:"namespace>name"`
|
||||
Version *string `xml:"namespace>version"`
|
||||
}{
|
||||
&c.Namespace,
|
||||
&c.Version,
|
||||
}
|
||||
|
||||
err = xml.NewDecoder(res.Body).Decode(&v)
|
||||
_ = res.Body.Close()
|
||||
|
@ -171,6 +180,11 @@ func (c *Client) Valid() bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// Path returns vim25.Path (see cache.Client)
|
||||
func (c *Client) Path() string {
|
||||
return Path
|
||||
}
|
||||
|
||||
// IsVC returns true if we are connected to a vCenter
|
||||
func (c *Client) IsVC() bool {
|
||||
return c.ServiceContent.About.ApiType == "VirtualCenter"
|
||||
|
|
|
@ -63,6 +63,26 @@ func AbdicateDomOwnership(ctx context.Context, r soap.RoundTripper, req *types.A
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type AbortCustomization_TaskBody struct {
|
||||
Req *types.AbortCustomization_Task `xml:"urn:vim25 AbortCustomization_Task,omitempty"`
|
||||
Res *types.AbortCustomization_TaskResponse `xml:"AbortCustomization_TaskResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *AbortCustomization_TaskBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func AbortCustomization_Task(ctx context.Context, r soap.RoundTripper, req *types.AbortCustomization_Task) (*types.AbortCustomization_TaskResponse, error) {
|
||||
var reqBody, resBody AbortCustomization_TaskBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type AcknowledgeAlarmBody struct {
|
||||
Req *types.AcknowledgeAlarm `xml:"urn:vim25 AcknowledgeAlarm,omitempty"`
|
||||
Res *types.AcknowledgeAlarmResponse `xml:"AcknowledgeAlarmResponse,omitempty"`
|
||||
|
@ -2263,6 +2283,26 @@ func ConfigureVFlashResourceEx_Task(ctx context.Context, r soap.RoundTripper, re
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type ConnectNvmeControllerBody struct {
|
||||
Req *types.ConnectNvmeController `xml:"urn:vim25 ConnectNvmeController,omitempty"`
|
||||
Res *types.ConnectNvmeControllerResponse `xml:"ConnectNvmeControllerResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *ConnectNvmeControllerBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func ConnectNvmeController(ctx context.Context, r soap.RoundTripper, req *types.ConnectNvmeController) (*types.ConnectNvmeControllerResponse, error) {
|
||||
var reqBody, resBody ConnectNvmeControllerBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type ConsolidateVMDisks_TaskBody struct {
|
||||
Req *types.ConsolidateVMDisks_Task `xml:"urn:vim25 ConsolidateVMDisks_Task,omitempty"`
|
||||
Res *types.ConsolidateVMDisks_TaskResponse `xml:"ConsolidateVMDisks_TaskResponse,omitempty"`
|
||||
|
@ -2943,6 +2983,26 @@ func CreateNvdimmPMemNamespace_Task(ctx context.Context, r soap.RoundTripper, re
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type CreateNvmeOverRdmaAdapterBody struct {
|
||||
Req *types.CreateNvmeOverRdmaAdapter `xml:"urn:vim25 CreateNvmeOverRdmaAdapter,omitempty"`
|
||||
Res *types.CreateNvmeOverRdmaAdapterResponse `xml:"CreateNvmeOverRdmaAdapterResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *CreateNvmeOverRdmaAdapterBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func CreateNvmeOverRdmaAdapter(ctx context.Context, r soap.RoundTripper, req *types.CreateNvmeOverRdmaAdapter) (*types.CreateNvmeOverRdmaAdapterResponse, error) {
|
||||
var reqBody, resBody CreateNvmeOverRdmaAdapterBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type CreateObjectScheduledTaskBody struct {
|
||||
Req *types.CreateObjectScheduledTask `xml:"urn:vim25 CreateObjectScheduledTask,omitempty"`
|
||||
Res *types.CreateObjectScheduledTaskResponse `xml:"CreateObjectScheduledTaskResponse,omitempty"`
|
||||
|
@ -3383,6 +3443,26 @@ func CreateVvolDatastore(ctx context.Context, r soap.RoundTripper, req *types.Cr
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type CryptoManagerHostDisableBody struct {
|
||||
Req *types.CryptoManagerHostDisable `xml:"urn:vim25 CryptoManagerHostDisable,omitempty"`
|
||||
Res *types.CryptoManagerHostDisableResponse `xml:"CryptoManagerHostDisableResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *CryptoManagerHostDisableBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func CryptoManagerHostDisable(ctx context.Context, r soap.RoundTripper, req *types.CryptoManagerHostDisable) (*types.CryptoManagerHostDisableResponse, error) {
|
||||
var reqBody, resBody CryptoManagerHostDisableBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type CryptoManagerHostEnableBody struct {
|
||||
Req *types.CryptoManagerHostEnable `xml:"urn:vim25 CryptoManagerHostEnable,omitempty"`
|
||||
Res *types.CryptoManagerHostEnableResponse `xml:"CryptoManagerHostEnableResponse,omitempty"`
|
||||
|
@ -3483,6 +3563,26 @@ func CustomizationSpecItemToXml(ctx context.Context, r soap.RoundTripper, req *t
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type CustomizeGuest_TaskBody struct {
|
||||
Req *types.CustomizeGuest_Task `xml:"urn:vim25 CustomizeGuest_Task,omitempty"`
|
||||
Res *types.CustomizeGuest_TaskResponse `xml:"CustomizeGuest_TaskResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *CustomizeGuest_TaskBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func CustomizeGuest_Task(ctx context.Context, r soap.RoundTripper, req *types.CustomizeGuest_Task) (*types.CustomizeGuest_TaskResponse, error) {
|
||||
var reqBody, resBody CustomizeGuest_TaskBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type CustomizeVM_TaskBody struct {
|
||||
Req *types.CustomizeVM_Task `xml:"urn:vim25 CustomizeVM_Task,omitempty"`
|
||||
Res *types.CustomizeVM_TaskResponse `xml:"CustomizeVM_TaskResponse,omitempty"`
|
||||
|
@ -4423,6 +4523,46 @@ func DetachTagFromVStorageObject(ctx context.Context, r soap.RoundTripper, req *
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type DisableAlarmBody struct {
|
||||
Req *types.DisableAlarm `xml:"urn:vim25 DisableAlarm,omitempty"`
|
||||
Res *types.DisableAlarmResponse `xml:"DisableAlarmResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *DisableAlarmBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func DisableAlarm(ctx context.Context, r soap.RoundTripper, req *types.DisableAlarm) (*types.DisableAlarmResponse, error) {
|
||||
var reqBody, resBody DisableAlarmBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type DisableClusteredVmdkSupportBody struct {
|
||||
Req *types.DisableClusteredVmdkSupport `xml:"urn:vim25 DisableClusteredVmdkSupport,omitempty"`
|
||||
Res *types.DisableClusteredVmdkSupportResponse `xml:"DisableClusteredVmdkSupportResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *DisableClusteredVmdkSupportBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func DisableClusteredVmdkSupport(ctx context.Context, r soap.RoundTripper, req *types.DisableClusteredVmdkSupport) (*types.DisableClusteredVmdkSupportResponse, error) {
|
||||
var reqBody, resBody DisableClusteredVmdkSupportBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type DisableEvcMode_TaskBody struct {
|
||||
Req *types.DisableEvcMode_Task `xml:"urn:vim25 DisableEvcMode_Task,omitempty"`
|
||||
Res *types.DisableEvcMode_TaskResponse `xml:"DisableEvcMode_TaskResponse,omitempty"`
|
||||
|
@ -4583,6 +4723,26 @@ func DisconnectHost_Task(ctx context.Context, r soap.RoundTripper, req *types.Di
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type DisconnectNvmeControllerBody struct {
|
||||
Req *types.DisconnectNvmeController `xml:"urn:vim25 DisconnectNvmeController,omitempty"`
|
||||
Res *types.DisconnectNvmeControllerResponse `xml:"DisconnectNvmeControllerResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *DisconnectNvmeControllerBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func DisconnectNvmeController(ctx context.Context, r soap.RoundTripper, req *types.DisconnectNvmeController) (*types.DisconnectNvmeControllerResponse, error) {
|
||||
var reqBody, resBody DisconnectNvmeControllerBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type DiscoverFcoeHbasBody struct {
|
||||
Req *types.DiscoverFcoeHbas `xml:"urn:vim25 DiscoverFcoeHbas,omitempty"`
|
||||
Res *types.DiscoverFcoeHbasResponse `xml:"DiscoverFcoeHbasResponse,omitempty"`
|
||||
|
@ -4603,6 +4763,26 @@ func DiscoverFcoeHbas(ctx context.Context, r soap.RoundTripper, req *types.Disco
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type DiscoverNvmeControllersBody struct {
|
||||
Req *types.DiscoverNvmeControllers `xml:"urn:vim25 DiscoverNvmeControllers,omitempty"`
|
||||
Res *types.DiscoverNvmeControllersResponse `xml:"DiscoverNvmeControllersResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *DiscoverNvmeControllersBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func DiscoverNvmeControllers(ctx context.Context, r soap.RoundTripper, req *types.DiscoverNvmeControllers) (*types.DiscoverNvmeControllersResponse, error) {
|
||||
var reqBody, resBody DiscoverNvmeControllersBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type DissociateProfileBody struct {
|
||||
Req *types.DissociateProfile `xml:"urn:vim25 DissociateProfile,omitempty"`
|
||||
Res *types.DissociateProfileResponse `xml:"DissociateProfileResponse,omitempty"`
|
||||
|
@ -4643,6 +4823,26 @@ func DoesCustomizationSpecExist(ctx context.Context, r soap.RoundTripper, req *t
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type DownloadDescriptionTreeBody struct {
|
||||
Req *types.DownloadDescriptionTree `xml:"urn:vim25 DownloadDescriptionTree,omitempty"`
|
||||
Res *types.DownloadDescriptionTreeResponse `xml:"DownloadDescriptionTreeResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *DownloadDescriptionTreeBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func DownloadDescriptionTree(ctx context.Context, r soap.RoundTripper, req *types.DownloadDescriptionTree) (*types.DownloadDescriptionTreeResponse, error) {
|
||||
var reqBody, resBody DownloadDescriptionTreeBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type DuplicateCustomizationSpecBody struct {
|
||||
Req *types.DuplicateCustomizationSpec `xml:"urn:vim25 DuplicateCustomizationSpec,omitempty"`
|
||||
Res *types.DuplicateCustomizationSpecResponse `xml:"DuplicateCustomizationSpecResponse,omitempty"`
|
||||
|
@ -4703,6 +4903,26 @@ func EagerZeroVirtualDisk_Task(ctx context.Context, r soap.RoundTripper, req *ty
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type EnableAlarmBody struct {
|
||||
Req *types.EnableAlarm `xml:"urn:vim25 EnableAlarm,omitempty"`
|
||||
Res *types.EnableAlarmResponse `xml:"EnableAlarmResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *EnableAlarmBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func EnableAlarm(ctx context.Context, r soap.RoundTripper, req *types.EnableAlarm) (*types.EnableAlarmResponse, error) {
|
||||
var reqBody, resBody EnableAlarmBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type EnableAlarmActionsBody struct {
|
||||
Req *types.EnableAlarmActions `xml:"urn:vim25 EnableAlarmActions,omitempty"`
|
||||
Res *types.EnableAlarmActionsResponse `xml:"EnableAlarmActionsResponse,omitempty"`
|
||||
|
@ -4723,6 +4943,26 @@ func EnableAlarmActions(ctx context.Context, r soap.RoundTripper, req *types.Ena
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type EnableClusteredVmdkSupportBody struct {
|
||||
Req *types.EnableClusteredVmdkSupport `xml:"urn:vim25 EnableClusteredVmdkSupport,omitempty"`
|
||||
Res *types.EnableClusteredVmdkSupportResponse `xml:"EnableClusteredVmdkSupportResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *EnableClusteredVmdkSupportBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func EnableClusteredVmdkSupport(ctx context.Context, r soap.RoundTripper, req *types.EnableClusteredVmdkSupport) (*types.EnableClusteredVmdkSupportResponse, error) {
|
||||
var reqBody, resBody EnableClusteredVmdkSupportBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type EnableCryptoBody struct {
|
||||
Req *types.EnableCrypto `xml:"urn:vim25 EnableCrypto,omitempty"`
|
||||
Res *types.EnableCryptoResponse `xml:"EnableCryptoResponse,omitempty"`
|
||||
|
@ -5963,6 +6203,26 @@ func GetCustomizationSpec(ctx context.Context, r soap.RoundTripper, req *types.G
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type GetDefaultKmsClusterBody struct {
|
||||
Req *types.GetDefaultKmsCluster `xml:"urn:vim25 GetDefaultKmsCluster,omitempty"`
|
||||
Res *types.GetDefaultKmsClusterResponse `xml:"GetDefaultKmsClusterResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *GetDefaultKmsClusterBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func GetDefaultKmsCluster(ctx context.Context, r soap.RoundTripper, req *types.GetDefaultKmsCluster) (*types.GetDefaultKmsClusterResponse, error) {
|
||||
var reqBody, resBody GetDefaultKmsClusterBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type GetPublicKeyBody struct {
|
||||
Req *types.GetPublicKey `xml:"urn:vim25 GetPublicKey,omitempty"`
|
||||
Res *types.GetPublicKeyResponse `xml:"GetPublicKeyResponse,omitempty"`
|
||||
|
@ -6003,6 +6263,26 @@ func GetResourceUsage(ctx context.Context, r soap.RoundTripper, req *types.GetRe
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type GetSiteInfoBody struct {
|
||||
Req *types.GetSiteInfo `xml:"urn:vim25 GetSiteInfo,omitempty"`
|
||||
Res *types.GetSiteInfoResponse `xml:"GetSiteInfoResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *GetSiteInfoBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func GetSiteInfo(ctx context.Context, r soap.RoundTripper, req *types.GetSiteInfo) (*types.GetSiteInfoResponse, error) {
|
||||
var reqBody, resBody GetSiteInfoBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type GetVchaClusterHealthBody struct {
|
||||
Req *types.GetVchaClusterHealth `xml:"urn:vim25 GetVchaClusterHealth,omitempty"`
|
||||
Res *types.GetVchaClusterHealthResponse `xml:"GetVchaClusterHealthResponse,omitempty"`
|
||||
|
@ -7203,6 +7483,26 @@ func InstantClone_Task(ctx context.Context, r soap.RoundTripper, req *types.Inst
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type IsKmsClusterActiveBody struct {
|
||||
Req *types.IsKmsClusterActive `xml:"urn:vim25 IsKmsClusterActive,omitempty"`
|
||||
Res *types.IsKmsClusterActiveResponse `xml:"IsKmsClusterActiveResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *IsKmsClusterActiveBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func IsKmsClusterActive(ctx context.Context, r soap.RoundTripper, req *types.IsKmsClusterActive) (*types.IsKmsClusterActiveResponse, error) {
|
||||
var reqBody, resBody IsKmsClusterActiveBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type IsSharedGraphicsActiveBody struct {
|
||||
Req *types.IsSharedGraphicsActive `xml:"urn:vim25 IsSharedGraphicsActive,omitempty"`
|
||||
Res *types.IsSharedGraphicsActiveResponse `xml:"IsSharedGraphicsActiveResponse,omitempty"`
|
||||
|
@ -7423,6 +7723,26 @@ func ListKmipServers(ctx context.Context, r soap.RoundTripper, req *types.ListKm
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type ListKmsClustersBody struct {
|
||||
Req *types.ListKmsClusters `xml:"urn:vim25 ListKmsClusters,omitempty"`
|
||||
Res *types.ListKmsClustersResponse `xml:"ListKmsClustersResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *ListKmsClustersBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func ListKmsClusters(ctx context.Context, r soap.RoundTripper, req *types.ListKmsClusters) (*types.ListKmsClustersResponse, error) {
|
||||
var reqBody, resBody ListKmsClustersBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type ListProcessesInGuestBody struct {
|
||||
Req *types.ListProcessesInGuest `xml:"urn:vim25 ListProcessesInGuest,omitempty"`
|
||||
Res *types.ListProcessesInGuestResponse `xml:"ListProcessesInGuestResponse,omitempty"`
|
||||
|
@ -8003,6 +8323,26 @@ func MarkPerenniallyReservedEx_Task(ctx context.Context, r soap.RoundTripper, re
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type MarkServiceProviderEntitiesBody struct {
|
||||
Req *types.MarkServiceProviderEntities `xml:"urn:vim25 MarkServiceProviderEntities,omitempty"`
|
||||
Res *types.MarkServiceProviderEntitiesResponse `xml:"MarkServiceProviderEntitiesResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *MarkServiceProviderEntitiesBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func MarkServiceProviderEntities(ctx context.Context, r soap.RoundTripper, req *types.MarkServiceProviderEntities) (*types.MarkServiceProviderEntitiesResponse, error) {
|
||||
var reqBody, resBody MarkServiceProviderEntitiesBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type MergeDvs_TaskBody struct {
|
||||
Req *types.MergeDvs_Task `xml:"urn:vim25 MergeDvs_Task,omitempty"`
|
||||
Res *types.MergeDvs_TaskResponse `xml:"MergeDvs_TaskResponse,omitempty"`
|
||||
|
@ -11983,6 +12323,26 @@ func RegisterKmipServer(ctx context.Context, r soap.RoundTripper, req *types.Reg
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type RegisterKmsClusterBody struct {
|
||||
Req *types.RegisterKmsCluster `xml:"urn:vim25 RegisterKmsCluster,omitempty"`
|
||||
Res *types.RegisterKmsClusterResponse `xml:"RegisterKmsClusterResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *RegisterKmsClusterBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func RegisterKmsCluster(ctx context.Context, r soap.RoundTripper, req *types.RegisterKmsCluster) (*types.RegisterKmsClusterResponse, error) {
|
||||
var reqBody, resBody RegisterKmsClusterBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type RegisterVM_TaskBody struct {
|
||||
Req *types.RegisterVM_Task `xml:"urn:vim25 RegisterVM_Task,omitempty"`
|
||||
Res *types.RegisterVM_TaskResponse `xml:"RegisterVM_TaskResponse,omitempty"`
|
||||
|
@ -12603,6 +12963,26 @@ func RemoveNetworkResourcePool(ctx context.Context, r soap.RoundTripper, req *ty
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type RemoveNvmeOverRdmaAdapterBody struct {
|
||||
Req *types.RemoveNvmeOverRdmaAdapter `xml:"urn:vim25 RemoveNvmeOverRdmaAdapter,omitempty"`
|
||||
Res *types.RemoveNvmeOverRdmaAdapterResponse `xml:"RemoveNvmeOverRdmaAdapterResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *RemoveNvmeOverRdmaAdapterBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func RemoveNvmeOverRdmaAdapter(ctx context.Context, r soap.RoundTripper, req *types.RemoveNvmeOverRdmaAdapter) (*types.RemoveNvmeOverRdmaAdapterResponse, error) {
|
||||
var reqBody, resBody RemoveNvmeOverRdmaAdapterBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type RemovePerfIntervalBody struct {
|
||||
Req *types.RemovePerfInterval `xml:"urn:vim25 RemovePerfInterval,omitempty"`
|
||||
Res *types.RemovePerfIntervalResponse `xml:"RemovePerfIntervalResponse,omitempty"`
|
||||
|
@ -13563,6 +13943,26 @@ func RetrieveDiskPartitionInfo(ctx context.Context, r soap.RoundTripper, req *ty
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type RetrieveDynamicPassthroughInfoBody struct {
|
||||
Req *types.RetrieveDynamicPassthroughInfo `xml:"urn:vim25 RetrieveDynamicPassthroughInfo,omitempty"`
|
||||
Res *types.RetrieveDynamicPassthroughInfoResponse `xml:"RetrieveDynamicPassthroughInfoResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *RetrieveDynamicPassthroughInfoBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func RetrieveDynamicPassthroughInfo(ctx context.Context, r soap.RoundTripper, req *types.RetrieveDynamicPassthroughInfo) (*types.RetrieveDynamicPassthroughInfoResponse, error) {
|
||||
var reqBody, resBody RetrieveDynamicPassthroughInfoBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type RetrieveEntityPermissionsBody struct {
|
||||
Req *types.RetrieveEntityPermissions `xml:"urn:vim25 RetrieveEntityPermissions,omitempty"`
|
||||
Res *types.RetrieveEntityPermissionsResponse `xml:"RetrieveEntityPermissionsResponse,omitempty"`
|
||||
|
@ -13603,6 +14003,26 @@ func RetrieveEntityScheduledTask(ctx context.Context, r soap.RoundTripper, req *
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type RetrieveFreeEpcMemoryBody struct {
|
||||
Req *types.RetrieveFreeEpcMemory `xml:"urn:vim25 RetrieveFreeEpcMemory,omitempty"`
|
||||
Res *types.RetrieveFreeEpcMemoryResponse `xml:"RetrieveFreeEpcMemoryResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *RetrieveFreeEpcMemoryBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func RetrieveFreeEpcMemory(ctx context.Context, r soap.RoundTripper, req *types.RetrieveFreeEpcMemory) (*types.RetrieveFreeEpcMemoryResponse, error) {
|
||||
var reqBody, resBody RetrieveFreeEpcMemoryBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type RetrieveHardwareUptimeBody struct {
|
||||
Req *types.RetrieveHardwareUptime `xml:"urn:vim25 RetrieveHardwareUptime,omitempty"`
|
||||
Res *types.RetrieveHardwareUptimeResponse `xml:"RetrieveHardwareUptimeResponse,omitempty"`
|
||||
|
@ -13883,6 +14303,46 @@ func RetrieveServiceContent(ctx context.Context, r soap.RoundTripper, req *types
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type RetrieveServiceProviderEntitiesBody struct {
|
||||
Req *types.RetrieveServiceProviderEntities `xml:"urn:vim25 RetrieveServiceProviderEntities,omitempty"`
|
||||
Res *types.RetrieveServiceProviderEntitiesResponse `xml:"RetrieveServiceProviderEntitiesResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *RetrieveServiceProviderEntitiesBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func RetrieveServiceProviderEntities(ctx context.Context, r soap.RoundTripper, req *types.RetrieveServiceProviderEntities) (*types.RetrieveServiceProviderEntitiesResponse, error) {
|
||||
var reqBody, resBody RetrieveServiceProviderEntitiesBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type RetrieveSnapshotDetailsBody struct {
|
||||
Req *types.RetrieveSnapshotDetails `xml:"urn:vim25 RetrieveSnapshotDetails,omitempty"`
|
||||
Res *types.RetrieveSnapshotDetailsResponse `xml:"RetrieveSnapshotDetailsResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *RetrieveSnapshotDetailsBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func RetrieveSnapshotDetails(ctx context.Context, r soap.RoundTripper, req *types.RetrieveSnapshotDetails) (*types.RetrieveSnapshotDetailsResponse, error) {
|
||||
var reqBody, resBody RetrieveSnapshotDetailsBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type RetrieveSnapshotInfoBody struct {
|
||||
Req *types.RetrieveSnapshotInfo `xml:"urn:vim25 RetrieveSnapshotInfo,omitempty"`
|
||||
Res *types.RetrieveSnapshotInfoResponse `xml:"RetrieveSnapshotInfoResponse,omitempty"`
|
||||
|
@ -14363,6 +14823,46 @@ func SetCollectorPageSize(ctx context.Context, r soap.RoundTripper, req *types.S
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type SetCryptoModeBody struct {
|
||||
Req *types.SetCryptoMode `xml:"urn:vim25 SetCryptoMode,omitempty"`
|
||||
Res *types.SetCryptoModeResponse `xml:"SetCryptoModeResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *SetCryptoModeBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func SetCryptoMode(ctx context.Context, r soap.RoundTripper, req *types.SetCryptoMode) (*types.SetCryptoModeResponse, error) {
|
||||
var reqBody, resBody SetCryptoModeBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type SetDefaultKmsClusterBody struct {
|
||||
Req *types.SetDefaultKmsCluster `xml:"urn:vim25 SetDefaultKmsCluster,omitempty"`
|
||||
Res *types.SetDefaultKmsClusterResponse `xml:"SetDefaultKmsClusterResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *SetDefaultKmsClusterBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func SetDefaultKmsCluster(ctx context.Context, r soap.RoundTripper, req *types.SetDefaultKmsCluster) (*types.SetDefaultKmsClusterResponse, error) {
|
||||
var reqBody, resBody SetDefaultKmsClusterBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type SetDisplayTopologyBody struct {
|
||||
Req *types.SetDisplayTopology `xml:"urn:vim25 SetDisplayTopology,omitempty"`
|
||||
Res *types.SetDisplayTopologyResponse `xml:"SetDisplayTopologyResponse,omitempty"`
|
||||
|
@ -14783,6 +15283,26 @@ func StandbyGuest(ctx context.Context, r soap.RoundTripper, req *types.StandbyGu
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type StartGuestNetwork_TaskBody struct {
|
||||
Req *types.StartGuestNetwork_Task `xml:"urn:vim25 StartGuestNetwork_Task,omitempty"`
|
||||
Res *types.StartGuestNetwork_TaskResponse `xml:"StartGuestNetwork_TaskResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *StartGuestNetwork_TaskBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func StartGuestNetwork_Task(ctx context.Context, r soap.RoundTripper, req *types.StartGuestNetwork_Task) (*types.StartGuestNetwork_TaskResponse, error) {
|
||||
var reqBody, resBody StartGuestNetwork_TaskBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type StartProgramInGuestBody struct {
|
||||
Req *types.StartProgramInGuest `xml:"urn:vim25 StartProgramInGuest,omitempty"`
|
||||
Res *types.StartProgramInGuestResponse `xml:"StartProgramInGuestResponse,omitempty"`
|
||||
|
@ -15223,6 +15743,26 @@ func UnmapVmfsVolumeEx_Task(ctx context.Context, r soap.RoundTripper, req *types
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type UnmarkServiceProviderEntitiesBody struct {
|
||||
Req *types.UnmarkServiceProviderEntities `xml:"urn:vim25 UnmarkServiceProviderEntities,omitempty"`
|
||||
Res *types.UnmarkServiceProviderEntitiesResponse `xml:"UnmarkServiceProviderEntitiesResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *UnmarkServiceProviderEntitiesBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func UnmarkServiceProviderEntities(ctx context.Context, r soap.RoundTripper, req *types.UnmarkServiceProviderEntities) (*types.UnmarkServiceProviderEntitiesResponse, error) {
|
||||
var reqBody, resBody UnmarkServiceProviderEntitiesBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type UnmountDiskMapping_TaskBody struct {
|
||||
Req *types.UnmountDiskMapping_Task `xml:"urn:vim25 UnmountDiskMapping_Task,omitempty"`
|
||||
Res *types.UnmountDiskMapping_TaskResponse `xml:"UnmountDiskMapping_TaskResponse,omitempty"`
|
||||
|
@ -15403,6 +15943,26 @@ func UnregisterHealthUpdateProvider(ctx context.Context, r soap.RoundTripper, re
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type UnregisterKmsClusterBody struct {
|
||||
Req *types.UnregisterKmsCluster `xml:"urn:vim25 UnregisterKmsCluster,omitempty"`
|
||||
Res *types.UnregisterKmsClusterResponse `xml:"UnregisterKmsClusterResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *UnregisterKmsClusterBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func UnregisterKmsCluster(ctx context.Context, r soap.RoundTripper, req *types.UnregisterKmsCluster) (*types.UnregisterKmsClusterResponse, error) {
|
||||
var reqBody, resBody UnregisterKmsClusterBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type UnregisterVMBody struct {
|
||||
Req *types.UnregisterVM `xml:"urn:vim25 UnregisterVM,omitempty"`
|
||||
Res *types.UnregisterVMResponse `xml:"UnregisterVMResponse,omitempty"`
|
||||
|
@ -15443,6 +16003,26 @@ func UpdateAnswerFile_Task(ctx context.Context, r soap.RoundTripper, req *types.
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type UpdateAssignableHardwareConfigBody struct {
|
||||
Req *types.UpdateAssignableHardwareConfig `xml:"urn:vim25 UpdateAssignableHardwareConfig,omitempty"`
|
||||
Res *types.UpdateAssignableHardwareConfigResponse `xml:"UpdateAssignableHardwareConfigResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *UpdateAssignableHardwareConfigBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func UpdateAssignableHardwareConfig(ctx context.Context, r soap.RoundTripper, req *types.UpdateAssignableHardwareConfig) (*types.UpdateAssignableHardwareConfigResponse, error) {
|
||||
var reqBody, resBody UpdateAssignableHardwareConfigBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type UpdateAssignedLicenseBody struct {
|
||||
Req *types.UpdateAssignedLicense `xml:"urn:vim25 UpdateAssignedLicense,omitempty"`
|
||||
Res *types.UpdateAssignedLicenseResponse `xml:"UpdateAssignedLicenseResponse,omitempty"`
|
||||
|
@ -15923,6 +16503,26 @@ func UpdateHostSubSpecification(ctx context.Context, r soap.RoundTripper, req *t
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type UpdateHppMultipathLunPolicyBody struct {
|
||||
Req *types.UpdateHppMultipathLunPolicy `xml:"urn:vim25 UpdateHppMultipathLunPolicy,omitempty"`
|
||||
Res *types.UpdateHppMultipathLunPolicyResponse `xml:"UpdateHppMultipathLunPolicyResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *UpdateHppMultipathLunPolicyBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func UpdateHppMultipathLunPolicy(ctx context.Context, r soap.RoundTripper, req *types.UpdateHppMultipathLunPolicy) (*types.UpdateHppMultipathLunPolicyResponse, error) {
|
||||
var reqBody, resBody UpdateHppMultipathLunPolicyBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type UpdateInternetScsiAdvancedOptionsBody struct {
|
||||
Req *types.UpdateInternetScsiAdvancedOptions `xml:"urn:vim25 UpdateInternetScsiAdvancedOptions,omitempty"`
|
||||
Res *types.UpdateInternetScsiAdvancedOptionsResponse `xml:"UpdateInternetScsiAdvancedOptionsResponse,omitempty"`
|
||||
|
@ -16783,6 +17383,26 @@ func UpdateVStorageInfrastructureObjectPolicy_Task(ctx context.Context, r soap.R
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type UpdateVStorageObjectCrypto_TaskBody struct {
|
||||
Req *types.UpdateVStorageObjectCrypto_Task `xml:"urn:vim25 UpdateVStorageObjectCrypto_Task,omitempty"`
|
||||
Res *types.UpdateVStorageObjectCrypto_TaskResponse `xml:"UpdateVStorageObjectCrypto_TaskResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *UpdateVStorageObjectCrypto_TaskBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func UpdateVStorageObjectCrypto_Task(ctx context.Context, r soap.RoundTripper, req *types.UpdateVStorageObjectCrypto_Task) (*types.UpdateVStorageObjectCrypto_TaskResponse, error) {
|
||||
var reqBody, resBody UpdateVStorageObjectCrypto_TaskBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type UpdateVStorageObjectPolicy_TaskBody struct {
|
||||
Req *types.UpdateVStorageObjectPolicy_Task `xml:"urn:vim25 UpdateVStorageObjectPolicy_Task,omitempty"`
|
||||
Res *types.UpdateVStorageObjectPolicy_TaskResponse `xml:"UpdateVStorageObjectPolicy_TaskResponse,omitempty"`
|
||||
|
@ -17243,6 +17863,26 @@ func ValidateStoragePodConfig(ctx context.Context, r soap.RoundTripper, req *typ
|
|||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type VstorageObjectVCenterQueryChangedDiskAreasBody struct {
|
||||
Req *types.VstorageObjectVCenterQueryChangedDiskAreas `xml:"urn:vim25 VstorageObjectVCenterQueryChangedDiskAreas,omitempty"`
|
||||
Res *types.VstorageObjectVCenterQueryChangedDiskAreasResponse `xml:"VstorageObjectVCenterQueryChangedDiskAreasResponse,omitempty"`
|
||||
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
|
||||
}
|
||||
|
||||
func (b *VstorageObjectVCenterQueryChangedDiskAreasBody) Fault() *soap.Fault { return b.Fault_ }
|
||||
|
||||
func VstorageObjectVCenterQueryChangedDiskAreas(ctx context.Context, r soap.RoundTripper, req *types.VstorageObjectVCenterQueryChangedDiskAreas) (*types.VstorageObjectVCenterQueryChangedDiskAreasResponse, error) {
|
||||
var reqBody, resBody VstorageObjectVCenterQueryChangedDiskAreasBody
|
||||
|
||||
reqBody.Req = req
|
||||
|
||||
if err := r.RoundTrip(ctx, &reqBody, &resBody); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resBody.Res, nil
|
||||
}
|
||||
|
||||
type WaitForUpdatesBody struct {
|
||||
Req *types.WaitForUpdates `xml:"urn:vim25 WaitForUpdates,omitempty"`
|
||||
Res *types.WaitForUpdatesResponse `xml:"WaitForUpdatesResponse,omitempty"`
|
||||
|
|
|
@ -129,6 +129,7 @@ type ComputeResource struct {
|
|||
Summary types.BaseComputeResourceSummary `mo:"summary"`
|
||||
EnvironmentBrowser *types.ManagedObjectReference `mo:"environmentBrowser"`
|
||||
ConfigurationEx types.BaseComputeResourceConfigInfo `mo:"configurationEx"`
|
||||
LifecycleManaged *bool `mo:"lifecycleManaged"`
|
||||
}
|
||||
|
||||
func (m *ComputeResource) Entity() *ManagedEntity {
|
||||
|
@ -442,6 +443,7 @@ type Folder struct {
|
|||
|
||||
ChildType []string `mo:"childType"`
|
||||
ChildEntity []types.ManagedObjectReference `mo:"childEntity"`
|
||||
Namespace *string `mo:"namespace"`
|
||||
}
|
||||
|
||||
func (m *Folder) Entity() *ManagedEntity {
|
||||
|
@ -578,6 +580,21 @@ func init() {
|
|||
t["HostActiveDirectoryAuthentication"] = reflect.TypeOf((*HostActiveDirectoryAuthentication)(nil)).Elem()
|
||||
}
|
||||
|
||||
type HostAssignableHardwareManager struct {
|
||||
Self types.ManagedObjectReference
|
||||
|
||||
Binding []types.HostAssignableHardwareBinding `mo:"binding"`
|
||||
Config types.HostAssignableHardwareConfig `mo:"config"`
|
||||
}
|
||||
|
||||
func (m HostAssignableHardwareManager) Reference() types.ManagedObjectReference {
|
||||
return m.Self
|
||||
}
|
||||
|
||||
func init() {
|
||||
t["HostAssignableHardwareManager"] = reflect.TypeOf((*HostAssignableHardwareManager)(nil)).Elem()
|
||||
}
|
||||
|
||||
type HostAuthenticationManager struct {
|
||||
Self types.ManagedObjectReference
|
||||
|
||||
|
@ -1266,10 +1283,10 @@ func init() {
|
|||
type Network struct {
|
||||
ManagedEntity
|
||||
|
||||
Name string `mo:"name"`
|
||||
Summary types.BaseNetworkSummary `mo:"summary"`
|
||||
Host []types.ManagedObjectReference `mo:"host"`
|
||||
Vm []types.ManagedObjectReference `mo:"vm"`
|
||||
Name string `mo:"name"`
|
||||
}
|
||||
|
||||
func (m *Network) Entity() *ManagedEntity {
|
||||
|
@ -1445,6 +1462,7 @@ type ResourcePool struct {
|
|||
ResourcePool []types.ManagedObjectReference `mo:"resourcePool"`
|
||||
Vm []types.ManagedObjectReference `mo:"vm"`
|
||||
Config types.ResourceConfigSpec `mo:"config"`
|
||||
Namespace *string `mo:"namespace"`
|
||||
ChildConfiguration []types.ResourceConfigSpec `mo:"childConfiguration"`
|
||||
}
|
||||
|
||||
|
@ -1557,6 +1575,18 @@ func init() {
|
|||
t["SimpleCommand"] = reflect.TypeOf((*SimpleCommand)(nil)).Elem()
|
||||
}
|
||||
|
||||
type SiteInfoManager struct {
|
||||
Self types.ManagedObjectReference
|
||||
}
|
||||
|
||||
func (m SiteInfoManager) Reference() types.ManagedObjectReference {
|
||||
return m.Self
|
||||
}
|
||||
|
||||
func init() {
|
||||
t["SiteInfoManager"] = reflect.TypeOf((*SiteInfoManager)(nil)).Elem()
|
||||
}
|
||||
|
||||
type StoragePod struct {
|
||||
Folder
|
||||
|
||||
|
@ -1568,6 +1598,18 @@ func init() {
|
|||
t["StoragePod"] = reflect.TypeOf((*StoragePod)(nil)).Elem()
|
||||
}
|
||||
|
||||
type StorageQueryManager struct {
|
||||
Self types.ManagedObjectReference
|
||||
}
|
||||
|
||||
func (m StorageQueryManager) Reference() types.ManagedObjectReference {
|
||||
return m.Self
|
||||
}
|
||||
|
||||
func init() {
|
||||
t["StorageQueryManager"] = reflect.TypeOf((*StorageQueryManager)(nil)).Elem()
|
||||
}
|
||||
|
||||
type StorageResourceManager struct {
|
||||
Self types.ManagedObjectReference
|
||||
}
|
||||
|
@ -1616,6 +1658,18 @@ func init() {
|
|||
t["TaskManager"] = reflect.TypeOf((*TaskManager)(nil)).Elem()
|
||||
}
|
||||
|
||||
type TenantTenantManager struct {
|
||||
Self types.ManagedObjectReference
|
||||
}
|
||||
|
||||
func (m TenantTenantManager) Reference() types.ManagedObjectReference {
|
||||
return m.Self
|
||||
}
|
||||
|
||||
func init() {
|
||||
t["TenantTenantManager"] = reflect.TypeOf((*TenantTenantManager)(nil)).Elem()
|
||||
}
|
||||
|
||||
type UserDirectory struct {
|
||||
Self types.ManagedObjectReference
|
||||
|
||||
|
@ -1745,6 +1799,18 @@ func init() {
|
|||
t["VirtualMachineCompatibilityChecker"] = reflect.TypeOf((*VirtualMachineCompatibilityChecker)(nil)).Elem()
|
||||
}
|
||||
|
||||
type VirtualMachineGuestCustomizationManager struct {
|
||||
Self types.ManagedObjectReference
|
||||
}
|
||||
|
||||
func (m VirtualMachineGuestCustomizationManager) Reference() types.ManagedObjectReference {
|
||||
return m.Self
|
||||
}
|
||||
|
||||
func init() {
|
||||
t["VirtualMachineGuestCustomizationManager"] = reflect.TypeOf((*VirtualMachineGuestCustomizationManager)(nil)).Elem()
|
||||
}
|
||||
|
||||
type VirtualMachineProvisioningChecker struct {
|
||||
Self types.ManagedObjectReference
|
||||
}
|
||||
|
|
|
@ -159,6 +159,10 @@ func NewClient(u *url.URL, insecure bool) *Client {
|
|||
return &c
|
||||
}
|
||||
|
||||
func (c *Client) DefaultTransport() *http.Transport {
|
||||
return c.t
|
||||
}
|
||||
|
||||
// NewServiceClient creates a NewClient with the given URL.Path and namespace.
|
||||
func (c *Client) NewServiceClient(path string, namespace string) *Client {
|
||||
vc := c.URL()
|
||||
|
@ -173,7 +177,7 @@ func (c *Client) NewServiceClient(path string, namespace string) *Client {
|
|||
|
||||
client := NewClient(u, c.k)
|
||||
client.Namespace = "urn:" + namespace
|
||||
client.Transport.(*http.Transport).TLSClientConfig = c.Transport.(*http.Transport).TLSClientConfig
|
||||
client.DefaultTransport().TLSClientConfig = c.DefaultTransport().TLSClientConfig
|
||||
if cert := c.Certificate(); cert != nil {
|
||||
client.SetCertificate(*cert)
|
||||
}
|
||||
|
|
|
@ -200,8 +200,7 @@ func init() {
|
|||
type CannotEnableVmcpForClusterReason string
|
||||
|
||||
const (
|
||||
CannotEnableVmcpForClusterReasonAPDTimeoutDisabled = CannotEnableVmcpForClusterReason("APDTimeoutDisabled")
|
||||
CannotEnableVmcpForClusterReasonIncompatibleHostVersion = CannotEnableVmcpForClusterReason("IncompatibleHostVersion")
|
||||
CannotEnableVmcpForClusterReasonAPDTimeoutDisabled = CannotEnableVmcpForClusterReason("APDTimeoutDisabled")
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -239,6 +238,8 @@ const (
|
|||
CannotUseNetworkReasonMismatchedNetworkPolicies = CannotUseNetworkReason("MismatchedNetworkPolicies")
|
||||
CannotUseNetworkReasonMismatchedDvsVersionOrVendor = CannotUseNetworkReason("MismatchedDvsVersionOrVendor")
|
||||
CannotUseNetworkReasonVMotionToUnsupportedNetworkType = CannotUseNetworkReason("VMotionToUnsupportedNetworkType")
|
||||
CannotUseNetworkReasonNetworkUnderMaintenance = CannotUseNetworkReason("NetworkUnderMaintenance")
|
||||
CannotUseNetworkReasonMismatchedEnsMode = CannotUseNetworkReason("MismatchedEnsMode")
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -271,6 +272,17 @@ func init() {
|
|||
t["ClusterComputeResourceHCIWorkflowState"] = reflect.TypeOf((*ClusterComputeResourceHCIWorkflowState)(nil)).Elem()
|
||||
}
|
||||
|
||||
type ClusterCryptoConfigInfoCryptoMode string
|
||||
|
||||
const (
|
||||
ClusterCryptoConfigInfoCryptoModeOnDemand = ClusterCryptoConfigInfoCryptoMode("onDemand")
|
||||
ClusterCryptoConfigInfoCryptoModeForceEnable = ClusterCryptoConfigInfoCryptoMode("forceEnable")
|
||||
)
|
||||
|
||||
func init() {
|
||||
t["ClusterCryptoConfigInfoCryptoMode"] = reflect.TypeOf((*ClusterCryptoConfigInfoCryptoMode)(nil)).Elem()
|
||||
}
|
||||
|
||||
type ClusterDasAamNodeStateDasState string
|
||||
|
||||
const (
|
||||
|
@ -509,17 +521,28 @@ func init() {
|
|||
type CryptoManagerKmipCryptoKeyStatusKeyUnavailableReason string
|
||||
|
||||
const (
|
||||
CryptoManagerKmipCryptoKeyStatusKeyUnavailableReasonKeyStateMissingInCache = CryptoManagerKmipCryptoKeyStatusKeyUnavailableReason("KeyStateMissingInCache")
|
||||
CryptoManagerKmipCryptoKeyStatusKeyUnavailableReasonKeyStateClusterInvalid = CryptoManagerKmipCryptoKeyStatusKeyUnavailableReason("KeyStateClusterInvalid")
|
||||
CryptoManagerKmipCryptoKeyStatusKeyUnavailableReasonKeyStateClusterUnreachable = CryptoManagerKmipCryptoKeyStatusKeyUnavailableReason("KeyStateClusterUnreachable")
|
||||
CryptoManagerKmipCryptoKeyStatusKeyUnavailableReasonKeyStateMissingInKMS = CryptoManagerKmipCryptoKeyStatusKeyUnavailableReason("KeyStateMissingInKMS")
|
||||
CryptoManagerKmipCryptoKeyStatusKeyUnavailableReasonKeyStateNotActiveOrEnabled = CryptoManagerKmipCryptoKeyStatusKeyUnavailableReason("KeyStateNotActiveOrEnabled")
|
||||
CryptoManagerKmipCryptoKeyStatusKeyUnavailableReasonKeyStateMissingInCache = CryptoManagerKmipCryptoKeyStatusKeyUnavailableReason("KeyStateMissingInCache")
|
||||
CryptoManagerKmipCryptoKeyStatusKeyUnavailableReasonKeyStateClusterInvalid = CryptoManagerKmipCryptoKeyStatusKeyUnavailableReason("KeyStateClusterInvalid")
|
||||
CryptoManagerKmipCryptoKeyStatusKeyUnavailableReasonKeyStateClusterUnreachable = CryptoManagerKmipCryptoKeyStatusKeyUnavailableReason("KeyStateClusterUnreachable")
|
||||
CryptoManagerKmipCryptoKeyStatusKeyUnavailableReasonKeyStateMissingInKMS = CryptoManagerKmipCryptoKeyStatusKeyUnavailableReason("KeyStateMissingInKMS")
|
||||
CryptoManagerKmipCryptoKeyStatusKeyUnavailableReasonKeyStateNotActiveOrEnabled = CryptoManagerKmipCryptoKeyStatusKeyUnavailableReason("KeyStateNotActiveOrEnabled")
|
||||
CryptoManagerKmipCryptoKeyStatusKeyUnavailableReasonKeyStateManagedByTrustAuthority = CryptoManagerKmipCryptoKeyStatusKeyUnavailableReason("KeyStateManagedByTrustAuthority")
|
||||
)
|
||||
|
||||
func init() {
|
||||
t["CryptoManagerKmipCryptoKeyStatusKeyUnavailableReason"] = reflect.TypeOf((*CryptoManagerKmipCryptoKeyStatusKeyUnavailableReason)(nil)).Elem()
|
||||
}
|
||||
|
||||
type CustomizationFailedReasonCode string
|
||||
|
||||
const (
|
||||
CustomizationFailedReasonCodeUserDefinedScriptDisabled = CustomizationFailedReasonCode("userDefinedScriptDisabled")
|
||||
)
|
||||
|
||||
func init() {
|
||||
t["CustomizationFailedReasonCode"] = reflect.TypeOf((*CustomizationFailedReasonCode)(nil)).Elem()
|
||||
}
|
||||
|
||||
type CustomizationLicenseDataMode string
|
||||
|
||||
const (
|
||||
|
@ -602,6 +625,8 @@ const (
|
|||
DasConfigFaultDasConfigFaultReasonCreateConfigVvolFailed = DasConfigFaultDasConfigFaultReason("CreateConfigVvolFailed")
|
||||
DasConfigFaultDasConfigFaultReasonVSanNotSupportedOnHost = DasConfigFaultDasConfigFaultReason("VSanNotSupportedOnHost")
|
||||
DasConfigFaultDasConfigFaultReasonDasNetworkMisconfiguration = DasConfigFaultDasConfigFaultReason("DasNetworkMisconfiguration")
|
||||
DasConfigFaultDasConfigFaultReasonSetDesiredImageSpecFailed = DasConfigFaultDasConfigFaultReason("SetDesiredImageSpecFailed")
|
||||
DasConfigFaultDasConfigFaultReasonApplyHAVibsOnClusterFailed = DasConfigFaultDasConfigFaultReason("ApplyHAVibsOnClusterFailed")
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -729,6 +754,17 @@ func init() {
|
|||
t["DisallowedChangeByServiceDisallowedChange"] = reflect.TypeOf((*DisallowedChangeByServiceDisallowedChange)(nil)).Elem()
|
||||
}
|
||||
|
||||
type DistributedVirtualPortgroupBackingType string
|
||||
|
||||
const (
|
||||
DistributedVirtualPortgroupBackingTypeStandard = DistributedVirtualPortgroupBackingType("standard")
|
||||
DistributedVirtualPortgroupBackingTypeNsx = DistributedVirtualPortgroupBackingType("nsx")
|
||||
)
|
||||
|
||||
func init() {
|
||||
t["DistributedVirtualPortgroupBackingType"] = reflect.TypeOf((*DistributedVirtualPortgroupBackingType)(nil)).Elem()
|
||||
}
|
||||
|
||||
type DistributedVirtualPortgroupMetaTagName string
|
||||
|
||||
const (
|
||||
|
@ -786,6 +822,17 @@ func init() {
|
|||
t["DistributedVirtualSwitchHostMemberHostComponentState"] = reflect.TypeOf((*DistributedVirtualSwitchHostMemberHostComponentState)(nil)).Elem()
|
||||
}
|
||||
|
||||
type DistributedVirtualSwitchHostMemberTransportZoneType string
|
||||
|
||||
const (
|
||||
DistributedVirtualSwitchHostMemberTransportZoneTypeVlan = DistributedVirtualSwitchHostMemberTransportZoneType("vlan")
|
||||
DistributedVirtualSwitchHostMemberTransportZoneTypeOverlay = DistributedVirtualSwitchHostMemberTransportZoneType("overlay")
|
||||
)
|
||||
|
||||
func init() {
|
||||
t["DistributedVirtualSwitchHostMemberTransportZoneType"] = reflect.TypeOf((*DistributedVirtualSwitchHostMemberTransportZoneType)(nil)).Elem()
|
||||
}
|
||||
|
||||
type DistributedVirtualSwitchNetworkResourceControlVersion string
|
||||
|
||||
const (
|
||||
|
@ -1272,9 +1319,10 @@ func init() {
|
|||
type HostCryptoState string
|
||||
|
||||
const (
|
||||
HostCryptoStateIncapable = HostCryptoState("incapable")
|
||||
HostCryptoStatePrepared = HostCryptoState("prepared")
|
||||
HostCryptoStateSafe = HostCryptoState("safe")
|
||||
HostCryptoStateIncapable = HostCryptoState("incapable")
|
||||
HostCryptoStatePrepared = HostCryptoState("prepared")
|
||||
HostCryptoStateSafe = HostCryptoState("safe")
|
||||
HostCryptoStatePendingIncapable = HostCryptoState("pendingIncapable")
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -1298,6 +1346,17 @@ func init() {
|
|||
t["HostDasErrorEventHostDasErrorReason"] = reflect.TypeOf((*HostDasErrorEventHostDasErrorReason)(nil)).Elem()
|
||||
}
|
||||
|
||||
type HostDateTimeInfoProtocol string
|
||||
|
||||
const (
|
||||
HostDateTimeInfoProtocolNtp = HostDateTimeInfoProtocol("ntp")
|
||||
HostDateTimeInfoProtocolPtp = HostDateTimeInfoProtocol("ptp")
|
||||
)
|
||||
|
||||
func init() {
|
||||
t["HostDateTimeInfoProtocol"] = reflect.TypeOf((*HostDateTimeInfoProtocol)(nil)).Elem()
|
||||
}
|
||||
|
||||
type HostDigestInfoDigestMethodType string
|
||||
|
||||
const (
|
||||
|
@ -1670,6 +1729,16 @@ func init() {
|
|||
t["HostLowLevelProvisioningManagerReloadTarget"] = reflect.TypeOf((*HostLowLevelProvisioningManagerReloadTarget)(nil)).Elem()
|
||||
}
|
||||
|
||||
type HostMaintenanceSpecPurpose string
|
||||
|
||||
const (
|
||||
HostMaintenanceSpecPurposeHostUpgrade = HostMaintenanceSpecPurpose("hostUpgrade")
|
||||
)
|
||||
|
||||
func init() {
|
||||
t["HostMaintenanceSpecPurpose"] = reflect.TypeOf((*HostMaintenanceSpecPurpose)(nil)).Elem()
|
||||
}
|
||||
|
||||
type HostMountInfoInaccessibleReason string
|
||||
|
||||
const (
|
||||
|
@ -1763,12 +1832,65 @@ func init() {
|
|||
t["HostNumericSensorType"] = reflect.TypeOf((*HostNumericSensorType)(nil)).Elem()
|
||||
}
|
||||
|
||||
type HostNvmeDiscoveryLogSubsystemType string
|
||||
|
||||
const (
|
||||
HostNvmeDiscoveryLogSubsystemTypeDiscovery = HostNvmeDiscoveryLogSubsystemType("discovery")
|
||||
HostNvmeDiscoveryLogSubsystemTypeNvm = HostNvmeDiscoveryLogSubsystemType("nvm")
|
||||
)
|
||||
|
||||
func init() {
|
||||
t["HostNvmeDiscoveryLogSubsystemType"] = reflect.TypeOf((*HostNvmeDiscoveryLogSubsystemType)(nil)).Elem()
|
||||
}
|
||||
|
||||
type HostNvmeDiscoveryLogTransportRequirements string
|
||||
|
||||
const (
|
||||
HostNvmeDiscoveryLogTransportRequirementsSecureChannelRequired = HostNvmeDiscoveryLogTransportRequirements("secureChannelRequired")
|
||||
HostNvmeDiscoveryLogTransportRequirementsSecureChannelNotRequired = HostNvmeDiscoveryLogTransportRequirements("secureChannelNotRequired")
|
||||
HostNvmeDiscoveryLogTransportRequirementsRequirementsNotSpecified = HostNvmeDiscoveryLogTransportRequirements("requirementsNotSpecified")
|
||||
)
|
||||
|
||||
func init() {
|
||||
t["HostNvmeDiscoveryLogTransportRequirements"] = reflect.TypeOf((*HostNvmeDiscoveryLogTransportRequirements)(nil)).Elem()
|
||||
}
|
||||
|
||||
type HostNvmeTransportParametersNvmeAddressFamily string
|
||||
|
||||
const (
|
||||
HostNvmeTransportParametersNvmeAddressFamilyIpv4 = HostNvmeTransportParametersNvmeAddressFamily("ipv4")
|
||||
HostNvmeTransportParametersNvmeAddressFamilyIpv6 = HostNvmeTransportParametersNvmeAddressFamily("ipv6")
|
||||
HostNvmeTransportParametersNvmeAddressFamilyInfiniBand = HostNvmeTransportParametersNvmeAddressFamily("infiniBand")
|
||||
HostNvmeTransportParametersNvmeAddressFamilyFc = HostNvmeTransportParametersNvmeAddressFamily("fc")
|
||||
HostNvmeTransportParametersNvmeAddressFamilyLoopback = HostNvmeTransportParametersNvmeAddressFamily("loopback")
|
||||
HostNvmeTransportParametersNvmeAddressFamilyUnknown = HostNvmeTransportParametersNvmeAddressFamily("unknown")
|
||||
)
|
||||
|
||||
func init() {
|
||||
t["HostNvmeTransportParametersNvmeAddressFamily"] = reflect.TypeOf((*HostNvmeTransportParametersNvmeAddressFamily)(nil)).Elem()
|
||||
}
|
||||
|
||||
type HostNvmeTransportType string
|
||||
|
||||
const (
|
||||
HostNvmeTransportTypePcie = HostNvmeTransportType("pcie")
|
||||
HostNvmeTransportTypeFibreChannel = HostNvmeTransportType("fibreChannel")
|
||||
HostNvmeTransportTypeRdma = HostNvmeTransportType("rdma")
|
||||
HostNvmeTransportTypeLoopback = HostNvmeTransportType("loopback")
|
||||
HostNvmeTransportTypeUnsupported = HostNvmeTransportType("unsupported")
|
||||
)
|
||||
|
||||
func init() {
|
||||
t["HostNvmeTransportType"] = reflect.TypeOf((*HostNvmeTransportType)(nil)).Elem()
|
||||
}
|
||||
|
||||
type HostOpaqueSwitchOpaqueSwitchState string
|
||||
|
||||
const (
|
||||
HostOpaqueSwitchOpaqueSwitchStateUp = HostOpaqueSwitchOpaqueSwitchState("up")
|
||||
HostOpaqueSwitchOpaqueSwitchStateWarning = HostOpaqueSwitchOpaqueSwitchState("warning")
|
||||
HostOpaqueSwitchOpaqueSwitchStateDown = HostOpaqueSwitchOpaqueSwitchState("down")
|
||||
HostOpaqueSwitchOpaqueSwitchStateUp = HostOpaqueSwitchOpaqueSwitchState("up")
|
||||
HostOpaqueSwitchOpaqueSwitchStateWarning = HostOpaqueSwitchOpaqueSwitchState("warning")
|
||||
HostOpaqueSwitchOpaqueSwitchStateDown = HostOpaqueSwitchOpaqueSwitchState("down")
|
||||
HostOpaqueSwitchOpaqueSwitchStateMaintenance = HostOpaqueSwitchOpaqueSwitchState("maintenance")
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -1921,6 +2043,21 @@ func init() {
|
|||
t["HostProtocolEndpointProtocolEndpointType"] = reflect.TypeOf((*HostProtocolEndpointProtocolEndpointType)(nil)).Elem()
|
||||
}
|
||||
|
||||
type HostRdmaDeviceConnectionState string
|
||||
|
||||
const (
|
||||
HostRdmaDeviceConnectionStateUnknown = HostRdmaDeviceConnectionState("unknown")
|
||||
HostRdmaDeviceConnectionStateDown = HostRdmaDeviceConnectionState("down")
|
||||
HostRdmaDeviceConnectionStateInit = HostRdmaDeviceConnectionState("init")
|
||||
HostRdmaDeviceConnectionStateArmed = HostRdmaDeviceConnectionState("armed")
|
||||
HostRdmaDeviceConnectionStateActive = HostRdmaDeviceConnectionState("active")
|
||||
HostRdmaDeviceConnectionStateActiveDefer = HostRdmaDeviceConnectionState("activeDefer")
|
||||
)
|
||||
|
||||
func init() {
|
||||
t["HostRdmaDeviceConnectionState"] = reflect.TypeOf((*HostRdmaDeviceConnectionState)(nil)).Elem()
|
||||
}
|
||||
|
||||
type HostReplayUnsupportedReason string
|
||||
|
||||
const (
|
||||
|
@ -1961,6 +2098,35 @@ func init() {
|
|||
t["HostServicePolicy"] = reflect.TypeOf((*HostServicePolicy)(nil)).Elem()
|
||||
}
|
||||
|
||||
type HostSgxInfoFlcModes string
|
||||
|
||||
const (
|
||||
HostSgxInfoFlcModesOff = HostSgxInfoFlcModes("off")
|
||||
HostSgxInfoFlcModesLocked = HostSgxInfoFlcModes("locked")
|
||||
HostSgxInfoFlcModesUnlocked = HostSgxInfoFlcModes("unlocked")
|
||||
)
|
||||
|
||||
func init() {
|
||||
t["HostSgxInfoFlcModes"] = reflect.TypeOf((*HostSgxInfoFlcModes)(nil)).Elem()
|
||||
}
|
||||
|
||||
type HostSgxInfoSgxStates string
|
||||
|
||||
const (
|
||||
HostSgxInfoSgxStatesNotPresent = HostSgxInfoSgxStates("notPresent")
|
||||
HostSgxInfoSgxStatesDisabledBIOS = HostSgxInfoSgxStates("disabledBIOS")
|
||||
HostSgxInfoSgxStatesDisabledCFW101 = HostSgxInfoSgxStates("disabledCFW101")
|
||||
HostSgxInfoSgxStatesDisabledCPUMismatch = HostSgxInfoSgxStates("disabledCPUMismatch")
|
||||
HostSgxInfoSgxStatesDisabledNoFLC = HostSgxInfoSgxStates("disabledNoFLC")
|
||||
HostSgxInfoSgxStatesDisabledNUMAUnsup = HostSgxInfoSgxStates("disabledNUMAUnsup")
|
||||
HostSgxInfoSgxStatesDisabledMaxEPCRegs = HostSgxInfoSgxStates("disabledMaxEPCRegs")
|
||||
HostSgxInfoSgxStatesEnabled = HostSgxInfoSgxStates("enabled")
|
||||
)
|
||||
|
||||
func init() {
|
||||
t["HostSgxInfoSgxStates"] = reflect.TypeOf((*HostSgxInfoSgxStates)(nil)).Elem()
|
||||
}
|
||||
|
||||
type HostSnmpAgentCapability string
|
||||
|
||||
const (
|
||||
|
@ -1986,6 +2152,17 @@ func init() {
|
|||
t["HostStandbyMode"] = reflect.TypeOf((*HostStandbyMode)(nil)).Elem()
|
||||
}
|
||||
|
||||
type HostStorageProtocol string
|
||||
|
||||
const (
|
||||
HostStorageProtocolScsi = HostStorageProtocol("scsi")
|
||||
HostStorageProtocolNvme = HostStorageProtocol("nvme")
|
||||
)
|
||||
|
||||
func init() {
|
||||
t["HostStorageProtocol"] = reflect.TypeOf((*HostStorageProtocol)(nil)).Elem()
|
||||
}
|
||||
|
||||
type HostSystemConnectionState string
|
||||
|
||||
const (
|
||||
|
@ -2084,6 +2261,8 @@ const (
|
|||
HostVirtualNicManagerNicTypeVsan = HostVirtualNicManagerNicType("vsan")
|
||||
HostVirtualNicManagerNicTypeVSphereProvisioning = HostVirtualNicManagerNicType("vSphereProvisioning")
|
||||
HostVirtualNicManagerNicTypeVsanWitness = HostVirtualNicManagerNicType("vsanWitness")
|
||||
HostVirtualNicManagerNicTypeVSphereBackupNFC = HostVirtualNicManagerNicType("vSphereBackupNFC")
|
||||
HostVirtualNicManagerNicTypePtp = HostVirtualNicManagerNicType("ptp")
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -2246,6 +2425,18 @@ func init() {
|
|||
t["IscsiPortInfoPathStatus"] = reflect.TypeOf((*IscsiPortInfoPathStatus)(nil)).Elem()
|
||||
}
|
||||
|
||||
type KmipClusterInfoKmsManagementType string
|
||||
|
||||
const (
|
||||
KmipClusterInfoKmsManagementTypeUnknown = KmipClusterInfoKmsManagementType("unknown")
|
||||
KmipClusterInfoKmsManagementTypeVCenter = KmipClusterInfoKmsManagementType("vCenter")
|
||||
KmipClusterInfoKmsManagementTypeTrustAuthority = KmipClusterInfoKmsManagementType("trustAuthority")
|
||||
)
|
||||
|
||||
func init() {
|
||||
t["KmipClusterInfoKmsManagementType"] = reflect.TypeOf((*KmipClusterInfoKmsManagementType)(nil)).Elem()
|
||||
}
|
||||
|
||||
type LatencySensitivitySensitivityLevel string
|
||||
|
||||
const (
|
||||
|
@ -2717,6 +2908,7 @@ const (
|
|||
PerformanceManagerUnitWatt = PerformanceManagerUnit("watt")
|
||||
PerformanceManagerUnitJoule = PerformanceManagerUnit("joule")
|
||||
PerformanceManagerUnitTeraBytes = PerformanceManagerUnit("teraBytes")
|
||||
PerformanceManagerUnitCelsius = PerformanceManagerUnit("celsius")
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -2907,6 +3099,9 @@ const (
|
|||
RecommendationReasonCodeHostExitDegradation = RecommendationReasonCode("hostExitDegradation")
|
||||
RecommendationReasonCodeMaxVmsConstraint = RecommendationReasonCode("maxVmsConstraint")
|
||||
RecommendationReasonCodeFtConstraints = RecommendationReasonCode("ftConstraints")
|
||||
RecommendationReasonCodeVmHostAffinityPolicy = RecommendationReasonCode("vmHostAffinityPolicy")
|
||||
RecommendationReasonCodeVmHostAntiAffinityPolicy = RecommendationReasonCode("vmHostAntiAffinityPolicy")
|
||||
RecommendationReasonCodeVmAntiAffinityPolicy = RecommendationReasonCode("vmAntiAffinityPolicy")
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -3009,6 +3204,17 @@ func init() {
|
|||
t["ReplicationVmState"] = reflect.TypeOf((*ReplicationVmState)(nil)).Elem()
|
||||
}
|
||||
|
||||
type ResourceConfigSpecScaleSharesBehavior string
|
||||
|
||||
const (
|
||||
ResourceConfigSpecScaleSharesBehaviorDisabled = ResourceConfigSpecScaleSharesBehavior("disabled")
|
||||
ResourceConfigSpecScaleSharesBehaviorScaleCpuAndMemoryShares = ResourceConfigSpecScaleSharesBehavior("scaleCpuAndMemoryShares")
|
||||
)
|
||||
|
||||
func init() {
|
||||
t["ResourceConfigSpecScaleSharesBehavior"] = reflect.TypeOf((*ResourceConfigSpecScaleSharesBehavior)(nil)).Elem()
|
||||
}
|
||||
|
||||
type ScheduledHardwareUpgradeInfoHardwareUpgradePolicy string
|
||||
|
||||
const (
|
||||
|
@ -4108,6 +4314,7 @@ const (
|
|||
VirtualMachineGuestOsIdentifierWindows9_64Guest = VirtualMachineGuestOsIdentifier("windows9_64Guest")
|
||||
VirtualMachineGuestOsIdentifierWindows9Server64Guest = VirtualMachineGuestOsIdentifier("windows9Server64Guest")
|
||||
VirtualMachineGuestOsIdentifierWindowsHyperVGuest = VirtualMachineGuestOsIdentifier("windowsHyperVGuest")
|
||||
VirtualMachineGuestOsIdentifierWindows2019srv_64Guest = VirtualMachineGuestOsIdentifier("windows2019srv_64Guest")
|
||||
VirtualMachineGuestOsIdentifierFreebsdGuest = VirtualMachineGuestOsIdentifier("freebsdGuest")
|
||||
VirtualMachineGuestOsIdentifierFreebsd64Guest = VirtualMachineGuestOsIdentifier("freebsd64Guest")
|
||||
VirtualMachineGuestOsIdentifierFreebsd11Guest = VirtualMachineGuestOsIdentifier("freebsd11Guest")
|
||||
|
@ -4176,6 +4383,8 @@ const (
|
|||
VirtualMachineGuestOsIdentifierDebian9_64Guest = VirtualMachineGuestOsIdentifier("debian9_64Guest")
|
||||
VirtualMachineGuestOsIdentifierDebian10Guest = VirtualMachineGuestOsIdentifier("debian10Guest")
|
||||
VirtualMachineGuestOsIdentifierDebian10_64Guest = VirtualMachineGuestOsIdentifier("debian10_64Guest")
|
||||
VirtualMachineGuestOsIdentifierDebian11Guest = VirtualMachineGuestOsIdentifier("debian11Guest")
|
||||
VirtualMachineGuestOsIdentifierDebian11_64Guest = VirtualMachineGuestOsIdentifier("debian11_64Guest")
|
||||
VirtualMachineGuestOsIdentifierAsianux3Guest = VirtualMachineGuestOsIdentifier("asianux3Guest")
|
||||
VirtualMachineGuestOsIdentifierAsianux3_64Guest = VirtualMachineGuestOsIdentifier("asianux3_64Guest")
|
||||
VirtualMachineGuestOsIdentifierAsianux4Guest = VirtualMachineGuestOsIdentifier("asianux4Guest")
|
||||
|
@ -4229,11 +4438,14 @@ const (
|
|||
VirtualMachineGuestOsIdentifierDarwin16_64Guest = VirtualMachineGuestOsIdentifier("darwin16_64Guest")
|
||||
VirtualMachineGuestOsIdentifierDarwin17_64Guest = VirtualMachineGuestOsIdentifier("darwin17_64Guest")
|
||||
VirtualMachineGuestOsIdentifierDarwin18_64Guest = VirtualMachineGuestOsIdentifier("darwin18_64Guest")
|
||||
VirtualMachineGuestOsIdentifierDarwin19_64Guest = VirtualMachineGuestOsIdentifier("darwin19_64Guest")
|
||||
VirtualMachineGuestOsIdentifierVmkernelGuest = VirtualMachineGuestOsIdentifier("vmkernelGuest")
|
||||
VirtualMachineGuestOsIdentifierVmkernel5Guest = VirtualMachineGuestOsIdentifier("vmkernel5Guest")
|
||||
VirtualMachineGuestOsIdentifierVmkernel6Guest = VirtualMachineGuestOsIdentifier("vmkernel6Guest")
|
||||
VirtualMachineGuestOsIdentifierVmkernel65Guest = VirtualMachineGuestOsIdentifier("vmkernel65Guest")
|
||||
VirtualMachineGuestOsIdentifierVmkernel7Guest = VirtualMachineGuestOsIdentifier("vmkernel7Guest")
|
||||
VirtualMachineGuestOsIdentifierAmazonlinux2_64Guest = VirtualMachineGuestOsIdentifier("amazonlinux2_64Guest")
|
||||
VirtualMachineGuestOsIdentifierCrxPod1Guest = VirtualMachineGuestOsIdentifier("crxPod1Guest")
|
||||
VirtualMachineGuestOsIdentifierOtherGuest = VirtualMachineGuestOsIdentifier("otherGuest")
|
||||
VirtualMachineGuestOsIdentifierOtherGuest64 = VirtualMachineGuestOsIdentifier("otherGuest64")
|
||||
)
|
||||
|
@ -4425,6 +4637,17 @@ func init() {
|
|||
t["VirtualMachineScsiPassthroughType"] = reflect.TypeOf((*VirtualMachineScsiPassthroughType)(nil)).Elem()
|
||||
}
|
||||
|
||||
type VirtualMachineSgxInfoFlcModes string
|
||||
|
||||
const (
|
||||
VirtualMachineSgxInfoFlcModesLocked = VirtualMachineSgxInfoFlcModes("locked")
|
||||
VirtualMachineSgxInfoFlcModesUnlocked = VirtualMachineSgxInfoFlcModes("unlocked")
|
||||
)
|
||||
|
||||
func init() {
|
||||
t["VirtualMachineSgxInfoFlcModes"] = reflect.TypeOf((*VirtualMachineSgxInfoFlcModes)(nil)).Elem()
|
||||
}
|
||||
|
||||
type VirtualMachineStandbyActionType string
|
||||
|
||||
const (
|
||||
|
@ -4450,11 +4673,12 @@ func init() {
|
|||
type VirtualMachineTicketType string
|
||||
|
||||
const (
|
||||
VirtualMachineTicketTypeMks = VirtualMachineTicketType("mks")
|
||||
VirtualMachineTicketTypeDevice = VirtualMachineTicketType("device")
|
||||
VirtualMachineTicketTypeGuestControl = VirtualMachineTicketType("guestControl")
|
||||
VirtualMachineTicketTypeWebmks = VirtualMachineTicketType("webmks")
|
||||
VirtualMachineTicketTypeGuestIntegrity = VirtualMachineTicketType("guestIntegrity")
|
||||
VirtualMachineTicketTypeMks = VirtualMachineTicketType("mks")
|
||||
VirtualMachineTicketTypeDevice = VirtualMachineTicketType("device")
|
||||
VirtualMachineTicketTypeGuestControl = VirtualMachineTicketType("guestControl")
|
||||
VirtualMachineTicketTypeWebmks = VirtualMachineTicketType("webmks")
|
||||
VirtualMachineTicketTypeGuestIntegrity = VirtualMachineTicketType("guestIntegrity")
|
||||
VirtualMachineTicketTypeWebRemoteDevice = VirtualMachineTicketType("webRemoteDevice")
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -4549,11 +4773,12 @@ func init() {
|
|||
type VirtualMachineUsbInfoSpeed string
|
||||
|
||||
const (
|
||||
VirtualMachineUsbInfoSpeedLow = VirtualMachineUsbInfoSpeed("low")
|
||||
VirtualMachineUsbInfoSpeedFull = VirtualMachineUsbInfoSpeed("full")
|
||||
VirtualMachineUsbInfoSpeedHigh = VirtualMachineUsbInfoSpeed("high")
|
||||
VirtualMachineUsbInfoSpeedSuperSpeed = VirtualMachineUsbInfoSpeed("superSpeed")
|
||||
VirtualMachineUsbInfoSpeedUnknownSpeed = VirtualMachineUsbInfoSpeed("unknownSpeed")
|
||||
VirtualMachineUsbInfoSpeedLow = VirtualMachineUsbInfoSpeed("low")
|
||||
VirtualMachineUsbInfoSpeedFull = VirtualMachineUsbInfoSpeed("full")
|
||||
VirtualMachineUsbInfoSpeedHigh = VirtualMachineUsbInfoSpeed("high")
|
||||
VirtualMachineUsbInfoSpeedSuperSpeed = VirtualMachineUsbInfoSpeed("superSpeed")
|
||||
VirtualMachineUsbInfoSpeedSuperSpeedPlus = VirtualMachineUsbInfoSpeed("superSpeedPlus")
|
||||
VirtualMachineUsbInfoSpeedUnknownSpeed = VirtualMachineUsbInfoSpeed("unknownSpeed")
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
|
|
@ -1424,6 +1424,28 @@ func init() {
|
|||
t["BaseHostMultipathInfoLogicalUnitPolicy"] = reflect.TypeOf((*HostMultipathInfoLogicalUnitPolicy)(nil)).Elem()
|
||||
}
|
||||
|
||||
func (b *HostNvmeSpec) GetHostNvmeSpec() *HostNvmeSpec { return b }
|
||||
|
||||
type BaseHostNvmeSpec interface {
|
||||
GetHostNvmeSpec() *HostNvmeSpec
|
||||
}
|
||||
|
||||
func init() {
|
||||
t["BaseHostNvmeSpec"] = reflect.TypeOf((*HostNvmeSpec)(nil)).Elem()
|
||||
}
|
||||
|
||||
func (b *HostNvmeTransportParameters) GetHostNvmeTransportParameters() *HostNvmeTransportParameters {
|
||||
return b
|
||||
}
|
||||
|
||||
type BaseHostNvmeTransportParameters interface {
|
||||
GetHostNvmeTransportParameters() *HostNvmeTransportParameters
|
||||
}
|
||||
|
||||
func init() {
|
||||
t["BaseHostNvmeTransportParameters"] = reflect.TypeOf((*HostNvmeTransportParameters)(nil)).Elem()
|
||||
}
|
||||
|
||||
func (b *HostPciPassthruConfig) GetHostPciPassthruConfig() *HostPciPassthruConfig { return b }
|
||||
|
||||
type BaseHostPciPassthruConfig interface {
|
||||
|
@ -1476,6 +1498,16 @@ func init() {
|
|||
t["BaseHostProfilesEntityCustomizations"] = reflect.TypeOf((*HostProfilesEntityCustomizations)(nil)).Elem()
|
||||
}
|
||||
|
||||
func (b *HostRdmaDeviceBacking) GetHostRdmaDeviceBacking() *HostRdmaDeviceBacking { return b }
|
||||
|
||||
type BaseHostRdmaDeviceBacking interface {
|
||||
GetHostRdmaDeviceBacking() *HostRdmaDeviceBacking
|
||||
}
|
||||
|
||||
func init() {
|
||||
t["BaseHostRdmaDeviceBacking"] = reflect.TypeOf((*HostRdmaDeviceBacking)(nil)).Elem()
|
||||
}
|
||||
|
||||
func (b *HostSriovDevicePoolInfo) GetHostSriovDevicePoolInfo() *HostSriovDevicePoolInfo { return b }
|
||||
|
||||
type BaseHostSriovDevicePoolInfo interface {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2012 The Go Authors. All rights reserved.
|
||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
|
|
|
@ -16,7 +16,7 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
// A generic XML header suitable for use with the output of Marshal.
|
||||
// Header is a generic XML header suitable for use with the output of Marshal.
|
||||
// This is not automatically added to any output of this package,
|
||||
// it is provided as a convenience.
|
||||
Header = `<?xml version="1.0" encoding="UTF-8"?>` + "\n"
|
||||
|
@ -24,21 +24,21 @@ const (
|
|||
|
||||
// Marshal returns the XML encoding of v.
|
||||
//
|
||||
// Marshal handles an array or slice by marshalling each of the elements.
|
||||
// Marshal handles a pointer by marshalling the value it points at or, if the
|
||||
// pointer is nil, by writing nothing. Marshal handles an interface value by
|
||||
// marshalling the value it contains or, if the interface value is nil, by
|
||||
// writing nothing. Marshal handles all other data by writing one or more XML
|
||||
// Marshal handles an array or slice by marshaling each of the elements.
|
||||
// Marshal handles a pointer by marshaling the value it points at or, if the
|
||||
// pointer is nil, by writing nothing. Marshal handles an interface value by
|
||||
// marshaling the value it contains or, if the interface value is nil, by
|
||||
// writing nothing. Marshal handles all other data by writing one or more XML
|
||||
// elements containing the data.
|
||||
//
|
||||
// The name for the XML elements is taken from, in order of preference:
|
||||
// - the tag on the XMLName field, if the data is a struct
|
||||
// - the value of the XMLName field of type xml.Name
|
||||
// - the value of the XMLName field of type Name
|
||||
// - the tag of the struct field used to obtain the data
|
||||
// - the name of the struct field used to obtain the data
|
||||
// - the name of the marshalled type
|
||||
// - the name of the marshaled type
|
||||
//
|
||||
// The XML element for a struct contains marshalled elements for each of the
|
||||
// The XML element for a struct contains marshaled elements for each of the
|
||||
// exported fields of the struct, with these exceptions:
|
||||
// - the XMLName field, described above, is omitted.
|
||||
// - a field with tag "-" is omitted.
|
||||
|
@ -48,10 +48,12 @@ const (
|
|||
// field name in the XML element.
|
||||
// - a field with tag ",chardata" is written as character data,
|
||||
// not as an XML element.
|
||||
// - a field with tag ",cdata" is written as character data
|
||||
// wrapped in one or more <![CDATA[ ... ]]> tags, not as an XML element.
|
||||
// - a field with tag ",innerxml" is written verbatim, not subject
|
||||
// to the usual marshalling procedure.
|
||||
// to the usual marshaling procedure.
|
||||
// - a field with tag ",comment" is written as an XML comment, not
|
||||
// subject to the usual marshalling procedure. It must not contain
|
||||
// subject to the usual marshaling procedure. It must not contain
|
||||
// the "--" string within it.
|
||||
// - a field with a tag including the "omitempty" option is omitted
|
||||
// if the field value is empty. The empty values are false, 0, any
|
||||
|
@ -59,11 +61,18 @@ const (
|
|||
// string of length zero.
|
||||
// - an anonymous struct field is handled as if the fields of its
|
||||
// value were part of the outer struct.
|
||||
// - a field implementing Marshaler is written by calling its MarshalXML
|
||||
// method.
|
||||
// - a field implementing encoding.TextMarshaler is written by encoding the
|
||||
// result of its MarshalText method as text.
|
||||
//
|
||||
// If a field uses a tag "a>b>c", then the element c will be nested inside
|
||||
// parent elements a and b. Fields that appear next to each other that name
|
||||
// parent elements a and b. Fields that appear next to each other that name
|
||||
// the same parent will be enclosed in one XML element.
|
||||
//
|
||||
// If the XML name for a struct field is defined by both the field tag and the
|
||||
// struct's XMLName field, the names must match.
|
||||
//
|
||||
// See MarshalIndent for an example.
|
||||
//
|
||||
// Marshal will return an error if asked to marshal a channel, function, or map.
|
||||
|
@ -173,9 +182,9 @@ func (enc *Encoder) EncodeElement(v interface{}, start StartElement) error {
|
|||
}
|
||||
|
||||
var (
|
||||
endComment = []byte("-->")
|
||||
endProcInst = []byte("?>")
|
||||
endDirective = []byte(">")
|
||||
begComment = []byte("<!--")
|
||||
endComment = []byte("-->")
|
||||
endProcInst = []byte("?>")
|
||||
)
|
||||
|
||||
// EncodeToken writes the given XML token to the stream.
|
||||
|
@ -191,6 +200,7 @@ var (
|
|||
// EncodeToken allows writing a ProcInst with Target set to "xml" only as the first token
|
||||
// in the stream.
|
||||
func (enc *Encoder) EncodeToken(t Token) error {
|
||||
|
||||
p := &enc.p
|
||||
switch t := t.(type) {
|
||||
case StartElement:
|
||||
|
@ -202,7 +212,7 @@ func (enc *Encoder) EncodeToken(t Token) error {
|
|||
return err
|
||||
}
|
||||
case CharData:
|
||||
EscapeText(p, t)
|
||||
escapeText(p, t, false)
|
||||
case Comment:
|
||||
if bytes.Contains(t, endComment) {
|
||||
return fmt.Errorf("xml: EncodeToken of Comment containing --> marker")
|
||||
|
@ -213,7 +223,7 @@ func (enc *Encoder) EncodeToken(t Token) error {
|
|||
return p.cachedWriteError()
|
||||
case ProcInst:
|
||||
// First token to be encoded which is also a ProcInst with target of xml
|
||||
// is the xml declaration. The only ProcInst where target of xml is allowed.
|
||||
// is the xml declaration. The only ProcInst where target of xml is allowed.
|
||||
if t.Target == "xml" && p.Buffered() != 0 {
|
||||
return fmt.Errorf("xml: EncodeToken of ProcInst xml target only valid for xml declaration, first token encoded")
|
||||
}
|
||||
|
@ -231,16 +241,59 @@ func (enc *Encoder) EncodeToken(t Token) error {
|
|||
}
|
||||
p.WriteString("?>")
|
||||
case Directive:
|
||||
if bytes.Contains(t, endDirective) {
|
||||
return fmt.Errorf("xml: EncodeToken of Directive containing > marker")
|
||||
if !isValidDirective(t) {
|
||||
return fmt.Errorf("xml: EncodeToken of Directive containing wrong < or > markers")
|
||||
}
|
||||
p.WriteString("<!")
|
||||
p.Write(t)
|
||||
p.WriteString(">")
|
||||
default:
|
||||
return fmt.Errorf("xml: EncodeToken of invalid token type")
|
||||
|
||||
}
|
||||
return p.cachedWriteError()
|
||||
}
|
||||
|
||||
// isValidDirective reports whether dir is a valid directive text,
|
||||
// meaning angle brackets are matched, ignoring comments and strings.
|
||||
func isValidDirective(dir Directive) bool {
|
||||
var (
|
||||
depth int
|
||||
inquote uint8
|
||||
incomment bool
|
||||
)
|
||||
for i, c := range dir {
|
||||
switch {
|
||||
case incomment:
|
||||
if c == '>' {
|
||||
if n := 1 + i - len(endComment); n >= 0 && bytes.Equal(dir[n:i+1], endComment) {
|
||||
incomment = false
|
||||
}
|
||||
}
|
||||
// Just ignore anything in comment
|
||||
case inquote != 0:
|
||||
if c == inquote {
|
||||
inquote = 0
|
||||
}
|
||||
// Just ignore anything within quotes
|
||||
case c == '\'' || c == '"':
|
||||
inquote = c
|
||||
case c == '<':
|
||||
if i+len(begComment) < len(dir) && bytes.Equal(dir[i:i+len(begComment)], begComment) {
|
||||
incomment = true
|
||||
} else {
|
||||
depth++
|
||||
}
|
||||
case c == '>':
|
||||
if depth == 0 {
|
||||
return false
|
||||
}
|
||||
depth--
|
||||
}
|
||||
}
|
||||
return depth == 0 && inquote == 0 && !incomment
|
||||
}
|
||||
|
||||
// Flush flushes any buffered XML to the underlying writer.
|
||||
// See the EncodeToken documentation for details about when it is necessary.
|
||||
func (enc *Encoder) Flush() error {
|
||||
|
@ -274,7 +327,7 @@ func (p *printer) createAttrPrefix(url string) string {
|
|||
// (The "http://www.w3.org/2000/xmlns/" name space is also predefined as "xmlns",
|
||||
// but users should not be trying to use that one directly - that's our job.)
|
||||
if url == xmlURL {
|
||||
return "xml"
|
||||
return xmlPrefix
|
||||
}
|
||||
|
||||
// Need to define a new name space.
|
||||
|
@ -453,7 +506,6 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat
|
|||
continue
|
||||
}
|
||||
fv := finfo.value(val)
|
||||
name := Name{Space: finfo.xmlns, Local: finfo.name}
|
||||
|
||||
if finfo.flags&fOmitEmpty != 0 && isEmptyValue(fv) {
|
||||
continue
|
||||
|
@ -463,69 +515,10 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat
|
|||
continue
|
||||
}
|
||||
|
||||
if fv.CanInterface() && fv.Type().Implements(marshalerAttrType) {
|
||||
attr, err := fv.Interface().(MarshalerAttr).MarshalXMLAttr(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if attr.Name.Local != "" {
|
||||
start.Attr = append(start.Attr, attr)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if fv.CanAddr() {
|
||||
pv := fv.Addr()
|
||||
if pv.CanInterface() && pv.Type().Implements(marshalerAttrType) {
|
||||
attr, err := pv.Interface().(MarshalerAttr).MarshalXMLAttr(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if attr.Name.Local != "" {
|
||||
start.Attr = append(start.Attr, attr)
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if fv.CanInterface() && fv.Type().Implements(textMarshalerType) {
|
||||
text, err := fv.Interface().(encoding.TextMarshaler).MarshalText()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
start.Attr = append(start.Attr, Attr{name, string(text)})
|
||||
continue
|
||||
}
|
||||
|
||||
if fv.CanAddr() {
|
||||
pv := fv.Addr()
|
||||
if pv.CanInterface() && pv.Type().Implements(textMarshalerType) {
|
||||
text, err := pv.Interface().(encoding.TextMarshaler).MarshalText()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
start.Attr = append(start.Attr, Attr{name, string(text)})
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// Dereference or skip nil pointer, interface values.
|
||||
switch fv.Kind() {
|
||||
case reflect.Ptr, reflect.Interface:
|
||||
if fv.IsNil() {
|
||||
continue
|
||||
}
|
||||
fv = fv.Elem()
|
||||
}
|
||||
|
||||
s, b, err := p.marshalSimple(fv.Type(), fv)
|
||||
if err != nil {
|
||||
name := Name{Space: finfo.xmlns, Local: finfo.name}
|
||||
if err := p.marshalAttr(&start, name, fv); err != nil {
|
||||
return err
|
||||
}
|
||||
if b != nil {
|
||||
s = string(b)
|
||||
}
|
||||
start.Attr = append(start.Attr, Attr{name, s})
|
||||
}
|
||||
|
||||
if err := p.writeStart(&start); err != nil {
|
||||
|
@ -555,6 +548,90 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplat
|
|||
return p.cachedWriteError()
|
||||
}
|
||||
|
||||
// marshalAttr marshals an attribute with the given name and value, adding to start.Attr.
|
||||
func (p *printer) marshalAttr(start *StartElement, name Name, val reflect.Value) error {
|
||||
if val.CanInterface() && val.Type().Implements(marshalerAttrType) {
|
||||
attr, err := val.Interface().(MarshalerAttr).MarshalXMLAttr(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if attr.Name.Local != "" {
|
||||
start.Attr = append(start.Attr, attr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if val.CanAddr() {
|
||||
pv := val.Addr()
|
||||
if pv.CanInterface() && pv.Type().Implements(marshalerAttrType) {
|
||||
attr, err := pv.Interface().(MarshalerAttr).MarshalXMLAttr(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if attr.Name.Local != "" {
|
||||
start.Attr = append(start.Attr, attr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if val.CanInterface() && val.Type().Implements(textMarshalerType) {
|
||||
text, err := val.Interface().(encoding.TextMarshaler).MarshalText()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
start.Attr = append(start.Attr, Attr{name, string(text)})
|
||||
return nil
|
||||
}
|
||||
|
||||
if val.CanAddr() {
|
||||
pv := val.Addr()
|
||||
if pv.CanInterface() && pv.Type().Implements(textMarshalerType) {
|
||||
text, err := pv.Interface().(encoding.TextMarshaler).MarshalText()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
start.Attr = append(start.Attr, Attr{name, string(text)})
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Dereference or skip nil pointer, interface values.
|
||||
switch val.Kind() {
|
||||
case reflect.Ptr, reflect.Interface:
|
||||
if val.IsNil() {
|
||||
return nil
|
||||
}
|
||||
val = val.Elem()
|
||||
}
|
||||
|
||||
// Walk slices.
|
||||
if val.Kind() == reflect.Slice && val.Type().Elem().Kind() != reflect.Uint8 {
|
||||
n := val.Len()
|
||||
for i := 0; i < n; i++ {
|
||||
if err := p.marshalAttr(start, name, val.Index(i)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if val.Type() == attrType {
|
||||
start.Attr = append(start.Attr, val.Interface().(Attr))
|
||||
return nil
|
||||
}
|
||||
|
||||
s, b, err := p.marshalSimple(val.Type(), val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if b != nil {
|
||||
s = string(b)
|
||||
}
|
||||
start.Attr = append(start.Attr, Attr{name, s})
|
||||
return nil
|
||||
}
|
||||
|
||||
// defaultStart returns the default start element to use,
|
||||
// given the reflect type, field info, and start template.
|
||||
func defaultStart(typ reflect.Type, finfo *fieldInfo, startTemplate *StartElement) StartElement {
|
||||
|
@ -716,6 +793,20 @@ func (p *printer) marshalSimple(typ reflect.Type, val reflect.Value) (string, []
|
|||
|
||||
var ddBytes = []byte("--")
|
||||
|
||||
// indirect drills into interfaces and pointers, returning the pointed-at value.
|
||||
// If it encounters a nil interface or pointer, indirect returns that nil value.
|
||||
// This can turn into an infinite loop given a cyclic chain,
|
||||
// but it matches the Go 1 behavior.
|
||||
func indirect(vf reflect.Value) reflect.Value {
|
||||
for vf.Kind() == reflect.Interface || vf.Kind() == reflect.Ptr {
|
||||
if vf.IsNil() {
|
||||
return vf
|
||||
}
|
||||
vf = vf.Elem()
|
||||
}
|
||||
return vf
|
||||
}
|
||||
|
||||
func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error {
|
||||
s := parentStack{p: p}
|
||||
for i := range tinfo.fields {
|
||||
|
@ -725,22 +816,23 @@ func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error {
|
|||
}
|
||||
vf := finfo.value(val)
|
||||
|
||||
// Dereference or skip nil pointer, interface values.
|
||||
switch vf.Kind() {
|
||||
case reflect.Ptr, reflect.Interface:
|
||||
if !vf.IsNil() {
|
||||
vf = vf.Elem()
|
||||
}
|
||||
}
|
||||
|
||||
switch finfo.flags & fMode {
|
||||
case fCharData:
|
||||
case fCDATA, fCharData:
|
||||
emit := EscapeText
|
||||
if finfo.flags&fMode == fCDATA {
|
||||
emit = emitCDATA
|
||||
}
|
||||
if err := s.trim(finfo.parents); err != nil {
|
||||
return err
|
||||
}
|
||||
if vf.CanInterface() && vf.Type().Implements(textMarshalerType) {
|
||||
data, err := vf.Interface().(encoding.TextMarshaler).MarshalText()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
Escape(p, data)
|
||||
if err := emit(p, data); err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
if vf.CanAddr() {
|
||||
|
@ -750,27 +842,39 @@ func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
Escape(p, data)
|
||||
if err := emit(p, data); err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
var scratch [64]byte
|
||||
vf = indirect(vf)
|
||||
switch vf.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
Escape(p, strconv.AppendInt(scratch[:0], vf.Int(), 10))
|
||||
if err := emit(p, strconv.AppendInt(scratch[:0], vf.Int(), 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
Escape(p, strconv.AppendUint(scratch[:0], vf.Uint(), 10))
|
||||
if err := emit(p, strconv.AppendUint(scratch[:0], vf.Uint(), 10)); err != nil {
|
||||
return err
|
||||
}
|
||||
case reflect.Float32, reflect.Float64:
|
||||
Escape(p, strconv.AppendFloat(scratch[:0], vf.Float(), 'g', -1, vf.Type().Bits()))
|
||||
if err := emit(p, strconv.AppendFloat(scratch[:0], vf.Float(), 'g', -1, vf.Type().Bits())); err != nil {
|
||||
return err
|
||||
}
|
||||
case reflect.Bool:
|
||||
Escape(p, strconv.AppendBool(scratch[:0], vf.Bool()))
|
||||
if err := emit(p, strconv.AppendBool(scratch[:0], vf.Bool())); err != nil {
|
||||
return err
|
||||
}
|
||||
case reflect.String:
|
||||
if err := EscapeText(p, []byte(vf.String())); err != nil {
|
||||
if err := emit(p, []byte(vf.String())); err != nil {
|
||||
return err
|
||||
}
|
||||
case reflect.Slice:
|
||||
if elem, ok := vf.Interface().([]byte); ok {
|
||||
if err := EscapeText(p, elem); err != nil {
|
||||
if err := emit(p, elem); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -778,6 +882,10 @@ func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error {
|
|||
continue
|
||||
|
||||
case fComment:
|
||||
if err := s.trim(finfo.parents); err != nil {
|
||||
return err
|
||||
}
|
||||
vf = indirect(vf)
|
||||
k := vf.Kind()
|
||||
if !(k == reflect.String || k == reflect.Slice && vf.Type().Elem().Kind() == reflect.Uint8) {
|
||||
return fmt.Errorf("xml: bad type for comment field of %s", val.Type())
|
||||
|
@ -792,14 +900,14 @@ func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error {
|
|||
switch k {
|
||||
case reflect.String:
|
||||
s := vf.String()
|
||||
dashDash = strings.Index(s, "--") >= 0
|
||||
dashDash = strings.Contains(s, "--")
|
||||
dashLast = s[len(s)-1] == '-'
|
||||
if !dashDash {
|
||||
p.WriteString(s)
|
||||
}
|
||||
case reflect.Slice:
|
||||
b := vf.Bytes()
|
||||
dashDash = bytes.Index(b, ddBytes) >= 0
|
||||
dashDash = bytes.Contains(b, ddBytes)
|
||||
dashLast = b[len(b)-1] == '-'
|
||||
if !dashDash {
|
||||
p.Write(b)
|
||||
|
@ -818,6 +926,7 @@ func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error {
|
|||
continue
|
||||
|
||||
case fInnerXml:
|
||||
vf = indirect(vf)
|
||||
iface := vf.Interface()
|
||||
switch raw := iface.(type) {
|
||||
case []byte:
|
||||
|
@ -891,8 +1000,8 @@ type parentStack struct {
|
|||
}
|
||||
|
||||
// trim updates the XML context to match the longest common prefix of the stack
|
||||
// and the given parents. A closing tag will be written for every parent
|
||||
// popped. Passing a zero slice or nil will close all the elements.
|
||||
// and the given parents. A closing tag will be written for every parent
|
||||
// popped. Passing a zero slice or nil will close all the elements.
|
||||
func (s *parentStack) trim(parents []string) error {
|
||||
split := 0
|
||||
for ; split < len(parents) && split < len(s.stack); split++ {
|
||||
|
@ -905,7 +1014,7 @@ func (s *parentStack) trim(parents []string) error {
|
|||
return err
|
||||
}
|
||||
}
|
||||
s.stack = parents[:split]
|
||||
s.stack = s.stack[:split]
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -920,7 +1029,7 @@ func (s *parentStack) push(parents []string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// A MarshalXMLError is returned when Marshal encounters a type
|
||||
// UnsupportedTypeError is returned when Marshal encounters a type
|
||||
// that cannot be converted into XML.
|
||||
type UnsupportedTypeError struct {
|
||||
Type reflect.Type
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
@ -27,7 +27,7 @@ import (
|
|||
// discarded.
|
||||
//
|
||||
// Because Unmarshal uses the reflect package, it can only assign
|
||||
// to exported (upper case) fields. Unmarshal uses a case-sensitive
|
||||
// to exported (upper case) fields. Unmarshal uses a case-sensitive
|
||||
// comparison to match XML element names to tag values and struct
|
||||
// field names.
|
||||
//
|
||||
|
@ -37,9 +37,9 @@ import (
|
|||
//
|
||||
// * If the struct has a field of type []byte or string with tag
|
||||
// ",innerxml", Unmarshal accumulates the raw XML nested inside the
|
||||
// element in that field. The rest of the rules still apply.
|
||||
// element in that field. The rest of the rules still apply.
|
||||
//
|
||||
// * If the struct has a field named XMLName of type xml.Name,
|
||||
// * If the struct has a field named XMLName of type Name,
|
||||
// Unmarshal records the element name in that field.
|
||||
//
|
||||
// * If the XMLName field has an associated tag of the form
|
||||
|
@ -52,6 +52,11 @@ import (
|
|||
// the explicit name in a struct field tag of the form "name,attr",
|
||||
// Unmarshal records the attribute value in that field.
|
||||
//
|
||||
// * If the XML element has an attribute not handled by the previous
|
||||
// rule and the struct has a field with an associated tag containing
|
||||
// ",any,attr", Unmarshal records the attribute value in the first
|
||||
// such field.
|
||||
//
|
||||
// * If the XML element contains character data, that data is
|
||||
// accumulated in the first struct field that has tag ",chardata".
|
||||
// The struct field may have type []byte or string.
|
||||
|
@ -59,7 +64,7 @@ import (
|
|||
//
|
||||
// * If the XML element contains comments, they are accumulated in
|
||||
// the first struct field that has tag ",comment". The struct
|
||||
// field may have type []byte or string. If there is no such
|
||||
// field may have type []byte or string. If there is no such
|
||||
// field, the comments are discarded.
|
||||
//
|
||||
// * If the XML element contains a sub-element whose name matches
|
||||
|
@ -85,7 +90,12 @@ import (
|
|||
// * An anonymous struct field is handled as if the fields of its
|
||||
// value were part of the outer struct.
|
||||
//
|
||||
// * A struct field with tag "-" is never unmarshalled into.
|
||||
// * A struct field with tag "-" is never unmarshaled into.
|
||||
//
|
||||
// If Unmarshal encounters a field type that implements the Unmarshaler
|
||||
// interface, Unmarshal calls its UnmarshalXML method to produce the value from
|
||||
// the XML element. Otherwise, if the value implements
|
||||
// encoding.TextUnmarshaler, Unmarshal calls that value's UnmarshalText method.
|
||||
//
|
||||
// Unmarshal maps an XML element to a string or []byte by saving the
|
||||
// concatenation of that element's character data in the string or
|
||||
|
@ -94,34 +104,42 @@ import (
|
|||
// Unmarshal maps an attribute value to a string or []byte by saving
|
||||
// the value in the string or slice.
|
||||
//
|
||||
// Unmarshal maps an XML element to a slice by extending the length of
|
||||
// the slice and mapping the element to the newly created value.
|
||||
// Unmarshal maps an attribute value to an Attr by saving the attribute,
|
||||
// including its name, in the Attr.
|
||||
//
|
||||
// Unmarshal maps an XML element or attribute value to a slice by
|
||||
// extending the length of the slice and mapping the element or attribute
|
||||
// to the newly created value.
|
||||
//
|
||||
// Unmarshal maps an XML element or attribute value to a bool by
|
||||
// setting it to the boolean value represented by the string.
|
||||
// setting it to the boolean value represented by the string. Whitespace
|
||||
// is trimmed and ignored.
|
||||
//
|
||||
// Unmarshal maps an XML element or attribute value to an integer or
|
||||
// floating-point field by setting the field to the result of
|
||||
// interpreting the string value in decimal. There is no check for
|
||||
// overflow.
|
||||
// interpreting the string value in decimal. There is no check for
|
||||
// overflow. Whitespace is trimmed and ignored.
|
||||
//
|
||||
// Unmarshal maps an XML element to an xml.Name by recording the
|
||||
// element name.
|
||||
// Unmarshal maps an XML element to a Name by recording the element
|
||||
// name.
|
||||
//
|
||||
// Unmarshal maps an XML element to a pointer by setting the pointer
|
||||
// to a freshly allocated value and then mapping the element to that value.
|
||||
//
|
||||
// A missing element or empty attribute value will be unmarshaled as a zero value.
|
||||
// If the field is a slice, a zero value will be appended to the field. Otherwise, the
|
||||
// field will be set to its zero value.
|
||||
func Unmarshal(data []byte, v interface{}) error {
|
||||
return NewDecoder(bytes.NewReader(data)).Decode(v)
|
||||
}
|
||||
|
||||
// Decode works like xml.Unmarshal, except it reads the decoder
|
||||
// Decode works like Unmarshal, except it reads the decoder
|
||||
// stream to find the start element.
|
||||
func (d *Decoder) Decode(v interface{}) error {
|
||||
return d.DecodeElement(v, nil)
|
||||
}
|
||||
|
||||
// DecodeElement works like xml.Unmarshal except that it takes
|
||||
// DecodeElement works like Unmarshal except that it takes
|
||||
// a pointer to the start XML element to decode into v.
|
||||
// It is useful when a client reads some raw XML tokens itself
|
||||
// but also wants to defer to Unmarshal for some elements.
|
||||
|
@ -133,7 +151,7 @@ func (d *Decoder) DecodeElement(v interface{}, start *StartElement) error {
|
|||
return d.unmarshal(val.Elem(), start)
|
||||
}
|
||||
|
||||
// An UnmarshalError represents an error in the unmarshalling process.
|
||||
// An UnmarshalError represents an error in the unmarshaling process.
|
||||
type UnmarshalError string
|
||||
|
||||
func (e UnmarshalError) Error() string { return string(e) }
|
||||
|
@ -148,7 +166,7 @@ func (e UnmarshalError) Error() string { return string(e) }
|
|||
// UnmarshalXML must consume exactly one XML element.
|
||||
// One common implementation strategy is to unmarshal into
|
||||
// a separate value with a layout matching the expected XML
|
||||
// using d.DecodeElement, and then to copy the data from
|
||||
// using d.DecodeElement, and then to copy the data from
|
||||
// that value into the receiver.
|
||||
// Another common strategy is to use d.Token to process the
|
||||
// XML object one token at a time.
|
||||
|
@ -180,19 +198,19 @@ func receiverType(val interface{}) string {
|
|||
|
||||
// unmarshalInterface unmarshals a single XML element into val.
|
||||
// start is the opening tag of the element.
|
||||
func (p *Decoder) unmarshalInterface(val Unmarshaler, start *StartElement) error {
|
||||
func (d *Decoder) unmarshalInterface(val Unmarshaler, start *StartElement) error {
|
||||
// Record that decoder must stop at end tag corresponding to start.
|
||||
p.pushEOF()
|
||||
d.pushEOF()
|
||||
|
||||
p.unmarshalDepth++
|
||||
err := val.UnmarshalXML(p, *start)
|
||||
p.unmarshalDepth--
|
||||
d.unmarshalDepth++
|
||||
err := val.UnmarshalXML(d, *start)
|
||||
d.unmarshalDepth--
|
||||
if err != nil {
|
||||
p.popEOF()
|
||||
d.popEOF()
|
||||
return err
|
||||
}
|
||||
|
||||
if !p.popEOF() {
|
||||
if !d.popEOF() {
|
||||
return fmt.Errorf("xml: %s.UnmarshalXML did not consume entire <%s> element", receiverType(val), start.Name.Local)
|
||||
}
|
||||
|
||||
|
@ -202,11 +220,11 @@ func (p *Decoder) unmarshalInterface(val Unmarshaler, start *StartElement) error
|
|||
// unmarshalTextInterface unmarshals a single XML element into val.
|
||||
// The chardata contained in the element (but not its children)
|
||||
// is passed to the text unmarshaler.
|
||||
func (p *Decoder) unmarshalTextInterface(val encoding.TextUnmarshaler, start *StartElement) error {
|
||||
func (d *Decoder) unmarshalTextInterface(val encoding.TextUnmarshaler) error {
|
||||
var buf []byte
|
||||
depth := 1
|
||||
for depth > 0 {
|
||||
t, err := p.Token()
|
||||
t, err := d.Token()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -225,14 +243,13 @@ func (p *Decoder) unmarshalTextInterface(val encoding.TextUnmarshaler, start *St
|
|||
}
|
||||
|
||||
// unmarshalAttr unmarshals a single XML attribute into val.
|
||||
func (p *Decoder) unmarshalAttr(val reflect.Value, attr Attr) error {
|
||||
func (d *Decoder) unmarshalAttr(val reflect.Value, attr Attr) error {
|
||||
if val.Kind() == reflect.Ptr {
|
||||
if val.IsNil() {
|
||||
val.Set(reflect.New(val.Type().Elem()))
|
||||
}
|
||||
val = val.Elem()
|
||||
}
|
||||
|
||||
if val.CanInterface() && val.Type().Implements(unmarshalerAttrType) {
|
||||
// This is an unmarshaler with a non-pointer receiver,
|
||||
// so it's likely to be incorrect, but we do what we're told.
|
||||
|
@ -258,11 +275,30 @@ func (p *Decoder) unmarshalAttr(val reflect.Value, attr Attr) error {
|
|||
}
|
||||
}
|
||||
|
||||
copyValue(val, []byte(attr.Value))
|
||||
return nil
|
||||
if val.Type().Kind() == reflect.Slice && val.Type().Elem().Kind() != reflect.Uint8 {
|
||||
// Slice of element values.
|
||||
// Grow slice.
|
||||
n := val.Len()
|
||||
val.Set(reflect.Append(val, reflect.Zero(val.Type().Elem())))
|
||||
|
||||
// Recur to read element into slice.
|
||||
if err := d.unmarshalAttr(val.Index(n), attr); err != nil {
|
||||
val.SetLen(n)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if val.Type() == attrType {
|
||||
val.Set(reflect.ValueOf(attr))
|
||||
return nil
|
||||
}
|
||||
|
||||
return copyValue(val, []byte(attr.Value))
|
||||
}
|
||||
|
||||
var (
|
||||
attrType = reflect.TypeOf(Attr{})
|
||||
unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
|
||||
unmarshalerAttrType = reflect.TypeOf((*UnmarshalerAttr)(nil)).Elem()
|
||||
textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
|
||||
|
@ -271,21 +307,9 @@ var (
|
|||
// Find reflect.Type for an element's type attribute.
|
||||
func (p *Decoder) typeForElement(val reflect.Value, start *StartElement) reflect.Type {
|
||||
t := ""
|
||||
for i, a := range start.Attr {
|
||||
for _, a := range start.Attr {
|
||||
if a.Name == xmlSchemaInstance || a.Name == xsiType {
|
||||
t = a.Value
|
||||
// HACK: ensure xsi:type is last in the list to avoid using that value for
|
||||
// a "type" attribute, such as ManagedObjectReference.Type for example.
|
||||
// Note that xsi:type is already the last attribute in VC/ESX responses.
|
||||
// This is only an issue with govmomi simulator generated responses.
|
||||
// Proper fix will require finding a few needles in this xml package haystack.
|
||||
// Note: govmomi uses xmlSchemaInstance, other clients (e.g. rbvmomi) use xsiType.
|
||||
// They are the same thing to XML parsers, but not to this hack here.
|
||||
x := len(start.Attr) - 1
|
||||
if i != x {
|
||||
start.Attr[i] = start.Attr[x]
|
||||
start.Attr[x] = a
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -312,11 +336,11 @@ func (p *Decoder) typeForElement(val reflect.Value, start *StartElement) reflect
|
|||
}
|
||||
|
||||
// Unmarshal a single XML element into val.
|
||||
func (p *Decoder) unmarshal(val reflect.Value, start *StartElement) error {
|
||||
func (d *Decoder) unmarshal(val reflect.Value, start *StartElement) error {
|
||||
// Find start element if we need it.
|
||||
if start == nil {
|
||||
for {
|
||||
tok, err := p.Token()
|
||||
tok, err := d.Token()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -329,10 +353,10 @@ func (p *Decoder) unmarshal(val reflect.Value, start *StartElement) error {
|
|||
|
||||
// Try to figure out type for empty interface values.
|
||||
if val.Kind() == reflect.Interface && val.IsNil() {
|
||||
typ := p.typeForElement(val, start)
|
||||
typ := d.typeForElement(val, start)
|
||||
if typ != nil {
|
||||
pval := reflect.New(typ).Elem()
|
||||
err := p.unmarshal(pval, start)
|
||||
err := d.unmarshal(pval, start)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -371,24 +395,24 @@ func (p *Decoder) unmarshal(val reflect.Value, start *StartElement) error {
|
|||
if val.CanInterface() && val.Type().Implements(unmarshalerType) {
|
||||
// This is an unmarshaler with a non-pointer receiver,
|
||||
// so it's likely to be incorrect, but we do what we're told.
|
||||
return p.unmarshalInterface(val.Interface().(Unmarshaler), start)
|
||||
return d.unmarshalInterface(val.Interface().(Unmarshaler), start)
|
||||
}
|
||||
|
||||
if val.CanAddr() {
|
||||
pv := val.Addr()
|
||||
if pv.CanInterface() && pv.Type().Implements(unmarshalerType) {
|
||||
return p.unmarshalInterface(pv.Interface().(Unmarshaler), start)
|
||||
return d.unmarshalInterface(pv.Interface().(Unmarshaler), start)
|
||||
}
|
||||
}
|
||||
|
||||
if val.CanInterface() && val.Type().Implements(textUnmarshalerType) {
|
||||
return p.unmarshalTextInterface(val.Interface().(encoding.TextUnmarshaler), start)
|
||||
return d.unmarshalTextInterface(val.Interface().(encoding.TextUnmarshaler))
|
||||
}
|
||||
|
||||
if val.CanAddr() {
|
||||
pv := val.Addr()
|
||||
if pv.CanInterface() && pv.Type().Implements(textUnmarshalerType) {
|
||||
return p.unmarshalTextInterface(pv.Interface().(encoding.TextUnmarshaler), start)
|
||||
return d.unmarshalTextInterface(pv.Interface().(encoding.TextUnmarshaler))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -414,7 +438,7 @@ func (p *Decoder) unmarshal(val reflect.Value, start *StartElement) error {
|
|||
// TODO: For now, simply ignore the field. In the near
|
||||
// future we may choose to unmarshal the start
|
||||
// element on it, if not nil.
|
||||
return p.Skip()
|
||||
return d.Skip()
|
||||
|
||||
case reflect.Slice:
|
||||
typ := v.Type()
|
||||
|
@ -427,19 +451,10 @@ func (p *Decoder) unmarshal(val reflect.Value, start *StartElement) error {
|
|||
// Slice of element values.
|
||||
// Grow slice.
|
||||
n := v.Len()
|
||||
if n >= v.Cap() {
|
||||
ncap := 2 * n
|
||||
if ncap < 4 {
|
||||
ncap = 4
|
||||
}
|
||||
new := reflect.MakeSlice(typ, n, ncap)
|
||||
reflect.Copy(new, v)
|
||||
v.Set(new)
|
||||
}
|
||||
v.SetLen(n + 1)
|
||||
v.Set(reflect.Append(val, reflect.Zero(v.Type().Elem())))
|
||||
|
||||
// Recur to read element into slice.
|
||||
if err := p.unmarshal(v.Index(n), start); err != nil {
|
||||
if err := d.unmarshal(v.Index(n), start); err != nil {
|
||||
v.SetLen(n)
|
||||
return err
|
||||
}
|
||||
|
@ -483,23 +498,45 @@ func (p *Decoder) unmarshal(val reflect.Value, start *StartElement) error {
|
|||
}
|
||||
|
||||
// Assign attributes.
|
||||
// Also, determine whether we need to save character data or comments.
|
||||
for _, a := range start.Attr {
|
||||
handled := false
|
||||
any := -1
|
||||
for i := range tinfo.fields {
|
||||
finfo := &tinfo.fields[i]
|
||||
switch finfo.flags & fMode {
|
||||
case fAttr:
|
||||
strv := finfo.value(sv)
|
||||
if a.Name.Local == finfo.name && (finfo.xmlns == "" || finfo.xmlns == a.Name.Space) {
|
||||
needTypeAttr := (finfo.flags & fTypeAttr) != 0
|
||||
// HACK: avoid using xsi:type value for a "type" attribute, such as ManagedObjectReference.Type for example.
|
||||
if needTypeAttr || (a.Name != xmlSchemaInstance && a.Name != xsiType) {
|
||||
if err := d.unmarshalAttr(strv, a); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
handled = true
|
||||
}
|
||||
|
||||
case fAny | fAttr:
|
||||
if any == -1 {
|
||||
any = i
|
||||
}
|
||||
}
|
||||
}
|
||||
if !handled && any >= 0 {
|
||||
finfo := &tinfo.fields[any]
|
||||
strv := finfo.value(sv)
|
||||
if err := d.unmarshalAttr(strv, a); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Determine whether we need to save character data or comments.
|
||||
for i := range tinfo.fields {
|
||||
finfo := &tinfo.fields[i]
|
||||
switch finfo.flags & fMode {
|
||||
case fAttr:
|
||||
strv := finfo.value(sv)
|
||||
// Look for attribute.
|
||||
for _, a := range start.Attr {
|
||||
if a.Name.Local == finfo.name && (finfo.xmlns == "" || finfo.xmlns == a.Name.Space) {
|
||||
if err := p.unmarshalAttr(strv, a); err != nil {
|
||||
return err
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
case fCharData:
|
||||
case fCDATA, fCharData:
|
||||
if !saveData.IsValid() {
|
||||
saveData = finfo.value(sv)
|
||||
}
|
||||
|
@ -517,11 +554,11 @@ func (p *Decoder) unmarshal(val reflect.Value, start *StartElement) error {
|
|||
case fInnerXml:
|
||||
if !saveXML.IsValid() {
|
||||
saveXML = finfo.value(sv)
|
||||
if p.saved == nil {
|
||||
if d.saved == nil {
|
||||
saveXMLIndex = 0
|
||||
p.saved = new(bytes.Buffer)
|
||||
d.saved = new(bytes.Buffer)
|
||||
} else {
|
||||
saveXMLIndex = p.savedOffset()
|
||||
saveXMLIndex = d.savedOffset()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -534,9 +571,9 @@ Loop:
|
|||
for {
|
||||
var savedOffset int
|
||||
if saveXML.IsValid() {
|
||||
savedOffset = p.savedOffset()
|
||||
savedOffset = d.savedOffset()
|
||||
}
|
||||
tok, err := p.Token()
|
||||
tok, err := d.Token()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -544,28 +581,28 @@ Loop:
|
|||
case StartElement:
|
||||
consumed := false
|
||||
if sv.IsValid() {
|
||||
consumed, err = p.unmarshalPath(tinfo, sv, nil, &t)
|
||||
consumed, err = d.unmarshalPath(tinfo, sv, nil, &t)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !consumed && saveAny.IsValid() {
|
||||
consumed = true
|
||||
if err := p.unmarshal(saveAny, &t); err != nil {
|
||||
if err := d.unmarshal(saveAny, &t); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
if !consumed {
|
||||
if err := p.Skip(); err != nil {
|
||||
if err := d.Skip(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
case EndElement:
|
||||
if saveXML.IsValid() {
|
||||
saveXMLData = p.saved.Bytes()[saveXMLIndex:savedOffset]
|
||||
saveXMLData = d.saved.Bytes()[saveXMLIndex:savedOffset]
|
||||
if saveXMLIndex == 0 {
|
||||
p.saved = nil
|
||||
d.saved = nil
|
||||
}
|
||||
}
|
||||
break Loop
|
||||
|
@ -614,7 +651,9 @@ Loop:
|
|||
case reflect.String:
|
||||
t.SetString(string(saveXMLData))
|
||||
case reflect.Slice:
|
||||
t.Set(reflect.ValueOf(saveXMLData))
|
||||
if t.Type().Elem().Kind() == reflect.Uint8 {
|
||||
t.Set(reflect.ValueOf(saveXMLData))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -637,7 +676,11 @@ func copyValue(dst reflect.Value, src []byte) (err error) {
|
|||
default:
|
||||
return errors.New("cannot unmarshal into " + dst0.Type().String())
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
itmp, err := strconv.ParseInt(string(src), 10, dst.Type().Bits())
|
||||
if len(src) == 0 {
|
||||
dst.SetInt(0)
|
||||
return nil
|
||||
}
|
||||
itmp, err := strconv.ParseInt(strings.TrimSpace(string(src)), 10, dst.Type().Bits())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -663,19 +706,32 @@ func copyValue(dst reflect.Value, src []byte) (err error) {
|
|||
utmp = uint64(uint64(itmp))
|
||||
}
|
||||
} else {
|
||||
utmp, err = strconv.ParseUint(string(src), 10, dst.Type().Bits())
|
||||
if len(src) == 0 {
|
||||
dst.SetUint(0)
|
||||
return nil
|
||||
}
|
||||
|
||||
utmp, err = strconv.ParseUint(strings.TrimSpace(string(src)), 10, dst.Type().Bits())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
dst.SetUint(utmp)
|
||||
case reflect.Float32, reflect.Float64:
|
||||
ftmp, err := strconv.ParseFloat(string(src), dst.Type().Bits())
|
||||
if len(src) == 0 {
|
||||
dst.SetFloat(0)
|
||||
return nil
|
||||
}
|
||||
ftmp, err := strconv.ParseFloat(strings.TrimSpace(string(src)), dst.Type().Bits())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dst.SetFloat(ftmp)
|
||||
case reflect.Bool:
|
||||
if len(src) == 0 {
|
||||
dst.SetBool(false)
|
||||
return nil
|
||||
}
|
||||
value, err := strconv.ParseBool(strings.TrimSpace(string(src)))
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -698,7 +754,7 @@ func copyValue(dst reflect.Value, src []byte) (err error) {
|
|||
// The consumed result tells whether XML elements have been consumed
|
||||
// from the Decoder until start's matching end element, or if it's
|
||||
// still untouched because start is uninteresting for sv's fields.
|
||||
func (p *Decoder) unmarshalPath(tinfo *typeInfo, sv reflect.Value, parents []string, start *StartElement) (consumed bool, err error) {
|
||||
func (d *Decoder) unmarshalPath(tinfo *typeInfo, sv reflect.Value, parents []string, start *StartElement) (consumed bool, err error) {
|
||||
recurse := false
|
||||
Loop:
|
||||
for i := range tinfo.fields {
|
||||
|
@ -713,7 +769,7 @@ Loop:
|
|||
}
|
||||
if len(finfo.parents) == len(parents) && finfo.name == start.Name.Local {
|
||||
// It's a perfect match, unmarshal the field.
|
||||
return true, p.unmarshal(finfo.value(sv), start)
|
||||
return true, d.unmarshal(finfo.value(sv), start)
|
||||
}
|
||||
if len(finfo.parents) > len(parents) && finfo.parents[len(parents)] == start.Name.Local {
|
||||
// It's a prefix for the field. Break and recurse
|
||||
|
@ -736,18 +792,18 @@ Loop:
|
|||
// prefix. Recurse and attempt to match these.
|
||||
for {
|
||||
var tok Token
|
||||
tok, err = p.Token()
|
||||
tok, err = d.Token()
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
switch t := tok.(type) {
|
||||
case StartElement:
|
||||
consumed2, err := p.unmarshalPath(tinfo, sv, parents, &t)
|
||||
consumed2, err := d.unmarshalPath(tinfo, sv, parents, &t)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
if !consumed2 {
|
||||
if err := p.Skip(); err != nil {
|
||||
if err := d.Skip(); err != nil {
|
||||
return true, err
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
@ -31,6 +31,7 @@ type fieldFlags int
|
|||
const (
|
||||
fElement fieldFlags = 1 << iota
|
||||
fAttr
|
||||
fCDATA
|
||||
fCharData
|
||||
fInnerXml
|
||||
fComment
|
||||
|
@ -39,29 +40,28 @@ const (
|
|||
fOmitEmpty
|
||||
fTypeAttr
|
||||
|
||||
fMode = fElement | fAttr | fCharData | fInnerXml | fComment | fAny
|
||||
fMode = fElement | fAttr | fCDATA | fCharData | fInnerXml | fComment | fAny
|
||||
|
||||
xmlName = "XMLName"
|
||||
)
|
||||
|
||||
var tinfoMap = make(map[reflect.Type]*typeInfo)
|
||||
var tinfoLock sync.RWMutex
|
||||
var tinfoMap sync.Map // map[reflect.Type]*typeInfo
|
||||
|
||||
var nameType = reflect.TypeOf(Name{})
|
||||
|
||||
// getTypeInfo returns the typeInfo structure with details necessary
|
||||
// for marshalling and unmarshalling typ.
|
||||
// for marshaling and unmarshaling typ.
|
||||
func getTypeInfo(typ reflect.Type) (*typeInfo, error) {
|
||||
tinfoLock.RLock()
|
||||
tinfo, ok := tinfoMap[typ]
|
||||
tinfoLock.RUnlock()
|
||||
if ok {
|
||||
return tinfo, nil
|
||||
if ti, ok := tinfoMap.Load(typ); ok {
|
||||
return ti.(*typeInfo), nil
|
||||
}
|
||||
tinfo = &typeInfo{}
|
||||
|
||||
tinfo := &typeInfo{}
|
||||
if typ.Kind() == reflect.Struct && typ != nameType {
|
||||
n := typ.NumField()
|
||||
for i := 0; i < n; i++ {
|
||||
f := typ.Field(i)
|
||||
if f.PkgPath != "" || f.Tag.Get("xml") == "-" {
|
||||
if (f.PkgPath != "" && !f.Anonymous) || f.Tag.Get("xml") == "-" {
|
||||
continue // Private field
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ func getTypeInfo(typ reflect.Type) (*typeInfo, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if f.Name == "XMLName" {
|
||||
if f.Name == xmlName {
|
||||
tinfo.xmlname = finfo
|
||||
continue
|
||||
}
|
||||
|
@ -105,10 +105,9 @@ func getTypeInfo(typ reflect.Type) (*typeInfo, error) {
|
|||
}
|
||||
}
|
||||
}
|
||||
tinfoLock.Lock()
|
||||
tinfoMap[typ] = tinfo
|
||||
tinfoLock.Unlock()
|
||||
return tinfo, nil
|
||||
|
||||
ti, _ := tinfoMap.LoadOrStore(typ, tinfo)
|
||||
return ti.(*typeInfo), nil
|
||||
}
|
||||
|
||||
// structFieldInfo builds and returns a fieldInfo for f.
|
||||
|
@ -131,6 +130,8 @@ func structFieldInfo(typ reflect.Type, f *reflect.StructField) (*fieldInfo, erro
|
|||
switch flag {
|
||||
case "attr":
|
||||
finfo.flags |= fAttr
|
||||
case "cdata":
|
||||
finfo.flags |= fCDATA
|
||||
case "chardata":
|
||||
finfo.flags |= fCharData
|
||||
case "innerxml":
|
||||
|
@ -151,8 +152,8 @@ func structFieldInfo(typ reflect.Type, f *reflect.StructField) (*fieldInfo, erro
|
|||
switch mode := finfo.flags & fMode; mode {
|
||||
case 0:
|
||||
finfo.flags |= fElement
|
||||
case fAttr, fCharData, fInnerXml, fComment, fAny:
|
||||
if f.Name == "XMLName" || tag != "" && mode != fAttr {
|
||||
case fAttr, fCDATA, fCharData, fInnerXml, fComment, fAny, fAny | fAttr:
|
||||
if f.Name == xmlName || tag != "" && mode != fAttr {
|
||||
valid = false
|
||||
}
|
||||
default:
|
||||
|
@ -177,7 +178,7 @@ func structFieldInfo(typ reflect.Type, f *reflect.StructField) (*fieldInfo, erro
|
|||
f.Name, typ, f.Tag.Get("xml"))
|
||||
}
|
||||
|
||||
if f.Name == "XMLName" {
|
||||
if f.Name == xmlName {
|
||||
// The XMLName field records the XML element name. Don't
|
||||
// process it as usual because its name should default to
|
||||
// empty rather than to the field name.
|
||||
|
@ -214,7 +215,7 @@ func structFieldInfo(typ reflect.Type, f *reflect.StructField) (*fieldInfo, erro
|
|||
}
|
||||
|
||||
// If the field type has an XMLName field, the names must match
|
||||
// so that the behavior of both marshalling and unmarshalling
|
||||
// so that the behavior of both marshaling and unmarshaling
|
||||
// is straightforward and unambiguous.
|
||||
if finfo.flags&fElement != 0 {
|
||||
ftyp := f.Type
|
||||
|
@ -239,11 +240,11 @@ func lookupXMLName(typ reflect.Type) (xmlname *fieldInfo) {
|
|||
}
|
||||
for i, n := 0, typ.NumField(); i < n; i++ {
|
||||
f := typ.Field(i)
|
||||
if f.Name != "XMLName" {
|
||||
if f.Name != xmlName {
|
||||
continue
|
||||
}
|
||||
finfo, err := structFieldInfo(typ, &f)
|
||||
if finfo.name != "" && err == nil {
|
||||
if err == nil && finfo.name != "" {
|
||||
return finfo
|
||||
}
|
||||
// Also consider errors as a non-existent field tag
|
||||
|
@ -334,7 +335,7 @@ Loop:
|
|||
return nil
|
||||
}
|
||||
|
||||
// A TagPathError represents an error in the unmarshalling process
|
||||
// A TagPathError represents an error in the unmarshaling process
|
||||
// caused by the use of field tags with conflicting paths.
|
||||
type TagPathError struct {
|
||||
Struct reflect.Type
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
package xml
|
||||
|
||||
// References:
|
||||
// Annotated XML spec: http://www.xml.com/axml/testaxml.htm
|
||||
// XML name spaces: http://www.w3.org/TR/REC-xml-names/
|
||||
// Annotated XML spec: https://www.xml.com/axml/testaxml.htm
|
||||
// XML name spaces: https://www.w3.org/TR/REC-xml-names/
|
||||
|
||||
// TODO(rsc):
|
||||
// Test error handling.
|
||||
|
@ -61,6 +61,7 @@ type StartElement struct {
|
|||
Attr []Attr
|
||||
}
|
||||
|
||||
// Copy creates a new copy of StartElement.
|
||||
func (e StartElement) Copy() StartElement {
|
||||
attrs := make([]Attr, len(e.Attr))
|
||||
copy(attrs, e.Attr)
|
||||
|
@ -89,12 +90,14 @@ func makeCopy(b []byte) []byte {
|
|||
return b1
|
||||
}
|
||||
|
||||
// Copy creates a new copy of CharData.
|
||||
func (c CharData) Copy() CharData { return CharData(makeCopy(c)) }
|
||||
|
||||
// A Comment represents an XML comment of the form <!--comment-->.
|
||||
// The bytes do not include the <!-- and --> comment markers.
|
||||
type Comment []byte
|
||||
|
||||
// Copy creates a new copy of Comment.
|
||||
func (c Comment) Copy() Comment { return Comment(makeCopy(c)) }
|
||||
|
||||
// A ProcInst represents an XML processing instruction of the form <?target inst?>
|
||||
|
@ -103,6 +106,7 @@ type ProcInst struct {
|
|||
Inst []byte
|
||||
}
|
||||
|
||||
// Copy creates a new copy of ProcInst.
|
||||
func (p ProcInst) Copy() ProcInst {
|
||||
p.Inst = makeCopy(p.Inst)
|
||||
return p
|
||||
|
@ -112,6 +116,7 @@ func (p ProcInst) Copy() ProcInst {
|
|||
// The bytes do not include the <! and > markers.
|
||||
type Directive []byte
|
||||
|
||||
// Copy creates a new copy of Directive.
|
||||
func (d Directive) Copy() Directive { return Directive(makeCopy(d)) }
|
||||
|
||||
// CopyToken returns a copy of a Token.
|
||||
|
@ -131,6 +136,23 @@ func CopyToken(t Token) Token {
|
|||
return t
|
||||
}
|
||||
|
||||
// A TokenReader is anything that can decode a stream of XML tokens, including a
|
||||
// Decoder.
|
||||
//
|
||||
// When Token encounters an error or end-of-file condition after successfully
|
||||
// reading a token, it returns the token. It may return the (non-nil) error from
|
||||
// the same call or return the error (and a nil token) from a subsequent call.
|
||||
// An instance of this general case is that a TokenReader returning a non-nil
|
||||
// token at the end of the token stream may return either io.EOF or a nil error.
|
||||
// The next Read should return nil, io.EOF.
|
||||
//
|
||||
// Implementations of Token are discouraged from returning a nil token with a
|
||||
// nil error. Callers should treat a return of nil, nil as indicating that
|
||||
// nothing happened; in particular it does not indicate EOF.
|
||||
type TokenReader interface {
|
||||
Token() (Token, error)
|
||||
}
|
||||
|
||||
// A Decoder represents an XML parser reading a particular input stream.
|
||||
// The parser assumes that its input is encoded in UTF-8.
|
||||
type Decoder struct {
|
||||
|
@ -146,9 +168,9 @@ type Decoder struct {
|
|||
//
|
||||
// Setting:
|
||||
//
|
||||
// d.Strict = false;
|
||||
// d.AutoClose = HTMLAutoClose;
|
||||
// d.Entity = HTMLEntity
|
||||
// d.Strict = false
|
||||
// d.AutoClose = xml.HTMLAutoClose
|
||||
// d.Entity = xml.HTMLEntity
|
||||
//
|
||||
// creates a parser that can handle typical HTML.
|
||||
//
|
||||
|
@ -177,7 +199,7 @@ type Decoder struct {
|
|||
// charset-conversion readers, converting from the provided
|
||||
// non-UTF-8 charset into UTF-8. If CharsetReader is nil or
|
||||
// returns an error, parsing stops with an error. One of the
|
||||
// the CharsetReader's result values must be non-nil.
|
||||
// CharsetReader's result values must be non-nil.
|
||||
CharsetReader func(charset string, input io.Reader) (io.Reader, error)
|
||||
|
||||
// DefaultSpace sets the default name space used for unadorned tags,
|
||||
|
@ -189,6 +211,7 @@ type Decoder struct {
|
|||
TypeFunc func(string) (reflect.Type, bool)
|
||||
|
||||
r io.ByteReader
|
||||
t TokenReader
|
||||
buf bytes.Buffer
|
||||
saved *bytes.Buffer
|
||||
stk *stack
|
||||
|
@ -200,6 +223,7 @@ type Decoder struct {
|
|||
ns map[string]string
|
||||
err error
|
||||
line int
|
||||
offset int64
|
||||
unmarshalDepth int
|
||||
}
|
||||
|
||||
|
@ -217,12 +241,28 @@ func NewDecoder(r io.Reader) *Decoder {
|
|||
return d
|
||||
}
|
||||
|
||||
// NewTokenDecoder creates a new XML parser using an underlying token stream.
|
||||
func NewTokenDecoder(t TokenReader) *Decoder {
|
||||
// Is it already a Decoder?
|
||||
if d, ok := t.(*Decoder); ok {
|
||||
return d
|
||||
}
|
||||
d := &Decoder{
|
||||
ns: make(map[string]string),
|
||||
t: t,
|
||||
nextByte: -1,
|
||||
line: 1,
|
||||
Strict: true,
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
// Token returns the next XML token in the input stream.
|
||||
// At the end of the input stream, Token returns nil, io.EOF.
|
||||
//
|
||||
// Slices of bytes in the returned token data refer to the
|
||||
// parser's internal buffer and remain valid only until the next
|
||||
// call to Token. To acquire a copy of the bytes, call CopyToken
|
||||
// call to Token. To acquire a copy of the bytes, call CopyToken
|
||||
// or the token's Copy method.
|
||||
//
|
||||
// Token expands self-closing elements such as <br/>
|
||||
|
@ -230,25 +270,30 @@ func NewDecoder(r io.Reader) *Decoder {
|
|||
//
|
||||
// Token guarantees that the StartElement and EndElement
|
||||
// tokens it returns are properly nested and matched:
|
||||
// if Token encounters an unexpected end element,
|
||||
// if Token encounters an unexpected end element
|
||||
// or EOF before all expected end elements,
|
||||
// it will return an error.
|
||||
//
|
||||
// Token implements XML name spaces as described by
|
||||
// http://www.w3.org/TR/REC-xml-names/. Each of the
|
||||
// https://www.w3.org/TR/REC-xml-names/. Each of the
|
||||
// Name structures contained in the Token has the Space
|
||||
// set to the URL identifying its name space when known.
|
||||
// If Token encounters an unrecognized name space prefix,
|
||||
// it uses the prefix as the Space rather than report an error.
|
||||
func (d *Decoder) Token() (t Token, err error) {
|
||||
func (d *Decoder) Token() (Token, error) {
|
||||
var t Token
|
||||
var err error
|
||||
if d.stk != nil && d.stk.kind == stkEOF {
|
||||
err = io.EOF
|
||||
return
|
||||
return nil, io.EOF
|
||||
}
|
||||
if d.nextToken != nil {
|
||||
t = d.nextToken
|
||||
d.nextToken = nil
|
||||
} else if t, err = d.rawToken(); err != nil {
|
||||
return
|
||||
if err == io.EOF && d.stk != nil && d.stk.kind != stkEOF {
|
||||
err = d.syntaxError("unexpected EOF")
|
||||
}
|
||||
return t, err
|
||||
}
|
||||
|
||||
if !d.Strict {
|
||||
|
@ -264,12 +309,12 @@ func (d *Decoder) Token() (t Token, err error) {
|
|||
// to the other attribute names, so process
|
||||
// the translations first.
|
||||
for _, a := range t1.Attr {
|
||||
if a.Name.Space == "xmlns" {
|
||||
if a.Name.Space == xmlnsPrefix {
|
||||
v, ok := d.ns[a.Name.Local]
|
||||
d.pushNs(a.Name.Local, v, ok)
|
||||
d.ns[a.Name.Local] = a.Value
|
||||
}
|
||||
if a.Name.Space == "" && a.Name.Local == "xmlns" {
|
||||
if a.Name.Space == "" && a.Name.Local == xmlnsPrefix {
|
||||
// Default space for untagged names
|
||||
v, ok := d.ns[""]
|
||||
d.pushNs("", v, ok)
|
||||
|
@ -291,23 +336,27 @@ func (d *Decoder) Token() (t Token, err error) {
|
|||
}
|
||||
t = t1
|
||||
}
|
||||
return
|
||||
return t, err
|
||||
}
|
||||
|
||||
const xmlURL = "http://www.w3.org/XML/1998/namespace"
|
||||
const (
|
||||
xmlURL = "http://www.w3.org/XML/1998/namespace"
|
||||
xmlnsPrefix = "xmlns"
|
||||
xmlPrefix = "xml"
|
||||
)
|
||||
|
||||
// Apply name space translation to name n.
|
||||
// The default name space (for Space=="")
|
||||
// applies only to element names, not to attribute names.
|
||||
func (d *Decoder) translate(n *Name, isElementName bool) {
|
||||
switch {
|
||||
case n.Space == "xmlns":
|
||||
case n.Space == xmlnsPrefix:
|
||||
return
|
||||
case n.Space == "" && !isElementName:
|
||||
return
|
||||
case n.Space == "xml":
|
||||
case n.Space == xmlPrefix:
|
||||
n.Space = xmlURL
|
||||
case n.Space == "" && n.Local == "xmlns":
|
||||
case n.Space == "" && n.Local == xmlnsPrefix:
|
||||
return
|
||||
}
|
||||
if v, ok := d.ns[n.Space]; ok {
|
||||
|
@ -330,7 +379,7 @@ func (d *Decoder) switchToReader(r io.Reader) {
|
|||
}
|
||||
|
||||
// Parsing state - stack holds old name space translations
|
||||
// and the current set of open elements. The translations to pop when
|
||||
// and the current set of open elements. The translations to pop when
|
||||
// ending a given tag are *below* it on the stack, which is
|
||||
// more work but forced on us by XML.
|
||||
type stack struct {
|
||||
|
@ -501,6 +550,9 @@ func (d *Decoder) RawToken() (Token, error) {
|
|||
}
|
||||
|
||||
func (d *Decoder) rawToken() (Token, error) {
|
||||
if d.t != nil {
|
||||
return d.t.Token()
|
||||
}
|
||||
if d.err != nil {
|
||||
return nil, d.err
|
||||
}
|
||||
|
@ -552,7 +604,6 @@ func (d *Decoder) rawToken() (Token, error) {
|
|||
|
||||
case '?':
|
||||
// <?: Processing instruction.
|
||||
// TODO(rsc): Should parse the <?xml declaration to make sure the version is 1.0.
|
||||
var target string
|
||||
if target, ok = d.name(); !ok {
|
||||
if d.err == nil {
|
||||
|
@ -577,8 +628,14 @@ func (d *Decoder) rawToken() (Token, error) {
|
|||
data = data[0 : len(data)-2] // chop ?>
|
||||
|
||||
if target == "xml" {
|
||||
enc := procInstEncoding(string(data))
|
||||
if enc != "" && enc != "utf-8" && enc != "UTF-8" {
|
||||
content := string(data)
|
||||
ver := procInst("version", content)
|
||||
if ver != "" && ver != "1.0" {
|
||||
d.err = fmt.Errorf("xml: unsupported version %q; only version 1.0 is supported", ver)
|
||||
return nil, d.err
|
||||
}
|
||||
enc := procInst("encoding", content)
|
||||
if enc != "" && enc != "utf-8" && enc != "UTF-8" && !strings.EqualFold(enc, "utf-8") {
|
||||
if d.CharsetReader == nil {
|
||||
d.err = fmt.Errorf("xml: encoding %q declared but Decoder.CharsetReader is nil", enc)
|
||||
return nil, d.err
|
||||
|
@ -619,7 +676,12 @@ func (d *Decoder) rawToken() (Token, error) {
|
|||
return nil, d.err
|
||||
}
|
||||
d.buf.WriteByte(b)
|
||||
if b0 == '-' && b1 == '-' && b == '>' {
|
||||
if b0 == '-' && b1 == '-' {
|
||||
if b != '>' {
|
||||
d.err = d.syntaxError(
|
||||
`invalid sequence "--" not allowed in comments`)
|
||||
return nil, d.err
|
||||
}
|
||||
break
|
||||
}
|
||||
b0, b1 = b1, b
|
||||
|
@ -726,7 +788,7 @@ func (d *Decoder) rawToken() (Token, error) {
|
|||
return nil, d.err
|
||||
}
|
||||
|
||||
attr = make([]Attr, 0, 4)
|
||||
attr = []Attr{}
|
||||
for {
|
||||
d.space()
|
||||
if b, ok = d.mustgetc(); !ok {
|
||||
|
@ -748,14 +810,7 @@ func (d *Decoder) rawToken() (Token, error) {
|
|||
}
|
||||
d.ungetc(b)
|
||||
|
||||
n := len(attr)
|
||||
if n >= cap(attr) {
|
||||
nattr := make([]Attr, n, 2*cap(attr))
|
||||
copy(nattr, attr)
|
||||
attr = nattr
|
||||
}
|
||||
attr = attr[0 : n+1]
|
||||
a := &attr[n]
|
||||
a := Attr{}
|
||||
if a.Name, ok = d.nsname(); !ok {
|
||||
if d.err == nil {
|
||||
d.err = d.syntaxError("expected attribute name in element")
|
||||
|
@ -770,10 +825,9 @@ func (d *Decoder) rawToken() (Token, error) {
|
|||
if d.Strict {
|
||||
d.err = d.syntaxError("attribute name without = in element")
|
||||
return nil, d.err
|
||||
} else {
|
||||
d.ungetc(b)
|
||||
a.Value = a.Name.Local
|
||||
}
|
||||
d.ungetc(b)
|
||||
a.Value = a.Name.Local
|
||||
} else {
|
||||
d.space()
|
||||
data := d.attrval()
|
||||
|
@ -782,6 +836,7 @@ func (d *Decoder) rawToken() (Token, error) {
|
|||
}
|
||||
a.Value = string(data)
|
||||
}
|
||||
attr = append(attr, a)
|
||||
}
|
||||
if empty {
|
||||
d.needClose = true
|
||||
|
@ -812,7 +867,7 @@ func (d *Decoder) attrval() []byte {
|
|||
if !ok {
|
||||
return nil
|
||||
}
|
||||
// http://www.w3.org/TR/REC-html40/intro/sgmltut.html#h-3.2.2
|
||||
// https://www.w3.org/TR/REC-html40/intro/sgmltut.html#h-3.2.2
|
||||
if 'a' <= b && b <= 'z' || 'A' <= b && b <= 'Z' ||
|
||||
'0' <= b && b <= '9' || b == '_' || b == ':' || b == '-' {
|
||||
d.buf.WriteByte(b)
|
||||
|
@ -863,9 +918,17 @@ func (d *Decoder) getc() (b byte, ok bool) {
|
|||
if b == '\n' {
|
||||
d.line++
|
||||
}
|
||||
d.offset++
|
||||
return b, true
|
||||
}
|
||||
|
||||
// InputOffset returns the input stream byte offset of the current decoder position.
|
||||
// The offset gives the location of the end of the most recently returned token
|
||||
// and the beginning of the next token.
|
||||
func (d *Decoder) InputOffset() int64 {
|
||||
return d.offset
|
||||
}
|
||||
|
||||
// Return saved offset.
|
||||
// If we did ungetc (nextByte >= 0), have to back up one.
|
||||
func (d *Decoder) savedOffset() int {
|
||||
|
@ -895,6 +958,7 @@ func (d *Decoder) ungetc(b byte) {
|
|||
d.line--
|
||||
}
|
||||
d.nextByte = int(b)
|
||||
d.offset--
|
||||
}
|
||||
|
||||
var entity = map[string]int{
|
||||
|
@ -1002,7 +1066,6 @@ Input:
|
|||
if d.err != nil {
|
||||
return nil
|
||||
}
|
||||
ok = false
|
||||
}
|
||||
if b, ok = d.mustgetc(); !ok {
|
||||
return nil
|
||||
|
@ -1075,13 +1138,13 @@ Input:
|
|||
}
|
||||
|
||||
// Decide whether the given rune is in the XML Character Range, per
|
||||
// the Char production of http://www.xml.com/axml/testaxml.htm,
|
||||
// the Char production of https://www.xml.com/axml/testaxml.htm,
|
||||
// Section 2.2 Characters.
|
||||
func isInCharacterRange(r rune) (inrange bool) {
|
||||
return r == 0x09 ||
|
||||
r == 0x0A ||
|
||||
r == 0x0D ||
|
||||
r >= 0x20 && r <= 0xDF77 ||
|
||||
r >= 0x20 && r <= 0xD7FF ||
|
||||
r >= 0xE000 && r <= 0xFFFD ||
|
||||
r >= 0x10000 && r <= 0x10FFFF
|
||||
}
|
||||
|
@ -1113,12 +1176,12 @@ func (d *Decoder) name() (s string, ok bool) {
|
|||
}
|
||||
|
||||
// Now we check the characters.
|
||||
s = d.buf.String()
|
||||
if !isName([]byte(s)) {
|
||||
d.err = d.syntaxError("invalid XML name: " + s)
|
||||
b := d.buf.Bytes()
|
||||
if !isName(b) {
|
||||
d.err = d.syntaxError("invalid XML name: " + string(b))
|
||||
return "", false
|
||||
}
|
||||
return s, true
|
||||
return string(b), true
|
||||
}
|
||||
|
||||
// Read a name and append its bytes to d.buf.
|
||||
|
@ -1204,8 +1267,8 @@ func isNameString(s string) bool {
|
|||
}
|
||||
|
||||
// These tables were generated by cut and paste from Appendix B of
|
||||
// the XML spec at http://www.xml.com/axml/testaxml.htm
|
||||
// and then reformatting. First corresponds to (Letter | '_' | ':')
|
||||
// the XML spec at https://www.xml.com/axml/testaxml.htm
|
||||
// and then reformatting. First corresponds to (Letter | '_' | ':')
|
||||
// and second corresponds to NameChar.
|
||||
|
||||
var first = &unicode.RangeTable{
|
||||
|
@ -1522,7 +1585,9 @@ var second = &unicode.RangeTable{
|
|||
|
||||
// HTMLEntity is an entity map containing translations for the
|
||||
// standard HTML entity characters.
|
||||
var HTMLEntity = htmlEntity
|
||||
//
|
||||
// See the Decoder.Strict and Decoder.Entity fields' documentation.
|
||||
var HTMLEntity map[string]string = htmlEntity
|
||||
|
||||
var htmlEntity = map[string]string{
|
||||
/*
|
||||
|
@ -1789,7 +1854,9 @@ var htmlEntity = map[string]string{
|
|||
|
||||
// HTMLAutoClose is the set of HTML elements that
|
||||
// should be considered to close automatically.
|
||||
var HTMLAutoClose = htmlAutoClose
|
||||
//
|
||||
// See the Decoder.Strict and Decoder.Entity fields' documentation.
|
||||
var HTMLAutoClose []string = htmlAutoClose
|
||||
|
||||
var htmlAutoClose = []string{
|
||||
/*
|
||||
|
@ -1812,20 +1879,27 @@ var htmlAutoClose = []string{
|
|||
}
|
||||
|
||||
var (
|
||||
esc_quot = []byte(""") // shorter than """
|
||||
esc_apos = []byte("'") // shorter than "'"
|
||||
esc_amp = []byte("&")
|
||||
esc_lt = []byte("<")
|
||||
esc_gt = []byte(">")
|
||||
esc_tab = []byte("	")
|
||||
esc_nl = []byte("
")
|
||||
esc_cr = []byte("
")
|
||||
esc_fffd = []byte("\uFFFD") // Unicode replacement character
|
||||
escQuot = []byte(""") // shorter than """
|
||||
escApos = []byte("'") // shorter than "'"
|
||||
escAmp = []byte("&")
|
||||
escLT = []byte("<")
|
||||
escGT = []byte(">")
|
||||
escTab = []byte("	")
|
||||
escNL = []byte("
")
|
||||
escCR = []byte("
")
|
||||
escFFFD = []byte("\uFFFD") // Unicode replacement character
|
||||
)
|
||||
|
||||
// EscapeText writes to w the properly escaped XML equivalent
|
||||
// of the plain text data s.
|
||||
func EscapeText(w io.Writer, s []byte) error {
|
||||
return escapeText(w, s, true)
|
||||
}
|
||||
|
||||
// escapeText writes to w the properly escaped XML equivalent
|
||||
// of the plain text data s. If escapeNewline is true, newline
|
||||
// characters will be escaped.
|
||||
func escapeText(w io.Writer, s []byte, escapeNewline bool) error {
|
||||
var esc []byte
|
||||
last := 0
|
||||
for i := 0; i < len(s); {
|
||||
|
@ -1833,24 +1907,27 @@ func EscapeText(w io.Writer, s []byte) error {
|
|||
i += width
|
||||
switch r {
|
||||
case '"':
|
||||
esc = esc_quot
|
||||
esc = escQuot
|
||||
case '\'':
|
||||
esc = esc_apos
|
||||
esc = escApos
|
||||
case '&':
|
||||
esc = esc_amp
|
||||
esc = escAmp
|
||||
case '<':
|
||||
esc = esc_lt
|
||||
esc = escLT
|
||||
case '>':
|
||||
esc = esc_gt
|
||||
esc = escGT
|
||||
case '\t':
|
||||
esc = esc_tab
|
||||
esc = escTab
|
||||
case '\n':
|
||||
esc = esc_nl
|
||||
if !escapeNewline {
|
||||
continue
|
||||
}
|
||||
esc = escNL
|
||||
case '\r':
|
||||
esc = esc_cr
|
||||
esc = escCR
|
||||
default:
|
||||
if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) {
|
||||
esc = esc_fffd
|
||||
esc = escFFFD
|
||||
break
|
||||
}
|
||||
continue
|
||||
|
@ -1863,10 +1940,8 @@ func EscapeText(w io.Writer, s []byte) error {
|
|||
}
|
||||
last = i
|
||||
}
|
||||
if _, err := w.Write(s[last:]); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
_, err := w.Write(s[last:])
|
||||
return err
|
||||
}
|
||||
|
||||
// EscapeString writes to p the properly escaped XML equivalent
|
||||
|
@ -1879,24 +1954,24 @@ func (p *printer) EscapeString(s string) {
|
|||
i += width
|
||||
switch r {
|
||||
case '"':
|
||||
esc = esc_quot
|
||||
esc = escQuot
|
||||
case '\'':
|
||||
esc = esc_apos
|
||||
esc = escApos
|
||||
case '&':
|
||||
esc = esc_amp
|
||||
esc = escAmp
|
||||
case '<':
|
||||
esc = esc_lt
|
||||
esc = escLT
|
||||
case '>':
|
||||
esc = esc_gt
|
||||
esc = escGT
|
||||
case '\t':
|
||||
esc = esc_tab
|
||||
esc = escTab
|
||||
case '\n':
|
||||
esc = esc_nl
|
||||
esc = escNL
|
||||
case '\r':
|
||||
esc = esc_cr
|
||||
esc = escCR
|
||||
default:
|
||||
if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) {
|
||||
esc = esc_fffd
|
||||
esc = escFFFD
|
||||
break
|
||||
}
|
||||
continue
|
||||
|
@ -1915,16 +1990,55 @@ func Escape(w io.Writer, s []byte) {
|
|||
EscapeText(w, s)
|
||||
}
|
||||
|
||||
// procInstEncoding parses the `encoding="..."` or `encoding='...'`
|
||||
var (
|
||||
cdataStart = []byte("<![CDATA[")
|
||||
cdataEnd = []byte("]]>")
|
||||
cdataEscape = []byte("]]]]><![CDATA[>")
|
||||
)
|
||||
|
||||
// emitCDATA writes to w the CDATA-wrapped plain text data s.
|
||||
// It escapes CDATA directives nested in s.
|
||||
func emitCDATA(w io.Writer, s []byte) error {
|
||||
if len(s) == 0 {
|
||||
return nil
|
||||
}
|
||||
if _, err := w.Write(cdataStart); err != nil {
|
||||
return err
|
||||
}
|
||||
for {
|
||||
i := bytes.Index(s, cdataEnd)
|
||||
if i >= 0 && i+len(cdataEnd) <= len(s) {
|
||||
// Found a nested CDATA directive end.
|
||||
if _, err := w.Write(s[:i]); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write(cdataEscape); err != nil {
|
||||
return err
|
||||
}
|
||||
i += len(cdataEnd)
|
||||
} else {
|
||||
if _, err := w.Write(s); err != nil {
|
||||
return err
|
||||
}
|
||||
break
|
||||
}
|
||||
s = s[i:]
|
||||
}
|
||||
_, err := w.Write(cdataEnd)
|
||||
return err
|
||||
}
|
||||
|
||||
// procInst parses the `param="..."` or `param='...'`
|
||||
// value out of the provided string, returning "" if not found.
|
||||
func procInstEncoding(s string) string {
|
||||
func procInst(param, s string) string {
|
||||
// TODO: this parsing is somewhat lame and not exact.
|
||||
// It works for all actual cases, though.
|
||||
idx := strings.Index(s, "encoding=")
|
||||
param = param + "="
|
||||
idx := strings.Index(s, param)
|
||||
if idx == -1 {
|
||||
return ""
|
||||
}
|
||||
v := s[idx+len("encoding="):]
|
||||
v := s[idx+len(param):]
|
||||
if v == "" {
|
||||
return ""
|
||||
}
|
||||
|
|
|
@ -559,7 +559,7 @@ github.com/ulikunitz/xz
|
|||
github.com/ulikunitz/xz/internal/hash
|
||||
github.com/ulikunitz/xz/internal/xlog
|
||||
github.com/ulikunitz/xz/lzma
|
||||
# github.com/vmware/govmomi v0.22.2
|
||||
# github.com/vmware/govmomi v0.23.1
|
||||
github.com/vmware/govmomi
|
||||
github.com/vmware/govmomi/find
|
||||
github.com/vmware/govmomi/list
|
||||
|
@ -568,6 +568,7 @@ github.com/vmware/govmomi/object
|
|||
github.com/vmware/govmomi/ovf
|
||||
github.com/vmware/govmomi/property
|
||||
github.com/vmware/govmomi/session
|
||||
github.com/vmware/govmomi/session/keepalive
|
||||
github.com/vmware/govmomi/task
|
||||
github.com/vmware/govmomi/vapi/internal
|
||||
github.com/vmware/govmomi/vapi/library
|
||||
|
|
|
@ -216,7 +216,7 @@ iso_paths = [
|
|||
|
||||
@include 'builder/vsphere/common/ContentLibraryDestinationConfig-not-required.mdx'
|
||||
|
||||
Minimal example of usage:
|
||||
Minimal example of usage to import a VM template:
|
||||
|
||||
<Tabs>
|
||||
<Tab heading="JSON">
|
||||
|
@ -239,6 +239,31 @@ Minimal example of usage:
|
|||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
Minimal example of usage to import a OVF template:
|
||||
|
||||
<Tabs>
|
||||
<Tab heading="JSON">
|
||||
|
||||
```json
|
||||
"content_library_destination" : {
|
||||
"library": "Packer Library Test",
|
||||
"ovf": true
|
||||
}
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="HCL2">
|
||||
|
||||
```hcl
|
||||
content_library_destination {
|
||||
library = "Packer Library Test"
|
||||
ovf = true
|
||||
}
|
||||
```
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### Extra Configuration Parameters
|
||||
|
||||
@include 'builder/vsphere/common/ConfigParamsConfig-not-required.mdx'
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
- `export` (\*common.ExportConfig) - Configuration for exporting VM to an ovf file.
|
||||
The VM will not be exported if no [Export Configuration](#export-configuration) is specified.
|
||||
|
||||
- `content_library_destination` (\*common.ContentLibraryDestinationConfig) - Configuration for importing the VM template to a Content Library.
|
||||
The VM template will not be imported if no [Content Library Import Configuration](#content-library-import-configuration) is specified.
|
||||
- `content_library_destination` (\*common.ContentLibraryDestinationConfig) - Configuration for importing a VM template or OVF template to a Content Library.
|
||||
The template will not be imported if no [Content Library Import Configuration](#content-library-import-configuration) is specified.
|
||||
The import doesn't work if [convert_to_template](#convert_to_template) is set to true.
|
||||
|
||||
- `customize` (\*CustomizeConfig) - Customize the cloned VM to configure host, network, or licensing settings. See the [customization options](#customization).
|
||||
|
|
|
@ -1,24 +1,35 @@
|
|||
<!-- Code generated from the comments of the ContentLibraryDestinationConfig struct in builder/vsphere/common/step_import_to_content_library.go; DO NOT EDIT MANUALLY -->
|
||||
|
||||
- `library` (string) - Name of the library in which the new library item containing the VM template should be created.
|
||||
- `library` (string) - Name of the library in which the new library item containing the template should be created/updated.
|
||||
The Content Library should be of type Local to allow deploying virtual machines.
|
||||
|
||||
- `name` (string) - Name of the library item that will be created. The name of the item should be different from [vm_name](#vm_name).
|
||||
Defaults to [vm_name](#vm_name) + timestamp.
|
||||
- `name` (string) - Name of the library item that will be created or updated.
|
||||
For VM templates, the name of the item should be different from [vm_name](#vm_name) and
|
||||
the default is [vm_name](#vm_name) + timestamp when not set. VM templates will be always imported to a new library item.
|
||||
For OVF templates, the name defaults to [vm_name](#vm_name) when not set, and if an item with the same name already
|
||||
exists it will be then updated with the new OVF template, otherwise a new item will be created.
|
||||
|
||||
~> **Note**: It's not possible to update existing library items with a new VM template. If updating an existing library
|
||||
item is necessary, use an OVF template instead by setting the [ovf](#ovf) option as `true`.
|
||||
|
||||
- `description` (string) - Description of the library item that will be created. Defaults to "Packer imported [vm_name](#vm_name) VM template".
|
||||
- `description` (string) - Description of the library item that will be created.
|
||||
This option is not used when importing OVF templates.
|
||||
Defaults to "Packer imported [vm_name](#vm_name) VM template".
|
||||
|
||||
- `cluster` (string) - Cluster onto which the virtual machine template should be placed.
|
||||
If cluster and resource_pool are both specified, resource_pool must belong to cluster.
|
||||
If cluster and host are both specified, host must be a member of cluster.
|
||||
This option is not used when importing OVF templates.
|
||||
Defaults to [cluster](#cluster).
|
||||
|
||||
- `folder` (string) - Virtual machine folder into which the virtual machine template should be placed.
|
||||
This option is not used when importing OVF templates.
|
||||
Defaults to the same folder as the source virtual machine.
|
||||
|
||||
- `host` (string) - Host onto which the virtual machine template should be placed.
|
||||
If host and resource_pool are both specified, resource_pool must belong to host.
|
||||
If host and cluster are both specified, host must be a member of cluster.
|
||||
This option is not used when importing OVF templates.
|
||||
Defaults to [host](#host).
|
||||
|
||||
- `resource_pool` (string) - Resource pool into which the virtual machine template should be placed.
|
||||
|
@ -26,6 +37,10 @@
|
|||
the system will attempt to choose a suitable resource pool for the virtual machine template.
|
||||
|
||||
- `datastore` (string) - The datastore for the virtual machine template's configuration and log files.
|
||||
This option is not used when importing OVF templates.
|
||||
Defaults to the storage backing associated with the library specified by library.
|
||||
|
||||
- `destroy` (bool) - If set to true, the VM will be destroyed after deploying the template to the Content Library. Defaults to `false`.
|
||||
- `destroy` (bool) - If set to true, the VM will be destroyed after deploying the template to the Content Library.
|
||||
Defaults to `false`.
|
||||
|
||||
- `ovf` (bool) - When set to true, Packer will import and OVF template to the content library item. Defaults to `false`.
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<!-- Code generated from the comments of the ContentLibraryDestinationConfig struct in builder/vsphere/common/step_import_to_content_library.go; DO NOT EDIT MANUALLY -->
|
||||
|
||||
With this configuration Packer creates a library item in a content library whose content is a virtual machine template created from the just built VM.
|
||||
The virtual machine template is stored in a newly created library item.
|
||||
With this configuration Packer creates a library item in a content library whose content is a VM template
|
||||
or an OVF template created from the just built VM.
|
||||
The template is stored in a existing or newly created library item.
|
||||
|
|
Loading…
Reference in New Issue