Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #28

Merged
merged 14 commits into from
Mar 30, 2021
Merged
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ It features a check mode which complies with the [monitoring plugins development

## Installation

You can download the latest compiled version for your platform under the "Releases" tab or build it yourself:
You can download the latest compiled version for your platform under the "Releases" tab or build it yourself (requires go 1.16):

git clone https://github.com/inexio/thola.git
cd thola
Expand Down
2 changes: 1 addition & 1 deletion cmd/check_disk.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ var checkDiskCMD = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) {
r := request.CheckDiskRequest{
CheckDeviceRequest: getCheckDeviceRequest(args[0]),
DiskThresholds: generateCheckThresholds(cmd, "warning", "", "critical", "", false),
DiskThresholds: generateCheckThresholds(cmd, "", "warning", "", "critical", true),
}
handleRequest(&r)
},
Expand Down
9 changes: 9 additions & 0 deletions config/device-classes/generic/timos.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name: timos

match:
conditions:
- match_mode: startsWith
type: SysObjectID
values:
- ".1.3.6.1.4.1.6527"
logical_operator: OR
70 changes: 35 additions & 35 deletions core/communicator/adva.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func (c *advaCommunicator) GetInterfaces(ctx context.Context) ([]device.Interfac
func advaGetDWDMInterfaces(ctx context.Context, interfaces []device.Interface) ([]device.Interface, error) {
con, ok := network.DeviceConnectionFromContext(ctx)
if !ok || con.SNMP == nil {
return []device.Interface{}, errors.New("no device connection available")
return nil, errors.New("no device connection available")
}

specialInterfacesRaw, err := getValuesBySNMPWalk(ctx, deviceClassOIDs{
Expand Down Expand Up @@ -78,15 +78,15 @@ func advaGetDWDMInterfaces(ctx context.Context, interfaces []device.Interface) (
})

if err != nil {
return []device.Interface{}, errors.Wrap(err, "failed to read rx/tx power of ports")
return nil, errors.Wrap(err, "failed to read rx/tx power of ports")
}

for i, networkInterface := range interfaces {
if specialValues, ok := specialInterfacesRaw[fmt.Sprint(*networkInterface.IfIndex)]; ok {
err := addSpecialInterfacesValuesToInterface("dwdm", &interfaces[i], specialValues)
if err != nil {
log.Ctx(ctx).Trace().Err(err).Msg("can't parse oid values into Interface struct")
return []device.Interface{}, errors.Wrap(err, "can't parse oid values into Interface struct")
return nil, errors.Wrap(err, "can't parse oid values into Interface struct")
}
}
}
Expand All @@ -108,11 +108,11 @@ func advaGetDWDMInterfaces(ctx context.Context, interfaces []device.Interface) (
if (rxOK || txOK) && interf.DWDM == nil {
interfaces[i].DWDM = &device.DWDMInterface{}
}
if rxOK {
interfaces[i].DWDM.RXPower100G = &rxVal
if rxOK && (interfaces[i].DWDM.RXPower == nil || *interfaces[i].DWDM.RXPower == -6553.5) {
interfaces[i].DWDM.RXPower = &rxVal
}
if txOK {
interfaces[i].DWDM.TXPower100G = &txVal
if txOK && (interfaces[i].DWDM.TXPower == nil || *interfaces[i].DWDM.TXPower == -6553.5) {
interfaces[i].DWDM.TXPower = &txVal
}
}

Expand All @@ -122,12 +122,12 @@ func advaGetDWDMInterfaces(ctx context.Context, interfaces []device.Interface) (
if err == nil && len(res) == 1 {
valString, err := res[0].GetValueString()
if err != nil {
return []device.Interface{}, errors.Wrap(err, "failed to get corrected 15m bit error rate string value for interface "+fmt.Sprint(*interf.IfIndex))
return nil, errors.Wrap(err, "failed to get corrected 15m bit error rate string value for interface "+fmt.Sprint(*interf.IfIndex))
}

val, err := strconv.ParseFloat(valString, 64)
if err != nil {
return []device.Interface{}, errors.Wrap(err, "failed to parse corrected 15m bit error rate for interface "+fmt.Sprint(*interf.IfIndex))
return nil, errors.Wrap(err, "failed to parse corrected 15m bit error rate for interface "+fmt.Sprint(*interf.IfIndex))
}

if interfaces[i].DWDM == nil {
Expand All @@ -145,12 +145,12 @@ func advaGetDWDMInterfaces(ctx context.Context, interfaces []device.Interface) (
if err == nil && len(res) == 1 {
valString, err := res[0].GetValueString()
if err != nil {
return []device.Interface{}, errors.Wrap(err, "failed to get uncorrected 15m bit error rate string value for interface "+fmt.Sprint(*interf.IfIndex))
return nil, errors.Wrap(err, "failed to get uncorrected 15m bit error rate string value for interface "+fmt.Sprint(*interf.IfIndex))
}

val, err := strconv.ParseFloat(valString, 64)
if err != nil {
return []device.Interface{}, errors.Wrap(err, "failed to parse uncorrected 15m bit error rate for interface "+fmt.Sprint(*interf.IfIndex))
return nil, errors.Wrap(err, "failed to parse uncorrected 15m bit error rate for interface "+fmt.Sprint(*interf.IfIndex))
}

if interfaces[i].DWDM == nil {
Expand All @@ -168,12 +168,12 @@ func advaGetDWDMInterfaces(ctx context.Context, interfaces []device.Interface) (
if err == nil && len(res) == 1 {
valString, err := res[0].GetValueString()
if err != nil {
return []device.Interface{}, errors.Wrap(err, "failed to get corrected 1d bit error rate string value for interface "+fmt.Sprint(*interf.IfIndex))
return nil, errors.Wrap(err, "failed to get corrected 1d bit error rate string value for interface "+fmt.Sprint(*interf.IfIndex))
}

val, err := strconv.ParseFloat(valString, 64)
if err != nil {
return []device.Interface{}, errors.Wrap(err, "failed to parse corrected 1d bit error rate for interface "+fmt.Sprint(*interf.IfIndex))
return nil, errors.Wrap(err, "failed to parse corrected 1d bit error rate for interface "+fmt.Sprint(*interf.IfIndex))
}

if interfaces[i].DWDM == nil {
Expand All @@ -191,12 +191,12 @@ func advaGetDWDMInterfaces(ctx context.Context, interfaces []device.Interface) (
if err == nil && len(res) == 1 {
valString, err := res[0].GetValueString()
if err != nil {
return []device.Interface{}, errors.Wrap(err, "failed to get uncorrected 1d bit error rate string value for interface "+fmt.Sprint(*interf.IfIndex))
return nil, errors.Wrap(err, "failed to get uncorrected 1d bit error rate string value for interface "+fmt.Sprint(*interf.IfIndex))
}

val, err := strconv.ParseFloat(valString, 64)
if err != nil {
return []device.Interface{}, errors.Wrap(err, "failed to parse uncorrected 1d bit error rate for interface "+fmt.Sprint(*interf.IfIndex))
return nil, errors.Wrap(err, "failed to parse uncorrected 1d bit error rate for interface "+fmt.Sprint(*interf.IfIndex))
}

if interfaces[i].DWDM == nil {
Expand All @@ -217,7 +217,7 @@ func advaGetDWDMInterfaces(ctx context.Context, interfaces []device.Interface) (
func advaGetChannels(ctx context.Context, interfaces []device.Interface) ([]device.Interface, error) {
con, ok := network.DeviceConnectionFromContext(ctx)
if !ok || con.SNMP == nil {
return []device.Interface{}, errors.New("no device connection available")
return nil, errors.New("no device connection available")
}

facilityPhysInstValueInputPower := ".1.3.6.1.4.1.2544.1.11.11.7.2.1.1.1.2"
Expand All @@ -235,11 +235,11 @@ func advaGetChannels(ctx context.Context, interfaces []device.Interface) ([]devi
if s := strings.Split(strings.Trim(subtree, "."), "."); len(s) > 2 && s[len(s)-2] != "0" {
val, err := res.GetValueString()
if err != nil {
return []device.Interface{}, errors.Wrap(err, "failed to get rx value of channel "+subtree)
return nil, errors.Wrap(err, "failed to get rx value of channel "+subtree)
}
a, err := decimal.NewFromString(val)
if err != nil {
return []device.Interface{}, errors.Wrap(err, "failed to parse rx value of channel "+subtree)
return nil, errors.Wrap(err, "failed to parse rx value of channel "+subtree)
}
b := decimal.NewFromFloat(0.1)
valFin, _ := a.Mul(b).Float64()
Expand All @@ -255,20 +255,20 @@ func advaGetChannels(ctx context.Context, interfaces []device.Interface) ([]devi
for _, subtree := range subtrees {
res, err := con.SNMP.SnmpClient.SNMPGet(ctx, ".1.3.6.1.4.1.2544.1.11.11.7.2.1.1.1.1"+subtree)
if err != nil {
return []device.Interface{}, errors.Wrap(err, "failed to get facilityPhysInstValueOutputPower for subtree "+subtree)
return nil, errors.Wrap(err, "failed to get facilityPhysInstValueOutputPower for subtree "+subtree)
}

if len(res) != 1 {
return []device.Interface{}, errors.New("failed to get tx value of subtree " + subtree)
return nil, errors.New("failed to get tx value of subtree " + subtree)
}

val, err := res[0].GetValueString()
if err != nil {
return []device.Interface{}, errors.Wrap(err, "failed to get tx value of subtree "+subtree)
return nil, errors.Wrap(err, "failed to get tx value of subtree "+subtree)
}
valueDecimal, err := decimal.NewFromString(val)
if err != nil {
return []device.Interface{}, errors.Wrap(err, "failed to parse tx value of subtree "+subtree)
return nil, errors.Wrap(err, "failed to parse tx value of subtree "+subtree)
}
multiplier := decimal.NewFromFloat(0.1)
valFin, _ := valueDecimal.Mul(multiplier).Float64()
Expand All @@ -278,11 +278,11 @@ func advaGetChannels(ctx context.Context, interfaces []device.Interface) ([]devi

p := strings.Split(strings.ReplaceAll(strings.Trim(subtree, "."), "33152", "N"), ".")
if len(p) < 3 {
return []device.Interface{}, errors.New("invalid channel identifier")
return nil, errors.New("invalid channel identifier")
}
regex, err := regexp.Compile("-" + p[0] + "-" + p[1] + "-" + p[2])
if err != nil {
return []device.Interface{}, errors.Wrap(err, "failed to build regex")
return nil, errors.Wrap(err, "failed to build regex")
}

for j, interf := range interfaces {
Expand All @@ -303,13 +303,13 @@ func advaGetChannels(ctx context.Context, interfaces []device.Interface) ([]devi
func advaGet100GInterfaces(ctx context.Context, interfaces []device.Interface) ([]device.Interface, error) {
con, ok := network.DeviceConnectionFromContext(ctx)
if !ok || con.SNMP == nil {
return []device.Interface{}, errors.New("no device connection available")
return nil, errors.New("no device connection available")
}

ports := ".1.3.6.1.4.1.2544.1.11.7.2.7.1.6"
portValues, err := con.SNMP.SnmpClient.SNMPWalk(ctx, ports)
if err != nil {
return []device.Interface{}, errors.Wrap(err, "failed to walk ports")
log.Ctx(ctx).Trace().Err(err).Msg("failed to walk 100g ports")
}

var subtrees []string
Expand All @@ -319,29 +319,29 @@ func advaGet100GInterfaces(ctx context.Context, interfaces []device.Interface) (
for _, res := range portValues {
portName, err := res.GetValueString()
if err != nil {
return []device.Interface{}, errors.Wrap(err, "failed to get snmp response")
return nil, errors.Wrap(err, "failed to get snmp response")
}

if strings.HasPrefix(portName, "OTL-") {
subtree := strings.TrimPrefix(res.GetOID(), ports)

rxValue, err := con.SNMP.SnmpClient.SNMPGet(ctx, ".1.3.6.1.4.1.2544.1.11.7.7.2.3.1.2"+subtree)
if err != nil {
return []device.Interface{}, errors.Wrap(err, "failed to get rx value of port "+portName)
return nil, errors.Wrap(err, "failed to get rx value of port "+portName)
}

if len(rxValue) != 1 {
return []device.Interface{}, errors.Wrap(err, "failed to get rx value of port "+portName)
return nil, errors.Wrap(err, "failed to get rx value of port "+portName)
}

rxValueString, err := rxValue[0].GetValueString()
if err != nil {
return []device.Interface{}, errors.Wrap(err, "failed to get snmp response")
return nil, errors.Wrap(err, "failed to get snmp response")
}

valueDecimal, err := decimal.NewFromString(rxValueString)
if err != nil {
return []device.Interface{}, errors.Wrap(err, "failed to parse rx value of subtree "+subtree)
return nil, errors.Wrap(err, "failed to parse rx value of subtree "+subtree)
}
multiplier := decimal.NewFromFloat(0.1)
valFin, _ := valueDecimal.Mul(multiplier).Float64()
Expand All @@ -360,20 +360,20 @@ func advaGet100GInterfaces(ctx context.Context, interfaces []device.Interface) (
for _, subtree := range subtrees {
res, err := con.SNMP.SnmpClient.SNMPGet(ctx, ".1.3.6.1.4.1.2544.1.11.7.7.2.3.1.1"+subtree)
if err != nil {
return []device.Interface{}, errors.Wrap(err, "failed to get tx value for subtree "+subtree)
return nil, errors.Wrap(err, "failed to get tx value for subtree "+subtree)
}

if len(res) != 1 {
return []device.Interface{}, errors.New("failed to get tx value of subtree " + subtree)
return nil, errors.New("failed to get tx value of subtree " + subtree)
}

val, err := res[0].GetValueString()
if err != nil {
return []device.Interface{}, errors.Wrap(err, "failed to get tx value of subtree "+subtree)
return nil, errors.Wrap(err, "failed to get tx value of subtree "+subtree)
}
a, err := decimal.NewFromString(val)
if err != nil {
return []device.Interface{}, errors.Wrap(err, "failed to parse tx value of subtree "+subtree)
return nil, errors.Wrap(err, "failed to parse tx value of subtree "+subtree)
}
b := decimal.NewFromFloat(0.1)
valFin, _ := a.Mul(b).Float64()
Expand Down
2 changes: 2 additions & 0 deletions core/communicator/device_class_to_code_communicator.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ func getCodeCommunicator(classIdentifier string, rel *relatedNetworkDeviceCommun
return &ekinopsCommunicator{baseCommunicator{rel}}, nil
case "adva_fsp3kr7":
return &advaCommunicator{baseCommunicator{rel}}, nil
case "timos":
return &timosCommunicator{baseCommunicator{rel}}, nil
}
return nil, tholaerr.NewNotFoundError(fmt.Sprintf("no communicator found for device class identifier '%s'", classIdentifier))
}
4 changes: 2 additions & 2 deletions core/communicator/ekinops.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@ func normalizeEkinopsInterfaces(interfaces []device.Interface) ([]device.Interfa
slotNumber := strings.Split(*interf.IfName, "/")[2]
moduleName := strings.Split(*interf.IfDescr, "/")[3]

// change ifType of ports of slots > 1 to "opticalChannel" if ifType equals "other", but not OPM8 interfaces
if !(slotNumber == "0" || slotNumber == "1") && interf.IfType != nil && *interf.IfType == "other" && moduleName != "PM_OPM8" {
// change ifType of ports of slots > 0 to "opticalChannel" if ifType equals "other", but not OPM8 interfaces
if slotNumber != "0" && interf.IfType != nil && *interf.IfType == "other" && moduleName != "PM_OPM8" {
opticalChannel := "opticalChannel"
interf.IfType = &opticalChannel
}
Expand Down
72 changes: 72 additions & 0 deletions core/communicator/timos.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package communicator

import (
"context"
"github.com/inexio/thola/core/device"
"github.com/inexio/thola/core/network"
"github.com/pkg/errors"
"strconv"
"strings"
)

type timosCommunicator struct {
baseCommunicator
}

// GetInterfaces returns the interfaces of timetra devices.
func (c *timosCommunicator) GetInterfaces(ctx context.Context) ([]device.Interface, error) {
interfaces, err := c.sub.GetInterfaces(ctx)
if err != nil {
return nil, err
}

con, ok := network.DeviceConnectionFromContext(ctx)
if !ok || con.SNMP == nil {
return nil, errors.New("no device connection available")
}

ports := ".1.3.6.1.4.1.6527.3.1.2.4.3.2.1.5"
descriptions, err := con.SNMP.SnmpClient.SNMPWalk(ctx, ports)
if err != nil {
return nil, errors.Wrap(err, "error during snmp walk")
}
for _, response := range descriptions {
valueString, err := response.GetValueString()
if err != nil {
return nil, errors.Wrap(err, "couldn't get string value")
}
if valueString == "" {
continue
}
index := strings.TrimPrefix(response.GetOID(), ports)
in, err := con.SNMP.SnmpClient.SNMPGet(ctx, ".1.3.6.1.4.1.6527.6.2.2.2.8.1.1.1.4"+index)
if err != nil {
return nil, errors.Wrap(err, "error during snmp get")
}
inStr, err := in[0].GetValueString()
if err != nil {
return nil, errors.Wrap(err, "couldn't get string value")
}
trafficIn, err := strconv.ParseUint(inStr, 0, 64)
if err != nil {
return nil, errors.Wrap(err, "failed to parse snmp response")
}
out, err := con.SNMP.SnmpClient.SNMPGet(ctx, ".1.3.6.1.4.1.6527.6.2.2.2.8.1.1.1.6"+index)
if err != nil {
return nil, errors.Wrap(err, "error during snmp get")
}
outStr, err := out[0].GetValueString()
if err != nil {
return nil, errors.Wrap(err, "couldn't get string value")
}
trafficOut, err := strconv.ParseUint(outStr, 0, 64)
if err != nil {
return nil, errors.Wrap(err, "failed to parse snmp response")
}
interfaces = append(interfaces, device.Interface{
IfDescr: &valueString,
SAP: &device.SAPInterface{Inbound: &trafficIn, Outbound: &trafficOut}})
}

return interfaces, nil
}
Loading