Skip to content

Commit 07e5b94

Browse files
committed
score: generic check functions
1 parent f0e1c0d commit 07e5b94

File tree

13 files changed

+135
-148
lines changed

13 files changed

+135
-148
lines changed

score/checks/checks.go

+74-114
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@ func New(cnf config.Configuration) *Checks {
1818
cnf: cnf,
1919

2020
all: make([]ks.Check, 0),
21-
metas: make(map[string]MetaCheck),
21+
metas: make(map[string]GenCheck[ks.BothMeta]),
2222
pods: make(map[string]PodCheck),
23-
services: make(map[string]ServiceCheck),
24-
statefulsets: make(map[string]StatefulSetCheck),
25-
deployments: make(map[string]DeploymentCheck),
26-
networkpolicies: make(map[string]NetworkPolicyCheck),
27-
ingresses: make(map[string]IngressCheck),
28-
cronjobs: make(map[string]CronJobCheck),
29-
horizontalPodAutoscalers: make(map[string]HorizontalPodAutoscalerCheck),
30-
poddisruptionbudgets: make(map[string]PodDisruptionBudgetCheck),
23+
services: make(map[string]GenCheck[corev1.Service]),
24+
statefulsets: make(map[string]GenCheck[appsv1.StatefulSet]),
25+
deployments: make(map[string]GenCheck[appsv1.Deployment]),
26+
networkpolicies: make(map[string]GenCheck[networkingv1.NetworkPolicy]),
27+
ingresses: make(map[string]GenCheck[ks.Ingress]),
28+
cronjobs: make(map[string]GenCheck[ks.CronJob]),
29+
horizontalPodAutoscalers: make(map[string]GenCheck[ks.HpaTargeter]),
30+
poddisruptionbudgets: make(map[string]GenCheck[ks.PodDisruptionBudget]),
3131
}
3232
}
3333

@@ -59,66 +59,25 @@ type PodCheck struct {
5959
Fn PodCheckFn
6060
}
6161

62-
type ServiceCheckFn = func(corev1.Service) scorecard.TestScore
63-
type ServiceCheck struct {
64-
ks.Check
65-
Fn ServiceCheckFn
66-
}
67-
68-
type StatefulSetCheckFn = func(appsv1.StatefulSet) (scorecard.TestScore, error)
69-
type StatefulSetCheck struct {
70-
ks.Check
71-
Fn StatefulSetCheckFn
72-
}
73-
74-
type DeploymentCheckFn = func(appsv1.Deployment) (scorecard.TestScore, error)
75-
type DeploymentCheck struct {
76-
ks.Check
77-
Fn DeploymentCheckFn
78-
}
79-
80-
type NetworkPolicyCheckFn = func(networkingv1.NetworkPolicy) scorecard.TestScore
81-
type NetworkPolicyCheck struct {
82-
ks.Check
83-
Fn NetworkPolicyCheckFn
84-
}
62+
type CheckFunc[T any] func(T) (scorecard.TestScore, error)
8563

