Skip to content

Commit dcb59ce

Browse files
authored
init (#1)
* init structure * netbox device api * go workers * loops * small changes * init parsing * done with parsing * refactor + prepare to upload to netbox * refactor + inital update * create and update basic interfaces * update & create * remove debug * add virtual switch * virtual switch part 2 * redundant interface * fix aggr * Update readme
1 parent 6d92ab4 commit dcb59ce

File tree

14 files changed

+1477
-1
lines changed

14 files changed

+1477
-1
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,6 @@
2020
# Go workspace file
2121
go.work
2222
go.work.sum
23+
24+
configs/settings.json
25+
/netbox-oxidized-sync

.golangci.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
linters:
2+
enable:
3+
- ireturn
4+
# - err113
5+
- revive
6+
# - gosec
7+
- errcheck
8+
- nilnil
9+
- nilerr
10+
- asasalint
11+
- bodyclose
12+
- fatcontext

.vscode/launch.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"name": "Launch Package",
9+
"type": "go",
10+
"request": "launch",
11+
"mode": "auto",
12+
"program": "${workspaceFolder}/cmd/netbox-oxidized-sync/",
13+
"cwd": "${workspaceFolder}"
14+
}
15+
]
16+
}

README.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,26 @@
11
# netbox-oxidized-sync
2-
Sync Oxidized data to Netbox
2+
Sync Oxidized data to Netbox.
3+
4+
The device has to exists within netbox with the same name.
5+
This is because we need to get the tenant and the site from netbox. (oxidized does not have that info)
6+
7+
Currently supports FortiOS.
8+
Within FortiOS, the following items are synced
9+
10+
| Type | Supported |
11+
|---|---|
12+
| Vlans | ✓ |
13+
| Aggregate ports | ✓ |
14+
| Virtual switches | ✓ |
15+
| Redundant Ports | ✓ |
16+
| Normal Ports | ✓ |
17+
| Ip Adresses | ✗ |
18+
19+
20+
## Use
21+
Currently there is no published binary so you have to build it yourself.
22+
23+
Clone the repo and run `go build cmd/netbox-oxidized-sync/netbox-oxidized-sync.go`
24+
Then you can run `./netbox-oxidized-sync` to run the binary.
25+
26+
To configure the application copy the `configs/example.settings.json` to `configs/settings.json` and modify where needed.
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package main
2+
3+
import (
4+
"log"
5+
"slices"
6+
"strconv"
7+
8+
"github.com/mattieserver/netbox-oxidized-sync/internal/confighelper"
9+
"github.com/mattieserver/netbox-oxidized-sync/internal/configparser"
10+
"github.com/mattieserver/netbox-oxidized-sync/internal/httphelper"
11+
"github.com/mattieserver/netbox-oxidized-sync/internal/model"
12+
"github.com/mattieserver/netbox-oxidized-sync/internal/netboxparser"
13+
)
14+
15+
func worker(id int, jobs <-chan httphelper.OxidizedNode, results chan<- int, netboxdevices *[]model.NetboxDevice, oxidizedhttp *httphelper.OxidizedHTTPClient, netboxhttp *httphelper.NetboxHTTPClient) {
16+
for j := range jobs {
17+
log.Printf("Got oxided device: '%s' on worker %s",j.Name, strconv.Itoa(id), )
18+
19+
idx := slices.IndexFunc(*netboxdevices, func(c model.NetboxDevice) bool { return c.Name == j.Name })
20+
if idx == -1 {
21+
log.Printf("Device: '%s' not found in netbox", j.Name)
22+
} else {
23+
log.Printf("Device: '%s' found in netbox", j.Name)
24+
config := oxidizedhttp.GetNodeConfig(j.FullName)
25+
26+
switch j.Model {
27+
case "IOS":
28+
log.Println("IOS not supported for now")
29+
case "FortiOS":
30+
log.Printf("Device: '%s' has fortiOS", j.Name)
31+
fortigateInterfaces, _ := configparser.ParseFortiOSConfig(&config)
32+
var netboxDevice = (*netboxdevices)[idx]
33+
netboxInterfaceForDevice := netboxhttp.GetIntefacesForDevice(strconv.Itoa(netboxDevice.ID))
34+
netboxVlansForSite, err := netboxhttp.GetVlansForSite(strconv.Itoa(netboxDevice.Site.ID))
35+
if err != nil {
36+
continue
37+
}
38+
interfacesToUpdate := netboxparser.ParseFortigateInterfaces(fortigateInterfaces, &netboxInterfaceForDevice, strconv.Itoa(netboxDevice.ID))
39+
netboxhttp.UpdateOrCreateInferface(&interfacesToUpdate, &netboxVlansForSite, netboxDevice.Site.ID, netboxDevice.Tenant.ID)
40+
41+
default:
42+
log.Printf("Model '%s' currently not supported", j.Model)
43+
}
44+
}
45+
46+
results <- id * 2
47+
}
48+
}
49+
50+
func loadOxidizedDevices(oxidizedhttp *httphelper.OxidizedHTTPClient, netboxhttp *httphelper.NetboxHTTPClient) {
51+
log.Println("Starting to get all Oxidized Devices")
52+
nodes := oxidizedhttp.GetAllNodes()
53+
log.Println("Got all Oxidized Devices")
54+
55+
log.Println("Starting to get all Netbox Devices")
56+
devices := netboxhttp.GetAllDevices()
57+
log.Println("Got all Netbox Devices")
58+
59+
jobs := make(chan httphelper.OxidizedNode, len(nodes))
60+
results := make(chan int, len(nodes))
61+
62+
for w := 1; w <= 3; w++ {
63+
go worker(w, jobs, results, &devices, oxidizedhttp, netboxhttp)
64+
}
65+
66+
for _, element := range nodes {
67+
jobs <- element
68+
}
69+
close(jobs)
70+
71+
for a := 1; a <= len(nodes); a++ {
72+
<-results
73+
}
74+
75+
}
76+
77+
func main() {
78+
log.Println("Starting Oxidized to Netbox sync")
79+
80+
conf := confighelper.ReadConfig()
81+
log.Printf("Using Netbox: %s", conf.Netbox.BaseURL)
82+
log.Printf("Using Oxidized: %s", conf.Oxidized.BaseURL)
83+
84+
netboxhttp := httphelper.NewNetbox(conf.Netbox.BaseURL, conf.Netbox.APIKey, conf.Netbox.Roles)
85+
oxidizedhttp := httphelper.NewOxidized(conf.Oxidized.BaseURL, conf.Oxidized.Username, conf.Oxidized.Password)
86+
87+
loadOxidizedDevices(&oxidizedhttp, &netboxhttp)
88+
}

