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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ test-helm: ## Test Helm charts (lint, template, validate)
@echo "Testing template with Google Pub/Sub broker..."
helm template test-release $(HELM_CHART_DIR)/ \
--set broker.type=googlepubsub \
--set broker.googlepubsub.projectId=test-project > /dev/null
--set broker.googlepubsub.project_id=test-project > /dev/null
@echo "Google Pub/Sub broker template OK"
@echo ""
@echo "Testing template with PodMonitoring enabled..."
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,9 @@ Broker configuration is managed by the [hyperfleet-broker library](https://githu

| Variable | Description | Example |
|----------|-------------|---------|
| `BROKER_TOPIC` | Topic name for publishing events | `hyperfleet-dev-clusters` |
| `HYPERFLEET_BROKER_TOPIC` | Topic name for publishing events | `hyperfleet-dev-clusters` |

The `BROKER_TOPIC` environment variable sets the full topic name where events will be published. When using Helm, the default topic is `{namespace}-{resourceType}` (e.g., `hyperfleet-dev-clusters`, `hyperfleet-dev-nodepools`). This enables isolation between different environments or tenants sharing the same broker. See [Naming Strategy](https://github.com/openshift-hyperfleet/architecture/blob/main/hyperfleet/components/sentinel/sentinel-naming-strategy.md) for details.
The `HYPERFLEET_BROKER_TOPIC` environment variable sets the full topic name where events will be published. When using Helm, the default topic is `{namespace}-{resourceType}` (e.g., `hyperfleet-dev-clusters`, `hyperfleet-dev-nodepools`). This enables isolation between different environments or tenants sharing the same broker. See [Naming Strategy](https://github.com/openshift-hyperfleet/architecture/blob/main/hyperfleet/components/sentinel/sentinel-naming-strategy.md) for details.

For detailed broker configuration options, see the [hyperfleet-broker documentation](https://github.com/openshift-hyperfleet/hyperfleet-broker).

Expand Down
44 changes: 22 additions & 22 deletions charts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,14 @@ The following table lists the configurable parameters of the Sentinel chart and

| Parameter | Description | Default |
|-----------|-------------|---------|
| `config.resourceType` | Resource type to watch | `clusters` |
| `config.pollInterval` | Polling interval | `5s` |
| `config.maxAgeNotReady` | Max age for not ready resources | `10s` |
| `config.maxAgeReady` | Max age for ready resources | `30m` |
| `config.resourceSelector` | Resource selector for sharding | See values.yaml |
| `config.hyperfleetApi.baseUrl` | HyperFleet API base URL | `http://hyperfleet-api:8000` |
| `config.hyperfleetApi.timeout` | API timeout | `5s` |
| `config.messageData` | CloudEvents data payload fields | See values.yaml |
| `config.resource_type` | Resource type to watch | `clusters` |
| `config.poll_interval` | Polling interval | `5s` |
| `config.max_age_not_ready` | Max age for not ready resources | `10s` |
| `config.max_age_ready` | Max age for ready resources | `30m` |
| `config.resource_selector` | Resource selector for sharding | See values.yaml |
| `config.clients.hyperfleet_api.base_url` | HyperFleet API base URL | `http://hyperfleet-api:8000` |
| `config.clients.hyperfleet_api.timeout` | API timeout | `10s` |
| `config.message_data` | CloudEvents data payload fields | See values.yaml |

### Broker Configuration

Expand All @@ -94,13 +94,13 @@ The following table lists the configurable parameters of the Sentinel chart and
| Parameter | Description | Default |
|-----------|-------------|---------|
| `broker.type` | Broker type (`rabbitmq` or `googlepubsub`) | `rabbitmq` |
| `broker.topic` | Topic name for broker publishing (supports Helm templates) | `{{ .Release.Namespace }}-{{ .Values.config.resourceType }}` |
| `broker.topic` | Topic name for broker publishing (supports Helm templates) | `{{ .Release.Namespace }}-{{ .Values.config.resource_type }}` |
| `broker.rabbitmq.url` | RabbitMQ connection URL (format: `amqp://user:pass@host:port/vhost`) | `amqp://sentinel-user:change-me-in-production@rabbitmq.hyperfleet-system.svc.cluster.local:5672/hyperfleet` |
| `broker.rabbitmq.exchangeType` | RabbitMQ exchange type | `topic` |
| `broker.googlepubsub.projectId` | GCP project ID (for Pub/Sub) | `your-gcp-project-id` |
| `broker.googlepubsub.maxOutstandingMessages` | Max outstanding messages (for Pub/Sub) | `1000` |
| `broker.googlepubsub.numGoroutines` | Number of goroutines (for Pub/Sub) | `10` |
| `broker.googlepubsub.createTopicIfMissing` | Auto-create topic if it doesn't exist (for Pub/Sub) | `false` |
| `broker.rabbitmq.exchange_type` | RabbitMQ exchange type | `topic` |
| `broker.googlepubsub.project_id` | GCP project ID (for Pub/Sub) | `your-gcp-project-id` |
| `broker.googlepubsub.max_outstanding_messages` | Max outstanding messages (for Pub/Sub) | `1000` |
| `broker.googlepubsub.num_goroutines` | Number of goroutines (for Pub/Sub) | `10` |
| `broker.googlepubsub.create_topic_if_missing` | Auto-create topic if it doesn't exist (for Pub/Sub) | `false` |
| `subscriber.parallelism` | Number of parallel workers for message processing | `1` |
| `existingSecret` | Use existing secret for broker credentials | `""` |

Expand Down Expand Up @@ -135,10 +135,10 @@ broker:
rabbitmq:
# Connection URL with credentials, host, port, and vhost
url: amqp://sentinel-prod:super-secret-password@rabbitmq.messaging.svc.cluster.local:5672/prod
exchangeType: topic
exchange_type: topic

config:
resourceSelector:
resource_selector:
- label: environment
value: production
```
Expand All @@ -156,9 +156,9 @@ helm install sentinel ./charts \
broker:
type: googlepubsub
googlepubsub:
projectId: my-gcp-project
maxOutstandingMessages: 1000
numGoroutines: 10
project_id: my-gcp-project
max_outstanding_messages: 1000
num_goroutines: 10
```

```bash
Expand All @@ -179,7 +179,7 @@ kubectl create secret generic my-broker-credentials \
--from-literal=BROKER_RABBITMQ_URL=amqp://user:pass@rabbitmq.local:5672/

# Note: Google Pub/Sub doesn't require Secret
# projectId is configured in values.yaml (not sensitive)
# project_id is configured in values.yaml (not sensitive)
# Authentication uses Workload Identity in GKE
```

Expand All @@ -190,15 +190,15 @@ Deploy multiple Sentinel instances watching different resource shards:
```yaml
# values-shard-1.yaml
config:
resourceSelector:
resource_selector:
- label: shard
value: "1"
```

```yaml
# values-shard-2.yaml
config:
resourceSelector:
resource_selector:
- label: shard
value: "2"
```
Expand Down
78 changes: 53 additions & 25 deletions charts/templates/configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,58 @@ metadata:
{{- include "sentinel.labels" . | nindent 4 }}
data:
config.yaml: |
# Sentinel information
sentinel:
name: {{ tpl .Values.config.sentinel.name . }}

# Debug configuration
debug_config: {{ .Values.config.debug_config }}

# Logging configuration
log:
level: {{ .Values.config.log.level | quote }}
format: {{ .Values.config.log.format | quote }}
output: {{ .Values.config.log.output | quote }}

# Client configurations
clients:
# HyperFleet API client
hyperfleet_api:
base_url: {{ .Values.config.clients.hyperfleet_api.base_url }}
version: {{ .Values.config.clients.hyperfleet_api.version | quote }}
timeout: {{ .Values.config.clients.hyperfleet_api.timeout }}
retry_attempts: {{ .Values.config.clients.hyperfleet_api.retry_attempts }}
retry_backoff: {{ .Values.config.clients.hyperfleet_api.retry_backoff | quote }}
base_delay: {{ .Values.config.clients.hyperfleet_api.base_delay }}
max_delay: {{ .Values.config.clients.hyperfleet_api.max_delay }}
{{- if .Values.config.clients.hyperfleet_api.default_headers }}
default_headers:
{{- toYaml .Values.config.clients.hyperfleet_api.default_headers | nindent 10 }}
{{- end }}

# Broker client
broker:
topic: {{ tpl .Values.broker.topic . | quote }}

# Sentinel configuration
resource_type: {{ .Values.config.resourceType }}
poll_interval: {{ .Values.config.pollInterval }}
max_age_not_ready: {{ .Values.config.maxAgeNotReady }}
max_age_ready: {{ .Values.config.maxAgeReady }}
resource_type: {{ .Values.config.resource_type }}
poll_interval: {{ .Values.config.poll_interval }}
max_age_not_ready: {{ .Values.config.max_age_not_ready }}
max_age_ready: {{ .Values.config.max_age_ready }}

{{- if .Values.config.resourceSelector }}
{{- if .Values.config.resource_selector }}
# Resource selector for horizontal sharding
resource_selector:
{{- range .Values.config.resourceSelector }}
{{- range .Values.config.resource_selector }}
- label: {{ .label }}
value: {{ .value | quote }}
{{- end }}
{{- end }}

# HyperFleet API configuration
hyperfleet_api:
endpoint: {{ .Values.config.hyperfleetApi.baseUrl }}
timeout: {{ .Values.config.hyperfleetApi.timeout }}

{{- if .Values.config.messageData }}
{{- if .Values.config.message_data }}
# CloudEvents data payload configuration
message_data:
{{- toYaml .Values.config.messageData | nindent 6 }}
{{- toYaml .Values.config.message_data | nindent 6 }}
{{- end }}
---
apiVersion: v1
Expand All @@ -46,24 +74,24 @@ data:
{{- if eq .Values.broker.type "rabbitmq" }}
rabbitmq:
url: {{ .Values.broker.rabbitmq.url | quote }}
exchange_type: {{ .Values.broker.rabbitmq.exchangeType | default "topic" }}
{{- if .Values.broker.rabbitmq.prefetchCount }}
prefetch_count: {{ .Values.broker.rabbitmq.prefetchCount }}
exchange_type: {{ .Values.broker.rabbitmq.exchange_type | default "topic" }}
{{- if .Values.broker.rabbitmq.prefetch_count }}
prefetch_count: {{ .Values.broker.rabbitmq.prefetch_count }}
{{- end }}
{{- if .Values.broker.rabbitmq.prefetchSize }}
prefetch_size: {{ .Values.broker.rabbitmq.prefetchSize }}
{{- if .Values.broker.rabbitmq.prefetch_size }}
prefetch_size: {{ .Values.broker.rabbitmq.prefetch_size }}
{{- end }}
Comment on lines +78 to 83
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, check the current state of configmap.yaml at and around lines 78-83
cd charts/templates && wc -l configmap.yaml

Repository: openshift-hyperfleet/hyperfleet-sentinel

Length of output: 102


🏁 Script executed:

# Read the relevant section of configmap.yaml with context around lines 78-95
sed -n '70,100p' charts/templates/configmap.yaml | cat -n

Repository: openshift-hyperfleet/hyperfleet-sentinel

Length of output: 1729


🏁 Script executed:

# Search for hasKey usage in configmap.yaml to verify the pattern mentioned
grep -n "hasKey" charts/templates/configmap.yaml

Repository: openshift-hyperfleet/hyperfleet-sentinel

Length of output: 165


🏁 Script executed:

# Check for values.yaml or schema that might document these fields
find . -name "values.yaml" -o -name "*schema*" | head -20

Repository: openshift-hyperfleet/hyperfleet-sentinel

Length of output: 104


🏁 Script executed:

# Search for any documentation about broker prefetch settings
find . -type f \( -name "*.md" -o -name "*.txt" \) | xargs grep -l "prefetch\|broker" 2>/dev/null | head -10

Repository: openshift-hyperfleet/hyperfleet-sentinel

Length of output: 244


🏁 Script executed:

# Check if there are any comments in the configmap about these broker settings
sed -n '1,30p' charts/templates/configmap.yaml | cat -n

Repository: openshift-hyperfleet/hyperfleet-sentinel

Length of output: 1323


🏁 Script executed:

# Check values.yaml for broker configuration defaults
grep -A 20 "broker:" charts/values.yaml | head -40

Repository: openshift-hyperfleet/hyperfleet-sentinel

Length of output: 1394


🏁 Script executed:

# Look for documentation about broker settings and zero values
grep -A 5 -B 5 "prefetch\|max_outstanding" docs/configuration.md

Repository: openshift-hyperfleet/hyperfleet-sentinel

Length of output: 66


🏁 Script executed:

# Check if configuration.md mentions broker settings at all
grep -i "broker\|prefetch" docs/configuration.md

Repository: openshift-hyperfleet/hyperfleet-sentinel

Length of output: 483


🏁 Script executed:

# Get more of the broker configuration from values.yaml
grep -A 50 "rabbitmq:" charts/values.yaml | head -60

Repository: openshift-hyperfleet/hyperfleet-sentinel

Length of output: 1922


🏁 Script executed:

# Check for googlepubsub broker config in values.yaml
grep -A 20 "googlepubsub:" charts/values.yaml

Repository: openshift-hyperfleet/hyperfleet-sentinel

Length of output: 788


Preserve explicit zero values for broker tuning.

These truthy guards drop the key entirely when an operator sets 0, so prefetch_count, prefetch_size, max_outstanding_messages, and num_goroutines cannot be intentionally configured to zero. Use the same hasKey pattern you already use for create_topic_if_missing.

Suggested template change
-        {{- if .Values.broker.rabbitmq.prefetch_count }}
+        {{- if hasKey .Values.broker.rabbitmq "prefetch_count" }}
         prefetch_count: {{ .Values.broker.rabbitmq.prefetch_count }}
         {{- end }}
-        {{- if .Values.broker.rabbitmq.prefetch_size }}
+        {{- if hasKey .Values.broker.rabbitmq "prefetch_size" }}
         prefetch_size: {{ .Values.broker.rabbitmq.prefetch_size }}
         {{- end }}
-        {{- if .Values.broker.googlepubsub.max_outstanding_messages }}
+        {{- if hasKey .Values.broker.googlepubsub "max_outstanding_messages" }}
         max_outstanding_messages: {{ .Values.broker.googlepubsub.max_outstanding_messages }}
         {{- end }}
-        {{- if .Values.broker.googlepubsub.num_goroutines }}
+        {{- if hasKey .Values.broker.googlepubsub "num_goroutines" }}
         num_goroutines: {{ .Values.broker.googlepubsub.num_goroutines }}
         {{- end }}
📝 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
{{- if .Values.broker.rabbitmq.prefetch_count }}
prefetch_count: {{ .Values.broker.rabbitmq.prefetch_count }}
{{- end }}
{{- if .Values.broker.rabbitmq.prefetchSize }}
prefetch_size: {{ .Values.broker.rabbitmq.prefetchSize }}
{{- if .Values.broker.rabbitmq.prefetch_size }}
prefetch_size: {{ .Values.broker.rabbitmq.prefetch_size }}
{{- end }}
{{- if hasKey .Values.broker.rabbitmq "prefetch_count" }}
prefetch_count: {{ .Values.broker.rabbitmq.prefetch_count }}
{{- end }}
{{- if hasKey .Values.broker.rabbitmq "prefetch_size" }}
prefetch_size: {{ .Values.broker.rabbitmq.prefetch_size }}
{{- end }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@charts/templates/configmap.yaml` around lines 78 - 83, The template currently
uses truthy guards that drop keys when values are zero; update the guards to use
the hasKey pattern (as used for create_topic_if_missing) so explicit 0 is
preserved. Replace the conditional blocks that reference
.Values.broker.rabbitmq.prefetch_count and .Values.broker.rabbitmq.prefetch_size
with hasKey checks (e.g. hasKey .Values.broker.rabbitmq "prefetch_count"), and
apply the same change for max_outstanding_messages and num_goroutines so those
keys are rendered when set to 0.

{{- else if eq .Values.broker.type "googlepubsub" }}
googlepubsub:
project_id: {{ .Values.broker.googlepubsub.projectId | quote }}
{{- if .Values.broker.googlepubsub.maxOutstandingMessages }}
max_outstanding_messages: {{ .Values.broker.googlepubsub.maxOutstandingMessages }}
project_id: {{ .Values.broker.googlepubsub.project_id | quote }}
{{- if .Values.broker.googlepubsub.max_outstanding_messages }}
max_outstanding_messages: {{ .Values.broker.googlepubsub.max_outstanding_messages }}
{{- end }}
{{- if .Values.broker.googlepubsub.numGoroutines }}
num_goroutines: {{ .Values.broker.googlepubsub.numGoroutines }}
{{- if .Values.broker.googlepubsub.num_goroutines }}
num_goroutines: {{ .Values.broker.googlepubsub.num_goroutines }}
{{- end }}
{{- if hasKey .Values.broker.googlepubsub "createTopicIfMissing" }}
create_topic_if_missing: {{ .Values.broker.googlepubsub.createTopicIfMissing }}
{{- if hasKey .Values.broker.googlepubsub "create_topic_if_missing" }}
create_topic_if_missing: {{ .Values.broker.googlepubsub.create_topic_if_missing }}
{{- end }}
{{- end }}

Expand Down
2 changes: 1 addition & 1 deletion charts/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ spec:
- name: BROKER_CONFIG_FILE
value: /etc/sentinel/broker.yaml
# Topic name for broker publishing
- name: BROKER_TOPIC
- name: HYPERFLEET_BROKER_TOPIC
value: {{ tpl .Values.broker.topic . | quote }}
# Broker credentials can be overridden via environment variables from Secret
{{- if eq .Values.broker.type "rabbitmq" }}
Expand Down
69 changes: 50 additions & 19 deletions charts/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,32 +75,63 @@ podDisruptionBudget:

# Sentinel configuration
config:
# Sentinel information
sentinel:
# Sentinel component name - will be templated with shard value if resource selector is used
# Example: hyperfleet-sentinel-clusters-shard-1
name: hyperfleet-sentinel-{{ .Values.config.resource_type }}

# Debug configuration - log merged config on startup
debug_config: false

# Logging configuration
log:
level: info
format: json
output: stdout

# Client configurations
clients:
# HyperFleet API client configuration
hyperfleet_api:
# Use in-cluster service name for API endpoint
base_url: http://hyperfleet-api:8000
version: v1
timeout: 10s
retry_attempts: 3
retry_backoff: exponential
base_delay: 1s
max_delay: 30s
# Optional default headers
# default_headers:
# X-Custom-Header: "value"

# Broker configuration
# Note: broker implementation details (RabbitMQ URL, etc.) are in broker section below
broker:
# Topic will be set from broker.topic template below
topic: ""

# Resource type to watch (clusters, nodepools)
resourceType: clusters
resource_type: clusters

# How often to poll the API for resource updates
pollInterval: 5s
poll_interval: 5s

# Max age interval for resources not ready
maxAgeNotReady: 10s
max_age_not_ready: 10s

# Max age interval for ready resources
maxAgeReady: 30m
max_age_ready: 30m

# Resource selector for horizontal sharding
# Deploy multiple Sentinel instances with different shard values
resourceSelector:
resource_selector:
- label: shard
value: "1"

# HyperFleet API configuration
hyperfleetApi:
# Use in-cluster service name for API endpoint
baseUrl: http://hyperfleet-api:8000
timeout: 5s

# CloudEvents data payload configuration
messageData:
message_data:
id: resource.id
kind: resource.kind
href: resource.href
Expand All @@ -125,25 +156,25 @@ broker:
# Default uses Helm template: {namespace}-{resourceType} for multi-tenant isolation
# Example result: hyperfleet-dev-clusters, hyperfleet-dev-nodepools
# Override with a static value if needed: topic: "my-custom-topic"
topic: '{{ .Release.Namespace }}-{{ .Values.config.resourceType }}'
topic: '{{ .Release.Namespace }}-{{ .Values.config.resource_type }}'

# RabbitMQ configuration
# Uses BROKER_RABBITMQ_URL environment variable (single connection string)
rabbitmq:
# Connection URL format: amqp://user:password@host:port/vhost
url: amqp://<USER>:<PASSWORD>@rabbitmq.hyperfleet-system.svc.cluster.local:5672/hyperfleet
exchangeType: topic
exchange_type: topic

# Google Pub/Sub configuration (alternative to RabbitMQ)
# projectId is written to broker.yaml ConfigMap (not Secret - it's not sensitive)
# project_id is written to broker.yaml ConfigMap (not Secret - it's not sensitive)
googlepubsub:
#REQUIRED: Replace with your actual GCP project ID
projectId: your-gcp-project-id
maxOutstandingMessages: 1000
numGoroutines: 10
project_id: your-gcp-project-id
max_outstanding_messages: 1000
num_goroutines: 10
# Auto-creation flags (default: false - manual creation required)
# Set to true to automatically create topics/subscriptions if they don't exist
createTopicIfMissing: false
create_topic_if_missing: false

# Subscriber configuration (optional)
subscriber:
Expand Down
Loading