Skip to content
Open
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
22 changes: 12 additions & 10 deletions helm/adapter1/adapter-task-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,23 @@ spec:
field: "name"
- name: "generation"
field: "generation"
- name: "readyConditionStatus"
- name: "clusterNotReady"
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].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
Comment on lines +42 to +53
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Guard status.conditions/last_transition_time access to avoid brittle preconditions.

Line 44 and Line 50 assume status.conditions is always present, and Line 51 assumes last_transition_time exists. Partial API responses can make these expressions fail at runtime instead of cleanly falling back.

Suggested hardening
         - name: "clusterNotReady"
           expression: |
-            status.conditions.filter(c, c.type == "Ready").size() > 0
-              ? status.conditions.filter(c, c.type == "Ready")[0].status != "True"
+            status.?conditions.orValue([]).filter(c, c.type == "Ready").size() > 0
+              ? status.?conditions.orValue([]).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
+              status.?conditions.orValue([]).filter(c, c.type == "Ready").size() > 0 &&
+              has(status.?conditions.orValue([]).filter(c, c.type == "Ready")[0].last_transition_time)
+                ? status.?conditions.orValue([]).filter(c, c.type == "Ready")[0].last_transition_time
                 : now()
             )).getSeconds() >= 300

As per coding guidelines, **: -Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@helm/adapter1/adapter-task-config.yaml` around lines 42 - 53, clusterNotReady
and clusterReadyTTL assume status.conditions and last_transition_time exist;
make the CEL expressions null-safe by first checking status.conditions != null
and that the filtered list has >0 elements before indexing, and for
clusterReadyTTL also check the existence of last_transition_time and fall back
to now() if missing. Update the clusterNotReady expression used in the
"clusterNotReady" rule to: status.conditions != null &&
status.conditions.filter(c, c.type == "Ready").size() > 0 ?
status.conditions.filter(c, c.type == "Ready")[0].status != "True" : true; and
update "clusterReadyTTL" to compute the timestamp using a guarded
last_transition_time: (timestamp(now()) - timestamp(status.conditions != null &&
status.conditions.filter(c, c.type == "Ready").size() > 0 &&
status.conditions.filter(c, c.type == "Ready")[0].last_transition_time != null ?
status.conditions.filter(c, c.type == "Ready")[0].last_transition_time :
now())).getSeconds() >= 300 so accesses in clusterReadyTTL and clusterNotReady
(status.conditions and last_transition_time) are protected.


- name: "validationCheck"
# Valid CEL expression
# Precondition passes if cluster is NOT Ready OR if cluster is Ready and stable for >300 seconds since last transition (enables self-healing)
expression: |
readyConditionStatus == "False"
clusterNotReady || clusterReadyTTL

# Resources with valid K8s manifests
resources:
Expand Down
22 changes: 12 additions & 10 deletions helm/adapter3/adapter-task-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,23 @@ spec:
field: "name"
- name: "generation"
field: "generation"
- name: "readyConditionStatus"
- name: "nodepoolNotReady"
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].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
Comment on lines +47 to +58
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Handle missing readiness fields defensively to prevent CEL runtime failures.

Line 49 and Line 55 assume status.conditions exists, and Line 56 assumes last_transition_time exists. If either is missing in API payloads, precondition evaluation can error and block execution instead of falling back.

Suggested hardening
         - name: "nodepoolNotReady"
           expression: |
-            status.conditions.filter(c, c.type == "Ready").size() > 0
-              ? status.conditions.filter(c, c.type == "Ready")[0].status != "True"
+            status.?conditions.orValue([]).filter(c, c.type == "Ready").size() > 0
+              ? status.?conditions.orValue([]).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
+              status.?conditions.orValue([]).filter(c, c.type == "Ready").size() > 0 &&
+              has(status.?conditions.orValue([]).filter(c, c.type == "Ready")[0].last_transition_time)
+                ? status.?conditions.orValue([]).filter(c, c.type == "Ready")[0].last_transition_time
                 : now()
             )).getSeconds() >= 300

As per coding guidelines, **: -Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@helm/adapter3/adapter-task-config.yaml` around lines 47 - 58, The CEL
expressions for nodepoolNotReady and nodepoolReadyTTL assume status.conditions
and last_transition_time exist; make them defensive by first checking status and
conditions are present and non-empty and that last_transition_time is present
before indexing or calling timestamp. Update the nodepoolNotReady expression to
use a guard like status != null && status.conditions != null &&
status.conditions.size() > 0 ? status.conditions.filter(c, c.type ==
"Ready")[0].status != "True" : true, and update nodepoolReadyTTL to compute the
reference time only when status/conditions and last_transition_time exist
(fallback to now() otherwise), e.g. check status != null && status.conditions !=
null && status.conditions.size() > 0 && status.conditions.filter(c, c.type ==
"Ready")[0].last_transition_time != null ? timestamp(status.conditions.filter(c,
c.type == "Ready")[0].last_transition_time) : timestamp(now()), then compare
getSeconds() >= 300; apply these guards in the nodepoolNotReady and
nodepoolReadyTTL expressions to avoid runtime errors.


- name: "validationCheck"
# Valid CEL expression
# Precondition passes if nodepool is NOT Ready OR if nodepool is Ready and stable for >300 seconds since last transition (enables self-healing)
expression: |
readyConditionStatus == "False"
nodepoolNotReady || nodepoolReadyTTL

# Resources with valid K8s manifests
resources:
Expand Down