Skip to content

Commit

Permalink
Support batch/v1/CronJob from Kubernetes 1.21
Browse files Browse the repository at this point in the history
Recommending to use the batch/v1 of CronJobs from Kubernetes 1.21 and later, as controlled by the --kubernetes-version flag.

Updates #360
  • Loading branch information
zegl committed Apr 15, 2021
1 parent 0a9e59a commit 97e5ce6
Show file tree
Hide file tree
Showing 17 changed files with 250 additions and 41 deletions.
5 changes: 3 additions & 2 deletions domain/kube-score.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"io"
appsv1 "k8s.io/api/apps/v1"
autoscalingv1 "k8s.io/api/autoscaling/v1"
batchv1beta1 "k8s.io/api/batch/v1beta1"
corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
policyv1beta1 "k8s.io/api/policy/v1beta1"
Expand Down Expand Up @@ -118,7 +117,9 @@ type Ingresses interface {
}

type CronJob interface {
CronJob() batchv1beta1.CronJob
GetTypeMeta() metav1.TypeMeta
GetObjectMeta() metav1.ObjectMeta
StartingDeadlineSeconds() *int64
FileLocationer
}

Expand Down
78 changes: 78 additions & 0 deletions go.sum

Large diffs are not rendered by default.

35 changes: 35 additions & 0 deletions parser/internal/cronjob/v1.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package cronjob

