Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: crossplane health #77

Merged
merged 1 commit into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions pkg/health/health_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ import (
"sigs.k8s.io/yaml"
)

func assertAppHealthMsg(t *testing.T, yamlPath string, expectedStatus health.HealthStatusCode, expectedHealth health.Health, expectedReady bool, expectedMsg string) {
health := getHealthStatus(yamlPath, t, nil)
assert.NotNil(t, health)
assert.Equal(t, expectedHealth, health.Health)
assert.Equal(t, expectedReady, health.Ready)
assert.Equal(t, expectedStatus, health.Status)
assert.Equal(t, expectedMsg, health.Message)
}

func assertAppHealth(t *testing.T, yamlPath string, expectedStatus health.HealthStatusCode, expectedHealth health.Health, expectedReady bool) {
health := getHealthStatus(yamlPath, t, nil)
assert.NotNil(t, health)
Expand Down Expand Up @@ -62,8 +71,11 @@ func getHealthStatus(yamlPath string, t *testing.T, overwrites map[string]string
}

func TestCrossplane(t *testing.T) {
assertAppHealth(t, "./testdata/crossplane.yaml", "ApplyFailure", health.HealthWarning, true)
assertAppHealth(t, "./testdata/crossplane-healthy.yaml", "Success", health.HealthHealthy, true)
assertAppHealthMsg(t, "./testdata/crossplane-apply-failure.yaml", "ApplyFailure", health.HealthWarning, true, "apply failed: an existing `high_availability.0.standby_availability_zone` can only be changed when exchanged with the zone specified in `zone`: ")
assertAppHealthMsg(t, "./testdata/crossplane-healthy.yaml", "ReconcileSuccess", health.HealthHealthy, true, "")
assertAppHealthMsg(t, "./testdata/crossplane-installed.yaml", "ActivePackageRevision", health.HealthHealthy, true, "")
assertAppHealthMsg(t, "./testdata/crossplane-provider-revision.yaml", "HealthyPackageRevision", health.HealthHealthy, true, "")
assertAppHealthMsg(t, "./testdata/crossplane-reconcile-error.yaml", "ReconcileError", health.HealthUnhealthy, true, "observe failed: cannot run plan: plan failed: Instance cannot be destroyed: Resource azurerm_kubernetes_cluster_node_pool.prodeu01 has lifecycle.prevent_destroy set, but the plan calls for this resource to be destroyed. To avoid this error and continue with the plan, either disable lifecycle.prevent_destroy or reduce the scope of the plan using the -target flag.")
}

func TestNamespace(t *testing.T) {
Expand Down
4 changes: 3 additions & 1 deletion pkg/health/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,13 @@ func (mapped *OnCondition) Apply(health *HealthStatus, c *metav1.Condition) {
if mapped.Status != "" {
if health.Status == "" || mapped.Order >= health.order {
health.Status = mapped.Status
health.order = mapped.Order
}
} else if c.Reason != "" {
if health.Status == "" || mapped.Order >= health.order {
health.Status = HealthStatusCode(c.Reason)
health.order = mapped.Order
}

}

if mapped.Message && c.Message != "" {
Expand Down Expand Up @@ -170,6 +171,7 @@ func (mapped *Condition) Apply(health *HealthStatus, c *metav1.Condition) {
} else if c.Status == metav1.ConditionUnknown && mapped.OnUnknown != nil {
mapped.OnUnknown.Apply(health, c)
}

if reason, ok := mapped.Reasons[c.Reason]; ok {
reason.Apply(health, c)
}
Expand Down
25 changes: 23 additions & 2 deletions pkg/health/statusMap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,20 @@ image.toolkit.fluxcd.io/v1beta2/ImageUpdateAutomation: *flux
# Not an actual kind.
crossplane.io:
conditions:
Healthy:
reasons:
HealthyPackageRevision:
health: healthy
message: true
ready: true
Installed:
reasons:
ActivePackageRevision:
health: healthy
message: true
ready: true
Ready:
order: 2
reasons:
Available:
ready: true
Expand All @@ -197,7 +210,7 @@ crossplane.io:
health: unknown
ready: false
AsyncOperation:
order: -1
order: 1
reasons:
Finished:
order: -1
Expand All @@ -207,14 +220,22 @@ crossplane.io:
order: -1
ready: false
LastAsyncOperation:
order: 3
onFalse:
ready: false
order: 5
message: true
health: warning
Synced:
order: 4
reasons:
ReconcileSuccess:
ready: true
ReconcileError:
health: unhealthy
message: true
ReconcilePaused:
ready: false
onFalse:
order: 6
message: true
health: warning
28 changes: 28 additions & 0 deletions pkg/health/testdata/crossplane-installed.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
uid: a84bcf77-4abc-4798-8e99-76c75964424f
name: provider-azure-authorization
labels:
kustomize.toolkit.fluxcd.io/name: common
kustomize.toolkit.fluxcd.io/namespace: flux-system
creationTimestamp: 2023-11-12T15:50:07Z
spec:
package: xpkg.upbound.io/upbound/provider-azure-authorization:v0.38.2
packagePullPolicy: IfNotPresent
controllerConfigRef:
name: provider-azure-family-config
revisionHistoryLimit: 1
revisionActivationPolicy: Automatic
skipDependencyResolution: false
ignoreCrossplaneConstraints: false
status:
conditions:
- type: Healthy
reason: HealthyPackageRevision
status: "True"
- type: Installed
reason: ActivePackageRevision
status: "True"
currentRevision: provider-azure-authorization-29b8a8ac7b22
currentIdentifier: xpkg.upbound.io/upbound/provider-azure-authorization:v0.38.2
58 changes: 58 additions & 0 deletions pkg/health/testdata/crossplane-provider-revision.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
apiVersion: pkg.crossplane.io/v1
kind: ProviderRevision
metadata:
uid: b42bf5da-9dad-4082-a682-46de82bc996e
name: provider-azure-authorization-29b8a8ac7b22
labels:
pkg.crossplane.io/package: provider-azure-authorization
pkg.crossplane.io/provider-family: provider-family-azure
finalizers:
- revision.pkg.crossplane.io
annotations:
auth.upbound.io/group: azure.upbound.io
meta.crossplane.io/readme: >
Provider Azure is a Crossplane provider for [Microsoft
Azure](https://azure.microsoft.com)

developed and supported by Upbound.

Available resources and their fields can be found in the [Upbound

Marketplace](https://marketplace.upbound.io/providers/upbound/provider-azure).

If you encounter an issue please reach out on [email protected] email

address. This is a subpackage for the authorization API group.
meta.crossplane.io/source: github.com/upbound/provider-azure
meta.crossplane.io/maintainer: Upbound <[email protected]>
meta.crossplane.io/description: |
Upbound's official Crossplane provider to manage Microsoft Azure
authorization services in Kubernetes.
friendly-name.meta.crossplane.io: Provider Azure (authorization)
ownerReferences:
- uid: a84bcf77-4abc-4798-8e99-76c75964424f
kind: Provider
name: provider-azure-authorization
apiVersion: pkg.crossplane.io/v1
controller: true
blockOwnerDeletion: true
creationTimestamp: 2023-11-12T15:50:08Z
spec:
image: xpkg.upbound.io/upbound/provider-azure-authorization:v0.38.2
revision: 1
desiredState: Active
packagePullPolicy: IfNotPresent
controllerConfigRef:
name: provider-azure-family-config
webhookTLSSecretName: webhook-tls-secret
skipDependencyResolution: false
ignoreCrossplaneConstraints: false
status:
conditions:
- type: Healthy
reason: HealthyPackageRevision
status: "True"
controllerRef:
name: provider-azure-authorization-29b8a8ac7b22
foundDependencies: 1
installedDependencies: 1
101 changes: 101 additions & 0 deletions pkg/health/testdata/crossplane-reconcile-error.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
apiVersion: containerservice.azure.upbound.io/v1beta1
kind: KubernetesClusterNodePool
metadata:
uid: 8680aee9-b7ed-4ccf-b29b-b9088fd1a686
name: prodeu01
labels:
kustomize.toolkit.fluxcd.io/name: workload-prod-az-eu-01
kustomize.toolkit.fluxcd.io/namespace: flux-system
finalizers:
- finalizer.managedresource.crossplane.io
annotations:
crossplane.io/external-name: prodeu01
upjet.crossplane.io/provider-meta: '{"e2bfb730-ecaa-11e6-8f88-34363bc7c4c0":{"create":3600000000000,"delete":3600000000000,"read":300000000000,"update":3600000000000},"schema_version":"1"}'
crossplane.io/external-create-pending: 2024-05-23T08:47:21Z
crossplane.io/external-create-succeeded: 2024-05-23T08:47:21Z
creationTimestamp: 2024-05-23T08:15:32Z
spec:
forProvider:
mode: User
osSku: Ubuntu
osType: Linux
vmSize: Standard_D8as_v5
maxPods: 250
maxCount: 0
minCount: 0
priority: Regular
nodeCount: 0
osDiskType: Ephemeral
podSubnetId: /subscriptions/0cd017bb-aa54-4611-b21f-ecf8daee0511/resourceGroups/crossplane/providers/Microsoft.Network/virtualNetworks/workload-prod-az-eu-01/subnets/workload-prod-az-eu-01-pods
osDiskSizeGb: 128
spotMaxPrice: -1
vnetSubnetId: /subscriptions/0cd017bb-aa54-4611-b21f-ecf8daee0511/resourceGroups/crossplane/providers/Microsoft.Network/virtualNetworks/workload-prod-az-eu-01/subnets/workload-prod-az-eu-01-nodes
scaleDownMode: Delete
podSubnetIdRef:
name: workload-prod-az-eu-01-pods
kubeletDiskType: OS
vnetSubnetIdRef:
name: workload-prod-az-eu-01-nodes
enableAutoScaling: true
kubernetesClusterId: /subscriptions/0cd017bb-aa54-4611-b21f-ecf8daee0511/resourceGroups/crossplane/providers/Microsoft.ContainerService/managedClusters/workload-prod-eu-01
orchestratorVersion: 1.27.9
kubernetesClusterIdRef:
name: workload-prod-eu-01
initProvider: {}
deletionPolicy: Delete
providerConfigRef:
name: azure-north-europe
managementPolicies:
- '*'
status:
atProvider:
id: /subscriptions/0cd017bb-aa54-4611-b21f-ecf8daee0511/resourceGroups/crossplane/providers/Microsoft.ContainerService/managedClusters/workload-prod-eu-01/agentPools/prodeu01
mode: User
osSku: Ubuntu
osType: Linux
vmSize: Standard_D4s_v5
maxPods: 250
maxCount: 4
minCount: 0
priority: Regular
nodeCount: 1
osDiskType: Managed
fipsEnabled: false
hostGroupId: ''
podSubnetId: /subscriptions/0cd017bb-aa54-4611-b21f-ecf8daee0511/resourceGroups/crossplane/providers/Microsoft.Network/virtualNetworks/workload-prod-az-eu-01/subnets/workload-prod-az-eu-01-pods
osDiskSizeGb: 128
spotMaxPrice: -1
vnetSubnetId: /subscriptions/0cd017bb-aa54-4611-b21f-ecf8daee0511/resourceGroups/crossplane/providers/Microsoft.Network/virtualNetworks/workload-prod-az-eu-01/subnets/workload-prod-az-eu-01-nodes
scaleDownMode: Delete
evictionPolicy: ''
kubeletDiskType: OS
messageOfTheDay: ''
ultraSsdEnabled: false
enableAutoScaling: true
enableNodePublicIp: false
kubernetesClusterId: /subscriptions/0cd017bb-aa54-4611-b21f-ecf8daee0511/resourceGroups/crossplane/providers/Microsoft.ContainerService/managedClusters/workload-prod-eu-01
orchestratorVersion: 1.27.9
customCaTrustEnabled: false
enableHostEncryption: false
nodePublicIpPrefixId: ''
proximityPlacementGroupId: ''
capacityReservationGroupId: ''
conditions:
- type: Ready
reason: Available
status: 'True'
- type: Synced
reason: ReconcileError
status: 'False'
message: 'observe failed: cannot run plan: plan failed: Instance cannot be
destroyed: Resource azurerm_kubernetes_cluster_node_pool.prodeu01 has
lifecycle.prevent_destroy set, but the plan calls for this resource to
be destroyed. To avoid this error and continue with the plan, either
disable lifecycle.prevent_destroy or reduce the scope of the plan using
the -target flag.'
- type: LastAsyncOperation
reason: Success
status: 'True'
- type: AsyncOperation
reason: Finished
status: 'True'
Loading