helpers.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. Copyright 2016 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 unversioned
  14. import (
  15. "fmt"
  16. "k8s.io/kubernetes/pkg/labels"
  17. "k8s.io/kubernetes/pkg/selection"
  18. "k8s.io/kubernetes/pkg/util/sets"
  19. )
  20. // LabelSelectorAsSelector converts the LabelSelector api type into a struct that implements
  21. // labels.Selector
  22. // Note: This function should be kept in sync with the selector methods in pkg/labels/selector.go
  23. func LabelSelectorAsSelector(ps *LabelSelector) (labels.Selector, error) {
  24. if ps == nil {
  25. return labels.Nothing(), nil
  26. }
  27. if len(ps.MatchLabels)+len(ps.MatchExpressions) == 0 {
  28. return labels.Everything(), nil
  29. }
  30. selector := labels.NewSelector()
  31. for k, v := range ps.MatchLabels {
  32. r, err := labels.NewRequirement(k, selection.Equals, sets.NewString(v))
  33. if err != nil {
  34. return nil, err
  35. }
  36. selector = selector.Add(*r)
  37. }
  38. for _, expr := range ps.MatchExpressions {
  39. var op selection.Operator
  40. switch expr.Operator {
  41. case LabelSelectorOpIn:
  42. op = selection.In
  43. case LabelSelectorOpNotIn:
  44. op = selection.NotIn
  45. case LabelSelectorOpExists:
  46. op = selection.Exists
  47. case LabelSelectorOpDoesNotExist:
  48. op = selection.DoesNotExist
  49. default:
  50. return nil, fmt.Errorf("%q is not a valid pod selector operator", expr.Operator)
  51. }
  52. r, err := labels.NewRequirement(expr.Key, op, sets.NewString(expr.Values...))
  53. if err != nil {
  54. return nil, err
  55. }
  56. selector = selector.Add(*r)
  57. }
  58. return selector, nil
  59. }
  60. // LabelSelectorAsMap converts the LabelSelector api type into a map of strings, ie. the
  61. // original structure of a label selector. Operators that cannot be converted into plain
  62. // labels (Exists, DoesNotExist, NotIn, and In with more than one value) will result in
  63. // an error.
  64. func LabelSelectorAsMap(ps *LabelSelector) (map[string]string, error) {
  65. if ps == nil {
  66. return nil, nil
  67. }
  68. selector := map[string]string{}
  69. for k, v := range ps.MatchLabels {
  70. selector[k] = v
  71. }
  72. for _, expr := range ps.MatchExpressions {
  73. switch expr.Operator {
  74. case LabelSelectorOpIn:
  75. if len(expr.Values) != 1 {
  76. return selector, fmt.Errorf("operator %q without a single value cannot be converted into the old label selector format", expr.Operator)
  77. }
  78. // Should we do anything in case this will override a previous key-value pair?
  79. selector[expr.Key] = expr.Values[0]
  80. case LabelSelectorOpNotIn, LabelSelectorOpExists, LabelSelectorOpDoesNotExist:
  81. return selector, fmt.Errorf("operator %q cannot be converted into the old label selector format", expr.Operator)
  82. default:
  83. return selector, fmt.Errorf("%q is not a valid selector operator", expr.Operator)
  84. }
  85. }
  86. return selector, nil
  87. }
  88. // ParseToLabelSelector parses a string representing a selector into a LabelSelector object.
  89. // Note: This function should be kept in sync with the parser in pkg/labels/selector.go
  90. func ParseToLabelSelector(selector string) (*LabelSelector, error) {
  91. reqs, err := labels.ParseToRequirements(selector)
  92. if err != nil {
  93. return nil, fmt.Errorf("couldn't parse the selector string \"%s\": %v", selector, err)
  94. }
  95. labelSelector := &LabelSelector{
  96. MatchLabels: map[string]string{},
  97. MatchExpressions: []LabelSelectorRequirement{},
  98. }
  99. for _, req := range reqs {
  100. var op LabelSelectorOperator
  101. switch req.Operator() {
  102. case selection.Equals, selection.DoubleEquals:
  103. vals := req.Values()
  104. if vals.Len() != 1 {
  105. return nil, fmt.Errorf("equals operator must have exactly one value")
  106. }
  107. val, ok := vals.PopAny()
  108. if !ok {
  109. return nil, fmt.Errorf("equals operator has exactly one value but it cannot be retrieved")
  110. }
  111. labelSelector.MatchLabels[req.Key()] = val
  112. continue
  113. case selection.In:
  114. op = LabelSelectorOpIn
  115. case selection.NotIn:
  116. op = LabelSelectorOpNotIn
  117. case selection.Exists:
  118. op = LabelSelectorOpExists
  119. case selection.DoesNotExist:
  120. op = LabelSelectorOpDoesNotExist
  121. case selection.GreaterThan, selection.LessThan:
  122. // Adding a separate case for these operators to indicate that this is deliberate
  123. return nil, fmt.Errorf("%q isn't supported in label selectors", req.Operator())
  124. default:
  125. return nil, fmt.Errorf("%q is not a valid label selector operator", req.Operator())
  126. }
  127. labelSelector.MatchExpressions = append(labelSelector.MatchExpressions, LabelSelectorRequirement{
  128. Key: req.Key(),
  129. Operator: op,
  130. Values: req.Values().List(),
  131. })
  132. }
  133. return labelSelector, nil
  134. }
  135. // SetAsLabelSelector converts the labels.Set object into a LabelSelector api object.
  136. func SetAsLabelSelector(ls labels.Set) *LabelSelector {
  137. if ls == nil {
  138. return nil
  139. }
  140. selector := &LabelSelector{
  141. MatchLabels: make(map[string]string),
  142. }
  143. for label, value := range ls {
  144. selector.MatchLabels[label] = value
  145. }
  146. return selector
  147. }
  148. // FormatLabelSelector convert labelSelector into plain string
  149. func FormatLabelSelector(labelSelector *LabelSelector) string {
  150. selector, err := LabelSelectorAsSelector(labelSelector)
  151. if err != nil {
  152. return "<error>"
  153. }
  154. l := selector.String()
  155. if len(l) == 0 {
  156. l = "<none>"
  157. }
  158. return l
  159. }
  160. func ExtractGroupVersions(l *APIGroupList) []string {
  161. var groupVersions []string
  162. for _, g := range l.Groups {
  163. for _, gv := range g.Versions {
  164. groupVersions = append(groupVersions, gv.GroupVersion)
  165. }
  166. }
  167. return groupVersions
  168. }