From 066064f0f6bb2fdb5c4a7eaf8f9fc50efa5eb824 Mon Sep 17 00:00:00 2001 From: mikameyer Date: Mon, 18 Oct 2021 11:49:28 +0200 Subject: [PATCH 1/8] restructured filter --- config/codecommunicator/ceraos-ip10.go | 2 +- config/codecommunicator/code_communicator.go | 67 +--- config/codecommunicator/ekinops.go | 2 +- config/codecommunicator/junos.go | 6 +- config/codecommunicator/timos-sas.go | 2 +- config/codecommunicator/timos.go | 2 +- internal/device/device.go | 290 +++++++++--------- internal/deviceclass/groupproperty/filter.go | 188 +++++++++--- internal/deviceclass/groupproperty/reader.go | 12 + ...check_interface_metrics_request_process.go | 8 +- internal/value/value.go | 8 +- 11 files changed, 328 insertions(+), 259 deletions(-) diff --git a/config/codecommunicator/ceraos-ip10.go b/config/codecommunicator/ceraos-ip10.go index e20c099..3c6a3e3 100644 --- a/config/codecommunicator/ceraos-ip10.go +++ b/config/codecommunicator/ceraos-ip10.go @@ -75,5 +75,5 @@ func (c *ceraosIP10Communicator) GetInterfaces(ctx context.Context, filter ...gr } } - return filterInterfaces(subInterfaces, filter) + return filterInterfaces(ctx, subInterfaces, filter) } diff --git a/config/codecommunicator/code_communicator.go b/config/codecommunicator/code_communicator.go index a1310af..e0c6f2a 100644 --- a/config/codecommunicator/code_communicator.go +++ b/config/codecommunicator/code_communicator.go @@ -8,7 +8,6 @@ import ( "github.com/inexio/thola/internal/deviceclass/groupproperty" "github.com/inexio/thola/internal/tholaerr" "github.com/pkg/errors" - "regexp" ) type codeCommunicator struct { @@ -203,70 +202,28 @@ func (c *codeCommunicator) GetSBCComponentSystemHealthScore(_ context.Context) ( return 0, tholaerr.NewNotImplementedError("function is not implemented for this communicator") } -func filterInterfaces(interfaces []device.Interface, filter []groupproperty.Filter) ([]device.Interface, error) { +func filterInterfaces(ctx context.Context, interfaces []device.Interface, filter []groupproperty.Filter) ([]device.Interface, error) { if len(filter) == 0 { return interfaces, nil } - var ifDescrFilter, ifNameFilter, ifTypeFilter []*regexp.Regexp + var propertyGroups groupproperty.PropertyGroups + err := propertyGroups.Encode(interfaces) + if err != nil { + return nil, errors.Wrap(err, "failed to encode interfaces to property groups") + } for _, fil := range filter { - if interfaceFilter, ok := fil.(groupproperty.GroupFilter); ok { - key, regex := interfaceFilter.GetFilterProperties() - - switch key { - case "ifDescr": - regex, err := regexp.Compile(regex) - if err != nil { - return nil, errors.Wrap(err, "failed to compile ifDescr regex") - } - ifDescrFilter = append(ifDescrFilter, regex) - case "ifName": - regex, err := regexp.Compile(regex) - if err != nil { - return nil, errors.Wrap(err, "failed to compile ifName regex") - } - ifNameFilter = append(ifNameFilter, regex) - case "ifType": - regex, err := regexp.Compile(regex) - if err != nil { - return nil, errors.Wrap(err, "failed to compile ifType regex") - } - ifTypeFilter = append(ifTypeFilter, regex) - default: - return nil, errors.New("unknown filter key: " + key) - } + propertyGroups, err = fil.ApplyPropertyGroups(ctx, propertyGroups) + if err != nil { + return nil, errors.Wrap(err, "failed to apply filter on property groups") } } var res []device.Interface -out: - for _, interf := range interfaces { - if interf.IfDescr != nil { - for _, fil := range ifDescrFilter { - if fil.MatchString(*interf.IfDescr) { - continue out - } - } - } - - if interf.IfName != nil { - for _, fil := range ifNameFilter { - if fil.MatchString(*interf.IfName) { - continue out - } - } - } - - if interf.IfType != nil { - for _, fil := range ifTypeFilter { - if fil.MatchString(*interf.IfType) { - continue out - } - } - } - - res = append(res, interf) + err = propertyGroups.Decode(&res) + if err != nil { + return nil, errors.Wrap(err, "failed to decode property groups to interfaces") } return res, nil diff --git a/config/codecommunicator/ekinops.go b/config/codecommunicator/ekinops.go index c054fe0..d002338 100644 --- a/config/codecommunicator/ekinops.go +++ b/config/codecommunicator/ekinops.go @@ -74,7 +74,7 @@ func (c *ekinopsCommunicator) GetInterfaces(ctx context.Context, filter ...group return nil, errors.Wrap(err, "failed to normalize interfaces") } - return filterInterfaces(interfaces, filter) + return filterInterfaces(ctx, interfaces, filter) } func ekinopsInterfacesIfIdentifierToSliceIndex(interfaces []device.Interface) (map[string]int, error) { diff --git a/config/codecommunicator/junos.go b/config/codecommunicator/junos.go index 9a8a241..2f4ff2b 100644 --- a/config/codecommunicator/junos.go +++ b/config/codecommunicator/junos.go @@ -23,10 +23,8 @@ func (c *junosCommunicator) GetInterfaces(ctx context.Context, filter ...grouppr } for _, fil := range filter { - if valueFilter, ok := fil.(groupproperty.ValueFilter); ok { - if valueFilter.GetFilterProperties() == "vlan" { - return interfaces, nil - } + if valueFilter, ok := fil.(groupproperty.ValueFilter); ok && valueFilter.CheckMatch([]string{"vlan"}) { + return interfaces, nil } } diff --git a/config/codecommunicator/timos-sas.go b/config/codecommunicator/timos-sas.go index e914a74..48d0c2f 100644 --- a/config/codecommunicator/timos-sas.go +++ b/config/codecommunicator/timos-sas.go @@ -70,7 +70,7 @@ func (c *timosSASCommunicator) GetInterfaces(ctx context.Context, filter ...grou } } - return filterInterfaces(interfaces, filter) + return filterInterfaces(ctx, interfaces, filter) } // getInterfaceBySubIndex returns the index of the interface that has the given index. diff --git a/config/codecommunicator/timos.go b/config/codecommunicator/timos.go index 4d3674e..f700a3a 100644 --- a/config/codecommunicator/timos.go +++ b/config/codecommunicator/timos.go @@ -90,7 +90,7 @@ func (c *timosCommunicator) GetInterfaces(ctx context.Context, filter ...grouppr }) } - return filterInterfaces(interfaces, filter) + return filterInterfaces(ctx, interfaces, filter) } // getPhysPortDescriptions returns a mapping from every ifIndex to a description. diff --git a/internal/device/device.go b/internal/device/device.go index 7c740d5..5565228 100644 --- a/internal/device/device.go +++ b/internal/device/device.go @@ -77,43 +77,43 @@ type Properties struct { // // swagger:model type Interface struct { - IfIndex *uint64 `yaml:"ifIndex" json:"ifIndex" xml:"ifIndex"` - IfDescr *string `yaml:"ifDescr" json:"ifDescr" xml:"ifDescr"` - IfType *string `yaml:"ifType" json:"ifType" xml:"ifType"` - IfMtu *uint64 `yaml:"ifMtu" json:"ifMtu" xml:"ifMtu"` - IfSpeed *uint64 `yaml:"ifSpeed" json:"ifSpeed" xml:"ifSpeed"` - IfPhysAddress *string `yaml:"ifPhysAddress" json:"ifPhysAddress" xml:"ifPhysAddress"` - IfAdminStatus *Status `yaml:"ifAdminStatus" json:"ifAdminStatus" xml:"ifAdminStatus"` - IfOperStatus *Status `yaml:"ifOperStatus" json:"ifOperStatus" xml:"ifOperStatus"` - IfLastChange *uint64 `yaml:"ifLastChange" json:"ifLastChange" xml:"ifLastChange"` - IfInOctets *uint64 `yaml:"ifInOctets" json:"ifInOctets" xml:"ifInOctets"` - IfInUcastPkts *uint64 `yaml:"ifInUcastPkts" json:"ifInUcastPkts" xml:"ifInUcastPkts"` - IfInNUcastPkts *uint64 `yaml:"ifInNUcastPkts" json:"ifInNUcastPkts" xml:"ifInNUcastPkts"` - IfInDiscards *uint64 `yaml:"ifInDiscards" json:"ifInDiscards" xml:"ifInDiscards"` - IfInErrors *uint64 `yaml:"ifInErrors" json:"ifInErrors" xml:"ifInErrors"` - IfInUnknownProtos *uint64 `yaml:"ifInUnknownProtos" json:"ifInUnknownProtos" xml:"ifInUnknownProtos"` - IfOutOctets *uint64 `yaml:"ifOutOctets" json:"ifOutOctets" xml:"ifOutOctets"` - IfOutUcastPkts *uint64 `yaml:"ifOutUcastPkts" json:"ifOutUcastPkts" xml:"ifOutUcastPkts"` - IfOutNUcastPkts *uint64 `yaml:"ifOutNUcastPkts" json:"ifOutNUcastPkts" xml:"ifOutNUcastPkts"` - IfOutDiscards *uint64 `yaml:"ifOutDiscards" json:"ifOutDiscards" xml:"ifOutDiscards"` - IfOutErrors *uint64 `yaml:"ifOutErrors" json:"ifOutErrors" xml:"ifOutErrors"` - IfOutQLen *uint64 `yaml:"ifOutQLen" json:"ifOutQLen" xml:"ifOutQLen"` - IfSpecific *string `yaml:"ifSpecific" json:"ifSpecific" xml:"ifSpecific"` - IfName *string `yaml:"ifName" json:"ifName" xml:"ifName"` - IfInMulticastPkts *uint64 `yaml:"ifInMulticastPkts" json:"ifInMulticastPkts" xml:"ifInMulticastPkts"` - IfInBroadcastPkts *uint64 `yaml:"ifInBroadcastPkts" json:"ifInBroadcastPkts" xml:"ifInBroadcastPkts"` - IfOutMulticastPkts *uint64 `yaml:"ifOutMulticastPkts" json:"ifOutMulticastPkts" xml:"ifOutMulticastPkts"` - IfOutBroadcastPkts *uint64 `yaml:"ifOutBroadcastPkts" json:"ifOutBroadcastPkts" xml:"ifOutBroadcastPkts"` - IfHCInOctets *uint64 `yaml:"ifHCInOctets" json:"ifHCInOctets" xml:"ifHCInOctets"` - IfHCInUcastPkts *uint64 `yaml:"ifHCInUcastPkts" json:"ifHCInUcastPkts" xml:"ifHCInUcastPkts"` - IfHCInMulticastPkts *uint64 `yaml:"ifHCInMulticastPkts" json:"ifHCInMulticastPkts" xml:"ifHCInMulticastPkts"` - IfHCInBroadcastPkts *uint64 `yaml:"ifHCInBroadcastPkts" json:"ifHCInBroadcastPkts" xml:"ifHCInBroadcastPkts"` - IfHCOutOctets *uint64 `yaml:"ifHCOutOctets" json:"ifHCOutOctets" xml:"ifHCOutOctets"` - IfHCOutUcastPkts *uint64 `yaml:"ifHCOutUcastPkts" json:"ifHCOutUcastPkts" xml:"ifHCOutUcastPkts"` - IfHCOutMulticastPkts *uint64 `yaml:"ifHCOutMulticastPkts" json:"ifHCOutMulticastPkts" xml:"ifHCOutMulticastPkts"` - IfHCOutBroadcastPkts *uint64 `yaml:"ifHCOutBroadcastPkts" json:"ifHCOutBroadcastPkts" xml:"ifHCOutBroadcastPkts"` - IfHighSpeed *uint64 `yaml:"ifHighSpeed" json:"ifHighSpeed" xml:"ifHighSpeed"` - IfAlias *string `yaml:"ifAlias" json:"ifAlias" xml:"ifAlias"` + IfIndex *uint64 `yaml:"ifIndex" json:"ifIndex" xml:"ifIndex" mapstructure:"ifIndex"` + IfDescr *string `yaml:"ifDescr" json:"ifDescr" xml:"ifDescr" mapstructure:"ifDescr"` + IfType *string `yaml:"ifType" json:"ifType" xml:"ifType" mapstructure:"ifType"` + IfMtu *uint64 `yaml:"ifMtu" json:"ifMtu" xml:"ifMtu" mapstructure:"ifMtu"` + IfSpeed *uint64 `yaml:"ifSpeed" json:"ifSpeed" xml:"ifSpeed" mapstructure:"ifSpeed"` + IfPhysAddress *string `yaml:"ifPhysAddress" json:"ifPhysAddress" xml:"ifPhysAddress" mapstructure:"ifPhysAddress"` + IfAdminStatus *Status `yaml:"ifAdminStatus" json:"ifAdminStatus" xml:"ifAdminStatus" mapstructure:"ifAdminStatus"` + IfOperStatus *Status `yaml:"ifOperStatus" json:"ifOperStatus" xml:"ifOperStatus" mapstructure:"ifOperStatus"` + IfLastChange *uint64 `yaml:"ifLastChange" json:"ifLastChange" xml:"ifLastChange" mapstructure:"ifLastChange"` + IfInOctets *uint64 `yaml:"ifInOctets" json:"ifInOctets" xml:"ifInOctets" mapstructure:"ifInOctets"` + IfInUcastPkts *uint64 `yaml:"ifInUcastPkts" json:"ifInUcastPkts" xml:"ifInUcastPkts" mapstructure:"ifInUcastPkts"` + IfInNUcastPkts *uint64 `yaml:"ifInNUcastPkts" json:"ifInNUcastPkts" xml:"ifInNUcastPkts" mapstructure:"ifInNUcastPkts"` + IfInDiscards *uint64 `yaml:"ifInDiscards" json:"ifInDiscards" xml:"ifInDiscards" mapstructure:"ifInDiscards"` + IfInErrors *uint64 `yaml:"ifInErrors" json:"ifInErrors" xml:"ifInErrors" mapstructure:"ifInErrors"` + IfInUnknownProtos *uint64 `yaml:"ifInUnknownProtos" json:"ifInUnknownProtos" xml:"ifInUnknownProtos" mapstructure:"ifInUnknownProtos"` + IfOutOctets *uint64 `yaml:"ifOutOctets" json:"ifOutOctets" xml:"ifOutOctets" mapstructure:"ifOutOctets"` + IfOutUcastPkts *uint64 `yaml:"ifOutUcastPkts" json:"ifOutUcastPkts" xml:"ifOutUcastPkts" mapstructure:"ifOutUcastPkts"` + IfOutNUcastPkts *uint64 `yaml:"ifOutNUcastPkts" json:"ifOutNUcastPkts" xml:"ifOutNUcastPkts" mapstructure:"ifOutNUcastPkts"` + IfOutDiscards *uint64 `yaml:"ifOutDiscards" json:"ifOutDiscards" xml:"ifOutDiscards" mapstructure:"ifOutDiscards"` + IfOutErrors *uint64 `yaml:"ifOutErrors" json:"ifOutErrors" xml:"ifOutErrors" mapstructure:"ifOutErrors"` + IfOutQLen *uint64 `yaml:"ifOutQLen" json:"ifOutQLen" xml:"ifOutQLen" mapstructure:"ifOutQLen"` + IfSpecific *string `yaml:"ifSpecific" json:"ifSpecific" xml:"ifSpecific" mapstructure:"ifSpecific"` + IfName *string `yaml:"ifName" json:"ifName" xml:"ifName" mapstructure:"ifName"` + IfInMulticastPkts *uint64 `yaml:"ifInMulticastPkts" json:"ifInMulticastPkts" xml:"ifInMulticastPkts" mapstructure:"ifInMulticastPkts"` + IfInBroadcastPkts *uint64 `yaml:"ifInBroadcastPkts" json:"ifInBroadcastPkts" xml:"ifInBroadcastPkts" mapstructure:"ifInBroadcastPkts"` + IfOutMulticastPkts *uint64 `yaml:"ifOutMulticastPkts" json:"ifOutMulticastPkts" xml:"ifOutMulticastPkts" mapstructure:"ifOutMulticastPkts"` + IfOutBroadcastPkts *uint64 `yaml:"ifOutBroadcastPkts" json:"ifOutBroadcastPkts" xml:"ifOutBroadcastPkts" mapstructure:"ifOutBroadcastPkts"` + IfHCInOctets *uint64 `yaml:"ifHCInOctets" json:"ifHCInOctets" xml:"ifHCInOctets" mapstructure:"ifHCInOctets"` + IfHCInUcastPkts *uint64 `yaml:"ifHCInUcastPkts" json:"ifHCInUcastPkts" xml:"ifHCInUcastPkts" mapstructure:"ifHCInUcastPkts"` + IfHCInMulticastPkts *uint64 `yaml:"ifHCInMulticastPkts" json:"ifHCInMulticastPkts" xml:"ifHCInMulticastPkts" mapstructure:"ifHCInMulticastPkts"` + IfHCInBroadcastPkts *uint64 `yaml:"ifHCInBroadcastPkts" json:"ifHCInBroadcastPkts" xml:"ifHCInBroadcastPkts" mapstructure:"ifHCInBroadcastPkts"` + IfHCOutOctets *uint64 `yaml:"ifHCOutOctets" json:"ifHCOutOctets" xml:"ifHCOutOctets" mapstructure:"ifHCOutOctets"` + IfHCOutUcastPkts *uint64 `yaml:"ifHCOutUcastPkts" json:"ifHCOutUcastPkts" xml:"ifHCOutUcastPkts" mapstructure:"ifHCOutUcastPkts"` + IfHCOutMulticastPkts *uint64 `yaml:"ifHCOutMulticastPkts" json:"ifHCOutMulticastPkts" xml:"ifHCOutMulticastPkts" mapstructure:"ifHCOutMulticastPkts"` + IfHCOutBroadcastPkts *uint64 `yaml:"ifHCOutBroadcastPkts" json:"ifHCOutBroadcastPkts" xml:"ifHCOutBroadcastPkts" mapstructure:"ifHCOutBroadcastPkts"` + IfHighSpeed *uint64 `yaml:"ifHighSpeed" json:"ifHighSpeed" xml:"ifHighSpeed" mapstructure:"ifHighSpeed"` + IfAlias *string `yaml:"ifAlias" json:"ifAlias" xml:"ifAlias" mapstructure:"ifAlias"` // MaxSpeedIn and MaxSpeedOut are set if an interface has different values for max speed in / out MaxSpeedIn *uint64 `yaml:"max_speed_in" json:"max_speed_in" xml:"max_speed_in" mapstructure:"max_speed_in"` @@ -143,24 +143,24 @@ type Interface struct { // // swagger:model type EthernetLikeInterface struct { - Dot3StatsAlignmentErrors *uint64 `yaml:"dot3StatsAlignmentErrors,omitempty" json:"dot3StatsAlignmentErrors,omitempty" xml:"dot3StatsAlignmentErrors,omitempty"` - Dot3StatsFCSErrors *uint64 `yaml:"dot3StatsFCSErrors,omitempty" json:"dot3StatsFCSErrors,omitempty" xml:"dot3StatsFCSErrors,omitempty"` - Dot3StatsSingleCollisionFrames *uint64 `yaml:"dot3StatsSingleCollisionFrames,omitempty" json:"dot3StatsSingleCollisionFrames,omitempty" xml:"dot3StatsSingleCollisionFrames,omitempty"` - Dot3StatsMultipleCollisionFrames *uint64 `yaml:"dot3StatsMultipleCollisionFrames,omitempty" json:"dot3StatsMultipleCollisionFrames,omitempty" xml:"dot3StatsMultipleCollisionFrames,omitempty"` - Dot3StatsSQETestErrors *uint64 `yaml:"dot3StatsSQETestErrors,omitempty" json:"dot3StatsSQETestErrors,omitempty" xml:"dot3StatsSQETestErrors,omitempty"` - Dot3StatsDeferredTransmissions *uint64 `yaml:"dot3StatsDeferredTransmissions,omitempty" json:"dot3StatsDeferredTransmissions,omitempty" xml:"dot3StatsDeferredTransmissions,omitempty"` - Dot3StatsLateCollisions *uint64 `yaml:"dot3StatsLateCollisions,omitempty" json:"dot3StatsLateCollisions,omitempty" xml:"dot3StatsLateCollisions,omitempty"` - Dot3StatsExcessiveCollisions *uint64 `yaml:"dot3StatsExcessiveCollisions,omitempty" json:"dot3StatsExcessiveCollisions,omitempty" xml:"dot3StatsExcessiveCollisions,omitempty"` - Dot3StatsInternalMacTransmitErrors *uint64 `yaml:"dot3StatsInternalMacTransmitErrors,omitempty" json:"dot3StatsInternalMacTransmitErrors,omitempty" xml:"dot3StatsInternalMacTransmitErrors,omitempty"` - Dot3StatsCarrierSenseErrors *uint64 `yaml:"dot3StatsCarrierSenseErrors,omitempty" json:"dot3StatsCarrierSenseErrors,omitempty" xml:"dot3StatsCarrierSenseErrors,omitempty"` - Dot3StatsFrameTooLongs *uint64 `yaml:"dot3StatsFrameTooLongs,omitempty" json:"dot3StatsFrameTooLongs,omitempty" xml:"dot3StatsFrameTooLongs,omitempty"` - Dot3StatsInternalMacReceiveErrors *uint64 `yaml:"dot3StatsInternalMacReceiveErrors,omitempty" json:"dot3StatsInternalMacReceiveErrors,omitempty" xml:"dot3StatsInternalMacReceiveErrors,omitempty"` - Dot3HCStatsAlignmentErrors *uint64 `yaml:"dot3HCStatsAlignmentErrors,omitempty" json:"dot3HCStatsAlignmentErrors,omitempty" xml:"dot3HCStatsAlignmentErrors,omitempty"` - Dot3HCStatsFCSErrors *uint64 `yaml:"dot3HCStatsFCSErrors,omitempty" json:"dot3HCStatsFCSErrors,omitempty" xml:"dot3HCStatsFCSErrors,omitempty"` - Dot3HCStatsInternalMacTransmitErrors *uint64 `yaml:"dot3HCStatsInternalMacTransmitErrors,omitempty" json:"dot3HCStatsInternalMacTransmitErrors,omitempty" xml:"dot3HCStatsInternalMacTransmitErrors,omitempty"` - Dot3HCStatsFrameTooLongs *uint64 `yaml:"dot3HCStatsFrameTooLongs,omitempty" json:"dot3HCStatsFrameTooLongs,omitempty" xml:"dot3HCStatsFrameTooLongs,omitempty"` - Dot3HCStatsInternalMacReceiveErrors *uint64 `yaml:"dot3HCStatsInternalMacReceiveErrors,omitempty" json:"dot3HCStatsInternalMacReceiveErrors,omitempty" xml:"dot3HCStatsInternalMacReceiveErrors,omitempty"` - EtherStatsCRCAlignErrors *uint64 `yaml:"etherStatsCRCAlignErrors,omitempty" json:"etherStatsCRCAlignErrors,omitempty" xml:"etherStatsCRCAlignErrors,omitempty"` + Dot3StatsAlignmentErrors *uint64 `yaml:"dot3StatsAlignmentErrors" json:"dot3StatsAlignmentErrors" xml:"dot3StatsAlignmentErrors" mapstructure:"dot3StatsAlignmentErrors"` + Dot3StatsFCSErrors *uint64 `yaml:"dot3StatsFCSErrors" json:"dot3StatsFCSErrors" xml:"dot3StatsFCSErrors" mapstructure:"dot3StatsFCSErrors"` + Dot3StatsSingleCollisionFrames *uint64 `yaml:"dot3StatsSingleCollisionFrames" json:"dot3StatsSingleCollisionFrames" xml:"dot3StatsSingleCollisionFrames" mapstructure:"dot3StatsSingleCollisionFrames"` + Dot3StatsMultipleCollisionFrames *uint64 `yaml:"dot3StatsMultipleCollisionFrames" json:"dot3StatsMultipleCollisionFrames" xml:"dot3StatsMultipleCollisionFrames" mapstructure:"dot3StatsMultipleCollisionFrames"` + Dot3StatsSQETestErrors *uint64 `yaml:"dot3StatsSQETestErrors" json:"dot3StatsSQETestErrors" xml:"dot3StatsSQETestErrors" mapstructure:"dot3StatsSQETestErrors"` + Dot3StatsDeferredTransmissions *uint64 `yaml:"dot3StatsDeferredTransmissions" json:"dot3StatsDeferredTransmissions" xml:"dot3StatsDeferredTransmissions" mapstructure:"dot3StatsDeferredTransmissions"` + Dot3StatsLateCollisions *uint64 `yaml:"dot3StatsLateCollisions" json:"dot3StatsLateCollisions" xml:"dot3StatsLateCollisions" mapstructure:"dot3StatsLateCollisions"` + Dot3StatsExcessiveCollisions *uint64 `yaml:"dot3StatsExcessiveCollisions" json:"dot3StatsExcessiveCollisions" xml:"dot3StatsExcessiveCollisions" mapstructure:"dot3StatsExcessiveCollisions"` + Dot3StatsInternalMacTransmitErrors *uint64 `yaml:"dot3StatsInternalMacTransmitErrors" json:"dot3StatsInternalMacTransmitErrors" xml:"dot3StatsInternalMacTransmitErrors" mapstructure:"dot3StatsInternalMacTransmitErrors"` + Dot3StatsCarrierSenseErrors *uint64 `yaml:"dot3StatsCarrierSenseErrors" json:"dot3StatsCarrierSenseErrors" xml:"dot3StatsCarrierSenseErrors" mapstructure:"dot3StatsCarrierSenseErrors"` + Dot3StatsFrameTooLongs *uint64 `yaml:"dot3StatsFrameTooLongs" json:"dot3StatsFrameTooLongs" xml:"dot3StatsFrameTooLongs" mapstructure:"dot3StatsFrameTooLongs"` + Dot3StatsInternalMacReceiveErrors *uint64 `yaml:"dot3StatsInternalMacReceiveErrors" json:"dot3StatsInternalMacReceiveErrors" xml:"dot3StatsInternalMacReceiveErrors" mapstructure:"dot3StatsInternalMacReceiveErrors"` + Dot3HCStatsAlignmentErrors *uint64 `yaml:"dot3HCStatsAlignmentErrors" json:"dot3HCStatsAlignmentErrors" xml:"dot3HCStatsAlignmentErrors" mapstructure:"dot3HCStatsAlignmentErrors"` + Dot3HCStatsFCSErrors *uint64 `yaml:"dot3HCStatsFCSErrors" json:"dot3HCStatsFCSErrors" xml:"dot3HCStatsFCSErrors" mapstructure:"dot3HCStatsFCSErrors"` + Dot3HCStatsInternalMacTransmitErrors *uint64 `yaml:"dot3HCStatsInternalMacTransmitErrors" json:"dot3HCStatsInternalMacTransmitErrors" xml:"dot3HCStatsInternalMacTransmitErrors" mapstructure:"dot3HCStatsInternalMacTransmitErrors"` + Dot3HCStatsFrameTooLongs *uint64 `yaml:"dot3HCStatsFrameTooLongs" json:"dot3HCStatsFrameTooLongs" xml:"dot3HCStatsFrameTooLongs" mapstructure:"dot3HCStatsFrameTooLongs"` + Dot3HCStatsInternalMacReceiveErrors *uint64 `yaml:"dot3HCStatsInternalMacReceiveErrors" json:"dot3HCStatsInternalMacReceiveErrors" xml:"dot3HCStatsInternalMacReceiveErrors" mapstructure:"dot3HCStatsInternalMacReceiveErrors"` + EtherStatsCRCAlignErrors *uint64 `yaml:"etherStatsCRCAlignErrors" json:"etherStatsCRCAlignErrors" xml:"etherStatsCRCAlignErrors" mapstructure:"etherStatsCRCAlignErrors"` } // RadioInterface @@ -169,10 +169,10 @@ type EthernetLikeInterface struct { // // swagger:model type RadioInterface struct { - LevelOut *int64 `yaml:"level_out,omitempty" json:"level_out,omitempty" xml:"level_out,omitempty" mapstructure:"level_out"` - LevelIn *int64 `yaml:"level_in,omitempty" json:"level_in,omitempty" xml:"level_in,omitempty" mapstructure:"level_in"` - MaxbitrateOut *uint64 `yaml:"maxbitrate_out,omitempty" json:"maxbitrate_out,omitempty" xml:"maxbitrate_out,omitempty" mapstructure:"maxbitrate_out"` - MaxbitrateIn *uint64 `yaml:"maxbitrate_in,omitempty" json:"maxbitrate_in,omitempty" xml:"maxbitrate_in,omitempty" mapstructure:"maxbitrate_in"` + LevelOut *int64 `yaml:"level_out" json:"level_out" xml:"level_out" mapstructure:"level_out"` + LevelIn *int64 `yaml:"level_in" json:"level_in" xml:"level_in" mapstructure:"level_in"` + MaxbitrateOut *uint64 `yaml:"maxbitrate_out" json:"maxbitrate_out" xml:"maxbitrate_out" mapstructure:"maxbitrate_out"` + MaxbitrateIn *uint64 `yaml:"maxbitrate_in" json:"maxbitrate_in" xml:"maxbitrate_in" mapstructure:"maxbitrate_in"` } // DWDMInterface @@ -181,11 +181,11 @@ type RadioInterface struct { // // swagger:model type DWDMInterface struct { - RXPower *float64 `yaml:"rx_power,omitempty" json:"rx_power,omitempty" xml:"rx_power,omitempty" mapstructure:"rx_power"` - TXPower *float64 `yaml:"tx_power,omitempty" json:"tx_power,omitempty" xml:"tx_power,omitempty" mapstructure:"tx_power"` - CorrectedFEC []Rate `yaml:"corrected_fec,omitempty" json:"corrected_fec,omitempty" xml:"corrected_fec,omitempty" mapstructure:"corrected_fec"` - UncorrectedFEC []Rate `yaml:"uncorrected_fec,omitempty" json:"uncorrected_fec,omitempty" xml:"uncorrected_fec,omitempty" mapstructure:"uncorrected_fec"` - Channels []OpticalChannel `yaml:"channels,omitempty" json:"channels,omitempty" xml:"channels,omitempty" mapstructure:"channels"` + RXPower *float64 `yaml:"rx_power" json:"rx_power" xml:"rx_power" mapstructure:"rx_power"` + TXPower *float64 `yaml:"tx_power" json:"tx_power" xml:"tx_power" mapstructure:"tx_power"` + CorrectedFEC []Rate `yaml:"corrected_fec" json:"corrected_fec" xml:"corrected_fec" mapstructure:"corrected_fec"` + UncorrectedFEC []Rate `yaml:"uncorrected_fec" json:"uncorrected_fec" xml:"uncorrected_fec" mapstructure:"uncorrected_fec"` + Channels []OpticalChannel `yaml:"channels" json:"channels" xml:"channels" mapstructure:"channels"` } // OpticalTransponderInterface @@ -194,12 +194,12 @@ type DWDMInterface struct { // // swagger:model type OpticalTransponderInterface struct { - Identifier *string `yaml:"identifier,omitempty" json:"identifier,omitempty" xml:"identifier,omitempty" mapstructure:"identifier"` - Label *string `yaml:"label,omitempty" json:"label,omitempty" xml:"label,omitempty" mapstructure:"label"` - RXPower *float64 `yaml:"rx_power,omitempty" json:"rx_power,omitempty" xml:"rx_power,omitempty" mapstructure:"rx_power"` - TXPower *float64 `yaml:"tx_power,omitempty" json:"tx_power,omitempty" xml:"tx_power,omitempty" mapstructure:"tx_power"` - CorrectedFEC *uint64 `yaml:"corrected_fec,omitempty" json:"corrected_fec,omitempty" xml:"corrected_fec,omitempty" mapstructure:"corrected_fec"` - UncorrectedFEC *uint64 `yaml:"uncorrected_fec,omitempty" json:"uncorrected_fec,omitempty" xml:"uncorrected_fec,omitempty" mapstructure:"uncorrected_fec"` + Identifier *string `yaml:"identifier" json:"identifier" xml:"identifier" mapstructure:"identifier"` + Label *string `yaml:"label" json:"label" xml:"label" mapstructure:"label"` + RXPower *float64 `yaml:"rx_power" json:"rx_power" xml:"rx_power" mapstructure:"rx_power"` + TXPower *float64 `yaml:"tx_power" json:"tx_power" xml:"tx_power" mapstructure:"tx_power"` + CorrectedFEC *uint64 `yaml:"corrected_fec" json:"corrected_fec" xml:"corrected_fec" mapstructure:"corrected_fec"` + UncorrectedFEC *uint64 `yaml:"uncorrected_fec" json:"uncorrected_fec" xml:"uncorrected_fec" mapstructure:"uncorrected_fec"` } // OpticalAmplifierInterface @@ -208,11 +208,11 @@ type OpticalTransponderInterface struct { // // swagger:model type OpticalAmplifierInterface struct { - Identifier *string `yaml:"identifier,omitempty" json:"identifier,omitempty" xml:"identifier,omitempty" mapstructure:"identifier"` - Label *string `yaml:"label,omitempty" json:"label,omitempty" xml:"label,omitempty" mapstructure:"label"` - RXPower *float64 `yaml:"rx_power,omitempty" json:"rx_power,omitempty" xml:"rx_power,omitempty" mapstructure:"rx_power"` - TXPower *float64 `yaml:"tx_power,omitempty" json:"tx_power,omitempty" xml:"tx_power,omitempty" mapstructure:"tx_power"` - Gain *float64 `yaml:"gain,omitempty" json:"gain,omitempty" xml:"gain,omitempty" mapstructure:"gain"` + Identifier *string `yaml:"identifier" json:"identifier" xml:"identifier" mapstructure:"identifier"` + Label *string `yaml:"label" json:"label" xml:"label" mapstructure:"label"` + RXPower *float64 `yaml:"rx_power" json:"rx_power" xml:"rx_power" mapstructure:"rx_power"` + TXPower *float64 `yaml:"tx_power" json:"tx_power" xml:"tx_power" mapstructure:"tx_power"` + Gain *float64 `yaml:"gain" json:"gain" xml:"gain" mapstructure:"gain"` } // OpticalOPMInterface @@ -221,10 +221,10 @@ type OpticalAmplifierInterface struct { // // swagger:model type OpticalOPMInterface struct { - Identifier *string `yaml:"identifier,omitempty" json:"identifier,omitempty" xml:"identifier,omitempty" mapstructure:"identifier"` - Label *string `yaml:"label,omitempty" json:"label,omitempty" xml:"label,omitempty" mapstructure:"label"` - RXPower *float64 `yaml:"rx_power,omitempty" json:"rx_power,omitempty" xml:"rx_power,omitempty" mapstructure:"rx_power"` - Channels []OpticalChannel `yaml:"channels,omitempty" json:"channels,omitempty" xml:"channels,omitempty" mapstructure:"channels"` + Identifier *string `yaml:"identifier" json:"identifier" xml:"identifier" mapstructure:"identifier"` + Label *string `yaml:"label" json:"label" xml:"label" mapstructure:"label"` + RXPower *float64 `yaml:"rx_power" json:"rx_power" xml:"rx_power" mapstructure:"rx_power"` + Channels []OpticalChannel `yaml:"channels" json:"channels" xml:"channels" mapstructure:"channels"` } // OpticalChannel @@ -233,9 +233,9 @@ type OpticalOPMInterface struct { // // swagger:model type OpticalChannel struct { - Channel *string `yaml:"channel,omitempty" json:"channel,omitempty" xml:"channel,omitempty" mapstructure:"channel"` - RXPower *float64 `yaml:"rx_power,omitempty" json:"rx_power,omitempty" xml:"rx_power,omitempty" mapstructure:"rx_power"` - TXPower *float64 `yaml:"tx_power,omitempty" json:"tx_power,omitempty" xml:"tx_power,omitempty" mapstructure:"tx_power"` + Channel *string `yaml:"channel" json:"channel" xml:"channel" mapstructure:"channel"` + RXPower *float64 `yaml:"rx_power" json:"rx_power" xml:"rx_power" mapstructure:"rx_power"` + TXPower *float64 `yaml:"tx_power" json:"tx_power" xml:"tx_power" mapstructure:"tx_power"` } // SAPInterface @@ -244,8 +244,8 @@ type OpticalChannel struct { // // swagger:model type SAPInterface struct { - Inbound *uint64 `yaml:"inbound,omitempty" json:"inbound,omitempty" xml:"inbound,omitempty" mapstructure:"inbound"` - Outbound *uint64 `yaml:"outbound,omitempty" json:"outbound,omitempty" xml:"outbound,omitempty" mapstructure:"outbound"` + Inbound *uint64 `yaml:"inbound" json:"inbound" xml:"inbound" mapstructure:"inbound"` + Outbound *uint64 `yaml:"outbound" json:"outbound" xml:"outbound" mapstructure:"outbound"` } // VLANInformation @@ -254,7 +254,7 @@ type SAPInterface struct { // // swagger:model type VLANInformation struct { - VLANs []VLAN `yaml:"vlans,omitempty" json:"vlans,omitempty" xml:"vlans,omitempty" mapstructure:"vlans"` + VLANs []VLAN `yaml:"vlans" json:"vlans" xml:"vlans" mapstructure:"vlans"` } // VLAN @@ -263,8 +263,8 @@ type VLANInformation struct { // // swagger:model type VLAN struct { - Name *string `yaml:"name,omitempty" json:"name,omitempty" xml:"name,omitempty" mapstructure:"name"` - Status *string `yaml:"status,omitempty" json:"status,omitempty" xml:"status,omitempty" mapstructure:"status"` + Name *string `yaml:"name" json:"name" xml:"name" mapstructure:"name"` + Status *string `yaml:"status" json:"status" xml:"status" mapstructure:"status"` } // @@ -277,7 +277,7 @@ type VLAN struct { // // swagger:model type CPUComponent struct { - CPUs []CPU `yaml:"cpus" json:"cpus" xml:"cpus"` + CPUs []CPU `yaml:"cpus" json:"cpus" xml:"cpus" mapstructure:"cpus"` } // CPU @@ -286,8 +286,8 @@ type CPUComponent struct { // // swagger:model type CPU struct { - Label *string `yaml:"label" json:"label" xml:"label"` - Load *float64 `yaml:"load" json:"load" xml:"load"` + Label *string `yaml:"label" json:"label" xml:"label" mapstructure:"label"` + Load *float64 `yaml:"load" json:"load" xml:"load" mapstructure:"load"` } // MemoryComponent @@ -296,7 +296,7 @@ type CPU struct { // // swagger:model type MemoryComponent struct { - Pools []MemoryPool `yaml:"pools" json:"pools" xml:"pools"` + Pools []MemoryPool `yaml:"pools" json:"pools" xml:"pools" mapstructure:"pools"` } // MemoryPool @@ -305,8 +305,8 @@ type MemoryComponent struct { // // swagger:model type MemoryPool struct { - Label *string `yaml:"label" json:"label" xml:"label"` - Usage *float64 `yaml:"usage" json:"usage" xml:"usage"` + Label *string `yaml:"label" json:"label" xml:"label" mapstructure:"label"` + Usage *float64 `yaml:"usage" json:"usage" xml:"usage" mapstructure:"usage"` PerformanceDataPointModifier `yaml:"-" json:"-" xml:"-" human_readable:"-"` } @@ -316,7 +316,7 @@ type MemoryPool struct { // // swagger:model type DiskComponent struct { - Storages []DiskComponentStorage `yaml:"storages" json:"storages" xml:"storages"` + Storages []DiskComponentStorage `yaml:"storages" json:"storages" xml:"storages" mapstructure:"storages"` } // DiskComponentStorage @@ -325,10 +325,10 @@ type DiskComponent struct { // // swagger:model type DiskComponentStorage struct { - Type *string `yaml:"type" json:"type" xml:"type"` - Description *string `yaml:"description" json:"description" xml:"description"` - Available *int `yaml:"available" json:"available" xml:"available"` - Used *int `yaml:"used" json:"used" xml:"used"` + Type *string `yaml:"type" json:"type" xml:"type" mapstructure:"type"` + Description *string `yaml:"description" json:"description" xml:"description" mapstructure:"description"` + Available *int `yaml:"available" json:"available" xml:"available" mapstructure:"available"` + Used *int `yaml:"used" json:"used" xml:"used" mapstructure:"used"` } // UPSComponent @@ -337,17 +337,17 @@ type DiskComponentStorage struct { // // swagger:model type UPSComponent struct { - AlarmLowVoltageDisconnect *int `yaml:"alarm_low_voltage_disconnect" json:"alarm_low_voltage_disconnect" xml:"alarm_low_voltage_disconnect"` - BatteryAmperage *float64 `yaml:"battery_amperage " json:"battery_amperage " xml:"battery_amperage"` - BatteryCapacity *float64 `yaml:"battery_capacity" json:"battery_capacity" xml:"battery_capacity"` - BatteryCurrent *float64 `yaml:"battery_current" json:"battery_current" xml:"battery_current"` - BatteryRemainingTime *float64 `yaml:"battery_remaining_time" json:"battery_remaining_time" xml:"battery_remaining_time"` - BatteryTemperature *float64 `yaml:"battery_temperature" json:"battery_temperature" xml:"battery_temperature"` - BatteryVoltage *float64 `yaml:"battery_voltage" json:"battery_voltage" xml:"battery_voltage"` - CurrentLoad *float64 `yaml:"current_load" json:"current_load" xml:"current_load"` - MainsVoltageApplied *bool `yaml:"mains_voltage_applied" json:"mains_voltage_applied" xml:"mains_voltage_applied"` - RectifierCurrent *float64 `yaml:"rectifier_current" json:"rectifier_current" xml:"rectifier_current"` - SystemVoltage *float64 `yaml:"system_voltage" json:"system_voltage" xml:"system_voltage"` + AlarmLowVoltageDisconnect *int `yaml:"alarm_low_voltage_disconnect" json:"alarm_low_voltage_disconnect" xml:"alarm_low_voltage_disconnect" mapstructure:"alarm_low_voltage_disconnect"` + BatteryAmperage *float64 `yaml:"battery_amperage " json:"battery_amperage " xml:"battery_amperage" mapstructure:"battery_amperage"` + BatteryCapacity *float64 `yaml:"battery_capacity" json:"battery_capacity" xml:"battery_capacity" mapstructure:"battery_capacity"` + BatteryCurrent *float64 `yaml:"battery_current" json:"battery_current" xml:"battery_current" mapstructure:"battery_current"` + BatteryRemainingTime *float64 `yaml:"battery_remaining_time" json:"battery_remaining_time" xml:"battery_remaining_time" mapstructure:"battery_remaining_time"` + BatteryTemperature *float64 `yaml:"battery_temperature" json:"battery_temperature" xml:"battery_temperature" mapstructure:"battery_temperature"` + BatteryVoltage *float64 `yaml:"battery_voltage" json:"battery_voltage" xml:"battery_voltage" mapstructure:"battery_voltage"` + CurrentLoad *float64 `yaml:"current_load" json:"current_load" xml:"current_load" mapstructure:"current_load"` + MainsVoltageApplied *bool `yaml:"mains_voltage_applied" json:"mains_voltage_applied" xml:"mains_voltage_applied" mapstructure:"mains_voltage_applied"` + RectifierCurrent *float64 `yaml:"rectifier_current" json:"rectifier_current" xml:"rectifier_current" mapstructure:"rectifier_current"` + SystemVoltage *float64 `yaml:"system_voltage" json:"system_voltage" xml:"system_voltage" mapstructure:"system_voltage"` } // ServerComponent @@ -356,8 +356,8 @@ type UPSComponent struct { // // swagger:model type ServerComponent struct { - Procs *int `yaml:"procs" json:"procs" xml:"procs"` - Users *int `yaml:"users" json:"users" xml:"users"` + Procs *int `yaml:"procs" json:"procs" xml:"procs" mapstructure:"procs"` + Users *int `yaml:"users" json:"users" xml:"users" mapstructure:"users"` } // SBCComponent @@ -366,15 +366,15 @@ type ServerComponent struct { // // swagger:model type SBCComponent struct { - Agents []SBCComponentAgent `yaml:"agents" json:"agents" xml:"agents"` - Realms []SBCComponentRealm `yaml:"realms" json:"realms" xml:"realms"` - GlobalCallPerSecond *int `yaml:"global_call_per_second" json:"global_call_per_second" xml:"global_call_per_second"` - GlobalConcurrentSessions *int `yaml:"global_concurrent_sessions " json:"global_concurrent_sessions " xml:"global_concurrent_sessions"` - ActiveLocalContacts *int `yaml:"active_local_contacts" json:"active_local_contacts" xml:"active_local_contacts"` - TranscodingCapacity *int `yaml:"transcoding_capacity" json:"transcoding_capacity" xml:"transcoding_capacity"` - LicenseCapacity *int `yaml:"license_capacity" json:"license_capacity" xml:"license_capacity"` - SystemRedundancy *int `yaml:"system_redundancy" json:"system_redundancy" xml:"system_redundancy"` - SystemHealthScore *int `yaml:"system_health_score" json:"system_health_score" xml:"system_health_score"` + Agents []SBCComponentAgent `yaml:"agents" json:"agents" xml:"agents" mapstructure:"agents"` + Realms []SBCComponentRealm `yaml:"realms" json:"realms" xml:"realms" mapstructure:"realms"` + GlobalCallPerSecond *int `yaml:"global_call_per_second" json:"global_call_per_second" xml:"global_call_per_second" mapstructure:"global_call_per_second"` + GlobalConcurrentSessions *int `yaml:"global_concurrent_sessions " json:"global_concurrent_sessions " xml:"global_concurrent_sessions" mapstructure:"global_concurrent_sessions"` + ActiveLocalContacts *int `yaml:"active_local_contacts" json:"active_local_contacts" xml:"active_local_contacts" mapstructure:"active_local_contacts"` + TranscodingCapacity *int `yaml:"transcoding_capacity" json:"transcoding_capacity" xml:"transcoding_capacity" mapstructure:"transcoding_capacity"` + LicenseCapacity *int `yaml:"license_capacity" json:"license_capacity" xml:"license_capacity" mapstructure:"license_capacity"` + SystemRedundancy *int `yaml:"system_redundancy" json:"system_redundancy" xml:"system_redundancy" mapstructure:"system_redundancy"` + SystemHealthScore *int `yaml:"system_health_score" json:"system_health_score" xml:"system_health_score" mapstructure:"system_health_score"` } // SBCComponentAgent @@ -414,11 +414,11 @@ type SBCComponentRealm struct { // // swagger:model type HardwareHealthComponent struct { - EnvironmentMonitorState *HardwareHealthComponentState `yaml:"environment_monitor_state" json:"environment_monitor_state" xml:"environment_monitor_state"` - Fans []HardwareHealthComponentFan `yaml:"fans" json:"fans" xml:"fans"` - PowerSupply []HardwareHealthComponentPowerSupply `yaml:"power_supply" json:"power_supply" xml:"power_supply"` - Temperature []HardwareHealthComponentTemperature `yaml:"temperature" json:"temperature" xml:"temperature"` - Voltage []HardwareHealthComponentVoltage `yaml:"voltage" json:"voltage" xml:"voltage"` + EnvironmentMonitorState *HardwareHealthComponentState `yaml:"environment_monitor_state" json:"environment_monitor_state" xml:"environment_monitor_state" mapstructure:"environment_monitor_state"` + Fans []HardwareHealthComponentFan `yaml:"fans" json:"fans" xml:"fans" mapstructure:"fans"` + PowerSupply []HardwareHealthComponentPowerSupply `yaml:"power_supply" json:"power_supply" xml:"power_supply" mapstructure:"power_supply"` + Temperature []HardwareHealthComponentTemperature `yaml:"temperature" json:"temperature" xml:"temperature" mapstructure:"temperature"` + Voltage []HardwareHealthComponentVoltage `yaml:"voltage" json:"voltage" xml:"voltage" mapstructure:"voltage"` } // HardwareHealthComponentFan @@ -427,8 +427,8 @@ type HardwareHealthComponent struct { // // swagger:model type HardwareHealthComponentFan struct { - Description *string `yaml:"description" json:"description" xml:"description"` - State *HardwareHealthComponentState `yaml:"state" json:"state" xml:"state"` + Description *string `yaml:"description" json:"description" xml:"description" mapstructure:"description"` + State *HardwareHealthComponentState `yaml:"state" json:"state" xml:"state" mapstructure:"state"` } // HardwareHealthComponentTemperature @@ -437,9 +437,9 @@ type HardwareHealthComponentFan struct { // // swagger:model type HardwareHealthComponentTemperature struct { - Description *string `yaml:"description" json:"description" xml:"description"` - Temperature *float64 `yaml:"temperature" json:"temperature" xml:"temperature"` - State *HardwareHealthComponentState `yaml:"state" json:"state" xml:"state"` + Description *string `yaml:"description" json:"description" xml:"description" mapstructure:"description"` + Temperature *float64 `yaml:"temperature" json:"temperature" xml:"temperature" mapstructure:"temperature"` + State *HardwareHealthComponentState `yaml:"state" json:"state" xml:"state" mapstructure:"state"` } // HardwareHealthComponentVoltage @@ -448,9 +448,19 @@ type HardwareHealthComponentTemperature struct { // // swagger:model type HardwareHealthComponentVoltage struct { - Description *string `yaml:"description" json:"description" xml:"description"` - Voltage *float64 `yaml:"voltage" json:"voltage" xml:"voltage"` - State *HardwareHealthComponentState `yaml:"state" json:"state" xml:"state"` + Description *string `yaml:"description" json:"description" xml:"description" mapstructure:"description"` + Voltage *float64 `yaml:"voltage" json:"voltage" xml:"voltage" mapstructure:"voltage"` + State *HardwareHealthComponentState `yaml:"state" json:"state" xml:"state" mapstructure:"state"` +} + +// HardwareHealthComponentPowerSupply +// +// HardwareHealthComponentPowerSupply represents one power supply of a device. +// +// swagger:model +type HardwareHealthComponentPowerSupply struct { + Description *string `yaml:"description" json:"description" xml:"description" mapstructure:"description"` + State *HardwareHealthComponentState `yaml:"state" json:"state" xml:"state" mapstructure:"state"` } type HardwareHealthComponentState string @@ -488,24 +498,14 @@ func (h HardwareHealthComponentState) GetInt() (int, error) { return 7, fmt.Errorf("invalid hardware health state '%s'", h) } -// HardwareHealthComponentPowerSupply -// -// HardwareHealthComponentPowerSupply represents one power supply of a device. -// -// swagger:model -type HardwareHealthComponentPowerSupply struct { - Description *string `yaml:"description" json:"description" xml:"description"` - State *HardwareHealthComponentState `yaml:"state" json:"state" xml:"state"` -} - // Rate // // Rate encapsulates values which refer to a time span. // // swagger:model type Rate struct { - Time string `yaml:"time" json:"time" xml:"time"` - Value float64 `yaml:"value" json:"value" xml:"value"` + Time string `yaml:"time" json:"time" xml:"time" mapstructure:"time"` + Value float64 `yaml:"value" json:"value" xml:"value" mapstructure:"value"` } // NewContextWithDeviceProperties returns a new context with the device properties. diff --git a/internal/deviceclass/groupproperty/filter.go b/internal/deviceclass/groupproperty/filter.go index 1cf760e..7ff15d4 100644 --- a/internal/deviceclass/groupproperty/filter.go +++ b/internal/deviceclass/groupproperty/filter.go @@ -6,31 +6,69 @@ import ( "github.com/pkg/errors" "github.com/rs/zerolog/log" "regexp" - "strings" + "strconv" ) type Filter interface { - applySNMP(ctx context.Context, reader snmpReader) (snmpReader, error) -} + ApplyPropertyGroups(context.Context, PropertyGroups) (PropertyGroups, error) -type GroupFilter interface { - GetFilterProperties() (string, string) + applySNMP(context.Context, snmpReader) (snmpReader, error) } type groupFilter struct { - key string + key []string regex string } -func GetGroupFilter(key, regex string) Filter { +func GetGroupFilter(key []string, regex string) Filter { return &groupFilter{ key: key, regex: regex, } } -func (g *groupFilter) GetFilterProperties() (string, string) { - return g.key, g.regex +func (g *groupFilter) ApplyPropertyGroups(ctx context.Context, propertyGroups PropertyGroups) (PropertyGroups, error) { + var res PropertyGroups + + // compile filter regex + regex, err := regexp.Compile(g.regex) + if err != nil { + return nil, errors.Wrap(err, "filter regex failed to compile") + } + +out: + for i, group := range propertyGroups { + currentGroup := group + + for i, attr := range g.key { + if next, ok := currentGroup[attr]; ok { + if i == len(g.key)-1 { + break + } + var nextGroup propertyGroup + err = nextGroup.encode(next) + if err != nil { + return nil, errors.Wrap(err, "failed to encode next filter key value to property group") + } + currentGroup = nextGroup + } else { + // current interface does not have the filter key so skip it + res = append(res, group) + continue out + } + } + + v := currentGroup[g.key[len(g.key)-1]] + if vString := value.New(v).String(); regex.MatchString(vString) { + log.Ctx(ctx).Debug().Strs("filter_key", g.key).Str("filter_regex", g.regex). + Str("received_value", vString). + Msgf("filter matched on index '%s' of property group", strconv.Itoa(i)) + } else { + res = append(res, group) + } + } + + return res, nil } func (g *groupFilter) applySNMP(ctx context.Context, reader snmpReader) (snmpReader, error) { @@ -39,9 +77,9 @@ func (g *groupFilter) applySNMP(ctx context.Context, reader snmpReader) (snmpRea reader.wantedIndices, err = reader.getIndices(ctx) if err != nil { log.Ctx(ctx).Debug().Err(err).Msg("failed to read indices, ignoring index oid") - } } + // TODO copy maps if reader.wantedIndices == nil { reader.wantedIndices = make(map[string]struct{}) } @@ -56,9 +94,8 @@ func (g *groupFilter) applySNMP(ctx context.Context, reader snmpReader) (snmpRea } // find filter oid - attrs := strings.Split(g.key, "/") oidReader := reader.oids - for _, attr := range attrs { + for _, attr := range g.key { // check if current oid reader contains multiple OIDs multipleReader, ok := oidReader.(*deviceClassOIDs) if !ok || multipleReader == nil { @@ -88,7 +125,7 @@ func (g *groupFilter) applySNMP(ctx context.Context, reader snmpReader) (snmpRea // if filter matches add to filtered indices map and delete from wanted indices reader.filteredIndices[index] = struct{}{} delete(reader.wantedIndices, index) - log.Ctx(ctx).Debug().Str("filter_key", g.key).Str("filter_regex", g.regex). + log.Ctx(ctx).Debug().Strs("filter_key", g.key).Str("filter_regex", g.regex). Str("received_value", result.(value.Value).String()). Msgf("filter matched on index '%s'", index) } else { @@ -104,58 +141,117 @@ func (g *groupFilter) applySNMP(ctx context.Context, reader snmpReader) (snmpRea } type ValueFilter interface { - GetFilterProperties() string + CheckMatch([]string) bool } type valueFilter struct { - value string + value []string } -func GetValueFilter(value string) Filter { +func GetValueFilter(value []string) Filter { return &valueFilter{ value: value, } } -func (g *valueFilter) GetFilterProperties() string { - return g.value +func (g *valueFilter) CheckMatch(value []string) bool { + for i, k := range value { + if i == len(g.value) { + return false + } + if k != g.value[i] { + return false + } + } + return true } -func (g *valueFilter) applySNMP(ctx context.Context, reader snmpReader) (snmpReader, error) { - var recursiveAnonymous func(OIDReader, []string) (OIDReader, error) - recursiveAnonymous = func(currentReader OIDReader, key []string) (OIDReader, error) { - // check if current oid reader contains multiple OIDs - multipleReader, ok := currentReader.(*deviceClassOIDs) - if !ok || multipleReader == nil { - return nil, errors.New("filter attribute does not exist") - } +func (g *valueFilter) ApplyPropertyGroups(ctx context.Context, propertyGroups PropertyGroups) (PropertyGroups, error) { + var res PropertyGroups - //copy values - readerCopy := make(deviceClassOIDs) - for k, v := range *multipleReader { - if k == key[0] { - if len(key) > 1 { - r, err := recursiveAnonymous(v, key[1:]) - if err != nil { - return nil, err - } - readerCopy[k] = r - } else { - log.Ctx(ctx).Debug().Str("value", k).Msg("filter matched on value in snmpReader") - } - continue - } - readerCopy[k] = v + for _, group := range propertyGroups { + newGroup, err := filterPropertyGroupKey(ctx, group, g.value, func(a, b string) bool { + return a == b + }) + if err != nil { + return nil, errors.Wrap(err, "failed to filter group property") } - - return &readerCopy, nil + res = append(res, newGroup) } + return res, nil +} + +func (g *valueFilter) applySNMP(ctx context.Context, reader snmpReader) (snmpReader, error) { var err error - attrs := strings.Split(g.value, "/") - reader.oids, err = recursiveAnonymous(reader.oids, attrs) + reader.oids, err = filterOIDReaderKey(ctx, reader.oids, g.value, func(a, b string) bool { + return a == b + }) if err != nil { return snmpReader{}, err } return reader, nil } + +func filterPropertyGroupKey(ctx context.Context, group propertyGroup, key []string, compareFunc func(a, b string) bool) (propertyGroup, error) { + if len(key) == 0 { + return nil, errors.New("filter key is empty") + } + + //copy values + groupCopy := make(propertyGroup) + for k, v := range group { + if compareFunc(k, key[0]) { + if len(key) > 1 { + var nextGroup propertyGroup + err := nextGroup.encode(v) + if err != nil { + return nil, errors.Wrap(err, "failed to encode next filter key value to property group") + } + r, err := filterPropertyGroupKey(ctx, nextGroup, key[1:], compareFunc) + if err != nil { + return nil, err + } + groupCopy[k] = r + } else { + log.Ctx(ctx).Debug().Str("value", k).Msg("filter matched on value in property group") + } + continue + } + groupCopy[k] = v + } + + return groupCopy, nil +} + +func filterOIDReaderKey(ctx context.Context, reader OIDReader, key []string, compareFunc func(a, b string) bool) (OIDReader, error) { + if len(key) == 0 { + return nil, errors.New("filter key is empty") + } + + // check if current oid reader contains multiple OIDs + multipleReader, ok := reader.(*deviceClassOIDs) + if !ok || multipleReader == nil { + return nil, errors.New("filter attribute does not exist") + } + + //copy values + readerCopy := make(deviceClassOIDs) + for k, v := range *multipleReader { + if compareFunc(k, key[0]) { + if len(key) > 1 { + r, err := filterOIDReaderKey(ctx, v, key[1:], compareFunc) + if err != nil { + return nil, err + } + readerCopy[k] = r + } else { + log.Ctx(ctx).Debug().Str("value", k).Msg("filter matched on value in snmp reader") + } + continue + } + readerCopy[k] = v + } + + return &readerCopy, nil +} diff --git a/internal/deviceclass/groupproperty/reader.go b/internal/deviceclass/groupproperty/reader.go index 6ea1208..412ec44 100644 --- a/internal/deviceclass/groupproperty/reader.go +++ b/internal/deviceclass/groupproperty/reader.go @@ -102,12 +102,24 @@ func Interface2Reader(i interface{}, parentReader Reader) (Reader, error) { type propertyGroup map[string]interface{} +func (g *propertyGroup) decode(destination interface{}) error { + return mapstructure.WeakDecode(g, destination) +} + +func (g *propertyGroup) encode(data interface{}) error { + return mapstructure.WeakDecode(data, g) +} + type PropertyGroups []propertyGroup func (g *PropertyGroups) Decode(destination interface{}) error { return mapstructure.WeakDecode(g, destination) } +func (g *PropertyGroups) Encode(data interface{}) error { + return mapstructure.WeakDecode(data, g) +} + type Reader interface { GetProperty(ctx context.Context, filter ...Filter) (PropertyGroups, []value.Value, error) } diff --git a/internal/request/check_interface_metrics_request_process.go b/internal/request/check_interface_metrics_request_process.go index e2c0c07..4589e70 100644 --- a/internal/request/check_interface_metrics_request_process.go +++ b/internal/request/check_interface_metrics_request_process.go @@ -106,16 +106,16 @@ func (r *CheckInterfaceMetricsRequest) getFilter() []groupproperty.Filter { var res []groupproperty.Filter for _, f := range r.IfTypeFilter { - res = append(res, groupproperty.GetGroupFilter("ifType", f)) + res = append(res, groupproperty.GetGroupFilter([]string{"ifType"}, f)) } for _, f := range r.IfNameFilter { - res = append(res, groupproperty.GetGroupFilter("ifName", f)) + res = append(res, groupproperty.GetGroupFilter([]string{"ifName"}, f)) } for _, f := range r.IfDescrFilter { - res = append(res, groupproperty.GetGroupFilter("ifDescr", f)) + res = append(res, groupproperty.GetGroupFilter([]string{"ifDescr"}, f)) } - res = append(res, groupproperty.GetValueFilter("vlan")) + res = append(res, groupproperty.GetValueFilter([]string{"vlan"})) return res } diff --git a/internal/value/value.go b/internal/value/value.go index fc237c2..55f69b4 100644 --- a/internal/value/value.go +++ b/internal/value/value.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/pkg/errors" "math/big" + "reflect" "strconv" ) @@ -36,7 +37,12 @@ func New(i interface{}) Value { case nil: v = "" default: - v = value(fmt.Sprint(t)) + switch val := reflect.ValueOf(i); val.Kind() { + case reflect.Ptr: + return New(reflect.Indirect(val).Interface()) + default: + v = value(fmt.Sprint(t)) + } } return v } From 59f9ed547c12b689dfa17826b9b61a35786e7620 Mon Sep 17 00:00:00 2001 From: mikameyer Date: Mon, 18 Oct 2021 12:03:33 +0200 Subject: [PATCH 2/8] fixed tests --- internal/deviceclass/groupproperty/reader_test.go | 4 ++-- test/integration_test.go | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/internal/deviceclass/groupproperty/reader_test.go b/internal/deviceclass/groupproperty/reader_test.go index c1ba064..0343bae 100644 --- a/internal/deviceclass/groupproperty/reader_test.go +++ b/internal/deviceclass/groupproperty/reader_test.go @@ -483,7 +483,7 @@ func TestSNMPReader_getProperty_filter(t *testing.T) { } res, indices, err := sut.GetProperty(ctx, &groupFilter{ - key: "ifDescr", + key: []string{"ifDescr"}, regex: "2", }) if assert.NoError(t, err) { @@ -638,7 +638,7 @@ func TestSNMPReader_getProperty_getsInsteadOfWalkFilter(t *testing.T) { } res, indices, err := sut.GetProperty(ctx, &groupFilter{ - key: "ifDescr", + key: []string{"ifDescr"}, regex: "2", }) if assert.NoError(t, err) { diff --git a/test/integration_test.go b/test/integration_test.go index 499e6e2..f8561e3 100644 --- a/test/integration_test.go +++ b/test/integration_test.go @@ -96,6 +96,10 @@ func init() { } func TestIntegration(t *testing.T) { + if testing.Short() { + t.Skip("skipping integration tests in short mode") + } + if !testConf.SimpleUI { _, _ = colorstring.Println("[cyan][1/3][reset] Building up test environment...") } From 19c3f9c8d75ee0d080700d8464e979ef0a57044a Mon Sep 17 00:00:00 2001 From: mikameyer Date: Mon, 18 Oct 2021 12:12:51 +0200 Subject: [PATCH 3/8] bump echo version --- go.mod | 4 ++-- go.sum | 37 +++++++++++++++++++++++-------------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/go.mod b/go.mod index 119975f..beff8c5 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/gosnmp/gosnmp v1.30.0 github.com/inexio/go-monitoringplugin v1.0.11 github.com/jmoiron/sqlx v1.2.0 - github.com/labstack/echo/v4 v4.2.1 + github.com/labstack/echo/v4 v4.6.1 github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db github.com/mitchellh/mapstructure v1.3.3 github.com/pkg/errors v0.9.1 @@ -25,6 +25,6 @@ require ( github.com/spf13/viper v1.7.1 github.com/stretchr/testify v1.7.0 github.com/ulule/limiter/v3 v3.5.0 - golang.org/x/text v0.3.3 + golang.org/x/text v0.3.7 gopkg.in/yaml.v2 v2.3.0 ) diff --git a/go.sum b/go.sum index 52c01f9..d887153 100644 --- a/go.sum +++ b/go.sum @@ -48,7 +48,6 @@ github.com/dgraph-io/badger/v2 v2.2007.2 h1:EjjK0KqwaFMlPin1ajhP943VPENHJdEz1KLI github.com/dgraph-io/badger/v2 v2.2007.2/go.mod h1:26P/7fbL4kUZVEVKLAKXkBXKOydDmM2p1e+NhhnBCAE= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de h1:t0UHb5vdojIDUqktM6+xJAfScFBsVpXZmqC9dsgJmeA= github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= @@ -80,6 +79,8 @@ github.com/gocarina/gocsv v0.0.0-20210516172204-ca9e8a8ddea8 h1:hp1oqdzmv37vPLYF github.com/gocarina/gocsv v0.0.0-20210516172204-ca9e8a8ddea8/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -165,8 +166,8 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/labstack/echo/v4 v4.2.1 h1:LF5Iq7t/jrtUuSutNuiEWtB5eiHfZ5gSe2pcu5exjQw= -github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= +github.com/labstack/echo/v4 v4.6.1 h1:OMVsrnNFzYlGSdaiYGHbgWQnr+JM7NG+B9suCPie14M= +github.com/labstack/echo/v4 v4.6.1/go.mod h1:RnjgMWNDB9g/HucVWhQYNQP9PvbYf6adqftqryo7s9k= github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= @@ -177,13 +178,14 @@ github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzR github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.7 h1:bQGKb3vps/j0E9GfJQ03JyhRuxsvdAanXlT9BTw3mdw= -github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/4= @@ -310,9 +312,8 @@ golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM= -golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -350,8 +351,9 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210913180222-943fd674d43e h1:+b/22bPvDYt4NPDcy4xAGCmON713ONAWFeY3Z7I3tR8= +golang.org/x/net v0.0.0-20210913180222-943fd674d43e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -383,13 +385,20 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6 h1:DvY3Zkh7KabQE/kfzMvYvKirSiguP9Q/veMtkYyf0o8= -golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0 h1:xrCZDmdtoloIiooiA9q0OQb9r8HejIHYoHGhGCe1pGg= +golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 h1:Hir2P/De0WpUhtrKGGjvSb2YxUgyZ7EFOSLIcSSpiwE= From 65739346631099d713171b8ecfb09d421c3ec8f6 Mon Sep 17 00:00:00 2001 From: mikameyer Date: Mon, 18 Oct 2021 14:50:10 +0200 Subject: [PATCH 4/8] added filter tests --- .../deviceclass/groupproperty/filter_test.go | 464 ++++++++++++++++++ ...check_interface_metrics_request_process.go | 23 +- 2 files changed, 476 insertions(+), 11 deletions(-) create mode 100644 internal/deviceclass/groupproperty/filter_test.go diff --git a/internal/deviceclass/groupproperty/filter_test.go b/internal/deviceclass/groupproperty/filter_test.go new file mode 100644 index 0000000..0766ef7 --- /dev/null +++ b/internal/deviceclass/groupproperty/filter_test.go @@ -0,0 +1,464 @@ +package groupproperty + +import ( + "context" + "github.com/gosnmp/gosnmp" + "github.com/inexio/thola/internal/network" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestGroupFilter_ApplyPropertyGroups(t *testing.T) { + filter := GetGroupFilter([]string{"ifDescr"}, "Ethernet .*") + + groups := PropertyGroups{ + propertyGroup{ + "ifIndex": "1", + "ifDescr": "Ethernet #1", + }, + propertyGroup{ + "ifIndex": "2", + "ifDescr": "Mgmt", + }, + } + + filteredGroup, err := filter.ApplyPropertyGroups(context.Background(), groups) + assert.NoError(t, err) + + expected := PropertyGroups{ + propertyGroup{ + "ifIndex": "2", + "ifDescr": "Mgmt", + }, + } + + assert.Equal(t, expected, filteredGroup) +} + +func TestGroupFilter_ApplyPropertyGroups_noMatch(t *testing.T) { + filter := GetGroupFilter([]string{"ifDescr"}, "Ethernet #2") + + groups := PropertyGroups{ + propertyGroup{ + "ifIndex": "1", + "ifDescr": "Ethernet #1", + }, + propertyGroup{ + "ifIndex": "2", + "ifDescr": "Mgmt", + }, + } + + filteredGroup, err := filter.ApplyPropertyGroups(context.Background(), groups) + assert.NoError(t, err) + + assert.Equal(t, groups, filteredGroup) +} + +func TestGroupFilter_ApplyPropertyGroups_nested(t *testing.T) { + filter := GetGroupFilter([]string{"radio", "level_in"}, "10") + + groups := PropertyGroups{ + propertyGroup{ + "ifIndex": "1", + "ifDescr": "Ethernet #1", + "radio": propertyGroup{ + "level_in": "10", + }, + }, + propertyGroup{ + "ifIndex": "2", + "ifDescr": "Mgmt", + }, + } + + filteredGroup, err := filter.ApplyPropertyGroups(context.Background(), groups) + assert.NoError(t, err) + + expected := PropertyGroups{ + propertyGroup{ + "ifIndex": "2", + "ifDescr": "Mgmt", + }, + } + + assert.Equal(t, expected, filteredGroup) +} + +func TestGroupFilter_applySNMP(t *testing.T) { + filter := GetGroupFilter([]string{"ifDescr"}, "Ethernet .*") + + var snmpClient network.MockSNMPClient + ctx := network.NewContextWithDeviceConnection(context.Background(), &network.RequestDeviceConnection{ + SNMP: &network.RequestDeviceConnectionSNMP{ + SnmpClient: &snmpClient, + }, + }) + + snmpClient. + On("SNMPWalk", ctx, network.OID("1")). + Return([]network.SNMPResponse{ + network.NewSNMPResponse("1.1", gosnmp.OctetString, "Ethernet #1"), + network.NewSNMPResponse("1.2", gosnmp.OctetString, "Mgmt"), + }, nil) + + reader := snmpReader{ + oids: &deviceClassOIDs{ + "ifDescr": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "1", + }, + }, + }, + } + + filteredGroup, err := filter.applySNMP(ctx, reader) + assert.NoError(t, err) + + expected := snmpReader{ + wantedIndices: map[string]struct{}{ + "2": {}, + }, + filteredIndices: map[string]struct{}{ + "1": {}, + }, + oids: &deviceClassOIDs{ + "ifDescr": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "1", + }, + }, + }, + } + + assert.Equal(t, expected, filteredGroup) +} + +func TestGroupFilter_applySNMP_nested(t *testing.T) { + filter := GetGroupFilter([]string{"radio", "level_in"}, "10") + + var snmpClient network.MockSNMPClient + ctx := network.NewContextWithDeviceConnection(context.Background(), &network.RequestDeviceConnection{ + SNMP: &network.RequestDeviceConnectionSNMP{ + SnmpClient: &snmpClient, + }, + }) + + snmpClient. + On("SNMPWalk", ctx, network.OID("1")). + Return([]network.SNMPResponse{ + network.NewSNMPResponse("1.1", gosnmp.OctetString, "Ethernet #1"), + network.NewSNMPResponse("1.2", gosnmp.OctetString, "Mgmt"), + }, nil). + On("SNMPWalk", ctx, network.OID("2")). + Return([]network.SNMPResponse{ + network.NewSNMPResponse("2.1", gosnmp.OctetString, "10"), + network.NewSNMPResponse("2.2", gosnmp.OctetString, "7"), + }, nil) + + reader := snmpReader{ + oids: &deviceClassOIDs{ + "ifDescr": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "1", + }, + }, + "radio": &deviceClassOIDs{ + "level_in": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "2", + }, + }, + }, + }, + } + + filteredGroup, err := filter.applySNMP(ctx, reader) + assert.NoError(t, err) + + expected := snmpReader{ + wantedIndices: map[string]struct{}{ + "2": {}, + }, + filteredIndices: map[string]struct{}{ + "1": {}, + }, + oids: &deviceClassOIDs{ + "ifDescr": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "1", + }, + }, + "radio": &deviceClassOIDs{ + "level_in": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "2", + }, + }, + }, + }, + } + + assert.Equal(t, expected, filteredGroup) +} + +func TestGroupFilter_applySNMP_noMatch(t *testing.T) { + filter := GetGroupFilter([]string{"ifDescr"}, "Ethernet #3") + + var snmpClient network.MockSNMPClient + ctx := network.NewContextWithDeviceConnection(context.Background(), &network.RequestDeviceConnection{ + SNMP: &network.RequestDeviceConnectionSNMP{ + SnmpClient: &snmpClient, + }, + }) + + snmpClient. + On("SNMPWalk", ctx, network.OID("1")). + Return([]network.SNMPResponse{ + network.NewSNMPResponse("1.1", gosnmp.OctetString, "Ethernet #1"), + network.NewSNMPResponse("1.2", gosnmp.OctetString, "Mgmt"), + }, nil) + + reader := snmpReader{ + oids: &deviceClassOIDs{ + "ifDescr": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "1", + }, + }, + }, + } + + filteredGroup, err := filter.applySNMP(ctx, reader) + assert.NoError(t, err) + + expected := snmpReader{ + wantedIndices: map[string]struct{}{ + "1": {}, + "2": {}, + }, + filteredIndices: map[string]struct{}{}, + oids: &deviceClassOIDs{ + "ifDescr": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "1", + }, + }, + }, + } + + assert.Equal(t, expected, filteredGroup) +} + +func TestValueFilter_CheckMatch(t *testing.T) { + valueFilter := GetValueFilter([]string{"radio", "level_in"}) + + filter, ok := valueFilter.(ValueFilter) + assert.True(t, ok, "value filter is not implementing the ValueFilter interface") + + assert.True(t, filter.CheckMatch([]string{"radio"})) + assert.False(t, filter.CheckMatch([]string{"ifDescr"})) + assert.True(t, filter.CheckMatch([]string{"radio", "level_in"})) + assert.False(t, filter.CheckMatch([]string{"radio", "level_out"})) +} + +func TestValueFilter_ApplyPropertyGroups(t *testing.T) { + filter := GetValueFilter([]string{"ifDescr"}) + + groups := PropertyGroups{ + propertyGroup{ + "ifIndex": "1", + "ifDescr": "Ethernet #1", + }, + } + + filteredGroup, err := filter.ApplyPropertyGroups(context.Background(), groups) + assert.NoError(t, err) + + expected := PropertyGroups{ + propertyGroup{ + "ifIndex": "1", + }, + } + + assert.Equal(t, expected, filteredGroup) +} + +func TestValueFilter_ApplyPropertyGroups_noMatch(t *testing.T) { + filter := GetValueFilter([]string{"ifOperStatus"}) + + groups := PropertyGroups{ + propertyGroup{ + "ifIndex": "1", + "ifDescr": "Ethernet #1", + }, + } + + filteredGroup, err := filter.ApplyPropertyGroups(context.Background(), groups) + assert.NoError(t, err) + + assert.Equal(t, groups, filteredGroup) +} + +func TestValueFilter_ApplyPropertyGroups_nested(t *testing.T) { + filter := GetValueFilter([]string{"radio", "level_in"}) + + groups := PropertyGroups{ + propertyGroup{ + "ifIndex": "1", + "ifDescr": "Ethernet #1", + "radio": propertyGroup{ + "level_in": "10", + "level_out": "10", + }, + }, + } + + filteredGroup, err := filter.ApplyPropertyGroups(context.Background(), groups) + assert.NoError(t, err) + + expected := PropertyGroups{ + propertyGroup{ + "ifIndex": "1", + "ifDescr": "Ethernet #1", + "radio": propertyGroup{ + "level_out": "10", + }, + }, + } + + assert.Equal(t, expected, filteredGroup) +} + +func TestValueFilter_ApplyPropertyGroups_nestedWholeMatch(t *testing.T) { + filter := GetValueFilter([]string{"radio"}) + + groups := PropertyGroups{ + propertyGroup{ + "ifIndex": "1", + "ifDescr": "Ethernet #1", + "radio": propertyGroup{ + "level_in": "10", + "level_out": "10", + }, + }, + } + + filteredGroup, err := filter.ApplyPropertyGroups(context.Background(), groups) + assert.NoError(t, err) + + expected := PropertyGroups{ + propertyGroup{ + "ifIndex": "1", + "ifDescr": "Ethernet #1", + }, + } + + assert.Equal(t, expected, filteredGroup) +} + +func TestValueFilter_applySNMP(t *testing.T) { + filter := GetValueFilter([]string{"ifOperStatus"}) + + reader := snmpReader{ + oids: &deviceClassOIDs{ + "ifDescr": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "1", + }, + }, + "ifOperStatus": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "2", + }, + }, + }, + } + + filteredGroup, err := filter.applySNMP(context.Background(), reader) + assert.NoError(t, err) + + expected := snmpReader{ + oids: &deviceClassOIDs{ + "ifDescr": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "1", + }, + }, + }, + } + + assert.Equal(t, expected, filteredGroup) +} + +func TestValueFilter_applySNMP_nested(t *testing.T) { + filter := GetValueFilter([]string{"radio", "level_in"}) + + reader := snmpReader{ + oids: &deviceClassOIDs{ + "ifDescr": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "1", + }, + }, + "radio": &deviceClassOIDs{ + "level_in": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "2", + }, + }, + "level_out": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "3", + }, + }, + }, + }, + } + + filteredGroup, err := filter.applySNMP(context.Background(), reader) + assert.NoError(t, err) + + expected := snmpReader{ + oids: &deviceClassOIDs{ + "ifDescr": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "1", + }, + }, + "radio": &deviceClassOIDs{ + "level_out": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "3", + }, + }, + }, + }, + } + + assert.Equal(t, expected, filteredGroup) +} + +func TestValueFilter_applySNMP_noMatch(t *testing.T) { + filter := GetValueFilter([]string{"ifSpeed"}) + + reader := snmpReader{ + oids: &deviceClassOIDs{ + "ifDescr": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "1", + }, + }, + "ifOperStatus": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "2", + }, + }, + }, + } + + filteredGroup, err := filter.applySNMP(context.Background(), reader) + assert.NoError(t, err) + + assert.Equal(t, reader, filteredGroup) +} diff --git a/internal/request/check_interface_metrics_request_process.go b/internal/request/check_interface_metrics_request_process.go index 4589e70..b08216d 100644 --- a/internal/request/check_interface_metrics_request_process.go +++ b/internal/request/check_interface_metrics_request_process.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package request @@ -14,17 +15,17 @@ import ( ) type interfaceCheckOutput struct { - IfIndex *string `json:"ifIndex" csv:"ifIndex"` - IfDescr *string `json:"ifDescr" csv:"ifDescr"` - IfType *string `json:"ifType" csv:"ifType"` - IfName *string `json:"ifName" csv:"ifName"` - IfAlias *string `json:"ifAlias" csv:"ifAlias"` - IfPhysAddress *string `json:"ifPhysAddress" csv:"ifPhysAddress"` - IfAdminStatus *string `json:"ifAdminStatus" csv:"ifAdminStatus"` - IfOperStatus *string `json:"ifOperStatus" csv:"ifOperStatus"` - MaxSpeedIn *string `json:"maxSpeedIn" csv:"maxSpeedIn"` - MaxSpeedOut *string `json:"maxSpeedOut" csv:"maxSpeedOut"` - SubType *string `json:"subType" csv:"subType"` + IfIndex *string `csv:"ifIndex"` + IfDescr *string `csv:"ifDescr"` + IfType *string `csv:"ifType"` + IfName *string `csv:"ifName"` + IfAlias *string `csv:"ifAlias"` + IfPhysAddress *string `csv:"ifPhysAddress"` + IfAdminStatus *string `csv:"ifAdminStatus"` + IfOperStatus *string `csv:"ifOperStatus"` + MaxSpeedIn *string `csv:"maxSpeedIn"` + MaxSpeedOut *string `csv:"maxSpeedOut"` + SubType *string `csv:"subType"` } func (r *CheckInterfaceMetricsRequest) process(ctx context.Context) (Response, error) { From 04cb2d659b09b72e98522c24625fc2fab9071418 Mon Sep 17 00:00:00 2001 From: mikameyer Date: Tue, 19 Oct 2021 09:06:49 +0200 Subject: [PATCH 5/8] added exclusive value filter --- internal/deviceclass/groupproperty/filter.go | 97 ++++++-- .../deviceclass/groupproperty/filter_test.go | 220 ++++++++++++++++++ internal/deviceclass/groupproperty/reader.go | 20 ++ .../deviceclass/groupproperty/reader_test.go | 35 +++ 4 files changed, 356 insertions(+), 16 deletions(-) diff --git a/internal/deviceclass/groupproperty/filter.go b/internal/deviceclass/groupproperty/filter.go index 7ff15d4..8ef3b87 100644 --- a/internal/deviceclass/groupproperty/filter.go +++ b/internal/deviceclass/groupproperty/filter.go @@ -170,8 +170,8 @@ func (g *valueFilter) ApplyPropertyGroups(ctx context.Context, propertyGroups Pr var res PropertyGroups for _, group := range propertyGroups { - newGroup, err := filterPropertyGroupKey(ctx, group, g.value, func(a, b string) bool { - return a == b + newGroup, err := filterPropertyGroupKey(ctx, group, g.value, func(val string, key []string) (bool, bool) { + return val == key[0], len(key) == 1 }) if err != nil { return nil, errors.Wrap(err, "failed to filter group property") @@ -184,8 +184,8 @@ func (g *valueFilter) ApplyPropertyGroups(ctx context.Context, propertyGroups Pr func (g *valueFilter) applySNMP(ctx context.Context, reader snmpReader) (snmpReader, error) { var err error - reader.oids, err = filterOIDReaderKey(ctx, reader.oids, g.value, func(a, b string) bool { - return a == b + reader.oids, err = filterOIDReaderKey(ctx, reader.oids, g.value, func(val string, key []string) (bool, bool) { + return val == key[0], len(key) == 1 }) if err != nil { return snmpReader{}, err @@ -193,7 +193,72 @@ func (g *valueFilter) applySNMP(ctx context.Context, reader snmpReader) (snmpRea return reader, nil } -func filterPropertyGroupKey(ctx context.Context, group propertyGroup, key []string, compareFunc func(a, b string) bool) (propertyGroup, error) { +type exclusiveValueFilter struct { + values [][]string +} + +func GetExclusiveValueFilter(values [][]string) Filter { + return &exclusiveValueFilter{ + values: values, + } +} + +func (g *exclusiveValueFilter) CheckMatch(value []string) bool { + for _, val := range g.values { + for i, k := range value { + if i >= len(val) || k != val[i] { + continue + } + if i == len(val)-1 && k == val[i] { + return false + } + } + } + return true +} + +func (g *exclusiveValueFilter) ApplyPropertyGroups(ctx context.Context, propertyGroups PropertyGroups) (PropertyGroups, error) { + var res PropertyGroups + + for _, group := range propertyGroups { + newGroup := make(propertyGroup) + for _, k := range g.values { + exclusiveGroup, err := filterPropertyGroupKey(ctx, group, k, func(val string, key []string) (bool, bool) { + return !(val == key[0] && len(key) == 1), !(val == key[0]) + }) + if err != nil { + return nil, errors.Wrap(err, "failed to filter group property") + } + newGroup = newGroup.merge(exclusiveGroup) + } + res = append(res, newGroup) + } + + return res, nil +} + +func (g *exclusiveValueFilter) applySNMP(ctx context.Context, reader snmpReader) (snmpReader, error) { + res := reader + oids := make(deviceClassOIDs) + res.oids = &oids + + for _, k := range g.values { + tmp, err := filterOIDReaderKey(ctx, reader.oids, k, func(val string, key []string) (bool, bool) { + return !(val == key[0] && len(key) == 1), !(val == key[0]) + }) + if err != nil { + return snmpReader{}, err + } + + if tmpConverted, ok := tmp.(*deviceClassOIDs); ok { + oids = oids.merge(*tmpConverted) + } + } + + return res, nil +} + +func filterPropertyGroupKey(ctx context.Context, group propertyGroup, key []string, matcher func(string, []string) (bool, bool)) (propertyGroup, error) { if len(key) == 0 { return nil, errors.New("filter key is empty") } @@ -201,20 +266,20 @@ func filterPropertyGroupKey(ctx context.Context, group propertyGroup, key []stri //copy values groupCopy := make(propertyGroup) for k, v := range group { - if compareFunc(k, key[0]) { - if len(key) > 1 { + if match, del := matcher(k, key); match { + if del { + log.Ctx(ctx).Debug().Str("value", k).Msg("filter matched on value in property group") + } else { var nextGroup propertyGroup err := nextGroup.encode(v) if err != nil { return nil, errors.Wrap(err, "failed to encode next filter key value to property group") } - r, err := filterPropertyGroupKey(ctx, nextGroup, key[1:], compareFunc) + r, err := filterPropertyGroupKey(ctx, nextGroup, key[1:], matcher) if err != nil { return nil, err } groupCopy[k] = r - } else { - log.Ctx(ctx).Debug().Str("value", k).Msg("filter matched on value in property group") } continue } @@ -224,7 +289,7 @@ func filterPropertyGroupKey(ctx context.Context, group propertyGroup, key []stri return groupCopy, nil } -func filterOIDReaderKey(ctx context.Context, reader OIDReader, key []string, compareFunc func(a, b string) bool) (OIDReader, error) { +func filterOIDReaderKey(ctx context.Context, reader OIDReader, key []string, matcher func(string, []string) (bool, bool)) (OIDReader, error) { if len(key) == 0 { return nil, errors.New("filter key is empty") } @@ -238,15 +303,15 @@ func filterOIDReaderKey(ctx context.Context, reader OIDReader, key []string, com //copy values readerCopy := make(deviceClassOIDs) for k, v := range *multipleReader { - if compareFunc(k, key[0]) { - if len(key) > 1 { - r, err := filterOIDReaderKey(ctx, v, key[1:], compareFunc) + if match, del := matcher(k, key); match { + if del { + log.Ctx(ctx).Debug().Str("value", k).Msg("filter matched on value in snmp reader") + } else { + r, err := filterOIDReaderKey(ctx, v, key[1:], matcher) if err != nil { return nil, err } readerCopy[k] = r - } else { - log.Ctx(ctx).Debug().Str("value", k).Msg("filter matched on value in snmp reader") } continue } diff --git a/internal/deviceclass/groupproperty/filter_test.go b/internal/deviceclass/groupproperty/filter_test.go index 0766ef7..a4c7525 100644 --- a/internal/deviceclass/groupproperty/filter_test.go +++ b/internal/deviceclass/groupproperty/filter_test.go @@ -462,3 +462,223 @@ func TestValueFilter_applySNMP_noMatch(t *testing.T) { assert.Equal(t, reader, filteredGroup) } + +func TestExclusiveValueFilter_CheckMatch(t *testing.T) { + valueFilter := GetExclusiveValueFilter([][]string{{"radio", "level_in"}}) + + filter, ok := valueFilter.(ValueFilter) + assert.True(t, ok, "exclusive value filter is not implementing the ValueFilter interface") + + assert.True(t, filter.CheckMatch([]string{"radio"})) + assert.True(t, filter.CheckMatch([]string{"ifDescr"})) + assert.True(t, filter.CheckMatch([]string{"radio", "level_out"})) + assert.False(t, filter.CheckMatch([]string{"radio", "level_in"})) + assert.False(t, filter.CheckMatch([]string{"radio", "level_in", "test"})) +} + +func TestExclusiveValueFilter_ApplyPropertyGroups(t *testing.T) { + filter := GetExclusiveValueFilter([][]string{{"ifDescr"}}) + + groups := PropertyGroups{ + propertyGroup{ + "ifIndex": "1", + "ifDescr": "Ethernet #1", + "ifOperStatus": "1", + }, + } + + filteredGroup, err := filter.ApplyPropertyGroups(context.Background(), groups) + assert.NoError(t, err) + + expected := PropertyGroups{ + propertyGroup{ + "ifDescr": "Ethernet #1", + }, + } + + assert.Equal(t, expected, filteredGroup) +} + +func TestExclusiveValueFilter_ApplyPropertyGroups_multiple(t *testing.T) { + filter := GetExclusiveValueFilter([][]string{{"ifIndex"}, {"ifDescr"}}) + + groups := PropertyGroups{ + propertyGroup{ + "ifIndex": "1", + "ifDescr": "Ethernet #1", + "ifOperStatus": "1", + }, + } + + filteredGroup, err := filter.ApplyPropertyGroups(context.Background(), groups) + assert.NoError(t, err) + + expected := PropertyGroups{ + propertyGroup{ + "ifIndex": "1", + "ifDescr": "Ethernet #1", + }, + } + + assert.Equal(t, expected, filteredGroup) +} + +func TestExclusiveValueFilter_ApplyPropertyGroups_nested(t *testing.T) { + filter := GetExclusiveValueFilter([][]string{{"radio", "level_in"}}) + + groups := PropertyGroups{ + propertyGroup{ + "ifIndex": "1", + "radio": propertyGroup{ + "level_in": "10", + }, + }, + } + + filteredGroup, err := filter.ApplyPropertyGroups(context.Background(), groups) + assert.NoError(t, err) + + expected := PropertyGroups{ + propertyGroup{ + "radio": propertyGroup{ + "level_in": "10", + }, + }, + } + + assert.Equal(t, expected, filteredGroup) +} + +func TestExclusiveValueFilter_ApplyPropertyGroups_multipleNested(t *testing.T) { + filter := GetExclusiveValueFilter([][]string{{"radio", "level_in"}, {"radio", "level_out"}}) + + groups := PropertyGroups{ + propertyGroup{ + "ifIndex": "1", + "radio": propertyGroup{ + "level_in": "10", + "level_out": "10", + "max_bitrate_in": "100000", + }, + }, + } + + filteredGroup, err := filter.ApplyPropertyGroups(context.Background(), groups) + assert.NoError(t, err) + + expected := PropertyGroups{ + propertyGroup{ + "radio": propertyGroup{ + "level_in": "10", + "level_out": "10", + }, + }, + } + + assert.Equal(t, expected, filteredGroup) +} + +func TestExclusiveValueFilter_applySNMP(t *testing.T) { + filter := GetExclusiveValueFilter([][]string{{"ifDescr"}}) + + reader := snmpReader{ + oids: &deviceClassOIDs{ + "ifDescr": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "1", + }, + }, + "ifOperStatus": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "2", + }, + }, + }, + } + + filteredGroup, err := filter.applySNMP(context.Background(), reader) + assert.NoError(t, err) + + expected := snmpReader{ + oids: &deviceClassOIDs{ + "ifDescr": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "1", + }, + }, + }, + } + + assert.Equal(t, expected, filteredGroup) +} + +func TestExclusiveValueFilter_applySNMP_nested(t *testing.T) { + filter := GetExclusiveValueFilter([][]string{{"radio", "level_in"}}) + + reader := snmpReader{ + oids: &deviceClassOIDs{ + "ifDescr": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "1", + }, + }, + "radio": &deviceClassOIDs{ + "level_in": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "2", + }, + }, + "level_out": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "3", + }, + }, + }, + }, + } + + filteredGroup, err := filter.applySNMP(context.Background(), reader) + assert.NoError(t, err) + + expected := snmpReader{ + oids: &deviceClassOIDs{ + "radio": &deviceClassOIDs{ + "level_in": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "2", + }, + }, + }, + }, + } + + assert.Equal(t, expected, filteredGroup) +} + +func TestExclusiveValueFilter_applySNMP_noMatch(t *testing.T) { + filter := GetExclusiveValueFilter([][]string{{"ifSpeed"}}) + + reader := snmpReader{ + oids: &deviceClassOIDs{ + "ifDescr": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "1", + }, + }, + "ifOperStatus": &deviceClassOID{ + SNMPGetConfiguration: network.SNMPGetConfiguration{ + OID: "2", + }, + }, + }, + } + + filteredGroup, err := filter.applySNMP(context.Background(), reader) + assert.NoError(t, err) + + expected := snmpReader{ + oids: &deviceClassOIDs{}, + } + + assert.Equal(t, expected, filteredGroup) +} diff --git a/internal/deviceclass/groupproperty/reader.go b/internal/deviceclass/groupproperty/reader.go index 412ec44..b9f9122 100644 --- a/internal/deviceclass/groupproperty/reader.go +++ b/internal/deviceclass/groupproperty/reader.go @@ -110,6 +110,26 @@ func (g *propertyGroup) encode(data interface{}) error { return mapstructure.WeakDecode(data, g) } +func (g *propertyGroup) merge(overwrite propertyGroup) propertyGroup { + res := make(propertyGroup) + for k, v := range *g { + res[k] = v + } + for k, v := range overwrite { + if origEntry, ok := (*g)[k]; ok { + origEntryGroupProperty, origOK := origEntry.(propertyGroup) + newEntryGroupProperty, newOK := v.(propertyGroup) + if origOK && newOK { + res[k] = origEntryGroupProperty.merge(newEntryGroupProperty) + continue + } + } + res[k] = v + } + + return res +} + type PropertyGroups []propertyGroup func (g *PropertyGroups) Decode(destination interface{}) error { diff --git a/internal/deviceclass/groupproperty/reader_test.go b/internal/deviceclass/groupproperty/reader_test.go index 0343bae..0ad778a 100644 --- a/internal/deviceclass/groupproperty/reader_test.go +++ b/internal/deviceclass/groupproperty/reader_test.go @@ -11,6 +11,41 @@ import ( "testing" ) +func TestGroupProperty_merge(t *testing.T) { + g1 := propertyGroup{ + "ifIndex": "1", + } + + g2 := propertyGroup{ + "ifDescr": "3", + "radio": propertyGroup{ + "level_in": "3", + }, + } + + expected := propertyGroup{ + "ifIndex": "1", + "ifDescr": "3", + "radio": propertyGroup{ + "level_in": "3", + }, + } + + assert.Equal(t, expected, g1.merge(g2)) +} + +func TestGroupProperty_merge_overwrite(t *testing.T) { + g1 := propertyGroup{ + "ifIndex": "1", + } + + g2 := propertyGroup{ + "ifIndex": "3", + } + + assert.Equal(t, g2, g1.merge(g2)) +} + // TestDeviceClassOID_readOID tests deviceClassOID.readOid(...) without indices and skipEmpty = false func TestDeviceClassOID_readOID(t *testing.T) { var snmpClient network.MockSNMPClient From 21ce171cd537a3fed92cdc71846eeb78c0c9fec0 Mon Sep 17 00:00:00 2001 From: mikameyer Date: Tue, 19 Oct 2021 12:09:05 +0200 Subject: [PATCH 6/8] added value filter to read interfaces --- cmd/read_interfaces.go | 9 +++++++++ internal/request/read_interfaces_request.go | 4 +++- .../request/read_interfaces_request_process.go | 16 ++++++++++++++-- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/cmd/read_interfaces.go b/cmd/read_interfaces.go index 5858e28..b46f74a 100644 --- a/cmd/read_interfaces.go +++ b/cmd/read_interfaces.go @@ -2,12 +2,15 @@ package cmd import ( "github.com/inexio/thola/internal/request" + "github.com/rs/zerolog/log" "github.com/spf13/cobra" ) func init() { addDeviceFlags(readInterfacesCMD) readCMD.AddCommand(readInterfacesCMD) + + readInterfacesCMD.Flags().StringSlice("value", []string{}, "Only read out these values of the interfaces (e.g. 'ifDescr')") } var readInterfacesCMD = &cobra.Command{ @@ -16,7 +19,13 @@ var readInterfacesCMD = &cobra.Command{ Long: "Read out interface information of a device.\n\n" + "Also reads special values based on the interface type.", Run: func(cmd *cobra.Command, args []string) { + values, err := cmd.Flags().GetStringSlice("value") + if err != nil { + log.Fatal().Err(err).Msg("value needs to be a string") + } + request := request.ReadInterfacesRequest{ + Values: values, ReadRequest: getReadRequest(args[0]), } handleRequest(&request) diff --git a/internal/request/read_interfaces_request.go b/internal/request/read_interfaces_request.go index 894cc9c..7c670d7 100644 --- a/internal/request/read_interfaces_request.go +++ b/internal/request/read_interfaces_request.go @@ -6,10 +6,12 @@ import ( // ReadInterfacesRequest // -// ReadInterfacesRequest is a the request struct for the read interfaces request. +// ReadInterfacesRequest is the request struct for the read interfaces request. // // swagger:model type ReadInterfacesRequest struct { + // If you only want specific values of the interfaces you can specify them here. + Values []string `yaml:"values" json:"values" xml:"values"` ReadRequest } diff --git a/internal/request/read_interfaces_request_process.go b/internal/request/read_interfaces_request_process.go index 501cf88..67f6ad6 100644 --- a/internal/request/read_interfaces_request_process.go +++ b/internal/request/read_interfaces_request_process.go @@ -1,10 +1,13 @@ +//go:build !client // +build !client package request import ( "context" + "github.com/inexio/thola/internal/deviceclass/groupproperty" "github.com/pkg/errors" + "strings" ) func (r *ReadInterfacesRequest) process(ctx context.Context) (Response, error) { @@ -13,9 +16,18 @@ func (r *ReadInterfacesRequest) process(ctx context.Context) (Response, error) { return nil, errors.Wrap(err, "failed to get communicator") } - result, err := com.GetInterfaces(ctx) + var filter []groupproperty.Filter + if len(r.Values) > 0 { + var values [][]string + for _, fil := range r.Values { + values = append(values, strings.Split(fil, "/")) + } + filter = append(filter, groupproperty.GetExclusiveValueFilter(values)) + } + + result, err := com.GetInterfaces(ctx, filter...) if err != nil { - return nil, errors.Wrap(err, "can't get interfaces") + return nil, errors.Wrap(err, "failed to get interfaces") } return &ReadInterfacesResponse{ From 26867dde13e06eb00016a5024e9ea2c01786c461 Mon Sep 17 00:00:00 2001 From: mikameyer Date: Tue, 19 Oct 2021 12:10:44 +0200 Subject: [PATCH 7/8] removed double build tag --- internal/request/check_interface_metrics_request_process.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/request/check_interface_metrics_request_process.go b/internal/request/check_interface_metrics_request_process.go index b08216d..3fb4578 100644 --- a/internal/request/check_interface_metrics_request_process.go +++ b/internal/request/check_interface_metrics_request_process.go @@ -1,4 +1,3 @@ -//go:build !client // +build !client package request From 5d0f1fd96ba0fd02d4893c9ab78b320359e55800 Mon Sep 17 00:00:00 2001 From: mikameyer Date: Tue, 19 Oct 2021 12:17:48 +0200 Subject: [PATCH 8/8] normalized build tags according to go 1.17 --- cmd/api.go | 1 + cmd/check_thola_server.go | 1 + cmd/device.go | 1 + cmd/device_client.go | 1 + cmd/root.go | 1 + cmd/root_client.go | 1 + internal/request/check_cpu_load_process.go | 1 + internal/request/check_disk_request_process.go | 1 + internal/request/check_hardware_health_process.go | 1 + internal/request/check_identify_request_process.go | 1 + internal/request/check_interface_metrics_request_process.go | 1 + internal/request/check_memory_usage_process.go | 1 + internal/request/check_sbc_request_process.go | 1 + internal/request/check_server_request_process.go | 1 + internal/request/check_snmp_request_process.go | 1 + internal/request/check_thola_server_request_process.go | 1 + internal/request/check_ups_process.go | 1 + internal/request/client_process.go | 1 + internal/request/get_communicator.go | 1 + internal/request/identify_request_process.go | 1 + internal/request/process_request.go | 1 + internal/request/process_request_client.go | 1 + internal/request/read_available_components_process.go | 1 + internal/request/read_count_interfaces_request_process.go | 1 + internal/request/read_cpu_load_process.go | 1 + internal/request/read_disk_request_process.go | 1 + internal/request/read_hardware_health_request_process.go | 1 + internal/request/read_memory_usage_process.go | 1 + internal/request/read_sbc_request_process.go | 1 + internal/request/read_server_request_process.go | 1 + internal/request/read_ups_request_process.go | 1 + 31 files changed, 31 insertions(+) diff --git a/cmd/api.go b/cmd/api.go index 87d9225..f93a345 100644 --- a/cmd/api.go +++ b/cmd/api.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package cmd diff --git a/cmd/check_thola_server.go b/cmd/check_thola_server.go index a336c7a..f65253a 100644 --- a/cmd/check_thola_server.go +++ b/cmd/check_thola_server.go @@ -1,3 +1,4 @@ +//go:build client // +build client package cmd diff --git a/cmd/device.go b/cmd/device.go index 8572714..c97f135 100644 --- a/cmd/device.go +++ b/cmd/device.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package cmd diff --git a/cmd/device_client.go b/cmd/device_client.go index 457ea51..64f73c1 100644 --- a/cmd/device_client.go +++ b/cmd/device_client.go @@ -1,3 +1,4 @@ +//go:build client // +build client package cmd diff --git a/cmd/root.go b/cmd/root.go index fd12536..837a663 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package cmd diff --git a/cmd/root_client.go b/cmd/root_client.go index 7009af5..acd844a 100644 --- a/cmd/root_client.go +++ b/cmd/root_client.go @@ -1,3 +1,4 @@ +//go:build client // +build client package cmd diff --git a/internal/request/check_cpu_load_process.go b/internal/request/check_cpu_load_process.go index fb0f39c..745e450 100644 --- a/internal/request/check_cpu_load_process.go +++ b/internal/request/check_cpu_load_process.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package request diff --git a/internal/request/check_disk_request_process.go b/internal/request/check_disk_request_process.go index 67f7a4f..cb91e9f 100644 --- a/internal/request/check_disk_request_process.go +++ b/internal/request/check_disk_request_process.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package request diff --git a/internal/request/check_hardware_health_process.go b/internal/request/check_hardware_health_process.go index 0aca5ea..26e44f1 100644 --- a/internal/request/check_hardware_health_process.go +++ b/internal/request/check_hardware_health_process.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package request diff --git a/internal/request/check_identify_request_process.go b/internal/request/check_identify_request_process.go index e1f887f..0892d3c 100644 --- a/internal/request/check_identify_request_process.go +++ b/internal/request/check_identify_request_process.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package request diff --git a/internal/request/check_interface_metrics_request_process.go b/internal/request/check_interface_metrics_request_process.go index 3fb4578..b08216d 100644 --- a/internal/request/check_interface_metrics_request_process.go +++ b/internal/request/check_interface_metrics_request_process.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package request diff --git a/internal/request/check_memory_usage_process.go b/internal/request/check_memory_usage_process.go index 53a1871..900014f 100644 --- a/internal/request/check_memory_usage_process.go +++ b/internal/request/check_memory_usage_process.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package request diff --git a/internal/request/check_sbc_request_process.go b/internal/request/check_sbc_request_process.go index b0eb524..2328032 100644 --- a/internal/request/check_sbc_request_process.go +++ b/internal/request/check_sbc_request_process.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package request diff --git a/internal/request/check_server_request_process.go b/internal/request/check_server_request_process.go index 7cd7fb9..e78ee51 100644 --- a/internal/request/check_server_request_process.go +++ b/internal/request/check_server_request_process.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package request diff --git a/internal/request/check_snmp_request_process.go b/internal/request/check_snmp_request_process.go index 430a156..b2adc52 100644 --- a/internal/request/check_snmp_request_process.go +++ b/internal/request/check_snmp_request_process.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package request diff --git a/internal/request/check_thola_server_request_process.go b/internal/request/check_thola_server_request_process.go index 8a4773f..09e2fa9 100644 --- a/internal/request/check_thola_server_request_process.go +++ b/internal/request/check_thola_server_request_process.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package request diff --git a/internal/request/check_ups_process.go b/internal/request/check_ups_process.go index e1c28a5..bad1daa 100644 --- a/internal/request/check_ups_process.go +++ b/internal/request/check_ups_process.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package request diff --git a/internal/request/client_process.go b/internal/request/client_process.go index 2e0ac7d..765782d 100644 --- a/internal/request/client_process.go +++ b/internal/request/client_process.go @@ -1,3 +1,4 @@ +//go:build client // +build client package request diff --git a/internal/request/get_communicator.go b/internal/request/get_communicator.go index 1d876b3..80c52e2 100644 --- a/internal/request/get_communicator.go +++ b/internal/request/get_communicator.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package request diff --git a/internal/request/identify_request_process.go b/internal/request/identify_request_process.go index 2e1af3e..ca9fcec 100644 --- a/internal/request/identify_request_process.go +++ b/internal/request/identify_request_process.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package request diff --git a/internal/request/process_request.go b/internal/request/process_request.go index ddca894..542208a 100644 --- a/internal/request/process_request.go +++ b/internal/request/process_request.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package request diff --git a/internal/request/process_request_client.go b/internal/request/process_request_client.go index 61e7e59..2a92110 100644 --- a/internal/request/process_request_client.go +++ b/internal/request/process_request_client.go @@ -1,3 +1,4 @@ +//go:build client // +build client package request diff --git a/internal/request/read_available_components_process.go b/internal/request/read_available_components_process.go index 799fd57..b46a03b 100644 --- a/internal/request/read_available_components_process.go +++ b/internal/request/read_available_components_process.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package request diff --git a/internal/request/read_count_interfaces_request_process.go b/internal/request/read_count_interfaces_request_process.go index c64b619..b938743 100644 --- a/internal/request/read_count_interfaces_request_process.go +++ b/internal/request/read_count_interfaces_request_process.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package request diff --git a/internal/request/read_cpu_load_process.go b/internal/request/read_cpu_load_process.go index 9169df6..9919bf0 100644 --- a/internal/request/read_cpu_load_process.go +++ b/internal/request/read_cpu_load_process.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package request diff --git a/internal/request/read_disk_request_process.go b/internal/request/read_disk_request_process.go index f7d300f..d2665a2 100644 --- a/internal/request/read_disk_request_process.go +++ b/internal/request/read_disk_request_process.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package request diff --git a/internal/request/read_hardware_health_request_process.go b/internal/request/read_hardware_health_request_process.go index 019da7f..b24a41f 100644 --- a/internal/request/read_hardware_health_request_process.go +++ b/internal/request/read_hardware_health_request_process.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package request diff --git a/internal/request/read_memory_usage_process.go b/internal/request/read_memory_usage_process.go index 9212332..9ea9797 100644 --- a/internal/request/read_memory_usage_process.go +++ b/internal/request/read_memory_usage_process.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package request diff --git a/internal/request/read_sbc_request_process.go b/internal/request/read_sbc_request_process.go index 6b143b5..4e354c7 100644 --- a/internal/request/read_sbc_request_process.go +++ b/internal/request/read_sbc_request_process.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package request diff --git a/internal/request/read_server_request_process.go b/internal/request/read_server_request_process.go index 4c42eb4..5517443 100644 --- a/internal/request/read_server_request_process.go +++ b/internal/request/read_server_request_process.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package request diff --git a/internal/request/read_ups_request_process.go b/internal/request/read_ups_request_process.go index c9dd512..4f5827b 100644 --- a/internal/request/read_ups_request_process.go +++ b/internal/request/read_ups_request_process.go @@ -1,3 +1,4 @@ +//go:build !client // +build !client package request