2 Copyright 2016 The Kubernetes Authors.
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
22 "k8s.io/apimachinery/pkg/fields"
23 "k8s.io/apimachinery/pkg/labels"
24 "k8s.io/apimachinery/pkg/selection"
25 "k8s.io/apimachinery/pkg/types"
28 // LabelSelectorAsSelector converts the LabelSelector api type into a struct that implements
30 // Note: This function should be kept in sync with the selector methods in pkg/labels/selector.go
31 func LabelSelectorAsSelector(ps *LabelSelector) (labels.Selector, error) {
33 return labels.Nothing(), nil
35 if len(ps.MatchLabels)+len(ps.MatchExpressions) == 0 {
36 return labels.Everything(), nil
38 selector := labels.NewSelector()
39 for k, v := range ps.MatchLabels {
40 r, err := labels.NewRequirement(k, selection.Equals, []string{v})
44 selector = selector.Add(*r)
46 for _, expr := range ps.MatchExpressions {
47 var op selection.Operator
48 switch expr.Operator {
49 case LabelSelectorOpIn:
51 case LabelSelectorOpNotIn:
53 case LabelSelectorOpExists:
55 case LabelSelectorOpDoesNotExist:
56 op = selection.DoesNotExist
58 return nil, fmt.Errorf("%q is not a valid pod selector operator", expr.Operator)
60 r, err := labels.NewRequirement(expr.Key, op, append([]string(nil), expr.Values...))
64 selector = selector.Add(*r)
69 // LabelSelectorAsMap converts the LabelSelector api type into a map of strings, ie. the
70 // original structure of a label selector. Operators that cannot be converted into plain
71 // labels (Exists, DoesNotExist, NotIn, and In with more than one value) will result in
73 func LabelSelectorAsMap(ps *LabelSelector) (map[string]string, error) {
77 selector := map[string]string{}
78 for k, v := range ps.MatchLabels {
81 for _, expr := range ps.MatchExpressions {
82 switch expr.Operator {
83 case LabelSelectorOpIn:
84 if len(expr.Values) != 1 {
85 return selector, fmt.Errorf("operator %q without a single value cannot be converted into the old label selector format", expr.Operator)
87 // Should we do anything in case this will override a previous key-value pair?
88 selector[expr.Key] = expr.Values[0]
89 case LabelSelectorOpNotIn, LabelSelectorOpExists, LabelSelectorOpDoesNotExist:
90 return selector, fmt.Errorf("operator %q cannot be converted into the old label selector format", expr.Operator)
92 return selector, fmt.Errorf("%q is not a valid selector operator", expr.Operator)
98 // ParseToLabelSelector parses a string representing a selector into a LabelSelector object.
99 // Note: This function should be kept in sync with the parser in pkg/labels/selector.go
100 func ParseToLabelSelector(selector string) (*LabelSelector, error) {
101 reqs, err := labels.ParseToRequirements(selector)
103 return nil, fmt.Errorf("couldn't parse the selector string \"%s\": %v", selector, err)
106 labelSelector := &LabelSelector{
107 MatchLabels: map[string]string{},
108 MatchExpressions: []LabelSelectorRequirement{},
110 for _, req := range reqs {
111 var op LabelSelectorOperator
112 switch req.Operator() {
113 case selection.Equals, selection.DoubleEquals:
116 return nil, fmt.Errorf("equals operator must have exactly one value")
118 val, ok := vals.PopAny()
120 return nil, fmt.Errorf("equals operator has exactly one value but it cannot be retrieved")
122 labelSelector.MatchLabels[req.Key()] = val
125 op = LabelSelectorOpIn
126 case selection.NotIn:
127 op = LabelSelectorOpNotIn
128 case selection.Exists:
129 op = LabelSelectorOpExists
130 case selection.DoesNotExist:
131 op = LabelSelectorOpDoesNotExist
132 case selection.GreaterThan, selection.LessThan:
133 // Adding a separate case for these operators to indicate that this is deliberate
134 return nil, fmt.Errorf("%q isn't supported in label selectors", req.Operator())
136 return nil, fmt.Errorf("%q is not a valid label selector operator", req.Operator())
138 labelSelector.MatchExpressions = append(labelSelector.MatchExpressions, LabelSelectorRequirement{
141 Values: req.Values().List(),
144 return labelSelector, nil
147 // SetAsLabelSelector converts the labels.Set object into a LabelSelector api object.
148 func SetAsLabelSelector(ls labels.Set) *LabelSelector {
153 selector := &LabelSelector{
154 MatchLabels: make(map[string]string),
156 for label, value := range ls {
157 selector.MatchLabels[label] = value
163 // FormatLabelSelector convert labelSelector into plain string
164 func FormatLabelSelector(labelSelector *LabelSelector) string {
165 selector, err := LabelSelectorAsSelector(labelSelector)
170 l := selector.String()
177 func ExtractGroupVersions(l *APIGroupList) []string {
178 var groupVersions []string
179 for _, g := range l.Groups {
180 for _, gv := range g.Versions {
181 groupVersions = append(groupVersions, gv.GroupVersion)
187 // HasAnnotation returns a bool if passed in annotation exists
188 func HasAnnotation(obj ObjectMeta, ann string) bool {
189 _, found := obj.Annotations[ann]
193 // SetMetaDataAnnotation sets the annotation and value
194 func SetMetaDataAnnotation(obj *ObjectMeta, ann string, value string) {
195 if obj.Annotations == nil {
196 obj.Annotations = make(map[string]string)
198 obj.Annotations[ann] = value
201 // SingleObject returns a ListOptions for watching a single object.
202 func SingleObject(meta ObjectMeta) ListOptions {
204 FieldSelector: fields.OneTermEqualSelector("metadata.name", meta.Name).String(),
205 ResourceVersion: meta.ResourceVersion,
209 // NewDeleteOptions returns a DeleteOptions indicating the resource should
210 // be deleted within the specified grace period. Use zero to indicate
211 // immediate deletion. If you would prefer to use the default grace period,
212 // use &metav1.DeleteOptions{} directly.
213 func NewDeleteOptions(grace int64) *DeleteOptions {
214 return &DeleteOptions{GracePeriodSeconds: &grace}
217 // NewPreconditionDeleteOptions returns a DeleteOptions with a UID precondition set.
218 func NewPreconditionDeleteOptions(uid string) *DeleteOptions {
220 p := Preconditions{UID: &u}
221 return &DeleteOptions{Preconditions: &p}
224 // NewUIDPreconditions returns a Preconditions with UID set.
225 func NewUIDPreconditions(uid string) *Preconditions {
227 return &Preconditions{UID: &u}
230 // HasObjectMetaSystemFieldValues returns true if fields that are managed by the system on ObjectMeta have values.
231 func HasObjectMetaSystemFieldValues(meta Object) bool {
232 return !meta.GetCreationTimestamp().Time.IsZero() ||
233 len(meta.GetUID()) != 0