From 57c8f779d8d08757c16960f686cf533763fc4eb5 Mon Sep 17 00:00:00 2001 From: dawang Date: Thu, 12 Mar 2026 18:04:55 +0800 Subject: [PATCH 1/2] HYPERFLEET-707 - doc: update adapter configs to add time-based precondition for resource deletion recovery --- .../cl-deployment/adapter-task-config.yaml | 26 +++++++++++++------ .../cl-job/adapter-task-config.yaml | 25 +++++++++++------- .../cl-namespace/adapter-task-config.yaml | 25 +++++++++++------- .../np-configmap/adapter-task-config.yaml | 26 +++++++++++++------ 4 files changed, 66 insertions(+), 36 deletions(-) diff --git a/testdata/adapter-configs/cl-deployment/adapter-task-config.yaml b/testdata/adapter-configs/cl-deployment/adapter-task-config.yaml index 87a4af4..e9bdbfb 100644 --- a/testdata/adapter-configs/cl-deployment/adapter-task-config.yaml +++ b/testdata/adapter-configs/cl-deployment/adapter-task-config.yaml @@ -14,6 +14,11 @@ spec: source: "event.id" type: "string" required: true + - name: "TTL_EXPIRY_THRESHOLD" + source: "env.TTL_EXPIRY_THRESHOLD" + type: "int" + required: false + default: 300 # Preconditions with valid operators and CEL expressions preconditions: @@ -29,16 +34,21 @@ spec: field: "name" - name: "generationSpec" field: "generation" - - name: "readyConditionStatus" + - name: "readyCondition" expression: | status.conditions.filter(c, c.type == "Ready").size() > 0 - ? status.conditions.filter(c, c.type == "Ready")[0].status - : "False" - # Structured conditions with valid operators - conditions: - - field: "readyConditionStatus" - operator: "equals" - value: "False" + ? status.conditions.filter(c, c.type == "Ready")[0] + : null + # Capture current time as a fixed timestamp for consistent time comparisons + # Using `now()` directly in multiple expressions would return different values + - name: "currentTime" + expression: "now()" + + - name: "validationCheck" + # Precondition passes if cluster is NOT Ready OR if cluster is Ready and stable for >TTL_EXPIRY_THRESHOLD seconds since last transition (enables self-healing) + expression: | + readyCondition == null || readyCondition.status != "True" || + (timestamp(currentTime) - timestamp(readyCondition.last_transition_time)).getSeconds() >= TTL_EXPIRY_THRESHOLD - name: "clusterAdapterStatus" apiCall: diff --git a/testdata/adapter-configs/cl-job/adapter-task-config.yaml b/testdata/adapter-configs/cl-job/adapter-task-config.yaml index a61db32..c832399 100644 --- a/testdata/adapter-configs/cl-job/adapter-task-config.yaml +++ b/testdata/adapter-configs/cl-job/adapter-task-config.yaml @@ -18,6 +18,11 @@ spec: source: "env.JOB_SLEEP_DURATION" type: "string" default: "15" + - name: "TTL_EXPIRY_THRESHOLD" + source: "env.TTL_EXPIRY_THRESHOLD" + type: "int" + required: false + default: 300 # Preconditions with valid operators and CEL expressions preconditions: @@ -36,21 +41,21 @@ spec: - name: "simulateResult" # possible values: success (default), failure, hang, crash, invalid-json, missing-status field: "simulateResult" default: "success" - - name: "readyConditionStatus" + - name: "readyCondition" expression: | status.conditions.filter(c, c.type == "Ready").size() > 0 - ? status.conditions.filter(c, c.type == "Ready")[0].status - : "False" - # Structured conditions with valid operators - conditions: - - field: "readyConditionStatus" - operator: "equals" - value: "False" + ? status.conditions.filter(c, c.type == "Ready")[0] + : null + # Capture current time as a fixed timestamp for consistent time comparisons + # Using `now()` directly in multiple expressions would return different values + - name: "currentTime" + expression: "now()" - name: "validationCheck" - # Valid CEL expression + # Precondition passes if cluster is NOT Ready OR if cluster is Ready and stable for >TTL_EXPIRY_THRESHOLD seconds since last transition (enables self-healing) expression: | - readyConditionStatus == "False" + readyCondition == null || readyCondition.status != "True" || + (timestamp(currentTime) - timestamp(readyCondition.last_transition_time)).getSeconds() >= TTL_EXPIRY_THRESHOLD - name: "clusterAdapterStatus" apiCall: diff --git a/testdata/adapter-configs/cl-namespace/adapter-task-config.yaml b/testdata/adapter-configs/cl-namespace/adapter-task-config.yaml index 072dbb6..66dbbf5 100644 --- a/testdata/adapter-configs/cl-namespace/adapter-task-config.yaml +++ b/testdata/adapter-configs/cl-namespace/adapter-task-config.yaml @@ -24,6 +24,11 @@ spec: type: "string" required: false default: "false" + - name: "TTL_EXPIRY_THRESHOLD" + source: "env.TTL_EXPIRY_THRESHOLD" + type: "int" + required: false + default: 300 # Preconditions with valid operators and CEL expressions preconditions: @@ -39,21 +44,21 @@ spec: field: "name" - name: "generationSpec" field: "generation" - - name: "readyConditionStatus" + - name: "readyCondition" expression: | status.conditions.filter(c, c.type == "Ready").size() > 0 - ? status.conditions.filter(c, c.type == "Ready")[0].status - : "False" - # Structured conditions with valid operators - conditions: - - field: "readyConditionStatus" - operator: "equals" - value: "False" + ? status.conditions.filter(c, c.type == "Ready")[0] + : null + # Capture current time as a fixed timestamp for consistent time comparisons + # Using `now()` directly in multiple expressions would return different values + - name: "currentTime" + expression: "now()" - name: "validationCheck" - # Valid CEL expression + # Precondition passes if cluster is NOT Ready OR if cluster is Ready and stable for >TTL_EXPIRY_THRESHOLD seconds since last transition (enables self-healing) expression: | - readyConditionStatus == "False" + readyCondition == null || readyCondition.status != "True" || + (timestamp(currentTime) - timestamp(readyCondition.last_transition_time)).getSeconds() >= TTL_EXPIRY_THRESHOLD # Resources with valid K8s manifests resources: diff --git a/testdata/adapter-configs/np-configmap/adapter-task-config.yaml b/testdata/adapter-configs/np-configmap/adapter-task-config.yaml index 38c7308..10a3ea3 100644 --- a/testdata/adapter-configs/np-configmap/adapter-task-config.yaml +++ b/testdata/adapter-configs/np-configmap/adapter-task-config.yaml @@ -18,6 +18,11 @@ spec: source: "event.id" type: "string" required: true + - name: "TTL_EXPIRY_THRESHOLD" + source: "env.TTL_EXPIRY_THRESHOLD" + type: "int" + required: false + default: 300 # Preconditions with valid operators and CEL expressions preconditions: @@ -33,16 +38,21 @@ spec: field: "name" - name: "generationSpec" field: "generation" - - name: "readyConditionStatus" + - name: "readyCondition" expression: | status.conditions.filter(c, c.type == "Ready").size() > 0 - ? status.conditions.filter(c, c.type == "Ready")[0].status - : "False" - # Structured conditions with valid operators - conditions: - - field: "readyConditionStatus" - operator: "equals" - value: "False" + ? status.conditions.filter(c, c.type == "Ready")[0] + : null + # Capture current time as a fixed timestamp for consistent time comparisons + # Using `now()` directly in multiple expressions would return different values + - name: "currentTime" + expression: "now()" + + - name: "validationCheck" + # Precondition passes if nodepool is NOT Ready OR if nodepool is Ready and stable for >TTL_EXPIRY_THRESHOLD seconds since last transition (enables self-healing) + expression: | + readyCondition == null || readyCondition.status != "True" || + (timestamp(currentTime) - timestamp(readyCondition.last_transition_time)).getSeconds() >= TTL_EXPIRY_THRESHOLD - name: "clusterAdapterStatus" apiCall: From 254d6b9756f26b968fb07bc954c218d5d06b9863 Mon Sep 17 00:00:00 2001 From: dawang Date: Fri, 13 Mar 2026 19:46:09 +0800 Subject: [PATCH 2/2] HYPERFLEET-707 - doc: update time-based precondition of adapter configs for more readable --- .../cl-deployment/adapter-task-config.yaml | 27 +++++++++---------- .../cl-job/adapter-task-config.yaml | 27 +++++++++---------- .../cl-namespace/adapter-task-config.yaml | 27 +++++++++---------- .../np-configmap/adapter-task-config.yaml | 27 +++++++++---------- 4 files changed, 48 insertions(+), 60 deletions(-) diff --git a/testdata/adapter-configs/cl-deployment/adapter-task-config.yaml b/testdata/adapter-configs/cl-deployment/adapter-task-config.yaml index e9bdbfb..e71718d 100644 --- a/testdata/adapter-configs/cl-deployment/adapter-task-config.yaml +++ b/testdata/adapter-configs/cl-deployment/adapter-task-config.yaml @@ -14,11 +14,6 @@ spec: source: "event.id" type: "string" required: true - - name: "TTL_EXPIRY_THRESHOLD" - source: "env.TTL_EXPIRY_THRESHOLD" - type: "int" - required: false - default: 300 # Preconditions with valid operators and CEL expressions preconditions: @@ -34,21 +29,23 @@ spec: field: "name" - name: "generationSpec" field: "generation" - - name: "readyCondition" + - name: "clusterNotReady" expression: | status.conditions.filter(c, c.type == "Ready").size() > 0 - ? status.conditions.filter(c, c.type == "Ready")[0] - : null - # Capture current time as a fixed timestamp for consistent time comparisons - # Using `now()` directly in multiple expressions would return different values - - name: "currentTime" - expression: "now()" + ? status.conditions.filter(c, c.type == "Ready")[0].status != "True" + : true + - name: "clusterReadyTTL" + expression: | + (timestamp(now()) - timestamp( + status.conditions.filter(c, c.type == "Ready").size() > 0 + ? status.conditions.filter(c, c.type == "Ready")[0].last_transition_time + : now() + )).getSeconds() >= 300 - name: "validationCheck" - # Precondition passes if cluster is NOT Ready OR if cluster is Ready and stable for >TTL_EXPIRY_THRESHOLD seconds since last transition (enables self-healing) + # Precondition passes if cluster is NOT Ready OR if cluster is Ready and stable for >300 seconds since last transition (enables self-healing) expression: | - readyCondition == null || readyCondition.status != "True" || - (timestamp(currentTime) - timestamp(readyCondition.last_transition_time)).getSeconds() >= TTL_EXPIRY_THRESHOLD + clusterNotReady || clusterReadyTTL - name: "clusterAdapterStatus" apiCall: diff --git a/testdata/adapter-configs/cl-job/adapter-task-config.yaml b/testdata/adapter-configs/cl-job/adapter-task-config.yaml index c832399..fc91076 100644 --- a/testdata/adapter-configs/cl-job/adapter-task-config.yaml +++ b/testdata/adapter-configs/cl-job/adapter-task-config.yaml @@ -18,11 +18,6 @@ spec: source: "env.JOB_SLEEP_DURATION" type: "string" default: "15" - - name: "TTL_EXPIRY_THRESHOLD" - source: "env.TTL_EXPIRY_THRESHOLD" - type: "int" - required: false - default: 300 # Preconditions with valid operators and CEL expressions preconditions: @@ -41,21 +36,23 @@ spec: - name: "simulateResult" # possible values: success (default), failure, hang, crash, invalid-json, missing-status field: "simulateResult" default: "success" - - name: "readyCondition" + - name: "clusterNotReady" expression: | status.conditions.filter(c, c.type == "Ready").size() > 0 - ? status.conditions.filter(c, c.type == "Ready")[0] - : null - # Capture current time as a fixed timestamp for consistent time comparisons - # Using `now()` directly in multiple expressions would return different values - - name: "currentTime" - expression: "now()" + ? status.conditions.filter(c, c.type == "Ready")[0].status != "True" + : true + - name: "clusterReadyTTL" + expression: | + (timestamp(now()) - timestamp( + status.conditions.filter(c, c.type == "Ready").size() > 0 + ? status.conditions.filter(c, c.type == "Ready")[0].last_transition_time + : now() + )).getSeconds() >= 300 - name: "validationCheck" - # Precondition passes if cluster is NOT Ready OR if cluster is Ready and stable for >TTL_EXPIRY_THRESHOLD seconds since last transition (enables self-healing) + # Precondition passes if cluster is NOT Ready OR if cluster is Ready and stable for >300 seconds since last transition (enables self-healing) expression: | - readyCondition == null || readyCondition.status != "True" || - (timestamp(currentTime) - timestamp(readyCondition.last_transition_time)).getSeconds() >= TTL_EXPIRY_THRESHOLD + clusterNotReady || clusterReadyTTL - name: "clusterAdapterStatus" apiCall: diff --git a/testdata/adapter-configs/cl-namespace/adapter-task-config.yaml b/testdata/adapter-configs/cl-namespace/adapter-task-config.yaml index 66dbbf5..7dd623b 100644 --- a/testdata/adapter-configs/cl-namespace/adapter-task-config.yaml +++ b/testdata/adapter-configs/cl-namespace/adapter-task-config.yaml @@ -24,11 +24,6 @@ spec: type: "string" required: false default: "false" - - name: "TTL_EXPIRY_THRESHOLD" - source: "env.TTL_EXPIRY_THRESHOLD" - type: "int" - required: false - default: 300 # Preconditions with valid operators and CEL expressions preconditions: @@ -44,21 +39,23 @@ spec: field: "name" - name: "generationSpec" field: "generation" - - name: "readyCondition" + - name: "clusterNotReady" expression: | status.conditions.filter(c, c.type == "Ready").size() > 0 - ? status.conditions.filter(c, c.type == "Ready")[0] - : null - # Capture current time as a fixed timestamp for consistent time comparisons - # Using `now()` directly in multiple expressions would return different values - - name: "currentTime" - expression: "now()" + ? status.conditions.filter(c, c.type == "Ready")[0].status != "True" + : true + - name: "clusterReadyTTL" + expression: | + (timestamp(now()) - timestamp( + status.conditions.filter(c, c.type == "Ready").size() > 0 + ? status.conditions.filter(c, c.type == "Ready")[0].last_transition_time + : now() + )).getSeconds() >= 300 - name: "validationCheck" - # Precondition passes if cluster is NOT Ready OR if cluster is Ready and stable for >TTL_EXPIRY_THRESHOLD seconds since last transition (enables self-healing) + # Precondition passes if cluster is NOT Ready OR if cluster is Ready and stable for >300 seconds since last transition (enables self-healing) expression: | - readyCondition == null || readyCondition.status != "True" || - (timestamp(currentTime) - timestamp(readyCondition.last_transition_time)).getSeconds() >= TTL_EXPIRY_THRESHOLD + clusterNotReady || clusterReadyTTL # Resources with valid K8s manifests resources: diff --git a/testdata/adapter-configs/np-configmap/adapter-task-config.yaml b/testdata/adapter-configs/np-configmap/adapter-task-config.yaml index 10a3ea3..8622160 100644 --- a/testdata/adapter-configs/np-configmap/adapter-task-config.yaml +++ b/testdata/adapter-configs/np-configmap/adapter-task-config.yaml @@ -18,11 +18,6 @@ spec: source: "event.id" type: "string" required: true - - name: "TTL_EXPIRY_THRESHOLD" - source: "env.TTL_EXPIRY_THRESHOLD" - type: "int" - required: false - default: 300 # Preconditions with valid operators and CEL expressions preconditions: @@ -38,21 +33,23 @@ spec: field: "name" - name: "generationSpec" field: "generation" - - name: "readyCondition" + - name: "nodepoolNotReady" expression: | status.conditions.filter(c, c.type == "Ready").size() > 0 - ? status.conditions.filter(c, c.type == "Ready")[0] - : null - # Capture current time as a fixed timestamp for consistent time comparisons - # Using `now()` directly in multiple expressions would return different values - - name: "currentTime" - expression: "now()" + ? status.conditions.filter(c, c.type == "Ready")[0].status != "True" + : true + - name: "nodepoolReadyTTL" + expression: | + (timestamp(now()) - timestamp( + status.conditions.filter(c, c.type == "Ready").size() > 0 + ? status.conditions.filter(c, c.type == "Ready")[0].last_transition_time + : now() + )).getSeconds() >= 300 - name: "validationCheck" - # Precondition passes if nodepool is NOT Ready OR if nodepool is Ready and stable for >TTL_EXPIRY_THRESHOLD seconds since last transition (enables self-healing) + # Precondition passes if nodepool is NOT Ready OR if nodepool is Ready and stable for >300 seconds since last transition (enables self-healing) expression: | - readyCondition == null || readyCondition.status != "True" || - (timestamp(currentTime) - timestamp(readyCondition.last_transition_time)).getSeconds() >= TTL_EXPIRY_THRESHOLD + nodepoolNotReady || nodepoolReadyTTL - name: "clusterAdapterStatus" apiCall: