Skip to content

feat(scenario-renderer): v1 route — render, materialize and deploy a canvas-authored scenario #109

Description

@pparage

Context

app/core/scenario_renderer/writer.py exposes render_scenario(spec) -> {path: content}
a pure, in-memory assembler that produces a complete bundle-scenario directory. Nothing
calls it from an API route yet, so a UI-authored scenario cannot actually be deployed.

Scope

Wire the renderer into the v1 deploy path:

  1. Render — accept a project/topology, adapt it to a ScenarioSpec, allocate vmids
    and IPs, call render_scenario.

  2. Materialize — write the tree to
    range42-playbooks/scenarios/<name>/.

    This location is not negotiable: the deployer-cli hardcodes it in
    workspace.symlinks, in SCENARIO_TEMPLATES_DIR, and in scenario discovery. A
    generated scenario cannot live in a project repo and be deployed — it must land there
    (or be symlinked into it).

  3. Commit/push to the scenario repo, then deploy through the existing deployment
    flow (/v1/deployments), so the generated scenario runs on the plain runner exactly
    like a hand-authored one.

Constraints worth knowing before starting

  • Scenario name must match ^[a-z][a-z0-9_]*$ (already enforced in
    ScenarioSpec.__post_init__). The deployer derives <name>.setup.sh from the directory
    basename, and the TUI parses the workspace name with ^(.+)-([a-z][a-z0-9_]*)$. A
    hyphenated or title-cased UI project title — the natural default — breaks both.
  • hosts.yml cannot be pre-rendered. The four templates/*.j2 files
    (ansible-inventory, ssh-config, ansible-vars, vault-example) are a hard deployer-cli
    discovery gate. The inventory carries per-workspace Jinja (codename, Proxmox address) and
    VM IPs come from ssh-config.j2, not the inventory. The renderer already emits
    99%-concrete files with a fixed Jinja frame — keep that property.
  • _reserved.json must be regenerated after materializing, and
    scenarios/_check_reserved.sh should gate the commit. Otherwise a UI-authored scenario
    can silently poison the collision ledger.
  • Deploy secrets already have a contract (Proxmox token via /v1/proxmox/hosts, git PAT in
    sources, vault_pass.txt + ssh keys in the workspace) — reuse it, don't invent a second one.

Depends on

  • The canvas → ScenarioSpec adapter.
  • The VMID/IP allocator.

Acceptance

  • A canvas-authored project renders, materializes, commits, and deploys end-to-end.
  • The generated scenario is byte-plausible next to a hand-authored one (a reviewer cannot
    tell which is which from the directory alone).
  • _check_reserved.sh passes after the commit.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions