20 Commits
Author SHA1 Message Date
Story Crater Bot 3d52eab41d fix(ci,deps): migrate to .gitea/workflows, update domain to forgejo.riotpiao.com/rock, fix k8s argocd config
ci / test (push) Canceled after 0s
2026-08-21 20:14:58 -07:00
Story Crater Bot f599d2d897 fix: drop dead Authentik env-var validation now that auth interceptors are unwired 2026-07-13 16:45:53 -07:00
Story Crater Bot 52b86ab8e8 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).
2026-07-13 13:02:40 -07:00
Story Crater Bot a584fb4462 fix: don't set cross-namespace owner ref on TemporalWorker
Queue lives in the sqs namespace while its TemporalWorker is created
in the Temporal namespace (KMSVC_TEMPORAL_NAMESPACE), so
SetControllerReference always failed with "cross-namespace owner
references are disallowed". Drop the owner ref (lifecycle already
handled explicitly in reconcileDelete) and move Spec population into
the CreateOrUpdate mutate closure so updates to an existing
TemporalWorker actually stick.

Also commit the generated TemporalWorker CRD and RBAC rules
(temporalworkers, deployments) that were previously untracked.
2026-07-13 11:32:04 -07:00
Story Crater Bot 9c01076092 feat: switch to public GitHub kmsvc-proto dependency and GHCR image builds
Forgejo registry unreachable from cluster nodes (WireGuard overlay vs LAN
network isolation, plus host-to-ClusterIP routing gaps). Move to public
GitHub dependency and GHCR image hosting to remove the private-network
dependency entirely.
2026-07-13 10:09:41 -07:00
Story Crater Bot c354876178 test: add comprehensive TemporalWorker tests
Queue reconciliation:
- TemporalWorker creation when label present
- Namespace label validation
- Kubernetes name validation
- Cleanup on Queue deletion

Validation helpers:
- isValidTemporalNamespace (8 cases)
- validateKubernetesName (9 cases)

TemporalWorker controller:
- Deployment creation and updates
- Env var injection including TEMPORAL_TASK_QUEUE
- Status tracking
- Delete handling
2026-07-11 07:30:33 -07:00
Story Crater Bot 317396e785 feat: add TemporalWorker auto-provisioning from Queue labels
- Validate temporal namespace and Kubernetes names
- Configurable via env vars: KMSVC_TEMPORAL_NAMESPACE, KMSVC_TEMPORAL_WORKER_IMAGE
- Set ownerReference for cascade deletion and lifecycle management
- Use CreateOrUpdate for spec propagation (idempotent)
- Clean up TemporalWorker on Queue deletion
2026-07-11 07:30:13 -07:00
Story Crater BotandClaude Haiku 4.5 6577efc100 feat: add TemporalWorker CRD and controller
Add TemporalWorker CRD definition with full status tracking and
TemporalWorkerReconciler that manages Deployment lifecycle:
- Auto-generate DeepCopy methods via kubebuilder markers
- Controller creates/updates Deployments matching worker spec
- Injects TEMPORAL_FRONTEND_ADDRESS and TEMPORAL_NAMESPACE env vars
- Tracks replica count and ready status
- Handles graceful deletion via finalizer

Design document (TEMPORAL_INTEGRATION.md) describes three-phase roadmap:
- Phase 1 (MVP): Manual TemporalWorker CRD creation
- Phase 2: Auto-provisioning from Queue labels
- Phase 3: Autoscaling based on queue depth

Co-Authored-By: Claude Haiku 4.5 <[email protected]>
2026-07-11 07:29:34 -07:00
riotpiaole c7eeed2617 feat: stamp Queue shard status with availability zones
Resolves each shard topic's replica broker IDs (internal/kafka.Admin.
ReplicaBrokerIDs) to the topology.kubernetes.io/zone labels of the nodes
hosting those brokers (ZoneLocator), and writes the result into
ShardStatus.AvailabilityZones each reconcile. Uses mgr.GetAPIReader()
rather than the cached client for the Pod/Node lookups, since the cached
client would otherwise require cluster-wide list/watch RBAC on Pods just
to serve occasional point Gets.
2026-06-22 17:30:26 -07:00
riotpiaole 9fa5420b22 fix: queue-operator dropped reconcile namespace and overflowed hash-range status
main.go called Reconcile(ctx, req.Name) without req.Namespace, so the
Get against the namespaced Queue CRD always 404'd and was silently
swallowed as success -- no shard topics or Redis state were ever created.

