cfgmgmt

package
v1.0.2 Latest Latest
Warning

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

Go to latest
Published: Aug 31, 2026 License: AGPL-3.0 Imports: 16 Imported by: 0

README

internal/cfgmgmt

Configuration management: scope tree, typed variables, service types, platform packs, and CLI render/preview.

How to design a service type (roles, fields, packs, templates, push): docs/cfgmgmt-service-design.md.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AttachDevice

func AttachDevice(db *gorm.DB, parentID, deviceID uint) (*models.ConfigScope, error)

AttachDevice creates or updates a device-kind node under parentID and ensures a child interface node exists for each inventory interface.

func CreateScope

func CreateScope(db *gorm.DB, s *models.ConfigScope) (*models.ConfigScope, error)

func DeleteAssignment

func DeleteAssignment(db *gorm.DB, id uint) error

func DeleteScope

func DeleteScope(db *gorm.DB, id uint) error

func DescendantScopes

func DescendantScopes(db *gorm.DB, rootID uint) ([]models.ConfigScope, error)

func GetScope

func GetScope(db *gorm.DB, id uint) (*models.ConfigScope, error)

func IsSROS

func IsSROS(platform string) bool

func ListAssignments

func ListAssignments(db *gorm.DB, scopeID uint) ([]models.ConfigAssignment, error)

func ListEndpoints

func ListEndpoints(db *gorm.DB, serviceID uint) ([]models.ServiceEndpoint, error)

func ListScopes

func ListScopes(db *gorm.DB) ([]models.ConfigScope, error)

func LookupPlatformPack

func LookupPlatformPack(db *gorm.DB, typeName, platform string) (*models.PlatformPack, error)

LookupPlatformPack returns the pack for typeName+platform. sros-md falls back to sros when no dedicated pack exists.

func LookupServiceType

func LookupServiceType(db *gorm.DB, name string) (*models.ServiceType, error)

LookupServiceType finds a service type by name.

func NormalizePlatform

func NormalizePlatform(p string) string

func RedactAssignmentSecrets

func RedactAssignmentSecrets(db *gorm.DB, rows []models.ConfigAssignment) error

func RedactVariableSecrets

func RedactVariableSecrets(def *models.ConfigVariableDef)

func Render

func Render(db *gorm.DB, body, define string, data any) ([]string, error)

Render executes Go text/template body (or a named define) against data. FuncMap is limited: include (named ConfigMacro), join. No file/HTTP/shell.

func RenderPackApply

func RenderPackApply(db *gorm.DB, pack *models.PlatformPack, data any) ([]string, error)

RenderPackApply renders a platform pack's apply template.

func RenderPackApplyBody

func RenderPackApplyBody(db *gorm.DB, pack *models.PlatformPack, data any) ([]string, error)

RenderPackApplyBody renders the apply template with the "cleanup" define emptied so a multi-endpoint push can run teardown once, then each body.

func RenderPackCleanup

func RenderPackCleanup(db *gorm.DB, pack *models.PlatformPack, data any) ([]string, error)

RenderPackCleanup renders teardown commands from CleanupTemplate, or the apply template's "cleanup" define when CleanupTemplate is empty.

func RenderPackCleanupIfPresent

func RenderPackCleanupIfPresent(db *gorm.DB, pack *models.PlatformPack, data any) ([]string, error)

RenderPackCleanupIfPresent is RenderPackCleanup, or nil if the pack has no cleanup template and no "cleanup" define.

func ReplaceEndpoints

func ReplaceEndpoints(db *gorm.DB, serviceID uint, eps []models.ServiceEndpoint) error

func RequireCLIPack

func RequireCLIPack(pack *models.PlatformPack) error

func Resolve

func Resolve(db *gorm.DB, interfaceID uint, varName string) (any, *models.ConfigScope, error)

Resolve walks from the interface's start scope to root and returns the first assignment of varName. Falls back to the def's DefaultValue.

func ResolveMap

func ResolveMap(db *gorm.DB, interfaceID uint) (map[string]any, error)

ResolveMap is ResolveAll as name → value, skipping vars that failed.

func ResolveMapForDevice

func ResolveMapForDevice(db *gorm.DB, deviceID uint) (map[string]any, error)

ResolveMapForDevice resolves variables from the device scope (not a particular interface), filtered by the device's platform.

func RootScope

func RootScope(db *gorm.DB) (*models.ConfigScope, error)

RootScope returns the global root folder.

func SDPIDFromNeighbor

