Skip to content

Commit 24e0bd0

Browse files
Rename sentinel → zentinel across entire codebase
- Brand: Sentinel → Zentinel (Zen + Sentinel) - Domain: sentinel.raskell.io → zentinelproxy.io - GitHub org: raskell-io → zentinelproxy - Package/crate names: sentinel-* → zentinel-* - Module names: sentinel_* → zentinel_* - All source, config, docs, CI/CD updated
1 parent 068fc74 commit 24e0bd0

606 files changed

Lines changed: 2905 additions & 2905 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/CLAUDE.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# Sentinel Control Plane - Development Guide
1+
# Zentinel Control Plane - Development Guide
22

33
## Overview
44

5-
Sentinel CP is a fleet management control plane for Sentinel reverse proxies, built in Elixir/Phoenix. It provides:
5+
Zentinel CP is a fleet management control plane for Zentinel reverse proxies, built in Elixir/Phoenix. It provides:
66

77
- Bundle compilation and distribution
88
- Safe rollout orchestration with health gates
@@ -44,7 +44,7 @@ mise run test
4444
│ └───────────────────────────┘
4545
4646
┌──────┴──────────────────────────────────────────────────────┐
47-
Sentinel Nodes │
47+
Zentinel Nodes │
4848
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
4949
│ │ Node 1 │ │ Node 2 │ │ Node 3 │ │ Node N │ ... │
5050
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
@@ -55,7 +55,7 @@ mise run test
5555

5656
```
5757
lib/
58-
├── sentinel_cp/
58+
├── zentinel_cp/
5959
│ ├── accounts/ # Users, API keys, authentication
6060
│ ├── audit/ # Audit logging
6161
│ ├── auth/ # JWT signing keys, node tokens (Ed25519)
@@ -64,11 +64,11 @@ lib/
6464
│ ├── nodes/ # Node management, heartbeats
6565
│ ├── orgs/ # Multi-org support, memberships
6666
│ ├── projects/ # Project/tenant management
67-
│ ├── prom_ex/ # Prometheus metrics (custom Sentinel plugin)
67+
│ ├── prom_ex/ # Prometheus metrics (custom Zentinel plugin)
6868
│ ├── rollouts/ # Rollout orchestration, tick worker, health gates
6969
│ ├── simulator/ # Node simulator (GenServer fleet)
7070
│ └── webhooks/ # GitHub webhook integration (GitOps)
71-
└── sentinel_cp_web/
71+
└── zentinel_cp_web/
7272
├── controllers/ # REST API + webhook endpoints
7373
├── live/ # LiveView pages (dashboard, nodes, bundles, rollouts, audit, orgs)
7474
├── plugs/ # Auth, API auth, node auth, scope checking, org scoping
@@ -79,7 +79,7 @@ lib/
7979

8080
### Bundles
8181
Immutable, content-addressed configuration artifacts:
82-
- Validated via `sentinel validate`
82+
- Validated via `zentinel validate`
8383
- Compressed as `.tar.zst`
8484
- Stored in S3/MinIO
8585
- Identified by SHA256 hash
@@ -92,7 +92,7 @@ Safe deployment plans:
9292
- Manual rollback support
9393

9494
### Nodes
95-
Sentinel proxy instances:
95+
Zentinel proxy instances:
9696
- Pull-based bundle distribution
9797
- Heartbeat-based health tracking
9898
- Per-node status during rollouts
@@ -102,7 +102,7 @@ Sentinel proxy instances:
102102
- **Development/Test**: SQLite (zero configuration)
103103
- **Production**: PostgreSQL
104104

105-
The adapter is selected at compile time via `config :sentinel_cp, :ecto_adapter`.
105+
The adapter is selected at compile time via `config :zentinel_cp, :ecto_adapter`.
106106

107107
## Background Jobs
108108

@@ -158,11 +158,11 @@ When implementing features:
158158

159159
### Naming Conventions
160160

161-
- Contexts: `SentinelCp.Nodes`, `SentinelCp.Bundles`, `SentinelCp.Orgs`
162-
- Schemas: `SentinelCp.Nodes.Node`, `SentinelCp.Bundles.Bundle`, `SentinelCp.Orgs.Org`
163-
- Workers: `SentinelCp.Rollouts.TickWorker`, `SentinelCp.Bundles.CompileWorker`
164-
- LiveViews: `SentinelCpWeb.NodesLive.Index`, `SentinelCpWeb.DashboardLive.Index`
165-
- Plugs: `SentinelCpWeb.Plugs.Auth`, `SentinelCpWeb.Plugs.NodeAuth`
161+
- Contexts: `ZentinelCp.Nodes`, `ZentinelCp.Bundles`, `ZentinelCp.Orgs`
162+
- Schemas: `ZentinelCp.Nodes.Node`, `ZentinelCp.Bundles.Bundle`, `ZentinelCp.Orgs.Org`
163+
- Workers: `ZentinelCp.Rollouts.TickWorker`, `ZentinelCp.Bundles.CompileWorker`
164+
- LiveViews: `ZentinelCpWeb.NodesLive.Index`, `ZentinelCpWeb.DashboardLive.Index`
165+
- Plugs: `ZentinelCpWeb.Plugs.Auth`, `ZentinelCpWeb.Plugs.NodeAuth`
166166

167167
## Environment Variables
168168

@@ -172,9 +172,9 @@ When implementing features:
172172
| `SECRET_KEY_BASE` | Phoenix secret | Required in prod |
173173
| `PHX_HOST` | Public hostname | `localhost` |
174174
| `PORT` | HTTP port | `4000` |
175-
| `S3_BUCKET` | Bundle storage bucket | `sentinel-bundles` |
175+
| `S3_BUCKET` | Bundle storage bucket | `zentinel-bundles` |
176176
| `S3_ENDPOINT` | S3/MinIO endpoint | `http://localhost:9000` |
177177
| `S3_ACCESS_KEY_ID` | S3 access key | - |
178178
| `S3_SECRET_ACCESS_KEY` | S3 secret key | - |
179-
| `SENTINEL_BINARY` | Path to `sentinel` CLI binary | `sentinel` |
179+
| `ZENTINEL_BINARY` | Path to `zentinel` CLI binary | `zentinel` |
180180
| `GITHUB_WEBHOOK_SECRET` | HMAC secret for GitHub webhooks | - |

