helpers.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. Copyright 2018 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 polymorphichelpers
  14. import (
  15. "context"
  16. "fmt"
  17. "sort"
  18. "time"
  19. appsv1 "k8s.io/api/apps/v1"
  20. appsv1beta1 "k8s.io/api/apps/v1beta1"
  21. appsv1beta2 "k8s.io/api/apps/v1beta2"
  22. batchv1 "k8s.io/api/batch/v1"
  23. corev1 "k8s.io/api/core/v1"
  24. extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
  25. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  26. "k8s.io/apimachinery/pkg/labels"
  27. "k8s.io/apimachinery/pkg/runtime"
  28. "k8s.io/apimachinery/pkg/watch"
  29. coreclient "k8s.io/client-go/kubernetes/typed/core/v1"
  30. watchtools "k8s.io/client-go/tools/watch"
  31. )
  32. // GetFirstPod returns a pod matching the namespace and label selector
  33. // and the number of all pods that match the label selector.
  34. func GetFirstPod(client coreclient.PodsGetter, namespace string, selector string, timeout time.Duration, sortBy func([]*corev1.Pod) sort.Interface) (*corev1.Pod, int, error) {
  35. options := metav1.ListOptions{LabelSelector: selector}
  36. podList, err := client.Pods(namespace).List(options)
  37. if err != nil {
  38. return nil, 0, err
  39. }
  40. pods := []*corev1.Pod{}
  41. for i := range podList.Items {
  42. pod := podList.Items[i]
  43. pods = append(pods, &pod)
  44. }
  45. if len(pods) > 0 {
  46. sort.Sort(sortBy(pods))
  47. return pods[0], len(podList.Items), nil
  48. }
  49. // Watch until we observe a pod
  50. options.ResourceVersion = podList.ResourceVersion
  51. w, err := client.Pods(namespace).Watch(options)
  52. if err != nil {
  53. return nil, 0, err
  54. }
  55. defer w.Stop()
  56. condition := func(event watch.Event) (bool, error) {
  57. return event.Type == watch.Added || event.Type == watch.Modified, nil
  58. }
  59. ctx, cancel := watchtools.ContextWithOptionalTimeout(context.Background(), timeout)
  60. defer cancel()
  61. event, err := watchtools.UntilWithoutRetry(ctx, w, condition)
  62. if err != nil {
  63. return nil, 0, err
  64. }
  65. pod, ok := event.Object.(*corev1.Pod)
  66. if !ok {
  67. return nil, 0, fmt.Errorf("%#v is not a pod event", event)
  68. }
  69. return pod, 1, nil
  70. }
  71. // SelectorsForObject returns the pod label selector for a given object
  72. func SelectorsForObject(object runtime.Object) (namespace string, selector labels.Selector, err error) {
  73. switch t := object.(type) {
  74. case *extensionsv1beta1.ReplicaSet:
  75. namespace = t.Namespace
  76. selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
  77. if err != nil {
  78. return "", nil, fmt.Errorf("invalid label selector: %v", err)
  79. }
  80. case *appsv1.ReplicaSet:
  81. namespace = t.Namespace
  82. selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
  83. if err != nil {
  84. return "", nil, fmt.Errorf("invalid label selector: %v", err)
  85. }
  86. case *appsv1beta2.ReplicaSet:
  87. namespace = t.Namespace
  88. selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
  89. if err != nil {
  90. return "", nil, fmt.Errorf("invalid label selector: %v", err)
  91. }
  92. case *corev1.ReplicationController:
  93. namespace = t.Namespace
  94. selector = labels.SelectorFromSet(t.Spec.Selector)
  95. case *appsv1.StatefulSet:
  96. namespace = t.Namespace
  97. selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
  98. if err != nil {
  99. return "", nil, fmt.Errorf("invalid label selector: %v", err)
  100. }
  101. case *appsv1beta1.StatefulSet:
  102. namespace = t.Namespace
  103. selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
  104. if err != nil {
  105. return "", nil, fmt.Errorf("invalid label selector: %v", err)
  106. }
  107. case *appsv1beta2.StatefulSet:
  108. namespace = t.Namespace
  109. selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
  110. if err != nil {
  111. return "", nil, fmt.Errorf("invalid label selector: %v", err)
  112. }
  113. case *extensionsv1beta1.DaemonSet:
  114. namespace = t.Namespace
  115. selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
  116. if err != nil {
  117. return "", nil, fmt.Errorf("invalid label selector: %v", err)
  118. }
  119. case *appsv1.DaemonSet:
  120. namespace = t.Namespace
  121. selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
  122. if err != nil {
  123. return "", nil, fmt.Errorf("invalid label selector: %v", err)
  124. }
  125. case *appsv1beta2.DaemonSet:
  126. namespace = t.Namespace
  127. selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
  128. if err != nil {
  129. return "", nil, fmt.Errorf("invalid label selector: %v", err)
  130. }
  131. case *extensionsv1beta1.Deployment:
  132. namespace = t.Namespace
  133. selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
  134. if err != nil {
  135. return "", nil, fmt.Errorf("invalid label selector: %v", err)
  136. }
  137. case *appsv1.Deployment:
  138. namespace = t.Namespace
  139. selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
  140. if err != nil {
  141. return "", nil, fmt.Errorf("invalid label selector: %v", err)
  142. }
  143. case *appsv1beta1.Deployment:
  144. namespace = t.Namespace
  145. selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
  146. if err != nil {
  147. return "", nil, fmt.Errorf("invalid label selector: %v", err)
  148. }
  149. case *appsv1beta2.Deployment:
  150. namespace = t.Namespace
  151. selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
  152. if err != nil {
  153. return "", nil, fmt.Errorf("invalid label selector: %v", err)
  154. }
  155. case *batchv1.Job:
  156. namespace = t.Namespace
  157. selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
  158. if err != nil {
  159. return "", nil, fmt.Errorf("invalid label selector: %v", err)
  160. }
  161. case *corev1.Service:
  162. namespace = t.Namespace
  163. if t.Spec.Selector == nil || len(t.Spec.Selector) == 0 {
  164. return "", nil, fmt.Errorf("invalid service '%s': Service is defined without a selector", t.Name)
  165. }
  166. selector = labels.SelectorFromSet(t.Spec.Selector)
  167. default:
  168. return "", nil, fmt.Errorf("selector for %T not implemented", object)
  169. }
  170. return namespace, selector, nil
  171. }