add vendoring with go dep

This commit is contained in:
Adrian Todorov
2017-10-25 20:52:40 +00:00
parent 704f4d20d1
commit a59409f16b
1627 changed files with 489673 additions and 0 deletions

137
vendor/github.com/vmware/govmomi/vim25/mo/ancestors.go generated vendored Normal file
View File

@@ -0,0 +1,137 @@
/*
Copyright (c) 2015 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 mo
import (
"context"
"fmt"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
// Ancestors returns the entire ancestry tree of a specified managed object.
// The return value includes the root node and the specified object itself.
func Ancestors(ctx context.Context, rt soap.RoundTripper, pc, obj types.ManagedObjectReference) ([]ManagedEntity, error) {
ospec := types.ObjectSpec{
Obj: obj,
SelectSet: []types.BaseSelectionSpec{
&types.TraversalSpec{
SelectionSpec: types.SelectionSpec{Name: "traverseParent"},
Type: "ManagedEntity",
Path: "parent",
Skip: types.NewBool(false),
SelectSet: []types.BaseSelectionSpec{
&types.SelectionSpec{Name: "traverseParent"},
},
},
&types.TraversalSpec{
SelectionSpec: types.SelectionSpec{},
Type: "VirtualMachine",
Path: "parentVApp",
Skip: types.NewBool(false),
SelectSet: []types.BaseSelectionSpec{
&types.SelectionSpec{Name: "traverseParent"},
},
},
},
Skip: types.NewBool(false),
}
pspec := []types.PropertySpec{
{
Type: "ManagedEntity",
PathSet: []string{"name", "parent"},
},
{
Type: "VirtualMachine",
PathSet: []string{"parentVApp"},
},
}
req := types.RetrieveProperties{
This: pc,
SpecSet: []types.PropertyFilterSpec{
{
ObjectSet: []types.ObjectSpec{ospec},
PropSet: pspec,
},
},
}
var ifaces []interface{}
err := RetrievePropertiesForRequest(ctx, rt, req, &ifaces)
if err != nil {
return nil, err
}
var out []ManagedEntity
// Build ancestry tree by iteratively finding a new child.
for len(out) < len(ifaces) {
var find types.ManagedObjectReference
if len(out) > 0 {
find = out[len(out)-1].Self
}
// Find entity we're looking for given the last entity in the current tree.
for _, iface := range ifaces {
me := iface.(IsManagedEntity).GetManagedEntity()
if me.Name == "" {
// The types below have their own 'Name' field, so ManagedEntity.Name (me.Name) is empty.
// We only hit this case when the 'obj' param is one of these types.
// In most cases, 'obj' is a Folder so Name isn't collected in this call.
switch x := iface.(type) {
case Network:
me.Name = x.Name
case DistributedVirtualSwitch:
me.Name = x.Name
case DistributedVirtualPortgroup:
me.Name = x.Name
case OpaqueNetwork:
me.Name = x.Name
default:
// ManagedEntity always has a Name, if we hit this point we missed a case above.
panic(fmt.Sprintf("%#v Name is empty", me.Reference()))
}
}
if me.Parent == nil {
// Special case for VirtualMachine within VirtualApp,
// unlikely to hit this other than via Finder.Element()
switch x := iface.(type) {
case VirtualMachine:
me.Parent = x.ParentVApp
}
}
if me.Parent == nil {
out = append(out, me)
break
}
if *me.Parent == find {
out = append(out, me)
break
}
}
}
return out, nil
}

24
vendor/github.com/vmware/govmomi/vim25/mo/entity.go generated vendored Normal file
View File

@@ -0,0 +1,24 @@
/*
Copyright (c) 2016 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 mo
// Entity is the interface that is implemented by all managed objects
// that extend ManagedEntity.
type Entity interface {
Reference
Entity() *ManagedEntity
}

61
vendor/github.com/vmware/govmomi/vim25/mo/extra.go generated vendored Normal file
View File

@@ -0,0 +1,61 @@
/*
Copyright (c) 2014 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 mo
type IsManagedEntity interface {
GetManagedEntity() ManagedEntity
}
func (m ComputeResource) GetManagedEntity() ManagedEntity {
return m.ManagedEntity
}
func (m Datacenter) GetManagedEntity() ManagedEntity {
return m.ManagedEntity
}
func (m Datastore) GetManagedEntity() ManagedEntity {
return m.ManagedEntity
}
func (m DistributedVirtualSwitch) GetManagedEntity() ManagedEntity {
return m.ManagedEntity
}
func (m DistributedVirtualPortgroup) GetManagedEntity() ManagedEntity {
return m.ManagedEntity
}
func (m Folder) GetManagedEntity() ManagedEntity {
return m.ManagedEntity
}
func (m HostSystem) GetManagedEntity() ManagedEntity {
return m.ManagedEntity
}
func (m Network) GetManagedEntity() ManagedEntity {
return m.ManagedEntity
}
func (m ResourcePool) GetManagedEntity() ManagedEntity {
return m.ManagedEntity
}
func (m VirtualMachine) GetManagedEntity() ManagedEntity {
return m.ManagedEntity
}

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<RetrievePropertiesResponse xmlns="urn:vim25" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<returnval>
<obj type="ClusterComputeResource">domain-c7</obj>
<propSet>
<name>host</name>
<val xsi:type="ArrayOfManagedObjectReference">
<ManagedObjectReference type="HostSystem" xsi:type="ManagedObjectReference">host-14</ManagedObjectReference>
<ManagedObjectReference type="HostSystem" xsi:type="ManagedObjectReference">host-17</ManagedObjectReference>
<ManagedObjectReference type="HostSystem" xsi:type="ManagedObjectReference">host-19</ManagedObjectReference>
<ManagedObjectReference type="HostSystem" xsi:type="ManagedObjectReference">host-52</ManagedObjectReference>
</val>
</propSet>
</returnval>
</RetrievePropertiesResponse>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<RetrievePropertiesResponse xmlns="urn:vim25" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<returnval>
<obj type="HostSystem">host-10</obj>
<propSet>
<name>name</name>
<val xsi:type="xsd:string">host-01.example.com</val>
</propSet>
</returnval>
<returnval>
<obj type="HostSystem">host-30</obj>
<propSet>
<name>name</name>
<val xsi:type="xsd:string">host-02.example.com</val>
</propSet>
</returnval>
</RetrievePropertiesResponse>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<RetrievePropertiesResponse xmlns="urn:vim25" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<returnval>
<obj type="VirtualMachine">vm-411</obj>
<propSet>
<name>config.name</name>
<val xsi:type="xsd:string">kubernetes-master</val>
</propSet>
<propSet>
<name>config.uuid</name>
<val xsi:type="xsd:string">422ec880-ab06-06b4-23f3-beb7a052a4c9</val>
</propSet>
</returnval>
</RetrievePropertiesResponse>

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<RetrievePropertiesResponse xmlns="urn:vim25" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<returnval>
<obj type="SessionManager">SessionManager</obj>
<propSet>
<name>defaultLocale</name>
<val xsi:type="xsd:string">en</val>
</propSet>
<propSet>
<name>messageLocaleList</name>
<val xsi:type="ArrayOfString">
<string xsi:type="xsd:string">ja</string>
<string xsi:type="xsd:string">zh_CN</string>
<string xsi:type="xsd:string">en</string>
<string xsi:type="xsd:string">de</string>
<string xsi:type="xsd:string">zh_TW</string>
<string xsi:type="xsd:string">ko</string>
<string xsi:type="xsd:string">fr</string>
</val>
</propSet>
<missingSet>
<path>message</path>
<fault>
<fault xsi:type="NotAuthenticated">
<object type="Folder">group-d1</object>
<privilegeId>System.View</privilegeId>
</fault>
<localizedMessage/>
</fault>
</missingSet>
<missingSet>
<path>sessionList</path>
<fault>
<fault xsi:type="NotAuthenticated">
<object type="Folder">group-d1</object>
<privilegeId>Sessions.TerminateSession</privilegeId>
</fault>
<localizedMessage/>
</fault>
</missingSet>
</returnval>
</RetrievePropertiesResponse>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<RetrievePropertiesResponse xmlns="urn:vim25" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<returnval>
<obj type="VirtualMachine">vm-411</obj>
<propSet>
<name>config.bootOptions</name>
<val xsi:type="VirtualMachineBootOptions">
<bootDelay>0</bootDelay>
<enterBIOSSetup>false</enterBIOSSetup>
<bootRetryEnabled>false</bootRetryEnabled>
<bootRetryDelay>10000</bootRetryDelay>
</val>
</propSet>
</returnval>
</RetrievePropertiesResponse>

1757
vendor/github.com/vmware/govmomi/vim25/mo/mo.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

26
vendor/github.com/vmware/govmomi/vim25/mo/reference.go generated vendored Normal file
View File

@@ -0,0 +1,26 @@
/*
Copyright (c) 2015 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 mo
import "github.com/vmware/govmomi/vim25/types"
// Reference is the interface that is implemented by all the managed objects
// defined in this package. It specifies that these managed objects have a
// function that returns the managed object reference to themselves.
type Reference interface {
Reference() types.ManagedObjectReference
}

21
vendor/github.com/vmware/govmomi/vim25/mo/registry.go generated vendored Normal file
View File

@@ -0,0 +1,21 @@
/*
Copyright (c) 2014 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 mo
import "reflect"
var t = map[string]reflect.Type{}

174
vendor/github.com/vmware/govmomi/vim25/mo/retrieve.go generated vendored Normal file
View File

@@ -0,0 +1,174 @@
/*
Copyright (c) 2014-2015 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 mo
import (
"context"
"reflect"
"github.com/vmware/govmomi/vim25/methods"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)
func ignoreMissingProperty(ref types.ManagedObjectReference, p types.MissingProperty) bool {
switch ref.Type {
case "VirtualMachine":
switch p.Path {
case "environmentBrowser":
// See https://github.com/vmware/govmomi/pull/242
return true
case "alarmActionsEnabled":
// Seen with vApp child VM
return true
}
}
return false
}
// ObjectContentToType loads an ObjectContent value into the value it
// represents. If the ObjectContent value has a non-empty 'MissingSet' field,
// it returns the first fault it finds there as error. If the 'MissingSet'
// field is empty, it returns a pointer to a reflect.Value. It handles contain
// nested properties, such as 'guest.ipAddress' or 'config.hardware'.
func ObjectContentToType(o types.ObjectContent) (interface{}, error) {
// Expect no properties in the missing set
for _, p := range o.MissingSet {
if ignoreMissingProperty(o.Obj, p) {
continue
}
return nil, soap.WrapVimFault(p.Fault.Fault)
}
ti := typeInfoForType(o.Obj.Type)
v, err := ti.LoadFromObjectContent(o)
if err != nil {
return nil, err
}
return v.Elem().Interface(), nil
}
// LoadRetrievePropertiesResponse converts the response of a call to
// RetrieveProperties to one or more managed objects.
func LoadRetrievePropertiesResponse(res *types.RetrievePropertiesResponse, dst interface{}) error {
rt := reflect.TypeOf(dst)
if rt == nil || rt.Kind() != reflect.Ptr {
panic("need pointer")
}
rv := reflect.ValueOf(dst).Elem()
if !rv.CanSet() {
panic("cannot set dst")
}
isSlice := false
switch rt.Elem().Kind() {
case reflect.Struct:
case reflect.Slice:
isSlice = true
default:
panic("unexpected type")
}
if isSlice {
for _, p := range res.Returnval {
v, err := ObjectContentToType(p)
if err != nil {
return err
}
vt := reflect.TypeOf(v)
if !rv.Type().AssignableTo(vt) {
// For example: dst is []ManagedEntity, res is []HostSystem
if field, ok := vt.FieldByName(rt.Elem().Elem().Name()); ok && field.Anonymous {
rv.Set(reflect.Append(rv, reflect.ValueOf(v).FieldByIndex(field.Index)))
continue
}
}
rv.Set(reflect.Append(rv, reflect.ValueOf(v)))
}
} else {
switch len(res.Returnval) {
case 0:
case 1:
v, err := ObjectContentToType(res.Returnval[0])
if err != nil {
return err
}
vt := reflect.TypeOf(v)
if !rv.Type().AssignableTo(vt) {
// For example: dst is ComputeResource, res is ClusterComputeResource
if field, ok := vt.FieldByName(rt.Elem().Name()); ok && field.Anonymous {
rv.Set(reflect.ValueOf(v).FieldByIndex(field.Index))
return nil
}
}
rv.Set(reflect.ValueOf(v))
default:
// If dst is not a slice, expect to receive 0 or 1 results
panic("more than 1 result")
}
}
return nil
}
// RetrievePropertiesForRequest calls the RetrieveProperties method with the
// specified request and decodes the response struct into the value pointed to
// by dst.
func RetrievePropertiesForRequest(ctx context.Context, r soap.RoundTripper, req types.RetrieveProperties, dst interface{}) error {
res, err := methods.RetrieveProperties(ctx, r, &req)
if err != nil {
return err
}
return LoadRetrievePropertiesResponse(res, dst)
}
// RetrieveProperties retrieves the properties of the managed object specified
// as obj and decodes the response struct into the value pointed to by dst.
func RetrieveProperties(ctx context.Context, r soap.RoundTripper, pc, obj types.ManagedObjectReference, dst interface{}) error {
req := types.RetrieveProperties{
This: pc,
SpecSet: []types.PropertyFilterSpec{
{
ObjectSet: []types.ObjectSpec{
{
Obj: obj,
Skip: types.NewBool(false),
},
},
PropSet: []types.PropertySpec{
{
All: types.NewBool(true),
Type: obj.Type,
},
},
},
},
}
return RetrievePropertiesForRequest(ctx, r, req, dst)
}

View File

@@ -0,0 +1,144 @@
/*
Copyright (c) 2014-2015 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 mo
import (
"os"
"testing"
"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
"github.com/vmware/govmomi/vim25/xml"
)
func load(name string) *types.RetrievePropertiesResponse {
f, err := os.Open(name)
if err != nil {
panic(err)
}
defer f.Close()
var b types.RetrievePropertiesResponse
dec := xml.NewDecoder(f)
dec.TypeFunc = types.TypeFunc()
if err := dec.Decode(&b); err != nil {
panic(err)
}
return &b
}
func TestNotAuthenticatedFault(t *testing.T) {
var s SessionManager
err := LoadRetrievePropertiesResponse(load("fixtures/not_authenticated_fault.xml"), &s)
if !soap.IsVimFault(err) {
t.Errorf("Expected IsVimFault")
}
fault := soap.ToVimFault(err).(*types.NotAuthenticated)
if fault.PrivilegeId != "System.View" {
t.Errorf("Expected first fault to be returned")
}
}
func TestNestedProperty(t *testing.T) {
var vm VirtualMachine
err := LoadRetrievePropertiesResponse(load("fixtures/nested_property.xml"), &vm)
if err != nil {
t.Fatalf("Expected no error, got: %s", err)
}
self := types.ManagedObjectReference{
Type: "VirtualMachine",
Value: "vm-411",
}
if vm.Self != self {
t.Fatalf("Expected vm.Self to be set")
}
if vm.Config == nil {
t.Fatalf("Expected vm.Config to be set")
}
if vm.Config.Name != "kubernetes-master" {
t.Errorf("Got: %s", vm.Config.Name)
}
if vm.Config.Uuid != "422ec880-ab06-06b4-23f3-beb7a052a4c9" {
t.Errorf("Got: %s", vm.Config.Uuid)
}
}
func TestPointerProperty(t *testing.T) {
var vm VirtualMachine
err := LoadRetrievePropertiesResponse(load("fixtures/pointer_property.xml"), &vm)
if err != nil {
t.Fatalf("Expected no error, got: %s", err)
}
if vm.Config == nil {
t.Fatalf("Expected vm.Config to be set")
}
if vm.Config.BootOptions == nil {
t.Fatalf("Expected vm.Config.BootOptions to be set")
}
}
func TestEmbeddedTypeProperty(t *testing.T) {
// Test that we avoid in this case:
// panic: reflect.Set: value of type mo.ClusterComputeResource is not assignable to type mo.ComputeResource
var cr ComputeResource
err := LoadRetrievePropertiesResponse(load("fixtures/cluster_host_property.xml"), &cr)
if err != nil {
t.Fatalf("Expected no error, got: %s", err)
}
if len(cr.Host) != 4 {
t.Fatalf("Expected cr.Host to be set")
}
}
func TestEmbeddedTypePropertySlice(t *testing.T) {
var me []ManagedEntity
err := LoadRetrievePropertiesResponse(load("fixtures/hostsystem_list_name_property.xml"), &me)
if err != nil {
t.Fatalf("Expected no error, got: %s", err)
}
if len(me) != 2 {
t.Fatalf("Expected 2 elements")
}
for _, m := range me {
if m.Name == "" {
t.Fatal("Expected Name field to be set")
}
}
if me[0].Name == me[1].Name {
t.Fatal("Name fields should not be the same")
}
}

247
vendor/github.com/vmware/govmomi/vim25/mo/type_info.go generated vendored Normal file
View File

@@ -0,0 +1,247 @@
/*
Copyright (c) 2014 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 mo
import (
"fmt"
"reflect"
"regexp"
"strings"
"sync"
"github.com/vmware/govmomi/vim25/types"
)
type typeInfo struct {
typ reflect.Type
// Field indices of "Self" field.
self []int
// Map property names to field indices.
props map[string][]int
}
var typeInfoLock sync.RWMutex
var typeInfoMap = make(map[string]*typeInfo)
func typeInfoForType(tname string) *typeInfo {
typeInfoLock.RLock()
ti, ok := typeInfoMap[tname]
typeInfoLock.RUnlock()
if ok {
return ti
}
// Create new typeInfo for type.
if typ, ok := t[tname]; !ok {
panic("unknown type: " + tname)
} else {
// Multiple routines may race to set it, but the result is the same.
typeInfoLock.Lock()
ti = newTypeInfo(typ)
typeInfoMap[tname] = ti
typeInfoLock.Unlock()
}
return ti
}
func newTypeInfo(typ reflect.Type) *typeInfo {
t := typeInfo{
typ: typ,
props: make(map[string][]int),
}
t.build(typ, "", []int{})
return &t
}
var managedObjectRefType = reflect.TypeOf((*types.ManagedObjectReference)(nil)).Elem()
func buildName(fn string, f reflect.StructField) string {
if fn != "" {
fn += "."
}
motag := f.Tag.Get("mo")
if motag != "" {
return fn + motag
}
xmltag := f.Tag.Get("xml")
if xmltag != "" {
tokens := strings.Split(xmltag, ",")
if tokens[0] != "" {
return fn + tokens[0]
}
}
return ""
}
func (t *typeInfo) build(typ reflect.Type, fn string, fi []int) {
if typ.Kind() == reflect.Ptr {
typ = typ.Elem()
}
if typ.Kind() != reflect.Struct {
panic("need struct")
}
for i := 0; i < typ.NumField(); i++ {
f := typ.Field(i)
ftyp := f.Type
// Copy field indices so they can be passed along.
fic := make([]int, len(fi)+1)
copy(fic, fi)
fic[len(fi)] = i
// Recurse into embedded field.
if f.Anonymous {
t.build(ftyp, fn, fic)
continue
}
// Top level type has a "Self" field.
if f.Name == "Self" && ftyp == managedObjectRefType {
t.self = fic
continue
}
fnc := buildName(fn, f)
if fnc == "" {
continue
}
t.props[fnc] = fic
// Dereference pointer.
if ftyp.Kind() == reflect.Ptr {
ftyp = ftyp.Elem()
}
// Slices are not addressable by `foo.bar.qux`.
if ftyp.Kind() == reflect.Slice {
continue
}
// Skip the managed reference type.
if ftyp == managedObjectRefType {
continue
}
// Recurse into structs.
if ftyp.Kind() == reflect.Struct {
t.build(ftyp, fnc, fic)
}
}
}
// assignValue assignes a value 'pv' to the struct pointed to by 'val', given a
// slice of field indices. It recurses into the struct until it finds the field
// specified by the indices. It creates new values for pointer types where
// needed.
func assignValue(val reflect.Value, fi []int, pv reflect.Value) {
// Create new value if necessary.
if val.Kind() == reflect.Ptr {
if val.IsNil() {
val.Set(reflect.New(val.Type().Elem()))
}
val = val.Elem()
}
rv := val.Field(fi[0])
fi = fi[1:]
if len(fi) == 0 {
rt := rv.Type()
pt := pv.Type()
// If type is a pointer, create new instance of type.
if rt.Kind() == reflect.Ptr {
rv.Set(reflect.New(rt.Elem()))
rv = rv.Elem()
rt = rv.Type()
}
// If type is an interface, check if pv implements it.
if rt.Kind() == reflect.Interface && !pt.Implements(rt) {
// Check if pointer to pv implements it.
if reflect.PtrTo(pt).Implements(rt) {
npv := reflect.New(pt)
npv.Elem().Set(pv)
pv = npv
pt = pv.Type()
} else {
panic(fmt.Sprintf("type %s doesn't implement %s", pt.Name(), rt.Name()))
}
}
if pt.AssignableTo(rt) {
rv.Set(pv)
} else if rt.ConvertibleTo(pt) {
rv.Set(pv.Convert(rt))
} else {
panic(fmt.Sprintf("cannot assign %s (%s) to %s (%s)", rt.Name(), rt.Kind(), pt.Name(), pt.Kind()))
}
return
}
assignValue(rv, fi, pv)
}
var arrayOfRegexp = regexp.MustCompile("ArrayOf(.*)$")
func anyTypeToValue(t interface{}) reflect.Value {
rt := reflect.TypeOf(t)
rv := reflect.ValueOf(t)
// Dereference if ArrayOfXYZ type
m := arrayOfRegexp.FindStringSubmatch(rt.Name())
if len(m) > 0 {
// ArrayOfXYZ type has single field named XYZ
rv = rv.FieldByName(m[1])
if !rv.IsValid() {
panic(fmt.Sprintf("expected %s type to have field %s", m[0], m[1]))
}
}
return rv
}
// LoadObjectFromContent loads properties from the 'PropSet' field in the
// specified ObjectContent value into the value it represents, which is
// returned as a reflect.Value.
func (t *typeInfo) LoadFromObjectContent(o types.ObjectContent) (reflect.Value, error) {
v := reflect.New(t.typ)
assignValue(v, t.self, reflect.ValueOf(o.Obj))
for _, p := range o.PropSet {
rv, ok := t.props[p.Name]
if !ok {
continue
}
assignValue(v, rv, anyTypeToValue(p.Val))
}
return v, nil
}

View File

@@ -0,0 +1,37 @@
/*
Copyright (c) 2014 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 mo
import (
"reflect"
"testing"
)
func TestLoadAll(*testing.T) {
for _, typ := range t {
newTypeInfo(typ)
}
}
// The virtual machine managed object has about 500 nested properties.
// It's likely to be indicative of the function's performance in general.
func BenchmarkLoadVirtualMachine(b *testing.B) {
vmtyp := reflect.TypeOf((*VirtualMachine)(nil)).Elem()
for i := 0; i < b.N; i++ {
newTypeInfo(vmtyp)
}
}