.claude/CONTROL_PLANE_ROADMAP.md

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# Sentinel Control Plane (Elixir) — Implementation Roadmap
1+
# Zentinel Control Plane (Elixir) — Implementation Roadmap
22

3-
> Refined implementation plan for the Sentinel Control Plane in Elixir/Phoenix.
3+
> Refined implementation plan for the Zentinel Control Plane in Elixir/Phoenix.
44
55
## 0) Goals, Non-goals, Principles
66

@@ -31,7 +31,7 @@
3131
- REST API for nodes and operators
3232
- LiveView for operator workflows
3333
2. **Compiler Service (Hybrid)**
34-
- Uses `sentinel validate` for validation (shells out to Rust binary)
34+
- Uses `zentinel validate` for validation (shells out to Rust binary)
3535
- Elixir handles bundling, hashing, signing, storage
3636
3. **Bundle Store**
3737
- S3/MinIO (always — MinIO for dev, S3/compatible for prod)
@@ -43,7 +43,7 @@
4343
### Data Flow (v1: pull)
4444
```
4545
Desired state updated (via API or GitOps webhook)
46-
→ Compiler validates config via `sentinel validate`
46+
→ Compiler validates config via `zentinel validate`
4747
→ Produces Bundle (tar.zst)
4848
→ Stored in MinIO/S3
4949
→ Rollout controller assigns target nodes
@@ -60,11 +60,11 @@ Desired state updated (via API or GitOps webhook)
6060
Single Phoenix application with clear module boundaries:
6161

6262
```
63-
sentinel-cp/
63+
zentinel-cp/
6464
├── .claude/
6565
│ └── CONTROL_PLANE_ROADMAP.md
6666
├── lib/
67-
│ ├── sentinel_cp/
67+
│ ├── zentinel_cp/
6868
│ │ ├── bundles/ # Bundle lifecycle
6969
│ │ ├── compiler/ # Compilation pipeline
7070
│ │ ├── nodes/ # Node management
@@ -74,7 +74,7 @@ sentinel-cp/
7474
│ │ ├── audit/ # Audit logging
7575
│ │ ├── storage/ # S3/MinIO abstraction
7676
│ │ └── simulator/ # Node simulator for testing
77-
│ └── sentinel_cp_web/
77+
│ └── zentinel_cp_web/
7878
│ ├── controllers/ # REST API
7979
│ ├── live/ # LiveView pages
8080
│ └── components/ # UI components
@@ -95,7 +95,7 @@ sentinel-cp/
9595
```elixir
9696
# Core entities
9797
Project # Tenant boundary
98-
Node # Sentinel instance
98+
Node # Zentinel instance
9999
NodeGroup # Label selector or explicit set
100100
DesiredConfig # Raw inputs (manifests)
101101
Bundle # Compiled immutable artifact
@@ -121,7 +121,7 @@ Org # Organization boundary
121121
```
122122
bundle.tar.zst
123123
├── manifest.json # Metadata + hashes
124-
├── config.json # Merged sentinel config
124+
├── config.json # Merged zentinel config
125125
└── checksums.txt # Per-file SHA256
126126
```
127127

@@ -140,7 +140,7 @@ bundle.tar.zst
140140
"config.json": "sha256:..."
141141
},
142142
"compat": {
143-
"sentinel_min_version": "2025.01"
143+
"zentinel_min_version": "2025.01"
144144
},
145145
"risk": "low|medium|high",
146146
"risk_reasons": []
@@ -308,7 +308,7 @@ CREATE TABLE audit_logs (
308308
## 6) API Design
309309

310310
### Node Authentication
311-
- Static node keys (v1): `X-Sentinel-Node-Key: <random>` stored hashed
311+
- Static node keys (v1): `X-Zentinel-Node-Key: <random>` stored hashed
312312
- v1.1: Add JWT option for short-lived tokens
313313

314314
### Node Endpoints
@@ -367,12 +367,12 @@ GET /api/v1/projects/:project/audit_logs
367367
## 7) Compiler Pipeline (Hybrid Approach)
368368

369369
### Strategy
370-
Use `sentinel validate` for validation, Elixir for bundling:
370+
Use `zentinel validate` for validation, Elixir for bundling:
371371

372372
```elixir
373-
defmodule SentinelCp.Compiler do
373+
defmodule ZentinelCp.Compiler do
374374
def compile(project, desired_config) do
375-
with {:ok, validated} <- validate_with_sentinel(desired_config),
375+
with {:ok, validated} <- validate_with_zentinel(desired_config),
376376
{:ok, bundle_content} <- build_bundle(project, validated),
377377
{:ok, hashes} <- compute_hashes(bundle_content),
378378
{:ok, manifest} <- build_manifest(project, hashes, desired_config),
@@ -383,17 +383,17 @@ defmodule SentinelCp.Compiler do
383383
end
384384
end
385385

