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
47 changes: 20 additions & 27 deletions helm/adapter1/adapter-config.yaml
Original file line number Diff line number Diff line change
@@ -1,33 +1,26 @@
# Example HyperFleet Adapter deployment configuration
apiVersion: hyperfleet.redhat.com/v1alpha1
kind: AdapterConfig
metadata:
adapter:
name: adapter1
labels:
hyperfleet.io/adapter-type: kubernetes
hyperfleet.io/component: adapter
spec:
adapter:
version: "0.1.0"
version: "0.2.0"

# Log the full merged configuration after load (default: false)
debugConfig: true
log:
level: debug
# Log the full merged configuration after load (default: false)
debug_config: true
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

Disable merged-config debug logging by default.

Line 7 enables verbose merged-config logging. Keep this disabled by default to reduce accidental sensitive-data exposure in logs.

🔧 Suggested change
-debug_config: true
+debug_config: false
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
debug_config: true
debug_config: false
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@helm/adapter1/adapter-config.yaml` at line 7, The merged-config debug flag
debug_config is currently enabled by default; change its default value to false
to prevent verbose merged-config logging and reduce risk of sensitive-data
exposure, i.e., update the debug_config setting in adapter-config.yaml to false
and ensure any chart/values templates or README mention that debug_config is
opt-in rather than enabled by default.

log:
level: debug

clients:
hyperfleetApi:
baseUrl: http://hyperfleet-api:8000
version: v1
timeout: 2s
retryAttempts: 3
retryBackoff: exponential
clients:
hyperfleet_api:
base_url: http://hyperfleet-api:8000
version: v1
timeout: 2s
retry_attempts: 3
retry_backoff: exponential

broker:
# These values are overridden at deploy time via env vars from Helm values
subscriptionId: "placeholder"
topic: "placeholder"
broker:
# These values are overridden at deploy time via env vars from Helm values
subscription_id: "placeholder"
topic: "placeholder"

kubernetes:
apiVersion: "v1"
#kubeConfigPath: PATH_TO_KUBECONFIG # for local development
kubernetes:
api_version: "v1"
#kube_config_path: PATH_TO_KUBECONFIG # for local development
283 changes: 136 additions & 147 deletions helm/adapter1/adapter-task-config.yaml
Original file line number Diff line number Diff line change
@@ -1,157 +1,146 @@
# Example HyperFleet Adapter task configuration
apiVersion: hyperfleet.redhat.com/v1alpha1
kind: AdapterTaskConfig
metadata:
name: adapter1
labels:
hyperfleet.io/adapter-type: adapter1
hyperfleet.io/component: adapter
spec:
# Parameters with all required variables
params:
params:

- name: "clusterId"
source: "event.id"
type: "string"
required: true

- name: "clusterId"
source: "event.id"
type: "string"
required: true
- name: "generation"
source: "event.generation"
type: "int"
required: true

- name: "generation"
source: "event.generation"
type: "int"
required: true
- name: "namespace"
source: "env.NAMESPACE"
type: "string"

- name: "namespace"
source: "env.NAMESPACE"
type: "string"
# Preconditions with valid operators and CEL expressions
preconditions:
- name: "clusterStatus"
api_call:
method: "GET"
url: "/clusters/{{ .clusterId }}"
timeout: 10s
retry_attempts: 3
retry_backoff: "exponential"
capture:
- name: "clusterName"
field: "name"
- name: "generation"
field: "generation"
- name: "readyConditionStatus"
expression: |
status.conditions.filter(c, c.type == "Ready").size() > 0
? status.conditions.filter(c, c.type == "Ready")[0].status
: "False"
Comment on lines +32 to +36
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

🧩 Analysis chain

🏁 Script executed:

# Find and examine the adapter-task-config.yaml file
find . -name "adapter-task-config.yaml" -type f

Repository: openshift-hyperfleet/hyperfleet-infra

Length of output: 203


🏁 Script executed:

# Once we find it, let's read the full context around the flagged lines
# First, let's see what files match the pattern
fd -t f "adapter-task-config.yaml"

Repository: openshift-hyperfleet/hyperfleet-infra

Length of output: 197


🏁 Script executed:

# Look for the file in helm directory
find . -path "*/helm/adapter1/adapter-task-config.yaml" -type f 2>/dev/null || echo "File not found in expected path"

Repository: openshift-hyperfleet/hyperfleet-infra

Length of output: 121


🏁 Script executed:

# Search more broadly for adapter-task-config files
find . -name "*adapter*task*config*" -type f 2>/dev/null | head -20

Repository: openshift-hyperfleet/hyperfleet-infra

Length of output: 203


🏁 Script executed:

# Read the adapter-task-config.yaml file to see the full context
cat -n helm/adapter1/adapter-task-config.yaml | head -50

Repository: openshift-hyperfleet/hyperfleet-infra

Length of output: 1655


🏁 Script executed:

# Also check if this same pattern exists in other adapter configs
cat -n helm/adapter2/adapter-task-config.yaml | head -50

Repository: openshift-hyperfleet/hyperfleet-infra

Length of output: 1712


🏁 Script executed:

# Get line count to understand file size
wc -l helm/adapter1/adapter-task-config.yaml

Repository: openshift-hyperfleet/hyperfleet-infra

Length of output: 123


🏁 Script executed:

# Check the full content of adapter2 to see if the pattern differs
cat -n helm/adapter2/adapter-task-config.yaml | head -50

Repository: openshift-hyperfleet/hyperfleet-infra

Length of output: 1712


🏁 Script executed:

# Check adapter3 as well
cat -n helm/adapter3/adapter-task-config.yaml | head -50

Repository: openshift-hyperfleet/hyperfleet-infra

Length of output: 1687


🏁 Script executed:

# Search for other CEL expressions in the codebase to understand patterns
rg "expression:" helm/ -A 2 -B 1 | head -100

Repository: openshift-hyperfleet/hyperfleet-infra

Length of output: 7448


🏁 Script executed:

# Look for documentation or comments about CEL usage
rg "CEL|has\(" helm/ -B 2 -A 2

Repository: openshift-hyperfleet/hyperfleet-infra

Length of output: 15626


🏁 Script executed:

# Check if there's any API documentation or comments about status.conditions
rg "status.conditions" helm/ -B 3 -A 3 | head -80

Repository: openshift-hyperfleet/hyperfleet-infra

Length of output: 5089


🏁 Script executed:

# Look for API endpoint documentation or schema validation
find . -name "*.md" -o -name "*.yaml" -o -name "*.json" | xargs grep -l "status.conditions\|cluster.*schema\|api.*contract" 2>/dev/null | head -20

Repository: openshift-hyperfleet/hyperfleet-infra

Length of output: 203


🏁 Script executed:

# Check the full context of how the readyConditionStatus is used after capture
cat -n helm/adapter1/adapter-task-config.yaml | sed -n '20,50p'

Repository: openshift-hyperfleet/hyperfleet-infra

Length of output: 1149


Add defensive guard for missing status.conditions in precondition capture.

The expression calls .filter() on status.conditions directly. If the status.conditions field is absent from the API response, this will fail before reaching the ternary fallback.

Suggested fix
      - name: "readyConditionStatus"
        expression: |
-         status.conditions.filter(c, c.type == "Ready").size() > 0
+         has(status.conditions)
+           && status.conditions.filter(c, c.type == "Ready").size() > 0
           ? status.conditions.filter(c, c.type == "Ready")[0].status
           : "False"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: "readyConditionStatus"
expression: |
status.conditions.filter(c, c.type == "Ready").size() > 0
? status.conditions.filter(c, c.type == "Ready")[0].status
: "False"
- name: "readyConditionStatus"
expression: |
has(status.conditions)
&& status.conditions.filter(c, c.type == "Ready").size() > 0
? status.conditions.filter(c, c.type == "Ready")[0].status
: "False"
🤖 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 32 - 36, The
precondition capture "readyConditionStatus" currently calls
status.conditions.filter(...) which will throw if status.conditions is missing;
update the expression to defensively check that status.conditions exists and is
an array (e.g., status.conditions != null && status.conditions.size() > 0 or
equivalent) before calling .filter(), and only then evaluate the Ready condition
with the existing ternary fallback to "False"; modify the expression for
"readyConditionStatus" to guard access to status.conditions and preserve the
same output semantics.

# Structured conditions with valid operators
conditions:
- field: "readyConditionStatus"
operator: "equals"
value: "False"

# Preconditions with valid operators and CEL expressions
preconditions:
- name: "clusterStatus"
apiCall:
method: "GET"
url: "/clusters/{{ .clusterId }}"
timeout: 10s
retryAttempts: 3
retryBackoff: "exponential"
capture:
- name: "clusterName"
field: "name"
- name: "generation"
field: "generation"
- name: "readyConditionStatus"
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"
- name: "validationCheck"
# Valid CEL expression
expression: |
readyConditionStatus == "False"

- name: "validationCheck"
# Valid CEL expression
expression: |
readyConditionStatus == "False"

# Resources with valid K8s manifests
resources:
- name: "resource0"
transport:
client: "kubernetes"
manifest:
apiVersion: v1
kind: ConfigMap
data:
cluster_id: "{{ .clusterId }}"
cluster_name: "{{ .clusterName }}"
metadata:
name: "{{ .clusterId }}-adapter1-configmap"
namespace: "{{ .namespace }}"
labels:
app.kubernetes.io/component: adapter
app.kubernetes.io/instance: adapter1
app.kubernetes.io/name: hyperfleet-adapter
app.kubernetes.io/version: 1.0.0
app.kubernetes.io/transport: kubernetes
hyperfleet.io/cluster-id: "{{ .clusterId }}"
hyperfleet.io/cluster-name: "{{ .clusterName }}"
discovery:
# Resources with valid K8s manifests
resources:
- name: "resource0"
transport:
client: "kubernetes"
manifest:
apiVersion: v1
kind: ConfigMap
data:
cluster_id: "{{ .clusterId }}"
cluster_name: "{{ .clusterName }}"
metadata:
name: "{{ .clusterId }}-adapter1-configmap"
namespace: "{{ .namespace }}"
bySelectors:
labelSelector:
hyperfleet.io/cluster-id: "{{ .clusterId }}"
hyperfleet.io/cluster-name: "{{ .clusterName }}"
labels:
app.kubernetes.io/component: adapter
app.kubernetes.io/instance: adapter1
app.kubernetes.io/name: hyperfleet-adapter
app.kubernetes.io/version: 1.0.0
app.kubernetes.io/transport: kubernetes
hyperfleet.io/cluster-id: "{{ .clusterId }}"
hyperfleet.io/cluster-name: "{{ .clusterName }}"
discovery:
namespace: "{{ .namespace }}"
by_selectors:
label_selector:
hyperfleet.io/cluster-id: "{{ .clusterId }}"
hyperfleet.io/cluster-name: "{{ .clusterName }}"

# Post-processing with valid CEL expressions
# This example contains multiple resources, we will only report on the conditions of the jobNamespace not to overcomplicate the example
post:
payloads:
- name: "statusPayload"
build:
# TODO: this should come from config.adapter.metadata.name
adapter: "adapter1"
conditions:
# Applied: Job successfully created
- type: "Applied"
status:
expression: |
has(resources.resource0.metadata.creationTimestamp) ? "True" : "False"
reason:
expression: |
has(resources.resource0.metadata.creationTimestamp) ? "ConfigMapApplied" : "ConfigMapPending"
message:
expression: |
has(resources.resource0.metadata.creationTimestamp)
? "ConfigMap has been applied correctly"
: "ConfigMap is pending to be applied"
# Available: Check job status conditions
- type: "Available"
status:
expression: |
has(resources.resource0.data.cluster_id) ? "True" : "False"
reason:
expression: |
has(resources.resource0.data.cluster_id)
? "ConfigMap data available"
: "ConfigMap data not yet available"
message:
expression: |
has(resources.resource0.data.cluster_id)
? "ConfigMap data available"
: "ConfigMap data not yet available"
# Health: Adapter execution status (runtime)
- type: "Health"
status:
expression: |
adapter.?executionStatus.orValue("") == "success" ? "True" : (adapter.?executionStatus.orValue("") == "failed" ? "False" : "Unknown")
reason:
expression: |
adapter.?errorReason.orValue("") != "" ? adapter.?errorReason.orValue("") : "Healthy"
message:
expression: |
adapter.?errorMessage.orValue("") != "" ? adapter.?errorMessage.orValue("") : "All adapter operations completed successfully"
# Event generation ID metadata field needs to use expression to avoid interpolation issues
observed_generation:
expression: "generation"
observed_time: "{{ now | date \"2006-01-02T15:04:05Z07:00\" }}"
# Optional data field for adapter-specific metrics extracted from resources
data:
namespace:
name:
expression: |
resources.?resources.resource0.?metadata.?name.orValue("")
creationTimestamp:
expression: |
resources.?resources.resource0.?metadata.?creationTimestamp.orValue("")
# Post-processing with valid CEL expressions
# This example contains multiple resources, we will only report on the conditions of the jobNamespace not to overcomplicate the example
post:
payloads:
- name: "statusPayload"
build:
adapter: "{{ .adapter.name }}"
conditions:
# Applied: Job successfully created
- type: "Applied"
status:
expression: |
has(resources.resource0.metadata.creationTimestamp) ? "True" : "False"
reason:
expression: |
has(resources.resource0.metadata.creationTimestamp) ? "ConfigMapApplied" : "ConfigMapPending"
message:
expression: |
has(resources.resource0.metadata.creationTimestamp)
? "ConfigMap has been applied correctly"
: "ConfigMap is pending to be applied"
# Available: Check job status conditions
- type: "Available"
status:
expression: |
has(resources.resource0.data.cluster_id) ? "True" : "False"
reason:
expression: |
has(resources.resource0.data.cluster_id)
? "ConfigMap data available"
: "ConfigMap data not yet available"
message:
expression: |
has(resources.resource0.data.cluster_id)
? "ConfigMap data available"
: "ConfigMap data not yet available"
# Health: Adapter execution status (runtime)
- type: "Health"
status:
expression: |
adapter.?executionStatus.orValue("") == "success" ? "True" : (adapter.?executionStatus.orValue("") == "failed" ? "False" : "Unknown")
reason:
expression: |
adapter.?errorReason.orValue("") != "" ? adapter.?errorReason.orValue("") : "Healthy"
message:
expression: |
adapter.?errorMessage.orValue("") != "" ? adapter.?errorMessage.orValue("") : "All adapter operations completed successfully"
# Event generation ID metadata field needs to use expression to avoid interpolation issues
observed_generation:
expression: "generation"
observed_time: "{{ now | date \"2006-01-02T15:04:05Z07:00\" }}"
# Optional data field for adapter-specific metrics extracted from resources
data:
namespace:
name:
expression: |
resources.?resources.resource0.?metadata.?name.orValue("")
creationTimestamp:
expression: |
resources.?resources.resource0.?metadata.?creationTimestamp.orValue("")

postActions:
- name: "reportClusterStatus"
apiCall:
method: "POST"
url: "/clusters/{{ .clusterId }}/statuses"
headers:
- name: "Content-Type"
value: "application/json"
body: "{{ .statusPayload }}"
post_actions:
- name: "reportClusterStatus"
api_call:
method: "POST"
url: "/clusters/{{ .clusterId }}/statuses"
headers:
- name: "Content-Type"
value: "application/json"
body: "{{ .statusPayload }}"
Loading