Skip to content
Draft
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
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ IMPORTANT: These return `*ServiceError`, not `error`. Use `.AsError()` to conver

- `internal/executor/` — event execution pipeline (params → preconditions → resources → post-actions)
- `internal/transportclient/` — unified apply interface abstracting K8s direct and Maestro ManifestWork
- `internal/logctx/` — adapter-specific typed context keys and the stack-trace filter for the shared `hyperfleet-logger` handler (see `docs/conventions/logging.md`)

## Links

Expand Down
43 changes: 43 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,49 @@ test-helm: verify-helm-docs ## Test Helm charts (lint, template, validate, kubec
echo "ERROR: expected helm template to fail when broker.rabbitmq.exchange is missing"; exit 1; \
fi
@echo "RabbitMQ missing exchange validation OK"
@echo ""
@echo "Testing Pub/Sub messageRetentionDuration=31d (max) is accepted..."
@helm template test-release charts/ \
--set image.registry=quay.io \
--set image.repository=openshift-hyperfleet/hyperfleet-adapter \
--set image.tag=test \
--set adapterConfig.yaml="apiVersion: hyperfleet.redhat.com/v1alpha1" \
--set adapterTaskConfig.yaml="apiVersion: hyperfleet.redhat.com/v1alpha1" \
--set broker.type=googlepubsub \
--set broker.googlepubsub.subscriptionId=test-sub \
--set broker.googlepubsub.topic=test-topic \
--set broker.googlepubsub.messageRetentionDuration=31d > /dev/null \
|| { echo "ERROR: helm template failed for messageRetentionDuration=31d"; exit 1; }
@echo "Pub/Sub 31d retention validation OK"
@echo ""
@echo "Testing Pub/Sub expirationTTL=86400s (1d) is accepted..."
@helm template test-release charts/ \
--set image.registry=quay.io \
--set image.repository=openshift-hyperfleet/hyperfleet-adapter \
--set image.tag=test \
--set adapterConfig.yaml="apiVersion: hyperfleet.redhat.com/v1alpha1" \
--set adapterTaskConfig.yaml="apiVersion: hyperfleet.redhat.com/v1alpha1" \
--set broker.type=googlepubsub \
--set broker.googlepubsub.subscriptionId=test-sub \
--set broker.googlepubsub.topic=test-topic \
--set broker.googlepubsub.expirationTTL=86400s > /dev/null \
|| { echo "ERROR: helm template failed for expirationTTL=86400s"; exit 1; }
@echo "Pub/Sub 86400s TTL validation OK"
@echo ""
@echo "Testing Pub/Sub numeric-zero messageRetentionDuration is rejected..."
@if helm template test-release charts/ \
--set image.registry=quay.io \
--set image.repository=openshift-hyperfleet/hyperfleet-adapter \
--set image.tag=test \
--set adapterConfig.yaml="apiVersion: hyperfleet.redhat.com/v1alpha1" \
--set adapterTaskConfig.yaml="apiVersion: hyperfleet.redhat.com/v1alpha1" \
--set broker.type=googlepubsub \
--set broker.googlepubsub.subscriptionId=test-sub \
--set broker.googlepubsub.topic=test-topic \
--set broker.googlepubsub.messageRetentionDuration=0 > /dev/null 2>&1; then \
echo "ERROR: expected helm template to fail when messageRetentionDuration=0"; exit 1; \
fi
@echo "Pub/Sub zero retention validation OK"

##@ Code Quality