func SDPIDFromNeighbor(neighborIP string) (int, error)

SDPIDFromNeighbor is the SR OS shared SDP ID (last IPv4 octet).

func SecretDefaultUnchanged

func SecretDefaultUnchanged(raw []byte) bool

SecretDefaultUnchanged reports that a write should keep the stored secret default: the client omitted it, sent JSON null, or echoed the redaction placeholder.

func Seed

func Seed(db *gorm.DB) error

Seed creates the global root scope, built-in service types, and ELINE platform packs when they are missing. Operator-edited packs are left alone; checksum-matching rows are refreshed from the embed files.

func ServiceTypeExists

func ServiceTypeExists(db *gorm.DB, name string) (bool, error)

func StartScope

func StartScope(db *gorm.DB, interfaceID uint) (*models.ConfigScope, error)

StartScope for an interface: interface node, else device node, else global.

func TypeCheck

func TypeCheck(def *models.ConfigVariableDef, v any) (any, error)

TypeCheck coerces and validates v against def. Type, constraints, and (for vlan) the 1–4094 range. List entries and map keys/values are checked recursively when constraints.items / keys / values are set.

func TypeCheckRaw

func TypeCheckRaw(def *models.ConfigVariableDef, raw json.RawMessage) (any, error)

func UpdateScope

func UpdateScope(db *gorm.DB, id uint, patch *models.ConfigScope) (*models.ConfigScope, error)

func UpsertAssignment

func UpsertAssignment(db *gorm.DB, defID, scopeID uint, value []byte) (*models.ConfigAssignment, error)

func ValidScopeKind

func ValidScopeKind(k string) bool

func ValidVarType

func ValidVarType(t string) bool

func ValidateConstraints

func ValidateConstraints(typ string, raw json.RawMessage) error

ValidateConstraints checks nested items/keys/values type names and that list/map-only fields are not set on scalar types.

func ValidateEndpoints

func ValidateEndpoints(db *gorm.DB, st *models.ServiceType, eps []models.ServiceEndpoint) error

ValidateEndpoints checks endpoints against the service type's EndpointRoles and that each device/interface pair exists in inventory.

func ValidateVariableDef

func ValidateVariableDef(def *models.ConfigVariableDef) error

ValidateVariableDef checks type, constraints, and default_value.

func WalkParents

func WalkParents(db *gorm.DB, start *models.ConfigScope) ([]models.ConfigScope, error)

WalkParents returns start then each ancestor up to root. A cycle is an error.

func WouldCycle

func WouldCycle(db *gorm.DB, nodeID uint, newParentID uint) (bool, error)

WouldCycle reports whether setting node's parent to newParentID would loop.

Types

type DCIMDevice

type DCIMDevice struct {
	ID           uint   `json:"id"`
	Name         string `json:"name"`
	Platform     string `json:"platform"`
	Site         string `json:"site"`
	Role         string `json:"role"`
	ModelName    string `json:"model_name"`
	Manufacturer string `json:"manufacturer"`
	Status       string `json:"status"`
	PrimaryIPv4  string `json:"primary_ipv4"`
	PrimaryIPv6  string `json:"primary_ipv6"`
}

DCIMDevice is the read-only inventory fragment templates may use.

func DCIMFromDevice

func DCIMFromDevice(d *models.Device) DCIMDevice

type DCIMInterface

type DCIMInterface struct {
	ID           uint     `json:"id"`
	Name         string   `json:"name"`
	Description  string   `json:"description"`
	Enabled      bool     `json:"enabled"`
	Type         string   `json:"type"`
	UntaggedVLAN int      `json:"untagged_vlan"`
	TaggedVLANs  []int    `json:"tagged_vlans"`
	Addresses    []string `json:"addresses"`
}

DCIMInterface is the read-only interface fragment templates may use.

func DCIMFromInterface

func DCIMFromInterface(iface *models.Interface) DCIMInterface

type DeviceRender

type DeviceRender struct {
	DeviceID uint             `json:"device_id"`
	Name     string           `json:"name"`
	Platform string           `json:"platform"`
	Sources  []RenderedSource `json:"sources"`
}

func RenderDevice

func RenderDevice(db *gorm.DB, deviceID uint) (*DeviceRender, error)

RenderDevice returns baseline templates + terminating services for a device. It does not talk to the device.

type ELINERemote

type ELINERemote struct {
	NeighborIP   string
	PseudowireID int
	MTU          int
	ControlWord  bool
	DeviceName   string
	RemoteIface  string
	RemoteVLAN   int
}

