Newer
Older
"context"
"log"
"os"
"code.fbi.h-da.de/danet/gosdn/api/go/gosdn/networkelement"
"code.fbi.h-da.de/danet/gosdn/applications/inventory-manager-netbox/config"
netboxapi "code.fbi.h-da.de/danet/gosdn/internal/netboxapi"
temp "code.fbi.h-da.de/danet/gosdn/models/generated/openconfig"
"github.com/openconfig/gnmi/proto/gnmi"
"github.com/openconfig/ygot/ytypes"
func FeedNetbox(elements *networkelement.GetAllResponse, configPathNetbox *string) error {
var manufacturerID int32
var deviceTypeID int32
var deviceRoleID int32
var siteID int32
var deviceID int32
var ifaceID int32
var ipID int32
//ctx := context.Background()
data, err := os.ReadFile(*configPathNetbox)
log.Printf("Error reading configuration file: %v", err)
return err
// YAML in Config-Struct einlesen
netboxconfig := &config.NetboxConfig{}
if err := yaml.Unmarshal(data, netboxconfig); err != nil {
log.Printf("Error parsing Netbox Config / YAML file: %v", err)
return err
log.Printf("Netbox Config Adresse: %v", netboxconfig.NetboxAddress)
log.Printf("Netbox Config Token: %v", netboxconfig.ApiToken)
client := netboxapi.NewAPIClientFor("http://"+netboxconfig.NetboxAddress, netboxconfig.ApiToken)
manufacturerID = makeManufacturer(client)
deviceTypeID = makeDeviceType(client, manufacturerID)
deviceRoleID = makeDeviceRole(client)
siteID = makeSite(client)
log.Printf(" ")
log.Printf(" ")
if (manufacturerID == 0) || (deviceTypeID == 0) || (deviceRoleID == 0) || (siteID == 0) {
log.Printf("ich kann kein Gerät hinzufügen, weil ich nicht alle ID habe")
return err
} else {
if elements != nil {
for _, element := range elements.Mne {
modelFormGNMI, err := GetModelAsStruct(element.GetMneNotification())
if err != nil {
log.Printf("Fehler beim Umwandeln des Element: %v", err)
log.Printf("ModelAsStruct modelFormGNMI: %v", modelFormGNMI)
}
deviceID = makeDevice(client, element.Name, deviceTypeID, deviceRoleID, siteID, element.Id, element.Plugin.String(), "active")
//log.Printf("Gerät erstellt createdDevice: %v ", deviceID)
for name, iface := range modelFormGNMI.Interfaces.Interface {
if iface == nil {
continue
}
log.Printf("")
log.Printf("")
//log.Printf("Interface Name (Key): %s", name)
interfaceType := netboxapi.InterfaceTypeValue("1000base-t")
ifaceID = makeInterface(client, name, deviceID, interfaceType, "Beschreibungstext, hier kann was sinvolle rein", true)
log.Printf("Interface erstellt mit der ID: %v ", ifaceID)
for idx, subif := range iface.Subinterfaces.Subinterface {
log.Printf("Subinterface [%d] index: %v", idx, *subif.Index)
if subif.Ipv4 != nil && subif.Ipv4.Addresses != nil {
for k := range subif.Ipv4.Addresses.Address {
ipID = int32(makeIPAddress(client, k+"/24", element.GetName()+"das ist der Beschreibungtext", "active", "dcim.interface", int64(ifaceID)))
log.Printf("IP Adresse erstellt mit der ID: %v ", ipID)
}
}
if subif.Ipv6 != nil && subif.Ipv6.Addresses != nil {
for k := range subif.Ipv6.Addresses.Address {
ipID = int32(makeIPAddress(client, k+"/64", element.GetName()+"das ist der beschreibungtext", "active", "dcim.interface", int64(ifaceID)))
log.Printf("IP Adresse erstellt mit der ID: %v ", ipID)
}
}
}
func makeManufacturer(client *netboxapi.APIClient) int32 {
var ManufacturerID int32
ManufacturerID = 0
slug := "EindeutigerName4"
manufacturer := CreateManufacturer("Grosse Box hersteller4", slug, "Wichtig gros und ganz alleine da oben")
//createdManufacturer, reqManufacturer, err := client.DcimAPI.DcimManufacturersCreate(context.Background()).ManufacturerRequest(*manufacturer).Execute()
created, resp, err := client.DcimAPI.DcimManufacturersCreate(context.Background()).ManufacturerRequest(*manufacturer).Execute()
log.Printf("Fehler beim Erstellen des Herstellers: %v", err)
log.Printf("Fehler beim Erstellen des Herstellers, reqManufacturer: %v", resp.Status)
//suche nach slug
manufacturerList, resp, err := client.DcimAPI.DcimManufacturersList(context.Background()).Slug([]string{slug}).Execute()
if err != nil {
log.Printf("Fehler beim Abfragen des Herstellers: %v", err)
//return err
}
if len(manufacturerList.Results) > 0 {
existingManufacturer := manufacturerList.Results[0]
ManufacturerID = existingManufacturer.Id
log.Printf("Hersteller existiert bereits mit ID: %d", ManufacturerID)
log.Printf("Hersteller existiert bereits mit der URL: %v", existingManufacturer.Url)
} else {
log.Printf("Hersteller mit Slug '%s' nicht gefunden.", slug)
log.Printf("Fehler: %v", resp.Status)
}
} else {
ManufacturerID = created.Id
log.Printf("Jippi, Herstller angelegt: %v", ManufacturerID)
log.Printf("Jippi, Die Link zu dem Gerät lautet: %v", created.Url)
return ManufacturerID
}
func makeDeviceType(client *netboxapi.APIClient, manufacturerID int32) int32 {
var deviceTypeID int32 = 0
slug := "eindeutige-id-slug" // genau so wie du ihn in CreateDeviceType übergibst
model := "model"
uHeight := float64(5)
manufacturerRef := netboxapi.Int32AsBriefDeviceTypeRequestManufacturer(&manufacturerID)
deviceType := CreateDeviceType(manufacturerRef, model, slug, uHeight)
created, resp, err := client.DcimAPI.DcimDeviceTypesCreate(context.Background()).
WritableDeviceTypeRequest(*deviceType).
Execute()
log.Printf("Fehler beim Erstellen des Gerätetyps: %v", err)
log.Printf("Fehler beim Erstellen des Gerätetyps, reqDeviceType: %v", resp.Status)
// versuche über Slug zu finden
list, resp, err := client.DcimAPI.DcimDeviceTypesList(context.Background()).Slug([]string{slug}).Execute()
if err != nil {
log.Printf("Fehler beim Abfragen des Device Types: %v", err)
} else if len(list.Results) > 0 {
existing := list.Results[0]
deviceTypeID = existing.Id
log.Printf("Device Type existiert bereits mit ID: %d", deviceTypeID)
log.Printf("Device Type existiert bereits unter: %v", existing.Url)
} else {
log.Printf("Kein Device Type mit Slug '%s' gefunden.", slug)
log.Printf("Fehler: %v", resp.Status)
} else {
deviceTypeID = created.Id
log.Printf("Gerätetyp erfolgreich angelegt: ID %d", deviceTypeID)
log.Printf("URL zum Gerätetyp: %s", created.Url)
}
return deviceTypeID
}
func makeDeviceRole(client *netboxapi.APIClient) int32 {
var deviceRoleID int32 = 0
slug := "grossUndWichtig" // muss slug-konform sein (keine Leerzeichen, Kleinbuchstaben)
role := CreateDeviceRole("Wichtige Box", slug, "Ist WohlWichtigGenug, damit es hier ist", "ff0000")
created, resp, err := client.DcimAPI.DcimDeviceRolesCreate(context.Background()).
DeviceRoleRequest(*role).
Execute()
if err != nil {
log.Printf("Fehler beim Erstellen der Device Role: %v", err)
log.Printf("Fehlerhafte Antwort: %v", resp.Status)
// versuche, die Rolle über den Slug zu finden
list, resp, err := client.DcimAPI.DcimDeviceRolesList(context.Background()).Slug([]string{slug}).Execute()
if err != nil {
log.Printf("Fehler beim Abfragen der Device Role: %v", err)
} else if len(list.Results) > 0 {
existing := list.Results[0]
deviceRoleID = existing.Id
log.Printf("Device Role existiert bereits mit ID: %d", deviceRoleID)
log.Printf("Device Role URL: %s", existing.Url)
} else {
log.Printf("Keine Device Role mit Slug '%s' gefunden.", slug)
log.Printf("Fehler: %v", resp.Status)
deviceRoleID = created.Id
log.Printf("Device Role erfolgreich erstellt: ID %d", deviceRoleID)
log.Printf("Device Role URL: %s", created.Url)
return deviceRoleID
func makeSite(client *netboxapi.APIClient) int32 {
var siteID int32 = 0
slug := "darmstadt-der-groe" // slug muss URL-konform sein
site := CreateSite(
"Darmstadt v2",
slug,
"Ort brauchen eine beschreibung",
"In der Uni und dann in den Keller oder ins Labor",
"Da so und dann Links",
"comments",
)
created, resp, err := client.DcimAPI.DcimSitesCreate(context.Background()).
WritableSiteRequest(*site).
Execute()
log.Printf("Fehler beim Erstellen der Site: %v", err)
log.Printf("Fehlerhafte Antwort: %v", resp.Status)
// versuche, die Site über den Slug zu finden
list, resp, err := client.DcimAPI.DcimSitesList(context.Background()).Slug([]string{slug}).Execute()
if err != nil {
log.Printf("Fehler beim Abfragen der Site: %v", err)
} else if len(list.Results) > 0 {
existing := list.Results[0]
siteID = existing.Id
log.Printf("Site existiert bereits mit ID: %d", siteID)
log.Printf("Site URL: %s", existing.Url)
} else {
log.Printf("Keine Site mit Slug '%s' gefunden.", slug)
log.Printf("Fehler: %v", resp.Status)
}
} else {
siteID = created.Id
log.Printf("Site erfolgreich erstellt: ID %d", siteID)
log.Printf("Site URL: %s", created.Url)
return siteID
}
func makeDevice(client *netboxapi.APIClient, name string, deviceTypeID, roleID, siteID int32, serial, description, status string) int32 {
var deviceID int32 = 0
// Gerät anlegen
device := CreateDevice(name, deviceTypeID, roleID, siteID, serial, description, status)
// Versuch, das Gerät zu erstellen
createdDevice, resp, err := client.DcimAPI.
DcimDevicesCreate(context.Background()).
WritableDeviceWithConfigContextRequest(*device).
Execute()
//log.Printf("Fehler beim Erstellen des Geräts: %v", err)
if resp != nil {
log.Printf("HTTP-Status: %s", resp.Status)
}
// Fallback: Searching for the Device with the name
existing, resp, err := client.DcimAPI.
DcimDevicesList(context.Background()).
Name([]string{name}).
Execute()
if err != nil {
log.Printf("Fehler bei der Gerätesuche: %v", err)
} else if len(existing.Results) > 0 {
deviceID = existing.Results[0].Id
log.Printf("Gerät existiert bereits: ID %d, URL: %s", deviceID, existing.Results[0].Url)
} else {
log.Printf("Kein bestehendes Gerät mit Name '%s' gefunden.", name)
log.Printf("Status: %d", resp.StatusCode)
}
} else {
deviceID = createdDevice.Id
log.Printf("Gerät erfolgreich erstellt: ID %d, URL: %s", deviceID, createdDevice.Url)
return deviceID
}
func makeInterface(client *netboxapi.APIClient, name string, deviceID int32, interfaceType netboxapi.InterfaceTypeValue, description string, enabled bool) int32 {
var interfaceID int32 = 0
// NetBox erwartet ein BriefInterfaceRequestDevice
deviceRef := netboxapi.Int32AsBriefInterfaceRequestDevice(&deviceID)
iface := CreateInterface(name, deviceRef, interfaceType, description, enabled)
createdIface, resp, err := client.DcimAPI.
DcimInterfacesCreate(context.Background()).
WritableInterfaceRequest(*iface).
Execute()
log.Printf("Fehler beim Erstellen der Schnittstelle: %v", err)
if resp != nil {
log.Printf("HTTP Status: %s", resp.Status)
}
// Suche nach bestehender Schnittstelle mit Name + Device
existing, resp, err := client.DcimAPI.
DcimInterfacesList(context.Background()).
Name([]string{name}).
DeviceId([]int32{deviceID}).
Execute()
if err != nil {
log.Printf("Fehler bei Schnittstellen-Suche: %v", err)
} else if len(existing.Results) > 0 {
interfaceID = existing.Results[0].Id
log.Printf("Schnittstelle existiert bereits: ID %d, URL: %s", interfaceID, existing.Results[0].Url)
} else {
log.Printf("Keine bestehende Schnittstelle '%s' gefunden für Device-ID %d.", name, deviceID)
log.Printf("Status: %d", resp.StatusCode)
}
} else {
interfaceID = createdIface.Id
log.Printf("Schnittstelle erfolgreich erstellt: ID %d, URL: %s", interfaceID, createdIface.Url)
return interfaceID
}
func makeIPAddress(client *netboxapi.APIClient, address, description, status, assignedType string, interfaceID int64) int64 {
var ipID int64 = 0
//addressWithoutPort := extractIP(address)
//addressWithoutPort = addressWithoutPort + "/32"
//ip := CreateIPAddress(address, description, "active", "dcim.interface", interfaceID)
ip := CreateIPAddress(address, description, status, assignedType, interfaceID)
createdIP, resp, err := client.IpamAPI.
IpamIpAddressesCreate(context.Background()).
WritableIPAddressRequest(*ip).
Execute()
log.Printf("Fehler beim Erstellen der IP-Adresse: %v", err)
if resp != nil {
log.Printf("Fehlerhafte Antwort: %v", address)
log.Printf("HTTP Status: %s", resp.Status)
log.Printf("HTTP Request: %v", resp.Request)
log.Printf("HTTP Body: %s", resp.Body)
log.Printf("HTTP StatusCode: %d", resp.StatusCode)
}
// Suche nach bereits existierender IP-Adresse
existing, resp, err := client.IpamAPI.IpamIpAddressesList(context.Background()).Address([]string{address}).Execute()
if err != nil {
log.Printf("Fehler beim Suchen nach IP-Adresse '%s': %v", address, err)
} else if len(existing.Results) > 0 {
ipID = int64(existing.Results[0].Id) // für Fehler 8
log.Printf("IP-Adresse existiert bereits: ID %d, URL: %s", ipID, existing.Results[0].Url)
} else {
log.Printf("Keine bestehende IP-Adresse gefunden: %s", address)
log.Printf("Status: %d", resp.StatusCode)
}
} else {
ipID := int64(createdIP.Id)
log.Printf("IP-Adresse erfolgreich erstellt: ID %d, URL: %s", ipID, createdIP.Url)
return ipID
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
func GetModelAsStruct(gnmiNotifications []*gnmi.Notification) (*temp.Device, error) {
modelAsSchema := ytypes.Schema{
Root: &temp.Device{},
SchemaTree: temp.SchemaTree,
}
err := ytypes.UnmarshalNotifications(&modelAsSchema, gnmiNotifications, &ytypes.IgnoreExtraFields{})
if err != nil {
return nil, err
}
modelAsStruct, ok := modelAsSchema.Root.(*temp.Device)
if !ok {
return nil, errors.New("dynamic cast fail")
}
return modelAsStruct, nil
}
/*
func extractPort(address string) string {
parts := strings.Split(address, ":")
if len(parts) == 2 {
return parts[1]
}
return address // falls kein Doppelpunkt vorhanden ist
}
func extractIP(address string) string {
parts := strings.Split(address, ":")
if len(parts) == 2 {
return parts[0]
}
return address
}
*/