selector

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 5, 2018 License: MIT Imports: 5 Imported by: 6

README

selector

selector is a library that matches as closely as possible the intent and semantics of kubernetes selectors.

It supports unicode in names (such as 함=수), but does not support escaped symbols (such as k=\,).

Goals / Purpose

The goals of this library are to match (enforced through cross reference testing) the k8s.io label selector functionality.

The reason we wrote this library was to have portable / encapsulated library for processing selectors. We also wanted to tune how the selectors are parsed to help with some high throughput scenarios. It's also helpful to have a stable version of the parser we can reference in longer lived projects.

For your team's use; when in doubt, just use the canonical parser found in apimachinery, unless you have performance concerns.

BNF

  <selector-syntax>         ::= <requirement> | <requirement> "," <selector-syntax>
  <requirement>             ::= [!] KEY [ <set-based-restriction> | <exact-match-restriction> ]
  <set-based-restriction>   ::= "" | <inclusion-exclusion> <value-set>
  <inclusion-exclusion>     ::= <inclusion> | <exclusion>
  <exclusion>               ::= "notin"
  <inclusion>               ::= "in"
  <value-set>               ::= "(" <values> ")"
  <values>                  ::= VALUE | VALUE "," <values>
  <exact-match-restriction> ::= ["="|"=="|"!="] VALUE

Usage

Fetch the package as normal:

> go get -u github.com/blend/go-sdk/selector

Include in your project:

import selector "github.com/blend/go-sdk/selector"

Example

Given a label collection:

valid := selector.Labels{
  "zoo":   "mar",
  "moo":   "lar",
  "thing": "map",
}

We can then compile a selector:

selector, _ := selector.Parse("zoo in (mar,lar,dar),moo,thing == map,!thingy")
fmt.Println(selector.Matches(valid)) //prints `true`

Performance (compared to k8s.io/apimachinery/pkg/labels/selector.go)

For most workloads go-selector is about 2x faster to compile and run versus the canonical kubernetes implementation.

This is achieved primarily by escewing regular expressions and replacing them with state machine processing where possible.

An example benchmark can be found in bench/main.go.

Documentation

Overview

Package selector is a high performance selector parsing library, tightly coupled to the functionality of selectors found in Kubernetes.

Index

Constants

View Source
const (
	// OpEquals is an operator.
	OpEquals = "="
	// OpDoubleEquals is an operator.
	OpDoubleEquals = "=="
	// OpNotEquals is an operator.
	OpNotEquals = "!="
	// OpIn is an operator.
	OpIn = "in"
	// OpNotIn is an operator.
	OpNotIn = "notin"
)
View Source
const (
	// At is a common rune.
	At = rune('@')
	// Colon is a common rune.
	Colon = rune(':')
	// Dash is a common rune.
	Dash = rune('-')
	// Underscore  is a common rune.
	Underscore = rune('_')
	// Dot is a common rune.
	Dot = rune('.')
	// ForwardSlash is a common rune.
	ForwardSlash = rune('/')
	// BackSlash is a common rune.
	BackSlash = rune('\\')
	// BackTick is a common rune.
	BackTick = rune('`')
	// Bang is a common rune.
	Bang = rune('!')
	// Comma is a common rune.
	Comma = rune(',')
	// OpenBracket is a common rune.
	OpenBracket = rune('[')
	// OpenParens is a common rune.
	OpenParens = rune('(')
	// OpenCurly is a common rune.
	OpenCurly = rune('{')
	// CloseBracket is a common rune.
	CloseBracket = rune(']')
	// CloseParens is a common rune.
	CloseParens = rune(')')
	// Equal is a common rune.
	Equal = rune('=')
	// Space is a common rune.
	Space = rune(' ')
	// Tab is a common rune.
	Tab = rune('\t')
	// Tilde is a common rune.
	Tilde = rune('~')
	// CarriageReturn is a common rune.
	CarriageReturn = rune('\r')
	// NewLine is a common rune.
	NewLine = rune('\n')
)
View Source
const (
	// ErrInvalidOperator is returned if the operator is invalid.
	ErrInvalidOperator = Error("invalid operator")

	// ErrInvalidSelector is returned if there is a structural issue with the selector.
	ErrInvalidSelector = Error("invalid selector")

	// ErrKeyEmpty indicates a key is empty.
	ErrKeyEmpty = Error("key empty")

	// ErrKeyTooLong indicates a key is too long.
	ErrKeyTooLong = Error("key too long")

	// ErrKeyDNSPrefixEmpty indicates a key's "dns" prefix is empty.
	ErrKeyDNSPrefixEmpty = Error("key dns prefix empty")

	// ErrKeyDNSPrefixTooLong indicates a key's "dns" prefix is empty.
	ErrKeyDNSPrefixTooLong = Error("key dns prefix too long; must be less than 253 characters")

	// ErrValueTooLong indicates a value is too long.
	ErrValueTooLong = Error("value too long; must be less than 63 characters")

	// ErrKeyInvalidCharacter indicates a key contains characters
	ErrKeyInvalidCharacter = Error(`key contains invalid characters, regex used: ([A-Za-z0-9_-\.])`)

	// MaxDNSPrefixLen is the maximum dns prefix length.
	MaxDNSPrefixLen = 253
	// MaxKeyLen is the maximum key length.
	MaxKeyLen = 63
	// MaxValueLen is the maximum value length.
	MaxValueLen = 63
)

Variables

View Source
var (
	// MaxKeyTotalLen is the maximum total key length.
	MaxKeyTotalLen = MaxDNSPrefixLen + MaxKeyLen + 1
)

Functions

func CheckKey

func CheckKey(key string) (err error)

CheckKey validates a key.

