Complete release compatibility and host inventory sprints
Signed-off-by: master <>
This commit is contained in:
@@ -1,237 +0,0 @@
|
||||
# Sprint 20260323-001 — Release API Proxy Fix + Missing Backend Endpoints
|
||||
|
||||
## Topic & Scope
|
||||
- Fix nginx proxy routes so the UI's `/api/v2/releases` calls reach the JobEngine backend.
|
||||
- Implement 41 missing backend endpoints across 5 service areas.
|
||||
- Working directories: `devops/docker/`, `src/JobEngine/`, `src/Platform/`, `src/EvidenceLocker/`
|
||||
- Expected evidence: all release CRUD flows work end-to-end via Playwright.
|
||||
|
||||
## Dependencies & Concurrency
|
||||
- TASK-001 (proxy fix) is prerequisite for all UI testing.
|
||||
- TASK-002 through TASK-006 can run in parallel after TASK-001.
|
||||
|
||||
## Documentation Prerequisites
|
||||
- `docs/modules/release-orchestrator/deployment/overview.md`
|
||||
- `docs/modules/release-orchestrator/deployment/strategies.md`
|
||||
- `src/JobEngine/StellaOps.JobEngine/StellaOps.JobEngine.WebService/Endpoints/ReleaseEndpoints.cs`
|
||||
- `src/JobEngine/StellaOps.JobEngine/StellaOps.JobEngine.WebService/Endpoints/ApprovalEndpoints.cs`
|
||||
|
||||
## Delivery Tracker
|
||||
|
||||
### TASK-001 - Fix nginx proxy routes for release APIs
|
||||
Status: TODO
|
||||
Dependency: none
|
||||
Owners: DevOps / FE
|
||||
|
||||
Task description:
|
||||
The console nginx (`devops/docker/Dockerfile.console`) reverse-proxies API calls. The UI calls:
|
||||
- `/api/v2/releases/*` → should reach JobEngine at `/api/v1/release-orchestrator/releases/*`
|
||||
- `/api/v1/release-control/bundles/*` → should reach JobEngine bundle endpoints
|
||||
- `/api/v1/registries/images/search` → should reach Scanner service
|
||||
- `/api/v2/releases/approvals` → should reach JobEngine approval endpoints
|
||||
- `/api/v2/releases/activity` → should reach JobEngine release events
|
||||
- `/api/v2/releases/runs/*` → should reach JobEngine run workbench
|
||||
|
||||
Options:
|
||||
A) Add nginx `location` blocks in `Dockerfile.console` to proxy these paths to the correct upstream services
|
||||
B) Add proxy routes in the Platform service (which already proxies many paths)
|
||||
C) Update the UI API clients to call the correct backend URLs directly (e.g., change `/api/v2/releases` to `/api/v1/release-orchestrator/releases`)
|
||||
|
||||
Recommended: Option C (most reliable, no proxy chain) + Option A as fallback.
|
||||
|
||||
Implementation for Option C:
|
||||
- Update `src/Web/StellaOps.Web/src/app/core/api/release-management.client.ts` — change base URLs
|
||||
- Update `release.store.ts` — ensure `loadReleases` calls the correct endpoint
|
||||
- Update `release-detail.component.ts` — fix all `/api/v2/releases/` calls to `/api/v1/release-orchestrator/releases/`
|
||||
- Update approval client — fix `/api/v2/releases/approvals` to `/api/v1/release-orchestrator/approvals`
|
||||
|
||||
For nginx (Option A fallback), add to `Dockerfile.console`:
|
||||
```nginx
|
||||
location /api/v2/releases/ {
|
||||
set $orchestrator_upstream http://orchestrator.stella-ops.local;
|
||||
rewrite ^/api/v2/releases/(.*) /api/v1/release-orchestrator/releases/$1 break;
|
||||
proxy_pass $orchestrator_upstream;
|
||||
}
|
||||
|
||||
location /api/v1/release-control/ {
|
||||
set $orchestrator_upstream http://orchestrator.stella-ops.local;
|
||||
rewrite ^/api/v1/release-control/(.*) /api/v1/release-control/$1 break;
|
||||
proxy_pass $orchestrator_upstream;
|
||||
}
|
||||
|
||||
location /api/v1/registries/ {
|
||||
set $scanner_upstream http://scanner.stella-ops.local;
|
||||
rewrite ^/api/v1/registries/(.*) /api/v1/registries/$1 break;
|
||||
proxy_pass $scanner_upstream;
|
||||
}
|
||||
```
|
||||
|
||||
Completion criteria:
|
||||
- [ ] `/api/v2/releases` returns data from JobEngine (not 404)
|
||||
- [ ] `/api/v1/registries/images/search?q=nginx` returns results from Scanner
|
||||
- [ ] `/api/v1/release-control/bundles` POST creates a bundle in JobEngine
|
||||
- [ ] UI pipeline page shows real releases (if any exist)
|
||||
- [ ] UI version create wizard can search registry images
|
||||
|
||||
### TASK-002 - Deployment monitoring endpoints (11 endpoints)
|
||||
Status: TODO
|
||||
Dependency: TASK-001
|
||||
Owners: BE (JobEngine)
|
||||
|
||||
Task description:
|
||||
Add deployment monitoring endpoints to JobEngine's `ReleaseEndpoints.cs` or new `DeploymentEndpoints.cs`:
|
||||
|
||||
```
|
||||
GET /api/v1/release-orchestrator/deployments — list deployments
|
||||
GET /api/v1/release-orchestrator/deployments/{id} — get deployment detail
|
||||
GET /api/v1/release-orchestrator/deployments/{id}/logs — get deployment logs
|
||||
GET /api/v1/release-orchestrator/deployments/{id}/targets/{targetId}/logs — target logs
|
||||
GET /api/v1/release-orchestrator/deployments/{id}/events — deployment events
|
||||
GET /api/v1/release-orchestrator/deployments/{id}/metrics — deployment metrics
|
||||
POST /api/v1/release-orchestrator/deployments/{id}/pause — pause deployment
|
||||
POST /api/v1/release-orchestrator/deployments/{id}/resume — resume deployment
|
||||
POST /api/v1/release-orchestrator/deployments/{id}/cancel — cancel deployment
|
||||
POST /api/v1/release-orchestrator/deployments/{id}/rollback — rollback deployment
|
||||
POST /api/v1/release-orchestrator/deployments/{id}/targets/{targetId}/retry — retry target
|
||||
```
|
||||
|
||||
Each endpoint needs:
|
||||
- Request/response models in contracts
|
||||
- Handler method with auth policy (ReleaseRead for GET, ReleaseWrite for POST)
|
||||
- Minimal implementation (can return mock/empty data initially, wired to real service later)
|
||||
|
||||
Completion criteria:
|
||||
- [ ] All 11 endpoints return 200/201 (not 404)
|
||||
- [ ] GET /deployments returns a list (even if empty)
|
||||
- [ ] POST /pause returns success
|
||||
- [ ] Auth policies enforced
|
||||
|
||||
### TASK-003 - Evidence management endpoints (6 endpoints)
|
||||
Status: TODO
|
||||
Dependency: TASK-001
|
||||
Owners: BE (EvidenceLocker or Attestor)
|
||||
|
||||
Task description:
|
||||
Add evidence lifecycle endpoints — either in EvidenceLocker service or as a new endpoints file in JobEngine:
|
||||
|
||||
```
|
||||
GET /api/v1/release-orchestrator/evidence — list evidence packets
|
||||
GET /api/v1/release-orchestrator/evidence/{id} — get evidence detail
|
||||
POST /api/v1/release-orchestrator/evidence/{id}/verify — verify evidence integrity
|
||||
GET /api/v1/release-orchestrator/evidence/{id}/export — export evidence bundle
|
||||
GET /api/v1/release-orchestrator/evidence/{id}/raw — download raw evidence
|
||||
GET /api/v1/release-orchestrator/evidence/{id}/timeline — evidence timeline
|
||||
```
|
||||
|
||||
Completion criteria:
|
||||
- [ ] All 6 endpoints return valid responses
|
||||
- [ ] Verify endpoint checks hash integrity
|
||||
- [ ] Export returns downloadable content-type
|
||||
|
||||
### TASK-004 - Environment/Target management endpoints (15 endpoints)
|
||||
Status: TODO
|
||||
Dependency: TASK-001
|
||||
Owners: BE (Platform)
|
||||
|
||||
Task description:
|
||||
Add environment and target management endpoints to Platform service. These may already partially exist in the topology/environment subsystem — check before implementing.
|
||||
|
||||
```
|
||||
GET /api/v1/release-orchestrator/environments — list environments
|
||||
GET /api/v1/release-orchestrator/environments/{id} — get environment
|
||||
POST /api/v1/release-orchestrator/environments — create environment
|
||||
PUT /api/v1/release-orchestrator/environments/{id} — update environment
|
||||
DELETE /api/v1/release-orchestrator/environments/{id} — delete environment
|
||||
PUT /api/v1/release-orchestrator/environments/{id}/settings — update settings
|
||||
GET /api/v1/release-orchestrator/environments/{id}/targets — list targets
|
||||
POST /api/v1/release-orchestrator/environments/{id}/targets — add target
|
||||
PUT /api/v1/release-orchestrator/environments/{id}/targets/{tid} — update target
|
||||
DELETE /api/v1/release-orchestrator/environments/{id}/targets/{tid} — remove target
|
||||
POST /api/v1/release-orchestrator/environments/{id}/targets/{tid}/health-check — check health
|
||||
GET /api/v1/release-orchestrator/environments/{id}/freeze-windows — list freeze windows
|
||||
POST /api/v1/release-orchestrator/environments/{id}/freeze-windows — create freeze window
|
||||
PUT /api/v1/release-orchestrator/environments/{id}/freeze-windows/{wid} — update
|
||||
DELETE /api/v1/release-orchestrator/environments/{id}/freeze-windows/{wid} — delete
|
||||
```
|
||||
|
||||
NOTE: The Platform service already has environment data via PlatformContextStore. These endpoints may be aliases or extensions of existing topology endpoints. Check `src/Platform/` for existing environment CRUD before implementing new ones.
|
||||
|
||||
Completion criteria:
|
||||
- [ ] Environment CRUD works
|
||||
- [ ] Target CRUD within environments works
|
||||
- [ ] Health check returns target status
|
||||
- [ ] Freeze window CRUD works
|
||||
|
||||
### TASK-005 - Release dashboard endpoint (3 endpoints)
|
||||
Status: TODO
|
||||
Dependency: TASK-001
|
||||
Owners: BE (JobEngine)
|
||||
|
||||
Task description:
|
||||
Add dashboard summary and promotion decision endpoints:
|
||||
|
||||
```
|
||||
GET /api/v1/release-orchestrator/dashboard — aggregated dashboard data
|
||||
POST /api/v1/release-orchestrator/promotions/{id}/approve — approve promotion
|
||||
POST /api/v1/release-orchestrator/promotions/{id}/reject — reject promotion
|
||||
```
|
||||
|
||||
Dashboard endpoint should return: release counts by status, deployment health, pending approvals, gate summary.
|
||||
|
||||
Completion criteria:
|
||||
- [ ] Dashboard returns aggregated stats
|
||||
- [ ] Approve/reject promotion updates approval status
|
||||
|
||||
### TASK-006 - Registry image search in Scanner service
|
||||
Status: TODO
|
||||
Dependency: none
|
||||
Owners: BE (Scanner)
|
||||
|
||||
Task description:
|
||||
Verify/implement registry image search endpoints in the Scanner service:
|
||||
|
||||
```
|
||||
GET /api/v1/registries/images/search?q={query} — search images by name
|
||||
GET /api/v1/registries/images/digests?repository={repo} — get image digests
|
||||
```
|
||||
|
||||
These are called by Create Version and Create Hotfix wizards. If the Scanner service doesn't have these endpoints, add them. The response format expected by the UI:
|
||||
|
||||
```json
|
||||
// Search response
|
||||
[
|
||||
{
|
||||
"name": "nginx",
|
||||
"repository": "library/nginx",
|
||||
"tags": ["latest", "1.25", "1.25-alpine"],
|
||||
"digests": [
|
||||
{ "tag": "latest", "digest": "sha256:abc123...", "pushedAt": "2026-03-20T10:00:00Z" }
|
||||
],
|
||||
"lastPushed": "2026-03-20T10:00:00Z"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
If no real registry is connected, return mock data so the wizard flow can be tested.
|
||||
|
||||
Completion criteria:
|
||||
- [ ] Search returns image results for common queries (nginx, redis, postgres)
|
||||
- [ ] Digests returns tags + SHA digests for a given repository
|
||||
- [ ] Create Version wizard can search and select images
|
||||
|
||||
## Execution Log
|
||||
| Date (UTC) | Update | Owner |
|
||||
| --- | --- | --- |
|
||||
| 2026-03-23 | Sprint created. TASK-001 is the critical path. | Planning |
|
||||
|
||||
## Decisions & Risks
|
||||
- TASK-001 (proxy fix) is the blocker — without it, no UI endpoint reaches the backend.
|
||||
- Option C (fix UI API URLs) is preferred over nginx rewrites because it eliminates a proxy hop.
|
||||
- Environment endpoints (TASK-004) may overlap with existing Platform topology — investigate before duplicating.
|
||||
- Evidence endpoints (TASK-003) may belong in EvidenceLocker rather than JobEngine — architecture decision needed.
|
||||
- Registry search (TASK-006) needs a connected registry or mock data for testing.
|
||||
|
||||
## Next Checkpoints
|
||||
- After TASK-001: re-run Playwright E2E tests to verify data flows
|
||||
- After TASK-002 + TASK-006: version/hotfix create → list → view flow should work end-to-end
|
||||
- After all tasks: full CRUD across all release control pages
|
||||
@@ -119,11 +119,13 @@ The `CircuitBreakerService` implements the circuit breaker pattern for downstrea
|
||||
- Event envelope draft (`docs/modules/jobengine/event-envelope.md`) defines notifier/webhook/SSE payloads with idempotency keys, provenance, and task runner metadata for job/pack-run events.
|
||||
- OpenAPI discovery: `/.well-known/openapi` exposes `/openapi/jobengine.json` (OAS 3.1) with pagination/idempotency/error-envelope examples; legacy job detail/summary endpoints now ship `Deprecation` + `Link` headers that point to their replacements.
|
||||
|
||||
### 4.5) Release control plane dashboard endpoints
|
||||
- `GET /api/v1/release-jobengine/dashboard` — control-plane dashboard payload (pipeline, pending approvals, active deployments, recent releases).
|
||||
- `POST /api/v1/release-jobengine/promotions/{id}/approve` — approve a pending promotion from dashboard context.
|
||||
- `POST /api/v1/release-jobengine/promotions/{id}/reject` — reject a pending promotion from dashboard context.
|
||||
- Compatibility aliases are exposed for legacy clients under `/api/release-jobengine/*`.
|
||||
### 4.5) Release control plane compatibility endpoints
|
||||
- `GET /api/v1/release-orchestrator/dashboard` — control-plane dashboard payload (pipeline, pending approvals, active deployments, recent releases).
|
||||
- `POST /api/v1/release-orchestrator/promotions/{id}/approve` — approve a pending promotion from dashboard context.
|
||||
- `POST /api/v1/release-orchestrator/promotions/{id}/reject` — reject a pending promotion from dashboard context.
|
||||
- `GET /api/v1/release-orchestrator/deployments` plus detail/log/event/metric endpoints and lifecycle actions (`pause`, `resume`, `cancel`, `rollback`, target `retry`) provide the release deployment monitoring surface used by the Console.
|
||||
- `GET /api/v1/release-orchestrator/evidence` plus `verify`, `export`, `raw`, and `timeline` routes provide deterministic evidence inspection and export for offline audit flows.
|
||||
- Compatibility aliases are exposed for legacy clients under `/api/release-orchestrator/*`.
|
||||
|
||||
All responses include deterministic timestamps, job digests, and DSSE signature fields for offline reconciliation.
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
**Status:** Active Development (backend substantially implemented; API surface layer in progress)
|
||||
|
||||
> **Implementation reality (updated 2026-02-22):** The backend is substantially complete with 140,000+ lines of production code across 49 projects. Core libraries (Release, Promotion, Deployment, Workflow, Evidence, PolicyGate, Progressive, Federation, Compliance) are implemented with comprehensive tests (283 test files, 37K lines). Six agent types are operational (Compose, Docker, SSH, WinRM, ECS, Nomad). The DAG workflow engine, promotion/approval framework, and evidence generation are functional. **Remaining gaps:** HTTP API layer is minimal (1 controller), no database migrations yet (in-memory stores only), and no Program.cs bootstrapping for the WebApi project.
|
||||
> **Implementation reality (updated 2026-03-31):** The backend is substantially complete with 140,000+ lines of production code across 49 projects. Core libraries (Release, Promotion, Deployment, Workflow, Evidence, PolicyGate, Progressive, Federation, Compliance) are implemented with comprehensive tests (283 test files, 37K lines). Six agent types are operational (Compose, Docker, SSH, WinRM, ECS, Nomad). Compatibility HTTP surfaces now exist across Platform, JobEngine, and Scanner for environment management, deployment monitoring, evidence inspection, dashboard promotion decisions, and registry search. **Remaining gaps:** the dedicated Release Orchestrator WebApi host is still incomplete, storage remains in-memory for these compatibility surfaces, and first-class migrations/persistence for the standalone API are still pending.
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -189,7 +189,7 @@ public sealed record Target
|
||||
public required Guid TenantId { get; init; }
|
||||
public required Guid EnvironmentId { get; init; }
|
||||
public required string Name { get; init; }
|
||||
public required TargetType Type { get; init; } // DockerHost, ComposeHost, ECSService, NomadJob
|
||||
public required TargetType Type { get; init; } // DockerHost, ComposeHost, EcsService, NomadJob, SshHost, WinRmHost
|
||||
public required ImmutableDictionary<string, string> Labels { get; init; }
|
||||
public required Guid? AgentId { get; init; } // Null for agentless
|
||||
public required TargetState State { get; init; }
|
||||
@@ -202,8 +202,8 @@ public enum TargetType
|
||||
ComposeHost,
|
||||
ECSService,
|
||||
NomadJob,
|
||||
SSHRemote,
|
||||
WinRMRemote
|
||||
SshHost,
|
||||
WinRmHost
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user