Skip to content

Commit b227f6b

Browse files
committed
[RFC-0009] Add CEL custom healthchecks
Signed-off-by: Matheus Pimenta <[email protected]>
1 parent 5967686 commit b227f6b

15 files changed

+553
-150
lines changed

api/go.mod

+6-6
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ module github.com/fluxcd/kustomize-controller/api
33
go 1.23.0
44

55
require (
6-
github.com/fluxcd/pkg/apis/kustomize v1.8.0
7-
github.com/fluxcd/pkg/apis/meta v1.9.0
8-
k8s.io/apiextensions-apiserver v0.32.0
9-
k8s.io/apimachinery v0.32.0
6+
github.com/fluxcd/pkg/apis/kustomize v1.9.0
7+
github.com/fluxcd/pkg/apis/meta v1.10.0
8+
k8s.io/apiextensions-apiserver v0.32.1
9+
k8s.io/apimachinery v0.32.1
1010
sigs.k8s.io/controller-runtime v0.19.3
1111
)
1212

@@ -23,8 +23,8 @@ require (
2323
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
2424
github.com/modern-go/reflect2 v1.0.2 // indirect
2525
github.com/x448/float16 v0.8.4 // indirect
26-
golang.org/x/net v0.30.0 // indirect
27-
golang.org/x/text v0.19.0 // indirect
26+
golang.org/x/net v0.34.0 // indirect
27+
golang.org/x/text v0.21.0 // indirect
2828
gopkg.in/inf.v0 v0.9.1 // indirect
2929
k8s.io/klog/v2 v2.130.1 // indirect
3030
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect

api/go.sum

+16-16
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
33
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
44
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
55
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
6-
github.com/fluxcd/pkg/apis/kustomize v1.8.0 h1:HH6YRa3SMS72KK4cUyb9m5sK/dZH+Eti1qhjWDCgwKg=
7-
github.com/fluxcd/pkg/apis/kustomize v1.8.0/go.mod h1:QCKIFj1ocdndaWSkrLs5JKvdGNYyTzQX1ZB3lYTwma0=
8-
github.com/fluxcd/pkg/apis/meta v1.9.0 h1:wPgm7bWNJZ/ImS5GqikOxt362IgLPFBG73dZ27uWRiQ=
9-
github.com/fluxcd/pkg/apis/meta v1.9.0/go.mod h1:pMea8eEZcsFSI7ngRnTHFtDZk2CEZGgtrueNgI6Iu70=
6+
github.com/fluxcd/pkg/apis/kustomize v1.9.0 h1:SJpT1CK58AnTvCpDKeGfMNA0Xud/4VReZNvPe8XkTxo=
7+
github.com/fluxcd/pkg/apis/kustomize v1.9.0/go.mod h1:AZl2GU03oPVue6SUivdiIYd/3mvF94j7t1G2JO26d4s=
8+
github.com/fluxcd/pkg/apis/meta v1.10.0 h1:rqbAuyl5ug7A5jjRf/rNwBXmNl6tJ9wG2iIsriwnQUk=
9+
github.com/fluxcd/pkg/apis/meta v1.10.0/go.mod h1:n7NstXHDaleAUMajcXTVkhz0MYkvEXy1C/eLI/t1xoI=
1010
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
1111
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
1212
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
@@ -65,20 +65,20 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
6565
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
6666
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
6767
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
68-
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
69-
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
68+
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
69+
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
7070
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
7171
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
7272
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
7373
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
7474
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
7575
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
76-
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
77-
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
76+
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
77+
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
7878
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
7979
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
80-
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
81-
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
80+
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
81+
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
8282
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
8383
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
8484
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
@@ -96,12 +96,12 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
9696
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
9797
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
9898
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
99-
k8s.io/api v0.32.0 h1:OL9JpbvAU5ny9ga2fb24X8H6xQlVp+aJMFlgtQjR9CE=
100-
k8s.io/api v0.32.0/go.mod h1:4LEwHZEf6Q/cG96F3dqR965sYOfmPM7rq81BLgsE0p0=
101-
k8s.io/apiextensions-apiserver v0.32.0 h1:S0Xlqt51qzzqjKPxfgX1xh4HBZE+p8KKBq+k2SWNOE0=
102-
k8s.io/apiextensions-apiserver v0.32.0/go.mod h1:86hblMvN5yxMvZrZFX2OhIHAuFIMJIZ19bTvzkP+Fmw=
103-
k8s.io/apimachinery v0.32.0 h1:cFSE7N3rmEEtv4ei5X6DaJPHHX0C+upp+v5lVPiEwpg=
104-
k8s.io/apimachinery v0.32.0/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
99+
k8s.io/api v0.32.1 h1:f562zw9cy+GvXzXf0CKlVQ7yHJVYzLfL6JAS4kOAaOc=
100+
k8s.io/api v0.32.1/go.mod h1:/Yi/BqkuueW1BgpoePYBRdDYfjPF5sgTr5+YqDZra5k=
101+
k8s.io/apiextensions-apiserver v0.32.1 h1:hjkALhRUeCariC8DiVmb5jj0VjIc1N0DREP32+6UXZw=
102+
k8s.io/apiextensions-apiserver v0.32.1/go.mod h1:sxWIGuGiYov7Io1fAS2X06NjMIk5CbRHc2StSmbaQto=
103+
k8s.io/apimachinery v0.32.1 h1:683ENpaCBjma4CYqsmZyhEzrGz6cjn1MY/X2jB2hkZs=
104+
k8s.io/apimachinery v0.32.1/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
105105
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
106106
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
107107
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro=

api/v1/kustomization_types.go

+5
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,11 @@ type KustomizationSpec struct {
179179
// Components specifies relative paths to specifications of other Components.
180180
// +optional
181181
Components []string `json:"components,omitempty"`
182+
183+
// HealthCheckExprs is a list of healthcheck expressions for evaluating the
184+
// health of custom resources using Common Expression Language (CEL).
185+
// +optional
186+
HealthCheckExprs []kustomize.CustomHealthCheck `json:"healthCheckExprs,omitempty"`
182187
}
183188

184189
// CommonMetadata defines the common labels and annotations.

api/v1/zz_generated.deepcopy.go

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/kustomize.toolkit.fluxcd.io_kustomizations.yaml

+35
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,41 @@ spec:
136136
Force instructs the controller to recreate resources
137137
when patching fails due to an immutable field change.
138138
type: boolean
139+
healthCheckExprs:
140+
description: |-
141+
HealthCheckExprs is a list of healthcheck expressions for evaluating the
142+
health of custom resources using Common Expression Language (CEL).
143+
items:
144+
description: CustomHealthCheck defines the health check for custom
145+
resources.
146+
properties:
147+
apiVersion:
148+
description: APIVersion of the custom resource under evaluation.
149+
type: string
150+
current:
151+
description: |-
152+
Current is the CEL expression that determines if the status
153+
of the custom resource has reached the desired state.
154+
type: string
155+
failed:
156+
description: |-
157+
Failed is the CEL expression that determines if the status
158+
of the custom resource has failed to reach the desired state.
159+
type: string
160+
inProgress:
161+
description: |-
162+
InProgress is the CEL expression that determines if the status
163+
of the custom resource has not yet reached the desired state.
164+
type: string
165+
kind:
166+
description: Kind of the custom resource under evaluation.
167+
type: string
168+
required:
169+
- apiVersion
170+
- current
171+
- kind
172+
type: object
173+
type: array
139174
healthChecks:
140175
description: A list of resources to be included in the health assessment.
141176
items:

docs/api/v1/kustomize.md

+30
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,21 @@ resources. When enabled, the HealthChecks are ignored. Defaults to false.</p>
395395
<p>Components specifies relative paths to specifications of other Components.</p>
396396
</td>
397397
</tr>
398+
<tr>
399+
<td>
400+
<code>healthCheckExprs</code><br>
401+
<em>
402+
<a href="https://godoc.org/github.com/fluxcd/pkg/apis/kustomize#CustomHealthCheck">
403+
[]github.com/fluxcd/pkg/apis/kustomize.CustomHealthCheck
404+
</a>
405+
</em>
406+
</td>
407+
<td>
408+
<em>(Optional)</em>
409+
<p>HealthCheckExprs is a list of healthcheck expressions for evaluating the
410+
health of custom resources using Common Expression Language (CEL).</p>
411+
</td>
412+
</tr>
398413
</table>
399414
</td>
400415
</tr>
@@ -918,6 +933,21 @@ resources. When enabled, the HealthChecks are ignored. Defaults to false.</p>
918933
<p>Components specifies relative paths to specifications of other Components.</p>
919934
</td>
920935
</tr>
936+
<tr>
937+
<td>
938+
<code>healthCheckExprs</code><br>
939+
<em>
940+
<a href="https://godoc.org/github.com/fluxcd/pkg/apis/kustomize#CustomHealthCheck">
941+
[]github.com/fluxcd/pkg/apis/kustomize.CustomHealthCheck
942+
</a>
943+
</em>
944+
</td>
945+
<td>
946+
<em>(Optional)</em>
947+
<p>HealthCheckExprs is a list of healthcheck expressions for evaluating the
948+
health of custom resources using Common Expression Language (CEL).</p>
949+
</td>
950+
</tr>
921951
</tbody>
922952
</table>
923953
</div>

docs/spec/v1/kustomizations.md

+61
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,67 @@ spec:
339339
If all the HelmRelease objects are successfully installed or upgraded, then
340340
the Kustomization will be marked as ready.
341341

342+
### Health check expressions
343+
344+
`.spec.healthCheckExprs` can be used to define custom logic for performing
345+
health checks on custom resources. This is done through Common Expression
346+
Language (CEL) expressions. This field accepts a list of objects with the
347+
following fields:
348+
349+
- `apiVersion`: The API version of the custom resource. Required.
350+
- `kind`: The kind of the custom resource. Required.
351+
- `current`: A required CEL expression that returns `true` if the resource is ready.
352+
- `inProgress`: An optional CEL expression that returns `true` if the resource
353+
is still being reconciled.
354+
- `failed`: An optional CEL expression that returns `true` if the resource
355+
failed to reconcile.
356+
357+
The controller will evaluate the expressions in the following order:
358+
359+
1. `inProgress` if specified
360+
2. `failed` if specified
361+
3. `current`
362+
363+
The first expression that evaluates to `true` will determine the health
364+
status of the custom resource.
365+
366+
For example, to define a set of health check expressions for the `SealedSecret`
367+
custom resource:
368+
369+
```yaml
370+
apiVersion: kustomize.toolkit.fluxcd.io/v1
371+
kind: Kustomization
372+
metadata:
373+
name: sealed-secrets
374+
namespace: flux-system
375+
spec:
376+
interval: 5m
377+
path: ./path/to/sealed/secrets
378+
prune: true
379+
sourceRef:
380+
kind: GitRepository
381+
name: flux-system
382+
timeout: 1m
383+
wait: true # Tells the controller to wait for all resources to be ready by performing health checks.
384+
healthCheckExprs:
385+
- apiVersion: bitnami.com/v1alpha1
386+
kind: SealedSecret
387+
inProgress: has(status.observedGeneration) && status.observedGeneration != metadata.generation
388+
failed: status.conditions.filter(e, e.type == 'Synced').all(e, e.status == 'False')
389+
current: status.conditions.filter(e, e.type == 'Synced').all(e, e.status == 'True')
390+
```
391+
392+
A common error is writing expressions that reference fields that do not
393+
exist in the custom resource. This will cause the controller to wait
394+
for the resource to be ready until the timeout is reached. To avoid this,
395+
make sure your CEL expressions are correct. The
396+
[CEL Playground](https://playcel.undistro.io/) is a useful resource for
397+
this task. The input passed to each expression is the custom resource
398+
object itself.
399+
400+
It's worth checking if [the library](/flux/cheatsheets/cel-healthchecks/)
401+
has expressions for the custom resources you are using.
402+
342403
### Wait
343404

344405
`.spec.wait` is an optional boolean field to perform health checks for __all__

0 commit comments

Comments
 (0)