386-
defp validate_with_sentinel(config) do
386+
defp validate_with_zentinel(config) do
387387
# Write config to temp file
388-
# Run: sentinel validate --json <temp_file>
388+
# Run: zentinel validate --json <temp_file>
389389
# Parse JSON output for errors/warnings
390390
end
391391
end
392392
```
393393

394394
### Risk Scoring (v1 minimal)
395395
```elixir
396-
defmodule SentinelCp.Compiler.Risk do
396+
defmodule ZentinelCp.Compiler.Risk do
397397
def score(prev_bundle, new_bundle) do
398398
reasons = []
399399

@@ -421,32 +421,32 @@ end
421421
### Oban Jobs
422422
```elixir
423423
# Process rollout ticks
424-
defmodule SentinelCp.Rollouts.TickWorker do
424+
defmodule ZentinelCp.Rollouts.TickWorker do
425425
use Oban.Worker, queue: :rollouts, max_attempts: 3
426426

427427
@impl Oban.Worker
428428
def perform(%Oban.Job{args: %{"rollout_id" => rollout_id}}) do
429-
SentinelCp.Rollouts.Orchestrator.tick(rollout_id)
429+
ZentinelCp.Rollouts.Orchestrator.tick(rollout_id)
430430
end
431431
end
432432

433433
# Mark stale nodes offline
434-
defmodule SentinelCp.Nodes.StalenessWorker do
434+
defmodule ZentinelCp.Nodes.StalenessWorker do
435435
use Oban.Worker, queue: :maintenance
436436

437437
@impl Oban.Worker
438438
def perform(_job) do
439-
SentinelCp.Nodes.mark_stale_offline()
439+
ZentinelCp.Nodes.mark_stale_offline()
440440
end
441441
end
442442

443443
# Clean old bundles
444-
defmodule SentinelCp.Bundles.GCWorker do
444+
defmodule ZentinelCp.Bundles.GCWorker do
445445
use Oban.Worker, queue: :maintenance
446446

447447
@impl Oban.Worker
448448
def perform(_job) do
449-
SentinelCp.Bundles.garbage_collect()
449+
ZentinelCp.Bundles.garbage_collect()
450450
end
451451
end
452452
```
@@ -462,7 +462,7 @@ NodeBundleStatus: assigned → staged → activated → verified
462462

