selector.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. /*
  2. Copyright 2015 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package fields
  14. import (
  15. "bytes"
  16. "fmt"
  17. "sort"
  18. "strings"
  19. "k8s.io/apimachinery/pkg/selection"
  20. )
  21. // Selector represents a field selector.
  22. type Selector interface {
  23. // Matches returns true if this selector matches the given set of fields.
  24. Matches(Fields) bool
  25. // Empty returns true if this selector does not restrict the selection space.
  26. Empty() bool
  27. // RequiresExactMatch allows a caller to introspect whether a given selector
  28. // requires a single specific field to be set, and if so returns the value it
  29. // requires.
  30. RequiresExactMatch(field string) (value string, found bool)
  31. // Transform returns a new copy of the selector after TransformFunc has been
  32. // applied to the entire selector, or an error if fn returns an error.
  33. // If for a given requirement both field and value are transformed to empty
  34. // string, the requirement is skipped.
  35. Transform(fn TransformFunc) (Selector, error)
  36. // Requirements converts this interface to Requirements to expose
  37. // more detailed selection information.
  38. Requirements() Requirements
  39. // String returns a human readable string that represents this selector.
  40. String() string
  41. // Make a deep copy of the selector.
  42. DeepCopySelector() Selector
  43. }
  44. type nothingSelector struct{}
  45. func (n nothingSelector) Matches(_ Fields) bool { return false }
  46. func (n nothingSelector) Empty() bool { return false }
  47. func (n nothingSelector) String() string { return "" }
  48. func (n nothingSelector) Requirements() Requirements { return nil }
  49. func (n nothingSelector) DeepCopySelector() Selector { return n }
  50. func (n nothingSelector) RequiresExactMatch(field string) (value string, found bool) { return "", false }
  51. func (n nothingSelector) Transform(fn TransformFunc) (Selector, error) { return n, nil }
  52. // Nothing returns a selector that matches no fields
  53. func Nothing() Selector {
  54. return nothingSelector{}
  55. }
  56. // Everything returns a selector that matches all fields.
  57. func Everything() Selector {
  58. return andTerm{}
  59. }
  60. type hasTerm struct {
  61. field, value string
  62. }
  63. func (t *hasTerm) Matches(ls Fields) bool {
  64. return ls.Get(t.field) == t.value
  65. }
  66. func (t *hasTerm) Empty() bool {
  67. return false
  68. }
  69. func (t *hasTerm) RequiresExactMatch(field string) (value string, found bool) {
  70. if t.field == field {
  71. return t.value, true
  72. }
  73. return "", false
  74. }
  75. func (t *hasTerm) Transform(fn TransformFunc) (Selector, error) {
  76. field, value, err := fn(t.field, t.value)
  77. if err != nil {
  78. return nil, err
  79. }
  80. if len(field) == 0 && len(value) == 0 {
  81. return Everything(), nil
  82. }
  83. return &hasTerm{field, value}, nil
  84. }
  85. func (t *hasTerm) Requirements() Requirements {
  86. return []Requirement{{
  87. Field: t.field,
  88. Operator: selection.Equals,
  89. Value: t.value,
  90. }}
  91. }
  92. func (t *hasTerm) String() string {
  93. return fmt.Sprintf("%v=%v", t.field, EscapeValue(t.value))
  94. }
  95. func (t *hasTerm) DeepCopySelector() Selector {
  96. if t == nil {
  97. return nil
  98. }
  99. out := new(hasTerm)
  100. *out = *t
  101. return out
  102. }
  103. type notHasTerm struct {
  104. field, value string
  105. }
  106. func (t *notHasTerm) Matches(ls Fields) bool {
  107. return ls.Get(t.field) != t.value
  108. }
  109. func (t *notHasTerm) Empty() bool {
  110. return false
  111. }
  112. func (t *notHasTerm) RequiresExactMatch(field string) (value string, found bool) {
  113. return "", false
  114. }
  115. func (t *notHasTerm) Transform(fn TransformFunc) (Selector, error) {
  116. field, value, err := fn(t.field, t.value)
  117. if err != nil {
  118. return nil, err
  119. }
  120. if len(field) == 0 && len(value) == 0 {
  121. return Everything(), nil
  122. }
  123. return &notHasTerm{field, value}, nil
  124. }
  125. func (t *notHasTerm) Requirements() Requirements {
  126. return []Requirement{{
  127. Field: t.field,
  128. Operator: selection.NotEquals,
  129. Value: t.value,
  130. }}
  131. }
  132. func (t *notHasTerm) String() string {
  133. return fmt.Sprintf("%v!=%v", t.field, EscapeValue(t.value))
  134. }
  135. func (t *notHasTerm) DeepCopySelector() Selector {
  136. if t == nil {
  137. return nil
  138. }
  139. out := new(notHasTerm)
  140. *out = *t
  141. return out
  142. }
  143. type andTerm []Selector
  144. func (t andTerm) Matches(ls Fields) bool {
  145. for _, q := range t {
  146. if !q.Matches(ls) {
  147. return false
  148. }
  149. }
  150. return true
  151. }
  152. func (t andTerm) Empty() bool {
  153. if t == nil {
  154. return true
  155. }
  156. if len([]Selector(t)) == 0 {
  157. return true
  158. }
  159. for i := range t {
  160. if !t[i].Empty() {
  161. return false
  162. }
  163. }
  164. return true
  165. }
  166. func (t andTerm) RequiresExactMatch(field string) (string, bool) {
  167. if t == nil || len([]Selector(t)) == 0 {
  168. return "", false
  169. }
  170. for i := range t {
  171. if value, found := t[i].RequiresExactMatch(field); found {
  172. return value, found
  173. }
  174. }
  175. return "", false
  176. }
  177. func (t andTerm) Transform(fn TransformFunc) (Selector, error) {
  178. next := make([]Selector, 0, len([]Selector(t)))
  179. for _, s := range []Selector(t) {
  180. n, err := s.Transform(fn)
  181. if err != nil {
  182. return nil, err
  183. }
  184. if !n.Empty() {
  185. next = append(next, n)
  186. }
  187. }
  188. return andTerm(next), nil
  189. }
  190. func (t andTerm) Requirements() Requirements {
  191. reqs := make([]Requirement, 0, len(t))
  192. for _, s := range []Selector(t) {
  193. rs := s.Requirements()
  194. reqs = append(reqs, rs...)
  195. }
  196. return reqs
  197. }
  198. func (t andTerm) String() string {
  199. var terms []string
  200. for _, q := range t {
  201. terms = append(terms, q.String())
  202. }
  203. return strings.Join(terms, ",")
  204. }
  205. func (t andTerm) DeepCopySelector() Selector {
  206. if t == nil {
  207. return nil
  208. }
  209. out := make([]Selector, len(t))
  210. for i := range t {
  211. out[i] = t[i].DeepCopySelector()
  212. }
  213. return andTerm(out)
  214. }
  215. // SelectorFromSet returns a Selector which will match exactly the given Set. A
  216. // nil Set is considered equivalent to Everything().
  217. func SelectorFromSet(ls Set) Selector {
  218. if ls == nil {
  219. return Everything()
  220. }
  221. items := make([]Selector, 0, len(ls))
  222. for field, value := range ls {
  223. items = append(items, &hasTerm{field: field, value: value})
  224. }
  225. if len(items) == 1 {
  226. return items[0]
  227. }
  228. return andTerm(items)
  229. }
  230. // valueEscaper prefixes \,= characters with a backslash
  231. var valueEscaper = strings.NewReplacer(
  232. // escape \ characters
  233. `\`, `\\`,
  234. // then escape , and = characters to allow unambiguous parsing of the value in a fieldSelector
  235. `,`, `\,`,
  236. `=`, `\=`,
  237. )
  238. // EscapeValue escapes an arbitrary literal string for use as a fieldSelector value
  239. func EscapeValue(s string) string {
  240. return valueEscaper.Replace(s)
  241. }
  242. // InvalidEscapeSequence indicates an error occurred unescaping a field selector
  243. type InvalidEscapeSequence struct {
  244. sequence string
  245. }
  246. func (i InvalidEscapeSequence) Error() string {
  247. return fmt.Sprintf("invalid field selector: invalid escape sequence: %s", i.sequence)
  248. }
  249. // UnescapedRune indicates an error occurred unescaping a field selector
  250. type UnescapedRune struct {
  251. r rune
  252. }
  253. func (i UnescapedRune) Error() string {
  254. return fmt.Sprintf("invalid field selector: unescaped character in value: %v", i.r)
  255. }
  256. // UnescapeValue unescapes a fieldSelector value and returns the original literal value.
  257. // May return the original string if it contains no escaped or special characters.
  258. func UnescapeValue(s string) (string, error) {
  259. // if there's no escaping or special characters, just return to avoid allocation
  260. if !strings.ContainsAny(s, `\,=`) {
  261. return s, nil
  262. }
  263. v := bytes.NewBuffer(make([]byte, 0, len(s)))
  264. inSlash := false
  265. for _, c := range s {
  266. if inSlash {
  267. switch c {
  268. case '\\', ',', '=':
  269. // omit the \ for recognized escape sequences
  270. v.WriteRune(c)
  271. default:
  272. // error on unrecognized escape sequences
  273. return "", InvalidEscapeSequence{sequence: string([]rune{'\\', c})}
  274. }
  275. inSlash = false
  276. continue
  277. }
  278. switch c {
  279. case '\\':
  280. inSlash = true
  281. case ',', '=':
  282. // unescaped , and = characters are not allowed in field selector values
  283. return "", UnescapedRune{r: c}
  284. default:
  285. v.WriteRune(c)
  286. }
  287. }
  288. // Ending with a single backslash is an invalid sequence
  289. if inSlash {
  290. return "", InvalidEscapeSequence{sequence: "\\"}
  291. }
  292. return v.String(), nil
  293. }
  294. // ParseSelectorOrDie takes a string representing a selector and returns an
  295. // object suitable for matching, or panic when an error occur.
  296. func ParseSelectorOrDie(s string) Selector {
  297. selector, err := ParseSelector(s)
  298. if err != nil {
  299. panic(err)
  300. }
  301. return selector
  302. }
  303. // ParseSelector takes a string representing a selector and returns an
  304. // object suitable for matching, or an error.
  305. func ParseSelector(selector string) (Selector, error) {
  306. return parseSelector(selector,
  307. func(lhs, rhs string) (newLhs, newRhs string, err error) {
  308. return lhs, rhs, nil
  309. })
  310. }
  311. // ParseAndTransformSelector parses the selector and runs them through the given TransformFunc.
  312. func ParseAndTransformSelector(selector string, fn TransformFunc) (Selector, error) {
  313. return parseSelector(selector, fn)
  314. }
  315. // TransformFunc transforms selectors.
  316. type TransformFunc func(field, value string) (newField, newValue string, err error)
  317. // splitTerms returns the comma-separated terms contained in the given fieldSelector.
  318. // Backslash-escaped commas are treated as data instead of delimiters, and are included in the returned terms, with the leading backslash preserved.
  319. func splitTerms(fieldSelector string) []string {
  320. if len(fieldSelector) == 0 {
  321. return nil
  322. }
  323. terms := make([]string, 0, 1)
  324. startIndex := 0
  325. inSlash := false
  326. for i, c := range fieldSelector {
  327. switch {
  328. case inSlash:
  329. inSlash = false
  330. case c == '\\':
  331. inSlash = true
  332. case c == ',':
  333. terms = append(terms, fieldSelector[startIndex:i])
  334. startIndex = i + 1
  335. }
  336. }
  337. terms = append(terms, fieldSelector[startIndex:])
  338. return terms
  339. }
  340. const (
  341. notEqualOperator = "!="
  342. doubleEqualOperator = "=="
  343. equalOperator = "="
  344. )
  345. // termOperators holds the recognized operators supported in fieldSelectors.
  346. // doubleEqualOperator and equal are equivalent, but doubleEqualOperator is checked first
  347. // to avoid leaving a leading = character on the rhs value.
  348. var termOperators = []string{notEqualOperator, doubleEqualOperator, equalOperator}
  349. // splitTerm returns the lhs, operator, and rhs parsed from the given term, along with an indicator of whether the parse was successful.
  350. // no escaping of special characters is supported in the lhs value, so the first occurrence of a recognized operator is used as the split point.
  351. // the literal rhs is returned, and the caller is responsible for applying any desired unescaping.
  352. func splitTerm(term string) (lhs, op, rhs string, ok bool) {
  353. for i := range term {
  354. remaining := term[i:]
  355. for _, op := range termOperators {
  356. if strings.HasPrefix(remaining, op) {
  357. return term[0:i], op, term[i+len(op):], true
  358. }
  359. }
  360. }
  361. return "", "", "", false
  362. }
  363. func parseSelector(selector string, fn TransformFunc) (Selector, error) {
  364. parts := splitTerms(selector)
  365. sort.StringSlice(parts).Sort()
  366. var items []Selector
  367. for _, part := range parts {
  368. if part == "" {
  369. continue
  370. }
  371. lhs, op, rhs, ok := splitTerm(part)
  372. if !ok {
  373. return nil, fmt.Errorf("invalid selector: '%s'; can't understand '%s'", selector, part)
  374. }
  375. unescapedRHS, err := UnescapeValue(rhs)
  376. if err != nil {
  377. return nil, err
  378. }
  379. switch op {
  380. case notEqualOperator:
  381. items = append(items, &notHasTerm{field: lhs, value: unescapedRHS})
  382. case doubleEqualOperator:
  383. items = append(items, &hasTerm{field: lhs, value: unescapedRHS})
  384. case equalOperator:
  385. items = append(items, &hasTerm{field: lhs, value: unescapedRHS})
  386. default:
  387. return nil, fmt.Errorf("invalid selector: '%s'; can't understand '%s'", selector, part)
  388. }
  389. }
  390. if len(items) == 1 {
  391. return items[0].Transform(fn)
  392. }
  393. return andTerm(items).Transform(fn)
  394. }
  395. // OneTermEqualSelector returns an object that matches objects where one field/field equals one value.
  396. // Cannot return an error.
  397. func OneTermEqualSelector(k, v string) Selector {
  398. return &hasTerm{field: k, value: v}
  399. }
  400. // OneTermNotEqualSelector returns an object that matches objects where one field/field does not equal one value.
  401. // Cannot return an error.
  402. func OneTermNotEqualSelector(k, v string) Selector {
  403. return &notHasTerm{field: k, value: v}
  404. }
  405. // AndSelectors creates a selector that is the logical AND of all the given selectors
  406. func AndSelectors(selectors ...Selector) Selector {
  407. return andTerm(selectors)
  408. }