Skip to content

Commit

Permalink
group property reader cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
TheFireMike committed May 10, 2021
1 parent b640095 commit bd14c06
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 57 deletions.
37 changes: 14 additions & 23 deletions core/communicator/device_class_communicator.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,19 @@ func (o *deviceClassCommunicator) GetInterfaces(ctx context.Context) ([]device.I
return nil, tholaerr.NewNotImplementedError("not implemented")
}

networkInterfacesRaw, _, err := o.components.interfaces.Values.getProperty(ctx)
interfacesRaw, err := o.components.interfaces.Values.getProperty(ctx)
if err != nil {
return nil, err
}

return convertRawInterfaces(ctx, networkInterfacesRaw)
var interfaces []device.Interface

err = interfacesRaw.Decode(&interfaces)
if err != nil {
return nil, errors.Wrap(err, "failed to decode raw interfaces into interface structs")
}

return interfaces, nil
}

func (o *deviceClassCommunicator) GetCountInterfaces(ctx context.Context) (int, error) {
Expand Down Expand Up @@ -214,7 +221,7 @@ func (o *deviceClassCommunicator) GetDiskComponentStorages(ctx context.Context)
}
logger := log.Ctx(ctx).With().Str("groupProperty", "DiskComponentStorages").Logger()
ctx = logger.WithContext(ctx)
res, _, err := o.components.disk.storages.getProperty(ctx)
res, err := o.components.disk.storages.getProperty(ctx)
if err != nil {
return nil, errors.Wrap(err, "failed to get property")
}
Expand Down Expand Up @@ -449,7 +456,7 @@ func (o *deviceClassCommunicator) GetSBCComponentAgents(ctx context.Context) ([]
}
logger := log.Ctx(ctx).With().Str("groupProperty", "SBCComponentAgents").Logger()
ctx = logger.WithContext(ctx)
res, _, err := o.components.sbc.agents.getProperty(ctx)
res, err := o.components.sbc.agents.getProperty(ctx)
if err != nil {
return nil, errors.Wrap(err, "failed to get property")
}
Expand All @@ -468,7 +475,7 @@ func (o *deviceClassCommunicator) GetSBCComponentRealms(ctx context.Context) ([]
}
logger := log.Ctx(ctx).With().Str("groupProperty", "SBCComponentRealms").Logger()
ctx = logger.WithContext(ctx)
res, _, err := o.components.sbc.realms.getProperty(ctx)
res, err := o.components.sbc.realms.getProperty(ctx)
if err != nil {
return nil, errors.Wrap(err, "failed to get property")
}
Expand Down Expand Up @@ -677,7 +684,7 @@ func (o *deviceClassCommunicator) GetHardwareHealthComponentFans(ctx context.Con
}
logger := log.Ctx(ctx).With().Str("groupProperty", "HardwareHealthComponentFans").Logger()
ctx = logger.WithContext(ctx)
res, _, err := o.components.hardwareHealth.fans.getProperty(ctx)
res, err := o.components.hardwareHealth.fans.getProperty(ctx)
if err != nil {
return nil, errors.Wrap(err, "failed to get property")
}
Expand All @@ -696,7 +703,7 @@ func (o *deviceClassCommunicator) GetHardwareHealthComponentPowerSupply(ctx cont
}
logger := log.Ctx(ctx).With().Str("groupProperty", "HardwareHealthComponentPowerSupply").Logger()
ctx = logger.WithContext(ctx)
res, _, err := o.components.hardwareHealth.powerSupply.getProperty(ctx)
res, err := o.components.hardwareHealth.powerSupply.getProperty(ctx)
if err != nil {
return nil, errors.Wrap(err, "failed to get property")
}
Expand All @@ -707,19 +714,3 @@ func (o *deviceClassCommunicator) GetHardwareHealthComponentPowerSupply(ctx cont
}
return powerSupply, nil
}