type ELINERenderData

type ELINERenderData struct {
	Name               string
	Description        string
	LocalIface         string
	LocalVLAN          int
	PeerLocalIface     string
	PeerLocalVLAN      int
	ServiceNumericID   int
	Remote             *ELINERemote
	StaleSubinterfaces []ELINEStale
	SDPID              int
	Vars               map[string]any
	Device             DCIMDevice
	Interface          DCIMInterface
}

ELINERenderData is the template context for ELINE packs. Field names match the existing embed templates (.Name, .LocalIface, .Remote, .SDPID, …).

type ELINEStale

type ELINEStale struct {
	Iface string
	VLAN  int
}

type GenericRenderData

type GenericRenderData struct {
	Name             string
	Description      string
	ServiceNumericID int
	Fields           map[string]any
	Endpoint         map[string]any
	Vars             map[string]any
	Device           DCIMDevice
	Interface        DCIMInterface
	LocalIface       string
	LocalVLAN        int
	Role             string
}

GenericRenderData is the template context for non-ELINE services.

func GenericData

func GenericData(db *gorm.DB, svc *models.Service, ep *models.ServiceEndpoint, device *models.Device, iface *models.Interface) (*GenericRenderData, error)

type MatrixRow

type MatrixRow struct {
	InterfaceID   uint   `json:"interface_id"`
	InterfaceName string `json:"interface_name"`
	DeviceID      uint   `json:"device_id"`
	DeviceName    string `json:"device_name"`
	ScopeID       *uint  `json:"scope_id,omitempty"`
	Value         any    `json:"value"`
	SourceID      *uint  `json:"source_id,omitempty"`
	SourceName    string `json:"source_name,omitempty"`
	FromDefault   bool   `json:"from_default"`
	Error         string `json:"error,omitempty"`
}

MatrixRows are interfaces under a scope subtree, with one variable resolved.

func Matrix

func Matrix(db *gorm.DB, scopeID uint, varName string) ([]MatrixRow, error)

type RenderedSource

type RenderedSource struct {
	Source      string   `json:"source"`
	Kind        string   `json:"kind"` // template | service
	Platform    string   `json:"platform"`
	PayloadKind string   `json:"payload_kind"`
	Commands    []string `json:"commands"`
	Error       string   `json:"error,omitempty"`
}

RenderedSource is one template or service's rendered CLI (or other payload).

func RenderService

func RenderService(db *gorm.DB, serviceID uint) ([]RenderedSource, error)

RenderService renders every endpoint of a service (preview, no device I/O).

type ResolvedVar

type ResolvedVar struct {
	Name        string
	Value       any
	Source      *models.ConfigScope
	FromDefault bool
	Secret      bool
	Required    bool
	Type        string
	Err         error
}

ResolvedVar is one variable's winning value and the scope it came from.

func RedactSecrets

func RedactSecrets(vars []ResolvedVar) []ResolvedVar

func ResolveAll

func ResolveAll(db *gorm.DB, interfaceID uint) ([]ResolvedVar, error)

ResolveAll returns every variable def resolved at interfaceID. Required vars with no value are included with Err set rather than failing the batch.

type ScopeTreeData

type ScopeTreeData struct {
	ID          uint   `json:"id"`
	Kind        string `json:"kind"`
	ParentID    *uint  `json:"parent_id,omitempty"`
	SiteID      *uint  `json:"site_id,omitempty"`
	DeviceID    *uint  `json:"device_id,omitempty"`
	InterfaceID *uint  `json:"interface_id,omitempty"`
	SortOrder   int    `json:"sort_order"`
}

type ScopeTreeNode

type ScopeTreeNode struct {
	Key      string          `json:"key"`
	Title    string          `json:"title"`
	Type     string          `json:"type"`
	Data     ScopeTreeData   `json:"data"`
	Children []ScopeTreeNode `json:"children,omitempty"`
}

ScopeTreeNode is one nested scope for GET /api/config/scopes/tree.

func ScopeTree

func ScopeTree(db *gorm.DB) ([]ScopeTreeNode, error)

type StatusError

type StatusError struct {
	Status  int
	Message string
}

StatusError is an application-level failure with an HTTP-ish status so handlers don't have to string-match error text.

func AsStatusError

func AsStatusError(err error) *StatusError

func (*StatusError) Error

func (e *StatusError) Error() string

Jump to

Keyboard shortcuts

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