Documentation
¶
Overview ¶
Package netboxtool is Factum's NetBox GraphQL/REST client (devices, VMs, interfaces, addresses, cables, VRFs, L2VPNs). Reads go through GraphQL; writes go through REST. See README.md in this directory for query architecture and pagination notes.
Index ¶
- type Cache
- type CacheSource
- type ConfigNetbox
- type ConfigRoot
- type InterfaceCustomFields
- type InterfaceTypeChoice
- type JSONDevice
- type JSONDevices
- type JSONInterface
- type JSONSites
- type JSONTenant
- type JSONTenants
- type JSONVMs
- type NBAddress
- type NBCable
- type NBCustomField
- type NBDecimal
- type NBDevice
- type NBInterface
- type NBL2VPN
- type NBL2VPNTermination
- type NBModel
- type NBParent
- type NBPrefix
- type NBTag
- type NBTenant
- type NBVRF
- type NBVlan
- type NBVlanGroup
- type NetboxAddress
- type NetboxAddressREST
- type NetboxClient
- func (nb *NetboxClient) AddressCreate(address string) (*NetboxAddressREST, error)
- func (nb *NetboxClient) AddressDelete(address_id int) error
- func (nb *NetboxClient) AddressUpdate(address_id int, changes map[string]any) error
- func (nb *NetboxClient) CreateCable(aInterfaceID, bInterfaceID uint) (*NBCable, error)
- func (nb *NetboxClient) CreateCableWithOptions(aInterfaceID, bInterfaceID uint, extra map[string]any) (*NBCable, error)
- func (nb *NetboxClient) CreateDevice(name string, extra map[string]any) (*NetboxDeviceREST, error)
- func (nb *NetboxClient) CreateInterfaceAddress(interfaceID uint, address string, extra map[string]any) (*NBAddress, error)
- func (nb *NetboxClient) CreateInterfaceWithOptions(deviceID uint, name string, extra map[string]any) (*NetboxInterfaceREST, error)
- func (nb *NetboxClient) CreateL2VPN(name, slug, l2vpnType string, identifier int) (*NBL2VPN, error)
- func (nb *NetboxClient) CreateL2VPNTermination(l2vpnID, interfaceID uint) (*NBL2VPNTermination, error)
- func (nb *NetboxClient) CreatePrefix(prefix string) (*NBPrefix, error)
- func (nb *NetboxClient) CreateSite(name, slug string, extra map[string]any) (*NetboxSiteREST, error)
- func (nb *NetboxClient) CreateTenant(name, slug string, changes map[string]any) (*NetboxTenantREST, error)
- func (nb *NetboxClient) CreateVRF(name, rd, description string) (*NBVRF, error)
- func (nb *NetboxClient) CreateVlan(vid int, name string, groupID uint) (*NBVlan, error)
- func (nb *NetboxClient) CreateVlanGroup(name, slug string) (*NBVlanGroup, error)
- func (nb *NetboxClient) DeleteCable(cableID uint) error
- func (nb *NetboxClient) DeleteDevice(id int) error
- func (nb *NetboxClient) DeleteL2VPN(l2vpnID uint) error
- func (nb *NetboxClient) DeleteL2VPNTermination(terminationID uint) error
- func (nb *NetboxClient) EnsureTag(name, slug string) (*NetboxNamedRef, error)
- func (nb *NetboxClient) GetCable(cableID uint) (*NBCable, error)
- func (nb *NetboxClient) GetCables() ([]*NBCable, error)
- func (nb *NetboxClient) GetCustomField(name string) (*NBCustomField, error)
- func (nb *NetboxClient) GetDevice(name string, id int) (*NBDevice, error)
- func (nb *NetboxClient) GetDeviceRoleBySlug(slug string) (*NetboxNamedRef, error)
- func (nb *NetboxClient) GetDeviceType(manufacturer string, model string) (*NetboxDeviceTypeDetail, error)
- func (nb *NetboxClient) GetDevices() ([]*NBDevice, error)
- func (nb *NetboxClient) GetDevices_(name string, id int) ([]*NBDevice, error)
- func (nb *NetboxClient) GetInterfaceCable(cableID uint) (*NBCable, error)
- func (nb *NetboxClient) GetInterfaceTypeChoices() ([]InterfaceTypeChoice, error)
- func (nb *NetboxClient) GetL2VPN(l2vpnID uint) (*NBL2VPN, error)
- func (nb *NetboxClient) GetL2VPNByIdentifier(identifier int) (*NBL2VPN, error)
- func (nb *NetboxClient) GetL2VPNByName(name string) (*NBL2VPN, error)
- func (nb *NetboxClient) GetL2VPNTerminations(l2vpnID uint) ([]*NBL2VPNTermination, error)
- func (nb *NetboxClient) GetL2VPNs(l2vpnType string) ([]*NBL2VPN, error)
- func (nb *NetboxClient) GetManufacturer(name string, id int) (*NetboxManufacturer, error)
- func (nb *NetboxClient) GetPlatformBySlug(slug string) (*NetboxNamedRef, error)
- func (nb *NetboxClient) GetPrefix(prefix string) (*NBPrefix, error)
- func (nb *NetboxClient) GetSite(id uint) (*NetboxSite, error)
- func (nb *NetboxClient) GetSiteByName(name string) (*NetboxNamedRef, error)
- func (nb *NetboxClient) GetSiteBySlug(slug string) (*NetboxNamedRef, error)
- func (nb *NetboxClient) GetSites() ([]*NetboxSite, error)
- func (nb *NetboxClient) GetTagBySlug(slug string) (*NetboxNamedRef, error)
- func (nb *NetboxClient) GetTenant(source, sourceID string) (*NBTenant, error)
- func (nb *NetboxClient) GetTenants() ([]*NBTenant, error)
- func (nb *NetboxClient) GetVM(name string, id int) (*NBDevice, error)
- func (nb *NetboxClient) GetVM_(name string, id int) ([]*NBDevice, error)
- func (nb *NetboxClient) GetVMs() ([]*NBDevice, error)
- func (nb *NetboxClient) GetVRFByName(name string) (*NBVRF, error)
- func (nb *NetboxClient) GetVlan(vid int, groupID uint) (*NBVlan, error)
- func (nb *NetboxClient) GetVlanGroup(name string) (*NBVlanGroup, error)
- func (nb *NetboxClient) InterfaceAddressCreate(intf NetboxInterface, address NetboxAddress, status string) (*NetboxAddressREST, error)
- func (nb *NetboxClient) InterfaceCreate(device_id int, name string) (*NetboxInterfaceREST, error)
- func (nb *NetboxClient) InterfaceDelete(interface_id int) error
- func (nb *NetboxClient) InterfaceUpdate(interface_id int, changes map[string]any) error
- func (nb *NetboxClient) NetboxAPICall(grapqlQuery string, name string, id int, start, limit int) ([]byte, error)
- func (nb *NetboxClient) RequireCustomField(name string, objectTypes ...string) error
- func (nb *NetboxClient) RestGet(endpoint string, out any) error
- func (nb *NetboxClient) RestPatch(endpoint string, payload, out any) error
- func (nb *NetboxClient) RestPost(endpoint string, payload, out any) error
- func (nb *NetboxClient) UpdateCable(cableID, aInterfaceID, bInterfaceID uint, extra map[string]any) error
- func (nb *NetboxClient) UpdateCableTermination(cableID uint, side int, interfaceID uint) error
- func (nb *NetboxClient) UpdateDevice(deviceID uint, changes map[string]any) error
- func (nb *NetboxClient) UpdateL2VPN(l2vpnID uint, changes map[string]any) error
- func (nb *NetboxClient) UpdateSite(siteID uint, changes map[string]any) error
- func (nb *NetboxClient) UpdateTenant(tenantID uint, changes map[string]any) error
- func (nb *NetboxClient) UpdateVM(vmID uint, changes map[string]any) error
- func (nb *NetboxClient) UpdateVlan(id uint, changes map[string]any) error
- type NetboxCustomFields
- type NetboxDeviceManufacturer
- type NetboxDeviceREST
- type NetboxDeviceType
- type NetboxDeviceTypeDetail
- type NetboxInterface
- type NetboxInterfaceREST
- type NetboxInterfaceTemplate
- type NetboxManufacturer
- type NetboxNamedRef
- type NetboxPlatform
- type NetboxRole
- type NetboxSite
- type NetboxSiteREST
- type NetboxTag
- type NetboxTenantREST
- type NetboxVRFRef
- type NetboxVlanRef
- type Response
- type TenantCustomFields
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Cache ¶
type Cache struct {
// contains filtered or unexported fields
}
Cache wraps a CacheSource with an in-memory, per-instance cache of devices (keyed by name) and device-type interface templates (keyed by "manufacturer/model"). It is not safe for concurrent use.
func NewCache ¶
func NewCache(src CacheSource) *Cache
func (*Cache) GetDevice ¶
GetDevice returns one device, from cache unless refresh is set. Returns nil, nil (not an error) for an unknown name, matching the underlying source's GetDevice.
func (*Cache) GetDevices ¶
GetDevices fetches every device and (re)primes the cache.
func (*Cache) RefreshDevice ¶
RefreshDevice reloads device and all its related data from the source - callers use this after a mutation so later cached lookups see the new state.
func (*Cache) TemplateInterfaceTypes ¶
TemplateInterfaceTypes returns the Netbox interface type (e.g. "1000base-t") of every interface defined by a device type's template (manufacturer+model), keyed by interface name. Returns nil, nil (not an error) when manufacturer or model is empty, since there's no template to look up. Results are cached per manufacturer/model for the life of the Cache.
type CacheSource ¶
type CacheSource interface {
GetDevices() ([]*NBDevice, error)
GetDevice(name string, id int) (*NBDevice, error)
GetDeviceType(manufacturer, model string) (*NetboxDeviceTypeDetail, error)
}
CacheSource is the subset of NetboxClient that Cache needs.
type ConfigNetbox ¶
type ConfigNetbox struct {
URL string `boa:"configonly" yaml:"url"`
Token string `boa:"configonly" yaml:"token"`
Insecure bool `boa:"configonly" yaml:"insecure"`
}
Configuration file YAML structure
type ConfigRoot ¶
type ConfigRoot struct {
Netbox ConfigNetbox `yaml:"netbox"`
}
var Config ConfigRoot
type InterfaceCustomFields ¶
type InterfaceCustomFields struct {
InterfaceRole string `json:"interface_role"`
All map[string]any `json:"-"`
}
InterfaceCustomFields is dcim.Interface.custom_fields. interface_role is the one field this package copies onto NBInterface.CfRole; everything else is available via All / NBInterface.CustomFields.
func (*InterfaceCustomFields) UnmarshalJSON ¶
func (c *InterfaceCustomFields) UnmarshalJSON(data []byte) error
type InterfaceTypeChoice ¶
InterfaceTypeChoice is one dcim.Interface.type value from NetBox's OPTIONS metadata (not a first-class API object).
type JSONDevice ¶
type JSONDevice struct {
ID uint `json:"id,string"`
Name string `json:"name"`
Comments string `json:"comments"`
Status string `json:"status"`
DeviceType *NetboxDeviceType `json:"device_type"`
Platform *NetboxPlatform `json:"platform"`
Role *NetboxRole `json:"role"`
Site *NetboxSite `json:"site"`
Latitude *NBDecimal `json:"latitude"`
Longitude *NBDecimal `json:"longitude"`
PrimaryIPv4 *NetboxAddress `json:"primary_ip4"`
PrimaryIPv6 *NetboxAddress `json:"primary_ip6"`
Tags []NetboxTag `json:"tags"`
CF NetboxCustomFields `json:"custom_fields"`
Interfaces []JSONInterface `json:"interfaces"`
}
Response from Graphql device_list / virtual_machine_list query. device_type/role/site/platform and interfaces (with their ip addresses) are nested inline in the query (see deviceListGraphQLbody/ ids.
type JSONDevices ¶
type JSONDevices struct {
Data struct {
// virtualMachineListGraphQLbody), so this shape carries names, not just
Devices []JSONDevice `json:"device_list"`
} `json:"data"`
}
type JSONInterface ¶
type JSONInterface struct {
ID uint `json:"id,string"`
Name string `json:"name"`
Description string `json:"description"`
Enabled bool `json:"enabled"`
Type string `json:"type"`
// Mode is dcim.Interface.mode ("access", "tagged", "tagged-all" or
// "q-in-q"), "" if the interface isn't a switchport at all.
Mode string `json:"mode"`
Label string `json:"label"`
Parent *struct {
ID uint `json:"id,string"`
} `json:"parent"`
VRF *NetboxVRFRef `json:"vrf"`
Cable *struct {
ID uint `json:"id,string"`
} `json:"cable"`
UntaggedVLAN *NetboxVlanRef `json:"untagged_vlan"`
TaggedVLANs []NetboxVlanRef `json:"tagged_vlans"`
// QinQSVlan is dcim.Interface.qinq_svlan - the S-VLAN Netbox uses in
// place of untagged_vlan when mode is "q-in-q", mutually exclusive with
// UntaggedVLAN.
QinQSVlan *NetboxVlanRef `json:"qinq_svlan"`
Tags []NetboxTag `json:"tags"`
IPAddresses []NetboxAddress `json:"ip_addresses"`
CustomFields InterfaceCustomFields `json:"custom_fields"`
}
type JSONSites ¶
type JSONSites struct {
Data struct {
Sites []NetboxSite `json:"site_list"`
} `json:"data"`
}
JSONSites is a page of the top-level site_list GraphQL query (see siteListGraphQLbody), reusing NetboxSite since its fields (id/name/ latitude/longitude) already match what device_list's nested "site" selection returns.
type JSONTenant ¶
type JSONTenant struct {
ID uint `json:"id,string"`
Name string `json:"name"`
Slug string `json:"slug"`
CF TenantCustomFields `json:"custom_fields"`
}
JSONTenant is a tenancy.Tenant row, fetched via GraphQL (see tenantListGraphQLbody).
type JSONTenants ¶
type JSONTenants struct {
Data struct {
Tenants []JSONTenant `json:"tenant_list"`
} `json:"data"`
}
type JSONVMs ¶
type JSONVMs struct {
Data struct {
Devices []JSONDevice `json:"virtual_machine_list"`
} `json:"data"`
}
type NBAddress ¶
type NBAddress struct {
NBModel
NBAddressID uint `json:"address_id"`
NBInterfaceID uint `json:"interface_id"`
NetboxID uint `json:"netbox_id"`
Address string `gorm:"type:varchar(80)"`
// Role is ipam.IPAddress.role (e.g. "anycast"), "" if unset.
Role string `gorm:"type:varchar(80)"`
// VRF is the name of the VRF this address belongs to, "" for the
// global/default VRF.
VRF string `gorm:"type:varchar(255)"`
}
type NBCable ¶
type NBCable struct {
NetboxID uint
AInterface uint // interface ID on the A side
BInterface uint // interface ID on the B side
Label string
}
NBCable is a dcim.Cable connecting exactly two interfaces (the only shape this package creates and returns - Netbox cables can in principle terminate on more than two endpoints, e.g. distribution cables, which this type doesn't attempt to represent).
type NBCustomField ¶
type NBCustomField struct {
NetboxID uint
Name string
Type string // "text", "integer", "boolean", "select", ...
Label string
Description string
Required bool
GroupName string
ObjectTypes []string
ChoiceSetID uint
}
NBCustomField is extras.CustomField. ObjectTypes are Netbox object-type strings such as "dcim.device" or "dcim.interface".
func (*NBCustomField) AssignedTo ¶
func (f *NBCustomField) AssignedTo(objectType string) bool
AssignedTo reports whether this custom field is assigned to objectType (e.g. "dcim.device").
type NBDecimal ¶
type NBDecimal float64
NBDecimal unmarshals a Netbox GraphQL Decimal scalar (used for latitude/longitude), which may be serialized as either a bare JSON number or a JSON string, into a float64.
func (*NBDecimal) UnmarshalJSON ¶
type NBDevice ¶
type NBDevice struct {
NBModel
VM bool
NetboxID uint `json:"netbox_id"`
Name string `json:"name" gorm:"type:varchar(255)"`
Comments string `json:"comments" gorm:"type:varchar(255)"`
Enabled bool `json:"enabled"`
Manufacturer string `json:"manufacturer" gorm:"type:varchar(255)"`
ManufacturerID uint `json:"manufacturer_id"`
ModelName string `json:"model_name" gorm:"type:varchar(255)"`
ModelID uint `json:"model_id"`
Platform string `json:"platform" gorm:"type:varchar(255)"`
PlatformID uint `json:"platform_id"`
PrimaryIPv4 string `json:"primary_ipv4" gorm:"type:varchar(255)"`
PrimaryIPv4ID uint `json:"primary_ipv4_id"`
PrimaryIPv6 string `json:"primary_ipv6" gorm:"type:varchar(255)"`
PrimaryIPv6ID uint `json:"primary_ipv6_id"`
Role string `json:"role" gorm:"type:varchar(255)"`
RoleID uint `json:"role_id"`
Site string `json:"site" gorm:"type:varchar(255)"`
SiteID uint `json:"site_id"`
Status string `json:"status" gorm:"type:varchar(255)"`
// Latitude/Longitude are the device's own GPS coordinates if set in
// Netbox, else inherited from its site (resolved in parseDevices) -
// nil if neither the device nor its site has coordinates.
Latitude *float64 `json:"latitude"`
Longitude *float64 `json:"longitude"`
CfAlarmTimeperiod string `json:"cf_alarm_timeperiod" gorm:"type:varchar(255)"`
CfAlarmDestination string `json:"cf_alarm_destination" gorm:"type:varchar(255)"`
CfAlarmInterfaces bool `json:"cf_alarm_interfaces"`
CfBackupOxidized bool `json:"cf_backup_oxidized"`
CfConnectionMethod string `json:"cf_connection_method" gorm:"type:varchar(255)"`
CfLocation string `json:"cf_location" gorm:"type:varchar(255)"`
CfMonitorGrafana bool `json:"cf_monitor_grafana"`
CfMonitorIcinga bool `json:"cf_monitor_icinga"`
CfMonitorLibrenms bool `json:"cf_monitor_librenms"`
CfSource string `json:"cf_source" gorm:"type:varchar(255)"`
CfSourceID uint `json:"cf_source_id"`
// CfParents is the comma-separated "parents" custom field.
CfParents string `json:"cf_parents"`
// CustomFields is the raw custom_fields object from Netbox, including
// keys this package also copies onto typed Cf* fields. Callers that
// need an instance-specific field not modelled here read it from here.
CustomFields map[string]any `json:"custom_fields"`
LibrenmsID uint `json:"librenms_id"`
Interfaces []NBInterface `json:"interfaces"` // gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"`
Tags []NBTag `json:"tags"`
}
type NBInterface ¶
type NBInterface struct {
NBModel
NBDeviceID uint `json:"nbdevice_id"`
NetboxID uint `json:"netbox_id"`
Name string `json:"name" gorm:"type:varchar(255)"`
Description string `json:"description" gorm:"type:varchar(255)"`
Enabled bool `json:"enabled"`
Type string `json:"type" gorm:"type:varchar(255)"`
VRF string `json:"vrf" gorm:"type:varchar(255)"`
CfRole string `json:"cf_role" gorm:"type:varchar(255)"`
// runtime data
LineProtocolStatus string `gorm:"-"`
InterfaceStatus string `gorm:"-"`
// CableID is the netbox ID of the cable terminated on this interface, 0
// if none - populated by GraphQL reads (deviceListGraphQLbody's
// interfaces{cable{id}}), not stored.
CableID uint `gorm:"-"`
// Label is dcim.Interface.label, Netbox's free-text interface label
// (distinct from Name) - populated by GraphQL reads
// (deviceListGraphQLbody's interfaces{label}), not stored.
Label string `gorm:"-"`
// ParentID is the netbox ID of this interface's parent interface, 0 if
// none - populated by GraphQL reads (deviceListGraphQLbody's
// interfaces{parent{id}}), not stored.
ParentID uint `gorm:"-"`
// UntaggedVLAN/TaggedVLANs are VIDs (not Netbox IDs), populated by
// GraphQL reads (deviceListGraphQLbody's interfaces{untagged_vlan,
// tagged_vlans}), not stored. UntaggedVLAN is 0 if unset.
UntaggedVLAN int `gorm:"-"`
TaggedVLANs []int `gorm:"-"`
// VLANNames maps VID -> name for this interface's untagged/tagged/qinq
// VLANs, from nested GraphQL vlan.name. Not stored on NBInterface.
VLANNames map[int]string `gorm:"-"`
// Mode is dcim.Interface.mode ("access", "tagged", "tagged-all" or
// "q-in-q"), populated by GraphQL reads (deviceListGraphQLbody's
// interfaces{mode}), not stored. "" if the interface isn't a switchport.
Mode string `gorm:"-"`
// CustomFields is the raw custom_fields object from Netbox. Typed
// fields this package knows about (currently CfRole) are also copied
// out separately.
CustomFields map[string]any `json:"custom_fields"`
Addresses []NBAddress `json:"addresses"` // gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"`
Tags []NBTag `json:"tags"`
}
func (*NBInterface) IsTag ¶
func (i *NBInterface) IsTag(name string) bool
IsTag reports whether the interface has a tag with the given name.
type NBL2VPN ¶
type NBL2VPN struct {
NetboxID uint
Name string
Slug string
Type string // e.g. "evpl"
Identifier int
}
NBL2VPN is an ipam.L2VPN row (e.g. an EVPL/ELINE service).
type NBL2VPNTermination ¶
NBL2VPNTermination is an ipam.L2VPNTermination row, binding an L2VPN to one assigned interface (dcim.interface).
type NBVlanGroup ¶
NBVlanGroup is an ipam.VLANGroup row. CreateVlanGroup always creates groups as global (unscoped).
type NetboxAddress ¶
type NetboxAddress struct {
ID uint `json:"id,string"`
Address string `json:"address"`
Role string `json:"role"`
VRF *NetboxVRFRef `json:"vrf"`
}
type NetboxAddressREST ¶
NetboxAddressREST is an ipam.IPAddress row as returned by the REST API (unlike NetboxAddress, whose `id,string` tag matches the GraphQL ID scalar, this one's id is a plain JSON number).
type NetboxClient ¶
type NetboxClient struct {
P ConfigNetbox
Device []*NBDevice
// contains filtered or unexported fields
}
client
func NewNetboxClient ¶
func NewNetboxClient(p ConfigNetbox) (*NetboxClient, error)
---------------------------------------------------------------------------
Functions
---------------------------------------------------------------------------
func (*NetboxClient) AddressCreate ¶
func (nb *NetboxClient) AddressCreate(address string) (*NetboxAddressREST, error)
Create an address, not assigned to any interface.
func (*NetboxClient) AddressDelete ¶
func (nb *NetboxClient) AddressDelete(address_id int) error
Delete an address
func (*NetboxClient) AddressUpdate ¶
func (nb *NetboxClient) AddressUpdate(address_id int, changes map[string]any) error
Update an address (e.g. its role or vrf). PATCH /api/ipam/ip-addresses/{id}/
func (*NetboxClient) CreateCable ¶
func (nb *NetboxClient) CreateCable(aInterfaceID, bInterfaceID uint) (*NBCable, error)
CreateCable creates a cable directly connecting two interfaces.
func (*NetboxClient) CreateCableWithOptions ¶
func (nb *NetboxClient) CreateCableWithOptions(aInterfaceID, bInterfaceID uint, extra map[string]any) (*NBCable, error)
CreateCableWithOptions is CreateCable plus arbitrary extra REST fields (e.g. "label": "uplink"). extra may be nil.
func (*NetboxClient) CreateDevice ¶
func (nb *NetboxClient) CreateDevice(name string, extra map[string]any) (*NetboxDeviceREST, error)
CreateDevice creates a physical device. extra may set site, device_type, role, platform, status, tags, custom_fields, and any other writable device field alongside name - same shape as CreateTenant.
func (*NetboxClient) CreateInterfaceAddress ¶
func (nb *NetboxClient) CreateInterfaceAddress(interfaceID uint, address string, extra map[string]any) (*NBAddress, error)
CreateInterfaceAddress creates an ip address assigned to interfaceID, plus arbitrary extra REST fields (e.g. "role": "anycast", "vrf": {"name": ...}) - unlike InterfaceAddressCreate, which only sends address/status, this is for callers that also set VRF and role (Netbox models those on the address, not the interface).
func (*NetboxClient) CreateInterfaceWithOptions ¶
func (nb *NetboxClient) CreateInterfaceWithOptions(deviceID uint, name string, extra map[string]any) (*NetboxInterfaceREST, error)
CreateInterfaceWithOptions is InterfaceCreate plus arbitrary extra REST fields (e.g. "type": "lag", "vrf": {"name": ...}) - for callers that know more about the interface being created than InterfaceCreate's fixed "virtual" type allows for.
func (*NetboxClient) CreateL2VPN ¶
func (nb *NetboxClient) CreateL2VPN(name, slug, l2vpnType string, identifier int) (*NBL2VPN, error)
CreateL2VPN creates a new L2VPN (e.g. an ELINE service), identified by identifier (the pseudowire ID) - l2vpnType is one of Netbox's L2VPN type choices, e.g. "evpl". identifier is omitted from the payload when 0 (Netbox treats it as optional; same-device patches often have no PWID).
func (*NetboxClient) CreateL2VPNTermination ¶
func (nb *NetboxClient) CreateL2VPNTermination(l2vpnID, interfaceID uint) (*NBL2VPNTermination, error)
CreateL2VPNTermination terminates l2vpnID on interfaceID - unlike a cable's a_terminations/b_terminations (object_type/object_id), an L2VPN termination uses Netbox's generic "assigned object" fields (assigned_object_type/assigned_object_id).
func (*NetboxClient) CreatePrefix ¶
func (nb *NetboxClient) CreatePrefix(prefix string) (*NBPrefix, error)
CreatePrefix creates a new prefix with status "active".
func (*NetboxClient) CreateSite ¶
func (nb *NetboxClient) CreateSite(name, slug string, extra map[string]any) (*NetboxSiteREST, error)
CreateSite creates a Netbox site. Status defaults to "active"; extra may set latitude/longitude and any other writable site field. Name and slug must be unique.
func (*NetboxClient) CreateTenant ¶
func (nb *NetboxClient) CreateTenant(name, slug string, changes map[string]any) (*NetboxTenantREST, error)
CreateTenant creates a tenant. Netbox requires both name and slug to be unique; changes may set "custom_fields" (map[string]any) and any other writable tenant field alongside name/slug.
func (*NetboxClient) CreateVRF ¶
func (nb *NetboxClient) CreateVRF(name, rd, description string) (*NBVRF, error)
CreateVRF creates a VRF. rd is omitted when empty (Netbox treats it as optional).
func (*NetboxClient) CreateVlan ¶
CreateVlan creates a new VLAN in groupID.
func (*NetboxClient) CreateVlanGroup ¶
func (nb *NetboxClient) CreateVlanGroup(name, slug string) (*NBVlanGroup, error)
CreateVlanGroup creates a new, global (unscoped) VLAN group.
func (*NetboxClient) DeleteCable ¶
func (nb *NetboxClient) DeleteCable(cableID uint) error
DeleteCable deletes a cable.
func (*NetboxClient) DeleteDevice ¶
func (nb *NetboxClient) DeleteDevice(id int) error
Delete a device in netbox, specificed by device id
func (*NetboxClient) DeleteL2VPN ¶
func (nb *NetboxClient) DeleteL2VPN(l2vpnID uint) error
DeleteL2VPN deletes an L2VPN.
func (*NetboxClient) DeleteL2VPNTermination ¶
func (nb *NetboxClient) DeleteL2VPNTermination(terminationID uint) error
DeleteL2VPNTermination deletes an L2VPN termination.
func (*NetboxClient) EnsureTag ¶
func (nb *NetboxClient) EnsureTag(name, slug string) (*NetboxNamedRef, error)
EnsureTag returns the tag with the given slug, creating it (name+slug) if it does not already exist.
func (*NetboxClient) GetCable ¶
func (nb *NetboxClient) GetCable(cableID uint) (*NBCable, error)
GetCable fetches one cable by id - interfaces already carry their own cable id (NBInterface.CableID, from the GraphQL device query), so this is how a caller resolves it to the cable's actual terminations.
func (*NetboxClient) GetCables ¶
func (nb *NetboxClient) GetCables() ([]*NBCable, error)
GetCables fetches every cable in Netbox via the REST API, paginating until "next" is null. Unlike GetCable, which resolves one already-known cable id, this is how a caller discovers the full set of cables - e.g. to build a device connectivity map, not just the ones this package itself created. Cables not directly connecting two interfaces (see isInterfaceToInterface) are silently skipped rather than represented with a wrong/zero AInterface or BInterface.
func (*NetboxClient) GetCustomField ¶
func (nb *NetboxClient) GetCustomField(name string) (*NBCustomField, error)
GetCustomField looks up extras.CustomField by exact name via REST. Returns nil, nil if none matches.
func (*NetboxClient) GetDevice ¶
func (nb *NetboxClient) GetDevice(name string, id int) (*NBDevice, error)
GetDevice fetches one device by name or id, returning nil, nil (not an error) if none matches - mirroring pynetbox's own .get(), which returns None rather than raising for an unknown name.
func (*NetboxClient) GetDeviceRoleBySlug ¶
func (nb *NetboxClient) GetDeviceRoleBySlug(slug string) (*NetboxNamedRef, error)
GetDeviceRoleBySlug looks up a device role by slug. Returns nil, nil if none matches.
func (*NetboxClient) GetDeviceType ¶
func (nb *NetboxClient) GetDeviceType(manufacturer string, model string) (*NetboxDeviceTypeDetail, error)
GetDeviceType looks up a device type by manufacturer name+model, and fetches its interface templates in the same nested GraphQL query (device_type_list.interfacetemplates), rather than a separate REST request.
func (*NetboxClient) GetDevices ¶
func (nb *NetboxClient) GetDevices() ([]*NBDevice, error)
GetDevices fetches every physical device, via getDevicesFlat's flat-queries-fetched-concurrently strategy (netboxtool_flat.go) rather than GetDevices_'s single nested query - benchmarked at ~8x faster on a 1400-device/37000-interface instance (see cmd/benchmark.go). A name/id-filtered single-device lookup doesn't have the same problem, so GetDevice still goes through GetDevices_.
func (*NetboxClient) GetDevices_ ¶
func (nb *NetboxClient) GetDevices_(name string, id int) ([]*NBDevice, error)
GetDevices_ fetches devices via a single nested device_list query (device_type/role/site/platform and interfaces/ip addresses are all resolved server-side, see deviceListGraphQLbody). name/id, if set, filter device_list itself so only the matching device is fetched.
func (*NetboxClient) GetInterfaceCable ¶
func (nb *NetboxClient) GetInterfaceCable(cableID uint) (*NBCable, error)
GetInterfaceCable is GetCable for the webhook/single-object path: a 404 or a cable that is not exactly one dcim.interface on each end returns nil, nil (a two-interface connection model cannot represent those).
func (*NetboxClient) GetInterfaceTypeChoices ¶
func (nb *NetboxClient) GetInterfaceTypeChoices() ([]InterfaceTypeChoice, error)
GetInterfaceTypeChoices returns the Interface.type choice list from OPTIONS /api/dcim/interfaces/. NetBox has no /dcim/interface-types/ resource; types are a ChoiceSet.
func (*NetboxClient) GetL2VPN ¶
func (nb *NetboxClient) GetL2VPN(l2vpnID uint) (*NBL2VPN, error)
GetL2VPN fetches one L2VPN by id.
func (*NetboxClient) GetL2VPNByIdentifier ¶
func (nb *NetboxClient) GetL2VPNByIdentifier(identifier int) (*NBL2VPN, error)
GetL2VPNByIdentifier looks up an existing L2VPN by its identifier (pseudowire ID), returning nil (no error) if none exists. Fallback when the on-device name doesn't match the Netbox L2VPN name but the pseudowire ID does.
func (*NetboxClient) GetL2VPNByName ¶
func (nb *NetboxClient) GetL2VPNByName(name string) (*NBL2VPN, error)
GetL2VPNByName looks up an existing L2VPN by its exact name, returning nil (no error) if none exists.
func (*NetboxClient) GetL2VPNTerminations ¶
func (nb *NetboxClient) GetL2VPNTerminations(l2vpnID uint) ([]*NBL2VPNTermination, error)
GetL2VPNTerminations returns every termination on l2vpnID (typically 1-2 for an EVPL). Paginated the same way as GetCables in case a multipoint L2VPN ever lands here with more than one page of ends.
func (*NetboxClient) GetL2VPNs ¶
func (nb *NetboxClient) GetL2VPNs(l2vpnType string) ([]*NBL2VPN, error)
GetL2VPNs fetches every L2VPN in Netbox via the REST API, paginating until "next" is null. When l2vpnType is non-empty (e.g. "evpl"), only that type is returned.
func (*NetboxClient) GetManufacturer ¶
func (nb *NetboxClient) GetManufacturer(name string, id int) (*NetboxManufacturer, error)
GetManufacturer looks up a manufacturer by its display name (e.g. "Cisco") or, if id is set (id > 0), by id.
func (*NetboxClient) GetPlatformBySlug ¶
func (nb *NetboxClient) GetPlatformBySlug(slug string) (*NetboxNamedRef, error)
GetPlatformBySlug looks up a platform by slug. Returns nil, nil if none matches.
func (*NetboxClient) GetPrefix ¶
func (nb *NetboxClient) GetPrefix(prefix string) (*NBPrefix, error)
GetPrefix looks up an existing prefix by its exact CIDR value, returning nil (no error) if none exists.
func (*NetboxClient) GetSite ¶
func (nb *NetboxClient) GetSite(id uint) (*NetboxSite, error)
GetSite fetches one site by id via REST. Returns nil, nil if the site is gone, is the placeholder "Default" site, or has no coordinates — the same filter GetSites applies, so a webhook create/update of an unplottable site is a no-op (or a delete of a previously-plotted row).
func (*NetboxClient) GetSiteByName ¶
func (nb *NetboxClient) GetSiteByName(name string) (*NetboxNamedRef, error)
GetSiteByName looks up a site by its exact display name, including the placeholder "Default" site that GetSites skips. Returns nil, nil if none matches.
func (*NetboxClient) GetSiteBySlug ¶
func (nb *NetboxClient) GetSiteBySlug(slug string) (*NetboxNamedRef, error)
GetSiteBySlug looks up a site by slug, including "Default". Returns nil, nil if none matches.
func (*NetboxClient) GetSites ¶
func (nb *NetboxClient) GetSites() ([]*NetboxSite, error)
GetSites fetches every Netbox site, for callers that need the full site inventory rather than just the sites referenced by a device (e.g. the network map, which also plots sites with no devices of their own). Sites with no coordinates, and the placeholder "Default" site, are skipped - same filtering parseDevices applies to a device's own site reference.
func (*NetboxClient) GetTagBySlug ¶
func (nb *NetboxClient) GetTagBySlug(slug string) (*NetboxNamedRef, error)
GetTagBySlug looks up a tag by slug. Returns nil, nil if none matches.
func (*NetboxClient) GetTenant ¶
func (nb *NetboxClient) GetTenant(source, sourceID string) (*NBTenant, error)
GetTenant looks up the single tenant whose custom fields match source/sourceID (see TenantCustomFields), via a server-side filtered REST call instead of GetTenants' full-table fetch - the point being O(1) instead of O(tenant count) for a caller that only ever wants one row. Returns nil, nil (not an error) if no tenant matches.
func (*NetboxClient) GetTenants ¶
func (nb *NetboxClient) GetTenants() ([]*NBTenant, error)
GetTenants fetches all tenants via a single tenant_list query.
func (*NetboxClient) GetVM ¶
func (nb *NetboxClient) GetVM(name string, id int) (*NBDevice, error)
GetVM fetches one virtual machine by name or id, returning nil, nil (not an error) if none matches - mirroring GetDevice/pynetbox's own .get(), which returns None rather than raising for an unknown name.
func (*NetboxClient) GetVM_ ¶
func (nb *NetboxClient) GetVM_(name string, id int) ([]*NBDevice, error)
GetVM_ is the virtual_machine equivalent of GetDevices_: a single nested virtual_machine_list query resolves site and interfaces/ip addresses server-side, and name/id, if set, filter virtual_machine_list itself so only the matching VM is fetched.
func (*NetboxClient) GetVMs ¶
func (nb *NetboxClient) GetVMs() ([]*NBDevice, error)
GetVMs is GetDevices' virtual-machine equivalent - see getVMsFlat.
func (*NetboxClient) GetVRFByName ¶
func (nb *NetboxClient) GetVRFByName(name string) (*NBVRF, error)
GetVRFByName looks up an existing VRF by its exact name, returning nil (no error) if none exists.
func (*NetboxClient) GetVlan ¶
func (nb *NetboxClient) GetVlan(vid int, groupID uint) (*NBVlan, error)
GetVlan looks up an existing VLAN by VID within groupID, returning nil (no error) if none exists.
func (*NetboxClient) GetVlanGroup ¶
func (nb *NetboxClient) GetVlanGroup(name string) (*NBVlanGroup, error)
GetVlanGroup looks up an existing VLAN group by its exact name, returning nil (no error) if none exists.
func (*NetboxClient) InterfaceAddressCreate ¶
func (nb *NetboxClient) InterfaceAddressCreate(intf NetboxInterface, address NetboxAddress, status string) (*NetboxAddressREST, error)
Create an address on an interface
func (*NetboxClient) InterfaceCreate ¶
func (nb *NetboxClient) InterfaceCreate(device_id int, name string) (*NetboxInterfaceREST, error)
Create an interface on a device. Netbox's graphql API is read-only, so this goes through the REST API instead (POST /api/dcim/interfaces/). "virtual" is used as the interface type since callers don't supply hardware-specific type info.
func (*NetboxClient) InterfaceDelete ¶
func (nb *NetboxClient) InterfaceDelete(interface_id int) error
Delete an interface
func (*NetboxClient) InterfaceUpdate ¶
func (nb *NetboxClient) InterfaceUpdate(interface_id int, changes map[string]any) error
Update an interface. changes is any, not map[string]string, so callers can send nested values (e.g. {"vrf": {"name": "MGMT"}}). PATCH /api/dcim/interfaces/{id}/
func (*NetboxClient) NetboxAPICall ¶
func (nb *NetboxClient) NetboxAPICall(grapqlQuery string, name string, id int, start, limit int) ([]byte, error)
Helper function, to fetch a page of
- all devices/vms
- one device/vm, selected by name
- one device/vm, selected by id
start is a cursor (the Netbox object id to resume from, "id >= start"), not a row offset - Netbox's offset-based pagination costs more the further into the table you page (Postgres has to scan and discard `offset` rows), while cursor pagination is a constant-cost index seek regardless of position. See fetchAllPages.
func (*NetboxClient) RequireCustomField ¶
func (nb *NetboxClient) RequireCustomField(name string, objectTypes ...string) error
RequireCustomField returns an error unless a custom field with the given name exists and is assigned to every object type in objectTypes (e.g. "dcim.device"). Callers that only care that the field exists can pass no object types.
func (*NetboxClient) RestGet ¶
func (nb *NetboxClient) RestGet(endpoint string, out any) error
RestGet, RestPost and RestPatch expose the REST helpers for callers that talk to extras endpoints this package does not wrap (custom fields, webhooks, event rules).
func (*NetboxClient) RestPatch ¶
func (nb *NetboxClient) RestPatch(endpoint string, payload, out any) error
func (*NetboxClient) RestPost ¶
func (nb *NetboxClient) RestPost(endpoint string, payload, out any) error
func (*NetboxClient) UpdateCable ¶
func (nb *NetboxClient) UpdateCable(cableID, aInterfaceID, bInterfaceID uint, extra map[string]any) error
UpdateCable replaces both terminations and any extra REST fields (e.g. "label") on an existing cable.
func (*NetboxClient) UpdateCableTermination ¶
func (nb *NetboxClient) UpdateCableTermination(cableID uint, side int, interfaceID uint) error
UpdateCableTermination replaces one side of an existing cable with interfaceID - side 1 is the A side, side 2 is the B side.
func (*NetboxClient) UpdateDevice ¶
func (nb *NetboxClient) UpdateDevice(deviceID uint, changes map[string]any) error
UpdateDevice updates a Netbox device with arbitrary (possibly nested, e.g. custom_fields) values. https://netboxlabs.com/docs/netbox/en/stable/rest-api/overview/#update
func (*NetboxClient) UpdateL2VPN ¶
func (nb *NetboxClient) UpdateL2VPN(l2vpnID uint, changes map[string]any) error
UpdateL2VPN applies changes (field -> new value) to an existing L2VPN.
func (*NetboxClient) UpdateSite ¶
func (nb *NetboxClient) UpdateSite(siteID uint, changes map[string]any) error
UpdateSite patches a Netbox site with arbitrary writable fields (latitude/longitude, name, slug, …).
func (*NetboxClient) UpdateTenant ¶
func (nb *NetboxClient) UpdateTenant(tenantID uint, changes map[string]any) error
UpdateTenant updates a Netbox tenant with arbitrary (possibly nested, e.g. custom_fields) values.
func (*NetboxClient) UpdateVM ¶
func (nb *NetboxClient) UpdateVM(vmID uint, changes map[string]any) error
UpdateVM updates a Netbox virtual machine with arbitrary (possibly nested) values
func (*NetboxClient) UpdateVlan ¶
func (nb *NetboxClient) UpdateVlan(id uint, changes map[string]any) error
UpdateVlan applies changes (field -> new value) to an existing VLAN.
type NetboxCustomFields ¶
type NetboxCustomFields struct {
AlarmDestination string `json:"alarm_destination"`
AlarmInterfaces bool `json:"alarm_interfaces"`
AlarmTimeperiod string `json:"alarm_timeperiod"`
Alias string `json:"alias"`
BackupOxidized bool `json:"backup_oxidized"`
Location string `json:"location"`
MonitorIcinga bool `json:"monitor_icinga"`
MonitorGrafana bool `json:"monitor_grafana"`
// MonitorLibrenms is a *bool, not bool: netbox returns null for a
// custom field that has never been set on a device (no default
// configured), and that must be distinguished from an explicit
// false - unset devices default to monitored, matching the old
// (pre-Go) sync script's behavior. See the copy into
// dbdevice.CfMonitorLibrenms below.
MonitorLibrenms *bool `json:"monitor_librenms"`
Parents string `json:"parents"`
ConnectMethod string `json:"connection_method"`
LibrenmsID int `json:"librenms_id"`
// All is the raw custom_fields object, including keys that also have
// typed fields above. Callers that need an instance-specific field
// this package does not model read it from All (or from
// NBDevice.CustomFields, which is a copy).
All map[string]any `json:"-"`
}
func (*NetboxCustomFields) UnmarshalJSON ¶
func (c *NetboxCustomFields) UnmarshalJSON(data []byte) error
type NetboxDeviceREST ¶
NetboxDeviceREST is a dcim.Device row as returned by the REST API (unlike JSONDevice, whose `id,string` tag matches the GraphQL ID scalar, this one's id is a plain JSON number).
type NetboxDeviceType ¶
type NetboxDeviceType struct {
ID uint `json:"id,string"`
Model string `json:"model"`
Manufacturer *NetboxDeviceManufacturer
}
type NetboxDeviceTypeDetail ¶
type NetboxDeviceTypeDetail struct {
ID uint `json:"id,string"`
Model string `json:"model"`
Manufacturer NetboxDeviceManufacturer `json:"manufacturer"`
DefaultPlatform *NetboxPlatform `json:"default_platform"`
CF NetboxCustomFields `json:"custom_fields"`
Interfaces []NetboxInterfaceTemplate `json:"interfacetemplates"`
}
NetboxDeviceTypeDetail is a device type together with its interface templates, both resolved server-side in a single nested GraphQL query (see deviceTypeGraphQLbody).
type NetboxInterface ¶
type NetboxInterface struct {
ID uint `json:"id,string"`
Name string `json:"name"`
IP_addresses []NetboxAddress `json:"ip_addresses"`
CustomFields struct {
InterfaceRole string `json:"interface_role"`
} `json:"custom_fields"`
}
type NetboxInterfaceREST ¶
type NetboxInterfaceREST struct {
ID uint `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
}
NetboxInterfaceREST is a dcim.Interface row as returned by the REST API (unlike NetboxInterface, whose `id,string` tag matches the GraphQL ID scalar, this one's id is a plain JSON number).
type NetboxInterfaceTemplate ¶
type NetboxInterfaceTemplate struct {
ID uint `json:"id,string"`
Name string `json:"name"`
Description string `json:"description"`
Type string `json:"type"`
}
NetboxInterfaceTemplate is a dcim.InterfaceTemplate row, as attached to a device type.
type NetboxManufacturer ¶
type NetboxManufacturer struct {
ID uint `json:"id,string"`
Name string `json:"name"`
Description string `json:"description"`
Comments string `json:"comments"`
}
NetboxManufacturer is a dcim.Manufacturer row, fetched via GraphQL (see manufacturerListGraphQLbody).
type NetboxNamedRef ¶
type NetboxNamedRef struct {
ID uint `json:"id"`
Name string `json:"name"`
Slug string `json:"slug"`
}
NetboxNamedRef is a REST row that has id/name/slug - sites, device roles, platforms and tags all share this shape. GraphQL IDs are strings; REST IDs are numbers, so this is distinct from NetboxSite/NetboxRole.
type NetboxPlatform ¶
type NetboxRole ¶
type NetboxSite ¶
type NetboxSiteREST ¶
type NetboxSiteREST struct {
ID uint `json:"id"`
Name string `json:"name"`
Slug string `json:"slug"`
Latitude *float64 `json:"latitude"`
Longitude *float64 `json:"longitude"`
}
NetboxSiteREST is a dcim.Site row as returned by the REST API (plain JSON numbers for id/latitude/longitude, unlike GraphQL NetboxSite).
type NetboxTenantREST ¶
type NetboxTenantREST struct {
ID uint `json:"id"`
Name string `json:"name"`
Slug string `json:"slug"`
}
NetboxTenantREST is a tenancy.Tenant row as returned by the REST API (unlike JSONTenant, whose `id,string` tag matches the GraphQL ID scalar, this one's id is a plain JSON number).
type NetboxVRFRef ¶
NetboxVRFRef is the minimal VRF reference nested under an interface or ip address in GraphQL responses.
type NetboxVlanRef ¶
type NetboxVlanRef struct {
ID uint `json:"id,string"`
VID int `json:"vid"`
Name string `json:"name"`
}
Response from the interfaces field nested under - device_list (dcim.Interface) - virtual_machine_list (virtualization.VMInterface)
type Response ¶
type Response struct {
Status string `json:"status"`
Message string `json:"message"`
Data any `json:"data"`
}
API structures
type TenantCustomFields ¶
TenantCustomFields holds the subset of a tenant's custom_fields this package knows about: "source"/"source_id" identify which external system (and which record within it, e.g. a CRM customer id) a tenant was synced from.