netbox

package
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 20, 2026 License: AGPL-3.0 Imports: 23 Imported by: 0

Documentation

Index

Constants

View Source
const CableLabelLLDP = "lldp"

CableLabelLLDP is the dcim.Cable.label written on cables created from LLDP neighbors. device-sync only creates, retargets, or deletes cables with this exact label so operator-drawn cables stay untouched.

Variables

View Source
var ErrInvalidLocation = errors.New("invalid location")

ErrInvalidLocation is a caller-input problem (missing coords, placeholder site name, device not in Netbox) rather than a Netbox/DB failure.

Functions

func ApplyCable

func ApplyCable(db *gorm.DB, netboxID uint, cable *netboxtool.NBCable) (created, updated, deleted, skipped int, err error)

ApplyCable upserts or removes one Connection. cable == nil means the object is gone or not interface-to-interface — delete the local row. Unresolved endpoints also drop the local row (skip=1) rather than leave a stale Connection pointing at the old terminations.

func ApplySite

func ApplySite(db *gorm.DB, netboxID uint, site *netboxtool.NetboxSite) (created, updated, deleted int, err error)

ApplySite upserts or removes one dcim.site row. site == nil means gone or Default — delete the local synced row. Missing coordinates no longer delete the row; the org tree keeps unplotted sites. Parent is left unchanged so a map pin does not strip a synced region parent.

func Check

func Check(c *util.ConfigRoot, opts CheckOptions, reporter jobevent.Reporter) error

Check verifies Netbox webhooks/event rules and the custom fields factum needs. Without Update it only reports. With Update it creates missing webhooks, event rules and fields, and patches mutable attributes (custom field type is never changed).

func CheckDB

func CheckDB(nb checkAPI, settings *models.Settings, opts CheckOptions, reporter jobevent.Reporter) error

CheckDB is Check against an already-built client and Settings row.

func CreateLLDPCable added in v1.0.3

func CreateLLDPCable(nb cableWriter, aInterfaceID, bInterfaceID uint) (*netboxtool.NBCable, error)

CreateLLDPCable creates a cable between two interfaces and marks it as LLDP-owned.

func DeleteConnectionByNetboxID

func DeleteConnectionByNetboxID(db *gorm.DB, netboxID uint) (int, error)

DeleteConnectionByNetboxID removes one Connection by its Netbox cable id and marks optical paths that used it stale. No-op if none matches.

func DeleteDeviceByNetboxID

func DeleteDeviceByNetboxID(db *gorm.DB, netboxID uint, vm bool) (int, error)