86-
type IngressCheckFn = func(ks.Ingress) scorecard.TestScore
87-
type IngressCheck struct {
64+
type GenCheck[T any] struct {
8865
ks.Check
89-
Fn IngressCheckFn
90-
}
91-
92-
type CronJobCheckFn = func(ks.CronJob) scorecard.TestScore
93-
type CronJobCheck struct {
94-
ks.Check
95-
Fn CronJobCheckFn
96-
}
97-
98-
type HorizontalPodAutoscalerCheckFn = func(ks.HpaTargeter) scorecard.TestScore
99-
type HorizontalPodAutoscalerCheck struct {
100-
ks.Check
101-
Fn HorizontalPodAutoscalerCheckFn
102-
}
103-
104-
type PodDisruptionBudgetCheckFn = func(ks.PodDisruptionBudget) scorecard.TestScore
105-
type PodDisruptionBudgetCheck struct {
106-
ks.Check
107-
Fn PodDisruptionBudgetCheckFn
66+
Fn CheckFunc[T]
10867
}
10968

11069
type Checks struct {
11170
all []ks.Check
112-
metas map[string]MetaCheck
71+
metas map[string]GenCheck[ks.BothMeta]
11372
pods map[string]PodCheck
114-
services map[string]ServiceCheck
115-
statefulsets map[string]StatefulSetCheck
116-
deployments map[string]DeploymentCheck
117-
networkpolicies map[string]NetworkPolicyCheck
118-
ingresses map[string]IngressCheck
119-
cronjobs map[string]CronJobCheck
120-
horizontalPodAutoscalers map[string]HorizontalPodAutoscalerCheck
121-
poddisruptionbudgets map[string]PodDisruptionBudgetCheck
73+
services map[string]GenCheck[corev1.Service]
74+
statefulsets map[string]GenCheck[appsv1.StatefulSet]
75+
deployments map[string]GenCheck[appsv1.Deployment]
76+
networkpolicies map[string]GenCheck[networkingv1.NetworkPolicy]
77+
ingresses map[string]GenCheck[ks.Ingress]
78+
cronjobs map[string]GenCheck[ks.CronJob]
79+
horizontalPodAutoscalers map[string]GenCheck[ks.HpaTargeter]
80+
poddisruptionbudgets map[string]GenCheck[ks.PodDisruptionBudget]
12281

12382
cnf config.Configuration
12483
}
@@ -128,17 +87,17 @@ func (c Checks) isEnabled(check ks.Check) bool {
12887
return !ok
12988
}
13089

131-
func (c *Checks) RegisterMetaCheck(name, comment string, fn MetaCheckFn) {
90+
func (c *Checks) RegisterMetaCheck(name, comment string, fn CheckFunc[ks.BothMeta]) {
13291
ch := NewCheck(name, "all", comment, false)
133-
c.registerMetaCheck(MetaCheck{ch, fn})
92+
c.registerMetaCheck(GenCheck[ks.BothMeta]{ch, fn})
13493
}
13594

136-
func (c *Checks) RegisterOptionalMetaCheck(name, comment string, fn MetaCheckFn) {
95+
func (c *Checks) RegisterOptionalMetaCheck(name, comment string, fn CheckFunc[ks.BothMeta]) {
13796
ch := NewCheck(name, "all", comment, true)
138-
c.registerMetaCheck(MetaCheck{ch, fn})
97+
c.registerMetaCheck(GenCheck[ks.BothMeta]{ch, fn})
13998
}
14099

141-
func (c *Checks) registerMetaCheck(ch MetaCheck) {
100+
func (c *Checks) registerMetaCheck(ch GenCheck[ks.BothMeta]) {
142101
c.all = append(c.all, ch.Check)
143102

144103
if !c.isEnabled(ch.Check) {
@@ -147,7 +106,7 @@ func (c *Checks) registerMetaCheck(ch MetaCheck) {
147106
c.metas[machineFriendlyName(ch.Name)] = ch
148107
}
149108

150-
func (c *Checks) Metas() map[string]MetaCheck {
109+
func (c *Checks) Metas() map[string]GenCheck[ks.BothMeta] {
151110
return c.metas
152111
}
153112

@@ -174,17 +133,17 @@ func (c *Checks) Pods() map[string]PodCheck {
174133
return c.pods
175134
}
176135

177-
func (c *Checks) RegisterHorizontalPodAutoscalerCheck(name, comment string, fn HorizontalPodAutoscalerCheckFn) {
136+
func (c *Checks) RegisterHorizontalPodAutoscalerCheck(name, comment string, fn CheckFunc[ks.HpaTargeter]) {
178137
ch := NewCheck(name, "HorizontalPodAutoscaler", comment, false)
179-
c.registerHorizontalPodAutoscalerCheck(HorizontalPodAutoscalerCheck{ch, fn})
138+
c.registerHorizontalPodAutoscalerCheck(GenCheck[ks.HpaTargeter]{ch, fn})
180139
}
181140

182-
func (c *Checks) RegisterOptionalHorizontalPodAutoscalerCheck(name, comment string, fn HorizontalPodAutoscalerCheckFn) {
141+
func (c *Checks) RegisterOptionalHorizontalPodAutoscalerCheck(name, comment string, fn CheckFunc[ks.HpaTargeter]) {
183142
ch := NewCheck(name, "HorizontalPodAutoscaler", comment, true)
184-
c.registerHorizontalPodAutoscalerCheck(HorizontalPodAutoscalerCheck{ch, fn})
143+
c.registerHorizontalPodAutoscalerCheck(GenCheck[ks.HpaTargeter]{ch, fn})
185144
}
186145

187-
func (c *Checks) registerHorizontalPodAutoscalerCheck(ch HorizontalPodAutoscalerCheck) {
146+
func (c *Checks) registerHorizontalPodAutoscalerCheck(ch GenCheck[ks.HpaTargeter]) {
188147
c.all = append(c.all, ch.Check)
189148

190149
if !c.isEnabled(ch.Check) {
@@ -193,21 +152,21 @@ func (c *Checks) registerHorizontalPodAutoscalerCheck(ch HorizontalPodAutoscaler
193152
c.horizontalPodAutoscalers[machineFriendlyName(ch.Name)] = ch
194153
}
195154

196-
func (c *Checks) HorizontalPodAutoscalers() map[string]HorizontalPodAutoscalerCheck {
155+
func (c *Checks) HorizontalPodAutoscalers() map[string]GenCheck[ks.HpaTargeter] {
197156
return c.horizontalPodAutoscalers
198157
}
199158

200-
func (c *Checks) RegisterCronJobCheck(name, comment string, fn CronJobCheckFn) {
159+
func (c *Checks) RegisterCronJobCheck(name, comment string, fn CheckFunc[ks.CronJob]) {
201160
ch := NewCheck(name, "CronJob", comment, false)
202-
c.registerCronJobCheck(CronJobCheck{ch, fn})
161+
c.registerCronJobCheck(GenCheck[ks.CronJob]{ch, fn})
203162
}
204163

205-
func (c *Checks) RegisterOptionalCronJobCheck(name, comment string, fn CronJobCheckFn) {
164+
func (c *Checks) RegisterOptionalCronJobCheck(name, comment string, fn CheckFunc[ks.CronJob]) {
206165
ch := NewCheck(name, "CronJob", comment, true)
207-
c.registerCronJobCheck(CronJobCheck{ch, fn})
166+
c.registerCronJobCheck(GenCheck[ks.CronJob]{ch, fn})
208167
}
209168

210-
func (c *Checks) registerCronJobCheck(ch CronJobCheck) {
169+
func (c *Checks) registerCronJobCheck(ch GenCheck[ks.CronJob]) {
211170
c.all = append(c.all, ch.Check)
212171

213172
if !c.isEnabled(ch.Check) {
@@ -216,21 +175,21 @@ func (c *Checks) registerCronJobCheck(ch CronJobCheck) {
216175
c.cronjobs[machineFriendlyName(ch.Name)] = ch
217176
}
218177

219-
func (c *Checks) CronJobs() map[string]CronJobCheck {
178+
func (c *Checks) CronJobs() map[string]GenCheck[ks.CronJob] {
220179
return c.cronjobs
221180
}
222181

223-
func (c *Checks) RegisterStatefulSetCheck(name, comment string, fn StatefulSetCheckFn) {
182+
func (c *Checks) RegisterStatefulSetCheck(name, comment string, fn CheckFunc[appsv1.StatefulSet]) {
224183
ch := NewCheck(name, "StatefulSet", comment, false)
225-
c.registerStatefulSetCheck(StatefulSetCheck{ch, fn})
184+
c.registerStatefulSetCheck(GenCheck[appsv1.StatefulSet]{ch, fn})
226185
}
227186

228-
func (c *Checks) RegisterOptionalStatefulSetCheck(name, comment string, fn StatefulSetCheckFn) {
187+
func (c *Checks) RegisterOptionalStatefulSetCheck(name, comment string, fn CheckFunc[appsv1.StatefulSet]) {
229188
ch := NewCheck(name, "StatefulSet", comment, true)
230-
c.registerStatefulSetCheck(StatefulSetCheck{ch, fn})
189+
c.registerStatefulSetCheck(GenCheck[appsv1.StatefulSet]{ch, fn})
231190
}
232191

233-
func (c *Checks) registerStatefulSetCheck(ch StatefulSetCheck) {
192+
func (c *Checks) registerStatefulSetCheck(ch GenCheck[appsv1.StatefulSet]) {
234193
c.all = append(c.all, ch.Check)
235194

236195
if !c.isEnabled(ch.Check) {
@@ -239,21 +198,21 @@ func (c *Checks) registerStatefulSetCheck(ch StatefulSetCheck) {
239198
c.statefulsets[machineFriendlyName(ch.Name)] = ch
240199
}
241200

242-
func (c *Checks) StatefulSets() map[string]StatefulSetCheck {
201+
func (c *Checks) StatefulSets() map[string]GenCheck[appsv1.StatefulSet] {
243202
return c.statefulsets
244203
}
245204

246-
func (c *Checks) RegisterDeploymentCheck(name, comment string, fn DeploymentCheckFn) {
205+
func (c *Checks) RegisterDeploymentCheck(name, comment string, fn CheckFunc[appsv1.Deployment]) {
247206
ch := NewCheck(name, "Deployment", comment, false)
248-
c.registerDeploymentCheck(DeploymentCheck{ch, fn})
207+
c.registerDeploymentCheck(GenCheck[appsv1.Deployment]{ch, fn})
249208
}
250209

251-
func (c *Checks) RegisterOptionalDeploymentCheck(name, comment string, fn DeploymentCheckFn) {
210+
func (c *Checks) RegisterOptionalDeploymentCheck(name, comment string, fn CheckFunc[appsv1.Deployment]) {
252211
ch := NewCheck(name, "Deployment", comment, true)
253-
c.registerDeploymentCheck(DeploymentCheck{ch, fn})
212+
c.registerDeploymentCheck(GenCheck[appsv1.Deployment]{ch, fn})
254213
}
255214

256-
func (c *Checks) registerDeploymentCheck(ch DeploymentCheck) {
215+
func (c *Checks) registerDeploymentCheck(ch GenCheck[appsv1.Deployment]) {
257216
c.all = append(c.all, ch.Check)
258217

259218
if !c.isEnabled(ch.Check) {
@@ -262,21 +221,21 @@ func (c *Checks) registerDeploymentCheck(ch DeploymentCheck) {
262221
c.deployments[machineFriendlyName(ch.Name)] = ch
263222
}
264223

265-
func (c *Checks) Deployments() map[string]DeploymentCheck {
224+
func (c *Checks) Deployments() map[string]GenCheck[appsv1.Deployment] {
266225
return c.deployments
267226
}
268227

269-
func (c *Checks) RegisterIngressCheck(name, comment string, fn IngressCheckFn) {
228+
func (c *Checks) RegisterIngressCheck(name, comment string, fn CheckFunc[ks.Ingress]) {
270229
ch := NewCheck(name, "Ingress", comment, false)
271-
c.registerIngressCheck(IngressCheck{ch, fn})
230+
c.registerIngressCheck(GenCheck[ks.Ingress]{ch, fn})
272231
}
273232

274-
func (c *Checks) RegisterOptionalIngressCheck(name, comment string, fn IngressCheckFn) {
233+
func (c *Checks) RegisterOptionalIngressCheck(name, comment string, fn CheckFunc[ks.Ingress]) {
275234
ch := NewCheck(name, "Ingress", comment, true)
276-
c.registerIngressCheck(IngressCheck{ch, fn})
235+
c.registerIngressCheck(GenCheck[ks.Ingress]{ch, fn})
277236
}
278237

279-
func (c *Checks) registerIngressCheck(ch IngressCheck) {
238+
func (c *Checks) registerIngressCheck(ch GenCheck[ks.Ingress]) {
280239
c.all = append(c.all, ch.Check)
281240

282241
if !c.isEnabled(ch.Check) {
@@ -285,21 +244,21 @@ func (c *Checks) registerIngressCheck(ch IngressCheck) {
285244
c.ingresses[machineFriendlyName(ch.Name)] = ch
286245
}
287246

288-
func (c *Checks) Ingresses() map[string]IngressCheck {
247+
func (c *Checks) Ingresses() map[string]GenCheck[ks.Ingress] {
289248
return c.ingresses
290249
}
291250

292-
func (c *Checks) RegisterNetworkPolicyCheck(name, comment string, fn NetworkPolicyCheckFn) {
251+
func (c *Checks) RegisterNetworkPolicyCheck(name, comment string, fn CheckFunc[networkingv1.NetworkPolicy]) {
293252
ch := NewCheck(name, "NetworkPolicy", comment, false)
294-
c.registerNetworkPolicyCheck(NetworkPolicyCheck{ch, fn})
253+
c.registerNetworkPolicyCheck(GenCheck[networkingv1.NetworkPolicy]{ch, fn})
295254
}
296255

297-
func (c *Checks) RegisterOptionalNetworkPolicyCheck(name, comment string, fn NetworkPolicyCheckFn) {
256+
func (c *Checks) RegisterOptionalNetworkPolicyCheck(name, comment string, fn CheckFunc[networkingv1.NetworkPolicy]) {
298257
ch := NewCheck(name, "NetworkPolicy", comment, true)
299-
c.registerNetworkPolicyCheck(NetworkPolicyCheck{ch, fn})
258+
c.registerNetworkPolicyCheck(GenCheck[networkingv1.NetworkPolicy]{ch, fn})
300259
}
301260

302-
func (c *Checks) registerNetworkPolicyCheck(ch NetworkPolicyCheck) {
261+
func (c *Checks) registerNetworkPolicyCheck(ch GenCheck[networkingv1.NetworkPolicy]) {
303262
c.all = append(c.all, ch.Check)
304263

305264
if !c.isEnabled(ch.Check) {
@@ -308,39 +267,40 @@ func (c *Checks) registerNetworkPolicyCheck(ch NetworkPolicyCheck) {
308267
c.networkpolicies[machineFriendlyName(ch.Name)] = ch
309268
}
310269

311-
func (c *Checks) NetworkPolicies() map[string]NetworkPolicyCheck {
270+
func (c *Checks) NetworkPolicies() map[string]GenCheck[networkingv1.NetworkPolicy] {
312271
return c.networkpolicies
313272
}
314273

315-
func (c *Checks) RegisterPodDisruptionBudgetCheck(name, comment string, fn PodDisruptionBudgetCheckFn) {
274+
func (c *Checks) RegisterPodDisruptionBudgetCheck(name, comment string, fn CheckFunc[ks.PodDisruptionBudget]) {
316275
ch := NewCheck(name, "PodDisruptionBudget", comment, false)
317-
c.registerPodDisruptionBudgetCheck(PodDisruptionBudgetCheck{ch, fn})
276+
c.registerPodDisruptionBudgetCheck(GenCheck[ks.PodDisruptionBudget]{ch, fn})
318277
}
319278

320-
func (c *Checks) registerPodDisruptionBudgetCheck(ch PodDisruptionBudgetCheck) {
279+
func (c *Checks) registerPodDisruptionBudgetCheck(ch GenCheck[ks.PodDisruptionBudget]) {
321280
c.all = append(c.all, ch.Check)
322281

323282
if !c.isEnabled(ch.Check) {
324283
return
325284
}
285+
326286
c.poddisruptionbudgets[machineFriendlyName(ch.Name)] = ch
327287
}
328288

329-
func (c *Checks) PodDisruptionBudgets() map[string]PodDisruptionBudgetCheck {
289+
func (c *Checks) PodDisruptionBudgets() map[string]GenCheck[ks.PodDisruptionBudget] {
330290
return c.poddisruptionbudgets
331291
}
332292

333-
func (c *Checks) RegisterServiceCheck(name, comment string, fn ServiceCheckFn) {
293+
func (c *Checks) RegisterServiceCheck(name, comment string, fn CheckFunc[corev1.Service]) {
334294
ch := NewCheck(name, "Service", comment, false)
335-
c.registerServiceCheck(ServiceCheck{ch, fn})
295+
c.registerServiceCheck(GenCheck[corev1.Service]{ch, fn})
336296
}
337297

338-
func (c *Checks) RegisterOptionalServiceCheck(name, comment string, fn ServiceCheckFn) {
298+
func (c *Checks) RegisterOptionalServiceCheck(name, comment string, fn CheckFunc[corev1.Service]) {
339299
ch := NewCheck(name, "Service", comment, true)
340-
c.registerServiceCheck(ServiceCheck{ch, fn})
300+
c.registerServiceCheck(GenCheck[corev1.Service]{ch, fn})
341301
}
342302

343-
func (c *Checks) registerServiceCheck(ch ServiceCheck) {
303+
func (c *Checks) registerServiceCheck(ch GenCheck[corev1.Service]) {
344304
c.all = append(c.all, ch.Check)
345305

346306
if !c.isEnabled(ch.Check) {
@@ -349,7 +309,7 @@ func (c *Checks) registerServiceCheck(ch ServiceCheck) {
349309
c.services[machineFriendlyName(ch.Name)] = ch
350310
}
351311

352-
func (c *Checks) Services() map[string]ServiceCheck {
312+
func (c *Checks) Services() map[string]GenCheck[corev1.Service] {
353313
return c.services
354314
}
355315

score/cronjob/cronjob.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ func Register(allChecks *checks.Checks) {
1111
allChecks.RegisterCronJobCheck("CronJob RestartPolicy", `Makes sure CronJobs have a valid RestartPolicy`, cronJobHasRestartPolicy)
1212
}
1313

14-
func cronJobHasDeadline(job ks.CronJob) (score scorecard.TestScore) {
14+
func cronJobHasDeadline(job ks.CronJob) (score scorecard.TestScore, err error) {
1515
if job.StartingDeadlineSeconds() == nil {
1616
score.Grade = scorecard.GradeCritical
1717
score.AddComment("", "The CronJob should have startingDeadlineSeconds configured",
@@ -24,8 +24,7 @@ func cronJobHasDeadline(job ks.CronJob) (score scorecard.TestScore) {
2424
}
2525

2626
// CronJob restartPolicy must be "OnFailure" or "Never". It cannot be empty (unspecified)
27-
func cronJobHasRestartPolicy(job ks.CronJob) (score scorecard.TestScore) {
28-
27+
func cronJobHasRestartPolicy(job ks.CronJob) (score scorecard.TestScore, err error) {
2928
podTmpl := job.GetPodTemplateSpec()
3029
restartPolicy := podTmpl.Spec.RestartPolicy
3130

score/disruptionbudget/disruptionbudget.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func deploymentHas(budgets []ks.PodDisruptionBudget) func(appsv1.Deployment) (sc
8787
}
8888
}
8989

90-
func hasPolicy(pdb ks.PodDisruptionBudget) (score scorecard.TestScore) {
90+
func hasPolicy(pdb ks.PodDisruptionBudget) (score scorecard.TestScore, err error) {
9191
spec := pdb.Spec()
9292
if spec.MinAvailable == nil && spec.MaxUnavailable == nil {
9393
score.AddComment("", "PodDisruptionBudget missing policy", "PodDisruptionBudget should specify minAvailable or maxUnavailable.")

score/hpa/hpa.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ func Register(allChecks *checks.Checks, allTargetableObjs []domain.BothMeta) {
1010
allChecks.RegisterHorizontalPodAutoscalerCheck("HorizontalPodAutoscaler has target", `Makes sure that the HPA targets a valid object`, hpaHasTarget(allTargetableObjs))
1111
}
1212

13-
func hpaHasTarget(allTargetableObjs []domain.BothMeta) func(hpa domain.HpaTargeter) scorecard.TestScore {
14-
return func(hpa domain.HpaTargeter) (score scorecard.TestScore) {
13+
func hpaHasTarget(allTargetableObjs []domain.BothMeta) func(hpa domain.HpaTargeter) (scorecard.TestScore, error) {
14+
return func(hpa domain.HpaTargeter) (score scorecard.TestScore, err error) {
1515
targetRef := hpa.HpaTarget()
1616
var hasTarget bool
1717
for _, t := range allTargetableObjs {

0 commit comments

Comments
 (0)