injection.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  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 cronjob
  14. import (
  15. "context"
  16. "fmt"
  17. "sync"
  18. batchv1 "k8s.io/api/batch/v1"
  19. batchv1beta1 "k8s.io/api/batch/v1beta1"
  20. "k8s.io/api/core/v1"
  21. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  22. "k8s.io/apimachinery/pkg/labels"
  23. "k8s.io/apimachinery/pkg/types"
  24. clientset "k8s.io/client-go/kubernetes"
  25. "k8s.io/client-go/tools/record"
  26. )
  27. // sjControlInterface is an interface that knows how to update CronJob status
  28. // created as an interface to allow testing.
  29. type sjControlInterface interface {
  30. UpdateStatus(sj *batchv1beta1.CronJob) (*batchv1beta1.CronJob, error)
  31. }
  32. // realSJControl is the default implementation of sjControlInterface.
  33. type realSJControl struct {
  34. KubeClient clientset.Interface
  35. }
  36. var _ sjControlInterface = &realSJControl{}
  37. func (c *realSJControl) UpdateStatus(sj *batchv1beta1.CronJob) (*batchv1beta1.CronJob, error) {
  38. return c.KubeClient.BatchV1beta1().CronJobs(sj.Namespace).UpdateStatus(context.TODO(), sj, metav1.UpdateOptions{})
  39. }
  40. // fakeSJControl is the default implementation of sjControlInterface.
  41. type fakeSJControl struct {
  42. Updates []batchv1beta1.CronJob
  43. }
  44. var _ sjControlInterface = &fakeSJControl{}
  45. func (c *fakeSJControl) UpdateStatus(sj *batchv1beta1.CronJob) (*batchv1beta1.CronJob, error) {
  46. c.Updates = append(c.Updates, *sj)
  47. return sj, nil
  48. }
  49. // ------------------------------------------------------------------ //
  50. // jobControlInterface is an interface that knows how to add or delete jobs
  51. // created as an interface to allow testing.
  52. type jobControlInterface interface {
  53. // GetJob retrieves a Job.
  54. GetJob(namespace, name string) (*batchv1.Job, error)
  55. // CreateJob creates new Jobs according to the spec.
  56. CreateJob(namespace string, job *batchv1.Job) (*batchv1.Job, error)
  57. // UpdateJob updates a Job.
  58. UpdateJob(namespace string, job *batchv1.Job) (*batchv1.Job, error)
  59. // PatchJob patches a Job.
  60. PatchJob(namespace string, name string, pt types.PatchType, data []byte, subresources ...string) (*batchv1.Job, error)
  61. // DeleteJob deletes the Job identified by name.
  62. // TODO: delete by UID?
  63. DeleteJob(namespace string, name string) error
  64. }
  65. // realJobControl is the default implementation of jobControlInterface.
  66. type realJobControl struct {
  67. KubeClient clientset.Interface
  68. Recorder record.EventRecorder
  69. }
  70. var _ jobControlInterface = &realJobControl{}
  71. func copyLabels(template *batchv1beta1.JobTemplateSpec) labels.Set {
  72. l := make(labels.Set)
  73. for k, v := range template.Labels {
  74. l[k] = v
  75. }
  76. return l
  77. }
  78. func copyAnnotations(template *batchv1beta1.JobTemplateSpec) labels.Set {
  79. a := make(labels.Set)
  80. for k, v := range template.Annotations {
  81. a[k] = v
  82. }
  83. return a
  84. }
  85. func (r realJobControl) GetJob(namespace, name string) (*batchv1.Job, error) {
  86. return r.KubeClient.BatchV1().Jobs(namespace).Get(context.TODO(), name, metav1.GetOptions{})
  87. }
  88. func (r realJobControl) UpdateJob(namespace string, job *batchv1.Job) (*batchv1.Job, error) {
  89. return r.KubeClient.BatchV1().Jobs(namespace).Update(context.TODO(), job, metav1.UpdateOptions{})
  90. }
  91. func (r realJobControl) PatchJob(namespace string, name string, pt types.PatchType, data []byte, subresources ...string) (*batchv1.Job, error) {
  92. return r.KubeClient.BatchV1().Jobs(namespace).Patch(context.TODO(), name, pt, data, metav1.PatchOptions{}, subresources...)
  93. }
  94. func (r realJobControl) CreateJob(namespace string, job *batchv1.Job) (*batchv1.Job, error) {
  95. return r.KubeClient.BatchV1().Jobs(namespace).Create(context.TODO(), job, metav1.CreateOptions{})
  96. }
  97. func (r realJobControl) DeleteJob(namespace string, name string) error {
  98. background := metav1.DeletePropagationBackground
  99. return r.KubeClient.BatchV1().Jobs(namespace).Delete(context.TODO(), name, &metav1.DeleteOptions{PropagationPolicy: &background})
  100. }
  101. type fakeJobControl struct {
  102. sync.Mutex
  103. Job *batchv1.Job
  104. Jobs []batchv1.Job
  105. DeleteJobName []string
  106. Err error
  107. UpdateJobName []string
  108. PatchJobName []string
  109. Patches [][]byte
  110. }
  111. var _ jobControlInterface = &fakeJobControl{}
  112. func (f *fakeJobControl) CreateJob(namespace string, job *batchv1.Job) (*batchv1.Job, error) {
  113. f.Lock()
  114. defer f.Unlock()
  115. if f.Err != nil {
  116. return nil, f.Err
  117. }
  118. job.SelfLink = fmt.Sprintf("/apis/batch/v1/namespaces/%s/jobs/%s", namespace, job.Name)
  119. f.Jobs = append(f.Jobs, *job)
  120. job.UID = "test-uid"
  121. return job, nil
  122. }
  123. func (f *fakeJobControl) GetJob(namespace, name string) (*batchv1.Job, error) {
  124. f.Lock()
  125. defer f.Unlock()
  126. if f.Err != nil {
  127. return nil, f.Err
  128. }
  129. return f.Job, nil
  130. }
  131. func (f *fakeJobControl) UpdateJob(namespace string, job *batchv1.Job) (*batchv1.Job, error) {
  132. f.Lock()
  133. defer f.Unlock()
  134. if f.Err != nil {
  135. return nil, f.Err
  136. }
  137. f.UpdateJobName = append(f.UpdateJobName, job.Name)
  138. return job, nil
  139. }
  140. func (f *fakeJobControl) PatchJob(namespace string, name string, pt types.PatchType, data []byte, subresources ...string) (*batchv1.Job, error) {
  141. f.Lock()
  142. defer f.Unlock()
  143. if f.Err != nil {
  144. return nil, f.Err
  145. }
  146. f.PatchJobName = append(f.PatchJobName, name)
  147. f.Patches = append(f.Patches, data)
  148. // We don't have anything to return. Just return something non-nil.
  149. return &batchv1.Job{}, nil
  150. }
  151. func (f *fakeJobControl) DeleteJob(namespace string, name string) error {
  152. f.Lock()
  153. defer f.Unlock()
  154. if f.Err != nil {
  155. return f.Err
  156. }
  157. f.DeleteJobName = append(f.DeleteJobName, name)
  158. return nil
  159. }
  160. func (f *fakeJobControl) Clear() {
  161. f.Lock()
  162. defer f.Unlock()
  163. f.DeleteJobName = []string{}
  164. f.Jobs = []batchv1.Job{}
  165. f.Err = nil
  166. }
  167. // ------------------------------------------------------------------ //
  168. // podControlInterface is an interface that knows how to list or delete pods
  169. // created as an interface to allow testing.
  170. type podControlInterface interface {
  171. // ListPods list pods
  172. ListPods(namespace string, opts metav1.ListOptions) (*v1.PodList, error)
  173. // DeleteJob deletes the pod identified by name.
  174. // TODO: delete by UID?
  175. DeletePod(namespace string, name string) error
  176. }
  177. // realPodControl is the default implementation of podControlInterface.
  178. type realPodControl struct {
  179. KubeClient clientset.Interface
  180. Recorder record.EventRecorder
  181. }
  182. var _ podControlInterface = &realPodControl{}
  183. func (r realPodControl) ListPods(namespace string, opts metav1.ListOptions) (*v1.PodList, error) {
  184. return r.KubeClient.CoreV1().Pods(namespace).List(context.TODO(), opts)
  185. }
  186. func (r realPodControl) DeletePod(namespace string, name string) error {
  187. return r.KubeClient.CoreV1().Pods(namespace).Delete(context.TODO(), name, nil)
  188. }
  189. type fakePodControl struct {
  190. sync.Mutex
  191. Pods []v1.Pod
  192. DeletePodName []string
  193. Err error
  194. }
  195. var _ podControlInterface = &fakePodControl{}
  196. func (f *fakePodControl) ListPods(namespace string, opts metav1.ListOptions) (*v1.PodList, error) {
  197. f.Lock()
  198. defer f.Unlock()
  199. if f.Err != nil {
  200. return nil, f.Err
  201. }
  202. return &v1.PodList{Items: f.Pods}, nil
  203. }
  204. func (f *fakePodControl) DeletePod(namespace string, name string) error {
  205. f.Lock()
  206. defer f.Unlock()
  207. if f.Err != nil {
  208. return f.Err
  209. }
  210. f.DeletePodName = append(f.DeletePodName, name)
  211. return nil
  212. }