selector.go 12 KB

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