goreflectionvmwaregovmomi

Reflect showing different a different type than error


Background: Im using govmomi for configuration collection for vmware. I'm currently in the process of getting the datastore info I require. One of the fields I need is the disk Naa. This can be found in the VmfsDatastoreInfo struct under the Vmfs field.

Issue: I am looping through a range and I believed Ds.Info to be of the VmfsDatastoreInfo type so in theory I could get the info I needed by going through Ds.Info.Vmfs. When I reference this I get the error:

ds.Info.Vmfs undefined (type types.BaseDatastoreInfo has no field or method Vmfs)

Out of curiosity I explored using reflection and did the following:

fmt.Println(reflect.TypeOf(ds.Info))

output was

*types.VmfsDatastoreInfo

Im trying to understand why the same object is showing as two different types?

Edit: Getting to ds :

c, err := govmomi.NewClient(ctx, u, true)

//Check if the connection was successful
if err != nil {
    fmt.Println(err)
}

// Create view of Datastore objects
m := view.NewManager(c.Client)

d, _ := m.CreateContainerView(ctx, c.ServiceContent.RootFolder, []string{"Datastore"}, true)



if err != nil {
    log.Fatal(err)
}

defer d.Destroy(ctx)

//Retrieve a list of all Virtual Machines including their summary and runtime
var dss []mo.Datastore
err = d.Retrieve(ctx, []string{"Datastore"}, []string{"info", "host"}, &dss)
if err != nil {
    log.Fatal(err)
}


for _, ds := range dss {
    fmt.Println(reflect.TypeOf(ds.Info))
    s := reflect.ValueOf(ds.Info).Elem()

    typeOfT := s.Type()

    for i := 0; i < s.NumField(); i++ {

    f := s.Field(i)

    fmt.Println(i, typeOfT.Field(i).Name, f.Type(), f.Interface())

    }

}

ds is a Datastore type :

type Datastore struct {
    ManagedEntity

    Info              types.BaseDatastoreInfo        `mo:"info"`
    Summary           types.DatastoreSummary         `mo:"summary"`
    Host              []types.DatastoreHostMount     `mo:"host"`
    Vm                []types.ManagedObjectReference `mo:"vm"`
    Browser           types.ManagedObjectReference   `mo:"browser"`
    Capability        types.DatastoreCapability      `mo:"capability"`
    IormConfiguration *types.StorageIORMInfo         `mo:"iormConfiguration"`
}

Following through the Govmomi package info I found the following

type BaseDatastoreInfo interface {
    GetDatastoreInfo() *DatastoreInfo
}

func (b *DatastoreInfo) GetDatastoreInfo() *DatastoreInfo

type DatastoreInfo struct {
    DynamicData

    Name                   string     `xml:"name"`
    Url                    string     `xml:"url"`
    FreeSpace              int64      `xml:"freeSpace"`
    MaxFileSize            int64      `xml:"maxFileSize"`
    MaxVirtualDiskCapacity int64      `xml:"maxVirtualDiskCapacity,omitempty"`
    MaxMemoryFileSize      int64      `xml:"maxMemoryFileSize,omitempty"`
    Timestamp              *time.Time `xml:"timestamp"`
    ContainerId            string     `xml:"containerId,omitempty"`
}

Govmomi Struct Info


Solution

  • Im trying to understand why the same object is showing as two different types?

    It is not.

    I believed Ds.Info to be of the VmfsDatastoreInfo type

    No. if ds is a Datastore than ds.Info is of type BaseDatastoreInfo which is a interface and as such has only one method GetDatastoreInfo(). That's why you see the error

    ds.Info.Vmfs undefined (type types.BaseDatastoreInfo has no field or method Vmfs)
    

    Now read the whole package documentation of package reflect and the documentation of reflect.TypoOf. Now read https://blog.golang.org/laws-of-reflection.

    Your reflect.TypeOf(ds.Info) resolves the dynamic type of ds.Info (its static type is BaseDatastoreInfo). For a simple example see https://play.golang.org/p/kgDYXv4i63T. reflect.TypeOf looks inside of its argument (which is interface {}); if it would not but report always the static type, reflect.TypeOf would always report interface{}).

    Probably you just should use the interface without reflection:

    ds.Info.GetDatastoreInfo()
    

    and use that information. No need to reflect here.