Skip to content

Commit

Permalink
added VLAN information to interfaces
Browse files Browse the repository at this point in the history
closes #38
  • Loading branch information
TheFireMike committed Jun 18, 2021
1 parent a75cc62 commit 4f33591
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 6 deletions.
2 changes: 2 additions & 0 deletions config/codecommunicator/code_communicator.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ func GetCodeCommunicator(deviceClass communicator.Communicator, parentNetworkDev
return &timosSASCommunicator{base}, nil
case "timos":
return &timosCommunicator{base}, nil
case "junos":
return &junosCommunicator{base}, nil
}
return nil, tholaerr.NewNotFoundError(fmt.Sprintf("no code communicator found for device class identifier '%s'", classIdentifier))
}
Expand Down
111 changes: 111 additions & 0 deletions config/codecommunicator/junos.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package codecommunicator

import (
"context"
"fmt"
"github.com/inexio/thola/internal/device"
"github.com/inexio/thola/internal/network"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
"strings"
)

type junosCommunicator struct {
codeCommunicator
}

func (c *junosCommunicator) GetInterfaces(ctx context.Context) ([]device.Interface, error) {
interfaces, err := c.deviceClass.GetInterfaces(ctx)
if err != nil {
return nil, err
}

con, ok := network.DeviceConnectionFromContext(ctx)
if !ok || con.SNMP == nil {
return nil, errors.New("snmp client is empty")
}

// dot1dBasePortIfIndex
res, err := con.SNMP.SnmpClient.SNMPWalk(ctx, "1.3.6.1.2.1.17.1.4.1.2")
if err != nil {
log.Ctx(ctx).Trace().Err(err).Msg("failed to get dot1dBasePortIfIndex, skipping VLANs")
return interfaces, nil
}

portIfIndex := make(map[string]string)
for _, response := range res {
ifIndex, err := response.GetValueString()
if err != nil {
return nil, err
}

oid := response.GetOID()
oidSplit := strings.Split(oid, ".")

portIfIndex[oidSplit[len(oidSplit)-1]] = ifIndex
}

// jnxExVlanPortStatus
res, err = con.SNMP.SnmpClient.SNMPWalk(ctx, "1.3.6.1.4.1.2636.3.40.1.5.1.7.1.3")
if err != nil {
log.Ctx(ctx).Trace().Err(err).Msg("failed to get jnxExVlanPortStatus, skipping VLANs")
return interfaces, nil
}

vlanIndexVLAN := make(map[string]device.VLAN)
ifIndexVLANIndices := make(map[string][]string)
for _, response := range res {
status, err := response.GetValueString()
if err != nil {
return nil, err
}

oid := response.GetOID()
oidSplit := strings.Split(oid, ".")

ifIndex := portIfIndex[oidSplit[len(oidSplit)-1]]
ifIndexVLANIndices[ifIndex] = append(ifIndexVLANIndices[ifIndex], oidSplit[len(oidSplit)-2])
vlanIndexVLAN[oidSplit[len(oidSplit)-2]] = device.VLAN{
Status: &status,
}
}

// jnxExVlanName
res, err = con.SNMP.SnmpClient.SNMPWalk(ctx, "1.3.6.1.4.1.2636.3.40.1.5.1.5.1.2")
if err != nil {
log.Ctx(ctx).Trace().Err(err).Msg("failed to get jnxExVlanName, skipping VLANs")
return interfaces, nil
}

for _, response := range res {
name, err := response.GetValueString()
if err != nil {
return nil, err
}

oid := response.GetOID()
oidSplit := strings.Split(oid, ".")

if vlan, ok := vlanIndexVLAN[oidSplit[len(oidSplit)-1]]; ok {
vlan.Name = name
vlanIndexVLAN[oidSplit[len(oidSplit)-1]] = vlan
}
}

for i, interf := range interfaces {
if interf.IfIndex != nil {
if vlanIndices, ok := ifIndexVLANIndices[fmt.Sprint(*interf.IfIndex)]; ok {
for _, vlanIndex := range vlanIndices {
if vlan, ok := vlanIndexVLAN[vlanIndex]; ok {
if interfaces[i].VLAN == nil {
interfaces[i].VLAN = &device.VLANInformation{}
}
interfaces[i].VLAN.VLANs = append(interfaces[i].VLAN.VLANs, vlan)
}
}
}
}
}

return interfaces, nil
}
32 changes: 26 additions & 6 deletions internal/device/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ type Interface struct {
OpticalAmplifier *OpticalAmplifierInterface `yaml:"optical_amplifier,omitempty" json:"optical_amplifier,omitempty" xml:"optical_amplifier,omitempty" mapstructure:"optical_amplifier,omitempty"`
OpticalOPM *OpticalOPMInterface `yaml:"optical_opm,omitempty" json:"optical_opm,omitempty" xml:"optical_opm,omitempty" mapstructure:"optical_opm,omitempty"`
SAP *SAPInterface `yaml:"sap,omitempty" json:"sap,omitempty" xml:"sap,omitempty" mapstructure:"sap,omitempty"`
VLAN *VLANInformation `yaml:"vlan,omitempty" json:"vlan,omitempty" xml:"vlan,omitempty" mapstructure:"vlan,omitempty"`
}

//
Expand Down Expand Up @@ -217,6 +218,17 @@ type OpticalOPMInterface struct {
Channels []OpticalChannel `yaml:"channels,omitempty" json:"channels,omitempty" xml:"channels,omitempty" mapstructure:"channels"`
}

// OpticalChannel
//
// OpticalChannel represents an optical channel.
//
// 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"`
}

// SAPInterface
//
// SAPInterface represents a service access point interface.
Expand All @@ -227,15 +239,23 @@ type SAPInterface struct {
Outbound *uint64 `yaml:"outbound,omitempty" json:"outbound,omitempty" xml:"outbound,omitempty" mapstructure:"outbound"`
}

// OpticalChannel
// VLANInformation
//
// OpticalChannel represents an optical channel.
// VLANInformation includes all information regarding the VLANs of the interface.
//
// 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"`
type VLANInformation struct {
VLANs []VLAN `yaml:"vlans,omitempty" json:"vlans,omitempty" xml:"vlans,omitempty" mapstructure:"vlans"`
}

// VLAN
//
// VLAN includes all information about a VLAN.
//
// 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"`
}

//
Expand Down

0 comments on commit 4f33591

Please sign in to comment.