feat: queue-operator auto-registers Temporal namespace before creating TemporalWorker

A Queue's temporal.io/namespace label was trusted as-is -- if the referenced
Temporal namespace was never registered (or typo'd), the failure only
surfaced as a worker pod silently polling a namespace that doesn't exist.
Now reconcileTemporalWorker calls RegisterNamespace (idempotent, ignores
AlreadyExists) via a direct WorkflowService gRPC client before creating the
TemporalWorker, so namespace and worker always come into existence together.

Also grant queue-operator's ClusterRole create/delete on temporalworkers
(previously missing, causing forbidden errors on the create-then-delete path).
This commit is contained in:
Story Crater Bot
2026-07-13 13:02:40 -07:00
parent a584fb4462
commit 52b86ab8e8
10 changed files with 299 additions and 15 deletions
+9 -4
View File
@@ -36,10 +36,11 @@ const minInsyncReplicas = 2
// QueueReconciler reconciles Queue objects (design.md §2a).
type QueueReconciler struct {
Client client.Client
Admin TopicAdmin
Redis *goredis.Client
Now func() time.Time
Client client.Client
Admin TopicAdmin
Redis *goredis.Client
Now func() time.Time
Temporal TemporalNamespaceRegisterer
// Zones resolves shard topics' broker placement to availability zones
// (design.md §2a AZ-awareness). Nil disables zone annotation entirely --
@@ -248,6 +249,10 @@ func (r *QueueReconciler) reconcileTemporalWorker(ctx context.Context, queue *km
return fmt.Errorf("invalid kubernetes name %q: %w", workerName, err)
}
if err := r.Temporal.RegisterNamespace(ctx, namespace); err != nil {
return fmt.Errorf("register temporal namespace %s: %w", namespace, err)
}
replicas := int32(1)
workerNamespace := getEnvOrDefault("KMSVC_TEMPORAL_NAMESPACE", "temporal")
workerImage := getEnvOrDefault("KMSVC_TEMPORAL_WORKER_IMAGE", "story-crater-backend:latest")