Documentation
¶
Index ¶
- Constants
- Variables
- func GetStringValue(nodes []XpathNode) string
- func GetStringValues(nodes []XpathNode, addEmptyStr bool) []string
- func GetTokenName(token int) string
- func MatchFilter(filter XFilter, target XTarget) bool
- func NodeString(xNode XpathNode) string
- func NodesEqual(n1, n2 XpathNode) error
- func NodesetsEqual(ns1, ns2 []XpathNode) error
- func PrintTree(startNode XpathNode)
- func ValidateTree(root XpathNode) error
- type MatchType
- type NodeRef
- type NodeRefElem
- type NodeRefKey
- type PathType
- type SortSpec
- type TargetType
- type WarnType
- type Warning
- type XFilter
- type XTarget
- type XpathNode
- func FilterNodeset(ns []XpathNode, key xml.Name, leafValue string) (retNs []XpathNode, debugLog string)
- func FindNode(startNode XpathNode, pathToFind NodeRef) XpathNode
- func RemoveDuplicateNodes(nodes []XpathNode) []XpathNode
- func WalkTree(node XpathNode, workFn worker, index int) (retNode XpathNode, finished bool, retErr error)
Constants ¶
const ( EOF = 0 ERR = 0xF000 + iota NUM FUNC DOTDOT DBLSLASH DBLCOLON GT GE LT LE EQ NE NODETYPE AXISNAME NAMETEST LITERAL OR AND MOD DIV TEXTFUNC CURRENTFUNC DEREFFUNC )
The parser expects the lexer to return 0 on EOF. Give it a name for clarity. Also define 'special' tokens so they won't clash with other token values (ASCII value in most cases). Just to ensure mapping is working correctly, YACC starts off at 0xE000 or thereabouts, so this enum is deliberately starting at a different place to catch bugs where we've forgotten to map and some tokens are ok, some not.
const ( StripPrefix = true DontStripPrefix = false )
Variables ¶
var AllCfgChildren = NewXFilterConfigOnly(xml.Name{Local: "*"})
var AllChildren = NewXFilterFullTree(xml.Name{Local: "*"})
This is the global wildcard, representing all child nodes regardless of module.
Functions ¶
func GetStringValue ¶
If no nodes, return empty string. Otherwise return string-value of first node in nodeset.
Just as a reminder, the string-value for anything other than a leaf node is (a) variable (depends what child nodes are configured) and (b) not unique to a node (imagine a chain of node -> child -> grandchild -> leaf which, in the absence of any defaults, or multiple nodes at any level, would all have the same value).
func GetStringValues ¶
Return a slice of strings containing the string-value for each node in <nodes>. If <addEmptyStr> is true, return a slice with a single empty string instead of an empty slice when <nodes> is empty. This is useful when using the strings with equality or relational operators.
func GetTokenName ¶
func MatchFilter ¶
Return true (match) if filter matches target or filter is AllChildren Note that filter may be '<namespaceName>:*'. Note also that we ignore prefix as this is local to a single namespace, and is converted to a namespace name for global uniqueness *and* global consistency of naming.
The filter may or may not have a prefix - if not then we only match on localPart.
Additionally, if the node we are matching is not a config node, and the filter indicates we can only match config nodes, no match will be made.
func NodeString ¶
Generate a unique string representation of a node, in 'leafref' format, including all key values for list entries, and ending with a leaf or leaf-list value if the node is of those types.
NB: This function is used to determine if 2 nodes are identical, not
just for pretty-printing. If in any doubt that changes may impact performance, try out TestFWPerformance in configd/session directory with a large number of rules and compare old and new times.
NB: This is NOT string-value, which is not unique to a specific node,
and which can vary for a single node depending on what is configured under it!
func NodesEqual ¶
If 2 nodes have the same NodeString then they are identical. Two separate list elements may have the same path, but add in the key values and they differ again.
func NodesetsEqual ¶
func ValidateTree ¶
Takes root node and verifies at each level: - parent is correct - root is correct - children have correct parent - children have unique NodeString - no child is equal to another child - index is as expected
Types ¶
type NodeRef ¶
type NodeRef struct {
// contains filtered or unexported fields
}
NodeRef: These allow Leafref-like objects be constructed and manipulated. These objects are references to nodes and so stop short of containing the actual value of leaf / leaf-list elements.
NB:
(1) Root node is represented by a NodeRef of length 0. (2)All NodeRefs are absolute.
func NewNodeRef ¶
func (*NodeRef) AddElem ¶
func (yp *NodeRef) AddElem(name string, keys []NodeRefKey)
type NodeRefElem ¶
type NodeRefElem struct {
// contains filtered or unexported fields
}
func (NodeRefElem) EqualTo ¶
func (ype1 NodeRefElem) EqualTo(ype2 NodeRefElem) bool
type NodeRefKey ¶
type NodeRefKey struct {
// contains filtered or unexported fields
}
func NewNodeRefKey ¶
func NewNodeRefKey(name, value string) (retKey NodeRefKey)
func (NodeRefKey) EqualTo ¶
func (ypk1 NodeRefKey) EqualTo(ypk2 NodeRefKey) bool
type PathType ¶
type PathType []string
PATHTYPE
Useful to have this for manipulating paths. Provides a comparison function and string function.
func GetAbsPath ¶
func NewPathType ¶
func (PathType) SpacedString ¶
type TargetType ¶
type TargetType int
TargetType - node type of the target to be matched Subtly different to MatchType as here we want to specify the type of our node explicitly whereas for MatchType we want to specify a set of types to be matched.
const ( NotConfigOrOpdTarget TargetType = iota ConfigTarget OpdTarget )
type Warning ¶
type Warning struct {
// contains filtered or unexported fields
}
func NewWarning ¶
func (Warning) GetUniqueString ¶
Uniquely identifies what is being tested, ie module:line source of statement, followed by specific path being tested. Note that testPath can be stripped of its prefix if we are wanting to filter out false positives.
func (Warning) MatchDebugContains ¶
Less strict on debug string matching - look for substring not exact match
type XFilter ¶
type XFilter struct {
// contains filtered or unexported fields
}
func NewXFilterConfigOnly ¶
func NewXFilterFullTree ¶
func (XFilter) MatchConfigOnly ¶
type XTarget ¶
type XTarget struct {
// contains filtered or unexported fields
}
func NewXConfigTarget ¶
func NewXTarget ¶
func NewXTarget(name xml.Name, targetType TargetType) XTarget
type XpathNode ¶
type XpathNode interface { // Return parent node XParent() XpathNode // Return all children, including list keys. // Specify 'Sorted' to get returned nodes in deterministic order. // Xpath uses 'document' order, so for YANG, our system sorts in natural // sorting order, unless ordered-by-user is specified. // 'Unsorted' should be used when order doesn't matter as it is much faster. XChildren(filter XFilter, sortSpec SortSpec) []XpathNode // Should return {"/"} for root node. Returns XPATH-compliant path // where tagnodes and other list elements are treated as siblings. XPath() PathType XRoot() XpathNode // Node name. For list entries, eg interfaces/dataplane entries, all list // entries would share the 'dataplane' name. The 'tagnode' children // would have 'tagnode' as name etc. XName() string // Node value, if a text node (ie leaf / leaf list element). XValue() string // Type check functions to make sure we are operating on the expected // type. XIsLeaf() bool XIsLeafList() bool XIsNonPresCont() bool // Ephemeral nodes are created for the purposes of evaluating must // statements on non-presence, unconfigured, containers. XIsEphemeral() bool // Return true if node is a ListEntry with a key that has the given value. XListKeyMatches(key xml.Name, val string) bool // If node is a list entry, return keys. Otherwise return nil. XListKeys() []NodeRefKey }
To isolate us from node types we may want to work with, we have our own interface. To avoid any namespace collisions with other interfaces, all methods are prefixed with 'X'.
func FilterNodeset ¶
func FilterNodeset( ns []XpathNode, key xml.Name, leafValue string, ) (retNs []XpathNode, debugLog string)
This is the code that actually does the work for leafref predicates. We need to find the nodes (if any) in the nodeset that match the given key/value tuple.
func FindNode ¶
Dumb function that uses brute force to find a node with the given path. Designed for use with leafrefs and tab-completion.
func RemoveDuplicateNodes ¶
Naive implementation is to simply loop through range of nodes and if not already in our return list, add them. However, this quickly multiplies up if we were to have a large number of nodes.
Instead, we create a map with a unique representation of each node, being the NodeString (categorically NOT the string-value which varies for a single node and may be the same across multiple nodes)
NodeString is guaranteed unique for different nodes as it combines both path and (where siblings with the same path exist) value.