Skip to content

Commit

Permalink
Add ovftool support
Browse files Browse the repository at this point in the history
  • Loading branch information
dougm committed Apr 7, 2019
1 parent 20c1873 commit 5611aaa
Show file tree
Hide file tree
Showing 18 changed files with 369 additions and 17 deletions.
3 changes: 3 additions & 0 deletions gen/vim_wsdl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,9 @@ def var_type
t = $1
case t
when "string"
if ["IpPoolName"].include?(var_name)
self.need_omitempty = false
end
when "int"
if pointer_type?
prefix += "*"
Expand Down
9 changes: 9 additions & 0 deletions govc/test/object.bats
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,15 @@ load test_helper
@test "object.collect vcsim" {
vcsim_env -app 1 -pool 1

# test that {Cluster}ComputeResource and HostSystem network fields have the expected refs
for obj in DC0_C0 DC0_C0/DC0_C0_H0 DC0_H0 DC0_H0/DC0_H0; do
run govc object.collect /DC0/host/$obj network
assert_success
echo "obj=$obj"
assert_matches "DistributedVirtualPortgroup:"
assert_matches "Network:"
done

run govc object.collect -s -type ClusterComputeResource / configStatus
assert_success green

Expand Down
16 changes: 16 additions & 0 deletions govc/test/vcsim.bats
Original file line number Diff line number Diff line change
Expand Up @@ -290,3 +290,19 @@ load test_helper
user=$(jq -r .value.user <<<"$output")
assert_equal "$USER" "$user"
}

@test "vcsim ovftool" {
if ! ovftool -h >/dev/null ; then
skip "requires ovftool"
fi

vcsim_env

url=$(govc env GOVC_URL)

run ovftool --noSSLVerify --acceptAllEulas -ds=LocalDS_0 --network=DC0_DVPG0 "$GOVC_IMAGES/$TTYLINUX_NAME.ova" "vi://user:pass@$url/DC0/host/DC0_C0/DC0_C0_H1"
assert_success

run govc vm.destroy "$TTYLINUX_NAME"
assert_success
}
2 changes: 1 addition & 1 deletion program.mk
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ $(PROGRAM):
CGO_ENABLED=0 go build -a $(BUILD_ARGS) -o $@

install:
CGO_ENABLED=0 go install $(BUILD_ARGS)
CGO_ENABLED=0 go install -i -v $(BUILD_ARGS)

ifneq (,$(strip $(BUILD_OS)))
ifneq (,$(strip $(BUILD_ARCH)))
Expand Down
2 changes: 2 additions & 0 deletions simulator/cluster_compute_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func (add *addHost) Run(task *Task) (types.AnyType, types.BaseMethodFault) {

cr.Host = append(cr.Host, host.Reference())
addComputeResource(cr.Summary.GetComputeResourceSummary(), host)
host.Network = cr.Network[:1] // VM Network

return host.Reference(), nil
}
Expand Down Expand Up @@ -306,6 +307,7 @@ func CreateClusterComputeResource(f *Folder, name string, spec types.ClusterConf
cluster := &ClusterComputeResource{}
cluster.EnvironmentBrowser = newEnvironmentBrowser()
cluster.Name = name
cluster.Network = Map.getEntityDatacenter(f).defaultNetwork()
cluster.Summary = &types.ClusterComputeResourceSummary{
UsageSummary: new(types.ClusterUsageSummary),
}
Expand Down
4 changes: 4 additions & 0 deletions simulator/datacenter.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ func (dc *Datacenter) createFolders() {
}
}

func (dc *Datacenter) defaultNetwork() []types.ManagedObjectReference {
return dc.Network[:1] // VM Network
}

