-
Notifications
You must be signed in to change notification settings - Fork 13
HYPERFLEET-999 - refactor: standardize adapter conditions for deletions #40
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,6 +31,8 @@ preconditions: | |
| field: "generation" | ||
| - name: "timestamp" | ||
| field: "created_time" | ||
| - name: "is_deleting" | ||
| expression: "clusterStatus.?deleted_time.hasValue()" | ||
| - name: "readyConditionStatus" | ||
| expression: | | ||
| status.conditions.filter(c, c.type == "Ready").size() > 0 | ||
|
|
@@ -39,16 +41,11 @@ preconditions: | |
| - name: "placementClusterName" | ||
| expression: "\"cluster1\"" # TBC coming from placement adapter | ||
|
|
||
| # Structured conditions with valid operators | ||
| conditions: | ||
| - field: "readyConditionStatus" | ||
| operator: "equals" | ||
| value: "False" | ||
|
|
||
| - name: "validationCheck" | ||
| # Valid CEL expression | ||
| # Precondition passes if cluster is NOT Ready (readyConditionStatus == "False") OR if cluster is being deleted | ||
| # Note: Unlike adapter1/adapter3, this adapter does not implement self-healing TTL checks | ||
| expression: | | ||
| readyConditionStatus == "False" | ||
| readyConditionStatus == "False" || is_deleting | ||
|
|
||
| # Resources with valid K8s manifests | ||
| resources: | ||
|
|
@@ -208,6 +205,15 @@ resources: | |
| discovery: | ||
| by_name: "{{ .clusterId | lower }}-{{ .adapter.name }}-configmap" | ||
|
|
||
| # Deletion lifecycle - ManifestWork deletion cascades to nested resources | ||
| lifecycle: | ||
| delete: | ||
| # Foreground propagation ensures nested resources (namespace, configmap) are deleted | ||
| # before the parent ManifestWork is removed, preventing orphaned resources | ||
| propagationPolicy: "Foreground" | ||
| when: | ||
| expression: "is_deleting" | ||
|
|
||
| post: | ||
| payloads: | ||
| - name: "statusPayload" | ||
|
|
@@ -218,47 +224,75 @@ post: | |
| - type: "Applied" | ||
| status: | ||
| expression: | | ||
| has(resources.resource0) && has(resources.resource0.status) && has(resources.resource0.status.conditions) && resources.resource0.status.conditions.filter(c, has(c.type) && c.type == "Applied").size() > 0 ? resources.resource0.status.conditions.filter(c, c.type == "Applied")[0].status : "False" | ||
| !is_deleting | ||
| ? (resources.?resource0.hasValue() && has(resources.resource0.status) && has(resources.resource0.status.conditions) && resources.resource0.status.conditions.filter(c, has(c.type) && c.type == "Applied").size() > 0 ? resources.resource0.status.conditions.filter(c, c.type == "Applied")[0].status : "False") | ||
| : "False" | ||
| reason: | ||
| expression: | | ||
| has(resources.resource0) && has(resources.resource0.status) && has(resources.resource0.status.conditions) && resources.resource0.status.conditions.filter(c, has(c.type) && c.type == "Applied").size() > 0 ? resources.resource0.status.conditions.filter(c, c.type == "Applied")[0].reason : "ManifestWorkNotDiscovered" | ||
| !is_deleting | ||
| ? (resources.?resource0.hasValue() && has(resources.resource0.status) && has(resources.resource0.status.conditions) && resources.resource0.status.conditions.filter(c, has(c.type) && c.type == "Applied").size() > 0 ? resources.resource0.status.conditions.filter(c, c.type == "Applied")[0].reason : "ManifestWorkNotDiscovered") | ||
| : (!resources.?resource0.hasValue() | ||
| ? "ResourceDeleted" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tip nit — non-blocking suggestion Category: Inconsistency During deletion, adapter2 reports granular reasons for Applied/Available ( If you keep the |
||
| : (adapter.?executionStatus.orValue("") == "failed" | ||
| ? "DeletionFailed" | ||
| : "DeletionInProgress")) | ||
| message: | ||
| expression: | | ||
| has(resources.resource0) && has(resources.resource0.status) && has(resources.resource0.status.conditions) && resources.resource0.status.conditions.filter(c, has(c.type) && c.type == "Applied").size() > 0 ? resources.resource0.status.conditions.filter(c, c.type == "Applied")[0].message : "ManifestWork not discovered from Maestro or no Applied condition" | ||
| !is_deleting | ||
| ? (resources.?resource0.hasValue() && has(resources.resource0.status) && has(resources.resource0.status.conditions) && resources.resource0.status.conditions.filter(c, has(c.type) && c.type == "Applied").size() > 0 ? resources.resource0.status.conditions.filter(c, c.type == "Applied")[0].message : "ManifestWork not discovered from Maestro or no Applied condition") | ||
| : (!resources.?resource0.hasValue() | ||
| ? "ManifestWork deleted" | ||
| : (adapter.?executionStatus.orValue("") == "failed" | ||
| ? "Deletion failed during adapter execution" | ||
| : "ManifestWork deletion in progress")) | ||
|
|
||
| # Available: Check if nested discovered manifests are available on the spoke cluster | ||
| # Each nested discovery is enriched with top-level "conditions" from status.resourceStatus.manifests[] | ||
| - type: "Available" | ||
| status: | ||
| expression: | | ||
| has(resources.namespace0) && has(resources.namespace0.conditions) | ||
| && resources.namespace0.conditions.exists(c, has(c.type) && c.type == "Available" && has(c.status) && c.status == "True") | ||
| && has(resources.configmap0) && has(resources.configmap0.conditions) | ||
| && resources.configmap0.conditions.exists(c, has(c.type) && c.type == "Available" && has(c.status) && c.status == "True") | ||
| ? "True" | ||
| : "False" | ||
| !is_deleting | ||
| ? (resources.?namespace0.hasValue() && has(resources.namespace0.conditions) | ||
| && resources.namespace0.conditions.exists(c, has(c.type) && c.type == "Available" && has(c.status) && c.status == "True") | ||
| && resources.?configmap0.hasValue() && has(resources.configmap0.conditions) | ||
| && resources.configmap0.conditions.exists(c, has(c.type) && c.type == "Available" && has(c.status) && c.status == "True") | ||
| ? "True" | ||
| : "False") | ||
| : "False" | ||
| reason: | ||
| expression: | | ||
| !(has(resources.namespace0) && has(resources.namespace0.conditions)) | ||
| ? "NamespaceNotDiscovered" | ||
| : !resources.namespace0.conditions.exists(c, has(c.type) && c.type == "Available" && has(c.status) && c.status == "True") | ||
| ? "NamespaceNotAvailable" | ||
| : !(has(resources.configmap0) && has(resources.configmap0.conditions)) | ||
| ? "ConfigMapNotDiscovered" | ||
| : !resources.configmap0.conditions.exists(c, has(c.type) && c.type == "Available" && has(c.status) && c.status == "True") | ||
| ? "ConfigMapNotAvailable" | ||
| : "AllResourcesAvailable" | ||
| !is_deleting | ||
| ? (!(resources.?namespace0.hasValue() && has(resources.namespace0.conditions)) | ||
| ? "NamespaceNotDiscovered" | ||
| : !resources.namespace0.conditions.exists(c, has(c.type) && c.type == "Available" && has(c.status) && c.status == "True") | ||
| ? "NamespaceNotAvailable" | ||
| : !(resources.?configmap0.hasValue() && has(resources.configmap0.conditions)) | ||
| ? "ConfigMapNotDiscovered" | ||
| : !resources.configmap0.conditions.exists(c, has(c.type) && c.type == "Available" && has(c.status) && c.status == "True") | ||
| ? "ConfigMapNotAvailable" | ||
| : "AllResourcesAvailable") | ||
| : (!resources.?namespace0.hasValue() && !resources.?configmap0.hasValue() | ||
| ? "ResourceDeleted" | ||
| : (adapter.?executionStatus.orValue("") == "failed" | ||
| ? "DeletionFailed" | ||
| : "DeletionInProgress")) | ||
| message: | ||
| expression: | | ||
| !(has(resources.namespace0) && has(resources.namespace0.conditions)) | ||
| ? "Namespace not discovered from ManifestWork" | ||
| : !resources.namespace0.conditions.exists(c, has(c.type) && c.type == "Available" && has(c.status) && c.status == "True") | ||
| ? "Namespace not yet available on spoke cluster" | ||
| : !(has(resources.configmap0) && has(resources.configmap0.conditions)) | ||
| ? "ConfigMap not discovered from ManifestWork" | ||
| : !resources.configmap0.conditions.exists(c, has(c.type) && c.type == "Available" && has(c.status) && c.status == "True") | ||
| ? "ConfigMap not yet available on spoke cluster" | ||
| : "All manifests (namespace, configmap) are available on spoke cluster" | ||
| !is_deleting | ||
| ? (!(resources.?namespace0.hasValue() && has(resources.namespace0.conditions)) | ||
| ? "Namespace not discovered from ManifestWork" | ||
| : !resources.namespace0.conditions.exists(c, has(c.type) && c.type == "Available" && has(c.status) && c.status == "True") | ||
| ? "Namespace not yet available on spoke cluster" | ||
| : !(resources.?configmap0.hasValue() && has(resources.configmap0.conditions)) | ||
| ? "ConfigMap not discovered from ManifestWork" | ||
| : !resources.configmap0.conditions.exists(c, has(c.type) && c.type == "Available" && has(c.status) && c.status == "True") | ||
| ? "ConfigMap not yet available on spoke cluster" | ||
| : "All manifests (namespace, configmap) are available on spoke cluster") | ||
| : (!resources.?namespace0.hasValue() && !resources.?configmap0.hasValue() | ||
| ? "Nested resources deleted" | ||
| : (adapter.?executionStatus.orValue("") == "failed" | ||
| ? "Deletion failed during adapter execution" | ||
| : "Nested resource deletion in progress")) | ||
|
|
||
| # Health: Adapter execution status — surfaces errors from any phase | ||
| - type: "Health" | ||
|
|
@@ -288,6 +322,40 @@ post: | |
| ? "Resources skipped: " + adapter.?skipReason.orValue("unknown reason") | ||
| : "Adapter execution completed successfully" | ||
|
|
||
| # Finalized: Deletion lifecycle completion | ||
| - type: "Finalized" | ||
| status: | ||
| expression: | | ||
| !is_deleting | ||
| ? "False" | ||
| : (!resources.?resource0.hasValue() | ||
| && !resources.?namespace0.hasValue() | ||
| && !resources.?configmap0.hasValue() | ||
| ? "True" | ||
| : "False") | ||
| reason: | ||
| expression: | | ||
| !is_deleting | ||
| ? "ResourceActive" | ||
| : (!resources.?resource0.hasValue() | ||
| && !resources.?namespace0.hasValue() | ||
| && !resources.?configmap0.hasValue() | ||
| ? "CleanupConfirmed" | ||
| : (adapter.?executionStatus.orValue("") == "failed" | ||
| ? "CleanupFailed" | ||
| : "CleanupInProgress")) | ||
| message: | ||
| expression: | | ||
| !is_deleting | ||
| ? "Resource is active, not scheduled for deletion" | ||
| : (!resources.?resource0.hasValue() | ||
| && !resources.?namespace0.hasValue() | ||
| && !resources.?configmap0.hasValue() | ||
| ? "ManifestWork and all nested resources deleted successfully" | ||
| : (adapter.?executionStatus.orValue("") == "failed" | ||
| ? "Deletion failed during adapter execution" | ||
| : "Deletion in progress")) | ||
|
|
||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| observed_generation: | ||
| expression: "generation" | ||
| observed_time: "{{ now | date \"2006-01-02T15:04:05Z07:00\" }}" | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Being in deletion phase is not a direct indication of
Appliednot beingTrueThe natural condition is still the resource being found in the discovery phase IMO
It wold be the same for reason and the
Availablecondition values