Separately, ShardStatus.HashRangeStart/End were uint32, but controller-gen
maps that to OpenAPI format:int32, whose max (2147483647) is smaller than
FullHashRangeEnd (0xFFFFFFFF), so the apiserver rejected every status
update with the (misleadingly empty-looking) "must be of type integer with
format int32" error. Widened to int64, regenerated the CRD, and synced the
chart's bundled copy.
2026-06-22 12:23:23 -07:00
riotpiaole 26b6922ad4 feat: implement gRPC server + grpc-gateway wiring (task 9)
Assembles tasks 1/6/7/8 into a runnable cmd/server binary: QueueServiceServer
handlers translating kafkamgmt.v1 proto to internal/core/queue's plain Go
types, a lazy per-queue Kafka consumer registry for ReceiveMessage, and a
Redis-scan-based queue discovery loop that starts a reaper goroutine per
queue (queue lifecycle isn't exposed over gRPC, so this is the server's only
signal). Promotes kmsvc-proto to a direct go.mod dependency.

Handler-level integration tests run against kfake+miniredis (same documented
tradeoff as tasks 5-7's envtest/testcontainers substitution), exercising
send->receive->delete through the real QueueServiceServer implementation.
2026-06-22 06:30:25 -07:00
riotpiaole b3be1f929a refactor: consume kmsvc-proto as a Go module instead of local generation
Remove local proto/, buf.yaml, buf.gen.yaml, and generated
internal/api/v1/*.pb.go. The message-plane contract now lives in the
sibling repo kmsvc-proto (forgejo.riotpiao.homelab.com/rock/kmsvc-proto),
fetched via go get — no local buf/protoc plugin install needed.

Nothing in this repo imported internal/api/v1 yet, so this is a clean
swap with no call-site changes.
2026-06-21 19:47:43 -07:00
riotpiaole ef7b54710d feat(auth): add Authentik JWT validation shared by gRPC and REST
JWKS caching via lestrrat-go/jwx, signature/iss/aud/exp validation, and
a single gRPC interceptor that grpc-gateway's forwarded headers make
work identically for REST callers.
2026-06-21 18:55:23 -07:00
riotpiaole 1373b9e548 feat(reaper): add redelivery/DLQ sweep
Per-queue ticker that scans vis_index for expired in-flight messages and
drives each through the atomic reap.lua check-and-act, routing maxed-out
messages to their queue's configured DLQ via the existing SendMessage
path. Safe to run from multiple replicas against the same queue.
2026-06-21 17:08:48 -07:00
riotpiaole b1f039ae25 feat(queue): add message-plane core logic for send/receive/delete/visibility
Implements SendMessage (size cap, FIFO dedup, shard routing), ReceiveMessage
(long-poll loop across active+closing shards, FIFO per-group exclusivity
gating, redelivery hand-out), DeleteMessage (ack + low-watermark offset
advancement), and ChangeMessageVisibility against the Redis state layer
and a real Kafka producer/consumer.
2026-06-21 17:08:24 -07:00
riotpiaole 3ac4083a68 feat(operator): add queue-operator CRD reconciler with shard split/drain
Reconciles Queue CRs into Kafka topics + Redis shard-map/queue-meta state:
creates shard-0 on first reconcile, splits a shard's hash range into two
children once its split threshold is crossed, drains and closes a parent
shard once its consumer group has fully caught up and its retention
window has elapsed, and tears down every shard's topic + Redis state on
deletion. Includes the manager entrypoint (cmd/queue-operator) and RBAC.
2026-06-21 17:08:17 -07:00
riotpiaole a04c76a684 feat(redis): add shard-aware key schema, Lua scripts, and atomic ops
Implements the kmsvc: key schema (inflight, pending/watermark keyed by
shard+partition, vis_index, dedup, fifo_lock, queue meta, shard map) plus
the atomic reap/ack Lua scripts used for safe multi-replica redelivery
and DLQ routing.
2026-06-21 17:05:38 -07:00
riotpiaole b704d401a1 feat(kafka): add shard-aware topology, admin, and client layer
Topic naming (kmsvc.{queue}.shard-{id} / .fifo.shard-{id} / .dlq.shard-{id}),
hash-range shard selection/splitting (murmur2-based, matching Kafka's
default partitioner), and topic admin/producer/consumer client
constructors shared by the operator and the message-plane.
2026-06-21 16:59:54 -07:00
riotpiaole d38ce2ac92 feat(proto): define message-plane gRPC/REST API
Adds queue_service.proto (SendMessage, SendMessageBatch, ReceiveMessage,
DeleteMessage, DeleteMessageBatch, ChangeMessageVisibility(Batch)) with
grpc-gateway REST annotations, plus the generated Go server/client and
gateway stubs.
2026-06-21 16:59:41 -07:00
riotpiaole db02d0fa7f chore: scaffold Go module, codegen tooling, and shared runtime config
Sets up go.mod/go.sum, buf (proto codegen) configuration, and the
env-driven Config shared by the message-plane server and queue-operator.
2026-06-21 16:59:35 -07:00