include vnic stats
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2023-09-29 14:09:39 +10:00
parent 6c7d447c56
commit 88c8109391
9 changed files with 346 additions and 132 deletions

View File

@@ -56,7 +56,7 @@ func main() {
log.Printf("Got authentication cookie: %s\n", ucsClient.Cookie)
// Register prometheus exporters
exporter := exporters.NewUcsmTemperatureCollector(ucsClient, ctx)
exporter := exporters.NewUcsmExporters(ucsClient, ctx)
prometheus.MustRegister(exporter)
// Start prometheus exporter
@@ -64,4 +64,6 @@ func main() {
// TODO - run this in a go routine to avoid blocking, as per cbs code
log.Fatal(http.ListenAndServe(*listenPort, nil))
// TODO - log off from UCS manager
}

1
go.mod
View File

@@ -5,6 +5,7 @@ go 1.21.0
require (
github.com/dnaeon/go-ucs v0.0.0-20180427075322-a04ea35bf5de
github.com/prometheus/client_golang v1.16.0
golang.org/x/sync v0.2.0
)
require (

4
go.sum
View File

@@ -4,8 +4,6 @@ github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dnaeon/go-ucs v0.0.0-20180427075322-a04ea35bf5de h1:TPQ2PEbeZy0m8Y/zO+IQx9pUDMqfanACLJqREaLroJU=
github.com/dnaeon/go-ucs v0.0.0-20180427075322-a04ea35bf5de/go.mod h1:CnATpmPv6+QWYn/4O/qrRmxhSvfsiTMB4mVBfsWwKs8=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
@@ -25,6 +23,8 @@ github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr
github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg=
github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=

View File

@@ -1,77 +0,0 @@
package exporters
import (
"context"
"encoding/xml"
"log"
"github.com/dnaeon/go-ucs/api"
"github.com/dnaeon/go-ucs/mo"
"github.com/prometheus/client_golang/prometheus"
)
type UcsmBladeCollector struct {
ucsClient *api.Client
ctx context.Context
}
/*
type ComputeMbTempStats struct {
XMLName xml.Name `xml:"computeMbTempStats"`
Dn string `xml:"dn,attr,omitempty"`
FmTempSenIo string `xml:"fmTempSenIo,attr,omitempty"`
FmTempSenRear string `xml:"fmTempSenRear,attr,omitempty"`
}
*/
func NewUcsmBladeCollector(client *api.Client, ctx context.Context) *UcsmTemperaturesCollector {
return &UcsmTemperaturesCollector{
ucsClient: client,
ctx: ctx,
}
}
// Describe prometheus describe
func (u *UcsmBladeCollector) Describe(ch chan<- *prometheus.Desc) {
log.Printf("Running Describe for UcsmTemperaturesCollector\n")
ch <- prometheus.NewDesc("ucsm_temperature_sensor",
"UCSM temperature sensor for motherboard/cpu/psu",
[]string{"server", "component", "description"}, nil,
)
ch <- prometheus.NewDesc("ucsm_temperature_sensor",
"UCSM temperature sensor for motherboard/cpu/psu",
[]string{"server", "component", "description"}, nil,
)
}
// Collect prometheus collect
func (u *UcsmBladeCollector) Collect(ch chan<- prometheus.Metric) {
// The type into which we unmarshal the result data
type blades struct {
XMLName xml.Name
Blades []mo.ComputeBlade `xml:"computeBlade"`
}
bladeRequest := api.ConfigResolveClassRequest{
Cookie: u.ucsClient.Cookie,
ClassId: "computeBlade",
InHierarchical: "false",
}
var bladeList blades
log.Println("Retrieving managed objects with class `computeBlade`")
if err := u.ucsClient.ConfigResolveClass(u.ctx, bladeRequest, &bladeList); err != nil {
log.Fatalf("Unable to retrieve `computeBlade` managed object: %s", err)
}
log.Printf("Retrieved %d compute blades\n", len(bladeList.Blades))
for _, blade := range bladeList.Blades {
log.Printf("%s:\n", blade.Dn)
log.Printf("\tNumber of CPUs: %d\n", blade.NumOfCpus)
log.Printf("\tTotal Memory: %d\n", blade.TotalMemory)
log.Printf("\tModel: %s\n", blade.Model)
log.Printf("\tVendor: %s\n", blade.Vendor)
}
}

View File

@@ -0,0 +1,123 @@
package exporters
import (
"context"
"encoding/xml"
"log"
"strings"
"github.com/dnaeon/go-ucs/api"
"github.com/dnaeon/go-ucs/mo"
)
// Define the fields we will send back to the collector
type UcsmVnicPortStats struct {
Server string
Component string
Metrics map[string]uint64
}
func (u *UcsExporters) GetUcsmPortStats(ctx context.Context, ucsmPortStatsChannel chan []UcsmVnicPortStats) {
portStatsResults := make([]UcsmVnicPortStats, 0)
// The type into which we unmarshal the result data
type vnicStats struct {
XMLName xml.Name
VnicStats []mo.AdaptorVnicStats `xml:"adaptorVnicStats"`
}
// Define the request we are making to UCS Manager
vnicStatsRequest := api.ConfigResolveClassRequest{
Cookie: u.ucsClient.Cookie,
ClassId: "adaptorVnicStats",
InHierarchical: "false",
}
var vnicStatsObject vnicStats
log.Println("Retrieving managed objects with class `adaptorVnicStats`")
if err := u.ucsClient.ConfigResolveClass(u.ctx, vnicStatsRequest, &vnicStatsObject); err != nil {
log.Fatalf("Unable to retrieve `computeMbTempStats` managed object: %s", err)
}
log.Printf("Retrieved port stats for %d vnics\n", len(vnicStatsObject.VnicStats))
for _, vnic := range vnicStatsObject.VnicStats {
var bladeDn string
// Extract the bladeDn
startIndex := strings.Index(vnic.Dn, "/adaptor-")
if startIndex != -1 {
bladeDn = vnic.Dn[:startIndex]
} else {
bladeDn = vnic.Dn
}
log.Printf("Network stats for blade %s and component %s:\n", bladeDn, vnic.Dn)
log.Printf("Bytes Rx: %d, Bytes Tx: %d\n", vnic.BytesRx, vnic.BytesTx)
log.Printf("Packets Rx: %d, Packets Tx: %d\n", vnic.PacketsRx, vnic.PacketsTx)
log.Printf("Dropped Rx: %d, Dropped Tx: %d\n", vnic.DroppedRx, vnic.DroppedTx)
log.Printf("Error Rx: %d, Error Tx: %d\n", vnic.ErrorsRx, vnic.ErrorsTx)
// Create a map of all the values we care about
portMetrics := make(map[string]uint64)
portMetrics["ucsm_vnic_rx_total_packets"] = vnic.PacketsRx
portMetrics["ucsm_vnic_tx_total_packets"] = vnic.PacketsTx
portMetrics["ucsm_vnic_rx_total_bytes"] = vnic.BytesRx
portMetrics["ucsm_vnic_tx_total_bytes"] = vnic.BytesTx
portMetrics["ucsm_vnic_rx_dropped"] = vnic.DroppedRx
portMetrics["ucsm_vnic_tx_dropped"] = vnic.DroppedTx
portMetrics["ucsm_vnic_rx_error"] = vnic.ErrorsRx
portMetrics["ucsm_vnic_tx_error"] = vnic.ErrorsTx
// Add the metrics along with the other properties to the results
vnicPortStats := UcsmVnicPortStats{
Server: bladeDn,
Component: vnic.Dn,
Metrics: portMetrics,
}
portStatsResults = append(portStatsResults, vnicPortStats)
/*
// Substring the Dn for the temperatures to get the Dn for the parent blade itself
bladeDn := strings.Replace(temps.Dn, "/board/temp-stats", "", -1)
log.Printf("Temps for blade %s:\n", bladeDn)
log.Printf("Front Temperature: %v\n", temps.FmTempSenIo)
log.Printf("Rear Temperature: %v\n", temps.FmTempSenRear)
boardTempFront := UcsmPortStats{
Server: bladeDn,
Component: temps.Dn,
Description: "motherboard_front_temperature",
Value: temps.FmTempSenIo,
}
boardTempRear := UcsmPortStats{
Server: bladeDn,
Component: temps.Dn,
Description: "motherboard_rear_temperature",
Value: temps.FmTempSenRear,
}
portStatsResults = append(portStatsResults, boardTempFront)
portStatsResults = append(portStatsResults, boardTempRear)
*/
/*
// TODO - work out a better way of running this twice, once for each temperature sensor
metric1 := prometheus.MustNewConstMetric(u.UcsmTemperatures, prometheus.GaugeValue, temps.FmTempSenIo, bladeDn, temps.Dn, "motherboard_rear_temperature")
// send the data
ch <- metric1
// generate the metric
metric2 := prometheus.MustNewConstMetric(u.UcsmTemperatures, prometheus.GaugeValue, temps.FmTempSenRear, bladeDn, temps.Dn, "motherboard_front_temperature")
// send the data
ch <- metric2
*/
}
log.Printf("GetUcsmPortStats sending results to channel\n")
ucsmPortStatsChannel <- portStatsResults
}

View File

@@ -8,9 +8,17 @@ import (
"github.com/dnaeon/go-ucs/api"
"github.com/dnaeon/go-ucs/mo"
"github.com/prometheus/client_golang/prometheus"
)
// Define the fields we will send back to the collector
type UcsmTemperatures struct {
Server string
Component string
Description string
Value float64
}
/*
type UcsmTemperaturesCollector struct {
ucsClient *api.Client
ctx context.Context
@@ -18,6 +26,7 @@ type UcsmTemperaturesCollector struct {
}
var metrics []prometheus.Desc
*/
//var ucsClient *api.Client
//var ctx context.Context
@@ -30,64 +39,44 @@ var metrics []prometheus.Desc
FmTempSenRear string `xml:"fmTempSenRear,attr,omitempty"`
}
*/
func NewUcsmTemperatureCollector(client *api.Client, ctx context.Context) *UcsmTemperaturesCollector {
/*
func NewUcsmTemperatureCollector(client *api.Client, ctx context.Context) *UcsExporters {
/*
ucsClient = client
ctx = ctx
*/
/*
return &main.Collector{
UcsmTemperature: prometheus.NewDesc("ucsm_temperature_sensor",
"UCSM temperature sensor for motherboard/cpu/psu",
[]string{"server", "component", "description"}, nil,
),
}
*/
return &UcsmTemperaturesCollector{
return &UcsExporters{
ucsClient: client,
ctx: ctx,
metrics: []*prometheus.Desc{
prometheus.NewDesc(
"ucsm_temperature_sensor",
UcsmTemperatures: prometheus.NewDesc("ucsm_temperature_sensor",
"UCSM temperature sensor for motherboard/cpu/psu",
[]string{"server", "component", "description"}, nil,
),
},
}
}
// Describe prometheus describe
func (u *UcsmTemperaturesCollector) Describe(ch chan<- *prometheus.Desc) {
func (u *UcsExporters) Describe(ch chan<- *prometheus.Desc) {
log.Printf("Running Describe for UcsmTemperaturesCollector\n")
// Describe the metrics and send them on the channel
for _, desc := range u.metrics {
ch <- desc
}
/*
metricDesc := prometheus.NewDesc("ucsm_temperature_sensor",
"UCSM temperature sensor for motherboard/cpu/psu",
[]string{"server", "component", "description"}, nil)
fmt.Printf("metricDesc: %v\n", *metricDesc)
metrics = append(metrics, *metricDesc)
ch <- metricDesc
*/
ch <- u.UcsmTemperatures
}
*/
// Collect prometheus collect
func (u *UcsmTemperaturesCollector) Collect(ch chan<- prometheus.Metric) {
func (u *UcsExporters) GetUcsmTemperatures(ctx context.Context, ucsmTempsChannel chan []UcsmTemperatures) {
/*
wg.Add(1)
defer wg.Done()
defer close(ucsmTempsChannel)
*/
temperatureResults := make([]UcsmTemperatures, 0)
// The type into which we unmarshal the result data
type temps struct {
XMLName xml.Name
Temperatures []mo.ComputeMbTempStats `xml:"computeMbTempStats"`
}
// Define the request we are making to UCS Manager
tempRequest := api.ConfigResolveClassRequest{
Cookie: u.ucsClient.Cookie,
ClassId: "computeMbTempStats",
@@ -96,6 +85,7 @@ func (u *UcsmTemperaturesCollector) Collect(ch chan<- prometheus.Metric) {
var boardTempList temps
//cswg := new(sync.WaitGroup)
log.Println("Retrieving managed objects with class `computeMbTempStats`")
if err := u.ucsClient.ConfigResolveClass(u.ctx, tempRequest, &boardTempList); err != nil {
@@ -111,28 +101,41 @@ func (u *UcsmTemperaturesCollector) Collect(ch chan<- prometheus.Metric) {
log.Printf("Front Temperature: %v\n", temps.FmTempSenIo)
log.Printf("Rear Temperature: %v\n", temps.FmTempSenRear)
boardTempFront := UcsmTemperatures{
Server: bladeDn,
Component: temps.Dn,
Description: "motherboard_front_temperature",
Value: temps.FmTempSenIo,
}
boardTempRear := UcsmTemperatures{
Server: bladeDn,
Component: temps.Dn,
Description: "motherboard_rear_temperature",
Value: temps.FmTempSenRear,
}
temperatureResults = append(temperatureResults, boardTempFront)
temperatureResults = append(temperatureResults, boardTempRear)
/*
// TODO - work out a better way of running this twice, once for each temperature sensor
// Collect the actual metric values and send them on the channel
for _, desc := range u.metrics {
// populate the labels array
//labelValues := []string{bladeDn, temps.Dn, "motherboard_rear_temperature"}
// generate the metric
metric1 := prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, temps.FmTempSenIo, bladeDn, temps.Dn, "motherboard_rear_temperature")
metric1 := prometheus.MustNewConstMetric(u.UcsmTemperatures, prometheus.GaugeValue, temps.FmTempSenIo, bladeDn, temps.Dn, "motherboard_rear_temperature")
// send the data
ch <- metric1
// generate the metric
metric2 := prometheus.MustNewConstMetric(desc, prometheus.GaugeValue, temps.FmTempSenRear, bladeDn, temps.Dn, "motherboard_front_temperature")
metric2 := prometheus.MustNewConstMetric(u.UcsmTemperatures, prometheus.GaugeValue, temps.FmTempSenRear, bladeDn, temps.Dn, "motherboard_front_temperature")
// send the data
ch <- metric2
*/
}
//cswg.Wait()
//ch <- prometheus.MustNewConstMetric()
}
log.Printf("GetUcsmTemperatures sending results to channel\n")
ucsmTempsChannel <- temperatureResults
//return
}
/*

View File

@@ -0,0 +1,141 @@
package exporters
import (
"context"
"log"
"github.com/dnaeon/go-ucs/api"
"github.com/prometheus/client_golang/prometheus"
"golang.org/x/sync/errgroup"
)
type UcsExporters struct {
// Define each type of metric here
UcsmTemperatures *prometheus.Desc
UcsmVnicStatsRxTotalPkts *prometheus.Desc
UcsmVnicStatsTxTotalPkts *prometheus.Desc
UcsmVnicStatsRxTotalBytes *prometheus.Desc
UcsmVnicStatsTxTotalBytes *prometheus.Desc
UcsmVnicStatsRxDropped *prometheus.Desc
UcsmVnicStatsTxDropped *prometheus.Desc
UcsmVnicStatsRxError *prometheus.Desc
UcsmVnicStatsTxError *prometheus.Desc
// Additional properties required
ucsClient *api.Client
ctx context.Context
}
func NewUcsmExporters(client *api.Client, ctx context.Context) *UcsExporters {
return &UcsExporters{
ucsClient: client,
ctx: ctx,
// UCS Temperatures
UcsmTemperatures: prometheus.NewDesc("ucsm_temperature_sensor",
"UCSM temperature sensor for motherboard/cpu/psu",
[]string{"server", "component", "description"}, nil,
),
// UCS Network statistics
UcsmVnicStatsRxTotalPkts: prometheus.NewDesc("ucsm_vnic_rx_total_packets",
"UCSM Ethernet RX counter: total_packets",
[]string{"server", "component", "description"}, nil,
),
UcsmVnicStatsTxTotalPkts: prometheus.NewDesc("ucsm_vnic_tx_total_packets",
"UCSM Ethernet TX counter: total_packets",
[]string{"server", "component", "description"}, nil,
),
UcsmVnicStatsRxTotalBytes: prometheus.NewDesc("ucsm_vnic_rx_total_bytes",
"UCSM Ethernet RX counter: total_bytes",
[]string{"server", "component", "description"}, nil,
),
UcsmVnicStatsTxTotalBytes: prometheus.NewDesc("ucsm_vnic_tx_total_bytes",
"UCSM Ethernet TX counter: total_bytes",
[]string{"server", "component", "description"}, nil,
),
UcsmVnicStatsRxDropped: prometheus.NewDesc("ucsm_vnic_rx_dropped",
"UCSM Ethernet Rx Dropped counter: total_count",
[]string{"server", "component", "description"}, nil,
),
UcsmVnicStatsTxDropped: prometheus.NewDesc("ucsm_vnic_tx_dropped",
"UCSM Ethernet Tx Dropped counter: total_count",
[]string{"server", "component", "description"}, nil,
),
UcsmVnicStatsRxError: prometheus.NewDesc("ucsm_vnic_rx_error",
"UCSM Ethernet Rx Error counter: total_count",
[]string{"server", "component", "description"}, nil,
),
UcsmVnicStatsTxError: prometheus.NewDesc("ucsm_vnic_tx_error",
"UCSM Ethernet Tx Error counter: total_count",
[]string{"server", "component", "description"}, nil,
),
}
}
// Describe prometheus describe
func (u *UcsExporters) Describe(ch chan<- *prometheus.Desc) {
log.Printf("Running Describe for UcsExporters\n")
// UCS Temperatures
ch <- u.UcsmTemperatures
// UCS Network statistics
ch <- u.UcsmVnicStatsRxTotalPkts
ch <- u.UcsmVnicStatsTxTotalPkts
ch <- u.UcsmVnicStatsRxTotalBytes
ch <- u.UcsmVnicStatsTxTotalBytes
ch <- u.UcsmVnicStatsRxDropped
ch <- u.UcsmVnicStatsTxDropped
ch <- u.UcsmVnicStatsRxError
ch <- u.UcsmVnicStatsTxError
}
// Collect prometheus collect
func (u *UcsExporters) Collect(ch chan<- prometheus.Metric) {
// TODO - refresh UCS Manager login session
//var wg = sync.WaitGroup{}
g, gCtx := errgroup.WithContext(u.ctx)
// Create channels to receive values
ucsmTempsChannel := make(chan []UcsmTemperatures)
ucsmPortStatsChannel := make(chan []UcsmVnicPortStats)
log.Printf("Running Collect for UCS Temperatures\n")
g.Go(func() error {
u.GetUcsmTemperatures(gCtx, ucsmTempsChannel)
return nil
})
log.Printf("Running Collect for UCS Network Statistics\n")
g.Go(func() error {
u.GetUcsmPortStats(gCtx, ucsmPortStatsChannel)
return nil
})
// Receive results from exporter channels
ucsmTempResults := <-ucsmTempsChannel
ucsmVnicStatsResults := <-ucsmPortStatsChannel
//wg.Wait()
// Send results back to prometheus channel
for _, blade := range ucsmTempResults {
log.Printf("Generating constant metric for component %s with value %f\n", blade.Component, blade.Value)
ch <- prometheus.MustNewConstMetric(u.UcsmTemperatures, prometheus.GaugeValue, blade.Value, blade.Server, blade.Component, blade.Description)
}
for _, vnic := range ucsmVnicStatsResults {
log.Printf("Generating constant metric for component %s\n", vnic.Component)
ch <- prometheus.MustNewConstMetric(u.UcsmVnicStatsRxTotalPkts, prometheus.GaugeValue, float64(vnic.Metrics["ucsm_vnic_rx_total_packets"]), vnic.Server, vnic.Component, "ucsm_vnic_rx_total_packets")
ch <- prometheus.MustNewConstMetric(u.UcsmVnicStatsTxTotalPkts, prometheus.GaugeValue, float64(vnic.Metrics["ucsm_vnic_tx_total_packets"]), vnic.Server, vnic.Component, "ucsm_vnic_tx_total_packets")
ch <- prometheus.MustNewConstMetric(u.UcsmVnicStatsRxTotalBytes, prometheus.GaugeValue, float64(vnic.Metrics["ucsm_vnic_rx_total_bytes"]), vnic.Server, vnic.Component, "ucsm_vnic_rx_total_bytes")
ch <- prometheus.MustNewConstMetric(u.UcsmVnicStatsTxTotalBytes, prometheus.GaugeValue, float64(vnic.Metrics["ucsm_vnic_tx_total_bytes"]), vnic.Server, vnic.Component, "ucsm_vnic_tx_total_bytes")
ch <- prometheus.MustNewConstMetric(u.UcsmVnicStatsRxDropped, prometheus.GaugeValue, float64(vnic.Metrics["ucsm_vnic_rx_dropped"]), vnic.Server, vnic.Component, "ucsm_vnic_rx_dropped")
ch <- prometheus.MustNewConstMetric(u.UcsmVnicStatsTxDropped, prometheus.GaugeValue, float64(vnic.Metrics["ucsm_vnic_tx_dropped"]), vnic.Server, vnic.Component, "ucsm_vnic_tx_dropped")
ch <- prometheus.MustNewConstMetric(u.UcsmVnicStatsRxError, prometheus.GaugeValue, float64(vnic.Metrics["ucsm_vnic_rx_error"]), vnic.Server, vnic.Component, "ucsm_vnic_rx_error")
ch <- prometheus.MustNewConstMetric(u.UcsmVnicStatsTxError, prometheus.GaugeValue, float64(vnic.Metrics["ucsm_vnic_tx_error"]), vnic.Server, vnic.Component, "ucsm_vnic_tx_error")
}
}

View File

@@ -0,0 +1 @@
package exporters

View File

@@ -359,6 +359,26 @@ type ProcessorUnit struct {
Voltage string `xml:"voltage,attr,omitempty"`
}
// AdaptorVnicStats is a managed object representing statistics for a network adaptor
// Added by Nathan. Incomplete representation of all data available
type AdaptorVnicStats struct {
XMLName xml.Name `xml:"adaptorVnicStats"`
Dn string `xml:"dn,attr,omitempty"`
Rn string `xml:"rn,attr,omitempty"`
BytesRx uint64 `xml:"bytesRx,attr,omitempty"`
BytesRxDelta uint64 `xml:"bytesRxDelta,attr,omitempty"`
BytesTx uint64 `xml:"bytesTx,attr,omitempty"`
BytesTxDelta uint64 `xml:"bytesTxDelta,attr,omitempty"`
PacketsRx uint64 `xml:"packetsRx,attr,omitempty"`
PacketsRxDelta uint64 `xml:"packetsRxDelta,attr,omitempty"`
PacketsTx uint64 `xml:"packetsTx,attr,omitempty"`
PacketsTxDelta uint64 `xml:"packetsTxDelta,attr,omitempty"`
DroppedRx uint64 `xml:"droppedRx,attr,omitempty"`
DroppedTx uint64 `xml:"droppedTx,attr,omitempty"`
ErrorsRx uint64 `xml:"errorsRx,attr,omitempty"`
ErrorsTx uint64 `xml:"errorsTx,attr,omitempty"`
}
// AdaptorUnit is a managed object representing a network adaptor unit such as a
// card that has NIC and/or HBA, SCSI functionality.
type AdaptorUnit struct {