Code refactoring for bpa operator
[icn.git] / cmd / bpa-operator / vendor / k8s.io / apimachinery / pkg / apis / meta / v1 / helpers.go
1 /*
2 Copyright 2016 The Kubernetes Authors.
3
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
7
8     http://www.apache.org/licenses/LICENSE-2.0
9
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.
15 */
16
17 package v1
18
19 import (
20         "fmt"
21
22         "k8s.io/apimachinery/pkg/fields"
23         "k8s.io/apimachinery/pkg/labels"
24         "k8s.io/apimachinery/pkg/selection"
25         "k8s.io/apimachinery/pkg/types"
26 )
27
28 // LabelSelectorAsSelector converts the LabelSelector api type into a struct that implements
29 // labels.Selector
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) {
32         if ps == nil {
33                 return labels.Nothing(), nil
34         }
35         if len(ps.MatchLabels)+len(ps.MatchExpressions) == 0 {
36                 return labels.Everything(), nil
37         }
38         selector := labels.NewSelector()
39         for k, v := range ps.MatchLabels {
40                 r, err := labels.NewRequirement(k, selection.Equals, []string{v})
41                 if err != nil {
42                         return nil, err
43                 }
44                 selector = selector.Add(*r)
45         }
46         for _, expr := range ps.MatchExpressions {
47                 var op selection.Operator
48                 switch expr.Operator {
49                 case LabelSelectorOpIn:
50                         op = selection.In
51                 case LabelSelectorOpNotIn:
52                         op = selection.NotIn
53                 case LabelSelectorOpExists:
54                         op = selection.Exists
55                 case LabelSelectorOpDoesNotExist:
56                         op = selection.DoesNotExist
57                 default:
58                         return nil, fmt.Errorf("%q is not a valid pod selector operator", expr.Operator)
59                 }
60                 r, err := labels.NewRequirement(expr.Key, op, append([]string(nil), expr.Values...))
61                 if err != nil {
62                         return nil, err
63                 }
64                 selector = selector.Add(*r)
65         }
66         return selector, nil
67 }
68
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
72 // an error.
73 func LabelSelectorAsMap(ps *LabelSelector) (map[string]string, error) {
74         if ps == nil {
75                 return nil, nil
76         }
77         selector := map[string]string{}
78         for k, v := range ps.MatchLabels {
79                 selector[k] = v
80         }
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)
86                         }
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)
91                 default:
92                         return selector, fmt.Errorf("%q is not a valid selector operator", expr.Operator)
93                 }
94         }
95         return selector, nil
96 }
97
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)
102         if err != nil {
103                 return nil, fmt.Errorf("couldn't parse the selector string \"%s\": %v", selector, err)
104         }
105
106         labelSelector := &LabelSelector{
107                 MatchLabels:      map[string]string{},
108                 MatchExpressions: []LabelSelectorRequirement{},
109         }
110         for _, req := range reqs {
111                 var op LabelSelectorOperator
112                 switch req.Operator() {
113                 case selection.Equals, selection.DoubleEquals:
114                         vals := req.Values()
115                         if vals.Len() != 1 {
116                                 return nil, fmt.Errorf("equals operator must have exactly one value")
117                         }
118                         val, ok := vals.PopAny()
119                         if !ok {
120                                 return nil, fmt.Errorf("equals operator has exactly one value but it cannot be retrieved")
121                         }
122                         labelSelector.MatchLabels[req.Key()] = val
123                         continue
124                 case selection.In:
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())
135                 default:
136                         return nil, fmt.Errorf("%q is not a valid label selector operator", req.Operator())
137                 }
138                 labelSelector.MatchExpressions = append(labelSelector.MatchExpressions, LabelSelectorRequirement{
139                         Key:      req.Key(),
140                         Operator: op,
141                         Values:   req.Values().List(),
142                 })
143         }
144         return labelSelector, nil
145 }
146
147 // SetAsLabelSelector converts the labels.Set object into a LabelSelector api object.
148 func SetAsLabelSelector(ls labels.Set) *LabelSelector {
149         if ls == nil {
150                 return nil
151         }
152
153         selector := &LabelSelector{
154                 MatchLabels: make(map[string]string),
155         }
156         for label, value := range ls {
157                 selector.MatchLabels[label] = value
158         }
159
160         return selector
161 }
162
163 // FormatLabelSelector convert labelSelector into plain string
164 func FormatLabelSelector(labelSelector *LabelSelector) string {
165         selector, err := LabelSelectorAsSelector(labelSelector)
166         if err != nil {
167                 return "<error>"
168         }
169
170         l := selector.String()
171         if len(l) == 0 {
172                 l = "<none>"
173         }
174         return l
175 }
176
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)
182                 }
183         }
184         return groupVersions
185 }
186
187 // HasAnnotation returns a bool if passed in annotation exists
188 func HasAnnotation(obj ObjectMeta, ann string) bool {
189         _, found := obj.Annotations[ann]
190         return found
191 }
192
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)
197         }
198         obj.Annotations[ann] = value
199 }
200
201 // SingleObject returns a ListOptions for watching a single object.
202 func SingleObject(meta ObjectMeta) ListOptions {
203         return ListOptions{
204                 FieldSelector:   fields.OneTermEqualSelector("metadata.name", meta.Name).String(),
205                 ResourceVersion: meta.ResourceVersion,
206         }
207 }
208
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}
215 }
216
217 // NewPreconditionDeleteOptions returns a DeleteOptions with a UID precondition set.
218 func NewPreconditionDeleteOptions(uid string) *DeleteOptions {
219         u := types.UID(uid)
220         p := Preconditions{UID: &u}
221         return &DeleteOptions{Preconditions: &p}
222 }
223
224 // NewUIDPreconditions returns a Preconditions with UID set.
225 func NewUIDPreconditions(uid string) *Preconditions {
226         u := types.UID(uid)
227         return &Preconditions{UID: &u}
228 }
229
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
234 }