func convertRawInterfaces(ctx context.Context, interfacesRaw groupProperties) ([]device.Interface, error) {
var networkInterfaces []device.Interface

for _, oidValue := range interfacesRaw {
var networkInterface device.Interface
err := mapstructure.WeakDecode(oidValue, &networkInterface)
if err != nil {
log.Ctx(ctx).Trace().Err(err).Msg("can't parse oid values into Interface struct")
return nil, errors.Wrap(err, "can't parse oid values into Interface struct")
}
networkInterfaces = append(networkInterfaces, networkInterface)
}

return networkInterfaces, nil
}
47 changes: 17 additions & 30 deletions core/communicator/device_class_group_properties.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,33 +15,29 @@ import (

type propertyGroup map[string]interface{}

func (g propertyGroup) Decode(destination interface{}) error {
return mapstructure.WeakDecode(g, destination)
}
type propertyGroups []propertyGroup

type groupProperties []propertyGroup

func (g groupProperties) Decode(destination interface{}) error {
func (g *propertyGroups) Decode(destination interface{}) error {
return mapstructure.WeakDecode(g, destination)
}

type groupPropertyReader interface {
getProperty(ctx context.Context) (groupProperties, map[string]int, error)
getProperty(ctx context.Context) (propertyGroups, error)
}

type snmpGroupPropertyReader struct {
oids deviceClassOIDs
}

func (s *snmpGroupPropertyReader) getProperty(ctx context.Context) (groupProperties, map[string]int, error) {
func (s *snmpGroupPropertyReader) getProperty(ctx context.Context) (propertyGroups, error) {
groups, err := s.oids.readOID(ctx)
if err != nil {
return nil, nil, errors.Wrap(err, "failed to read oids")
return nil, errors.Wrap(err, "failed to read oids")
}

var res groupProperties
indices := make(map[string]int)
var res propertyGroups

// this sorts the groups after their ifIndex
//TODO efficiency
size := len(groups)
for i := 0; i < size; i++ {
Expand All @@ -58,50 +54,40 @@ func (s *snmpGroupPropertyReader) getProperty(ctx context.Context) (groupPropert
}
x, ok := groups[smallestIndex].(map[string]interface{})
if !ok {
return nil, nil, fmt.Errorf("oidReader for index '%d' returned unexpected data type: %T", smallestIndex, groups[smallestIndex])
return nil, fmt.Errorf("oidReader for index '%d' returned unexpected data type: %T", smallestIndex, groups[smallestIndex])
}

res = append(res, x)
indices[fmt.Sprint(smallestIndex)] = i
delete(groups, smallestIndex)
}

return res, indices, nil
return res, nil
}

type oidReader interface {
readOID(context.Context) (map[int]interface{}, error)
}

// deviceClassOIDs maps labels to OIDs.
// deviceClassOIDs is a recursive data structure which maps labels to either a single OID (deviceClassOID) or another deviceClassOIDs
type deviceClassOIDs map[string]oidReader

func (d *deviceClassOIDs) readOID(ctx context.Context) (map[int]interface{}, error) {
result := make(map[int]map[string]interface{})
for name, oidReader := range *d {
res, err := oidReader.readOID(ctx)
for label, reader := range *d {
res, err := reader.readOID(ctx)
if err != nil {
if tholaerr.IsNotFoundError(err) {
log.Ctx(ctx).Trace().Err(err).Msgf("value %s", name)
log.Ctx(ctx).Trace().Err(err).Msgf("value %s", label)
continue
}
return nil, errors.Wrapf(err, "failed to get value '%s'", name)
return nil, errors.Wrapf(err, "failed to get value '%s'", label)
}
for ifIndex, v := range res {
// ifIndex was not known before, so create a new group
if _, ok := result[ifIndex]; !ok {
result[ifIndex] = make(map[string]interface{})
}
if m, ok := v.(map[string]interface{}); ok {
newMap := make(map[string]interface{})
for k, val := range m {
newMap[k] = val
}
result[ifIndex][name] = newMap
} else if val, ok := v.(value.Value); ok {
result[ifIndex][name] = val
} else {
return nil, fmt.Errorf("oidReader returned unexpected data type: %T", v)
}
result[ifIndex][label] = v
}
}

Expand Down Expand Up @@ -134,6 +120,7 @@ func (d *deviceClassOIDs) merge(overwrite deviceClassOIDs) deviceClassOIDs {
return devClassOIDsNew
}

// deviceClassOID represents a single OID which can be read
type deviceClassOID struct {
network.SNMPGetConfiguration
operators propertyOperators
Expand Down
13 changes: 10 additions & 3 deletions core/communicator/ekinops.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func (c *ekinopsCommunicator) GetInterfaces(ctx context.Context) ([]device.Inter
return normalizeEkinopsInterfaces(interfaces)
}

// GetInterfaces returns the interfaces of ekinops devices.
// GetIfTable returns the ifTable of ekinops devices.
// For ekinops devices, only a few interface values are required.
func (c *ekinopsCommunicator) GetIfTable(ctx context.Context) ([]device.Interface, error) {
if genericDeviceClass.components.interfaces.Values == nil {
Expand All @@ -92,12 +92,19 @@ func (c *ekinopsCommunicator) GetIfTable(ctx context.Context) ([]device.Interfac
}
reader.oids = oids

networkInterfacesRaw, _, err := reader.getProperty(ctx)
interfacesRaw, err := reader.getProperty(ctx)
if err != nil {
return nil, err
}

return convertRawInterfaces(ctx, networkInterfacesRaw)
var interfaces []device.Interface

err = interfacesRaw.Decode(&interfaces)
if err != nil {
return nil, errors.Wrap(err, "failed to decode raw interfaces into interface structs")
}

return interfaces, nil
}

func ekinopsInterfacesIfIdentifierToSliceIndex(interfaces []device.Interface) (map[string]int, error) {
Expand Down
1 change: 0 additions & 1 deletion core/communicator/network_device_communicator.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ type availableCommunicatorFunctions interface {
GetOSVersion(ctx context.Context) (string, error)

// GetInterfaces returns the interfaces of a device.
// This includes special interface values.
GetInterfaces(ctx context.Context) ([]device.Interface, error)

// GetCountInterfaces returns the count of interfaces of a device.
Expand Down

0 comments on commit bd14c06

Please sign in to comment.