func CheckLabels

func CheckLabels(labels Labels) (err error)

CheckLabels validates all the keys and values for the label set.

func CheckValue

func CheckValue(value string) error

CheckValue returns if the value is valid.

func SkipValidation

func SkipValidation(p *Parser)

SkipValidation is an option to skip checking the values of selector expressions.

Types

type And

type And []Selector

And is a combination selector.

func (And) Matches

func (a And) Matches(labels Labels) bool

Matches returns if both A and B match the labels.

func (And) String

func (a And) String() string

And returns a string representation for the selector.

func (And) Validate

func (a And) Validate() (err error)

Validate validates all the selectors in the clause.

type Any

type Any struct{}

Any matches everything

func (Any) Matches

func (a Any) Matches(labels Labels) bool

Matches returns true

func (Any) String

func (a Any) String() string

String returns a string representation of the selector

func (Any) Validate

func (a Any) Validate() (err error)

Validate validates the selector

type Equals

type Equals struct {
	Key, Value string
}

Equals returns if a key strictly equals a value.

func (Equals) Matches

func (e Equals) Matches(labels Labels) bool

Matches returns the selector result.

func (Equals) String

func (e Equals) String() string

String returns the string representation of the selector.

func (Equals) Validate

func (e Equals) Validate() (err error)

Validate validates the selector.

type Error

type Error string

Error is a hard alias to string.

func (Error) Error

func (e Error) Error() string

Error implements `error`

func (Error) MarshalJSON

func (e Error) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler.

type HasKey

type HasKey string

HasKey returns if a label set has a given key.

func (HasKey) Matches

func (hk HasKey) Matches(labels Labels) bool

Matches returns the selector result.

func (HasKey) String

func (hk HasKey) String() string

String returns a string representation of the selector.

func (HasKey) Validate

func (hk HasKey) Validate() (err error)

Validate validates the selector.

type In

type In struct {
	Key    string
	Values []string
}

In returns if a key matches a set of values.

func (In) Matches

func (i In) Matches(labels Labels) bool

Matches returns the selector result.

func (In) String

func (i In) String() string

String returns a string representation of the selector.

func (In) Validate

func (i In) Validate() (err error)

Validate validates the selector.

type Labels

type Labels = map[string]string

Labels is an alias for map[string]string

type NotEquals

type NotEquals struct {
	Key, Value string
}

NotEquals returns if a key strictly equals a value.

func (NotEquals) Matches

func (ne NotEquals) Matches(labels Labels) bool

Matches returns the selector result.

func (NotEquals) String

func (ne NotEquals) String() string

String returns a string representation of the selector.

func (NotEquals) Validate

func (ne NotEquals) Validate() (err error)

Validate validates the selector.

type NotHasKey

type NotHasKey string

NotHasKey returns if a label set does not have a given key.

func (NotHasKey) Matches

func (nhk NotHasKey) Matches(labels Labels) bool

Matches returns the selector result.

func (NotHasKey) String

func (nhk NotHasKey) String() string

String returns a string representation of the selector.

func (NotHasKey) Validate

func (nhk NotHasKey) Validate() (err error)

Validate validates the selector.

type NotIn

type NotIn struct {
	Key    string
	Values []string
}

NotIn returns if a key does not match a set of values.

func (NotIn) Matches

func (ni NotIn) Matches(labels Labels) bool

Matches returns the selector result.

func (NotIn) String

func (ni NotIn) String() string

String returns a string representation of the selector.

func (NotIn) Validate

func (ni NotIn) Validate() (err error)

Validate validates the selector.

type Option

type Option func(p *Parser)

Option is a tweak to selector parsing.

type Parser

type Parser struct {
	// contains filtered or unexported fields
}

Parser parses a selector incrementally.

func (*Parser) Parse

func (p *Parser) Parse() (Selector, error)

Parse does the actual parsing.

type Selector

type Selector interface {
	Matches(labels Labels) bool
	Validate() error
	String() string
}

Selector is the common interface for selector types.

func MustParse

func MustParse(query string, opts ...Option) Selector

MustParse parses the selector but will panic if there is an issue.

func Parse

func Parse(query string, opts ...Option) (Selector, error)

Parse takes a string representing a selector and returns a selector object, or an error. The input will cause an error if it does not follow this form:

<selector-syntax>         ::= <requirement> | <requirement> "," <selector-syntax>
<requirement>             ::= [!] KEY [ <set-based-restriction> | <exact-match-restriction> ]
<set-based-restriction>   ::= "" | <inclusion-exclusion> <value-set>
<inclusion-exclusion>     ::= <inclusion> | <exclusion>
<exclusion>               ::= "notin"
<inclusion>               ::= "in"
<value-set>               ::= "(" <values> ")"
<values>                  ::= VALUE | VALUE "," <values>
<exact-match-restriction> ::= ["="|"=="|"!="] VALUE

KEY is a sequence of one or more characters following [ DNS_SUBDOMAIN "/" ] DNS_LABEL. Max length is 63 characters. VALUE is a sequence of zero or more characters "([A-Za-z0-9_-\.])". Max length is 63 characters. Delimiter is white space: (' ', '\t') Example of valid syntax:

"x in (foo,,baz),y,z notin ()"

Note:

(1) Inclusion - " in " - denotes that the KEY exists and is equal to any of the
    VALUEs in its requirement
(2) Exclusion - " notin " - denotes that the KEY is not equal to any
    of the VALUEs in its requirement or does not exist
(3) The empty string is a valid VALUE
(4) A requirement with just a KEY - as in "y" above - denotes that
    the KEY exists and can be any VALUE.
(5) A requirement with just !KEY requires that the KEY not exist.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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