func datacenterEventArgument(obj mo.Entity) *types.DatacenterEventArgument {
dc, ok := obj.(*Datacenter)
if !ok {
Expand Down
2 changes: 2 additions & 0 deletions simulator/datastore.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ func (ds *Datastore) RefreshDatastore(*types.RefreshDatastore) soap.HasFault {
now := time.Now()

info.Timestamp = &now
info.MaxMemoryFileSize = info.FreeSpace
info.MaxFileSize = info.FreeSpace

return r
}
29 changes: 26 additions & 3 deletions simulator/dvs.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,24 @@ func (s *DistributedVirtualSwitch) AddDVPortgroupTask(c *types.AddDVPortgroup_Ta
}
}

if pg.Config.Policy == nil {
pg.Config.Policy = &types.VMwareDVSPortgroupPolicy{
DVPortgroupPolicy: types.DVPortgroupPolicy{
BlockOverrideAllowed: true,
ShapingOverrideAllowed: false,
VendorConfigOverrideAllowed: false,
LivePortMovingAllowed: false,
PortConfigResetAtDisconnect: true,
NetworkResourcePoolOverrideAllowed: types.NewBool(false),
TrafficFilterOverrideAllowed: types.NewBool(false),
},
VlanOverrideAllowed: false,
UplinkTeamingOverrideAllowed: false,
SecurityPolicyOverrideAllowed: false,
IpfixOverrideAllowed: types.NewBool(false),
}
}

pg.PortKeys = []string{}

portgroups = append(portgroups, pg.Self)
Expand Down Expand Up @@ -142,11 +160,16 @@ func (s *DistributedVirtualSwitch) ReconfigureDvsTask(req *types.ReconfigureDvs_
Map.Update(pg, []types.PropertyChange{
{Name: "host", Val: pgHosts},
})

cr := hostParent(&host.HostSystem)
if FindReference(cr.Network, ref) == nil {
computeNetworks := append(cr.Network, ref)
Map.Update(parent, []types.PropertyChange{
{Name: "network", Val: computeNetworks},
})
}
}

Map.Update(parent, []types.PropertyChange{
{Name: "network", Val: pgs},
})
case types.ConfigSpecOperationRemove:
for _, ref := range host.Vm {
vm := Map.Get(ref).(*VirtualMachine)
Expand Down
119 changes: 119 additions & 0 deletions simulator/environment_browser.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,24 @@ func newEnvironmentBrowser() *types.ManagedObjectReference {
return &env.Self
}

func (b *EnvironmentBrowser) hosts(ctx *Context) []types.ManagedObjectReference {
ctx.Map.m.Lock()
defer ctx.Map.m.Unlock()
for _, obj := range ctx.Map.objects {
switch e := obj.(type) {
case *mo.ComputeResource:
if b.Self == *e.EnvironmentBrowser {
return e.Host
}
case *ClusterComputeResource:
if b.Self == *e.EnvironmentBrowser {
return e.Host
}
}
}
return nil
}

func (b *EnvironmentBrowser) QueryConfigOption(req *types.QueryConfigOption) soap.HasFault {
body := new(methods.QueryConfigOptionBody)

Expand Down Expand Up @@ -63,3 +81,104 @@ func (b *EnvironmentBrowser) QueryConfigOptionEx(req *types.QueryConfigOptionEx)

return body
}

func (b *EnvironmentBrowser) QueryConfigOptionDescriptor(ctx *Context, req *types.QueryConfigOptionDescriptor) soap.HasFault {
body := &methods.QueryConfigOptionDescriptorBody{
Res: new(types.QueryConfigOptionDescriptorResponse),
}

body.Res.Returnval = []types.VirtualMachineConfigOptionDescriptor{{
Key: esx.HardwareVersion,
Description: esx.HardwareVersion,
Host: b.hosts(ctx),
CreateSupported: types.NewBool(true),
DefaultConfigOption: types.NewBool(false),
RunSupported: types.NewBool(true),
UpgradeSupported: types.NewBool(true),
}}

return body
}

func (b *EnvironmentBrowser) QueryConfigTarget(ctx *Context, req *types.QueryConfigTarget) soap.HasFault {
body := &methods.QueryConfigTargetBody{
Res: &types.QueryConfigTargetResponse{
Returnval: &types.ConfigTarget{
SmcPresent: types.NewBool(false),
},
},
}
target := body.Res.Returnval

var hosts []types.ManagedObjectReference
if req.Host == nil {
hosts = b.hosts(ctx)
} else {
hosts = append(hosts, *req.Host)
}

seen := make(map[types.ManagedObjectReference]bool)

for i := range hosts {
host := ctx.Map.Get(hosts[i]).(*HostSystem)
target.NumCpus += int32(host.Summary.Hardware.NumCpuPkgs)
target.NumCpuCores += int32(host.Summary.Hardware.NumCpuCores)
target.NumNumaNodes++

for _, ref := range host.Datastore {
if seen[ref] {
continue
}
seen[ref] = true

ds := ctx.Map.Get(ref).(*Datastore)
target.Datastore = append(target.Datastore, types.VirtualMachineDatastoreInfo{
VirtualMachineTargetInfo: types.VirtualMachineTargetInfo{
Name: ds.Name,
},
Datastore: ds.Summary,
Capability: ds.Capability,
Mode: string(types.HostMountModeReadWrite),
VStorageSupport: string(types.FileSystemMountInfoVStorageSupportStatusVStorageUnsupported),
})
}

for _, ref := range host.Network {
if seen[ref] {
continue
}
seen[ref] = true

switch n := ctx.Map.Get(ref).(type) {
case *mo.Network:
target.Network = append(target.Network, types.VirtualMachineNetworkInfo{
VirtualMachineTargetInfo: types.VirtualMachineTargetInfo{
Name: n.Name,
},
Network: n.Summary.GetNetworkSummary(),
})
case *DistributedVirtualPortgroup:
dvs := ctx.Map.Get(*n.Config.DistributedVirtualSwitch).(*DistributedVirtualSwitch)
target.DistributedVirtualPortgroup = append(target.DistributedVirtualPortgroup, types.DistributedVirtualPortgroupInfo{
SwitchName: dvs.Name,
SwitchUuid: dvs.Uuid,
PortgroupName: n.Name,
PortgroupKey: n.Key,
PortgroupType: n.Config.Type,
UplinkPortgroup: false,
Portgroup: n.Self,
NetworkReservationSupported: types.NewBool(false),
})
case *DistributedVirtualSwitch:
target.DistributedVirtualSwitch = append(target.DistributedVirtualSwitch, types.DistributedVirtualSwitchInfo{
SwitchName: n.Name,
SwitchUuid: n.Uuid,
DistributedVirtualSwitch: n.Self,
NetworkReservationSupported: types.NewBool(false),
})
}
}
}

return body
}
9 changes: 9 additions & 0 deletions simulator/host_datastore_system.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,15 @@ func (dss *HostDatastoreSystem) add(ds *Datastore) *soap.Fault {
ds.Summary.Datastore = &ds.Self
ds.Summary.Name = ds.Name
ds.Summary.Url = info.Url
ds.Capability = types.DatastoreCapability{
DirectoryHierarchySupported: true,
RawDiskMappingsSupported: false,
PerFileThinProvisioningSupported: true,
StorageIORMSupported: types.NewBool(true),
NativeSnapshotSupported: types.NewBool(false),
TopLevelDirectoryCreateSupported: types.NewBool(true),
SeSparseSupported: types.NewBool(true),
}

dss.Datastore = append(dss.Datastore, ds.Self)
dss.Host.Datastore = dss.Datastore
Expand Down
8 changes: 7 additions & 1 deletion simulator/host_system.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,15 @@ func CreateDefaultESX(f *Folder) {
summary := new(types.ComputeResourceSummary)
addComputeResource(summary, host)

cr := &mo.ComputeResource{Summary: summary}
cr := &mo.ComputeResource{
Summary: summary,
Network: esx.Datacenter.Network,
}
cr.EnvironmentBrowser = newEnvironmentBrowser()
cr.Self = *host.Parent
cr.Name = host.Name
cr.Host = append(cr.Host, host.Reference())
host.Network = cr.Network
Map.PutEntity(cr, host)

pool := NewResourcePool()
Expand Down Expand Up @@ -187,11 +191,13 @@ func CreateStandaloneHost(f *Folder, spec types.HostConnectSpec) (*HostSystem, t
Map.PutEntity(cr, Map.NewEntity(pool))

cr.Name = host.Name
cr.Network = Map.getEntityDatacenter(f).defaultNetwork()
cr.Host = append(cr.Host, host.Reference())
cr.ResourcePool = &pool.Self

f.putChild(cr)
pool.Owner = cr.Self
host.Network = cr.Network

return host, nil
}
Expand Down
73 changes: 73 additions & 0 deletions simulator/internal/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
Copyright (c) 2019 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 internal

import (
"reflect"

"github.com/vmware/govmomi/vim25/soap"
"github.com/vmware/govmomi/vim25/types"
)

// Minimal set of internal types and methods:
// - Fetch() - used by ovftool to collect various managed object properties
// - RetrieveInternalContent() - used by ovftool to obtain a reference to NfcService (which it does not use by default)

func init() {
types.Add("Fetch", reflect.TypeOf((*Fetch)(nil)).Elem())
}

type Fetch struct {
This types.ManagedObjectReference `xml:"_this"`
Prop string `xml:"prop"`
}

type FetchResponse struct {
Returnval types.AnyType `xml:"returnval,omitempty,typeattr"`
}

type FetchBody struct {
Res *FetchResponse `xml:"FetchResponse,omitempty"`
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
}

func (b *FetchBody) Fault() *soap.Fault { return b.Fault_ }

func init() {
types.Add("RetrieveInternalContent", reflect.TypeOf((*RetrieveInternalContent)(nil)).Elem())
}

type RetrieveInternalContent struct {
This types.ManagedObjectReference `xml:"_this"`
}

type RetrieveInternalContentResponse struct {
Returnval InternalServiceInstanceContent `xml:"returnval"`
}

type RetrieveInternalContentBody struct {
Res *RetrieveInternalContentResponse `xml:"RetrieveInternalContentResponse,omitempty"`
Fault_ *soap.Fault `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"`
}

func (b *RetrieveInternalContentBody) Fault() *soap.Fault { return b.Fault_ }

type InternalServiceInstanceContent struct {
types.DynamicData

NfcService types.ManagedObjectReference `xml:"nfcService"`
}
3 changes: 1 addition & 2 deletions simulator/ovf_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ func ovfNetwork(ctx *Context, req *types.CreateImportSpec, item ovf.ResourceAllo
return nil
}
pool := ctx.Map.Get(req.ResourcePool).(*ResourcePool)
dc := ctx.Map.getEntityDatacenter(pool)
ref := dc.Network[0] // Default to VM Network
ref := ctx.Map.getEntityDatacenter(pool).defaultNetwork()[0] // Default to VM Network
c := item.Connection[0]

for _, net := range req.Cisp.NetworkMapping {
Expand Down
Loading

0 comments on commit 5611aaa

Please sign in to comment.