Skip to content

Commit

Permalink
✨ Add distributed virtual switches and portgroups
Browse files Browse the repository at this point in the history
This adds these to the vShere datacenter

Signed-off-by: Christian Zunker <[email protected]>
  • Loading branch information
czunker committed Nov 13, 2024
1 parent 8e42171 commit 960c6b4
Show file tree
Hide file tree
Showing 11 changed files with 441 additions and 8 deletions.
1 change: 1 addition & 0 deletions .github/actions/spelling/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,4 @@ vulnerabilityassessmentsettings
vulnmgmt
wil
xssmatchstatement
portgroup
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ require (
github.com/spdx/tools-golang v0.5.5
github.com/spf13/afero v1.11.0
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
github.com/spf13/pflag v1.0.6-0.20201009195203-85dd5c8bc61c
github.com/spf13/viper v1.19.0
github.com/stretchr/testify v1.9.0
github.com/toravir/csd v0.0.0-20200911003203-13ae77ad849c
Expand Down
3 changes: 2 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -862,8 +862,9 @@ github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.6-0.20201009195203-85dd5c8bc61c h1:zqmyTlQyufRC65JnImJ6H1Sf7BDj8bG31EV919NVEQc=
github.com/spf13/pflag v1.0.6-0.20201009195203-85dd5c8bc61c/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM=
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
Expand Down
2 changes: 1 addition & 1 deletion providers/mondoo/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ require (
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/skeema/knownhosts v1.3.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/pflag v1.0.6-0.20201009195203-85dd5c8bc61c // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
go.mondoo.com/ranger-rpc v0.6.4 // indirect
go.opencensus.io v0.24.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions providers/mondoo/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,8 @@ github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sS
github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60=
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.6-0.20201009195203-85dd5c8bc61c h1:zqmyTlQyufRC65JnImJ6H1Sf7BDj8bG31EV919NVEQc=
github.com/spf13/pflag v1.0.6-0.20201009195203-85dd5c8bc61c/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
Expand Down
90 changes: 90 additions & 0 deletions providers/vsphere/resources/datacenter.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package resources

import (
"context"
"fmt"

"github.com/vmware/govmomi/object"
Expand Down Expand Up @@ -178,3 +179,92 @@ func (v *mqlVsphereDatacenter) vms() ([]interface{}, error) {

return mqlVms, nil
}

func (v *mqlVsphereDatacenter) distributedSwitches() ([]interface{}, error) {
conn := v.MqlRuntime.Connection.(*connection.VsphereConnection)
client := getClientInstance(conn)

if v.InventoryPath.Error != nil {
return nil, v.InventoryPath.Error
}
path := v.InventoryPath.Data
if path == "" {
path = "/"
}

vswitches, err := client.GetDistributedVirtualSwitches(context.Background(), path)
if err != nil {
return nil, err
}

mqlVswitches := make([]interface{}, len(vswitches))
for i, s := range vswitches {

config, err := client.GetDistributedVirtualSwitchConfig(context.Background(), s)
if err != nil {
return nil, err
}
configMap, err := resourceclient.DistributedVirtualSwitchConfig(config)
if err != nil {
return nil, err
}

mqlVswitch, err := CreateResource(v.MqlRuntime, "vsphere.vswitch.dvs", map[string]*llx.RawData{
"moid": llx.StringData(s.Reference().Encode()),
"name": llx.StringData(s.Name()),
"properties": llx.DictData(configMap),
})
if err != nil {
return nil, err
}

// store host inventory path, so that sub resources can use that to quickly query more
r := mqlVswitch.(*mqlVsphereVswitchDvs)
r.hostInventoryPath = s.InventoryPath

mqlVswitches[i] = mqlVswitch
}

return mqlVswitches, nil
}

func (v *mqlVsphereDatacenter) distributedPortGroups() ([]interface{}, error) {
if v.InventoryPath.Error != nil {
return nil, v.InventoryPath.Error
}
path := v.InventoryPath.Data
conn := v.MqlRuntime.Connection.(*connection.VsphereConnection)
client := resourceclient.New(conn.Client())

distPGs, err := client.GetDistributedVirtualPortgroups(context.Background(), path)
if err != nil {
return nil, err
}

mqlPGs := make([]interface{}, len(distPGs))
for i, distPG := range distPGs {
config, err := client.GetDistributedVirtualPortgroupConfig(context.Background(), distPG)
if err != nil {
return nil, err
}

configMap, err := resourceclient.DistributedVirtualPortgroupConfig(config)
if err != nil {
return nil, err
}

name := distPG.Name()
mqlDistPG, err := NewResource(v.MqlRuntime, "vsphere.vswitch.portgroup", map[string]*llx.RawData{
"moid": llx.StringData(distPG.Reference().Encode()),
"name": llx.StringData(name),
"properties": llx.DictData(configMap),
})
if err != nil {
return nil, err
}

mqlPGs[i] = mqlDistPG.(*mqlVsphereVswitchPortgroup)
}

return mqlPGs, nil
}
14 changes: 11 additions & 3 deletions providers/vsphere/resources/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,14 @@ func (v *mqlVsphereVswitchDvs) uplinks() ([]interface{}, error) {
return nil, nil
}

uplinksRaw := properties["Uplinks"]
uplinksRaw, ok := properties["Uplinks"]
if !ok {
// no uplinks for dvs
return nil, nil
}

// no uplinks for dvs
if properties == nil {
// empty uplinks for dvs
if uplinksRaw == nil {
return nil, nil
}

Expand All @@ -177,3 +181,7 @@ func (v *mqlVsphereVswitchDvs) uplinks() ([]interface{}, error) {
// get all host adapter
return findHostAdapter(v.parentResource, uplinkNames)
}

func (v *mqlVsphereVswitchPortgroup) id() (string, error) {
return v.Name.Data, v.Name.Error
}
137 changes: 137 additions & 0 deletions providers/vsphere/resources/resourceclient/network.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// Copyright (c) Mondoo, Inc.
// SPDX-License-Identifier: BUSL-1.1

package resourceclient

import (
"context"
"errors"
"strings"

"github.com/rs/zerolog/log"
"github.com/vmware/govmomi/find"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/vim25/mo"
)

func (c *Client) GetDistributedVirtualSwitches(ctx context.Context, path string) ([]*object.DistributedVirtualSwitch, error) {
finder := find.NewFinder(c.Client.Client, true)
mos, err := finder.ManagedObjectListChildren(ctx, path)
if err != nil {
return nil, err
}
if len(mos) == 0 {
return nil, nil
}

var dvSwitches []*object.DistributedVirtualSwitch
for _, item := range mos {
if !strings.HasSuffix(item.Path, "/network") {
continue
}
log.Debug().Str("object", item.String()).Msg("???")
ref := item.Object.Reference()
log.Debug().Str("ref", ref.Type).Msg("???")
networkMos, err := finder.ManagedObjectListChildren(ctx, item.Path)
if err != nil {
return nil, err
}
for _, networkMo := range networkMos {
log.Debug().Str("networkMo", networkMo.String()).Msg("???")
if networkMo.Object.Reference().Type == "DistributedVirtualSwitch" || networkMo.Object.Reference().Type == "VmwareDistributedVirtualSwitch" {
dvpg, err := finder.Network(ctx, networkMo.Path)
if err != nil {
return nil, err
}
casted, ok := dvpg.(*object.DistributedVirtualSwitch)
if !ok {
return nil, errors.New("not a DistributedVirtualSwitch reference")
}
dvSwitches = append(dvSwitches, casted)
}
}
}

return dvSwitches, nil
}

func (c *Client) GetDistributedVirtualSwitchConfig(ctx context.Context, obj *object.DistributedVirtualSwitch) (*mo.DistributedVirtualSwitch, error) {
var moDvSwitch mo.DistributedVirtualSwitch
err := obj.Properties(ctx, obj.Reference(), nil, &moDvSwitch)
if err != nil {
return nil, err
}

return &moDvSwitch, nil
}

func DistributedVirtualSwitchConfig(dvSwitch *mo.DistributedVirtualSwitch) (map[string]interface{}, error) {
return PropertiesToDict(dvSwitch)
}

func (c *Client) GetDistributedVirtualPortgroups(ctx context.Context, path string) ([]*object.DistributedVirtualPortgroup, error) {
finder := find.NewFinder(c.Client.Client, true)
pathParts := strings.Split(path, "/")
if len(pathParts) < 2 {
return nil, nil
}
dcPath := "/" + pathParts[1]
dc, err := c.Datacenter(dcPath)
if err != nil {
return nil, err
}
finder.SetDatacenter(dc)

mos, err := finder.ManagedObjectListChildren(ctx, dcPath)
if err != nil {
return nil, err
}
if len(mos) == 0 {
return nil, nil
}

var pgs []*object.DistributedVirtualPortgroup
for _, item := range mos {
if !strings.HasSuffix(item.Path, "/network") {
continue
}
log.Debug().Str("object", item.String()).Msg("???")
ref := item.Object.Reference()
log.Debug().Str("ref", ref.Type).Msg("???")
networkMos, err := finder.ManagedObjectListChildren(ctx, item.Path)
if err != nil {
return nil, err
}
for _, networkMo := range networkMos {
log.Debug().Str("networkMo", networkMo.String()).Msg("???")
if networkMo.Object.Reference().Type == "DistributedVirtualPortgroup" {
dvpg, err := finder.Network(ctx, networkMo.Path)
if err != nil {
return nil, err
}
casted, ok := dvpg.(*object.DistributedVirtualPortgroup)
if !ok {
return nil, errors.New("not a DistributedVirtualPortgroup reference")
}

pgs = append(pgs, casted)
}
}
}

return pgs, nil
}

func (c *Client) GetDistributedVirtualPortgroupConfig(ctx context.Context, obj *object.DistributedVirtualPortgroup) (*mo.DistributedVirtualPortgroup, error) {
var moDvpg mo.DistributedVirtualPortgroup
err := obj.Properties(ctx, obj.Reference(), nil, &moDvpg)
if err != nil {
return nil, err
}

return &moDvpg, nil
}

func DistributedVirtualPortgroupConfig(dvpg *mo.DistributedVirtualPortgroup) (map[string]interface{}, error) {
return PropertiesToDict(dvpg)
}
16 changes: 16 additions & 0 deletions providers/vsphere/resources/vsphere.lr
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ private vsphere.datacenter @defaults("moid name") {
vms() []vsphere.vm
// Clusters in the datacenter
clusters() []vsphere.cluster
// Distributed virtual switches
distributedSwitches() []vsphere.vswitch.dvs
// List of distributed virtual port groups
distributedPortGroups() []vsphere.vswitch.portgroup
}

// vSphere cluster resource
Expand Down Expand Up @@ -216,6 +220,8 @@ private vsphere.vswitch.standard @defaults("name") {

// vSphere distributed virtual switch
private vsphere.vswitch.dvs @defaults("name") {
// vSphere managed object ID
moid string
// Virtual switch name
name string
// Virtual switch properties
Expand All @@ -224,6 +230,16 @@ private vsphere.vswitch.dvs @defaults("name") {
uplinks() []vsphere.vmnic
}

// vSphere distributed virtual port group
private vsphere.vswitch.portgroup @defaults("name") {
// vSphere managed object ID
moid string
// Port group name
name string
// Port group properties
properties dict
}

// vSphere ESXi physical network interface resource
private vsphere.vmnic @defaults("name") {
// NIC name
Expand Down
Loading

0 comments on commit 960c6b4

Please sign in to comment.