-
Notifications
You must be signed in to change notification settings - Fork 9
/
main.go
142 lines (119 loc) · 3.13 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package main
import (
"flag"
"fmt"
"os"
"strconv"
v1 "k8s.io/api/batch/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
log "github.com/sirupsen/logrus"
)
func FindExpiredJobs(jobList []v1.Job, annotation string, validatorList []JobValidator) []v1.Job {
expiredJobs := []v1.Job{}
ignoreAnnotationName := fmt.Sprintf("%s/ignore", annotation)
log.Debugf("(%d) jobs found", len(jobList))
for _, job := range jobList {
ignoreAnnotation := job.ObjectMeta.Annotations[ignoreAnnotationName]
ignore, err := strconv.ParseBool(ignoreAnnotation)
if err == nil && ignore {
log.Debugf(
"Ignoring (%s:%s) with annotation (%s) of (%s)",
job.ObjectMeta.Namespace,
job.ObjectMeta.Name,
ignoreAnnotationName,
ignoreAnnotation,
)
continue
}
for _, removeCheck := range validatorList {
remove, err := removeCheck(job)
if err != nil {
log.Error(err.Error())
continue
}
if remove {
expiredJobs = append(expiredJobs, job)
break
}
}
}
log.Debugf("(%d) jobs to remove", len(expiredJobs))
return expiredJobs
}
func main() {
annotation := flag.String(
"annotation",
"kube.janitor.io",
"Annotation prefix to check when deleting jobs",
)
dryrun := flag.Bool(
"dryrun",
false,
"Logs what jobs will be deleted when fully ran",
)
expiration := flag.Float64(
"expiration",
60.0,
"Expiration time on jobs (in minutes)",
)
namespace := flag.String(
"namespace",
"",
"Namespace to target when deleting jobs (by default all namespaces are targeted)",
)
pendingJobExpiration := flag.Float64(
"pendingJobExpiration",
-1.0,
`Set the time (in minutes) that jobs will be removed if they are still in the pending state.
By default, jobs stuck in a pending state are not removed`,
)
verbose := flag.Bool(
"verbose",
false,
"Increase verbosity of logging",
)
flag.Parse()
log.SetOutput(os.Stdout)
log.SetLevel(log.InfoLevel)
if *verbose {
log.SetLevel(log.DebugLevel)
}
config, err := rest.InClusterConfig()
if err != nil {
log.Fatal(err.Error())
}
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
log.Fatal(err.Error())
}
jobList, err := clientset.BatchV1().Jobs(*namespace).List(metav1.ListOptions{})
if err != nil {
log.Fatal(err.Error())
}
validatorList := []JobValidator{}
validatorList = append(validatorList, ExpiredJobs(*expiration, *annotation))
if *pendingJobExpiration > -1 {
validatorList = append(validatorList, PendingJobs(*pendingJobExpiration, clientset))
}
if *dryrun {
log.Warnf("!!! DRY RUN (JOBS WON'T BE DISCARDED) !!!")
}
targetJobs := FindExpiredJobs(jobList.Items, *annotation, validatorList)
deletePolicy := metav1.DeletePropagationForeground
for _, job := range targetJobs {
log.Infof("Deleting (%s:%s)", job.ObjectMeta.Namespace, job.ObjectMeta.Name)
if *dryrun {
continue
}
jobClient := clientset.BatchV1().Jobs(job.ObjectMeta.Namespace)
deletionOptions := &metav1.DeleteOptions{
PropagationPolicy: &deletePolicy,
}
err = jobClient.Delete(job.ObjectMeta.Name, deletionOptions)
if err != nil {
log.Warnf(err.Error())
}
}
}