import (
ks "github.com/zegl/kube-score/domain"
v1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type CronJobV1 struct {
Obj v1.CronJob
Location ks.FileLocation
}

func (c CronJobV1) StartingDeadlineSeconds() *int64 {
return c.Obj.Spec.StartingDeadlineSeconds
}

func (c CronJobV1) FileLocation() ks.FileLocation {
return c.Location
}

func (c CronJobV1) GetTypeMeta() metav1.TypeMeta {
return c.Obj.TypeMeta
}

func (c CronJobV1) GetObjectMeta() metav1.ObjectMeta {
return c.Obj.ObjectMeta
}

func (c CronJobV1) GetPodTemplateSpec() corev1.PodTemplateSpec {
t := c.Obj.Spec.JobTemplate.Spec.Template
t.ObjectMeta.Namespace = c.Obj.ObjectMeta.Namespace
return t
}
35 changes: 35 additions & 0 deletions parser/internal/cronjob/v1beta1.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package cronjob

import (
ks "github.com/zegl/kube-score/domain"
"k8s.io/api/batch/v1beta1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type CronJobV1beta1 struct {
Obj v1beta1.CronJob
Location ks.FileLocation
}

func (c CronJobV1beta1) StartingDeadlineSeconds() *int64 {
return c.Obj.Spec.StartingDeadlineSeconds
}

func (c CronJobV1beta1) FileLocation() ks.FileLocation {
return c.Location
}

func (c CronJobV1beta1) GetTypeMeta() metav1.TypeMeta {
return c.Obj.TypeMeta
}

func (c CronJobV1beta1) GetObjectMeta() metav1.ObjectMeta {
return c.Obj.ObjectMeta
}

func (c CronJobV1beta1) GetPodTemplateSpec() corev1.PodTemplateSpec {
t := c.Obj.Spec.JobTemplate.Spec.Template
t.ObjectMeta.Namespace = c.Obj.ObjectMeta.Namespace
return t
}
28 changes: 0 additions & 28 deletions parser/internal/jobs.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package internal

import (
batchv1 "k8s.io/api/batch/v1"
batchv1beta1 "k8s.io/api/batch/v1beta1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

Expand Down Expand Up @@ -30,30 +29,3 @@ func (d Batchv1Job) GetPodTemplateSpec() corev1.PodTemplateSpec {
d.Spec.Template.ObjectMeta.Namespace = d.ObjectMeta.Namespace
return d.Spec.Template
}

type Batchv1beta1CronJob struct {
Obj batchv1beta1.CronJob
Location ks.FileLocation
}

func (d Batchv1beta1CronJob) FileLocation() ks.FileLocation {
return d.Location
}

func (d Batchv1beta1CronJob) GetTypeMeta() metav1.TypeMeta {
return d.Obj.TypeMeta
}

func (d Batchv1beta1CronJob) GetObjectMeta() metav1.ObjectMeta {
return d.Obj.ObjectMeta
}

func (d Batchv1beta1CronJob) GetPodTemplateSpec() corev1.PodTemplateSpec {
t := d.Obj.Spec.JobTemplate.Spec.Template
t.ObjectMeta.Namespace = d.Obj.ObjectMeta.Namespace
return t
}

func (d Batchv1beta1CronJob) CronJob() batchv1beta1.CronJob {
return d.Obj
}
10 changes: 9 additions & 1 deletion parser/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/zegl/kube-score/config"
ks "github.com/zegl/kube-score/domain"
"github.com/zegl/kube-score/parser/internal"
internalcronjob "github.com/zegl/kube-score/parser/internal/cronjob"
internalnetpol "github.com/zegl/kube-score/parser/internal/networkpolicy"
internalpdb "github.com/zegl/kube-score/parser/internal/pdb"
internalpod "github.com/zegl/kube-score/parser/internal/pod"
Expand Down Expand Up @@ -242,7 +243,14 @@ func decodeItem(cnf config.Configuration, s *parsedObjects, detectedVersion sche
case batchv1beta1.SchemeGroupVersion.WithKind("CronJob"):
var cronjob batchv1beta1.CronJob
errs.AddIfErr(decode(fileContents, &cronjob))
cjob := internal.Batchv1beta1CronJob{cronjob, fileLocation}
cjob := internalcronjob.CronJobV1beta1{cronjob, fileLocation}
addPodSpeccer(cjob)
s.cronjobs = append(s.cronjobs, cjob)

case batchv1.SchemeGroupVersion.WithKind("CronJob"):
var cronjob batchv1.CronJob
errs.AddIfErr(decode(fileContents, &cronjob))
cjob := internalcronjob.CronJobV1{cronjob, fileLocation}
addPodSpeccer(cjob)
s.cronjobs = append(s.cronjobs, cjob)

Expand Down
3 changes: 1 addition & 2 deletions score/checks/checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"strings"

appsv1 "k8s.io/api/apps/v1"
batchv1beta1 "k8s.io/api/batch/v1beta1"
corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -89,7 +88,7 @@ type IngressCheck struct {
Fn IngressCheckFn
}

type CronJobCheckFn = func(batchv1beta1.CronJob) scorecard.TestScore
type CronJobCheckFn = func(ks.CronJob) scorecard.TestScore
type CronJobCheck struct {
ks.Check
Fn CronJobCheckFn
Expand Down
6 changes: 3 additions & 3 deletions score/cronjob/cronjob.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package cronjob

import (
ks "github.com/zegl/kube-score/domain"
"github.com/zegl/kube-score/score/checks"
"github.com/zegl/kube-score/scorecard"
"k8s.io/api/batch/v1beta1"
)

func Register(allChecks *checks.Checks) {
allChecks.RegisterCronJobCheck("CronJob has deadline", `Makes sure that all CronJobs has a configured deadline`, cronJobHasDeadline)
}

func cronJobHasDeadline(job v1beta1.CronJob) (score scorecard.TestScore) {
if job.Spec.StartingDeadlineSeconds == nil {
func cronJobHasDeadline(job ks.CronJob) (score scorecard.TestScore) {
if job.StartingDeadlineSeconds() == nil {
score.Grade = scorecard.GradeCritical
score.AddComment("", "The CronJob should have startingDeadlineSeconds configured",
"This makes sure that jobs are automatically cancelled if they can not be scheduled")
Expand Down
21 changes: 18 additions & 3 deletions score/cronjob_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,30 @@ import (

func TestCronJobHasDeadline(t *testing.T) {
t.Parallel()
testExpectedScore(t, "cronjob-deadline-set.yaml", "CronJob has deadline", scorecard.GradeAllOK)

for _, v := range []string{"batchv1beta1", "batchv1"} {
t.Run(v, func(t *testing.T) {
testExpectedScore(t, "cronjob-"+v+"-deadline-set.yaml", "CronJob has deadline", scorecard.GradeAllOK)
})
}
}

func TestCronJobNotHasDeadline(t *testing.T) {
t.Parallel()
testExpectedScore(t, "cronjob-deadline-not-set.yaml", "CronJob has deadline", scorecard.GradeCritical)

for _, v := range []string{"batchv1beta1", "batchv1"} {
t.Run(v, func(t *testing.T) {
testExpectedScore(t, "cronjob-"+v+"-deadline-not-set.yaml", "CronJob has deadline", scorecard.GradeCritical)
})
}
}

func TestProbesPodCronMissingReady(t *testing.T) {
t.Parallel()
testExpectedScore(t, "cronjob-deadline-not-set.yaml", "Pod Probes", scorecard.GradeAllOK)

for _, v := range []string{"batchv1beta1", "batchv1"} {
t.Run(v, func(t *testing.T) {
testExpectedScore(t, "cronjob-"+v+"-deadline-not-set.yaml", "Pod Probes", scorecard.GradeAllOK)
})
}
}
4 changes: 2 additions & 2 deletions score/score.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@ func Score(allObjects ks.AllTypes, cnf config.Configuration) (*scorecard.Scoreca
}

for _, cjob := range allObjects.CronJobs() {
o := newObject(cjob.CronJob().TypeMeta, cjob.CronJob().ObjectMeta)
o := newObject(cjob.GetTypeMeta(), cjob.GetObjectMeta())
for _, test := range allChecks.CronJobs() {
o.Add(test.Fn(cjob.CronJob()), test.Check, cjob)
o.Add(test.Fn(cjob), test.Check, cjob)
}
}

Expand Down
3 changes: 3 additions & 0 deletions score/stable/stable_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ func metaStableAvailable(kubernetsVersion config.Semver) func(meta domain.BothMe
"StatefulSet": recommendedApi{"apps/v1", config.Semver{1, 9}},
"DaemonSet": recommendedApi{"apps/v1", config.Semver{1, 9}},
},
"batch/v1beta1": {
"CronJob": recommendedApi{"batch/v1", config.Semver{1, 21}},
},
}

score.Grade = scorecard.GradeAllOK
Expand Down
13 changes: 13 additions & 0 deletions score/stable_version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,19 @@ func TestCronJobBatchv1beta1(t *testing.T) {
testExpectedScore(t, "cronjob-batchv1beta1.yaml", "Stable version", scorecard.GradeAllOK)
}

func TestCronJobBatchv1beta1Kubernetes1dot21(t *testing.T) {
t.Parallel()
testExpectedScoreWithConfig(t, config.Configuration{
AllFiles: []ks.NamedReader{testFile("cronjob-batchv1beta1.yaml")},
KubernetesVersion: config.Semver{1, 21},
}, "Stable version", scorecard.GradeWarning)
}

func TestCronJobBatchv1(t *testing.T) {
t.Parallel()
testExpectedScore(t, "cronjob-batchv1.yaml", "Stable version", scorecard.GradeAllOK)
}

func TestJobBatchv1(t *testing.T) {
t.Parallel()
testExpectedScore(t, "job-batchv1.yaml", "Stable version", scorecard.GradeAllOK)
Expand Down
18 changes: 18 additions & 0 deletions score/testdata/cronjob-batchv1-deadline-not-set.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
19 changes: 19 additions & 0 deletions score/testdata/cronjob-batchv1-deadline-set.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
startingDeadlineSeconds: 100
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
13 changes: 13 additions & 0 deletions score/testdata/cronjob-batchv1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: cronjob-test
spec:
schedule: "1 3 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: foo
image: bar:latest
File renamed without changes.

0 comments on commit 97e5ce6

Please sign in to comment.