Expand Down
51 changes: 47 additions & 4 deletions charts/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,12 @@ Per Helm Chart Conventions Standard section 9 (Deprecation and Migration Pattern
{{- end -}}
{{- end -}}
{{- end -}}
{{- if hasKey .Values "serviceMonitor" }}
{{- fail "serviceMonitor has moved to monitoring.serviceMonitor. Please update your values (e.g. monitoring.serviceMonitor.enabled)." }}
{{- end -}}
{{- if hasKey .Values "tracing" }}
{{- fail "tracing has moved to monitoring.tracing. Please update your values (e.g. monitoring.tracing.enabled)." }}
{{- end -}}
{{- end }}

{{/*
Expand All @@ -303,6 +309,32 @@ broker.type must be set explicitly — inference from sub-keys is not supported.
{{- required "broker.type must be set to one of: googlepubsub, rabbitmq" .Values.broker.type -}}
{{- end }}

{{/*
Convert a validated "<digits><unit>" duration string (unit one of s/m/h/d) to seconds.
Callers must validate the format (via regexMatch) before calling this.
Digit length is bounded so Sprig mul cannot wrap int64 (CWE-190).
*/}}
{{- define "hyperfleet-adapter.durationToSeconds" -}}
{{- $d := . -}}
{{- $length := len $d -}}
{{- $lastIdx := sub $length 1 | int -}}
{{- $unit := substr $lastIdx $length $d -}}
{{- $numStr := substr 0 $lastIdx $d -}}
{{- if gt (len $numStr) 10 -}}
{{- fail (printf "duration %s overflows int64 when converted to seconds" $d) -}}
{{- end -}}
{{- $num := $numStr | int64 -}}
{{- if eq $unit "s" -}}
{{- $num -}}
{{- else if eq $unit "m" -}}
{{- mul $num 60 -}}
{{- else if eq $unit "h" -}}
{{- mul $num 3600 -}}
{{- else if eq $unit "d" -}}
{{- mul $num 86400 -}}
{{- end -}}
{{- end }}

{{/*
Validate that required fields are set for the resolved broker type.
*/}}
Expand All @@ -311,14 +343,25 @@ Validate that required fields are set for the resolved broker type.
{{- if eq $brokerType "googlepubsub" -}}
{{- $ttl := .Values.broker.googlepubsub.expirationTTL | toString -}}
{{- if ne $ttl "" -}}
{{- if not (regexMatch "^(0|[1-9][0-9]*[smhd])$" $ttl) -}}
{{- if not (regexMatch "^(0|[1-9][0-9]{0,9}[smhd])$" $ttl) -}}
{{- fail "broker.googlepubsub.expirationTTL must be \"0\" (never expire) or a duration like \"1d\", \"12h\", \"30m\", \"604800s\"" -}}
{{- end -}}
{{- if ne $ttl "0" -}}
{{- $ttlSeconds := include "hyperfleet-adapter.durationToSeconds" $ttl | int64 -}}
{{- if lt $ttlSeconds 86400 -}}
{{- fail "broker.googlepubsub.expirationTTL must be \"0\" (never expire) or at least \"1d\" (Google Pub/Sub minimum)" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if .Values.broker.googlepubsub.messageRetentionDuration -}}
{{- if not (regexMatch "^[1-9][0-9]*[smhd]$" (.Values.broker.googlepubsub.messageRetentionDuration | toString)) -}}
{{- $retention := .Values.broker.googlepubsub.messageRetentionDuration | toString -}}
{{- if ne $retention "" -}}
{{- if not (regexMatch "^[1-9][0-9]{0,9}[smhd]$" $retention) -}}
{{- fail "broker.googlepubsub.messageRetentionDuration must be a duration like \"1d\", \"12h\", \"30m\", \"604800s\"" -}}
{{- end -}}
{{- $retentionSeconds := include "hyperfleet-adapter.durationToSeconds" $retention | int64 -}}
{{- if or (lt $retentionSeconds 600) (gt $retentionSeconds 2678400) -}}
{{- fail "broker.googlepubsub.messageRetentionDuration must be between \"10m\" and \"31d\" (Google Pub/Sub limits)" -}}
{{- end -}}
{{- end -}}
{{- else if eq $brokerType "rabbitmq" -}}
{{- if not .Values.broker.rabbitmq.url -}}
Expand Down Expand Up @@ -352,4 +395,4 @@ Also validate that all file paths in adapterTaskConfig.files actually exist
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
8 changes: 8 additions & 0 deletions charts/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,14 @@
"createSubscriptionIfMissing": {
"type": "boolean",
"description": "Auto-create subscription if missing"
},
"messageRetentionDuration": {
"type": "string",
"description": "Length to retain unacknowledged messages (e.g. 1d, 12h, 604800s). Min 10m, max 31d."
},
"expirationTTL": {
"type": "string",
"description": "Inactivity period before subscription is auto-deleted. Must be 0 (never expire) or at least 1d."
}
}
},
Expand Down
Loading