DeleteDeviceByNetboxID removes one netbox-sourced device (or VM) by its Netbox primary key. Used by the webhook delete path: Netbox has already removed the object, so it cannot be re-fetched and upserted. Returns 1 if a row was deleted, 0 if none matched (already gone, or cf_source != "netbox" — matching deleteMissingDevices' guard). vm must match the object's table: Netbox's dcim.Device and virtualization.VirtualMachine IDs are independent sequences, so a device and a VM can share a NetboxID.

func DeleteFactumInterface added in v1.1.0

func DeleteFactumInterface(db *gorm.DB, interfaceID uint) error

DeleteFactumInterface removes a factum interfaces row together with its addresses, tags, cables, and optical rows. GUI interface refresh calls this after deleting the matching Netbox object (or when the factum row had no Netbox ID).

func DeleteSiteByNetboxID

func DeleteSiteByNetboxID(db *gorm.DB, netboxID uint) (int, error)

DeleteSiteByNetboxID removes the synced dcim.site row for netboxID.

func DeleteSyncedSiteNode added in v1.1.0

func DeleteSyncedSiteNode(db *gorm.DB, kind string, netboxID uint) (int, error)

DeleteSyncedSiteNode removes the synced row for a region, site, or location.

func FetchRemoteConfig

func FetchRemoteConfig(factumConfig *util.ConfigFactum) (*util.ConfigNetbox, error)

FetchRemoteConfig pulls the Netbox API connection settings from the primary, authenticated with factumConfig.Token (checked against the primary's Settings.FactumApiToken - see web.Controller.checkServiceToken).

func FindOrCreateTenant

func FindOrCreateTenant(nb *netboxtool.NetboxClient, customer models.Customer) (*netboxtool.NBTenant, error)

FindOrCreateTenant returns the Netbox tenant for customer, matched via the same "source"="factum"/"source_id"=<customer.ID> custom fields syncCustomersToNetbox uses. Provisioning paths (currently generic service NetBox reconcile, when it assigns a service's L2VPN to its customer's tenant) call this directly instead of waiting for the next scheduled Netbox sync, so a customer's first service still gets a tenant even if Netbox sync hasn't run since the customer was created.

This runs synchronously in a user-facing request, so it looks the tenant up via nb.GetTenant's filtered REST call rather than nb.GetTenants' full tenant-table fetch - the latter used to mean every service update paid for pulling every Netbox tenant just to find one. GetTenants is only consulted on a miss, to adopt an existing same-name tenant (or pick a unique slug) instead of POSTing a name that already exists.

If a same-name tenant is already claimed by a different factum customer (duplicate customer rows sharing a Netbox-unique name), the existing tenant is returned as-is rather than erroring: the caller only needs a tenant id to hang an L2VPN on, and stealing the claim would take the tenant away from its owner. Bulk customer sync still skips that case.

func IsLLDPCable added in v1.0.3

func IsLLDPCable(c *netboxtool.NBCable) bool

IsLLDPCable reports whether c is owned by LLDP auto-cabling.

func RemoteClient

func RemoteClient(factumConfig *util.ConfigFactum) (*netboxtool.NetboxClient, error)

RemoteClient fetches util.ConfigNetbox from the primary and builds a netboxtool.NetboxClient from it.

func ReverseGeocode added in v1.0.5

func ReverseGeocode(lat, lng float64) (string, error)

ReverseGeocode turns lat/lng into a Netbox physical_address string using OSM Nominatim. Empty string, nil means nothing useful came back (ocean, no coverage) — not an error. Transport / HTTP failures are errors.

func Sync

func Sync(c *util.ConfigRoot, name string, reporter jobevent.Reporter) error

Fetch all devices (with their interfaces, addresses and tags) from Netbox and update the factum database.

If name is specified, only that device is synced. Otherwise every device is synced and any device previously imported from Netbox (cf_source == "netbox") that no longer exists there is removed, together with its interfaces, addresses and tags.

Interfaces, addresses and tags belonging to a synced device are always reconciled against Netbox: anything no longer present there is removed from factum, whether the sync is for a single device or all of them. Cable, site, VRF, interface type, customer, contact, and L2VPN→service import only run on a full sync.

func SyncCable

func SyncCable(db *gorm.DB, netboxID uint, reporter jobevent.Reporter) error

SyncCable applies one Netbox cable to factum's Connection table: refetch by id, upsert if both ends resolve to synced interfaces, otherwise remove any local row for that netbox_id. Used by the webhook; full sync still goes through syncCables.

func SyncDB

func SyncDB(db *gorm.DB, name string, reporter jobevent.Reporter) error

SyncDB is Sync against an already-connected database, for callers that already hold a shared *gorm.DB (currently just the Netbox webhook handler, web.ApiNetboxWebhook) - opening a brand new, unbounded connection pool on every single webhook call is what exhausted Postgres's max_connections under a burst of Netbox webhooks.

func SyncDCIMTreeItem added in v1.1.0

func SyncDCIMTreeItem(db *gorm.DB, kind string, netboxID uint, reporter jobevent.Reporter) error

SyncDCIMTreeItem applies one NetBox region/site/location. A missing or Default object deletes the matching local synced row.

func SyncLocation added in v1.1.0

func SyncLocation(db *gorm.DB, netboxID uint, reporter jobevent.Reporter) error

SyncLocation applies one Netbox dcim.location to factum's Site table.

func SyncRegion added in v1.1.0

func SyncRegion(db *gorm.DB, netboxID uint, reporter jobevent.Reporter) error

SyncRegion applies one Netbox dcim.region to factum's Site table.

func SyncSite

func SyncSite(db *gorm.DB, netboxID uint, reporter jobevent.Reporter) error

SyncSite applies one Netbox dcim.site to factum's Site table.

Types

type AssignLocationInput added in v1.0.5

type AssignLocationInput struct {
	SiteName        string
	Latitude        *float64
	Longitude       *float64
	PhysicalAddress string
}

AssignLocationInput is the GUI's "put this device here" request. SiteName is optional: empty writes GPS onto the device itself (one chassis, no site to share). When set, a Netbox site is created/updated and the device is assigned to it. Latitude/Longitude are required when creating a site, when the named site has no coordinates yet, or when pinning the device with no site; omitted they keep an already-plotted site's position.

type AssignLocationResult added in v1.0.5

type AssignLocationResult struct {
	Device models.Device
	Site   *models.Site
}

AssignLocationResult is the local Device (and Site, when a site was assigned) after a successful Netbox write and factum mirror.

func AssignDeviceLocation added in v1.0.5

func AssignDeviceLocation(db *gorm.DB, nb *netboxtool.NetboxClient, device models.Device, in AssignLocationInput) (*AssignLocationResult, error)

AssignDeviceLocation writes GPS to Netbox and mirrors it into factum. With a site name it creates/updates that site, assigns the device, and the device inherits the site's coordinates the same way netbox sync does. With no site name it PATCHes latitude/longitude on the device itself and leaves its site alone — for a lone chassis a site is overhead.

type CheckOptions

type CheckOptions struct {
	Update bool
}

CheckOptions controls Check. Update=false (default) only reports. Update=true creates/updates custom fields, the factum webhook, and its event rule when they are missing or have drifted.

type CustomFieldWrite added in v1.0.4

type CustomFieldWrite struct {
	Name        string
	Type        string
	Label       string
	Description string
	GroupName   string
	Required    bool
	ObjectTypes []string
	ChoiceSetID uint
}

CustomFieldWrite is the body for creating a custom field.

type EventRuleWrite added in v1.0.4

type EventRuleWrite struct {
	Name           string
	Enabled        bool
	ObjectTypes    []string
	EventTypes     []string
	ActionType     string
	ActionObjectID uint
}

EventRuleWrite is the body for creating extras.EventRule.

type NBChoiceSet added in v1.0.4

type NBChoiceSet struct {
	NetboxID     uint
	Name         string
	ExtraChoices [][2]string
}

NBChoiceSet is extras.CustomFieldChoiceSet. ExtraChoices are [value, label] pairs Netbox stores on the set (not on the custom field).

type NBContact added in v1.0.5

type NBContact struct {
	NetboxID   uint
	Name       string
	Email      string
	Phone      string
	CfSource   string
	CfSourceID string
}

NBContact is a tenancy.Contact row as this package needs it.

type NBContactAssignment added in v1.0.5

type NBContactAssignment struct {
	NetboxID   uint
	ObjectType string
	ObjectID   uint
	ContactID  uint
	RoleID     uint
}

NBContactAssignment is a tenancy.ContactAssignment row, flattened to ids.

type NBContactRole added in v1.0.5

type NBContactRole struct {
	NetboxID uint   `json:"id"`
	Name     string `json:"name"`
	Slug     string `json:"slug"`
}

NBContactRole is a tenancy.ContactRole row.

type NBEventRule added in v1.0.4

type NBEventRule struct {
	NetboxID       uint
	Name           string
	Enabled        bool
	ObjectTypes    []string
	EventTypes     []string
	ActionType     string
	ActionObjectID uint
	// Conditions is the optional JSON condition object; nil/empty means
	// the rule fires for every matching event.
	Conditions any
}

NBEventRule is extras.EventRule — binds object types and event types to an action (typically a webhook). ActionObjectID is the extras.Webhook id when ActionType is "webhook".

func (*NBEventRule) HasConditions added in v1.0.4

func (r *NBEventRule) HasConditions() bool

HasConditions reports whether the rule has a non-empty condition object that would restrict which events actually fire.

func (*NBEventRule) HasEvent added in v1.0.4

func (r *NBEventRule) HasEvent(eventType string) bool

HasEvent reports whether the rule lists eventType (e.g. "object_deleted").

func (*NBEventRule) HasObjectType added in v1.0.4

func (r *NBEventRule) HasObjectType(objectType string) bool

HasObjectType reports whether the rule lists objectType (e.g. "dcim.device").

type NBWebhook added in v1.0.4

type NBWebhook struct {
	NetboxID        uint
	Name            string
	PayloadURL      string
	HTTPMethod      string
	HTTPContentType string
	BodyTemplate    string
}

NBWebhook is extras.Webhook — the destination half of Netbox 3.7+'s webhook/event-rule split. Object types and events live on NBEventRule.

type WebhookWrite added in v1.0.4

type WebhookWrite struct {
	Name            string
	PayloadURL      string
	HTTPMethod      string
	HTTPContentType string
	BodyTemplate    string
	Secret          string
	SSLVerification bool
}

WebhookWrite is the body for creating extras.Webhook.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL