Skip to content
Merged
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
242 changes: 215 additions & 27 deletions e2e/tests/scenario-92-infra-admin.spec.ts

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.26.0

require (
github.com/DATA-DOG/go-sqlmock v1.5.2
github.com/GoCodeAlone/workflow v0.72.0
github.com/GoCodeAlone/workflow v0.74.0
github.com/GoCodeAlone/workflow-plugin-data-engineering v0.3.1
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af
gopkg.in/yaml.v3 v3.0.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ github.com/GoCodeAlone/modular/modules/jsonschema v1.17.0 h1:zoWioqUvuNNDfnjHA1s
github.com/GoCodeAlone/modular/modules/jsonschema v1.17.0/go.mod h1:GDU/jsD6AddmXKedj0wZwieUIaQsTBSGMzuj+XHXMrw=
github.com/GoCodeAlone/modular/modules/reverseproxy/v2 v2.10.0 h1:+2M/ecyCxDiXfJM4ibcERuu/BBeIbLTQNcVgRsllR64=
github.com/GoCodeAlone/modular/modules/reverseproxy/v2 v2.10.0/go.mod h1:tlVH1mA5yuU8CB7R7+HXIRaBixZoNid6h+5tew5u3FU=
github.com/GoCodeAlone/workflow v0.72.0 h1:h8t3NKqCGyTiK5uiaBcpqx3P9Jkz78OMQ3fbRvS7ong=
github.com/GoCodeAlone/workflow v0.72.0/go.mod h1:i/9ZTfR8YYlmr0+hvIZi4cYw7SxzkQRLlzYQCrRD/2k=
github.com/GoCodeAlone/workflow v0.74.0 h1:29/sBHzhHsFW6cPFHRUa0AuUVUVnt9ScrTvt+8F+qbQ=
github.com/GoCodeAlone/workflow v0.74.0/go.mod h1:i/9ZTfR8YYlmr0+hvIZi4cYw7SxzkQRLlzYQCrRD/2k=
github.com/GoCodeAlone/workflow-plugin-data-engineering v0.3.1 h1:NPdPpSc3PjYJ5Xzu0YKitMPqrnLB3DW5/pvKFXNHxTM=
github.com/GoCodeAlone/workflow-plugin-data-engineering v0.3.1/go.mod h1:vEqwFF4T/U9OVxbW8gfFFvkA3cMOqX918FBXAx3QaFY=
github.com/GoCodeAlone/yaegi v0.17.2 h1:WK6Y6e0t1a6U7r+S2dN3CGWW1PizYD3zO0zneToZPxM=
Expand Down
72 changes: 55 additions & 17 deletions scenarios/92-infra-admin-demo/README.md
Original file line number Diff line number Diff line change
@@ -1,58 +1,96 @@
# Scenario 92 — Infra Admin Migration Demo
# Scenario 92 — Infra Admin Phase 2/3 Demo

Demonstrates the migration from the deleted engine module to the new
step-based IaC pipeline architecture (workflow v0.70.0, PR-5 Task 18-19).
Demonstrates the Phase-2/3 infra-admin features against the REAL released stack:
**workflow v0.74.0** (ResourceDriver wired end-to-end, PR13) **+ workflow-plugin-infra v1.2.0
+ workflow-sandbox-runner agent**.

Phase 1 (shipped v0.70.0 / v1.1.0) migrated the deleted engine `infra.admin`
module to the step-based `step.iac_provider_*` pipeline architecture. Phase 2/3
(this scenario) adds dynamic specs, the secret-reachability pre-flight gate,
real git commit-back, reconcile, and the remote sandbox-runner agent.

## Architecture

The stub IaC provider is an **external gRPC plugin** built from
`fixtures/stub-iac-provider/`. The engine's `WiringHook` registers it as
service `"stub-iac-provider"` so `step.iac_provider_*` steps resolve it.
service `"stub-iac-provider"` so `step.iac_provider_*` steps resolve it. The stub
advertises `ResourceDriver` (via its gRPC service registration → ContractRegistry),
so on workflow v0.74.0 `step.iac_provider_apply` genuinely CREATEs resources and
`step.iac_commit_back` commits a branch.

**No engine-built-in `infra.admin` module is used** — that was deleted from the engine in v0.70.0. The `type: infra.admin` in `config/app.yaml` resolves to the **external `workflow-plugin-infra` plugin's** module type (the migrated admin SPA), discovered at runtime — not an engine built-in.
All IaC operations flow through the platform plugin's `step.iac_provider_*` step types.
**No engine-built-in `infra.admin` module is used** — that was deleted from the
engine in v0.70.0. The `type: infra.admin` in `config/app.yaml` resolves to the
**external `workflow-plugin-infra` plugin's** module type (the migrated admin SPA),
discovered at runtime. All IaC operations flow through the platform plugin's
`step.iac_provider_*` / `step.iac_commit_back` / `step.iac_provider_reconcile` /
`step.iac_secret_reachability` / `step.sandbox_exec` step types.

## API routes (step-based pipelines)

| Route | Method | Step | Notes |
| Route | Method | Step(s) | Notes |
|---|---|---|---|
| `/api/infra/catalog` | GET | `step.iac_provider_catalog` | Live regions via RegionLister gRPC |
| `/api/infra/resources` | GET | `step.iac_provider_list` | Status from external plugin |
| `/api/infra/plan` | POST | `step.iac_provider_plan` | Returns desired_hash + create action |
| `/api/infra/apply` | POST | `step.iac_provider_apply` | Two-phase hash guard |
| `/api/infra/plan` | POST | `step.iac_provider_plan` | DYNAMIC `specs_from` body → desired_hash |
| `/api/infra/apply` | POST | `step.iac_secret_reachability` → `step.iac_provider_apply` → `step.iac_commit_back` | Reachability pre-flight → CREATE → branch-push commit-back |
| `/api/infra/apply-remote` | POST | `step.iac_secret_reachability` (exec_env: remote) | 409 when host-local secrets unreachable from remote (ADR 0017) |
| `/api/infra/reconcile` | POST | `step.iac_provider_reconcile` | Drift → import → approximate YAML → draft branch |
| `/api/infra/exec-envs` | GET | `step.json_response` | Static `{exec_envs: ["local-docker","remote"]}` |
| `/api/infra/sandbox-demo` | POST | `step.sandbox_exec` (exec_env: remote) | Runs on the sandbox-runner agent; MARKER asserted |
| `/api/infra/drift` | GET | `step.iac_provider_drift` | DriftDetector via external gRPC |
| `/api/infra/commit` | POST | `step.json_response` | Gitops commit fixture |
| `/api/infra/secrets` | GET | `step.json_response` | Metadata-only, no values |
| `/api/admin/contributions` | GET | `step.admin_list_contributions` | Admin shell |

> The Phase-1 `/api/infra/commit` route is removed — commit-back is now integrated
> into the `/apply` pipeline via `step.iac_commit_back`.

## Auth/RBAC

JWT subject-based RBAC via `step.auth_validate` + `step.conditional`:
- `operator` → plan/apply/commit allowed
- `viewer` → catalog/list/drift only; plan/apply/commit → 403
- `operator` → plan/apply/reconcile/sandbox-demo allowed
- `viewer` → catalog/list/drift only; mutations → 403
- unauthenticated → 401

```
secret: "scenario-92-jwt-secret-do-not-use-in-prod"
```

## Dynamic apply → commit-back (the headline flow)

1. Operator POSTs operator-edited specs (with a `secret://scenario/...` ref) to
`/api/infra/plan` → `desired_hash` computed from the dynamic specs.
2. Operator POSTs the same specs + hash to `/api/infra/apply`:
- `step.iac_secret_reachability` pre-flight (local exec_env → reachable).
- `step.iac_provider_apply` recomputes the hash (two-phase guard) and CREATEs
each resource via the stub's `ResourceDriver.Create` (v0.74.0 wires it).
- `step.iac_commit_back` serialises the specs to `resources.yaml` and pushes a
branch (`gitops/infra-apply-demo`) to the bare repo. `secret://` refs are
written VERBATIM (`specgen.SpecToYAML` does not resolve them).

## Running

```bash
# Seed (builds external plugins + docker compose up)
# Seed (builds engine + sandbox-runner from the scenarios module's v0.74.0 pin,
# builds external plugins, sets up the bare repo + working clone, docker compose up)
./seed/seed.sh

# Tests (curl smoke + Playwright)
./test/run.sh
```

## External plugins loaded
## External plugins / agents

1. **stub-iac-provider** — built from `fixtures/stub-iac-provider/`
- Serves `IaCProviderRequired` + `IaCProviderRegionLister` + `IaCProviderDriftDetector`
- Serves `IaCProviderRequired` + `IaCProviderRegionLister` + `IaCProviderDriftDetector` + `ResourceDriver`
- WiringHook registers it as service `"stub-iac-provider"`
- Deterministic data: regions `stub-east`/`stub-west`, types `stub.database`/`stub.bucket`
- `ResourceDriver.Create` returns a stub ResourceOutput so apply CREATEs succeed

2. **workflow-plugin-admin** — built from local checkout (`PLUGIN_ADMIN_REPO`)
- Provides `admin.dashboard` module type
- Serves admin shell at `/admin/`
- Provides `admin.dashboard` module type; serves admin shell at `/admin/`

3. **workflow-plugin-infra** (v1.2.0) — built from local checkout (`PLUGIN_INFRA_REPO`)
- Provides `infra.admin` module type; serves the React SPA at `/admin/infra`

4. **workflow-sandbox-runner** — agent built from the scenarios module's v0.74.0 pin
- gRPC agent for `step.sandbox_exec` `exec_env: remote`; clamps `permissive` → `standard`
Loading
Loading