Skip to content

Commit

Permalink
add virtual switch
Browse files Browse the repository at this point in the history
  • Loading branch information
mattieserver committed Sep 10, 2024
1 parent 6d4b945 commit d384ba7
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 12 deletions.
3 changes: 1 addition & 2 deletions cmd/netbox-oxidized-sync/netbox-oxidized-sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package main

import (
"log"
"log/slog"
"slices"
"strconv"

Expand All @@ -29,7 +28,7 @@ func worker(id int, jobs <-chan httphelper.OxidizedNode, results chan<- int, net
log.Println("IOS not supported for now")
case "FortiOS":
log.Printf("Device: '%s' has fortiOS", j.Name)
fortigateInterfaces,_ := configparser.ParseFortiOSConfig(&config)
fortigateInterfaces, _ := configparser.ParseFortiOSConfig(&config)
var netboxDevice = (*netboxdevices)[idx]
netboxInterfaceForDevice := netboxhttp.GetIntefacesForDevice(strconv.Itoa(netboxDevice.ID))
netboxVlansForSite, err := netboxhttp.GetVlansForSite(strconv.Itoa(netboxDevice.Site.ID))
Expand Down
111 changes: 106 additions & 5 deletions internal/configparser/fortios.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,21 @@ const (
intefaceMember = " set member "
interfaceStatus = " set status "
interfaceDescription = " set description "
virtualSwitchPortPrefix = " edit "
)

func ParseFortiOSConfig(config *string) (*[]model.FortigateInterface, error) {
const (
start = "config system interface"
end = "end"
start = "config system interface"
end = "end"
startVirtualSwitch = "config system virtual-switch"
)

var (
configInterfacesTracking bool
configInterfaces []string
configVirtualSwitchTracking bool
configInterfacesTracking bool
configInterfaces []string
configVirtualSwitch []string
)

scanner := bufio.NewScanner(strings.NewReader(*config))
Expand All @@ -40,18 +44,93 @@ func ParseFortiOSConfig(config *string) (*[]model.FortigateInterface, error) {
switch {
case configInterfacesTracking && line == end:
configInterfacesTracking = false
case configVirtualSwitchTracking && line == end:
configVirtualSwitchTracking = false
case configVirtualSwitchTracking:
configVirtualSwitch = append(configVirtualSwitch, line)
case configInterfacesTracking:
configInterfaces = append(configInterfaces, line)
case line == start:
configInterfacesTracking = true
case line == startVirtualSwitch:
configVirtualSwitchTracking = true
}
}

deviceInterfaces := parseInterfaces(configInterfaces)
deviceVirtualSwitches := parseVirtualSwitch(configVirtualSwitch)
convertVirtualSwitch(deviceVirtualSwitches, deviceInterfaces)

return deviceInterfaces, nil
}

func parseVirtualSwitch(virtualSwitches []string) *[]model.FortigateVirtualSwitch{

var deviceVirtualSwitches []model.FortigateVirtualSwitch

var (
configVirtualSwitch []string
configVirtualSwitchTracking bool
)

for _, element := range virtualSwitches {
if strings.HasPrefix(element, interfaceNamePrefix) {
configVirtualSwitchTracking = true
configVirtualSwitch = []string{element}
continue
}

if strings.HasPrefix(element, " next") {
if configVirtualSwitchTracking {
configVirtualSwitchTracking = false
parseSingleVirtualSwitch(configVirtualSwitch, &deviceVirtualSwitches)
}
continue
}

if configVirtualSwitchTracking {
configVirtualSwitch = append(configVirtualSwitch, element)
}
}
return &deviceVirtualSwitches
}

func parseSingleVirtualSwitch(virtualSwitchData []string, results *[]model.FortigateVirtualSwitch) {
var name string
var portNames []string

portPrefixes := map[string]*[]string{
virtualSwitchPortPrefix: &portNames,
}

prefixes := map[string]*string{
interfaceNamePrefix: &name,
}

for _, element := range virtualSwitchData {
for prefix, value := range prefixes {
if strings.HasPrefix(element, prefix) {
*value = getElementValue(element, prefix)
}
}

for portPrefix, portValue := range portPrefixes {
if strings.HasPrefix(element, portPrefix) {
*portValue = append(*portValue, getElementValue(element, portPrefix))
}
}
}

if name == "''" {
return
}

var vSwitch model.FortigateVirtualSwitch
vSwitch.Name = name
vSwitch.Members = portNames
*results = append(*results, vSwitch)
}

func parseInterfaces(interfaces []string) *[]model.FortigateInterface {

var deviceInterfaces []model.FortigateInterface
Expand Down Expand Up @@ -89,6 +168,28 @@ func getElementValue(element string, filter string) string {
return strings.ReplaceAll(strings.ReplaceAll(element, filter, ""), "\"", "")
}

func convertVirtualSwitch(virtutalSwitches *[]model.FortigateVirtualSwitch, deviceInterfaces *[]model.FortigateInterface ) {

var virtualSwitchNames = map[string]string{}

for _, member := range *virtutalSwitches {
var vswitch model.FortigateInterface
vswitch.Name = member.Name
vswitch.InterfaceType = "bridge"
vswitch.Members = member.Members
*deviceInterfaces = append(*deviceInterfaces, vswitch)
for _, vswitchMember := range member.Members {
virtualSwitchNames[vswitchMember] = member.Name
}
}

for index, dinterface := range *deviceInterfaces {
if virtualSwitchNames[dinterface.Name] != "" {
(*deviceInterfaces)[index].Parent = virtualSwitchNames[dinterface.Name]
}
}
}

func parseSingleInterface(interfaceData []string, results *[]model.FortigateInterface) {

var name, interfaceType, vlanId, parentName, alias, vdom, ip, speed, member, status, description string
Expand Down Expand Up @@ -155,7 +256,7 @@ func createVlan(name string, alias string, vdom string, vlanId string, parentNam
vid.Name = alias
} else {
vid.Name = name
}
}
vid.Description = createDescription(alias, vdom, description)
vid.VlanId = vlanId
vid.Parent = parentName
Expand Down
10 changes: 9 additions & 1 deletion internal/model/DeviceInterface.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ type NetboxInterface struct {
} `json:"type"`
Enabled bool `json:"enabled"`
Parent interface{} `json:"parent"`
Bridge interface{} `json:"bridge"`
Bridge struct{
ID int `json:"id"`
Name string `json:"name"`
} `json:"bridge"`
Lag struct {
ID int `json:"id"`
URL string `json:"url"`
Expand Down Expand Up @@ -199,6 +202,11 @@ type NetboxDevice struct {
InventoryItemCount int `json:"inventory_item_count"`
}

type FortigateVirtualSwitch struct {
Name string
Members []string
}

type NetboxInterfaceUpdateCreate struct {
DeviceId string
PortType string
Expand Down
20 changes: 16 additions & 4 deletions internal/netboxparser/fortitonetbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,28 @@ func processPort(port model.FortigateInterface, allMembers map[string]int, forti
}
if port.InterfaceType == "physical" && len(allMembers) > 0 {
if parentIndex, ok := allMembers[port.Name]; ok {
if netboxInterface.Lag.ID == 0 {
matched.Parent = (*fortiInterfaces)[parentIndex].Name
} else {
if !strings.EqualFold(netboxInterface.Lag.Name, (*fortiInterfaces)[parentIndex].Name) {
if (*fortiInterfaces)[parentIndex].InterfaceType == "aggregate" {
if netboxInterface.Lag.ID == 0 {
matched.Parent = (*fortiInterfaces)[parentIndex].Name
} else {
if !strings.EqualFold(netboxInterface.Lag.Name, (*fortiInterfaces)[parentIndex].Name) {
matched.Parent = (*fortiInterfaces)[parentIndex].Name
}
}
} else if (*fortiInterfaces)[parentIndex].InterfaceType == "bridge" {
if netboxInterface.Bridge.ID == 0 {
matched.Parent = (*fortiInterfaces)[parentIndex].Name
} else {
if !strings.EqualFold(netboxInterface.Bridge.Name, (*fortiInterfaces)[parentIndex].Name) {
matched.Parent = (*fortiInterfaces)[parentIndex].Name
}
}
}

if matched.Parent != "" {
matched.ParentId = getParentID(matched.Parent, netboxDeviceInterfaces)
}

}
}
if port.InterfaceType == "vlan" {
Expand Down

0 comments on commit d384ba7

Please sign in to comment.