Skip to content

tracking: training-doc pipeline - credentials JSON schema + Quarto renderer role #66

Description

@hyde-repo

tracking: training-doc pipeline - credentials JSON schema + Quarto renderer role

Umbrella: TBD
Wave: WAVE_04 (since TBD)
Cross-repo umbrellas: TBD

Cross-cutting WAVE_04 task : at the end of provisioning, the operator hands
each student a per-student PDF listing their credentials, service URLs, and
getting-started instructions. Generated automatically from data emitted by
each admin service (gitea, mattermost, nextcloud, rocketchat).

Shape

[admin services]   --emit-->   <service>-credentials.json   --collect-->
[Ansible role]   --aggregate per student-->   [Quarto]   --render-->   [PDFs]

Storage

  • Per-service JSON artifacts : named volume on the lab VM (path TBD ; e.g. tokens/ already used by gitea-registry)
  • Aggregated structure + rendered PDFs : ~/range42/_current-training/<session-id>/ on the operator host - outside any git repo, ephemeral, never committed

Schema sketch (v1, to be locked)

Shared base + per-service extension :

{
  "service": "<short-name>",
  "service_url": "<base-url>",
  "service_version": "<version-tag>",
  "provisioned_at": "<ISO-8601-UTC>",
  "users": [
    {
      "username": "...",
      "email": "...",
      "password": "...",
      "ssh_public_key": "...",
      "groups": ["..."],
      "tokens": [ { "name": "...", "value": "...", "scope": "..." } ],
      "service_specific": { }
    }
  ]
}

Per-service service_specific extensions :

  • gitea : { repos: [...], orgs: [...] }
  • mattermost : { teams: [...], channels: [...], bot_account: {...} }
  • nextcloud : { shares: [...], app_passwords: [...] }
  • rocketchat : { channels: [...], bot_account: {...} }
  • misp : { org: "...", roles: [...], warning_lists_enabled: [...] }

Schema is not frozen - expected to evolve

The shape above is a starting point only. As soon as new features land
on the admin services, fields will appear in service_specific that the
schema sketch did not anticipate. The schema is deliberately versioned and
designed to evolve : shared base fields move slowly (versioned bumps for
breaking changes), service_specific is the free-form extension point that
absorbs most of the churn.

Concrete example already visible in WAVE_04 :

The Mattermost / Rocket.Chat tracking issues introduce a player-team layer
(suggested default blue/red/yellow/purple x 1-4 = 16 player teams) with a
dedicated channel per team and auto-join wiring. Implementing this surfaces
fields that do not yet exist in the sketch above :

"service_specific": {
  "player_team": "blue_1",
  "team_channel": "#team-blue-1",
  "auto_joined_channels": ["#general", "#help", "#team-blue-1"]
}

The aggregator + Quarto template will need to render this new shape (e.g. a
"Your team" section in the per-student PDF). Expect every Suggestions item
picked up from the per-element tracking issues to trigger a small parallel
evolution here : add the field(s) to service_specific, update the renderer
template, bump the schema patch version if needed.

Lock (in the scope below) applies to v1 only ; v2+ are expected.

Scope to cover

Deferred (tracked here for context, not for this iteration)

  • Schema versioning lifecycle (v2+ as services evolve)
  • HTML / DOC output variants (Quarto-trivial once PDF works)
  • Encrypted archive of the output dir for cross-operator handoff
  • Per-student delivery automation outside Nextcloud (email / portal)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions