Documentation
¶
Index ¶
- Constants
- Variables
- func CloseSSHPool()
- func CommitCLI(comment string, quoted bool) string
- func DeviceFQDN(name string, defaultDomain string) string
- func ELINETemplateData(intent *ELINEIntent, platform string) (any, error)
- func InitSSHPool(cfg SSHPoolConfig) error
- func InitSSHPoolFromDriver(d util.ConfigDriver) error
- func RenderCLITemplate(tmplText string, data any) ([]string, error)
- func ResetSSHPoolForTest()
- func ServeSSHSession(ctx context.Context, d util.ConfigDriver) error
- func SessionSocketPath(yamlOverride string) string
- func UnmarshalNodes(nodes []*ConfigNode, target any) error
- type AristaDriver
- func (driver *AristaDriver) ApplyCLISession(sessionName string, cmds []string, comment string) error
- func (driver *AristaDriver) ApplyELINE(intent *ELINEIntent) error
- func (driver *AristaDriver) Exec(cmd string) (*ExecModel, error)
- func (driver *AristaDriver) GetDeviceConfig() (*DeviceConfig, error)
- func (driver *AristaDriver) GetInterfacesStatus() ([]*netboxtool.NBInterface, error)
- func (driver *AristaDriver) GetNeighbors() ([]*Neighbor, error)
- func (driver *AristaDriver) RemoveELINE(removal *ELINERemoval) error
- func (driver *AristaDriver) RunningConfigGet(jsonformat bool) (*RunningConfigModel, error)
- func (driver *AristaDriver) RunningConfigSave() error
- func (driver *AristaDriver) SetInterfaceDescription(intf *netboxtool.NBInterface) error
- func (driver *AristaDriver) SetInterfaceDescriptions(name []string, intf []*netboxtool.NBInterface) error
- func (driver *AristaDriver) SetInterfaceVLANs(name []string, params []*VLANConfig) error
- func (driver *AristaDriver) Version() (*VersionModel, error)
- type CLISessionApplier
- type CiscoSMBDriver
- func (driver *CiscoSMBDriver) ApplyCLISession(_ string, cmds []string, _ string) error
- func (driver *CiscoSMBDriver) Exec(cmd string) (*ExecModel, error)
- func (driver *CiscoSMBDriver) GetDeviceConfig() (*DeviceConfig, error)
- func (driver *CiscoSMBDriver) GetInterfacesStatus() ([]*netboxtool.NBInterface, error)
- func (driver *CiscoSMBDriver) GetNeighbors() ([]*Neighbor, error)
- func (driver *CiscoSMBDriver) RunningConfigGet(jsonformat bool) (*RunningConfigModel, error)
- func (driver *CiscoSMBDriver) RunningConfigSave() error
- func (driver *CiscoSMBDriver) SetInterfaceDescription(intf *netboxtool.NBInterface) error
- func (driver *CiscoSMBDriver) SetInterfaceDescriptions(name []string, intf []*netboxtool.NBInterface) error
- func (driver *CiscoSMBDriver) SetInterfaceVLANs(name []string, params []*VLANConfig) error
- func (driver *CiscoSMBDriver) Version() (*VersionModel, error)
- type ConfigNode
- type DeviceConfig
- type DeviceModel
- type DriverClient
- type DriverFactory
- type DriverParam
- type ELAN
- type ELINE
- type ELINEApplier
- type ELINEIntent
- type ELINEPrepareChecker
- type ELINERemotePeer
- type ELINERemoval
- type ELINERemover
- type ELINEStaleSubinterface
- type ExecModel
- type IOSXRDriver
- func (driver *IOSXRDriver) ApplyCLISession(_ string, cmds []string, comment string) error
- func (driver *IOSXRDriver) ApplyELINE(intent *ELINEIntent) error
- func (driver *IOSXRDriver) Exec(cmd string) (*ExecModel, error)
- func (driver *IOSXRDriver) GetDeviceConfig() (*DeviceConfig, error)
- func (driver *IOSXRDriver) GetInterfacesStatus() ([]*netboxtool.NBInterface, error)
- func (driver *IOSXRDriver) GetNeighbors() ([]*Neighbor, error)
- func (driver *IOSXRDriver) RemoveELINE(removal *ELINERemoval) error
- func (driver *IOSXRDriver) RunningConfigGet(jsonformat bool) (*RunningConfigModel, error)
- func (driver *IOSXRDriver) RunningConfigSave() error
- func (driver *IOSXRDriver) SetInterfaceDescription(intf *netboxtool.NBInterface) error
- func (driver *IOSXRDriver) SetInterfaceDescriptions(name []string, intf []*netboxtool.NBInterface) error
- func (driver *IOSXRDriver) SetInterfaceVLANs(name []string, params []*VLANConfig) error
- func (driver *IOSXRDriver) Version() (*VersionModel, error)
- type Interface
- type InterfaceAddress
- type InterfaceModel
- type L3VPN
- type MyDevice
- type Neighbor
- type NokiaDriver
- func (driver *NokiaDriver) ApplyCLISession(_ string, cmds []string, comment string) error
- func (driver *NokiaDriver) ApplyELINE(intent *ELINEIntent) error
- func (driver *NokiaDriver) Exec(cmd string) (*ExecModel, error)
- func (driver *NokiaDriver) GetDeviceConfig() (*DeviceConfig, error)
- func (driver *NokiaDriver) GetInterfacesStatus() ([]*netboxtool.NBInterface, error)
- func (driver *NokiaDriver) GetNeighbors() ([]*Neighbor, error)
- func (driver *NokiaDriver) PrepareELINEApply(intent *ELINEIntent) error
- func (driver *NokiaDriver) RemoveELINE(removal *ELINERemoval) error
- func (driver *NokiaDriver) RunningConfigGet(jsonformat bool) (*RunningConfigModel, error)
- func (driver *NokiaDriver) RunningConfigSave() error
- func (driver *NokiaDriver) SetInterfaceDescription(intf *netboxtool.NBInterface) error
- func (driver *NokiaDriver) SetInterfaceDescriptions(name []string, description []*netboxtool.NBInterface) error
- func (driver *NokiaDriver) SetInterfaceVLANs(name []string, params []*VLANConfig) error
- func (driver *NokiaDriver) Version() (*VersionModel, error)
- type OpenROADMDriver
- func (driver *OpenROADMDriver) Exec(cmd string) (*ExecModel, error)
- func (driver *OpenROADMDriver) GetDeviceConfig() (*DeviceConfig, error)
- func (driver *OpenROADMDriver) GetInterfacesStatus() ([]*netboxtool.NBInterface, error)
- func (driver *OpenROADMDriver) GetNeighbors() ([]*Neighbor, error)
- func (driver *OpenROADMDriver) GetOpticalInventory() (*OpticalInventory, error)
- func (driver *OpenROADMDriver) RunningConfigGet(jsonformat bool) (*RunningConfigModel, error)
- func (driver *OpenROADMDriver) RunningConfigSave() error
- func (driver *OpenROADMDriver) SetInterfaceDescription(intf *netboxtool.NBInterface) error
- func (driver *OpenROADMDriver) SetInterfaceDescriptions(name []string, intf []*netboxtool.NBInterface) error
- func (driver *OpenROADMDriver) SetInterfaceVLANs(name []string, params []*VLANConfig) error
- func (driver *OpenROADMDriver) Version() (*VersionModel, error)
- type OpticalClient
- type OpticalInventory
- type OpticalPortView
- type OpticalXConnectView
- type Pseudowire
- type RunningConfigModel
- type RunningConfigStructured
- type SSHPoolConfig
- type VLAN
- type VLANConfig
- type VRF
- type VersionModel
- type VrpDriver
- func (driver *VrpDriver) ApplyCLISession(_ string, cmds []string, _ string) error
- func (driver *VrpDriver) Exec(cmd string) (*ExecModel, error)
- func (driver *VrpDriver) GetDeviceConfig() (*DeviceConfig, error)
- func (driver *VrpDriver) GetInterfacesStatus() ([]*netboxtool.NBInterface, error)
- func (driver *VrpDriver) GetNeighbors() ([]*Neighbor, error)
- func (driver *VrpDriver) RunningConfigGet(jsonformat bool) (*RunningConfigModel, error)
- func (driver *VrpDriver) RunningConfigSave() error
- func (driver *VrpDriver) SetInterfaceDescription(intf *netboxtool.NBInterface) error
- func (driver *VrpDriver) SetInterfaceDescriptions(name []string, intf []*netboxtool.NBInterface) error
- func (driver *VrpDriver) SetInterfaceVLANs(name []string, params []*VLANConfig) error
- func (driver *VrpDriver) Version() (*VersionModel, error)
Constants ¶
const ( // DefaultSessionSocket is the unix path factum2-driver start binds and // callers probe. Independent of the worker hub socket. DefaultSessionSocket = "/run/factum2-driver/session.sock" )
Variables ¶
var SupportedPlatforms = map[string]DriverFactory{}
SupportedPlatforms are the Netbox platform names (lower-cased) NewDriver can build a driver for, exported so callers like internal/device-sync can filter devices by platform up front rather than failing per-device. Each driver registers itself here via registerDriver in its own file's init(), so adding a platform never requires touching this file.
Functions ¶
func CloseSSHPool ¶ added in v1.1.1
func CloseSSHPool()
CloseSSHPool closes every in-process SSH client. Used by factum2-driver start on SIGTERM.
func CommitCLI ¶ added in v1.1.0
CommitCLI is the last command of a candidate-session apply. Platforms that support a commit comment (EOS, SR OS, IOS-XR) get `commit comment "..."` (quoted=true) or `commit comment ...` (quoted=false, XR) when comment is non-empty; otherwise a bare "commit".
func DeviceFQDN ¶
DeviceFQDN returns name as-is if it already looks like an FQDN (contains a dot); otherwise it appends defaultDomain, since drivers dial the device over the network and need a resolvable name while factum/Netbox device names are often stored as short hostnames.
func ELINETemplateData ¶ added in v1.0.2
func ELINETemplateData(intent *ELINEIntent, platform string) (any, error)
ELINETemplateData returns the value ELINE templates execute against. SR OS gets SDPID derived from the remote neighbor; other platforms get intent.
func InitSSHPool ¶ added in v1.1.1
func InitSSHPool(cfg SSHPoolConfig) error
InitSSHPool installs the process-lifetime in-process SSH CLI pool. It returns an error on invalid knobs and panics on double-init.
func InitSSHPoolFromDriver ¶ added in v1.1.1
func InitSSHPoolFromDriver(d util.ConfigDriver) error
InitSSHPoolFromDriver compiles YAML knobs and calls InitSSHPool.
func RenderCLITemplate ¶ added in v1.0.2
RenderCLITemplate is the CLI line renderer used by ELINE apply/remove.
func ResetSSHPoolForTest ¶ added in v1.1.1
func ResetSSHPoolForTest()
ResetSSHPoolForTest closes the process pool and re-inits compiled defaults with remote probe off so tests stay in-process.
func ServeSSHSession ¶ added in v1.1.1
func ServeSSHSession(ctx context.Context, d util.ConfigDriver) error
ServeSSHSession binds unix and/or TCP listeners and serves until ctx is done. InitSSHPool must already have client remote off so sshRunCLI* stay in-process.
func SessionSocketPath ¶ added in v1.1.1
SessionSocketPath resolves the session-owner unix socket for both factum2-driver start (listen) and callers (probe). yamlOverride is driver.socket. FACTUM_DRIVER_SESSION_SOCKET relocates or disables when yaml is empty. "none" and "0" disable unix. Must not use HubSocketPath.
func UnmarshalNodes ¶
func UnmarshalNodes(nodes []*ConfigNode, target any) error
UnmarshalNodes fills target (a pointer to a struct) from nodes - a top-level *ConfigNode slice, e.g. ParseConfigContext's return value, or any node's own Children for a partial/scoped parse.
Types ¶
type AristaDriver ¶
type AristaDriver struct {
DriverClient
// contains filtered or unexported fields
}
func NewAristaDriver ¶
func NewAristaDriver(p DriverParam) (*AristaDriver, error)
func (*AristaDriver) ApplyCLISession ¶ added in v1.0.2
func (driver *AristaDriver) ApplyCLISession(sessionName string, cmds []string, comment string) error
ApplyCLISession implements CLISessionApplier for Arista EOS.
func (*AristaDriver) ApplyELINE ¶
func (driver *AristaDriver) ApplyELINE(intent *ELINEIntent) error
ApplyELINE implements ELINEApplier for Arista EOS.
func (*AristaDriver) Exec ¶
func (driver *AristaDriver) Exec(cmd string) (*ExecModel, error)
Exec runs one command on the device and returns its output as text. Text format rather than JSON because cmd is arbitrary and plenty of EOS commands have no JSON representation (the device answers 1003 "not supported" for those).
func (*AristaDriver) GetDeviceConfig ¶
func (driver *AristaDriver) GetDeviceConfig() (*DeviceConfig, error)
GetDeviceConfig fetches "show running-config" over eAPI and parses it into interfaces/VRFs/ELINE/ELAN/L3VPN.
func (*AristaDriver) GetInterfacesStatus ¶
func (driver *AristaDriver) GetInterfacesStatus() ([]*netboxtool.NBInterface, error)
GetInterfacesStatus returns the operational state of every interface via NETCONF against openconfig-interfaces, or via eAPI's "show interfaces description" if NETCONF isn't available.
func (*AristaDriver) GetNeighbors ¶
func (driver *AristaDriver) GetNeighbors() ([]*Neighbor, error)
GetNeighbors returns LLDP neighbors via eAPI.
func (*AristaDriver) RemoveELINE ¶
func (driver *AristaDriver) RemoveELINE(removal *ELINERemoval) error
RemoveELINE implements ELINERemover for Arista EOS: tears down removal.Name's pseudowire/patch plus any subinterfaces still attributed to it, without configuring anything new - used when an ELINE endpoint moves off this device entirely (see web/handler_service_eline.go's ApiServiceElinePush), so the device is no longer touched by an ApplyELINE call that could otherwise carry the cleanup. Renders only the shared "cleanup" define from templates/eos_eline.tmpl.
func (*AristaDriver) RunningConfigGet ¶
func (driver *AristaDriver) RunningConfigGet(jsonformat bool) (*RunningConfigModel, error)
RunningConfigGet returns the running config as CLI text, or - with jsonformat - as EOS's own structured JSON rendering of it (a header/ comments/cmds object), passed through verbatim.
func (*AristaDriver) RunningConfigSave ¶
func (driver *AristaDriver) RunningConfigSave() error
func (*AristaDriver) SetInterfaceDescription ¶
func (driver *AristaDriver) SetInterfaceDescription(intf *netboxtool.NBInterface) error
func (*AristaDriver) SetInterfaceDescriptions ¶
func (driver *AristaDriver) SetInterfaceDescriptions(name []string, intf []*netboxtool.NBInterface) error
func (*AristaDriver) SetInterfaceVLANs ¶
func (driver *AristaDriver) SetInterfaceVLANs(name []string, params []*VLANConfig) error
SetInterfaceVLANs pushes switchport mode and VLAN membership to a set of interfaces, mirroring the config-mode CLI a human operator would type - same eAPI transport as setInterfaceDescriptionsEAPI. Every VID referenced by any target interface is first ensured to exist in EOS's own VLAN database (a top-level "vlan <id>" block, matching eosParseGlobalVlans' read shape) - EOS rejects "switchport access vlan"/"switchport trunk allowed vlan" for a VID with no such block.
func (*AristaDriver) Version ¶
func (driver *AristaDriver) Version() (*VersionModel, error)
type CLISessionApplier ¶ added in v1.0.2
type CLISessionApplier interface {
ApplyCLISession(sessionName string, cmds []string, comment string) error
}
CLISessionApplier applies already-rendered CLI lines in a config session. EOS uses sessionName for "configure session"; other platforms ignore it. comment names the operator when the platform supports it: EOS session description, SR OS/IOS-XR `commit comment`. Empty means no annotation.
type CiscoSMBDriver ¶ added in v1.0.6
type CiscoSMBDriver struct {
DriverClient
// contains filtered or unexported fields
}
func NewCiscoSMBDriver ¶ added in v1.0.6
func NewCiscoSMBDriver(p DriverParam) (*CiscoSMBDriver, error)
func (*CiscoSMBDriver) ApplyCLISession ¶ added in v1.0.6
func (driver *CiscoSMBDriver) ApplyCLISession(_ string, cmds []string, _ string) error
ApplyCLISession implements CLISessionApplier for Cisco SMB.
func (*CiscoSMBDriver) Exec ¶ added in v1.0.6
func (driver *CiscoSMBDriver) Exec(cmd string) (*ExecModel, error)
func (*CiscoSMBDriver) GetDeviceConfig ¶ added in v1.0.6
func (driver *CiscoSMBDriver) GetDeviceConfig() (*DeviceConfig, error)
func (*CiscoSMBDriver) GetInterfacesStatus ¶ added in v1.0.6
func (driver *CiscoSMBDriver) GetInterfacesStatus() ([]*netboxtool.NBInterface, error)
func (*CiscoSMBDriver) GetNeighbors ¶ added in v1.0.6
func (driver *CiscoSMBDriver) GetNeighbors() ([]*Neighbor, error)
func (*CiscoSMBDriver) RunningConfigGet ¶ added in v1.0.6
func (driver *CiscoSMBDriver) RunningConfigGet(jsonformat bool) (*RunningConfigModel, error)
func (*CiscoSMBDriver) RunningConfigSave ¶ added in v1.0.6
func (driver *CiscoSMBDriver) RunningConfigSave() error
RunningConfigSave answers the "Overwrite file [startup-config].... (Y/N)" prompt with "y".
func (*CiscoSMBDriver) SetInterfaceDescription ¶ added in v1.0.6
func (driver *CiscoSMBDriver) SetInterfaceDescription(intf *netboxtool.NBInterface) error
func (*CiscoSMBDriver) SetInterfaceDescriptions ¶ added in v1.0.6
func (driver *CiscoSMBDriver) SetInterfaceDescriptions(name []string, intf []*netboxtool.NBInterface) error
func (*CiscoSMBDriver) SetInterfaceVLANs ¶ added in v1.0.6
func (driver *CiscoSMBDriver) SetInterfaceVLANs(name []string, params []*VLANConfig) error
func (*CiscoSMBDriver) Version ¶ added in v1.0.6
func (driver *CiscoSMBDriver) Version() (*VersionModel, error)
Version scrapes "show version", "show inventory" and "show system". SG300 prints "SW version <ver>"; SG350/C1200/C1300 print an Active-image block with "Version: <ver>". PID/VID/SN come from inventory; MAC from "show system". Fields those commands don't expose are left zero-valued.
type ConfigNode ¶
type ConfigNode struct {
Line string
Children []*ConfigNode
}
ConfigNode is one line of config plus whatever's indented under it.
func FindChild ¶
func FindChild(nodes []*ConfigNode, prefix string) *ConfigNode
FindChild returns the first node in nodes whose Line has prefix as a prefix, or nil if none matches.
func GetContextLevel ¶
func GetContextLevel(nodes []*ConfigNode, path ...string) []*ConfigNode
GetContextLevel walks down path, each step matching the first child whose Line has that step as a prefix (startswith-based). Returns nil if any step isn't found.
func ParseConfigContext ¶
func ParseConfigContext(lines []string, commentPrefix string) []*ConfigNode
ParseConfigContext splits lines into a tree by leading-whitespace indentation: a line indented more than the line above it becomes that line's child, less-or-equal indentation ends the current context. Blank lines and lines starting with commentPrefix (once commentPrefix != "") are skipped entirely - they neither start nor end a context.
type DeviceConfig ¶
type DeviceConfig struct {
Interfaces []*Interface
InterfacesByName map[string]*Interface
VRFs map[string]*VRF
ELINEs map[string]*ELINE
ELANs map[string]*ELAN
L3VPNs map[string]*L3VPN
GlobalVLANs map[int]*VLAN
}
DeviceConfig is a device's fully parsed running config, returned by DriverClient.GetDeviceConfig().
func NewDeviceConfig ¶
func NewDeviceConfig() *DeviceConfig
NewDeviceConfig returns an empty, initialized DeviceConfig - callers should build through this rather than a zero value so the maps are never nil.
func (*DeviceConfig) AddInterface ¶
func (dc *DeviceConfig) AddInterface(interfaceObj *Interface)
AddInterface appends interface to both Interfaces and InterfacesByName.
type DeviceModel ¶
type DriverClient ¶
type DriverClient interface {
Exec(cmd string) (*ExecModel, error)
RunningConfigGet(json bool) (*RunningConfigModel, error)
RunningConfigSave() error
GetInterfacesStatus() ([]*netboxtool.NBInterface, error)
SetInterfaceDescription(intf *netboxtool.NBInterface) error
SetInterfaceDescriptions(name []string, intf []*netboxtool.NBInterface) error
// SetInterfaceVLANs pushes switchport/VLAN config to a set of interfaces
// - only implemented for global-VLAN platforms (EOS, VRP, Cisco SMB);
// every other platform returns an error, since they have no per-interface
// global VLAN concept (see Interface.SwitchportMode's doc comment).
SetInterfaceVLANs(name []string, params []*VLANConfig) error
Version() (*VersionModel, error)
// GetDeviceConfig fetches and parses the device's running config into
// interfaces/VRFs/pseudowires/ELINE/ELAN/L3VPN, for internal/device-sync
// to compare against Netbox.
GetDeviceConfig() (*DeviceConfig, error)
// GetNeighbors returns the device's LLDP-discovered neighbors.
GetNeighbors() ([]*Neighbor, error)
}
func NewDriver ¶
func NewDriver(deviceParam DriverParam) (DriverClient, error)
func NewDriverName ¶
func NewDriverName(factumConfig *util.ConfigFactum, name string, username string, password string) (DriverClient, error)
NewDriverName builds a driver for the device called name, looking up everything it needs over the primary's REST API rather than from Postgres: the device itself (GET /api/device/name/:name, for its platform) and util.CommonConfig (GET /api/common-config, for the default domain used to turn a short device name into something resolvable). That's what lets factum2-driver-cli run on a host that can reach the devices but has no database access - the same remote-config pattern the DNS/Icinga/LibreNMS/ Oxidized tools use, see internal/util.FetchRemoteConfig.
type DriverFactory ¶
type DriverFactory func(DriverParam) (DriverClient, error)
DriverFactory builds a DriverClient for one platform.
type DriverParam ¶
type DriverParam struct {
Name string // name on device
Port string
Username string
Password string
Platform string
// contains filtered or unexported fields
}
Parameters needed to create a device instance
func WithActor ¶ added in v1.1.1
func WithActor(p DriverParam, name string) DriverParam
WithActor returns a copy of p with the SSH session actor set. The field is unexported so JSON/constructors are not required to supply it.
type ELAN ¶
type ELAN struct {
Name string
Description string
RD string
RTImport string
RTExport string
Interfaces []string
}
ELAN is a multipoint L2 service (BGP VLAN / VPLS / bridge-domain). Interfaces holds interface/SAP names rather than resolved *Interface pointers, even though every name here also has a matching entry in DeviceConfig.InterfacesByName (SR OS's SAP ids included - see srosAddSapInterface) - callers that need the full Interface look it up there by name rather than this field carrying pointers itself.
type ELINE ¶
ELINE is a point-to-point service (patch panel / epipe / xconnect); each of Conn1/Conn2 is either a *Interface or a *Pseudowire - callers type-switch on it.
type ELINEApplier ¶
type ELINEApplier interface {
ApplyELINE(intent *ELINEIntent) error
}
ELINEApplier is implemented by drivers that can provision an ELINE. Deliberately not part of DriverClient: adding ELINE support to one driver should never force every other driver to grow a stub method. Callers type-assert for it (drv.(ELINEApplier)) and report a clean "not supported on this platform" error when the assertion fails.
type ELINEIntent ¶
type ELINEIntent struct {
Name string // ServiceID, used as the pseudowire/patch name
Description string // "ID=<ServiceID> <customer name>" - set on every subinterface this intent touches
LocalIface string // this device's physical interface, e.g. "Ethernet1"
LocalVLAN int
// ServiceNumericID is the same numeric ID as Remote.PseudowireID
// (web/handler_service_eline.go's pseudowireIDFromServiceID), but set
// unconditionally - including for a same-device ELINE, where Remote is
// nil. EOS has no use for it (a same-device patch needs no numeric ID
// at all), but SR OS does: every epipe needs a numeric service-id
// regardless of whether it carries a spoke-sdp, so this is the only
// place a same-device apply on that platform can get one from.
ServiceNumericID int
// Exactly one of PeerLocalIface or Remote is set: PeerLocalIface when
// the ELINE's other endpoint is on this same device (no pseudowire
// needed, the patch cross-connects two local subinterfaces directly),
// Remote when it's on a different device.
PeerLocalIface string
PeerLocalVLAN int
Remote *ELINERemotePeer
// StaleSubinterfaces lists "<iface>.<vlan>" subinterfaces a previous
// apply of this same service (by Name) created on this device and the
// current one no longer wants - e.g. after the service's interface or
// VLAN was edited. ELINEApplier removes them in the same atomic
// session as the rest of this apply, so a re-provision never leaves an
// orphaned subinterface behind. See ELINERemoval for the case where a
// whole device stops being an endpoint of this service.
StaleSubinterfaces []ELINEStaleSubinterface
}
ELINEIntent is one device's local half of a point-to-point ELINE service to provision - the input to an ELINEApplier. Vendor-agnostic: any future driver (SR OS, IOS-XR, ...) renders this through its own template rather than needing a new intent shape.
type ELINEPrepareChecker ¶ added in v1.0.2
type ELINEPrepareChecker interface {
PrepareELINEApply(intent *ELINEIntent) error
}
ELINEPrepareChecker runs platform guards that ApplyELINE would have executed before commit. The pack/CLISession path skips ApplyELINE, so callers must still invoke this (NokiaDriver refuses to repoint a shared SDP when last-octet IDs collide).
type ELINERemotePeer ¶
type ELINERemotePeer struct {
NeighborIP string
PseudowireID int
// MTU/ControlWord are EOS-only: its pseudowire config sets both
// explicitly per service. SR OS doesn't use either - its spoke-sdp's
// MTU and control-word are inherited from its apply-group instead (see
// driver_nokia_sros_eline.go), so there's nowhere for a per-service
// value to go on that platform even if a service needed a different
// one.
MTU int
ControlWord bool
// DeviceName/RemoteIface/RemoteVLAN describe the far end for SR OS's
// human-readable "PEER=<name> interface=<iface>.<vlan>" description
// convention (driver_nokia_sros_eline.go, confirmed against a real
// device) - EOS doesn't use them. RemoteIface/RemoteVLAN are the
// remote device's own LocalIface/LocalVLAN, i.e. the other side's
// intent - not to be confused with PeerLocalIface/PeerLocalVLAN above,
// which is this same device's other local port in the same-device
// case.
DeviceName string
RemoteIface string
RemoteVLAN int
}
ELINERemotePeer describes the ELINE's other endpoint when it's on a different device, reachable over an MPLS LDP pseudowire.
type ELINERemoval ¶
type ELINERemoval struct {
Name string // ServiceID, matches the pseudowire/patch name ApplyELINE used
StaleSubinterfaces []ELINEStaleSubinterface
}
ELINERemoval is passed to ELINERemover.RemoveELINE to fully tear down a service's config on a device that no longer participates in it at all (its endpoint moved to a different device) - unlike ApplyELINE, nothing new is configured afterward.
type ELINERemover ¶
type ELINERemover interface {
RemoveELINE(removal *ELINERemoval) error
}
ELINERemover is implemented by drivers that can tear down an abandoned ELINE endpoint. Separate from ELINEApplier for the same reason ELINEApplier is separate from DriverClient: a driver can gain ELINE support incrementally. Callers type-assert for it the same way as ELINEApplier.
type ELINEStaleSubinterface ¶
ELINEStaleSubinterface identifies one "<iface>.<vlan>" subinterface to remove as part of an ELINE apply or removal.
type IOSXRDriver ¶
type IOSXRDriver struct {
DriverClient
// contains filtered or unexported fields
}
func NewIosXRDriver ¶
func NewIosXRDriver(p DriverParam) (*IOSXRDriver, error)
func (*IOSXRDriver) ApplyCLISession ¶ added in v1.0.2
func (driver *IOSXRDriver) ApplyCLISession(_ string, cmds []string, comment string) error
ApplyCLISession implements CLISessionApplier for Cisco IOS-XR.
func (*IOSXRDriver) ApplyELINE ¶
func (driver *IOSXRDriver) ApplyELINE(intent *ELINEIntent) error
ApplyELINE implements ELINEApplier for Cisco IOS-XR.
func (*IOSXRDriver) Exec ¶
func (driver *IOSXRDriver) Exec(cmd string) (*ExecModel, error)
run command on device over classic CLI, return output.
func (*IOSXRDriver) GetDeviceConfig ¶
func (driver *IOSXRDriver) GetDeviceConfig() (*DeviceConfig, error)
GetDeviceConfig fetches and parses the device's running config.
func (*IOSXRDriver) GetInterfacesStatus ¶
func (driver *IOSXRDriver) GetInterfacesStatus() ([]*netboxtool.NBInterface, error)
GetInterfacesStatus returns the operational state of every interface via NETCONF against openconfig-interfaces.
func (*IOSXRDriver) GetNeighbors ¶
func (driver *IOSXRDriver) GetNeighbors() ([]*Neighbor, error)
GetNeighbors runs "show lldp neighbors detail" and parses the "---"- separated blocks. Local interfaces that are subinterfaces (name contains ".") are skipped.
func (*IOSXRDriver) RemoveELINE ¶
func (driver *IOSXRDriver) RemoveELINE(removal *ELINERemoval) error
RemoveELINE implements ELINERemover for Cisco IOS-XR: tears down removal.Name's xconnect entry plus any subinterfaces still attributed to it, without configuring anything new - used when an ELINE endpoint moves off this device entirely (see web/handler_service_eline.go's ApiServiceElinePush). Renders only the shared "cleanup" define from templates/iosxr_eline.tmpl.
func (*IOSXRDriver) RunningConfigGet ¶
func (driver *IOSXRDriver) RunningConfigGet(jsonformat bool) (*RunningConfigModel, error)
RunningConfigGet always returns CLI text (jsonformat is ignored) - NETCONF has no RPC that returns config the way an operator would read it (as CLI script), only the YANG tree as XML, so this goes over SSH CLI instead.
func (*IOSXRDriver) RunningConfigSave ¶
func (driver *IOSXRDriver) RunningConfigSave() error
RunningConfigSave has no XR equivalent: SetInterfaceDescriptions already commits straight to the running datastore, which persists across reload on its own - there's no separate "save" step to run.
func (*IOSXRDriver) SetInterfaceDescription ¶
func (driver *IOSXRDriver) SetInterfaceDescription(intf *netboxtool.NBInterface) error
func (*IOSXRDriver) SetInterfaceDescriptions ¶
func (driver *IOSXRDriver) SetInterfaceDescriptions(name []string, intf []*netboxtool.NBInterface) error
func (*IOSXRDriver) SetInterfaceVLANs ¶
func (driver *IOSXRDriver) SetInterfaceVLANs(name []string, params []*VLANConfig) error
SetInterfaceVLANs is unsupported on IOS-XR - it has no per-interface global-VLAN concept (see Interface.SwitchportMode's doc comment), only bridge-domain/EVI-scoped L2, which the web layer's "global VLAN platforms" gate is meant to keep this from ever being called for.
func (*IOSXRDriver) Version ¶
func (driver *IOSXRDriver) Version() (*VersionModel, error)
Version reads the chassis component's serial/hardware/software fields via NETCONF against openconfig-platform.
type Interface ¶
type Interface struct {
Name string
Description string
Type string // netbox interface type bucket: "virtual", "lag", ...
VRF string
LagID string
LagParent string
VlanID string
IPAddresses []InterfaceAddress
// Parent is another parsed Interface's Name that this one nests under in
// Netbox (Netbox's own "parent" interface relationship) - "" if this
// interface has no parent. Currently only set for SR OS SAP interfaces
// (see srosAddSapInterface), whose Parent is the physical port the SAP
// is bound to.
Parent string
// Label is Netbox's free-text interface label, distinct from Name -
// currently only set for SR OS SAP interfaces, to "SAP" (see
// srosAddSapInterface), since SR OS has no real subinterfaces and the
// Netbox interface standing in for one would otherwise look like it is.
Label string
// L2 switchport config, for global-VLAN platforms (EOS, VRP, Cisco SMB) where an
// access/trunk port references DeviceConfig.GlobalVLANs by ID - bridge-
// domain platforms (IOS-XR, SR OS) don't use these, since their VLANs
// are scoped per bridge-domain/ELAN instead, not global to the device.
SwitchportMode string // "access", "trunk" or "dot1q-tunnel" (Q-in-Q); "" if not an L2 switchport
UntaggedVLAN int // access VLAN (access mode), native/PVID VLAN (trunk mode), or outer/S-VLAN tag (dot1q-tunnel mode); 0 if none
TaggedVLANs []int // VLANs carried tagged on a trunk port
// L2Transport is true if this subinterface is configured as pure L2
// transport rather than L3/IP routing - IOS-XR's "interface X
// l2transport" and VRP's "interface X mode l2", both trailing tokens on
// the interface line itself rather than a child line. Distinct from
// SwitchportMode above, which is the global-VLAN platforms' (EOS, VRP,
// Cisco SMB physical ports) equivalent concept - a bridge-domain platform's L2
// subinterface has no global VLAN membership to express that way. Not
// consumed anywhere yet; captured so a caller like internal/device-sync
// can later tell "no IPAddresses because this is an L2 leg" apart from
// "no IPAddresses because config is incomplete".
L2Transport bool
}
Interface is one parsed interface (physical, subinterface or LAG).
type InterfaceAddress ¶
InterfaceAddress is one IP address configured on an interface, together with the VRF it belongs to (Netbox models VRF on the address; this application follows the device and keeps VRF on the interface instead - see Interface.VRF - but a device can technically configure a different VRF per address family, hence it's carried here too).
type InterfaceModel ¶
type Neighbor ¶
type Neighbor struct {
LocalInterface string
SystemID string
RemoteName string
RemoteInterface string
}
Neighbor is one LLDP-discovered neighbor.
type NokiaDriver ¶
type NokiaDriver struct {
DriverClient
// contains filtered or unexported fields
}
func NewNokiaDriver ¶
func NewNokiaDriver(p DriverParam) (*NokiaDriver, error)
func (*NokiaDriver) ApplyCLISession ¶ added in v1.0.2
func (driver *NokiaDriver) ApplyCLISession(_ string, cmds []string, comment string) error
ApplyCLISession implements CLISessionApplier for Nokia SR OS.
func (*NokiaDriver) ApplyELINE ¶
func (driver *NokiaDriver) ApplyELINE(intent *ELINEIntent) error
ApplyELINE implements ELINEApplier for Nokia SR OS.
func (*NokiaDriver) Exec ¶
func (driver *NokiaDriver) Exec(cmd string) (*ExecModel, error)
SR OS's NETCONF interface has no RPC to run an arbitrary CLI command (that's Arista eAPI's runCmds), so like RunningConfigGet this goes over SSH instead. Only the paging-disable step is forced through the classic CLI engine via "//" - cmd itself is sent as-is, since it's the caller's choice of command/engine, not ours to override.
func (*NokiaDriver) GetDeviceConfig ¶
func (driver *NokiaDriver) GetDeviceConfig() (*DeviceConfig, error)
GetDeviceConfig fetches and parses the device's MD-CLI JSON running config.
func (*NokiaDriver) GetInterfacesStatus ¶
func (driver *NokiaDriver) GetInterfacesStatus() ([]*netboxtool.NBInterface, error)
GetInterfacesStatus returns the operational state of every interface.
func (*NokiaDriver) GetNeighbors ¶
func (driver *NokiaDriver) GetNeighbors() ([]*Neighbor, error)
GetNeighbors runs "show port * ethernet lldp remote-info" and block- parses it - each neighbor starts at a "Port 1..." line, and "Port Id"'s real value (unlike every other field) is on the line *after* its header, quoted.
func (*NokiaDriver) PrepareELINEApply ¶ added in v1.0.2
func (driver *NokiaDriver) PrepareELINEApply(intent *ELINEIntent) error
PrepareELINEApply implements ELINEPrepareChecker: same SDP far-end guard ApplyELINE runs, for the pack/CLISession path that does not call ApplyELINE.
func (*NokiaDriver) RemoveELINE ¶
func (driver *NokiaDriver) RemoveELINE(removal *ELINERemoval) error
RemoveELINE implements ELINERemover for Nokia SR OS: deletes removal.Name's epipe (and everything nested under it) without configuring anything new. Renders only the shared "cleanup" define from templates/sros_eline.tmpl.
func (*NokiaDriver) RunningConfigGet ¶
func (driver *NokiaDriver) RunningConfigGet(jsonformat bool) (*RunningConfigModel, error)
func (*NokiaDriver) RunningConfigSave ¶
func (driver *NokiaDriver) RunningConfigSave() error
SR OS's <commit> (see SetInterfaceDescriptions) lands directly in the running datastore - there's no separate startup datastore involved at the NETCONF layer, so there is no separate "save running as startup" step. Persisting running config across a reboot is a distinct, unrelated step on SR OS (MD-CLI "admin save"), which this driver doesn't implement.
func (*NokiaDriver) SetInterfaceDescription ¶
func (driver *NokiaDriver) SetInterfaceDescription(intf *netboxtool.NBInterface) error
func (*NokiaDriver) SetInterfaceDescriptions ¶
func (driver *NokiaDriver) SetInterfaceDescriptions(name []string, description []*netboxtool.NBInterface) error
func (*NokiaDriver) SetInterfaceVLANs ¶
func (driver *NokiaDriver) SetInterfaceVLANs(name []string, params []*VLANConfig) error
SetInterfaceVLANs is unsupported on SR OS - it has no per-interface global-VLAN concept (see Interface.SwitchportMode's doc comment); every VLAN-tagged construct on this platform is a SAP scoped inside a service (epipe/vpls/vprn), not a standalone interface property. The web layer's "global VLAN platforms" gate is meant to keep this from ever being called.
func (*NokiaDriver) Version ¶
func (driver *NokiaDriver) Version() (*VersionModel, error)
type OpenROADMDriver ¶ added in v1.0.4
type OpenROADMDriver struct {
DriverClient
// contains filtered or unexported fields
}
OpenROADMDriver talks NETCONF (RFC 6241 over SSH 830) to an Open ROADM MSA device. It is read-only: inventory, interface status, neighbors and the YANG tree are fetched with <get>; every write method returns an error. The YANG namespace (http://org/openroadm/device) has been stable from MSA 1.2 through current device-model revisions; leaf names used here exist across that range. Frequency lives on later-model NMC-CTP / OCH / OTSi augment containers and is simply absent on 1.2/2.2 replies.
func NewOpenROADMDriver ¶ added in v1.0.4
func NewOpenROADMDriver(p DriverParam) (*OpenROADMDriver, error)
func (*OpenROADMDriver) Exec ¶ added in v1.0.4
func (driver *OpenROADMDriver) Exec(cmd string) (*ExecModel, error)
func (*OpenROADMDriver) GetDeviceConfig ¶ added in v1.0.4
func (driver *OpenROADMDriver) GetDeviceConfig() (*DeviceConfig, error)
func (*OpenROADMDriver) GetInterfacesStatus ¶ added in v1.0.4
func (driver *OpenROADMDriver) GetInterfacesStatus() ([]*netboxtool.NBInterface, error)
func (*OpenROADMDriver) GetNeighbors ¶ added in v1.0.4
func (driver *OpenROADMDriver) GetNeighbors() ([]*Neighbor, error)
func (*OpenROADMDriver) GetOpticalInventory ¶ added in v1.0.4
func (driver *OpenROADMDriver) GetOpticalInventory() (*OpticalInventory, error)
GetOpticalInventory maps org-openroadm-device onto Factum optical kinds, port roles and xconnects. Persist via optical.ApplyInventory (device-sync and `factum2-driver optical-inventory-apply`).
func (*OpenROADMDriver) RunningConfigGet ¶ added in v1.0.4
func (driver *OpenROADMDriver) RunningConfigGet(jsonformat bool) (*RunningConfigModel, error)
RunningConfigGet returns the raw org-openroadm-device XML from <get>. jsonformat is ignored: there is no CLI-text or CLI-JSON equivalent.
func (*OpenROADMDriver) RunningConfigSave ¶ added in v1.0.4
func (driver *OpenROADMDriver) RunningConfigSave() error
func (*OpenROADMDriver) SetInterfaceDescription ¶ added in v1.0.4
func (driver *OpenROADMDriver) SetInterfaceDescription(intf *netboxtool.NBInterface) error
func (*OpenROADMDriver) SetInterfaceDescriptions ¶ added in v1.0.4
func (driver *OpenROADMDriver) SetInterfaceDescriptions(name []string, intf []*netboxtool.NBInterface) error
func (*OpenROADMDriver) SetInterfaceVLANs ¶ added in v1.0.4
func (driver *OpenROADMDriver) SetInterfaceVLANs(name []string, params []*VLANConfig) error
func (*OpenROADMDriver) Version ¶ added in v1.0.4
func (driver *OpenROADMDriver) Version() (*VersionModel, error)
type OpticalClient ¶ added in v1.0.4
type OpticalClient interface {
GetOpticalInventory() (*OpticalInventory, error)
}
OpticalClient is implemented by drivers that can read optical inventory (ROADM degrees/SRGs, transponder ports, intra-device xconnects). Deliberately not part of DriverClient: adding optical support to one driver should never force every other driver to grow a stub method.
type OpticalInventory ¶ added in v1.0.4
type OpticalInventory struct {
NodeID string `json:"node_id"`
NodeType string `json:"node_type"`
OpticalKind string `json:"optical_kind"`
Vendor string `json:"vendor"`
Model string `json:"model"`
Serial string `json:"serial"`
SoftwareVersion string `json:"software_version"`
OpenROADMVersion string `json:"openroadm_version"`
Ports []OpticalPortView `json:"ports"`
XConnects []OpticalXConnectView `json:"xconnects"`
}
OpticalInventory is one device's Open ROADM inventory, keyed with the same kind/role/xconnect strings as models.OpticalKind* / Port* / XC*.
func (*OpticalInventory) ApplyInventory ¶ added in v1.0.4
func (inv *OpticalInventory) ApplyInventory() optical.Inventory
ApplyInventory is the Factum optical.Inventory shape of this dump, for optical.ApplyInventory / PUT /api/optical/device/:id/inventory.
type OpticalPortView ¶ added in v1.0.4
type OpticalPortView struct {
Name string `json:"name"`
CircuitPack string `json:"circuit_pack"`
PortName string `json:"port_name"`
Role string `json:"role"`
Description string `json:"description"`
AdminStatus string `json:"admin_status"`
OperStatus string `json:"oper_status"`
FreqHz uint64 `json:"freq_hz"`
Qual string `json:"qual"`
}
OpticalPortView is one physical circuit-pack port with a Factum optical role. Name is "circuit-pack-name/port-name".
type OpticalXConnectView ¶ added in v1.0.4
type OpticalXConnectView struct {
Name string `json:"name"`
Kind string `json:"kind"`
PortA string `json:"port_a"`
PortB string `json:"port_b"`
FreqHz uint64 `json:"freq_hz"`
CircuitID string `json:"circuit_id"`
}
OpticalXConnectView is one intra-device optical adjacency. PortA/PortB are OpticalPortView.Name values. Kind is models.XC*.
type Pseudowire ¶
type Pseudowire struct {
Name string
Neighbor string
Type string
PWID int
MTU int
ControlWord bool
}
Pseudowire is one MPLS/SDP pseudowire, used as one end of an ELINE.
type RunningConfigModel ¶
type RunningConfigModel struct {
ConfigStr string
}
type RunningConfigStructured ¶
type RunningConfigStructured struct {
ConfigStruct any
}
type SSHPoolConfig ¶ added in v1.1.1
type SSHPoolConfig struct {
Platforms *[]string
IdleTimeout time.Duration
MaxSessions int
QueueDepth int
AcquireTimeout time.Duration
Keepalive time.Duration
SessionURL string
SessionToken string
TLSCA string
Socket string
}
SSHPoolConfig is the process-lifetime pool knobs. Zero / empty values mean compiled defaults. Negative ints and durations are rejected by InitSSHPool.
func PoolConfigFromDriver ¶ added in v1.1.1
func PoolConfigFromDriver(d util.ConfigDriver) (SSHPoolConfig, error)
PoolConfigFromDriver maps YAML ConfigDriver onto SSHPoolConfig. Empty duration strings stay zero (compiled defaults at InitSSHPool).
type VLANConfig ¶
type VLANConfig struct {
SwitchportMode string // "access", "trunk" or "dot1q-tunnel" (Q-in-Q); "" to remove switchport config
UntaggedVLAN int // access VLAN, native/PVID VLAN, or outer/S-VLAN tag; 0 if none
TaggedVLANs []int // VLANs carried tagged on a trunk port
}
VLANConfig is the desired switchport/VLAN state for one interface, passed to DriverClient.SetInterfaceVLANs - the write-side counterpart of Interface's SwitchportMode/UntaggedVLAN/TaggedVLANs fields above. Only meaningful on global-VLAN platforms (EOS, VRP, Cisco SMB) - see SetInterfaceVLANs.
type VRF ¶
type VRF struct {
Name string
Description string
RD string
RTImport string
RTExport string
Interfaces []string
}
VRF is a routing/forwarding instance. Interfaces holds the names of parsed interfaces that reference this VRF.
type VersionModel ¶
type VrpDriver ¶
type VrpDriver struct {
DriverClient
// contains filtered or unexported fields
}
func NewVrpDriver ¶
func NewVrpDriver(p DriverParam) (*VrpDriver, error)
func (*VrpDriver) ApplyCLISession ¶ added in v1.0.6
ApplyCLISession implements CLISessionApplier for Huawei VRP.
func (*VrpDriver) GetDeviceConfig ¶
func (driver *VrpDriver) GetDeviceConfig() (*DeviceConfig, error)
func (*VrpDriver) GetInterfacesStatus ¶
func (driver *VrpDriver) GetInterfacesStatus() ([]*netboxtool.NBInterface, error)
func (*VrpDriver) GetNeighbors ¶
GetNeighbors runs "display lldp neighbor" and parses it: each "<ifname> has N neighbor(s):" line starts a new neighbor block.
func (*VrpDriver) RunningConfigGet ¶
func (driver *VrpDriver) RunningConfigGet(jsonformat bool) (*RunningConfigModel, error)
func (*VrpDriver) RunningConfigSave ¶
RunningConfigSave answers VRP's "save" confirmation prompt with "y".
func (*VrpDriver) SetInterfaceDescription ¶
func (driver *VrpDriver) SetInterfaceDescription(intf *netboxtool.NBInterface) error
func (*VrpDriver) SetInterfaceDescriptions ¶
func (driver *VrpDriver) SetInterfaceDescriptions(name []string, intf []*netboxtool.NBInterface) error
func (*VrpDriver) SetInterfaceVLANs ¶
func (driver *VrpDriver) SetInterfaceVLANs(name []string, params []*VLANConfig) error
SetInterfaceVLANs pushes switchport mode and VLAN membership to a set of interfaces. Every VID referenced by any target interface is first declared via "vlan batch <ids>" (matching vrpReVlanBatch's read shape) - VRP rejects "port default vlan"/"port trunk allow-pass vlan" for a VID that hasn't been declared.
func (*VrpDriver) Version ¶
func (driver *VrpDriver) Version() (*VersionModel, error)
Version scrapes a handful of fields out of "display version" text - VRP has no structured (JSON/NETCONF) equivalent to ask instead. Fields VRP's "display version" doesn't clearly expose (MemTotal/MemFree/ BootupTimestap/Architecture/InternalBuildId/SystemMacAddress/ SerialNumber/HardwareRevision) are left zero-valued rather than guessed.
Source Files
¶
- config_context.go
- driver.go
- driver_arista_eos.go
- driver_arista_eos_eline.go
- driver_ciscosmb.go
- driver_iosxr.go
- driver_iosxr_eline.go
- driver_nokia_sros.go
- driver_nokia_sros_eline.go
- driver_openroadm.go
- driver_openroadm_xml.go
- driver_vrp.go
- eapi.go
- eline_intent.go
- eline_template.go
- models.go
- openconfig.go
- sshsession.go
- sshsession_http.go
- tagparse.go