463463
### Health Gates (v1)
464464
```elixir
465-
defmodule SentinelCp.Rollouts.HealthGates do
465+
defmodule ZentinelCp.Rollouts.HealthGates do
466466
def check(rollout, step) do
467467
nodes = get_step_nodes(step)
468468

@@ -488,13 +488,13 @@ end
488488
## 9) Node Simulator
489489

490490
### Purpose
491-
- Test rollout logic without real Sentinel instances
491+
- Test rollout logic without real Zentinel instances
492492
- Load testing (simulate 100+ nodes)
493493
- CI integration tests
494494

495495
### Implementation
496496
```elixir
497-
defmodule SentinelCp.Simulator.Node do
497+
defmodule ZentinelCp.Simulator.Node do
498498
use GenServer
499499

500500
defstruct [:id, :name, :project_id, :node_key, :current_bundle, :state, :config]
@@ -558,12 +558,12 @@ defmodule SentinelCp.Simulator.Node do
558558
end
559559
end
560560

561-
defmodule SentinelCp.Simulator.Fleet do
561+
defmodule ZentinelCp.Simulator.Fleet do
562562
@moduledoc "Spawn and manage multiple simulated nodes"
563563

564564
def spawn_nodes(project_id, count, opts \\ []) do
565565
for i <- 1..count do
566-
SentinelCp.Simulator.Node.start_link(
566+
ZentinelCp.Simulator.Node.start_link(
567567
name: "sim-node-#{i}",
568568
project_id: project_id,
569569
config: %{
@@ -666,7 +666,7 @@ Log all mutations:
666666

667667
### Phase 3 — Compiler
668668
**Deliverables:**
669-
- `sentinel validate` integration
669+
- `zentinel validate` integration
670670
- Bundle assembly (tar.zst)
671671
- Hashing + manifest generation
672672
- Risk scoring (basic)

.claude/FEATURE_ROADMAP_V2.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
# Sentinel Control Plane — Feature Roadmap v2
1+
# Zentinel Control Plane — Feature Roadmap v2
22

33
> Competitive feature roadmap based on analysis of nevisAdmin4, HAProxy Fusion,
44
> NGINX One, Traefik Hub, Kong Konnect, and Envoy/Istio control planes.
55
>
6-
> **Goal:** Make Sentinel CP a "single pane of glass" where everything can be
6+
> **Goal:** Make Zentinel CP a "single pane of glass" where everything can be
77
> configured and deployed through one application (inspired by nevisAdmin4).
88
99
---
@@ -36,7 +36,7 @@
3636

3737
## Phase 8 — Full Proxy Configuration (Complete)
3838

39-
> Make Sentinel CP capable of configuring all core proxy features through the UI.
39+
> Make Zentinel CP capable of configuring all core proxy features through the UI.
4040
> Every competitor has these — they are table stakes.
4141
4242
### 8.1 TLS / Certificate Management — DONE
@@ -130,7 +130,7 @@
130130

131131
## Phase 10 — Traffic Intelligence (Complete)
132132

133-
> Advanced traffic management features that differentiate Sentinel CP.
133+
> Advanced traffic management features that differentiate Zentinel CP.
134134
135135
### 10.1 Traffic Splitting / Weighted Routing — DONE
136136
- [x] Weight-based routing between upstream groups (canary at the proxy level) — `Service.traffic_split`
@@ -238,11 +238,11 @@ All originally-identified stretch goals have been implemented:
238238

239239
## Competitive Positioning
240240

241-
### Where Sentinel CP Can Win
241+
### Where Zentinel CP Can Win
242242
1. **Unified config-to-deploy pipeline** — nevisAdmin4-style "configure everything and
243243
deploy from one place" but for a general-purpose proxy (not vendor-locked)
244244
2. **Immutable, signed bundles** — unique in the space; most competitors do live config
245-
pushes. Sentinel's compile→sign→distribute model is inherently safer.
245+
pushes. Zentinel's compile→sign→distribute model is inherently safer.
246246
3. **Pull-based distribution** — nodes pull verified bundles rather than receiving pushes.
247247
Better security posture than HAProxy Fusion or NGINX One push models.
248248
4. **Configuration templates with best practices** — nevisAdmin4's strongest idea,
@@ -254,7 +254,7 @@ All originally-identified stretch goals have been implemented:
254254
1. **WAF maturity** — HAProxy and NGINX/F5 have years of WAF signature development
255255
2. **Plugin ecosystem** — Kong's 100+ plugins are hard to replicate
256256
3. **API lifecycle management** — Kong Konnect and Traefik Hub are full API platforms
257-
4. **Service mesh** — Istio/Envoy own this space; Sentinel is not a mesh
257+
4. **Service mesh** — Istio/Envoy own this space; Zentinel is not a mesh
258258
5. **AI-assisted config** — NGINX One has AI config assistance (potential future feature)
259259

260260
---

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ erl_crash.dump
2323
/tmp/
2424

2525
# Ignore package tarball (built via "mix hex.build").
26-
sentinel_cp-*.tar
26+
zentinel_cp-*.tar
2727

2828
# Ignore assets that are produced by build tools.
2929
/priv/static/assets/

Dockerfile

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,16 @@ ENV MIX_ENV=prod
6363
ENV PHX_SERVER=true
6464

6565
# Copy the release from the build stage
66-
COPY --from=builder /app/_build/prod/rel/sentinel_cp ./
66+
COPY --from=builder /app/_build/prod/rel/zentinel_cp ./
6767

6868
# Create a non-root user
69-
RUN groupadd -r sentinel && useradd -r -g sentinel sentinel
70-
RUN chown -R sentinel:sentinel /app
71-
USER sentinel
69+
RUN groupadd -r zentinel && useradd -r -g zentinel zentinel
70+
RUN chown -R zentinel:zentinel /app
71+
USER zentinel
7272

7373
EXPOSE 4000
7474

7575
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
7676
CMD curl -f http://localhost:4000/health || exit 1
7777

78-
CMD /app/bin/sentinel_cp eval "SentinelCp.Release.migrate()" && /app/bin/sentinel_cp start
78+
CMD /app/bin/zentinel_cp eval "ZentinelCp.Release.migrate()" && /app/bin/zentinel_cp start

0 commit comments

Comments
 (0)