Documentation ¶
Overview ¶
allocationfilterutil provides functionality for parsing V2 of the Kubecost filter language for Allocation types.
e.g. "filter=namespace:kubecost+controllerkind:deployment"
Index ¶
- Constants
- func OpStringFor(node FilterNode, traversalState TraversalState, depth int) string
- func PreOrderTraversal(node FilterNode, f func(FilterNode, TraversalState))
- func ShortOpStringFor(node FilterNode, traversalState TraversalState) string
- func ToPreOrderShortString(node FilterNode) string
- func ToPreOrderString(node FilterNode) string
- type AndOp
- type ContainsOp
- type ContainsPrefixOp
- type ContainsSuffixOp
- type ContradictionOp
- type EqualOp
- type Field
- type FieldType
- type FilterGroup
- type FilterNode
- type FilterOp
- type FilterParser
- type Identifier
- type NotOp
- type OrOp
- type TraversalState
- type VoidOp
Examples ¶
Constants ¶
const ( // FilterOpEquals is the equality operator // // "kube-system" FilterOpEquals "kube-system" = true // "kube-syste" FilterOpEquals "kube-system" = false FilterOpEquals FilterOp = "equals" // FilterOpNotEquals is the inverse of equals. FilterOpNotEquals = "notequals" // FilterOpContains supports string fields, slice fields, and map fields. // For maps, this is equivalent to map.HasKey(x) // // "kube-system" FilterOpContains "e-s" = true // ["a", "b", "c"] FilterOpContains "a" = true // { "namespace": "kubecost", "cluster": "cluster-one" } FilterOpContains "namespace" = true FilterOpContains = "contains" // FilterOpNotContains is the inverse of contains. FilterOpNotContains = "notcontains" // FilterOpContainsPrefix is like FilterOpContains, but checks against the start of a string. // For maps, this checks to see if any of the keys start with the prefix // // "kube-system" ContainsPrefix "kube" = true // ["kube-system", "abc123"] ContainsPrefix "kube" = true // { "kube-label": "test", "abc": "123" } ContainsPrefix "ab" = true FilterOpContainsPrefix = "containsprefix" // FilterOpNotContainsPrefix is the inverse of FilterOpContainsPrefix FilterOpNotContainsPrefix = "notcontainsprefix" // FilterOpContainsSuffix is like FilterOpContains, but checks against the end of a string. // For maps, this checks to see if any of the keys end with the suffix // // "kube-system" ContainsSuffix "system" = true // ["kube-system", "abc123"] ContainsSuffix "system" = true // { "kube-label": "test", "abc": "123" } ContainsSuffix "-label" = true FilterOpContainsSuffix = "containssuffix" // FilterOpNotContainsSuffix is the inverse of FilterOpContainsSuffix FilterOpNotContainsSuffix = "notcontainssuffix" // FilterOpVoid is base-depth operator that is used for an empty filter FilterOpVoid = "void" // FilterOpContradiction is a base-depth operator that filters all data. FilterOpContradiction = "contradiction" // FilterOpAnd is an operator that succeeds if all parameters succeed. FilterOpAnd = "and" // FilterOpOr is an operator that succeeds if any parameter succeeds FilterOpOr = "or" // FilterOpNot is an operator that contains a single operand FilterOpNot = "not" )
If you add a FilterOp, MAKE SURE TO UPDATE ALL FILTER IMPLEMENTATIONS! Go does not enforce exhaustive pattern matching on "enum" types.
Variables ¶
This section is empty.
Functions ¶
func OpStringFor ¶
func OpStringFor(node FilterNode, traversalState TraversalState, depth int) string
OpStringFor returns a string for the provided leaf node, traversal state, and current depth.
func PreOrderTraversal ¶
func PreOrderTraversal(node FilterNode, f func(FilterNode, TraversalState))
PreOrderTraversal accepts a root `FilterNode` and calls the f callback on each leaf node it traverses. When entering "group" leaf nodes (leaf nodes which contain other leaf nodes), a TraversalStateEnter/Exit will be includes to denote each depth. In short, the callback will be executed twice for each "group" op, once before entering, and once bofore exiting.
func ShortOpStringFor ¶
func ShortOpStringFor(node FilterNode, traversalState TraversalState) string
ShortOpStringFor returns a condensed string for the provided leaf node, traversal state, and current depth.
func ToPreOrderShortString ¶
func ToPreOrderShortString(node FilterNode) string
ToPreOrderShortString runs a PreOrderTraversal and generates a condensed tree structure string format for the provided tree root.
func ToPreOrderString ¶
func ToPreOrderString(node FilterNode) string
ToPreOrderString runs a PreOrderTraversal and generates an indented tree structure string format for the provided tree root.
Types ¶
type AndOp ¶
type AndOp struct {
Operands []FilterNode
}
AndOp is a filter operation that contains a flat list of nodes which should all resolve to true in order for the result to be true.
func (*AndOp) Add ¶
func (ao *AndOp) Add(node FilterNode)
Add appends a filter node to the flat list of operands within the AND operator
type ContainsOp ¶
type ContainsOp struct { // Left contains a resolvable Identifier (property of an input type) which can be // used to query against using the Right value. Left Identifier // Right contains the value which we use to search the resolved Left identifier with. Right string }
ContainsOp is a filter operation that checks to see if a resolvable identifier (Left) contains a string value (Right)
func (*ContainsOp) Op ¶
func (_ *ContainsOp) Op() FilterOp
Op returns the FilterOp enumeration value for the operator.
type ContainsPrefixOp ¶
type ContainsPrefixOp struct { // Left contains a resolvable Identifier (property of an input type) which can be // used to query against using the Right value. Left Identifier // Right contains the value which we use to search the resolved Left identifier with. Right string }
ContainsPrefixOp is a filter operation that checks to see if a resolvable identifier (Left) starts with a string value (Right)
func (*ContainsPrefixOp) Op ¶
func (_ *ContainsPrefixOp) Op() FilterOp
Op returns the FilterOp enumeration value for the operator.
type ContainsSuffixOp ¶
type ContainsSuffixOp struct { // Left contains a resolvable Identifier (property of an input type) which can be // used to query against using the Right value. Left Identifier // Right contains the value which we use to search the resolved Left identifier with. Right string }
ContainsSuffixOp is a filter operation that checks to see if a resolvable identifier (Left) ends with a string value (Right)
func (*ContainsSuffixOp) Op ¶
func (_ *ContainsSuffixOp) Op() FilterOp
Op returns the FilterOp enumeration value for the operator.
type ContradictionOp ¶
type ContradictionOp struct{}
ContradictionOp is a base-depth operator that filters all data.
func (*ContradictionOp) Op ¶
func (_ *ContradictionOp) Op() FilterOp
Op returns the FilterOp enumeration value for the operator.
type EqualOp ¶
type EqualOp struct { // Left contains a resolvable Identifier (property of an input type) which can be // used to compare against the Right value. Left Identifier // Right contains the value which we wish to compare the resolved identifier to. Right string }
EqualOp is a filter operation that compares a resolvable identifier (Left) to a string value (Right)
type Field ¶
type Field struct { // Name contains the name of the specific field as it appears in language. Name string // contains filtered or unexported fields }
Field is a Lexer input which acts as a mapping of identifiers used to lex/parse filters.
func Fields ¶
func Fields(filter FilterNode) []Field
func NewAliasField ¶
NewAliasField creates a new alias field using the provided name.
func NewMapField ¶
NewMapField creates a new map field using the provided name.
func NewSliceField ¶
NewSliceField creates a slice field using the provided name.
func (*Field) IsAlias ¶
IsAlias returns true if the field is an alias type. This instructs the lexer that the field is an alias for custom logical resolution by an external compiler.
type FieldType ¶
type FieldType int
FieldType is an enumeration of specific types relevant to lexing and parsing a filter.
type FilterGroup ¶
type FilterGroup interface { FilterNode // Adds a new leaf node to the FilterGroup Add(FilterNode) }
FilterGroup is a specialized interface for ops which can collect N operands.
type FilterNode ¶
type FilterNode interface {
Op() FilterOp
}
FilterNode is the the base instance of a tree leaf node, which is a conditional operator which contains operands that may also be leaf nodes. A go type-switch should be used to reduce the FilterNode to a concrete type to operate on. If only the type of operator is required, the `Op()` field can be used.
func Clone ¶
func Clone(filter FilterNode) FilterNode
Clone deep copies and returns the AST parameter.
func TransformLeaves ¶
func TransformLeaves(node FilterNode, transformer func(FilterNode) FilterNode) FilterNode
TransformLeaves produces a new tree, leaving non-leaf nodes (e.g. And, Or) intact and replacing leaf nodes (e.g. Equals, Contains) with the result of calling leafTransformer(node).
Example ¶
originalTree := &AndOp{ Operands: []FilterNode{ &EqualOp{ Left: Identifier{ Field: &Field{ Name: "field1", }, Key: "foo", }, Right: "bar", }, &EqualOp{ Left: Identifier{ Field: &Field{ Name: "field2", }, }, Right: "bar", }, }, } // This transformer applies "Not" to all leaves transformFunc := func(node FilterNode) FilterNode { switch concrete := node.(type) { case *AndOp, *OrOp, *NotOp: panic("Leaf transformer should not be called on non-leaf nodes") default: return &NotOp{Operand: concrete} } } newTree := TransformLeaves(originalTree, transformFunc) fmt.Println(ToPreOrderString(newTree))
Output: And { Not { Equals { Left: field1[foo], Right: bar } } Not { Equals { Left: field2, Right: bar } } }
type FilterOp ¶
type FilterOp string
FilterOp is an enum that represents operations that can be performed when filtering (equality, inequality, etc.)
type FilterParser ¶
type FilterParser interface { // Parse parses a filter string into a FilterNode AST. Parse(filter string) (FilterNode, error) }
FilterParser is an object capable of parsing a filter string into a `FilterNode` AST
func NewFilterParser ¶
func NewFilterParser(fields []*Field) FilterParser
NewFilterParser creates a new `FilterParser` instance with the provided `Field` definitions to use when lexing and parsing.
type Identifier ¶
Identifier is a struct that contains the data required to resolve a specific operand to a concrete value during operator compilation.
func (*Identifier) Equal ¶
func (id *Identifier) Equal(ident Identifier) bool
Equal returns true if the identifiers are equal
func (*Identifier) String ¶
func (id *Identifier) String() string
String returns the string representation for the Identifier
type NotOp ¶
type NotOp struct {
Operand FilterNode
}
NotOp is a filter operation that logically inverts result of the child operand.
type OrOp ¶
type OrOp struct {
Operands []FilterNode
}
OrOp is a filter operation that contains a flat list of nodes which at least one node should resolve to true in order for the result to be true.
func (*OrOp) Add ¶
func (oo *OrOp) Add(node FilterNode)
Add appends a filter node to the flat list of operands within the OR operator
type TraversalState ¶
type TraversalState int
TraversalState represents the state of the current leaf node in a traversal of the filter Any grouping ops will include an Enter on their first occurence, and an Exit when leaving the op state.
const ( // TraversalStateNone is used whenever a binary op leaf node is traversed. TraversalStateNone TraversalState = iota // TraversalStateEnter is used when a group op leaf node is traversed (and, or, not) TraversalStateEnter // TraversalStateExit is used wwhen a group op leaf node is popped (and, or, not). TraversalStateExit )