configs/example.settings.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"netbox": {
3+
"base_url": "http://localhost:8000",
4+
"api_key": "xxxx-xxxx-xxxx",
5+
"roles": ""
6+
},
7+
"oxidized": {
8+
"base_url": "http://localhost:8001",
9+
"username": "XXXXX",
10+
"password": "YYYY"
11+
}
12+
}

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module github.com/mattieserver/netbox-oxidized-sync
2+
3+
go 1.22.1

internal/confighelper/confighelper.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package confighelper
2+
3+
import (
4+
"os"
5+
"log"
6+
"encoding/json"
7+
)
8+
9+
type Config struct {
10+
Netbox struct {
11+
BaseURL string `json:"base_url"`
12+
APIKey string `json:"api_key"`
13+
Roles string `json:"roles"`
14+
} `json:"netbox"`
15+
Oxidized struct {
16+
BaseURL string `json:"base_url"`
17+
Username string `json:"username"`
18+
Password string `json:"password"`
19+
} `json:"oxidized"`
20+
}
21+
22+
func ReadConfig() Config {
23+
f, err := os.ReadFile("configs/settings.json")
24+
if err != nil {
25+
log.Println(err)
26+
}
27+
28+
var data Config
29+
json.Unmarshal([]byte(f), &data)
30+
31+
return data
32+
33+
}

0 commit comments

Comments
 (0)