123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- /*
- Copyright 2016 The Kubernetes Authors.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package cronjob
- import (
- "fmt"
- "sync"
- batchv1 "k8s.io/api/batch/v1"
- batchv1beta1 "k8s.io/api/batch/v1beta1"
- "k8s.io/api/core/v1"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/labels"
- "k8s.io/apimachinery/pkg/types"
- clientset "k8s.io/client-go/kubernetes"
- "k8s.io/client-go/tools/record"
- )
- // sjControlInterface is an interface that knows how to update CronJob status
- // created as an interface to allow testing.
- type sjControlInterface interface {
- UpdateStatus(sj *batchv1beta1.CronJob) (*batchv1beta1.CronJob, error)
- }
- // realSJControl is the default implementation of sjControlInterface.
- type realSJControl struct {
- KubeClient clientset.Interface
- }
- var _ sjControlInterface = &realSJControl{}
- func (c *realSJControl) UpdateStatus(sj *batchv1beta1.CronJob) (*batchv1beta1.CronJob, error) {
- return c.KubeClient.BatchV1beta1().CronJobs(sj.Namespace).UpdateStatus(sj)
- }
- // fakeSJControl is the default implementation of sjControlInterface.
- type fakeSJControl struct {
- Updates []batchv1beta1.CronJob
- }
- var _ sjControlInterface = &fakeSJControl{}
- func (c *fakeSJControl) UpdateStatus(sj *batchv1beta1.CronJob) (*batchv1beta1.CronJob, error) {
- c.Updates = append(c.Updates, *sj)
- return sj, nil
- }
- // ------------------------------------------------------------------ //
- // jobControlInterface is an interface that knows how to add or delete jobs
- // created as an interface to allow testing.
- type jobControlInterface interface {
- // GetJob retrieves a Job.
- GetJob(namespace, name string) (*batchv1.Job, error)
- // CreateJob creates new Jobs according to the spec.
- CreateJob(namespace string, job *batchv1.Job) (*batchv1.Job, error)
- // UpdateJob updates a Job.
- UpdateJob(namespace string, job *batchv1.Job) (*batchv1.Job, error)
- // PatchJob patches a Job.
- PatchJob(namespace string, name string, pt types.PatchType, data []byte, subresources ...string) (*batchv1.Job, error)
- // DeleteJob deletes the Job identified by name.
- // TODO: delete by UID?
- DeleteJob(namespace string, name string) error
- }
- // realJobControl is the default implementation of jobControlInterface.
- type realJobControl struct {
- KubeClient clientset.Interface
- Recorder record.EventRecorder
- }
- var _ jobControlInterface = &realJobControl{}
- func copyLabels(template *batchv1beta1.JobTemplateSpec) labels.Set {
- l := make(labels.Set)
- for k, v := range template.Labels {
- l[k] = v
- }
- return l
- }
- func copyAnnotations(template *batchv1beta1.JobTemplateSpec) labels.Set {
- a := make(labels.Set)
- for k, v := range template.Annotations {
- a[k] = v
- }
- return a
- }
- func (r realJobControl) GetJob(namespace, name string) (*batchv1.Job, error) {
- return r.KubeClient.BatchV1().Jobs(namespace).Get(name, metav1.GetOptions{})
- }
- func (r realJobControl) UpdateJob(namespace string, job *batchv1.Job) (*batchv1.Job, error) {
- return r.KubeClient.BatchV1().Jobs(namespace).Update(job)
- }
- func (r realJobControl) PatchJob(namespace string, name string, pt types.PatchType, data []byte, subresources ...string) (*batchv1.Job, error) {
- return r.KubeClient.BatchV1().Jobs(namespace).Patch(name, pt, data, subresources...)
- }
- func (r realJobControl) CreateJob(namespace string, job *batchv1.Job) (*batchv1.Job, error) {
- return r.KubeClient.BatchV1().Jobs(namespace).Create(job)
- }
- func (r realJobControl) DeleteJob(namespace string, name string) error {
- background := metav1.DeletePropagationBackground
- return r.KubeClient.BatchV1().Jobs(namespace).Delete(name, &metav1.DeleteOptions{PropagationPolicy: &background})
- }
- type fakeJobControl struct {
- sync.Mutex
- Job *batchv1.Job
- Jobs []batchv1.Job
- DeleteJobName []string
- Err error
- UpdateJobName []string
- PatchJobName []string
- Patches [][]byte
- }
- var _ jobControlInterface = &fakeJobControl{}
- func (f *fakeJobControl) CreateJob(namespace string, job *batchv1.Job) (*batchv1.Job, error) {
- f.Lock()
- defer f.Unlock()
- if f.Err != nil {
- return nil, f.Err
- }
- job.SelfLink = fmt.Sprintf("/api/batch/v1/namespaces/%s/jobs/%s", namespace, job.Name)
- f.Jobs = append(f.Jobs, *job)
- job.UID = "test-uid"
- return job, nil
- }
- func (f *fakeJobControl) GetJob(namespace, name string) (*batchv1.Job, error) {
- f.Lock()
- defer f.Unlock()
- if f.Err != nil {
- return nil, f.Err
- }
- return f.Job, nil
- }
- func (f *fakeJobControl) UpdateJob(namespace string, job *batchv1.Job) (*batchv1.Job, error) {
- f.Lock()
- defer f.Unlock()
- if f.Err != nil {
- return nil, f.Err
- }
- f.UpdateJobName = append(f.UpdateJobName, job.Name)
- return job, nil
- }
- func (f *fakeJobControl) PatchJob(namespace string, name string, pt types.PatchType, data []byte, subresources ...string) (*batchv1.Job, error) {
- f.Lock()
- defer f.Unlock()
- if f.Err != nil {
- return nil, f.Err
- }
- f.PatchJobName = append(f.PatchJobName, name)
- f.Patches = append(f.Patches, data)
- // We don't have anything to return. Just return something non-nil.
- return &batchv1.Job{}, nil
- }
- func (f *fakeJobControl) DeleteJob(namespace string, name string) error {
- f.Lock()
- defer f.Unlock()
- if f.Err != nil {
- return f.Err
- }
- f.DeleteJobName = append(f.DeleteJobName, name)
- return nil
- }
- func (f *fakeJobControl) Clear() {
- f.Lock()
- defer f.Unlock()
- f.DeleteJobName = []string{}
- f.Jobs = []batchv1.Job{}
- f.Err = nil
- }
- // ------------------------------------------------------------------ //
- // podControlInterface is an interface that knows how to list or delete pods
- // created as an interface to allow testing.
- type podControlInterface interface {
- // ListPods list pods
- ListPods(namespace string, opts metav1.ListOptions) (*v1.PodList, error)
- // DeleteJob deletes the pod identified by name.
- // TODO: delete by UID?
- DeletePod(namespace string, name string) error
- }
- // realPodControl is the default implementation of podControlInterface.
- type realPodControl struct {
- KubeClient clientset.Interface
- Recorder record.EventRecorder
- }
- var _ podControlInterface = &realPodControl{}
- func (r realPodControl) ListPods(namespace string, opts metav1.ListOptions) (*v1.PodList, error) {
- return r.KubeClient.CoreV1().Pods(namespace).List(opts)
- }
- func (r realPodControl) DeletePod(namespace string, name string) error {
- return r.KubeClient.CoreV1().Pods(namespace).Delete(name, nil)
- }
- type fakePodControl struct {
- sync.Mutex
- Pods []v1.Pod
- DeletePodName []string
- Err error
- }
- var _ podControlInterface = &fakePodControl{}
- func (f *fakePodControl) ListPods(namespace string, opts metav1.ListOptions) (*v1.PodList, error) {
- f.Lock()
- defer f.Unlock()
- if f.Err != nil {
- return nil, f.Err
- }
- return &v1.PodList{Items: f.Pods}, nil
- }
- func (f *fakePodControl) DeletePod(namespace string, name string) error {
- f.Lock()
- defer f.Unlock()
- if f.Err != nil {
- return f.Err
- }
- f.DeletePodName = append(f.DeletePodName, name)
- return nil
- }
|