selector.go 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  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. "fmt"
  16. "sort"
  17. "strings"
  18. "k8s.io/kubernetes/pkg/selection"
  19. )
  20. // Selector represents a field selector.
  21. type Selector interface {
  22. // Matches returns true if this selector matches the given set of fields.
  23. Matches(Fields) bool
  24. // Empty returns true if this selector does not restrict the selection space.
  25. Empty() bool
  26. // RequiresExactMatch allows a caller to introspect whether a given selector
  27. // requires a single specific field to be set, and if so returns the value it
  28. // requires.
  29. RequiresExactMatch(field string) (value string, found bool)
  30. // Transform returns a new copy of the selector after TransformFunc has been
  31. // applied to the entire selector, or an error if fn returns an error.
  32. Transform(fn TransformFunc) (Selector, error)
  33. // Requirements converts this interface to Requirements to expose
  34. // more detailed selection information.
  35. Requirements() Requirements
  36. // String returns a human readable string that represents this selector.
  37. String() string
  38. }
  39. // Everything returns a selector that matches all fields.
  40. func Everything() Selector {
  41. return andTerm{}
  42. }
  43. type hasTerm struct {
  44. field, value string
  45. }
  46. func (t *hasTerm) Matches(ls Fields) bool {
  47. return ls.Get(t.field) == t.value
  48. }
  49. func (t *hasTerm) Empty() bool {
  50. return false
  51. }
  52. func (t *hasTerm) RequiresExactMatch(field string) (value string, found bool) {
  53. if t.field == field {
  54. return t.value, true
  55. }
  56. return "", false
  57. }
  58. func (t *hasTerm) Transform(fn TransformFunc) (Selector, error) {
  59. field, value, err := fn(t.field, t.value)
  60. if err != nil {
  61. return nil, err
  62. }
  63. return &hasTerm{field, value}, nil
  64. }
  65. func (t *hasTerm) Requirements() Requirements {
  66. return []Requirement{{
  67. Field: t.field,
  68. Operator: selection.Equals,
  69. Value: t.value,
  70. }}
  71. }
  72. func (t *hasTerm) String() string {
  73. return fmt.Sprintf("%v=%v", t.field, t.value)
  74. }
  75. type notHasTerm struct {
  76. field, value string
  77. }
  78. func (t *notHasTerm) Matches(ls Fields) bool {
  79. return ls.Get(t.field) != t.value
  80. }
  81. func (t *notHasTerm) Empty() bool {
  82. return false
  83. }
  84. func (t *notHasTerm) RequiresExactMatch(field string) (value string, found bool) {
  85. return "", false
  86. }
  87. func (t *notHasTerm) Transform(fn TransformFunc) (Selector, error) {
  88. field, value, err := fn(t.field, t.value)
  89. if err != nil {
  90. return nil, err
  91. }
  92. return &notHasTerm{field, value}, nil
  93. }
  94. func (t *notHasTerm) Requirements() Requirements {
  95. return []Requirement{{
  96. Field: t.field,
  97. Operator: selection.NotEquals,
  98. Value: t.value,
  99. }}
  100. }
  101. func (t *notHasTerm) String() string {
  102. return fmt.Sprintf("%v!=%v", t.field, t.value)
  103. }
  104. type andTerm []Selector
  105. func (t andTerm) Matches(ls Fields) bool {
  106. for _, q := range t {
  107. if !q.Matches(ls) {
  108. return false
  109. }
  110. }
  111. return true
  112. }
  113. func (t andTerm) Empty() bool {
  114. if t == nil {
  115. return true
  116. }
  117. if len([]Selector(t)) == 0 {
  118. return true
  119. }
  120. for i := range t {
  121. if !t[i].Empty() {
  122. return false
  123. }
  124. }
  125. return true
  126. }
  127. func (t andTerm) RequiresExactMatch(field string) (string, bool) {
  128. if t == nil || len([]Selector(t)) == 0 {
  129. return "", false
  130. }
  131. for i := range t {
  132. if value, found := t[i].RequiresExactMatch(field); found {
  133. return value, found
  134. }
  135. }
  136. return "", false
  137. }
  138. func (t andTerm) Transform(fn TransformFunc) (Selector, error) {
  139. next := make([]Selector, len([]Selector(t)))
  140. for i, s := range []Selector(t) {
  141. n, err := s.Transform(fn)
  142. if err != nil {
  143. return nil, err
  144. }
  145. next[i] = n
  146. }
  147. return andTerm(next), nil
  148. }
  149. func (t andTerm) Requirements() Requirements {
  150. reqs := make([]Requirement, 0, len(t))
  151. for _, s := range []Selector(t) {
  152. rs := s.Requirements()
  153. reqs = append(reqs, rs...)
  154. }
  155. return reqs
  156. }
  157. func (t andTerm) String() string {
  158. var terms []string
  159. for _, q := range t {
  160. terms = append(terms, q.String())
  161. }
  162. return strings.Join(terms, ",")
  163. }
  164. // SelectorFromSet returns a Selector which will match exactly the given Set. A
  165. // nil Set is considered equivalent to Everything().
  166. func SelectorFromSet(ls Set) Selector {
  167. if ls == nil {
  168. return Everything()
  169. }
  170. items := make([]Selector, 0, len(ls))
  171. for field, value := range ls {
  172. items = append(items, &hasTerm{field: field, value: value})
  173. }
  174. if len(items) == 1 {
  175. return items[0]
  176. }
  177. return andTerm(items)
  178. }
  179. // ParseSelectorOrDie takes a string representing a selector and returns an
  180. // object suitable for matching, or panic when an error occur.
  181. func ParseSelectorOrDie(s string) Selector {
  182. selector, err := ParseSelector(s)
  183. if err != nil {
  184. panic(err)
  185. }
  186. return selector
  187. }
  188. // ParseSelector takes a string representing a selector and returns an
  189. // object suitable for matching, or an error.
  190. func ParseSelector(selector string) (Selector, error) {
  191. return parseSelector(selector,
  192. func(lhs, rhs string) (newLhs, newRhs string, err error) {
  193. return lhs, rhs, nil
  194. })
  195. }
  196. // Parses the selector and runs them through the given TransformFunc.
  197. func ParseAndTransformSelector(selector string, fn TransformFunc) (Selector, error) {
  198. return parseSelector(selector, fn)
  199. }
  200. // Function to transform selectors.
  201. type TransformFunc func(field, value string) (newField, newValue string, err error)
  202. func try(selectorPiece, op string) (lhs, rhs string, ok bool) {
  203. pieces := strings.Split(selectorPiece, op)
  204. if len(pieces) == 2 {
  205. return pieces[0], pieces[1], true
  206. }
  207. return "", "", false
  208. }
  209. func parseSelector(selector string, fn TransformFunc) (Selector, error) {
  210. parts := strings.Split(selector, ",")
  211. sort.StringSlice(parts).Sort()
  212. var items []Selector
  213. for _, part := range parts {
  214. if part == "" {
  215. continue
  216. }
  217. if lhs, rhs, ok := try(part, "!="); ok {
  218. items = append(items, &notHasTerm{field: lhs, value: rhs})
  219. } else if lhs, rhs, ok := try(part, "=="); ok {
  220. items = append(items, &hasTerm{field: lhs, value: rhs})
  221. } else if lhs, rhs, ok := try(part, "="); ok {
  222. items = append(items, &hasTerm{field: lhs, value: rhs})
  223. } else {
  224. return nil, fmt.Errorf("invalid selector: '%s'; can't understand '%s'", selector, part)
  225. }
  226. }
  227. if len(items) == 1 {
  228. return items[0].Transform(fn)
  229. }
  230. return andTerm(items).Transform(fn)
  231. }
  232. // OneTermEqualSelector returns an object that matches objects where one field/field equals one value.
  233. // Cannot return an error.
  234. func OneTermEqualSelector(k, v string) Selector {
  235. return &hasTerm{field: k, value: v}
  236. }