Skip to content

Commit

Permalink
feat: crossplane health checks
Browse files Browse the repository at this point in the history
  • Loading branch information
adityathebe committed Jun 27, 2024
1 parent 5bf5772 commit dc4ed6d
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 20 deletions.
7 changes: 7 additions & 0 deletions pkg/health/health.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package health

import (
"strings"

"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
)
Expand Down Expand Up @@ -143,6 +145,11 @@ func GetHealthCheckFunc(gvk schema.GroupVersionKind) func(obj *unstructured.Unst
if gvk.Kind == "Node" {
return getNodeHealth
}

if strings.HasSuffix(gvk.Group, ".crossplane.io") || strings.HasSuffix(gvk.Group, ".upbound.io") {
return GetDefaultHealth
}

switch gvk.Group {
case "apps":
switch gvk.Kind {
Expand Down
14 changes: 0 additions & 14 deletions pkg/health/health_cert_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,3 @@ func GetCertificateHealth(obj *unstructured.Unstructured) (*HealthStatus, error)

return status, nil
}

// Certificate:
// conditions:
// Ready:
// ready: true
// health: healthy
// status: Issued
// onFalse:
// status: Issuing
// health: unknown
// reasons:
// ConfigError:
// ready: true
// health: unhealthy
4 changes: 4 additions & 0 deletions pkg/health/health_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ func getHealthStatus(yamlPath string, t *testing.T) *health.HealthStatus {
return health
}

func TestCrossplane(t *testing.T) {
assertAppHealth(t, "./testdata/crossplane.yaml", "Available", health.HealthHealthy, true)
}

func TestNamespace(t *testing.T) {
assertAppHealth(t, "./testdata/namespace.yaml", health.HealthStatusHealthy, health.HealthUnknown, true)
assertAppHealth(t, "./testdata/namespace-terminating.yaml", health.HealthStatusTerminating, health.HealthUnknown, false)
Expand Down
11 changes: 10 additions & 1 deletion pkg/health/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package health

import (
_ "embed"
"strings"

"gopkg.in/yaml.v2"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -181,9 +182,17 @@ type StatusMap struct {
const NoCondition = "none"

func GetDefaultHealth(obj *unstructured.Unstructured) (*HealthStatus, error) {
kind := obj.GetKind()
group := strings.Split(obj.GetAPIVersion(), "/")[0]
if strings.HasSuffix(group, "crossplane.io") || strings.HasSuffix(group, "upbound.io") {
// For crossplane resources, we use a single status mapping under the dummy Kind "crossplane.io"
// that is supposed to cater for all the crossplane kinds.
kind = "crossplane.io"
}

if statusMap, ok := statusByKind[obj.GetAPIVersion()+"/"+obj.GetKind()]; ok {
return GetHealthFromStatus(GetGenericStatus(obj), statusMap)
} else if statusMap, ok := statusByKind[obj.GetKind()]; ok {
} else if statusMap, ok := statusByKind[kind]; ok {
return GetHealthFromStatus(GetGenericStatus(obj), statusMap)
}

Expand Down
41 changes: 36 additions & 5 deletions pkg/health/statusMap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ Certificate:
ConfigError:
ready: true
health: unhealthy

CertificateRequest:
conditions:
InvalidRequest:
Expand All @@ -40,21 +39,20 @@ CertificateRequest:
status: Issuing
Failed:
ready: true

status:
acme:
order:
url: https://acme-v02.api.letsencrypt.org/acme/order/45250083/316944902
conditions:
- lastTransitionTime: "2019-02-15T18:21:10Z"
- lastTransitionTime: '2019-02-15T18:21:10Z'
message: Order validated
reason: OrderValidated
status: "False"
status: 'False'
type: ValidateFailed
- lastTransitionTime: null
message: Certificate issued successfully
reason: CertIssued
status: "True"
status: 'True'
type: Ready

Deployment:
Expand Down Expand Up @@ -180,3 +178,36 @@ source.toolkit.fluxcd.io/v1beta1/Bucket: *flux
image.toolkit.fluxcd.io/v1beta2/ImagePolicy: *flux
image.toolkit.fluxcd.io/v1beta2/ImageRepository: *flux
image.toolkit.fluxcd.io/v1beta2/ImageUpdateAutomation: *flux

# Not an actual kind.
crossplane.io:
conditions:
Ready:
reasons:
Available:
ready: true
health: healthy
Unavailble:
health: unhealthy
ready: true
Creating:
health: unknown
ready: false
Deleting:
health: unhealthy
ready: false
AsyncOperation:
reasons:
Finished:
ready: true
Ongoing:
ready: false
LastAsyncOperation:
Synced:
reasons:
ReconcileSuccess:
ready: true
ReconcileError:
health: unhealthy
ReconcilePaused:
ready: false
49 changes: 49 additions & 0 deletions pkg/health/testdata/crossplane.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
name: xpostgresqlinstances.database.example.org
spec:
group: database.example.org
names:
kind: XPostgreSQLInstance
plural: xpostgresqlinstances
claimNames:
kind: PostgreSQLInstance
plural: postgresqlinstances
versions:
- name: v1alpha1
served: true
referenceable: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
parameters:
type: object
properties:
storageGB:
type: integer
required:
- storageGB
required:
- parameters
status:
conditions:
- type: Ready
reason: Available
status: 'True'
- type: Synced
reason: ReconcileSuccess
status: 'True'
- type: LastAsyncOperation
reason: ApplyFailure
status: 'False'
message: 'apply failed: an existing
`high_availability.0.standby_availability_zone` can only be changed when
exchanged with the zone specified in `zone`: '
- type: AsyncOperation
reason: Finished
status: 'True'

0 comments on commit dc4ed6d

Please sign in to comment.