Documentation
¶
Overview ¶
Package confetti is a schema-aware, offline engine for network-device CLI configurations. It parses, validates, canonicalizes, remediates, rolls back, compares, and merges configuration text without connecting to a device.
The Engine ties a platform grammar (schema.Schema), a strict/lenient policy (diag.Policy), and the import/export transform pipelines. Grammar is data: platforms are authored as schemas and live outside this module (the in-repo internal/fixture schemas are test fixtures and authoring references). See docs/design.md for the architecture and the design invariants and docs/fixtures.md for fixture grammar lineage.
Remediate and Rollback run a commit check on their goal. Render, Merge, and Compare do not because callers can use them with incomplete configurations.
Example ¶
Example imports two configurations and renders the remediation commands.
package main
import (
"fmt"
confetti "github.com/acidsailor/confetti"
"github.com/acidsailor/confetti/schema"
)
// switchSchema defines VLANs and access ports that reference them.
func switchSchema() *schema.Schema {
s := schema.New()
vlan := s.Node("vlan {{ id:uint }}").
Card(schema.ZeroToN).
Kind("vlan").
Key("id")
vlan.Child("name {{ text:word }}").Card(schema.ZeroToOne).MarkIdempotent()
iface := s.Node("interface {{ name:word }}").
Card(schema.ZeroToN).
Kind("interface").
Key("name")
iface.Child("switchport access vlan {{ vlan:uint }}").
Card(schema.ZeroToOne).MarkIdempotent().Ref("vlan", "vlan.id")
return s
}
func main() {
e := confetti.New(switchSchema())
running, _ := e.Import(
"vlan 10\n" +
" name USERS\n" +
"vlan 30\n" +
" name LEGACY\n" +
"interface Ethernet1/1\n" +
" switchport access vlan 10\n")
intended, _ := e.Import(
"vlan 10\n" +
" name STAFF\n" +
"vlan 20\n" +
" name GUESTS\n" +
"interface Ethernet1/1\n" +
" switchport access vlan 20\n")
res, d := e.Remediate(running, intended)
if d.HasErrors() {
fmt.Print(d.String())
return
}
artifact, _ := e.Render(res.Tree)
fmt.Print(artifact)
}
Output: vlan 10 name STAFF vlan 20 name GUESTS interface Ethernet1/1 switchport access vlan 20 no vlan 30
Index ¶
- type Engine
- func (e *Engine) CommitCheck(cfg *tree.Config) *diag.Diagnostics
- func (e *Engine) Compare(running, intended *tree.Config) (string, *diag.Diagnostics)
- func (e *Engine) Import(text string) (*tree.Config, *diag.Diagnostics)
- func (e *Engine) Merge(parts ...*tree.Config) (*tree.Config, *diag.Diagnostics)
- func (e *Engine) Remediate(running, intended *tree.Config) (*remediate.Result, *diag.Diagnostics)
- func (e *Engine) Render(cfg *tree.Config) (string, *diag.Diagnostics)
- func (e *Engine) Rollback(running, intended *tree.Config) (*remediate.Result, *diag.Diagnostics)
- type Option
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine ties a schema, a policy, and the import/export transform pipelines.
func (*Engine) CommitCheck ¶
func (e *Engine) CommitCheck(cfg *tree.Config) *diag.Diagnostics
CommitCheck runs Phase B referential integrity over an assembled tree.
Example ¶
ExampleEngine_CommitCheck reports a reference to an undefined VLAN.
package main
import (
"fmt"
confetti "github.com/acidsailor/confetti"
"github.com/acidsailor/confetti/schema"
)
// switchSchema defines VLANs and access ports that reference them.
func switchSchema() *schema.Schema {
s := schema.New()
vlan := s.Node("vlan {{ id:uint }}").
Card(schema.ZeroToN).
Kind("vlan").
Key("id")
vlan.Child("name {{ text:word }}").Card(schema.ZeroToOne).MarkIdempotent()
iface := s.Node("interface {{ name:word }}").
Card(schema.ZeroToN).
Kind("interface").
Key("name")
iface.Child("switchport access vlan {{ vlan:uint }}").
Card(schema.ZeroToOne).MarkIdempotent().Ref("vlan", "vlan.id")
return s
}
func main() {
e := confetti.New(switchSchema())
cfg, _ := e.Import(
"interface Ethernet1/1\n" +
" switchport access vlan 999\n")
d := e.CommitCheck(cfg)
fmt.Print(d.String())
}
Output: 2: error: interface Ethernet1/1 / switchport access vlan 999: vlan "999" does not exist
func (*Engine) Compare ¶
Compare returns a git-diff-style view without commit-checking either input.
func (*Engine) Import ¶
Import applies text rules outside raw blocks, parses and folds the input, applies tree transforms, and runs Phase A validation.
func (*Engine) Merge ¶
Merge combines fragments in order without running a commit check; strict conflicts keep the first value, lenient conflicts keep the last, and list slots form a union.
func (*Engine) Remediate ¶
func (e *Engine) Remediate( running, intended *tree.Config, ) (*remediate.Result, *diag.Diagnostics)
Remediate checks intended and returns the operation-tagged difference from running to intended.
type Option ¶
type Option func(*Engine)
Option configures an Engine.
func WithExportText ¶
WithExportText appends export-side (post-render) text transforms.
func WithExportTree ¶
func WithExportTree(ts ...transform.TreeTransform) Option
WithExportTree appends export-side (pre-render) tree transforms.
func WithImportText ¶
WithImportText appends import-side (pre-parse) text transforms.
func WithImportTree ¶
func WithImportTree(ts ...transform.TreeTransform) Option
WithImportTree appends import-side (post-parse) tree transforms.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package compare renders a remediation change log in a git-diff-style format.
|
Package compare renders a remediation change log in a git-diff-style format. |
|
Package diag defines Error and Warning diagnostics with optional 1-based source lines.
|
Package diag defines Error and Warning diagnostics with optional 1-based source lines. |
|
Package graph defines the remediation-ordering dependency graph passed to schema OrderHooks.
|
Package graph defines the remediation-ordering dependency graph passed to schema OrderHooks. |
|
internal
|
|
|
fixture/alpha
Package alpha defines an imaginary switch CLI fixture for blocks, toggles, physical-port resets, feature gates, list values, and dual-form membership.
|
Package alpha defines an imaginary switch CLI fixture for blocks, toggles, physical-port resets, feature gates, list values, and dual-form membership. |
|
fixture/beta
Package beta defines an imaginary switch CLI fixture for composite keys, EmptyOnRemove, and self-union.
|
Package beta defines an imaginary switch CLI fixture for composite keys, EmptyOnRemove, and self-union. |
|
ident
Package ident defines the node-pairing identity shared by parse, remediate, merge, and validate.
|
Package ident defines the node-pairing identity shared by parse, remediate, merge, and validate. |
|
lcp
Package lcp computes the longest-common-prefix length of ordered paths.
|
Package lcp computes the longest-common-prefix length of ordered paths. |
|
listval
Package listval defines the separator and range grammar for list-valued arguments.
|
Package listval defines the separator and range grammar for list-valued arguments. |
|
testtypes
Package testtypes defines the ifname, ipv4, vlan, and asn value types used by core package tests.
|
Package testtypes defines the ifname, ipv4, vlan, and asn value types used by core package tests. |
|
valcheck
Package valcheck holds the value.Type Check helpers shared by the fixture schemas and the core test types.
|
Package valcheck holds the value.Type Check helpers shared by the fixture schemas and the core test types. |
|
Package merge assembles configuration fragments from left to right in a new tree.
|
Package merge assembles configuration fragments from left to right in a new tree. |
|
Package parse converts configuration text to a tree.Config.
|
Package parse converts configuration text to a tree.Config. |
|
Package remediate computes the ordered CLI commands that change running configuration into intended configuration.
|
Package remediate computes the ordered CLI commands that change running configuration into intended configuration. |
|
Package render converts a tree.Config to canonical text.
|
Package render converts a tree.Config to canonical text. |
|
Package schema declares a platform grammar as a tree of node definitions, each a line template with typed captures ("vlan {{ id:vlan }}"), plus the metadata used by other packages: cardinality, Kind/Key identity, cross-references (Ref), prerequisite Kinds (Requires), negation and reset forms (NegateAs/NegateDefault/NegateFunc), raw-block capture (BlockDelim/BlockUntil), toggle groups (Toggles), list-valued args (List/ListDelta/ListKeywords/ListContinues), dual-form spellings (Members/RespellAs), and Protected deletion constraints.
|
Package schema declares a platform grammar as a tree of node definitions, each a line template with typed captures ("vlan {{ id:vlan }}"), plus the metadata used by other packages: cardinality, Kind/Key identity, cross-references (Ref), prerequisite Kinds (Requires), negation and reset forms (NegateAs/NegateDefault/NegateFunc), raw-block capture (BlockDelim/BlockUntil), toggle groups (Toggles), list-valued args (List/ListDelta/ListKeywords/ListContinues), dual-form spellings (Members/RespellAs), and Protected deletion constraints. |
|
Package transform defines text rules and tree transforms.
|
Package transform defines text rules and tree transforms. |
|
Package tree defines the configuration tree shared by all pipeline stages.
|
Package tree defines the configuration tree shared by all pipeline stages. |
|
Package validate implements two phases of semantic validation.
|
Package validate implements two phases of semantic validation. |
|
Package value defines the registry for typed captures such as "{{ id:vlan }}".
|
Package value defines the registry for typed captures such as "{{ id:vlan }}". |