diff --git a/.cargo/config.toml b/.cargo/config.toml index 7622ef4..049af0c 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -64,6 +64,18 @@ offline = false # Strict version requirements for dependencies # force-non-semver-pre = true +[profile.ci-test] +# Pre-commit: no debug info, no incremental — shared .rlib between test + docs hooks +inherits = "test" +debug = 0 +incremental = false + +[profile.ci] +# CI pipeline: line-tables-only for actionable backtraces on remote failures +inherits = "test" +debug = "line-tables-only" +incremental = false + [alias] # Custom cargo commands build-all = "build --all-targets" diff --git a/.gitignore b/.gitignore index 2518f96..34df184 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ kcl *.k old_config +rollback_instructions* docs/book @@ -107,6 +108,10 @@ platform/*/config.local.* **/output/ !**/output/.gitkeep +# Generated Dockerfiles (source of truth = Nickel templates) +platform/crates/*/Dockerfile +docker-compose.build.yml + # === TEMPORARY & BACKUP FILES === *.bak *.backup @@ -123,6 +128,9 @@ platform/*/config.local.* .zed/ .coder/ .claude/ +.opencode +.openpackage +.AGENTS.md .migration/ #.shellcheckrc .DS_Store @@ -184,3 +192,4 @@ test-logs/ # ============================================================================ # End of .gitignore model # ============================================================================ +.aider* diff --git a/.ontology/connections.ncl b/.ontology/connections.ncl new file mode 100644 index 0000000..b676b03 --- /dev/null +++ b/.ontology/connections.ncl @@ -0,0 +1,37 @@ +let s = import "reflection/schemas/connections.ncl" in + +{ + upstream = [ + { + project = "ontoref", + kind = 'LibraryDependency, + node = "protocol-as-standalone", + via = "local", + note = "Ontoref protocol: .ontology/ schemas, ADR lifecycle, reflection modes, daemon sync.", + }, + { + project = "stratumiops", + kind = 'LibraryDependency, + node = "", + via = "local", + note = "stratum-graph, stratum-state, platform-nats, platform-db used by orchestrator and platform services.", + }, + { + project = "secretumvault", + kind = 'LibraryDependency, + node = "", + via = "local", + note = "Embedded in platform/secretumvault — Vault service for secrets management. Local age key in solo mode, Shamir threshold in multi-user.", + }, + ], + downstream = [ + { + project = "ontoref", + kind = 'CoDeveloped, + node = "dag-visualization", + via = "dag-ui", + note = "Provisioning DAG graph exposed to ontoref-daemon as a DagGraphProvider plugin. Co-developed: provisioning emits structured DAG events on provisioning.dag.>; ontoref-daemon consumes and visualizes them.", + }, + ], + peers = [], +} | s.Connections diff --git a/.ontology/core.ncl b/.ontology/core.ncl new file mode 100644 index 0000000..8704864 --- /dev/null +++ b/.ontology/core.ncl @@ -0,0 +1,633 @@ +let d = import "ontology/defaults/core.ncl" in + +{ + nodes = [ + + # ── Axioms (invariant = true) ───────────────────────────────────────────── + + d.make_node { + id = "config-driven-always", + name = "Config-Driven Always", + pole = 'Yang, + level = 'Axiom, + description = "Never hardcoded, always configuration. Runtime args > env > user config > infra config > defaults. TOML/YAML are output formats, never source of truth.", + invariant = true, + artifact_paths = ["config/", "schemas/config/"], + }, + + d.make_node { + id = "type-safety-nickel", + name = "Type Safety via Nickel", + pole = 'Yang, + level = 'Axiom, + description = "Nickel schemas for all infrastructure configuration. TOML/YAML are generated output, never source of truth. Every config change is validated at the schema level before reaching runtime.", + invariant = true, + artifact_paths = ["schemas/"], + }, + + d.make_node { + id = "solid-boundaries", + name = "SOLID Architecture Boundaries", + pole = 'Yang, + level = 'Axiom, + description = "6 hard boundaries with 6 layers of enforcement. Orchestrator ONLY does provider APIs + SSH. Auth decisions ONLY in Control Center. Secrets ONLY via Vault. Violations caught at compile-time, dev-time, pre-commit, CI, runtime, and audit.", + invariant = true, + artifact_paths = ["platform/crates/orchestrator/", "platform/crates/control-center/", "platform/secretumvault/"], + }, + + d.make_node { + id = "provider-abstraction", + name = "Provider Abstraction", + pole = 'Yang, + level = 'Axiom, + description = "Providers as pluggable interface of 25 functions. New provider = implement interface, not change platform. Provider implementations are isolated in catalog/providers/.", + invariant = true, + artifact_paths = ["catalog/providers/"], + }, + + # ── Tensions ────────────────────────────────────────────────────────────── + + d.make_node { + id = "nickel-complexity-vs-accessibility", + name = "Nickel Complexity vs Accessibility", + pole = 'Spiral, + level = 'Tension, + description = "Richer Nickel schemas provide better validation and safety but increase the barrier of entry for contributors. The balance: compose pattern over merge operator, progressive schema layers.", + }, + + d.make_node { + id = "monorepo-vs-split", + name = "Monorepo vs Split Repos", + pole = 'Spiral, + level = 'Tension, + description = "Everything in one repo simplifies development and cross-cutting changes but complicates CI, ownership boundaries, and workspace isolation.", + }, + + d.make_node { + id = "centralized-vs-scripted", + name = "Centralized Orchestration vs Scripts", + pole = 'Spiral, + level = 'Tension, + description = "Orchestrator provides audit trail, rollback, and state machine but adds complexity vs direct provider scripts. Solo mode mitigates by keeping full architecture with relaxed auth.", + }, + + d.make_node { + id = "extension-graph-vs-declarative-config", + name = "Extension Ontology vs Pure Config", + pole = 'Spiral, + level = 'Tension, + description = "The planned extension to embed ontology nodes in metadata.ncl makes extensions graph-aware but blurs the line between configuration and code. Simple extensions should remain pure config; only extensions with non-trivial platform relationships should declare ontology nodes. The resolution: ontology fields in metadata.ncl are optional and additive — the base metadata contract stays simple.", + }, + + d.make_node { + id = "nushell-vs-rust-boundary", + name = "Nushell Library Boundary vs Rust Platform", + pole = 'Spiral, + level = 'Tension, + description = "The Nushell CLI library (core/nulib/) grows to cover operations that could be in Rust platform crates. Moving logic to Rust improves type safety and testability; keeping it in Nushell keeps it operator-scriptable and writable without recompilation. Partial resolution via smart-interface-unification (ADR-029): Rust owns the Registry and all Tool dispatch semantics; Nushell owns orchestration sequences, the three-tier fallback probe chain, and the required legacy closure per operation. The boundary is now structural — operations cross it via tool-call, not via direct Nushell reimplementation.", + }, + + # ── Practices ───────────────────────────────────────────────────────────── + + d.make_node { + id = "nushell-cli-library", + name = "Nushell CLI Library", + pole = 'Yang, + level = 'Practice, + description = "The primary user-facing command surface — 60+ Nushell modules in core/nulib/ covering all platform operations: server/cluster/taskserv/workspace lifecycle, batch ops, provider discovery, extension loading, orchestrator integration, AI tooling, secrets, observability. The CLI composes nulib modules; the library consumes platform APIs and extension metadata.", + artifact_paths = ["core/nulib/", "core/nulib/main_provisioning/", "core/nulib/lib_provisioning/"], + }, + + d.make_node { + id = "extension-metadata-contract", + name = "Extension Metadata Contract", + pole = 'Yin, + level = 'Practice, + description = "Every extension (taskserv, provider, cluster) declares a metadata.ncl: name, version, category, description, typed dependencies, tags, and best_practices references. This contract is the machine-readable extension interface consumed by the CLI loader, schema validator, and orchestrator dependency resolver. Future: metadata.ncl will also declare ontology nodes, connecting extension capabilities to the platform DAG.", + artifact_paths = ["catalog/taskservs/*/metadata.ncl", "catalog/providers/*/", "catalog/clusters/"], + }, + + d.make_node { + id = "taskserv-dependency-dag", + name = "Taskserv Dependency DAG", + pole = 'Yang, + level = 'Practice, + description = "Taskservs form a typed dependency DAG via their metadata.ncl `dependencies` field. Execution order: infrastructure → networking/storage → container_runtime → kubernetes/databases/development → applications. The orchestrator resolves this DAG before building the formula execution plan — no taskserv executes before its declared dependencies complete.", + artifact_paths = ["catalog/taskservs/", "platform/crates/orchestrator/src/formula.rs"], + }, + + d.make_node { + id = "taskserv-pattern", + name = "TaskServ Pattern", + pole = 'Yang, + level = 'Practice, + description = "Extensions that serve infrastructure tasks — each taskserv declares dependencies, capabilities, and contracts. They consume workspace config and produce infrastructure operations. 10 built-in taskservs: infrastructure, networking, storage, container_runtime, kubernetes, databases, applications, development, cluster, misc.", + artifact_paths = ["catalog/taskservs/"], + }, + + d.make_node { + id = "workspace-layer-resolution", + name = "Workspace Layer Resolution", + pole = 'Yin, + level = 'Practice, + description = "Three-tier priority system for workspace configuration composition: Core Layer (Priority 100, catalog/) → Workspace Templates (Priority 200, workspace/templates/) → Infrastructure-Specific (Priority 300, workspace/infra/{name}/). Higher priority overrides lower. Enables shared patterns to be extracted to templates while infrastructure-specific concerns stay local.", + artifact_paths = ["workspace/layers/", "workspace/templates/", "workspace/registry/"], + }, + + d.make_node { + id = "workspace-as-implementation-plan", + name = "Workspace as Implementation Plan", + pole = 'Yin, + level = 'Practice, + description = "A workspace IS the implementation plan. It declares the complete typed composition: which providers, which taskservs with their dependencies, which formula DAG nodes, which clusters. The platform validates the composition against schemas and resolves the execution plan from it — no imperative scripting. Workspaces make infrastructure intent explicit and auditable.", + artifact_paths = ["workspace/templates/", "examples/workspaces/", "schemas/config/workspace_config/"], + }, + + d.make_node { + id = "workspace-contract", + name = "Workspace Contract", + pole = 'Yin, + level = 'Practice, + description = "Workspaces are typed compositions of ingredients in DAGs. Each workspace declares what it needs via Nickel schemas; the platform validates and provisions accordingly.", + artifact_paths = ["schemas/config/workspace_config/"], + }, + + d.make_node { + id = "platform-dispatch", + name = "Platform Dispatch Model", + pole = 'Yang, + level = 'Practice, + description = "Orchestrator dispatches tasks via NATS work queues, maintains state machine per task, and provides rollback capability. All provider API calls flow through this single dispatch point.", + artifact_paths = ["platform/crates/orchestrator/src/workflow.rs", "platform/crates/orchestrator/src/batch.rs"], + }, + + d.make_node { + id = "config-hierarchy", + name = "Configuration Hierarchy", + pole = 'Yin, + level = 'Practice, + description = "5-level config precedence: Runtime args > env vars > user config > infra config > system defaults. Implemented via Nickel schema composition and Nushell config loading.", + artifact_paths = ["schemas/config/", "config/config.defaults.toml"], + }, + + d.make_node { + id = "formula-dag-execution", + name = "Formula DAG Execution", + pole = 'Yang, + level = 'Practice, + description = "Workspace taskserv execution modeled as typed DAGs. Formulas replace positional arrays: each node declares depends_on, on_error, parallel, max_retries. Orchestrator converts via formula.rs into DependencyGraph for topological parallel execution.", + artifact_paths = ["schemas/lib/formula.ncl", "platform/crates/orchestrator/src/formula.rs"], + }, + + d.make_node { + id = "solo-mode", + name = "Solo Mode Architecture", + pole = 'Yin, + level = 'Practice, + description = "Full platform architecture with relaxed auth — solo_auth_middleware replaces JWT+Cedar, injecting a fixed admin session gated behind --mode solo runtime flag. Same binaries, same NATS subjects, same SurrealDB schema. SurrealDB uses embedded RocksDB, NATS runs as child process. Enables single-operator deployments and CI integration tests without external infrastructure.", + artifact_paths = ["platform/crates/control-center/src/middleware/", "platform/crates/orchestrator/src/nats.rs"], + }, + + # ── Smart Interface Unification (ADR-029) ──────────────────────────────── + + d.make_node { + id = "provisioning-registry", + name = "Provisioning Core Registry", + pole = 'Yang, + level = 'Practice, + description = "provisioning-core::Registry is the shared dispatch table for all 37 Tool implementations. Every surface (CLI binary, HTTP daemon, MCP server) must invoke operations through Registry::invoke — no surface may bypass it with direct tool instantiation. This structural constraint is the mechanism that makes semantic parity across surfaces a compile-time guarantee rather than a convention.", + artifact_paths = ["platform/crates/provisioning-core/src/", "platform/crates/provisioning-core/src/registry.rs"], + }, + + d.make_node { + id = "smart-interface-unification", + name = "Smart Interface Unification", + pole = 'Yang, + level = 'Practice, + description = "Three-tier fallback chain in Nushell (platform/clients/fallback.nu::tool-call): tier 1 probes the HTTP daemon, tier 2 spawns provisioning-tool as a child process, tier 3 executes the caller-supplied Nushell legacy closure. The probe sequence runs at call time; no daemon state is managed by the operator. All three tiers dispatch through provisioning-core::Registry. Tier-3 closures are the offline-first guarantee and can only be retired per-operation after G3 passes for that operation.", + artifact_paths = [ + "core/nulib/platform/clients/fallback.nu", + "core/nulib/platform/clients/daemon.nu", + "core/nulib/platform/clients/provisioning_tool.nu", + "platform/crates/provisioning-tool/", + "platform/crates/provisioning-daemon/", + "platform/scripts/start-provisioning-daemon.nu", + "justfiles/daemon.just", + ], + }, + + d.make_node { + id = "g3-contract-invariant", + name = "G3 Contract Invariant", + pole = 'Yin, + level = 'Practice, + description = "The contract-tests crate asserts that CLI, HTTP daemon, and MCP server produce semantically equivalent payloads and identical error codes for every fixture tool. Five tests must pass: listing agreement, echo agreement, invalid-param error agreement, failing-tool error agreement, tools/list count agreement. normalise() defines what 'equivalent' means by stripping volatile fields. G3 is the CI mechanism that converts sync-irrenunciable into an architectural invariant.", + artifact_paths = ["platform/crates/contract-tests/"], + }, + + # ── Reflection modes ────────────────────────────────────────────────────── + + d.make_node { + id = "mode-provisioning-assess", + name = "Mode: provisioning-assess", + pole = 'Yin, + level = 'Practice, + description = "On+re reflection mode: assess system readiness across orchestrator, CLI, control center, schema coverage, and KCL migration dimensions.", + artifact_paths = ["reflection/modes/provisioning-assess.ncl"], + }, + + d.make_node { + id = "mode-provisioning-audit", + name = "Mode: provisioning-audit", + pole = 'Yin, + level = 'Practice, + description = "On+re reflection mode: validate config, list and verify taskservs, check Nickel contracts, verify provider integrity, check axiom coherence.", + artifact_paths = ["reflection/modes/provisioning-audit.ncl"], + }, + + d.make_node { + id = "mode-provisioning-coverage", + name = "Mode: provisioning-coverage", + pole = 'Yin, + level = 'Practice, + description = "On+re reflection mode: map extension ecosystem maturity — taskservs, providers, clusters — and identify coverage gaps.", + artifact_paths = ["reflection/modes/provisioning-coverage.ncl"], + }, + + d.make_node { + id = "mode-provisioning-validate-formula", + name = "Mode: provisioning-validate-formula", + pole = 'Yin, + level = 'Practice, + description = "On+re reflection mode: cross-validate a workspace Formula DAG — typecheck, taskserv existence, metadata dep coverage, ConflictsWith detection, DAG acyclicity.", + artifact_paths = ["reflection/modes/provisioning-validate-formula.ncl"], + }, + + d.make_node { + id = "typedialog-web-ui", + name = "TypeDialog Schema-Driven Web UI", + pole = 'Yin, + level = 'Practice, + description = "Nickel schemas are the single source of truth for web form generation. TypeDialog reads contracts from `.typedialog/provisioning/schemas/` and generates validated HTML forms with no manual form code. Supports multi-user collaborative workflows (draft → review → approve), embedded in the control center dashboard. TUI is a fallback for SSH-only environments. Primary value: schema drift between form and config is structurally impossible.", + artifact_paths = [".typedialog/provisioning/", ".typedialog/provisioning/schemas/", ".typedialog/provisioning/form.toml"], + }, + + d.make_node { + id = "ai-rag-surface", + name = "Schema-Aware AI and RAG Surface", + pole = 'Yang, + level = 'Practice, + description = "AI config generation constrained by Nickel schemas — cannot produce invalid configs. RAG indexes Nickel schemas, docs, and past deployments as retrieval context. ai-service is the HTTP entry point (Cedar-gated); mcp-server exposes tool calling; rag crate manages vector store and embeddings. Cedar policy forbids AI from accessing secrets and requires human approval before any deployment.", + artifact_paths = ["platform/crates/ai-service/", "platform/crates/mcp-server/", "platform/crates/rag/"], + }, + + # ── DAG architecture (three-layer) ─────────────────────────────────────── + + d.make_node { + id = "extension-capability-dag", + name = "Extension Capability DAG", + pole = 'Yang, + level = 'Practice, + description = "Extensions declare typed capability provides/requires/conflicts_with in metadata.ncl. Resolution maps required capabilities to concrete extensions before formula execution. Enables conflict detection and dependency ordering without hardcoded extension names.", + artifact_paths = ["catalog/taskservs/*/metadata.ncl", "schemas/lib/dag/contracts.ncl"], + }, + + d.make_node { + id = "workspace-composition-dag", + name = "Workspace Composition DAG", + pole = 'Yang, + level = 'Practice, + description = "Workspaces declare inter-formula dependencies as a typed DAG via dag.ncl. Formula execution ordering and health gates between formula groups are schema-validated by the WorkspaceComposition Nickel contract and enforced at runtime by WorkspaceComposition::into_workflow in formula.rs.", + artifact_paths = ["schemas/lib/dag/contracts.ncl", "platform/crates/orchestrator/src/formula.rs"], + }, + + d.make_node { + id = "capability-resolution", + name = "Capability Resolution", + pole = 'Yang, + level = 'Practice, + description = "ResolutionPolicy maps required capabilities (from extension requires fields) to concrete extensions (from extension provides fields). Strict mode: all Required capabilities must resolve before execution proceeds. Optional gaps allowed only when resolution.allow_optional_gaps = true.", + artifact_paths = ["schemas/lib/dag/contracts.ncl", "schemas/config/dag/main.ncl"], + }, + + d.make_node { + id = "capability-granularity-vs-simplicity", + name = "Capability Granularity vs Simplicity", + pole = 'Spiral, + level = 'Tension, + description = "Fine-grained capabilities enable precise conflict detection but increase taxonomy maintenance burden. Initial set of 9 coarse capabilities (server-lifecycle, networking, storage, container-runtime, orchestration, database, application-deployment, dev-tooling, hypervisor) chosen to defer premature optimization.", + }, + + d.make_node { + id = "mode-provisioning-dag-integrity", + name = "Mode: provisioning-dag-integrity", + pole = 'Yin, + level = 'Practice, + description = "On+re reflection mode: audit all taskservs for provides/requires/conflicts_with completeness, validate capability graph has no unresolved Required deps, check that ConflictsWith pairs don't coexist in any formula. Runs after B3 migration.", + artifact_paths = ["reflection/modes/provisioning-dag-integrity.ncl"], + }, + + # ── CI pipelines ────────────────────────────────────────────────────────── + + d.make_node { + id = "ci-github-actions", + name = "CI: GitHub Actions", + pole = 'Yang, + level = 'Practice, + description = "GitHub Actions pipelines: nushell-lint, nickel-typecheck, rust-ci. Enforce code quality and schema validity on every PR.", + artifact_paths = [".github/workflows/nushell-lint.yml", ".github/workflows/nickel-typecheck.yml", ".github/workflows/rust-ci.yml"], + }, + + d.make_node { + id = "ci-woodpecker", + name = "CI: Woodpecker", + pole = 'Yang, + level = 'Practice, + description = "Woodpecker CI pipelines: ci.yml and ci-advanced.yml. Self-hosted CI for provisioning workloads.", + artifact_paths = [".woodpecker/ci.yml", ".woodpecker/ci-advanced.yml"], + }, + + # ── Examples ────────────────────────────────────────────────────────────── + + d.make_node { + id = "scenario-workspaces", + name = "Scenario: Workspaces", + pole = 'Yin, + level = 'Practice, + description = "Example workspace configurations demonstrating the workspace contract pattern, server composition, and formula DAGs.", + artifact_paths = ["examples/workspaces"], + }, + + # ── Platform service nodes (previously only in artifact_paths) ──────────── + + d.make_node { + id = "vault-service", + name = "Vault Service — Multi-Backend Secrets", + pole = 'Yin, + level = 'Practice, + description = "SOLID boundary for all secret storage and retrieval. Three backends: Age (development, filesystem key), Cosmian KMS (production, HSM-backed), RustyVault (self-hosted). Provider credentials are leased, never stored raw. Secrets never transit NATS — only lease_id references are published to the event bus. Cedar policies in the control-center prevent any other service from calling vault endpoints directly.", + artifact_paths = ["platform/crates/vault-service/", "platform/crates/vault-service/src/"], + }, + + d.make_node { + id = "extension-registry-service", + name = "Extension Registry — OCI Distribution Surface", + pole = 'Yang, + level = 'Practice, + description = "OCI-compliant registry proxy that distributes provisioning extensions (taskservs, providers, cluster definitions) as OCI artifacts. Validates digests, caches manifests via LRU, emits extension lifecycle events to NATS. Enables versioned extension delivery without requiring a full OCI registry deployment — the proxy layer handles authentication and manifest caching transparently.", + artifact_paths = ["platform/crates/extension-registry/", "platform/crates/extension-registry/src/"], + }, + + d.make_node { + id = "ncl-sync-daemon", + name = "NCL Sync Daemon — Config Compilation Pipeline", + pole = 'Yang, + level = 'Practice, + description = "Daemon that watches Nickel (NCL) source files, compiles them to JSON on change, and keeps the config cache fresh for Nushell processes that cannot afford `nickel export` startup cost on every invocation. File-watching via the `notify` crate; optional NATS publication for cross-process cache invalidation. Resolves the tension between type-safe NCL source of truth and low-latency config reads at CLI time.", + artifact_paths = ["platform/crates/ncl-sync/", "platform/crates/ncl-sync/src/"], + }, + + d.make_node { + id = "prvng-cli-daemon", + name = "prvng-cli — Zero-Cost CLI Query Daemon", + pole = 'Yang, + level = 'Practice, + description = "Unix-socket daemon (`~/.local/share/provisioning/cli.sock`) that answers command registry lookups with sub-millisecond latency. Eliminates the Nushell startup + `nickel export` cost from the bash wrapper's `_validate_command` path. File-watches `commands-registry.json` via the `notify` crate; auto-shuts after 60s idle; restarted by the bash wrapper on next invocation. The wrapper falls through to grep+JSON cache if the socket is absent.", + artifact_paths = ["platform/crates/prvng-cli/", "platform/crates/prvng-cli/src/"], + }, + + d.make_node { + id = "platform-shared-infra", + name = "Platform Shared Infrastructure Crates", + pole = 'Yin, + level = 'Practice, + description = "Three workspace libraries consumed by all platform services: `platform-config` (centralized config loading with Nickel merge layer), `platform-nats` (shared NATS JetStream bridge with retry loop, explicit ACK, and subject prefixing under `provisioning.>`), and `platform-db` (SurrealDB connection pool supporting embedded RocksDB for solo mode, SurrealKV for dev, and WebSocket for multi-user production). These three crates are the only infrastructure primitives that cross service boundaries in the Rust layer.", + artifact_paths = ["platform/crates/platform-config/", "platform/crates/platform-nats/", "platform/crates/platform-db/"], + }, + + d.make_node { + id = "platform-crate-naming", + name = "Platform Workspace Crate Naming Convention", + pole = 'Yin, + level = 'Practice, + description = "Four-rule naming convention applied to all workspace crates (ADR-030): (1) shared library crates use `platform-` package name; (2) smart interface layer uses `provisioning-`; (3) service binary package names are short — `provisioning-` prefix lives only in `[[bin]] name`; (4) ecosystem crates with many existing `use` callers use `platform-` package name + `[lib] name = 'old_name'` to preserve Rust crate names without modifying call sites. The convention disambiguates workspace dep declarations and eliminates crates.io name collision risk for generic names.", + artifact_paths = ["platform/Cargo.toml", "platform/crates/", "platform/prov-ecosystem/crates/"], + }, + + d.make_node { + id = "ops-contract-dual-mode", + name = "Ops Contract Dual-Mode — Pending Queue + Switchable Signer", + pole = 'Yang, + level = 'Practice, + description = "NATS JetStream-based ops coordination with three subject namespaces (ops.pending, ops.cmd, ops.audit) and JWT-signed commands carrying scoped permissions, monotonic sequence, idempotency key, and expected_state_version. Signers (keeper-daemon for auto, keeper-cli for manual) are interchangeable subscribers to ops.pending — switching modes is operational (start/stop daemon), not architectural. ops-controller is the single per-workspace WorkQueue consumer of ops.cmd, persisting in-flight ops to SurrealDB before ack to survive restart. Multi-emitter coordination is delegated to JetStream stream order with optimistic concurrency on expected_state_version. ADR-037.", + artifact_paths = ["adrs/adr-037-ops-contract-dual-mode.ncl", "platform/crates/ops-keeper/", "platform/crates/ops-controller/", "schemas/lib/ops_contract.ncl"], + }, + + d.make_node { + id = "decentralized-governance-radicle", + name = "Decentralized Governance — Radicle Heartwood Substrate", + pole = 'Yin, + level = 'Practice, + description = "Radicle Heartwood as the substrate for governance, desired-state, and audit ledger across all workspaces. Three repos per workspace: policy- (M-of-N delegation among operators), -desired (M-of-N + CI keys), -state (single delegate: ops-controller key). Keeper policy is declarative-only Nickel — parsed by Rust matcher, never evaluated as code. Audit mirror sidecar bridges NATS ops.audit subjects to -state commits with jti idempotency. Operators may use any frontend (git, jj) over their local Radicle replica. Domain-level commands (governance delegations, governance signers) read local clones uniformly. ADR-038.", + artifact_paths = ["adrs/adr-038-radicle-decentralized-governance.ncl", "platform/crates/audit-mirror/", "schemas/lib/radicle.ncl", "schemas/lib/keeper_policy.ncl"], + }, + + d.make_node { + id = "ephemeral-build-infrastructure", + name = "Ephemeral Build Infrastructure — Golden Runners + S3-Backed zot", + pole = 'Yang, + level = 'Practice, + description = "Build pipeline using orchestrator-spawned ephemeral VMs from periodically-rebuilt golden images (buildkit-runner-golden). Per-build sizing resolved from .build-spec.ncl declaration, p95 historical, or language defaults. zot relocated from libre-daoshi to libre-wuji with S3-compatible backend (versioning + cross-region replication for DR). Multi-tenant zot layout serves /images, /cache, /sccache, /crates with JWT-scoped auth. BuildKit registry-cache and sccache S3-backend both terminate at zot for warm-cache cold-spawn. buildkit-launcher (Woodpecker plugin) is a thin bridge to orchestrator's VM lease semantics. ADR-039.", + artifact_paths = ["adrs/adr-039-build-infrastructure-ephemeral.ncl", "catalog/components/buildkit_runner.ncl", "platform/crates/buildkit-launcher/", "schemas/lib/build_spec.ncl"], + }, + + d.make_node { + id = "federated-integration-modes", + name = "Federated Integration Modes — OCI Domain Artifacts", + pole = 'Yang, + level = 'Practice, + description = "Cross-project integration via typed OCI domain artifacts. Each project declares an IntegrationMode in its own reflection/modes/ with domains_used pointing to versioned artifacts at reg.librecloud.online/domains/:. Provisioning is a peer participant — not a plugin host; no filesystem coupling exists between participants. Cabling files at infra//integrations/.ncl resolve domain context fields to concrete sources (sops, component, literal, env). Domains are OCI artifacts with mediaType application/vnd.ontoref.domain.v1 containing a typed Nickel contract. Initial catalog: secret-delivery 0.1.0, event-emission 0.1.0, result-reporting 0.1.0. prvng integration domain publish/pull/describe/verify manage the OCI surface. ADR-042.", + artifact_paths = ["adrs/adr-042-ecosystem-integration-modes.ncl", "schemas/lib/integration/", "catalog/domains/", "core/nulib/platform/oci/domain_client.nu", "core/nulib/cli/integration.nu"], + }, + + ], + + edges = [ + + # Axiom manifestations + { from = "config-driven-always", to = "type-safety-nickel", kind = 'ManifestsIn, weight = 'High, + note = "Nickel is the manifestation of config-driven — typed schemas enforce the axiom" }, + { from = "config-driven-always", to = "config-hierarchy", kind = 'ManifestsIn, weight = 'High, + note = "The 5-level hierarchy implements the config-driven axiom at runtime" }, + { from = "workspace-contract", to = "config-driven-always", kind = 'ManifestsIn, weight = 'High, + note = "Workspaces are the user-facing manifestation of config-driven infrastructure" }, + + # Tension relationships + { from = "type-safety-nickel", to = "nickel-complexity-vs-accessibility", kind = 'Contradicts, weight = 'Medium, + note = "The axiom generates the tension — stricter types vs contributor friction" }, + { from = "platform-dispatch", to = "centralized-vs-scripted", kind = 'Resolves, weight = 'High, + note = "The dispatch model is the resolution of centralized vs scripted" }, + + # Structural relationships + { from = "solid-boundaries", to = "platform-dispatch", kind = 'ValidatedBy, weight = 'High, + note = "SOLID boundaries are validated by the dispatch model — only orchestrator touches providers" }, + { from = "solid-boundaries", to = "provider-abstraction", kind = 'Contains, weight = 'High, + note = "Provider abstraction is a corollary of SOLID boundaries" }, + { from = "solo-mode", to = "solid-boundaries", kind = 'ValidatedBy, weight = 'Medium, + note = "Solo mode preserves SOLID boundaries — auth bypass is the only runtime difference, not an architectural bypass" }, + { from = "solo-mode", to = "centralized-vs-scripted", kind = 'Resolves, weight = 'Medium, + note = "Solo mode proves single-operator usefulness without sacrificing the centralized architecture" }, + { from = "provider-abstraction", to = "taskserv-pattern", kind = 'Complements, weight = 'Medium, + note = "Providers and taskservs are complementary extension points" }, + { from = "taskserv-pattern", to = "workspace-contract", kind = 'FlowsTo, weight = 'High, + note = "Taskservs consume what workspaces declare — the data flow direction" }, + + # TypeDialog and AI relationships + { from = "typedialog-web-ui", to = "type-safety-nickel", kind = 'ManifestsIn, weight = 'High, + note = "TypeDialog is the user-facing manifestation of type-safety-nickel — schema contracts drive form generation" }, + { from = "typedialog-web-ui", to = "workspace-as-implementation-plan", kind = 'Complements, weight = 'High, + note = "TypeDialog is the authoring UI for workspace implementation plans" }, + { from = "ai-rag-surface", to = "type-safety-nickel", kind = 'ValidatedBy, weight = 'High, + note = "Nickel schemas constrain AI generation — AI cannot produce configs that fail schema validation" }, + { from = "ai-rag-surface", to = "solid-boundaries", kind = 'ValidatedBy, weight = 'High, + note = "Cedar policies enforce AI cannot read secrets or deploy without human approval" }, + { from = "ai-rag-surface", to = "typedialog-web-ui", kind = 'Complements, weight = 'Medium, + note = "AI fills TypeDialog forms; TypeDialog provides the schema context AI is constrained by" }, + + # Extension ecosystem relationships + { from = "extension-metadata-contract", to = "taskserv-pattern", kind = 'ValidatedBy, weight = 'High, + note = "Metadata contracts formalize the taskserv interface — every taskserv must satisfy the metadata contract to be loaded" }, + { from = "extension-metadata-contract", to = "provider-abstraction", kind = 'ValidatedBy, weight = 'Medium, + note = "Provider extensions also declare metadata — the contract applies across all extension categories" }, + { from = "taskserv-dependency-dag", to = "taskserv-pattern", kind = 'ManifestsIn, weight = 'High, + note = "The dependency DAG is the runtime expression of taskserv relationship declarations" }, + { from = "taskserv-dependency-dag", to = "formula-dag-execution", kind = 'FlowsTo, weight = 'High, + note = "Taskserv dependency graph feeds into the formula DAG execution plan — dependency resolution precedes formula construction" }, + { from = "extension-metadata-contract", to = "extension-graph-vs-declarative-config", kind = 'Contradicts, weight = 'Medium, + note = "Adding ontology fields to metadata.ncl is the planned evolution that generates this tension" }, + + # DAG architecture relationships + { from = "extension-capability-dag", to = "type-safety-nickel", kind = 'ManifestsIn, weight = 'High, + note = "Capability declarations are Nickel contracts — provides/requires/conflicts_with are schema-validated" }, + { from = "extension-capability-dag", to = "extension-metadata-contract", kind = 'ManifestsIn, weight = 'High, + note = "Capability fields extend the extension-metadata-contract; backwards-compatible via defaults" }, + { from = "capability-resolution", to = "formula-dag-execution", kind = 'FlowsTo, weight = 'High, + note = "Capability resolution produces the extension binding map consumed by formula execution" }, + { from = "workspace-composition-dag", to = "config-driven-always", kind = 'ManifestsIn, weight = 'High, + note = "dag.ncl is a typed Nickel declaration — no imperative composition scripts" }, + { from = "workspace-composition-dag", to = "formula-dag-execution", kind = 'FlowsTo, weight = 'High, + note = "Composition DAG drives the inter-formula execution order and health gate injection" }, + { from = "extension-capability-dag", to = "capability-granularity-vs-simplicity", kind = 'ManifestsIn, weight = 'Medium, + note = "The capability taxonomy is the direct expression of this tension" }, + { from = "mode-provisioning-dag-integrity", to = "extension-capability-dag", kind = 'ValidatedBy, weight = 'High, + note = "Integrity mode is the verification pass for the capability DAG" }, + + # Workspace relationships + { from = "workspace-as-implementation-plan", to = "workspace-contract", kind = 'ManifestsIn, weight = 'High, + note = "Workspace-as-plan is the semantic interpretation; workspace contract is the schema mechanism that enforces it" }, + { from = "workspace-layer-resolution", to = "workspace-contract", kind = 'ManifestsIn, weight = 'High, + note = "Layer resolution is the composition mechanism that realizes the workspace contract from template fragments" }, + { from = "workspace-as-implementation-plan", to = "formula-dag-execution", kind = 'FlowsTo, weight = 'High, + note = "The workspace composition is the input from which the formula DAG execution plan is derived" }, + { from = "workspace-layer-resolution", to = "config-driven-always", kind = 'ManifestsIn, weight = 'Medium, + note = "Layer resolution is config-driven-always applied to workspace composition — no imperative override paths" }, + + # Nushell CLI library relationships + { from = "nushell-cli-library", to = "workspace-as-implementation-plan", kind = 'ManifestsIn, weight = 'High, + note = "CLI library is the primary authoring surface for workspace definitions — workspace commands drive the full lifecycle" }, + { from = "nushell-cli-library", to = "centralized-vs-scripted", kind = 'Contradicts, weight = 'Medium, + note = "The CLI library's size generates the nushell-vs-rust-boundary tension — it could absorb orchestrator logic" }, + { from = "nushell-cli-library", to = "nushell-vs-rust-boundary", kind = 'ManifestsIn, weight = 'High, + note = "The library's growth is the direct expression of this tension" }, + + # Smart Interface Unification relationships (ADR-029) + { from = "provisioning-registry", to = "solid-boundaries", kind = 'ManifestsIn, weight = 'High, + note = "Registry::invoke is the single dispatch path — surfaces cannot bypass it; enforced by ADR-029 constraint registry-sole-dispatch-path" }, + { from = "provisioning-registry", to = "nushell-vs-rust-boundary", kind = 'Resolves, weight = 'High, + note = "Registry is the structural boundary: Rust owns dispatch semantics, Nushell owns orchestration sequences and the legacy closure" }, + { from = "smart-interface-unification", to = "nushell-cli-library", kind = 'ManifestsIn, weight = 'High, + note = "tool-call / tool-list in nulib/platform/clients/fallback.nu is the Nushell expression of the three-tier architecture" }, + { from = "smart-interface-unification", to = "provisioning-registry", kind = 'FlowsTo, weight = 'High, + note = "All three tiers ultimately converge on Registry::invoke — the fallback chain selects the transport, not the dispatch logic" }, + { from = "smart-interface-unification", to = "ai-rag-surface", kind = 'Complements, weight = 'Medium, + note = "mcp-server is now Registry-backed — MCP tool calling and AI tool calling use the same dispatch path" }, + { from = "g3-contract-invariant", to = "provisioning-registry", kind = 'ValidatedBy, weight = 'High, + note = "G3 is the runtime evidence that Registry dispatch produces identical semantics across all three surfaces" }, + { from = "g3-contract-invariant", to = "smart-interface-unification", kind = 'ValidatedBy, weight = 'High, + note = "G3 is the CI gate that prevents surface drift — the invariant that makes sync-irrenunciable structural" }, + { from = "smart-interface-unification", to = "config-driven-always", kind = 'ManifestsIn, weight = 'Medium, + note = "Tier selection is driven by environment probes at call time, not by hardcoded configuration — the fallback chain is config-driven" }, + + # Platform service node relationships + { from = "vault-service", to = "solid-boundaries", kind = 'ManifestsIn, weight = 'High, + note = "Vault is the concrete implementation of the secrets SOLID boundary — Cedar policies enforce no other service touches vault endpoints" }, + { from = "vault-service", to = "config-driven-always", kind = 'ManifestsIn, weight = 'High, + note = "Backend selection (Age/Cosmian/RustyVault) is purely configuration — same binary, different backend at runtime" }, + + { from = "extension-registry-service", to = "provider-abstraction", kind = 'Complements, weight = 'Medium, + note = "Extension registry distributes the versioned artifacts that implement provider and taskserv extensions" }, + { from = "extension-registry-service", to = "extension-metadata-contract", kind = 'ValidatedBy, weight = 'High, + note = "Registry validates OCI artifact digests; the metadata.ncl contract inside each artifact is validated by the CLI loader on install" }, + + { from = "ncl-sync-daemon", to = "type-safety-nickel", kind = 'ManifestsIn, weight = 'High, + note = "NCL sync makes NCL the live source of truth — JSON cache is always derived from NCL, never edited directly" }, + { from = "ncl-sync-daemon", to = "config-hierarchy", kind = 'ManifestsIn, weight = 'High, + note = "The JSON cache NCL sync maintains is the artifact consumed by the 5-level config hierarchy at runtime" }, + + { from = "prvng-cli-daemon", to = "nushell-cli-library", kind = 'Complements, weight = 'High, + note = "prvng-cli eliminates the startup cost that made fast bash-wrapper validation infeasible — the CLI library benefits from sub-ms command lookup" }, + { from = "prvng-cli-daemon", to = "nushell-vs-rust-boundary", kind = 'Resolves, weight = 'Medium, + note = "Unix-socket daemon shifts command validation entirely to Rust, removing the Nu + nickel export cost from the hot path" }, + + { from = "platform-shared-infra", to = "solid-boundaries", kind = 'ManifestsIn, weight = 'High, + note = "platform-config/nats/db are the only infra primitives crossing service boundaries — they are the shared substrate SOLID boundaries operate over" }, + { from = "platform-shared-infra", to = "solo-mode", kind = 'ManifestsIn, weight = 'High, + note = "Solo mode is implemented entirely in platform-db (embedded RocksDB) and platform-nats (child process) — no solo-specific code in the business services" }, + + { from = "platform-crate-naming", to = "monorepo-vs-split", kind = 'Resolves, weight = 'Medium, + note = "The naming convention makes the monorepo workspace unambiguous — dep declarations carry project affiliation without splitting into separate repos" }, + { from = "platform-crate-naming", to = "config-driven-always", kind = 'Complements, weight = 'Low, + note = "Consistent naming is a prerequisite for config-driven extension loading — ambiguous package names would make programmatic workspace dep discovery fragile" }, + + # Ops contract dual-mode relationships (ADR-037) + { from = "ops-contract-dual-mode", to = "solid-boundaries", kind = 'ManifestsIn, weight = 'High, + note = "ops-controller is a new SOLID boundary — consumes from ops.cmd, applies via orchestrator API, writes to ops.audit and SurrealDB; never calls provider APIs or auth services directly" }, + { from = "ops-contract-dual-mode", to = "config-driven-always", kind = 'ManifestsIn, weight = 'High, + note = "Mode switch (auto/manual/hybrid) is operational state, not configuration — keeper policy is declarative Nickel, ops contract is JWT scopes; no hardcoded mode constants" }, + { from = "ops-contract-dual-mode", to = "centralized-vs-scripted", kind = 'Resolves, weight = 'High, + note = "Pending queue + replaceable signer means automated CI and manual operator paths converge on the same contract — no fork between centralized and scripted" }, + { from = "ops-contract-dual-mode", to = "platform-shared-infra", kind = 'FlowsTo, weight = 'High, + note = "ops contract uses platform-nats for JetStream and platform-db for SurrealDB persistence — built on the same shared substrate as orchestrator" }, + + # Decentralized governance relationships (ADR-038) + { from = "decentralized-governance-radicle", to = "config-driven-always", kind = 'ManifestsIn, weight = 'High, + note = "Radicle repos (policy/desired/state) are versioned configuration with cryptographic provenance — config-driven extends to governance itself" }, + { from = "decentralized-governance-radicle", to = "type-safety-nickel", kind = 'ManifestsIn, weight = 'High, + note = "keeper policy uses declarative-only Nickel schema — type-safe data, never executed as code" }, + { from = "decentralized-governance-radicle", to = "monorepo-vs-split", kind = 'Resolves, weight = 'Medium, + note = "Three-repo split per workspace separates governance/desired/audit by authority profile without compromising the source-code monorepo" }, + { from = "decentralized-governance-radicle", to = "ops-contract-dual-mode", kind = 'Complements, weight = 'High, + note = "ops contract handles transit (NATS); Radicle handles permanent record (audit ledger via mirror sidecar) and governance (delegations)" }, + + # Ephemeral build infrastructure relationships (ADR-039) + { from = "ephemeral-build-infrastructure", to = "provider-abstraction", kind = 'FlowsTo, weight = 'High, + note = "buildkit_runner is a component spawned via orchestrator's VM lifecycle — same provider abstraction as taskservs" }, + { from = "ephemeral-build-infrastructure", to = "config-driven-always", kind = 'ManifestsIn, weight = 'High, + note = "Per-build sizing resolved from .build-spec.ncl declaration, historical p95, or language defaults — no hardcoded sizing" }, + { from = "ephemeral-build-infrastructure", to = "ops-contract-dual-mode", kind = 'FlowsTo, weight = 'Medium, + note = "Build artifacts (image push to zot) trigger downstream deploy ops via ops.pending — build pipeline emits ops, does not apply them" }, + { from = "ephemeral-build-infrastructure", to = "extension-registry-service", kind = 'Complements, weight = 'Medium, + note = "zot multi-tenant /crates and /images coexist with extension-registry's OCI distribution — both are OCI-spec consumers of the same backing storage" }, + + # Federated integration modes relationships (ADR-042) + { from = "federated-integration-modes", to = "type-safety-nickel", kind = 'ManifestsIn, weight = 'High, + note = "Cabling contracts and domain contracts are Nickel NCL — type safety extends to integration context assembly" }, + { from = "federated-integration-modes", to = "solid-boundaries", kind = 'ValidatedBy, weight = 'High, + note = "No filesystem coupling between participants — each project is an autonomous peer consuming typed OCI artifacts" }, + { from = "federated-integration-modes", to = "ephemeral-build-infrastructure", kind = 'Complements, weight = 'Medium, + note = "Domain artifacts are stored in the same zot registry as build artifacts — OCI storage is shared substrate" }, + { from = "federated-integration-modes", to = "config-driven-always", kind = 'ManifestsIn, weight = 'High, + note = "Cabling files are declarative config — no imperative wiring; context assembly reads config, not code" }, + + ], +} diff --git a/.ontology/gate.ncl b/.ontology/gate.ncl new file mode 100644 index 0000000..0471aa6 --- /dev/null +++ b/.ontology/gate.ncl @@ -0,0 +1,45 @@ +let d = import "ontology/defaults/gate.ncl" in + +{ + membranes = [ + + d.make_membrane { + id = "control-plane-readiness", + name = "Control Plane Readiness", + description = "Controls when the provisioning control plane is ready for production deployment and multi-user mode.", + permeability = 'Low, + accepts = ['EcosystemRelevance], + protects = ["production deployment", "multi-user mode"], + opening_condition = { + max_tension_dimensions = 2, + pending_transitions = 2, + core_stable = true, + description = "Orchestrator + Control Center operational, NATS streams configured and stable, SOLID boundaries passing all 6 enforcement layers, Cedar policies loaded and evaluated.", + }, + closing_condition = "Any SOLID enforcement layer failing or NATS stream misconfiguration detected.", + max_duration = 'Indefinite, + protocol = 'Challenge, + active = false, + }, + + d.make_membrane { + id = "workspace-certification", + name = "Workspace Certification", + description = "Controls when a workspace is ready for production use — all taskservs validated, config schema-checked, provider capabilities matched.", + permeability = 'Medium, + accepts = ['EcosystemRelevance, 'OpportunityAlignment], + protects = ["workspace production use"], + opening_condition = { + max_tension_dimensions = 3, + pending_transitions = 3, + core_stable = true, + description = "All taskservs in workspace have dependencies.ncl, config validates via nickel typecheck, provider capabilities match requirements.", + }, + closing_condition = "Workspace config fails schema validation or provider capabilities no longer match declared requirements.", + max_duration = 'Indefinite, + protocol = 'Observe, + active = false, + }, + + ], +} diff --git a/.ontology/manifest.ncl b/.ontology/manifest.ncl new file mode 100644 index 0000000..ca528ce --- /dev/null +++ b/.ontology/manifest.ncl @@ -0,0 +1,340 @@ +let m = import "ontology/defaults/manifest.ncl" in + +m.make_manifest { + project = "provisioning", + repo_kind = 'Mixed, + + description = "Multi-crate Rust platform for cloud infrastructure provisioning: typed Nickel schemas validated at the NCL layer, formula DAG execution engine, SOLID-enforced service boundaries, pluggable providers and taskservs, NATS-brokered orchestration, Cedar authorization, and full-architecture solo mode for single-operator deployments.", + + consumption_modes = [ + m.make_consumption_mode { + consumer = 'Developer, + needs = ['OntologyExport], + audit_level = 'Standard, + description = "Uses provisioning CLI and workspace definitions to manage infrastructure. Extends via providers and taskservs.", + }, + m.make_consumption_mode { + consumer = 'Agent, + needs = ['OntologyExport, 'JsonSchema], + audit_level = 'Quick, + description = "Reads .ontology/core.ncl to understand constraints and boundaries. Uses CLI and orchestrator APIs for infrastructure operations.", + }, + ], + + layers = [ + m.make_layer { + id = "schemas", + paths = ["schemas/"], + committed = true, + description = "Nickel type schemas for all infrastructure configuration: providers, workspaces, platform services, extensions.", + }, + m.make_layer { + id = "core", + paths = ["core/"], + committed = true, + description = "CLI, libraries, plugins, Nushell scripts — the user-facing surface of provisioning.", + }, + m.make_layer { + id = "platform", + paths = ["platform/"], + committed = true, + description = "Orchestrator, Control Center, Vault, Extension Registry — the control plane services.", + }, + m.make_layer { + id = "catalog", + paths = ["catalog/"], + committed = true, + description = "Providers, taskservs, clusters, components, domain artifacts — IaC building block catalog and federated integration domain contracts.", + }, + m.make_layer { + id = "config", + paths = ["config/", "templates/"], + committed = true, + description = "Default configuration files and infrastructure templates.", + }, + m.make_layer { + id = "self-description", + paths = [".ontology/"], + committed = true, + description = "Provisioning consuming on+re: axioms, tensions, practices, state, gates, ADRs.", + }, + ], + + operational_modes = [ + m.make_op_mode { + id = "dev", + visible_layers = ["schemas", "core", "platform", "catalog", "config", "self-description"], + description = "Full development view — all layers visible.", + }, + m.make_op_mode { + id = "platform-focus", + visible_layers = ["schemas", "platform", "config"], + description = "Platform engineering focus — schemas, platform services, and configuration.", + }, + m.make_op_mode { + id = "catalog-focus", + visible_layers = ["schemas", "catalog", "config"], + description = "Catalog development focus — schemas, providers, taskservs, components, and configuration.", + }, + ], + + config_surface = m.make_config_surface { + config_root = ".typedialog/provisioning/", + entry_point = "config.ncl", + kind = 'TypeDialog, + contracts_path = ".typedialog/provisioning/schemas", + overrides_dir = ".typedialog/provisioning/generated", + sections = [ + m.make_config_section { + id = "provisioning", + file = "config.ncl", + contract = "schemas/provisioning-config.ncl", + description = "Root workspace configuration generated by TypeDialog — project metadata, services, database, deployment target, network, storage, monitoring, security.", + rationale = "Consumer projects declare what infrastructure they need via an interactive TypeDialog form. The NCL output is the single source of truth fed to the orchestrator. TypeDialog fragments (database-postgres, deployment-k8s, etc.) ensure only valid combinations are generated.", + mutable = true, + consumers = [ + m.make_config_consumer { id = "orchestrator", kind = 'RustStruct, ref = "provisioning_orchestrator::config::OrchestratorConfig", fields = ["services", "deployment", "database"] }, + m.make_config_consumer { id = "configure-nu", kind = 'NuScript, ref = ".typedialog/provisioning/configure.nu" }, + m.make_config_consumer { id = "ci-woodpecker", kind = 'CiPipeline, ref = ".woodpecker/ci.yml" }, + ], + }, + m.make_config_section { + id = "database", + file = "schemas/database.ncl", + contract = "schemas/database.ncl", + description = "Database type and connection parameters — supports sqlite, postgres, surrealdb, mysql. Generated into the root config via TypeDialog database-* fragments.", + rationale = "Database configuration is the most provider-specific section. TypeDialog fragments enforce valid parameter combinations per engine (e.g. journal_mode only valid for SQLite).", + mutable = false, + consumers = [ + m.make_config_consumer { id = "orchestrator", kind = 'RustStruct, ref = "provisioning_orchestrator::config::OrchestratorConfig", fields = ["database"] }, + ], + }, + m.make_config_section { + id = "deployment", + file = "schemas/deployment.ncl", + contract = "schemas/deployment.ncl", + description = "Deployment target — docker-compose or kubernetes. Drives which taskservs are activated and which providers are called.", + rationale = "Deployment target selection is the primary branching decision in workspace execution. TypeDialog deployment-docker and deployment-k8s fragments capture the full parameter space for each target.", + mutable = false, + consumers = [ + m.make_config_consumer { id = "orchestrator", kind = 'RustStruct, ref = "provisioning_orchestrator::config::OrchestratorConfig", fields = ["deployment"] }, + ], + }, + m.make_config_section { + id = "monitoring", + file = "schemas/monitoring.ncl", + contract = "schemas/monitoring.ncl", + description = "Observability configuration — metrics, logging, alerting. Optional; defaults from .typedialog/provisioning/defaults/monitoring-defaults.ncl.", + mutable = false, + consumers = [ + m.make_config_consumer { id = "orchestrator", kind = 'RustStruct, ref = "provisioning_orchestrator::config::OrchestratorConfig", fields = ["monitoring"] }, + ], + }, + ], + }, + + capabilities = [ + m.make_capability { + id = "formula-dag-execution", + name = "Formula DAG Execution Engine", + summary = "Typed DAG-based workflow execution with topological parallelism, retry, and rollback.", + rationale = "Positional task arrays collapse on dependency ambiguity and lack parallelism signals. Formula nodes declare depends_on, on_error, parallel, max_retries — enabling the orchestrator to derive a topological execution plan without imperative scripting.", + how = "Workspace TOML declares Formula nodes; orchestrator's formula.rs converts to DependencyGraph via topological sort; BatchExecutor executes ready nodes in parallel via NATS work queues.", + artifacts = ["schemas/lib/formula.ncl", "platform/crates/orchestrator/src/formula.rs", "platform/crates/orchestrator/src/batch.rs"], + adrs = ["adr-016-workspace-formula-dag"], + nodes = ["formula-dag-execution"], + }, + m.make_capability { + id = "workspace-contract", + name = "Typed Workspace Contracts", + summary = "Nickel-validated workspace definitions that compose providers, taskservs, and ingredients into infrastructure DAGs.", + rationale = "Raw TOML workspace files have no type safety — invalid configs surface as runtime errors. Nickel schemas catch structural errors at write time, before any provider API is called.", + how = "CLI validates workspace TOML against schemas/config/workspace_config/ contracts via nickel export before submitting to orchestrator. Orchestrator re-validates on receipt.", + artifacts = ["schemas/config/workspace_config/", "core/crates/", "examples/workspaces/"], + nodes = ["workspace-contract"], + }, + m.make_capability { + id = "provider-plugin-system", + name = "Provider Plugin System", + summary = "25-function pluggable interface for infrastructure providers — add a provider without changing the platform.", + rationale = "Hardcoded provider logic makes multi-cloud support a fork, not an extension. The provider interface isolates provider specifics behind a stable contract.", + how = "Each provider implements the ProviderInterface trait (25 functions). Orchestrator dispatches operations via the interface; provider implementations are loaded from catalog/providers/.", + artifacts = ["catalog/providers/", "platform/crates/orchestrator/src/"], + nodes = ["provider-abstraction", "taskserv-pattern"], + }, + m.make_capability { + id = "solo-mode-deployment", + name = "Solo Mode — Full-Architecture Single-Operator Deployment", + summary = "Run the full platform on a laptop: embedded SurrealDB (RocksDB), child NATS server, solo_auth_middleware replacing JWT+Cedar.", + rationale = "Simplified mono-binary for solo creates two divergent code paths. Solo mode keeps the same binaries and NATS subjects — scripts written for solo work in multi-user unchanged.", + how = "--mode solo flag activates solo_auth_middleware (auto-injects admin session), SurrealDB switches to kv-surrealkv (RocksDB), NATS starts as child process. service-manager.nu orchestrates startup.", + artifacts = ["platform/crates/control-center/src/middleware/", "platform/crates/orchestrator/src/nats.rs"], + adrs = ["adr-015-solo-mode-architecture"], + nodes = ["solo-mode"], + }, + m.make_capability { + id = "nats-brokered-orchestration", + name = "NATS JetStream Orchestration", + summary = "All inter-service task dispatch via NATS JetStream work queues with at-least-once delivery and state machine tracking.", + rationale = "HTTP synchronous task dispatch couples orchestrator latency to provider API latency. NATS decouples dispatch from execution, enables fan-out to taskserv workers, and provides durable state even if a worker crashes mid-task.", + how = "Orchestrator publishes tasks to JetStream streams per provider type. Taskserv workers consume via pull consumers with ack/nack. Task state machine tracks pending → running → completed/failed in SurrealDB.", + artifacts = ["platform/crates/orchestrator/src/workflow.rs", "platform/crates/platform-nats/"], + adrs = ["adr-012-nats-event-broker"], + nodes = ["platform-dispatch"], + }, + m.make_capability { + id = "nickel-config-hierarchy", + name = "Nickel-Validated Configuration Hierarchy", + summary = "5-level config precedence with NCL contracts: runtime args > env vars > user config > infra config > system defaults.", + rationale = "Ad-hoc env var overrides without schema validation cause silent misconfiguration. The Nickel merge layer validates every override level against the same contracts before deserialization.", + how = "platform-config's ConfigLoader trait runs collect_env_overrides() → nickel export → serde::Deserialize. Override files are written to config/*.overrides.ncl and merged via & at the entry point.", + artifacts = ["platform/crates/platform-config/src/format.rs", "schemas/config/"], + adrs = ["adr-013-surrealdb-global-store"], + nodes = ["config-hierarchy", "type-safety-nickel"], + }, + m.make_capability { + id = "solid-enforcement", + name = "SOLID Boundary Enforcement", + summary = "6 compile-time and runtime SOLID boundaries: orchestrator-only provider calls, control-center-only auth, vault-only secrets.", + rationale = "Without enforced boundaries, authorization and secrets logic diffuses across services. ADR-014 documents 6 hard boundaries with 6 enforcement layers (compile-time, dev-time, pre-commit, CI, runtime, audit).", + how = "Clippy rules, grep CI checks, Cedar policies, and runtime middleware enforce the boundaries. solo_auth_middleware is the only documented auth bypass and requires --mode solo.", + artifacts = ["platform/crates/orchestrator/", "platform/crates/control-center/", "platform/secretumvault/"], + adrs = ["adr-014-solid-enforcement"], + nodes = ["solid-boundaries"], + }, + ], + + requirements = [ + m.make_requirement { + id = "rust", + name = "Rust toolchain", + kind = 'Tool, + env = 'Development, + version = "1.75+", + impact = "Platform services and CLI cannot compile.", + provision = "rustup toolchain install stable", + }, + m.make_requirement { + id = "nushell", + name = "Nushell", + kind = 'Tool, + env = 'Both, + version = "0.110+", + impact = "Reflection modes, service-manager.nu, and CLI scripts cannot execute.", + provision = "cargo install nu", + }, + m.make_requirement { + id = "nickel", + name = "Nickel", + kind = 'Tool, + env = 'Both, + version = "1.15+", + impact = "Schema validation and config export cannot run. platform-config's ConfigLoader cannot operate.", + provision = "cargo install nickel-lang-cli", + }, + m.make_requirement { + id = "surrealdb", + name = "SurrealDB", + kind = 'Service, + env = 'Production, + version = "2.3+", + required = false, + impact = "Multi-user deployments cannot persist task state, Cedar policies, or audit logs. Solo mode uses embedded RocksDB.", + provision = "Deploy surrealdb container or binary; solo mode uses kv-surrealkv.", + }, + m.make_requirement { + id = "nats-server", + name = "NATS Server (JetStream)", + kind = 'Service, + env = 'Both, + impact = "Orchestrator cannot dispatch tasks; taskserv workers cannot receive work items. Solo mode manages nats-server as a child process.", + provision = "Install nats-server in PATH for solo mode; deploy NATS cluster for multi-user.", + }, + m.make_requirement { + id = "cedar-policy", + name = "Cedar policy engine", + kind = 'Infrastructure, + env = 'Production, + required = false, + impact = "Cedar-based authorization unavailable in multi-user mode. Solo mode uses solo_auth_middleware which bypasses Cedar entirely.", + provision = "Policies stored in SurrealDB; loaded by control-center at startup.", + }, + ], + + critical_deps = [ + m.make_critical_dep { + id = "surrealdb-crate", + name = "SurrealDB client crate", + ref = "surrealdb@3", + used_for = "Task state machine persistence, Cedar policy storage, audit log, workspace history.", + failure_impact = "All stateful operations (task tracking, policy evaluation, audit) stop. Solo mode continues via kv-surrealkv but loses SurrealDB WS protocol.", + mitigation = "Feature-gated: --no-default-features disables SurrealDB for dev builds. Solo mode uses embedded kv-surrealkv (RocksDB).", + }, + m.make_critical_dep { + id = "async-nats", + name = "async-nats", + ref = "async-nats@0.46", + used_for = "All inter-service task dispatch, NATS JetStream work queues, taskserv worker consumers.", + failure_impact = "Orchestrator cannot dispatch workflows; taskserv workers go idle. Solo mode manages nats-server as child — child crash is fatal.", + mitigation = "Feature-gated via platform-nats crate. Solo mode restarts nats-server on SIGTERM.", + }, + m.make_critical_dep { + id = "cedar-policy-crate", + name = "cedar-policy", + ref = "cedar-policy@4.8", + used_for = "Authorization decisions in control-center: policy evaluation, RBAC, resource-level access control.", + failure_impact = "All authorization decisions in multi-user mode fail closed. Solo mode unaffected (solo_auth_middleware bypasses Cedar).", + mitigation = "Compile-time link; no runtime loading. cedar-policy is the Cedar Reference Implementation — stable API surface.", + }, + m.make_critical_dep { + id = "secretumvault", + name = "secretumvault", + ref = "secretumvault (local path ../../../Development/secretumvault)", + used_for = "Secrets management: age key management, Shamir threshold unsealing, secret storage for provider credentials.", + failure_impact = "Vault service cannot start; provider credential injection fails. All infrastructure operations that require provider API keys stop.", + mitigation = "Local path dependency — pinned to checkout. Solo mode uses filesystem backend (age key).", + }, + m.make_critical_dep { + id = "axum", + name = "axum", + ref = "axum@0.8", + used_for = "HTTP API layer for orchestrator, control-center, extension-registry, ai-service, mcp-server.", + failure_impact = "All HTTP API surfaces become unavailable. CLI falls back to NATS direct where supported.", + mitigation = "axum@0.8 is maintained by the Tokio project; API stability is high.", + }, + ], + + domain_provides = { + id = "provisioning-platform", + name = "Provisioning Platform", + schema_path = "reflection/schemas/", + impl_repo_kind = "DevWorkspace", + kind = 'Implicit, + description = "Workspace infrastructure contracts: cluster topology, state dimensions, gate membranes, and operational modes for DevWorkspace projects.", + }, + + registry_provides = m.make_registry_provides { + participant = "provisioning", + registries = m.make_registries_config { + default = "primary", + registries = [ + m.make_registry_entry { + id = "primary", + endpoint = "reg.librecloud.online", + role = 'primary, + tls = true, + namespaces = { + own = ["domains/provisioning/", "modes/provisioning/"], + prefixes = ["domains/provisioning/", "modes/provisioning/"], + }, + }, + ], + }, + }, + + level = { + index = 'Domain, + name = "provisioning-domain", + parent = "ontoref-base", + }, +} diff --git a/.ontology/state.ncl b/.ontology/state.ncl new file mode 100644 index 0000000..92b5640 --- /dev/null +++ b/.ontology/state.ncl @@ -0,0 +1,249 @@ +let d = import "ontology/defaults/state.ncl" in + +{ + dimensions = [ + + d.make_dimension { + id = "orchestrator-maturity", + name = "Orchestrator Maturity", + description = "Orchestrator service readiness — from functional prototype to production-grade task execution engine.", + current_state = "functional", + desired_state = "production", + horizon = 'Months, + states = [], + transitions = [ + d.make_transition { + from = "functional", + to = "production", + condition = "All 6 SOLID enforcement layers passing, NATS streams stable, task state machine handles all error paths with rollback, formula DAG execution covers all taskserv dependency combinations.", + catalyst = "Control Center JWT auth and Cedar policy evaluation wired end-to-end; solo mode auth bypass verified against ADR-015 constraints.", + blocker = "Cedar policy definitions stored in SurrealDB not finalized; WebSocket task status streaming not connected to NATS push consumers.", + horizon = 'Months, + }, + ], + }, + + d.make_dimension { + id = "cli-maturity", + name = "CLI and Nushell Library Maturity", + description = "CLI v3 and core/nulib/ stability — the primary user interface and Nushell command library for all platform operations.", + current_state = "stable-v3", + desired_state = "stable-v3", + horizon = 'Continuous, + states = [], + transitions = [], + }, + + d.make_dimension { + id = "control-center-maturity", + name = "Control Center Maturity", + description = "Control Center service readiness — from bootstrapped to operational with live auth, Cedar policies, and WebSocket streaming.", + current_state = "bootstrapped", + desired_state = "operational", + horizon = 'Months, + states = [], + transitions = [ + d.make_transition { + from = "bootstrapped", + to = "operational", + condition = "JWT auth middleware active in non-solo mode, Cedar policies loaded from SurrealDB and evaluated on all protected routes, WebSocket task status streaming connected to NATS push consumers.", + catalyst = "Solo mode (ADR-015) fully tested end-to-end as staging environment for multi-user auth path.", + blocker = "Cedar policy definitions not finalized; WebSocket streaming not connected to NATS; IaC detection and rules handlers partially commented out in router.", + horizon = 'Months, + }, + ], + }, + + d.make_dimension { + id = "schema-coverage", + name = "Schema Coverage", + description = "Nickel schema coverage across all configuration surfaces — from partial to comprehensive.", + current_state = "partial", + desired_state = "comprehensive", + horizon = 'Months, + states = [], + transitions = [ + d.make_transition { + from = "partial", + to = "comprehensive", + condition = "All provider configs, workspace configs, platform service configs, extension metadata (taskserv dependency declarations), and TypeDialog forms covered by typed Nickel schemas. Extension metadata.ncl files cover all 10 built-in taskservs.", + catalyst = "Extension ontology evolution (ADR-019 AI surface) requiring schema for RAG indexing.", + blocker = "Some extensions still use raw TOML or KCL remnants for metadata. TypeDialog schemas cover workspace config but not all platform service configs.", + horizon = 'Months, + }, + ], + }, + + d.make_dimension { + id = "kcl-migration", + name = "KCL Migration", + description = "Migration from KCL to Nickel — completed, continuous maintenance only.", + current_state = "completed", + desired_state = "completed", + horizon = 'Continuous, + states = [], + transitions = [], + }, + + d.make_dimension { + id = "smart-interface-migration", + name = "Smart Interface Migration", + description = "Migration of all 37 Nushell operations from direct legacy dispatch to the three-tier fallback chain (HTTP daemon → provisioning-tool → Nushell closure). Infrastructure complete; operation wiring is the remaining work.", + current_state = "bootstrapped", + desired_state = "migrated", + horizon = 'Months, + states = [], + transitions = [ + d.make_transition { + from = "bootstrapped", + to = "migrated", + condition = "All 37 operations call tool-call / tool-list with a real Nushell legacy closure; G3 contract test passes for each migrated operation; no handler calls the orchestrator or provider APIs directly from nulib without going through the Registry.", + catalyst = "G3 contract test gates each migration — an operation can only retire its tier-3 closure after G3 passes for it. Daemon install via `just daemon install` makes tier-1 available on developer machines.", + blocker = "36 operations still dispatch via Nushell legacy directly; only workspace_list is wired to the fallback chain. Migration is per-operation and non-breaking.", + horizon = 'Months, + }, + ], + }, + + d.make_dimension { + id = "extension-ecosystem-maturity", + name = "Internal Extension Mechanism Maturity", + description = "Maturity of the internal extension mechanism (taskservs and providers) — from basic metadata contracts to capability-aware DAG resolution to ontology-aware impact analysis. Distinct from federated integration modes (ADR-042) which governs cross-project integration via OCI domain artifacts.", + current_state = "capability-aware", + desired_state = "ontology-aware", + horizon = 'Months, + states = [], + transitions = [ + d.make_transition { + from = "metadata-contracts", + to = "capability-aware", + condition = "All 10 built-in taskserv metadata.ncl files migrated with provides/requires/conflicts_with fields. provisioning-dag-integrity reflection mode runs clean. CLI `provisioning extensions capabilities` outputs correct capability table.", + catalyst = "Three-layer DAG architecture (ADR-016) requiring typed capability declarations for formula dependency resolution.", + blocker = "Completed — B2 (schema extension) and B3 (metadata migration) done in DAG architecture session.", + horizon = 'Continuous, + }, + d.make_transition { + from = "capability-aware", + to = "ontology-aware", + condition = "Extension metadata.ncl can optionally declare ontology node IDs; orchestrator resolves extension DAG against platform ontology for impact analysis; CLI reports which ontology nodes are affected by a given workspace execution.", + catalyst = "AI RAG surface (ADR-019) requiring extension ontology data for schema-aware config generation.", + blocker = "Ontology node schema not yet added to metadata.ncl contract; no tooling to validate ontology references in extension metadata.", + horizon = 'Months, + }, + ], + }, + + d.make_dimension { + id = "ops-contract-evolution", + name = "Ops Contract Evolution (ADR-037)", + description = "Evolution of the dual-mode ops contract — from architectural decision to implemented crates to production deployment with multi-emitter coordination proven under load.", + current_state = "designed", + desired_state = "production", + horizon = 'Months, + states = [], + transitions = [ + d.make_transition { + from = "designed", + to = "implemented", + condition = "ops-keeper crate (keeper-daemon + keeper-cli binaries) compiles and passes unit tests; ops-controller crate subscribes to OPS_CMD JetStream stream and applies ops idempotently with SurrealDB persistence of in-flight state; schemas/lib/ops_contract.ncl + keeper_policy.ncl validated; NATS JetStream streams OPS_PENDING/OPS_CMD/OPS_AUDIT created with correct retention.", + catalyst = "ADR-037 accepted; design discussion produced 23 implementation tasks with explicit per-layer (domain/project/workspace) impact mapping.", + blocker = "Implementation not yet started — designed but no crates exist. Ordered prerequisite: schemas first, then ops-keeper crate, then ops-controller crate, then NATS config.", + horizon = 'Months, + }, + d.make_transition { + from = "implemented", + to = "production", + condition = "VM-ops workspace deployed with keeper-daemon running; libre-wuji ops-controller deployed with single-replica WorkQueue consumer; daoshi-CI Woodpecker pipelines emit ops via buildkit-launcher publish step; multi-emitter conflict scenario verified in staging (two emitters, second receives 409); operator-only mode tested via switch_to_operator_only playbook; pending queue depth and oldest-message-age observable in Prometheus.", + catalyst = "ops contract is gating for ADR-039 build infrastructure (build pipeline emits deploy ops via ops.pending) — production readiness blocks the deploy-from-CI path.", + blocker = "Implementation phase not complete; observability stack not deployed in libre-wuji; VM-ops workspace not yet provisioned.", + horizon = 'Months, + }, + ], + }, + + d.make_dimension { + id = "integration-modes-maturity", + name = "Federated Integration Modes Maturity (ADR-042)", + description = "Maturity of the federated integration modes protocol — from schema definitions and OCI domain artifacts to assembled context delivery to fully-wired invoke pipeline.", + current_state = "schema-defined", + desired_state = "assembled", + horizon = 'Months, + states = [], + transitions = [ + d.make_transition { + from = "schema-defined", + to = "assembled", + condition = "context-assembler crate reads cabling.ncl + SOPS secrets + component outputs and produces a typed SecretDeliveryContext JSON envelope; `prvng integration invoke ` pipes the assembled context to the mode binary stdin; lian-build provisioning mode receives the envelope and emits a valid ResultEnvelope; `prvng integration subscribe ` scaffolds a cabling file skeleton in infra//integrations/.", + catalyst = "context-assembler Nushell module complete (platform/integrations/context_assembler.nu); `prvng integration invoke/subscribe/validate` all wired; 7 domain artifacts in zot (secret-delivery, event-emission, result-reporting, compute-provisioning, registry-access, cache-management, backup-policy-binding 0.1.0); all signed with cosign; lian-build + cloudatasave modes declared with domain locks + libre-wuji cablings.", + blocker = "lian-build binary does not yet read stdin context — end-to-end live invoke not yet proven.", + horizon = 'Months, + }, + d.make_transition { + from = "assembled", + to = "production", + condition = "cloudatasave integration mode declared with its own lock + cabling; cosign signing applied to all domain artifacts in zot; zot trust policy rejects unsigned domain artifacts; NATS event-emission domain wired to production JetStream subjects in each workspace cabling.", + catalyst = "cosign signing complete for all 9 artifacts (7 domains + 2 modes) ✓; zot imagetrust extension enabled in configmap ✓; cloudatasave mode + lock + cabling declared ✓; client-side cosign verify in domain-verify + subscribe ✓; key rotation documented in docs/guides/cosign-key-rotation.md ✓; ZOT_ADMIN_PASS in zot.sops.yaml + adminPolicy for regadm + server-side cosign trust key uploaded (HTTP 200) ✓.", + blocker = "NATS event-emission wiring not yet live; lian-build binary stdin implementation external dependency.", + horizon = 'Months, + }, + ], + }, + + d.make_dimension { + id = "governance-model-state", + name = "Decentralized Governance Model State (ADR-038)", + description = "Adoption state of Radicle Heartwood as governance and audit substrate across all workspaces.", + current_state = "designed", + desired_state = "active", + horizon = 'Months, + states = [], + transitions = [ + d.make_transition { + from = "designed", + to = "bootstrapped", + condition = "Radicle Heartwood seed nodes installed on every operator laptop, on libre-daoshi designated node, on libre-wuji designated node, and on ops-vm; per-operator Radicle identities created; for each workspace, three repos (policy/desired/state) initialized with correct delegation profiles (M-of-N for policy/desired, single ops-controller for state); audit-mirror sidecar deployed in libre-wuji subscribing to ops.audit subjects with jti idempotency check.", + catalyst = "ADR-038 accepted; ops contract (ADR-037) requires the audit ledger to land somewhere durable and decentralized — Radicle is that target.", + blocker = "Implementation not started; Radicle CLI familiarity required across operators; bootstrap playbook not yet written; ops-controller signing keys not yet generated for state repo delegation.", + horizon = 'Months, + }, + d.make_transition { + from = "bootstrapped", + to = "active", + condition = "policy- patches signed by quorum and deployed in production; keeper-daemon polls policy repo for latest commit and applies declarative matcher; -state ledger receiving live audit events from wuji; operator on/off-boarding playbooks tested with delegation patches; cross-replica gossip lag measured and within acceptable bounds (seconds-to-minutes for policy/desired updates).", + catalyst = "First production op signed via the new contract validates the end-to-end path: emitter → pending → keeper signs per policy → ops-controller applies → audit lands in Radicle state repo.", + blocker = "Bootstrap phase incomplete; production deployment requires both ADR-037 (ops) and ADR-038 (governance) implemented and validated together.", + horizon = 'Months, + }, + ], + }, + + d.make_dimension { + id = "build-infrastructure-state", + name = "Build Infrastructure State (ADR-039)", + description = "Maturity of ephemeral-runner + S3-backed zot build pattern — from architectural decision to operational golden image v1 to dynamic-sizing production.", + current_state = "designed", + desired_state = "production", + horizon = 'Months, + states = [], + transitions = [ + d.make_transition { + from = "designed", + to = "golden-image-v1", + condition = "Initial buildkit-runner-golden image built off-platform (laptop or external CI) and pushed to bootstrap zot; weekly rebuild Woodpecker pipeline defined; orchestrator vm_pool extended with buildkit lifecycle (spawn from golden + cleanup hook); buildkit-launcher crate compiles; .build-spec.ncl schema validated against schemas/lib/build_spec.ncl.", + catalyst = "Vapora and other Rust workloads need a build path; current absence of build infrastructure means manual local builds — gating for production deploys.", + blocker = "Implementation not started; bootstrap golden image must be produced manually first time; zot relocation from libre-daoshi to libre-wuji not yet executed.", + horizon = 'Months, + }, + d.make_transition { + from = "golden-image-v1", + to = "production", + condition = "zot deployed in libre-wuji with S3 backend (versioning + cross-region replication); multi-tenant auth configured (daoshi-CI write to /images /cache /sccache /crates; wuji-pods read /images; operators write /crates); BuildKit registry-cache and sccache S3 backend pointing at zot.wuji.local proven on Vapora-class build with measured cold-spawn-to-completion time; OOM auto-retry verified once and bounded; weekly golden image rebuild running on schedule with no manual intervention; cross-provider replication tested via failover drill.", + catalyst = "Production deploys via ops contract (ADR-037) require image artifacts in zot — build infrastructure is on the critical path for the deploy-from-CI flow.", + blocker = "Golden image v1 phase incomplete; zot still in libre-daoshi; observability for build metrics (Prometheus on builder VMs) not deployed.", + horizon = 'Months, + }, + ], + }, + + ], +} diff --git a/.ontology/workflow.ncl b/.ontology/workflow.ncl new file mode 100644 index 0000000..d645a1a --- /dev/null +++ b/.ontology/workflow.ncl @@ -0,0 +1,56 @@ +let W = import "reflection/schemas/workflow.ncl" in +let D = import "reflection/defaults/workflow.ncl" in + +# Workflow declaration for provisioning. +# Each layer is independent — layers form a set, not a chain. +# Regenerate artifacts after editing: ore workflow generate +# Preview changes: ore workflow diff + +{ + layers = [ + + # ── Commit-fast: pre-commit local checks ───────────────────────────────── + # Generates entries for .pre-commit-config.yaml (printed for manual merge). + { + id = "commit-fast", + trigger = 'OnCommit, + validations = [ + "rust-fmt", + "rust-clippy", + "nextest-ci-test", + "deny-subset", + "docs-drift", + "manifest-coverage", + ], + builds = [], + distributions = [], + providers = [W.pre_commit "pre-commit"], + }, + + # ── CI-standard: push/PR pipeline ──────────────────────────────────────── + # Generates .woodpecker/ci.yml and justfiles/workflow.just. + { + id = "ci-standard", + trigger = 'OnPR, + validations = [ + "rust-clippy-all", + "nextest-ci", + "deny-subset", + "docs-check", + "nickel-typecheck", + "nushell-check", + ], + builds = ["release-native"], + distributions = [], + providers = [ + W.woodpecker ".woodpecker/ci.yml", + W.justfile "ci-standard", + ], + }, + + ], + + validations = D.validations, + builds = D.builds, + distributions = {}, +} diff --git a/.typedialog/ci/README.md b/.typedialog/ci/README.md index a2b022f..e350592 100644 --- a/.typedialog/ci/README.md +++ b/.typedialog/ci/README.md @@ -92,7 +92,7 @@ vim .typedialog/ci/config.ncl **This project uses Nickel format by default** for all configuration files. -### Why Nickel? +### Why Nickel - ✅ **Typed configuration** - Static type checking with `nickel typecheck` - ✅ **Documentation** - Generate docs with `nickel doc config.ncl` @@ -320,7 +320,7 @@ Edit `config.ncl` and add under `ci.tools`: enable_pre_commit = false ``` -## Need Help? +## Need Help For detailed documentation, see: diff --git a/.typedialog/platform/forms/fragments/ai-service/dag.toml b/.typedialog/platform/forms/fragments/ai-service/dag.toml index 4f84ea7..40d276f 100644 --- a/.typedialog/platform/forms/fragments/ai-service/dag.toml +++ b/.typedialog/platform/forms/fragments/ai-service/dag.toml @@ -1,4 +1,7 @@ -# AI Service DAG Workflow Configuration Fragment +name = "dag" +description = "AI Service DAG Workflow Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -15,7 +18,8 @@ min = 1 name = "ai_dag_max_concurrent_tasks" nickel_path = ["ai_service", "dag", "max_concurrent_tasks"] prompt = "Max Concurrent Tasks" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 600000 @@ -25,7 +29,8 @@ min = 10000 name = "ai_dag_task_timeout" nickel_path = ["ai_service", "dag", "task_timeout"] prompt = "Task Timeout (ms)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 5 @@ -35,4 +40,5 @@ min = 0 name = "ai_dag_retry_attempts" nickel_path = ["ai_service", "dag", "retry_attempts"] prompt = "Retry Attempts" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/ai-service/mcp-integration.toml b/.typedialog/platform/forms/fragments/ai-service/mcp-integration.toml index dc5e52a..16bae29 100644 --- a/.typedialog/platform/forms/fragments/ai-service/mcp-integration.toml +++ b/.typedialog/platform/forms/fragments/ai-service/mcp-integration.toml @@ -1,4 +1,7 @@ -# AI Service MCP Integration Fragment +name = "mcp_integration" +description = "AI Service MCP Integration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -34,4 +37,5 @@ min = 1000 name = "ai_mcp_timeout" nickel_path = ["ai_service", "mcp", "timeout"] prompt = "Timeout (ms)" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/ai-service/monitoring.toml b/.typedialog/platform/forms/fragments/ai-service/monitoring.toml index 5b7d606..ba94a22 100644 --- a/.typedialog/platform/forms/fragments/ai-service/monitoring.toml +++ b/.typedialog/platform/forms/fragments/ai-service/monitoring.toml @@ -1,4 +1,7 @@ -# AI Service Monitoring Configuration Fragment +name = "monitoring" +description = "AI Service Monitoring Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -24,4 +27,5 @@ min = 5000 name = "ai_monitoring_metrics_interval" nickel_path = ["ai_service", "monitoring", "metrics_interval"] prompt = "Metrics Interval (ms)" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/ai-service/rag-integration.toml b/.typedialog/platform/forms/fragments/ai-service/rag-integration.toml index 8ccbe9c..4918e22 100644 --- a/.typedialog/platform/forms/fragments/ai-service/rag-integration.toml +++ b/.typedialog/platform/forms/fragments/ai-service/rag-integration.toml @@ -1,4 +1,7 @@ -# AI Service RAG Integration Fragment +name = "rag_integration" +description = "AI Service RAG Integration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -34,4 +37,5 @@ min = 1000 name = "ai_rag_timeout" nickel_path = ["ai_service", "rag", "timeout"] prompt = "Timeout (ms)" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/ai-service/server.toml b/.typedialog/platform/forms/fragments/ai-service/server.toml index 009ff1d..2cbe013 100644 --- a/.typedialog/platform/forms/fragments/ai-service/server.toml +++ b/.typedialog/platform/forms/fragments/ai-service/server.toml @@ -1,4 +1,7 @@ -# AI Service Server Configuration Fragment +name = "server" +description = "AI Service Server Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -25,7 +28,8 @@ name = "ai_service_server_port" nickel_path = ["ai_service", "server", "port"] prompt = "Server Port" required = true -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 4 @@ -36,4 +40,5 @@ name = "ai_service_server_workers" nickel_path = ["ai_service", "server", "workers"] prompt = "Worker Threads" required = true -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/constraint_interpolation_guide.md b/.typedialog/platform/forms/fragments/constraint_interpolation_guide.md index a93a682..ec323c6 100644 --- a/.typedialog/platform/forms/fragments/constraint_interpolation_guide.md +++ b/.typedialog/platform/forms/fragments/constraint_interpolation_guide.md @@ -2,7 +2,8 @@ ## Overview -TypeDialog form fields can reference constraints from `constraints.toml` using Jinja2-style template syntax. This provides a **single source of truth** for validation limits across forms, Nickel schemas, and validators. +TypeDialog form fields can reference constraints from `constraints.toml` using Jinja2-style template syntax. +This provides a **single source of truth** for validation limits across forms, Nickel schemas, and validators. ## Pattern diff --git a/.typedialog/platform/forms/fragments/constraint_update_status.md b/.typedialog/platform/forms/fragments/constraint_update_status.md index 7dac465..e207209 100644 --- a/.typedialog/platform/forms/fragments/constraint_update_status.md +++ b/.typedialog/platform/forms/fragments/constraint_update_status.md @@ -6,7 +6,9 @@ ## Summary -Constraint interpolation has been implemented for critical numeric form fields, providing a single source of truth for validation limits. The comprehensive mapping guide documents which constraints should be applied to remaining fragments. +Constraint interpolation has been implemented for critical numeric form fields, providing a single +source of truth for validation limits. The comprehensive mapping guide documents which constraints +should be applied to remaining fragments. ## Completed Fragments ✅ @@ -295,4 +297,5 @@ Ready to proceed with implementation: --- -**To contribute**: Pick any unchecked fragment above and follow the pattern in `constraint_interpolation_guide.md`. Each constraint update takes ~5 minutes per fragment. +**To contribute**: Pick any unchecked fragment above and follow the pattern in +`constraint_interpolation_guide.md`. Each constraint update takes ~5 minutes per fragment. diff --git a/.typedialog/platform/forms/fragments/control-center/compliance-section.toml b/.typedialog/platform/forms/fragments/control-center/compliance-section.toml index 5b8e169..9e91c79 100644 --- a/.typedialog/platform/forms/fragments/control-center/compliance-section.toml +++ b/.typedialog/platform/forms/fragments/control-center/compliance-section.toml @@ -1,4 +1,7 @@ -# Control Center Compliance & Audit Configuration Fragment +name = "compliance_section" +description = "Control Center Compliance & Audit Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -25,7 +28,8 @@ min = "${constraint.control_center.audit.retention_days.min}" name = "audit_retention_days" nickel_path = ["audit", "storage", "retention_days"] prompt = "Audit Retention (days)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "audit_enabled == true" @@ -72,7 +76,8 @@ min = 1 name = "compliance_validation_interval" nickel_path = ["compliance", "validation", "interval_hours"] prompt = "Validation Interval (hours)" -type = "number" +type = "custom" +custom_type = "Number" # Data Retention [[elements]] @@ -84,7 +89,8 @@ min = 1 name = "compliance_data_retention_years" nickel_path = ["compliance", "data_retention", "policy_years"] prompt = "Data Retention Policy (years)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "compliance_enabled == true" @@ -95,7 +101,8 @@ min = 90 name = "compliance_audit_log_days" nickel_path = ["compliance", "data_retention", "audit_log_days"] prompt = "Audit Log Retention (days)" -type = "number" +type = "custom" +custom_type = "Number" # Encryption Requirements [[elements]] diff --git a/.typedialog/platform/forms/fragments/control-center/policy-section.toml b/.typedialog/platform/forms/fragments/control-center/policy-section.toml index 1aba580..744bead 100644 --- a/.typedialog/platform/forms/fragments/control-center/policy-section.toml +++ b/.typedialog/platform/forms/fragments/control-center/policy-section.toml @@ -1,4 +1,7 @@ -# Control Center Policy Engine Configuration Fragment +name = "policy_section" +description = "Control Center Policy Engine Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -33,7 +36,8 @@ min = 60 name = "policy_cache_ttl" nickel_path = ["policy", "cache", "ttl"] prompt = "Cache TTL (seconds)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "policy_enabled == true && policy_cache_enabled == true" @@ -44,7 +48,8 @@ min = 100 name = "policy_cache_max_policies" nickel_path = ["policy", "cache", "max_policies"] prompt = "Max Cached Policies" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "policy_enabled == true" @@ -64,4 +69,5 @@ min = 1 name = "policy_versioning_max_versions" nickel_path = ["policy", "versioning", "max_versions"] prompt = "Max Policy Versions" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/control-center/rbac-section.toml b/.typedialog/platform/forms/fragments/control-center/rbac-section.toml index b2f0ff8..60e932e 100644 --- a/.typedialog/platform/forms/fragments/control-center/rbac-section.toml +++ b/.typedialog/platform/forms/fragments/control-center/rbac-section.toml @@ -1,4 +1,7 @@ -# Control Center RBAC Configuration Fragment +name = "rbac_section" +description = "Control Center RBAC Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false diff --git a/.typedialog/platform/forms/fragments/control-center/security-section.toml b/.typedialog/platform/forms/fragments/control-center/security-section.toml index 76f041e..c98739e 100644 --- a/.typedialog/platform/forms/fragments/control-center/security-section.toml +++ b/.typedialog/platform/forms/fragments/control-center/security-section.toml @@ -1,5 +1,7 @@ -# Control Center Security Configuration Fragment -# JWT, RBAC, MFA, rate limiting +name = "security_section" +description = "Control Center Security Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -47,7 +49,8 @@ min = "${constraint.control_center.jwt.token_expiration.min}" name = "jwt_token_expiration" nickel_path = ["security", "jwt", "token_expiration"] prompt = "Token Expiration (seconds)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "jwt_enabled == true" @@ -58,7 +61,8 @@ min = "${constraint.control_center.jwt.refresh_expiration.min}" name = "jwt_refresh_expiration" nickel_path = ["security", "jwt", "refresh_expiration"] prompt = "Refresh Token Expiration (seconds)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "jwt_enabled == true" @@ -124,7 +128,8 @@ min = "${constraint.control_center.rate_limiting.max_requests.min}" name = "rate_limiting_max_requests" nickel_path = ["security", "rate_limiting", "max_requests"] prompt = "Max Requests per Window" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "rate_limiting_enabled == true" @@ -135,7 +140,8 @@ min = "${constraint.control_center.rate_limiting.window_seconds.min}" name = "rate_limiting_window" nickel_path = ["security", "rate_limiting", "window_seconds"] prompt = "Rate Limit Window (seconds)" -type = "number" +type = "custom" +custom_type = "Number" # TLS Configuration [[elements]] @@ -163,7 +169,8 @@ min = 300 name = "sessions_max_age" nickel_path = ["security", "sessions", "max_age"] prompt = "Session Max Age (seconds)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "sessions_enabled == true" diff --git a/.typedialog/platform/forms/fragments/control-center/users-section.toml b/.typedialog/platform/forms/fragments/control-center/users-section.toml index 33144bf..9104ef0 100644 --- a/.typedialog/platform/forms/fragments/control-center/users-section.toml +++ b/.typedialog/platform/forms/fragments/control-center/users-section.toml @@ -1,4 +1,7 @@ -# Control Center User Management Configuration Fragment +name = "users_section" +description = "Control Center User Management Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -54,7 +57,8 @@ min = 1 name = "users_sessions_max_active" nickel_path = ["users", "sessions", "max_active"] prompt = "Max Active Sessions per User" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "users_enabled == true" @@ -65,7 +69,8 @@ min = 300 name = "users_sessions_idle_timeout" nickel_path = ["users", "sessions", "idle_timeout"] prompt = "Session Idle Timeout (seconds)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "users_enabled == true" @@ -76,7 +81,8 @@ min = 3600 name = "users_sessions_absolute_timeout" nickel_path = ["users", "sessions", "absolute_timeout"] prompt = "Absolute Session Timeout (seconds)" -type = "number" +type = "custom" +custom_type = "Number" # User Audit [[elements]] diff --git a/.typedialog/platform/forms/fragments/database-postgres-section.toml b/.typedialog/platform/forms/fragments/database-postgres-section.toml index 6f94869..a79ad49 100644 --- a/.typedialog/platform/forms/fragments/database-postgres-section.toml +++ b/.typedialog/platform/forms/fragments/database-postgres-section.toml @@ -1,5 +1,7 @@ -# PostgreSQL Database Configuration Fragment -# Used by: control-center, installer (when backend = postgresql) +name = "database_postgres_section" +description = "PostgreSQL Database Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -33,7 +35,8 @@ min = "${constraint.common.server.port.min}" name = "database_postgres_port" nickel_path = ["database", "port"] prompt = "PostgreSQL Port" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] help = "PostgreSQL database name" @@ -68,7 +71,8 @@ min = 5 name = "database_pool_size" nickel_path = ["database", "pool_size"] prompt = "Connection Pool Size" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 30 @@ -78,7 +82,8 @@ min = 10 name = "database_timeout" nickel_path = ["database", "timeout"] prompt = "Timeout (seconds)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 3 @@ -88,7 +93,8 @@ min = 0 name = "database_retry_attempts" nickel_path = ["database", "retry_attempts"] prompt = "Retry Attempts" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 100 @@ -98,4 +104,5 @@ min = 1000 name = "database_retry_delay" nickel_path = ["database", "retry_delay"] prompt = "Retry Delay (ms)" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/database-rocksdb-section.toml b/.typedialog/platform/forms/fragments/database-rocksdb-section.toml index 07da5e5..5c773f1 100644 --- a/.typedialog/platform/forms/fragments/database-rocksdb-section.toml +++ b/.typedialog/platform/forms/fragments/database-rocksdb-section.toml @@ -1,5 +1,7 @@ -# RocksDB Database Configuration Fragment -# Used by: control-center, installer (when backend = rocksdb) +name = "database_rocksdb_section" +description = "RocksDB Database Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -33,7 +35,8 @@ min = 1 name = "database_pool_size" nickel_path = ["database", "pool_size"] prompt = "Connection Pool Size" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 30 @@ -43,7 +46,8 @@ min = 10 name = "database_timeout" nickel_path = ["database", "timeout"] prompt = "Timeout (seconds)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 3 @@ -53,7 +57,8 @@ min = 0 name = "database_retry_attempts" nickel_path = ["database", "retry_attempts"] prompt = "Retry Attempts" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 100 @@ -63,4 +68,5 @@ min = 1000 name = "database_retry_delay" nickel_path = ["database", "retry_delay"] prompt = "Retry Delay (ms)" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/database-surrealdb-section.toml b/.typedialog/platform/forms/fragments/database-surrealdb-section.toml index 30b37c5..8fa60e3 100644 --- a/.typedialog/platform/forms/fragments/database-surrealdb-section.toml +++ b/.typedialog/platform/forms/fragments/database-surrealdb-section.toml @@ -1,5 +1,7 @@ -# SurrealDB Database Configuration Fragment -# Used by: orchestrator, control-center (when backend = surrealdb) +name = "database_surrealdb_section" +description = "SurrealDB Database Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -48,7 +50,8 @@ min = 1 name = "database_pool_size" nickel_path = ["database", "pool_size"] prompt = "Connection Pool Size" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 30 @@ -58,7 +61,8 @@ min = 10 name = "database_timeout" nickel_path = ["database", "timeout"] prompt = "Timeout (seconds)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 3 @@ -68,7 +72,8 @@ min = 0 name = "database_retry_attempts" nickel_path = ["database", "retry_attempts"] prompt = "Retry Attempts" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 100 @@ -78,4 +83,5 @@ min = 1000 name = "database_retry_delay" nickel_path = ["database", "retry_delay"] prompt = "Retry Delay (ms)" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/deployment/database-backend-selection.toml b/.typedialog/platform/forms/fragments/deployment/database-backend-selection.toml index 292d132..4e4a3e5 100644 --- a/.typedialog/platform/forms/fragments/deployment/database-backend-selection.toml +++ b/.typedialog/platform/forms/fragments/deployment/database-backend-selection.toml @@ -1,6 +1,7 @@ -# Database Backend Selection Fragment -# This fragment allows selecting the appropriate database backend (RocksDB, SurrealDB, PostgreSQL) -# Based on the selection, include the corresponding database-*-section.toml fragment +name = "database_backend_selection" +description = "Database Backend Selection Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -26,7 +27,7 @@ default = false help = "RocksDB: Embedded key-value store. Zero external dependencies, local filesystem storage, good for solo/multiuser modes. Limited to single instance." name = "rocksdb_info" prompt = "RocksDB Info" -type = "info" +type = "section" [[elements]] condition = "database_backend_selection == 'surrealdb_embedded'" @@ -34,7 +35,7 @@ default = false help = "SurrealDB (Embedded): In-process SurrealDB. No external server needed, queryable JSON/SQL, suitable for small to medium deployments." name = "surrealdb_embedded_info" prompt = "SurrealDB Embedded Info" -type = "info" +type = "section" [[elements]] condition = "database_backend_selection == 'surrealdb_server'" @@ -42,7 +43,7 @@ default = false help = "SurrealDB (Server): External SurrealDB server. Scalable multi-instance, HA ready, suitable for multiuser/enterprise modes." name = "surrealdb_server_info" prompt = "SurrealDB Server Info" -type = "info" +type = "section" [[elements]] condition = "database_backend_selection == 'postgresql'" @@ -50,7 +51,7 @@ default = false help = "PostgreSQL: Traditional RDBMS. Proven stability, full ACID, complex queries, suitable for enterprise with HA via replication." name = "postgresql_info" prompt = "PostgreSQL Info" -type = "info" +type = "section" # Backend Selection Guidelines [[elements]] @@ -66,7 +67,7 @@ default = false help = "Recommended for Solo: RocksDB (simplest) or SurrealDB Embedded (more features, same simplicity)" name = "solo_recommendation" prompt = "Solo Recommendation" -type = "info" +type = "section" [[elements]] condition = "deployment_mode == 'multiuser'" @@ -74,7 +75,7 @@ default = false help = "Recommended for MultiUser: SurrealDB Server (scalable, easy clustering) or PostgreSQL (if you need traditional RDBMS)" name = "multiuser_recommendation" prompt = "MultiUser Recommendation" -type = "info" +type = "section" [[elements]] condition = "deployment_mode == 'cicd'" @@ -82,7 +83,7 @@ default = false help = "Recommended for CI/CD: SurrealDB Embedded (ephemeral, no external deps) or RocksDB (fastest)" name = "cicd_recommendation" prompt = "CI/CD Recommendation" -type = "info" +type = "section" [[elements]] condition = "deployment_mode == 'enterprise'" @@ -90,4 +91,4 @@ default = false help = "Recommended for Enterprise: SurrealDB Server HA (native clustering) or PostgreSQL with replication + external backup service" name = "enterprise_recommendation" prompt = "Enterprise Recommendation" -type = "info" +type = "section" diff --git a/.typedialog/platform/forms/fragments/deployment/mode-selection.toml b/.typedialog/platform/forms/fragments/deployment/mode-selection.toml index 0e25d0e..d1bf54a 100644 --- a/.typedialog/platform/forms/fragments/deployment/mode-selection.toml +++ b/.typedialog/platform/forms/fragments/deployment/mode-selection.toml @@ -1,4 +1,7 @@ -# Deployment Mode Selection Fragment +name = "mode_selection" +description = "Deployment Mode Selection Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -32,7 +35,7 @@ default = false help = "Solo Mode: Single developer environment. Filesystem/RocksDB storage, 2-4 CPU cores, 4GB RAM. Minimal security, no HA. Ideal for local development and testing." name = "mode_solo_info" prompt = "Solo Mode" -type = "info" +type = "section" # MultiUser Mode Info (conditional) [[elements]] @@ -41,7 +44,7 @@ default = false help = "MultiUser Mode: Team development environment. PostgreSQL/SurrealDB, 4-8 CPU cores, 8GB RAM. RBAC enabled, shared storage, staging-ready. Ideal for team collaboration." name = "mode_multiuser_info" prompt = "MultiUser Mode" -type = "info" +type = "section" # CI/CD Mode Info (conditional) [[elements]] @@ -50,7 +53,7 @@ default = false help = "CI/CD Mode: Automated testing and pipeline environment. Ephemeral storage, 8+ CPU cores, 16GB RAM. API-driven, minimal UI, optimized for throughput. Ideal for automated testing." name = "mode_cicd_info" prompt = "CI/CD Mode" -type = "info" +type = "section" # Enterprise Mode Info (conditional) [[elements]] @@ -59,7 +62,7 @@ default = false help = "Enterprise Mode: Production high-availability environment. SurrealDB cluster, PostgreSQL HA, 16+ CPU cores, 32+ GB RAM. MFA required, compliance, full monitoring. Ideal for production deployments." name = "mode_enterprise_info" prompt = "Enterprise Mode" -type = "info" +type = "section" # Mode-Specific Default Values (informational) [[elements]] diff --git a/.typedialog/platform/forms/fragments/extension-registry/auth.toml b/.typedialog/platform/forms/fragments/extension-registry/auth.toml index 33868dd..c40abce 100644 --- a/.typedialog/platform/forms/fragments/extension-registry/auth.toml +++ b/.typedialog/platform/forms/fragments/extension-registry/auth.toml @@ -1,4 +1,7 @@ -# Extension Registry Authentication Fragment +name = "auth" +description = "Extension Registry Authentication Fragment" +display_mode = "complete" + [[elements]] border_bottom = false diff --git a/.typedialog/platform/forms/fragments/extension-registry/cache.toml b/.typedialog/platform/forms/fragments/extension-registry/cache.toml index aa42e11..8511738 100644 --- a/.typedialog/platform/forms/fragments/extension-registry/cache.toml +++ b/.typedialog/platform/forms/fragments/extension-registry/cache.toml @@ -1,4 +1,7 @@ -# Extension Registry Cache Configuration Fragment +name = "cache" +description = "Extension Registry Cache Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -15,7 +18,8 @@ min = 10 name = "registry_cache_capacity" nickel_path = ["extension_registry", "cache", "capacity"] prompt = "Cache Capacity" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 300 @@ -25,7 +29,8 @@ min = 30 name = "registry_cache_ttl" nickel_path = ["extension_registry", "cache", "ttl"] prompt = "Cache TTL (seconds)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = true diff --git a/.typedialog/platform/forms/fragments/extension-registry/gitea.toml b/.typedialog/platform/forms/fragments/extension-registry/gitea.toml index a70ea9a..5795881 100644 --- a/.typedialog/platform/forms/fragments/extension-registry/gitea.toml +++ b/.typedialog/platform/forms/fragments/extension-registry/gitea.toml @@ -1,4 +1,7 @@ -# Extension Registry Gitea Configuration Fragment +name = "gitea" +description = "Extension Registry Gitea Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -44,7 +47,8 @@ min = 5000 name = "registry_gitea_timeout" nickel_path = ["extension_registry", "gitea", "timeout"] prompt = "Timeout (ms)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "registry_gitea_enabled == true" diff --git a/.typedialog/platform/forms/fragments/extension-registry/oci.toml b/.typedialog/platform/forms/fragments/extension-registry/oci.toml index 3373de0..f9bf72f 100644 --- a/.typedialog/platform/forms/fragments/extension-registry/oci.toml +++ b/.typedialog/platform/forms/fragments/extension-registry/oci.toml @@ -1,4 +1,7 @@ -# Extension Registry OCI Configuration Fragment +name = "oci" +description = "Extension Registry OCI Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -44,7 +47,8 @@ min = 5000 name = "registry_oci_timeout" nickel_path = ["extension_registry", "oci", "timeout"] prompt = "Timeout (ms)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "registry_oci_enabled == true" diff --git a/.typedialog/platform/forms/fragments/extension-registry/server.toml b/.typedialog/platform/forms/fragments/extension-registry/server.toml index 3f67522..1243551 100644 --- a/.typedialog/platform/forms/fragments/extension-registry/server.toml +++ b/.typedialog/platform/forms/fragments/extension-registry/server.toml @@ -1,4 +1,7 @@ -# Extension Registry Server Configuration Fragment +name = "server" +description = "Extension Registry Server Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -25,7 +28,8 @@ name = "registry_server_port" nickel_path = ["extension_registry", "server", "port"] prompt = "Server Port" required = true -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 4 @@ -36,7 +40,8 @@ name = "registry_server_workers" nickel_path = ["extension_registry", "server", "workers"] prompt = "Worker Threads" required = true -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = false diff --git a/.typedialog/platform/forms/fragments/installer/database-section.toml b/.typedialog/platform/forms/fragments/installer/database-section.toml index 324d12b..888a5c9 100644 --- a/.typedialog/platform/forms/fragments/installer/database-section.toml +++ b/.typedialog/platform/forms/fragments/installer/database-section.toml @@ -1,4 +1,7 @@ -# Installer Database Configuration Fragment +name = "database_section" +description = "Installer Database Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -62,7 +65,8 @@ min = 30 name = "migration_timeout_seconds" nickel_path = ["installer", "database", "migrations", "timeout_seconds"] prompt = "Migration Timeout (seconds)" -type = "number" +type = "custom" +custom_type = "Number" # Database Backup [[elements]] @@ -110,7 +114,8 @@ min = 1 name = "backup_retention_days" nickel_path = ["installer", "database", "backup", "retention_days"] prompt = "Backup Retention (days)" -type = "number" +type = "custom" +custom_type = "Number" # Database Verification [[elements]] @@ -185,7 +190,8 @@ min = 1 name = "connection_pool_size" nickel_path = ["installer", "database", "pool_size"] prompt = "Connection Pool Size" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 300 @@ -195,7 +201,8 @@ min = 10 name = "connection_pool_timeout" nickel_path = ["installer", "database", "pool_timeout_seconds"] prompt = "Pool Timeout (seconds)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 3600 @@ -205,7 +212,8 @@ min = 60 name = "connection_idle_timeout" nickel_path = ["installer", "database", "idle_timeout_seconds"] prompt = "Idle Timeout (seconds)" -type = "number" +type = "custom" +custom_type = "Number" # Database Optimization [[elements]] diff --git a/.typedialog/platform/forms/fragments/installer/ha-section.toml b/.typedialog/platform/forms/fragments/installer/ha-section.toml index a5ca359..b1aa551 100644 --- a/.typedialog/platform/forms/fragments/installer/ha-section.toml +++ b/.typedialog/platform/forms/fragments/installer/ha-section.toml @@ -1,4 +1,7 @@ -# Installer High Availability Configuration Fragment +name = "ha_section" +description = "Installer High Availability Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -26,7 +29,8 @@ min = 3 name = "ha_cluster_size" nickel_path = ["installer", "ha", "cluster_size"] prompt = "Cluster Size" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "ha_enabled == true" @@ -87,7 +91,8 @@ min = 1 name = "ha_db_quorum_size" nickel_path = ["installer", "ha", "database", "quorum_size"] prompt = "DB Quorum Size" -type = "number" +type = "custom" +custom_type = "Number" # Health Checks [[elements]] @@ -108,7 +113,8 @@ min = 1 name = "ha_health_check_interval" nickel_path = ["installer", "ha", "health_checks", "interval_seconds"] prompt = "Health Check Interval (seconds)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "ha_health_checks_enabled == true" @@ -119,7 +125,8 @@ min = 1000 name = "ha_health_check_timeout" nickel_path = ["installer", "ha", "health_checks", "timeout_ms"] prompt = "Health Check Timeout (ms)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "ha_health_checks_enabled == true" @@ -130,7 +137,8 @@ min = 1 name = "ha_health_check_failure_threshold" nickel_path = ["installer", "ha", "health_checks", "failure_threshold"] prompt = "Failure Threshold" -type = "number" +type = "custom" +custom_type = "Number" # Failover Configuration [[elements]] @@ -161,7 +169,8 @@ min = 0 name = "ha_failover_delay" nickel_path = ["installer", "ha", "failover", "delay_seconds"] prompt = "Failover Delay (seconds)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "ha_failover_enabled == true && ha_failover_strategy == 'priority_based'" @@ -172,7 +181,8 @@ min = 0 name = "ha_node_priority" nickel_path = ["installer", "ha", "failover", "node_priority"] prompt = "Node Priority" -type = "number" +type = "custom" +custom_type = "Number" # Split Brain Prevention [[elements]] @@ -193,7 +203,8 @@ min = 5 name = "ha_split_brain_timeout" nickel_path = ["installer", "ha", "split_brain", "timeout_seconds"] prompt = "Split-Brain Timeout (seconds)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "ha_split_brain_enabled == true" @@ -224,7 +235,8 @@ min = 300 name = "ha_backup_interval" nickel_path = ["installer", "ha", "backup", "interval_seconds"] prompt = "Backup Interval (seconds)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "ha_backup_enabled == true" @@ -235,7 +247,8 @@ min = 1 name = "ha_backup_retention_days" nickel_path = ["installer", "ha", "backup", "retention_days"] prompt = "Backup Retention (days)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "ha_backup_enabled == true" @@ -285,4 +298,5 @@ min = 5 name = "ha_metrics_interval" nickel_path = ["installer", "ha", "metrics", "interval_seconds"] prompt = "Metrics Interval (seconds)" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/installer/installation-section.toml b/.typedialog/platform/forms/fragments/installer/installation-section.toml index 67e9ae7..323c723 100644 --- a/.typedialog/platform/forms/fragments/installer/installation-section.toml +++ b/.typedialog/platform/forms/fragments/installer/installation-section.toml @@ -1,4 +1,7 @@ -# Installer Installation Strategy Configuration Fragment +name = "installation_section" +description = "Installer Installation Strategy Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -26,7 +29,8 @@ min = 1 name = "parallel_services" nickel_path = ["installer", "installation", "parallel_services"] prompt = "Parallel Services" -type = "number" +type = "custom" +custom_type = "Number" # Installation Timeout [[elements]] @@ -37,7 +41,8 @@ min = 0 name = "installation_timeout_seconds" nickel_path = ["installer", "installation", "timeout_seconds"] prompt = "Installation Timeout (seconds)" -type = "number" +type = "custom" +custom_type = "Number" # Rollback Strategy [[elements]] @@ -183,7 +188,8 @@ min = 5000 name = "validation_timeout" nickel_path = ["installer", "installation", "validation", "timeout_ms"] prompt = "Validation Timeout (ms)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "validate_installation == true" @@ -221,7 +227,8 @@ min = 1 name = "auto_recovery_max_attempts" nickel_path = ["installer", "installation", "auto_recovery", "max_attempts"] prompt = "Max Recovery Attempts" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "auto_recovery_enabled == true" @@ -231,4 +238,5 @@ min = 5 name = "auto_recovery_delay_seconds" nickel_path = ["installer", "installation", "auto_recovery", "delay_seconds"] prompt = "Recovery Delay (seconds)" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/installer/networking-section.toml b/.typedialog/platform/forms/fragments/installer/networking-section.toml index 161666f..4de8b52 100644 --- a/.typedialog/platform/forms/fragments/installer/networking-section.toml +++ b/.typedialog/platform/forms/fragments/installer/networking-section.toml @@ -1,4 +1,7 @@ -# Installer Networking Configuration Fragment +name = "networking_section" +description = "Installer Networking Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -61,7 +64,8 @@ min = 1 name = "dns_port" nickel_path = ["installer", "networking", "dns", "port"] prompt = "DNS Port" -type = "number" +type = "custom" +custom_type = "Number" # TLS/HTTPS Configuration [[elements]] @@ -146,7 +150,8 @@ min = 1 name = "firewall_rate_limit_rpm" nickel_path = ["installer", "networking", "firewall", "rate_limiting", "requests_per_minute"] prompt = "Rate Limit (req/min)" -type = "number" +type = "custom" +custom_type = "Number" # Load Balancer Configuration [[elements]] @@ -176,7 +181,8 @@ min = "${constraint.common.server.port.min}" name = "load_balancer_http_port" nickel_path = ["installer", "networking", "load_balancer", "http_port"] prompt = "Load Balancer HTTP Port" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "install_load_balancer == true" @@ -187,7 +193,8 @@ min = "${constraint.common.server.port.min}" name = "load_balancer_https_port" nickel_path = ["installer", "networking", "load_balancer", "https_port"] prompt = "Load Balancer HTTPS Port" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "install_load_balancer == true" @@ -282,4 +289,5 @@ min = 5 name = "traffic_monitoring_interval" nickel_path = ["installer", "networking", "monitoring", "interval_seconds"] prompt = "Monitoring Interval (seconds)" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/installer/post-install-section.toml b/.typedialog/platform/forms/fragments/installer/post-install-section.toml index b9b7860..f6ff9ee 100644 --- a/.typedialog/platform/forms/fragments/installer/post-install-section.toml +++ b/.typedialog/platform/forms/fragments/installer/post-install-section.toml @@ -1,4 +1,7 @@ -# Installer Post-Installation Configuration Fragment +name = "post_install_section" +description = "Installer Post-Installation Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -139,7 +142,8 @@ min = 30 name = "verification_timeout" nickel_path = ["installer", "post_install", "verification", "timeout_seconds"] prompt = "Verification Timeout (seconds)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "run_verification_tests == true" diff --git a/.typedialog/platform/forms/fragments/installer/preflight-section.toml b/.typedialog/platform/forms/fragments/installer/preflight-section.toml index 4f9decb..7a9f4c5 100644 --- a/.typedialog/platform/forms/fragments/installer/preflight-section.toml +++ b/.typedialog/platform/forms/fragments/installer/preflight-section.toml @@ -1,4 +1,7 @@ -# Installer Preflight Checks Configuration Fragment +name = "preflight_section" +description = "Installer Preflight Checks Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -25,7 +28,8 @@ min = 1 name = "min_disk_gb" nickel_path = ["installer", "preflight", "disk_space_check", "min_disk_gb"] prompt = "Min Disk Space (GB)" -type = "number" +type = "custom" +custom_type = "Number" # Memory Check [[elements]] @@ -45,7 +49,8 @@ min = 1 name = "min_memory_gb" nickel_path = ["installer", "preflight", "memory_check", "min_memory_gb"] prompt = "Min Memory (GB)" -type = "number" +type = "custom" +custom_type = "Number" # CPU Check [[elements]] @@ -65,7 +70,8 @@ min = 1 name = "min_cpu_cores" nickel_path = ["installer", "preflight", "cpu_check", "min_cpu_cores"] prompt = "Min CPU Cores" -type = "number" +type = "custom" +custom_type = "Number" # Network Check [[elements]] diff --git a/.typedialog/platform/forms/fragments/installer/services-section.toml b/.typedialog/platform/forms/fragments/installer/services-section.toml index 6021860..9318f8a 100644 --- a/.typedialog/platform/forms/fragments/installer/services-section.toml +++ b/.typedialog/platform/forms/fragments/installer/services-section.toml @@ -1,4 +1,7 @@ -# Installer Services Selection Fragment +name = "services_section" +description = "Installer Services Selection Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -125,7 +128,8 @@ min = "${constraint.common.server.port.min}" name = "orchestrator_port" nickel_path = ["installer", "services", "orchestrator", "port"] prompt = "Orchestrator Port" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "install_control_center == true" @@ -136,7 +140,8 @@ min = "${constraint.common.server.port.min}" name = "control_center_port" nickel_path = ["installer", "services", "control_center", "port"] prompt = "Control Center Port" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "install_mcp_server == true" @@ -147,7 +152,8 @@ min = "${constraint.common.server.port.min}" name = "mcp_server_port" nickel_path = ["installer", "services", "mcp_server", "port"] prompt = "MCP Server Port" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "install_api_gateway == true" @@ -158,7 +164,8 @@ min = "${constraint.common.server.port.min}" name = "api_gateway_port" nickel_path = ["installer", "services", "api_gateway", "port"] prompt = "API Gateway Port" -type = "number" +type = "custom" +custom_type = "Number" # Service Update Strategy [[elements]] @@ -186,4 +193,5 @@ min = 5 name = "health_check_interval" nickel_path = ["installer", "services", "health_checks", "interval_seconds"] prompt = "Health Check Interval (seconds)" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/installer/storage-section.toml b/.typedialog/platform/forms/fragments/installer/storage-section.toml index b3b7ac4..6631fcb 100644 --- a/.typedialog/platform/forms/fragments/installer/storage-section.toml +++ b/.typedialog/platform/forms/fragments/installer/storage-section.toml @@ -1,4 +1,7 @@ -# Installer Storage Configuration Fragment +name = "storage_section" +description = "Installer Storage Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -25,7 +28,8 @@ min = 10 name = "storage_size_gb" nickel_path = ["installer", "storage", "size_gb"] prompt = "Storage Size (GB)" -type = "number" +type = "custom" +custom_type = "Number" # Storage Backend Selection [[elements]] @@ -193,7 +197,8 @@ min = 2 name = "storage_replication_factor" nickel_path = ["installer", "storage", "replication", "factor"] prompt = "Replication Factor" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "storage_replication_enabled == true" @@ -223,7 +228,8 @@ min = 7 name = "storage_cleanup_retention_days" nickel_path = ["installer", "storage", "cleanup", "retention_days"] prompt = "Retention Period (days)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "storage_cleanup_enabled == true" diff --git a/.typedialog/platform/forms/fragments/installer/target-section.toml b/.typedialog/platform/forms/fragments/installer/target-section.toml index 3c7a0ea..993fc61 100644 --- a/.typedialog/platform/forms/fragments/installer/target-section.toml +++ b/.typedialog/platform/forms/fragments/installer/target-section.toml @@ -1,4 +1,7 @@ -# Installer Target Configuration Fragment +name = "target_section" +description = "Installer Target Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -49,7 +52,8 @@ min = "${constraint.common.server.port.min}" name = "remote_ssh_port" nickel_path = ["installer", "target", "remote_ssh_port"] prompt = "SSH Port" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "target_type == 'remote'" diff --git a/.typedialog/platform/forms/fragments/installer/upgrades-section.toml b/.typedialog/platform/forms/fragments/installer/upgrades-section.toml index 1725ad9..942c5fe 100644 --- a/.typedialog/platform/forms/fragments/installer/upgrades-section.toml +++ b/.typedialog/platform/forms/fragments/installer/upgrades-section.toml @@ -1,4 +1,7 @@ -# Installer Upgrades Configuration Fragment +name = "upgrades_section" +description = "Installer Upgrades Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -63,7 +66,8 @@ min = 1 name = "rolling_upgrade_parallel" nickel_path = ["installer", "upgrades", "rolling", "parallel_services"] prompt = "Parallel Services" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "upgrade_strategy == 'canary'" @@ -74,7 +78,8 @@ min = 1 name = "canary_percentage" nickel_path = ["installer", "upgrades", "canary", "traffic_percentage"] prompt = "Canary Traffic %" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "upgrade_strategy == 'canary'" @@ -85,7 +90,8 @@ min = 30 name = "canary_duration_seconds" nickel_path = ["installer", "upgrades", "canary", "duration_seconds"] prompt = "Canary Duration (seconds)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "upgrade_strategy == 'maintenance_window'" @@ -115,7 +121,8 @@ min = 600 name = "maintenance_duration_seconds" nickel_path = ["installer", "upgrades", "maintenance_window", "max_duration_seconds"] prompt = "Max Duration (seconds)" -type = "number" +type = "custom" +custom_type = "Number" # Pre-Upgrade Checks [[elements]] @@ -190,7 +197,8 @@ min = 5 name = "backup_timeout_minutes" nickel_path = ["installer", "upgrades", "backup_timeout_minutes"] prompt = "Backup Timeout (minutes)" -type = "number" +type = "custom" +custom_type = "Number" # Upgrade Rollback [[elements]] @@ -220,7 +228,8 @@ min = 30 name = "rollback_validation_delay" nickel_path = ["installer", "upgrades", "rollback", "validation_delay_seconds"] prompt = "Validation Delay (seconds)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "enable_rollback_on_failure == true" @@ -290,7 +299,8 @@ min = 5 name = "post_upgrade_health_check_interval" nickel_path = ["installer", "upgrades", "post_upgrade", "health_check_interval_seconds"] prompt = "Health Check Interval (seconds)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "health_checks_post_upgrade == true" @@ -301,7 +311,8 @@ min = 60 name = "post_upgrade_monitoring_duration" nickel_path = ["installer", "upgrades", "post_upgrade", "monitoring_duration_seconds"] prompt = "Monitoring Duration (seconds)" -type = "number" +type = "custom" +custom_type = "Number" # Version Constraints [[elements]] diff --git a/.typedialog/platform/forms/fragments/logging-section.toml b/.typedialog/platform/forms/fragments/logging-section.toml index 8a2cea7..635b2d3 100644 --- a/.typedialog/platform/forms/fragments/logging-section.toml +++ b/.typedialog/platform/forms/fragments/logging-section.toml @@ -1,5 +1,7 @@ -# Logging Configuration Fragment -# Optional for all services +name = "logging_section" +description = "Logging Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -43,7 +45,8 @@ min = "${constraint.common.logging.max_file_size.min}" name = "logging_max_file_size" nickel_path = ["logging", "file", "max_size"] prompt = "Max File Size (bytes)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "logging_file_enabled == true" @@ -54,4 +57,5 @@ min = "${constraint.common.logging.max_backups.min}" name = "logging_max_backups" nickel_path = ["logging", "file", "max_backups"] prompt = "Max Backup Files" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/mcp-server/prompts-section.toml b/.typedialog/platform/forms/fragments/mcp-server/prompts-section.toml index 3de206f..242c1bd 100644 --- a/.typedialog/platform/forms/fragments/mcp-server/prompts-section.toml +++ b/.typedialog/platform/forms/fragments/mcp-server/prompts-section.toml @@ -1,4 +1,7 @@ -# MCP Server Prompts Configuration Fragment +name = "prompts_section" +description = "MCP Server Prompts Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -24,7 +27,8 @@ min = "${constraint.mcp_server.prompts.max_templates.min}" name = "prompts_max_templates" nickel_path = ["prompts", "max_templates"] prompt = "Max Prompt Templates" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "prompts_enabled == true" @@ -44,7 +48,8 @@ min = 60 name = "prompts_cache_ttl" nickel_path = ["prompts", "cache", "ttl"] prompt = "Cache TTL (seconds)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "prompts_enabled == true" @@ -64,4 +69,5 @@ min = 1 name = "prompts_versioning_max_versions" nickel_path = ["prompts", "versioning", "max_versions"] prompt = "Max Prompt Versions" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/mcp-server/resources-section.toml b/.typedialog/platform/forms/fragments/mcp-server/resources-section.toml index 84ab8d3..b80b499 100644 --- a/.typedialog/platform/forms/fragments/mcp-server/resources-section.toml +++ b/.typedialog/platform/forms/fragments/mcp-server/resources-section.toml @@ -1,4 +1,7 @@ -# MCP Server Resources Configuration Fragment +name = "resources_section" +description = "MCP Server Resources Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -24,7 +27,8 @@ min = "${constraint.mcp_server.resources.max_size.min}" name = "resources_max_size" nickel_path = ["resources", "max_size"] prompt = "Max Resource Size (bytes)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "resources_enabled == true" @@ -44,7 +48,8 @@ min = 10 name = "resources_cache_max_size_mb" nickel_path = ["resources", "cache", "max_size_mb"] prompt = "Max Cache Size (MB)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "resources_enabled == true && resources_cache_enabled == true" @@ -55,7 +60,8 @@ min = "${constraint.mcp_server.resources.cache_ttl.min}" name = "resources_cache_ttl" nickel_path = ["resources", "cache", "ttl"] prompt = "Cache TTL (seconds)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "resources_enabled == true" @@ -75,4 +81,5 @@ min = 1 name = "resources_validation_max_depth" nickel_path = ["resources", "validation", "max_depth"] prompt = "Max Nesting Depth" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/mcp-server/sampling-section.toml b/.typedialog/platform/forms/fragments/mcp-server/sampling-section.toml index 50ab03a..f1a9d17 100644 --- a/.typedialog/platform/forms/fragments/mcp-server/sampling-section.toml +++ b/.typedialog/platform/forms/fragments/mcp-server/sampling-section.toml @@ -1,4 +1,7 @@ -# MCP Server Sampling Configuration Fragment +name = "sampling_section" +description = "MCP Server Sampling Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -24,7 +27,8 @@ min = "${constraint.mcp_server.sampling.max_tokens.min}" name = "sampling_max_tokens" nickel_path = ["sampling", "max_tokens"] prompt = "Max Tokens" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "sampling_enabled == true" @@ -44,7 +48,8 @@ min = 0.0 name = "sampling_temperature" nickel_path = ["sampling", "temperature"] prompt = "Temperature" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "sampling_enabled == true" @@ -64,4 +69,5 @@ min = 60 name = "sampling_cache_ttl" nickel_path = ["sampling", "cache", "ttl"] prompt = "Cache TTL (seconds)" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/mcp-server/tools-section.toml b/.typedialog/platform/forms/fragments/mcp-server/tools-section.toml index 3a2ef1d..0112dab 100644 --- a/.typedialog/platform/forms/fragments/mcp-server/tools-section.toml +++ b/.typedialog/platform/forms/fragments/mcp-server/tools-section.toml @@ -1,4 +1,7 @@ -# MCP Server Tools Configuration Fragment +name = "tools_section" +description = "MCP Server Tools Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -24,7 +27,8 @@ min = "${constraint.mcp_server.tools.max_concurrent.min}" name = "tools_max_concurrent" nickel_path = ["tools", "max_concurrent"] prompt = "Max Concurrent Tools" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "tools_enabled == true" @@ -35,7 +39,8 @@ min = "${constraint.mcp_server.tools.timeout.min}" name = "tools_timeout" nickel_path = ["tools", "timeout"] prompt = "Tool Timeout (ms)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "tools_enabled == true" @@ -72,4 +77,5 @@ min = 60 name = "tools_cache_ttl" nickel_path = ["tools", "cache", "ttl"] prompt = "Cache TTL (seconds)" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/monitoring-section.toml b/.typedialog/platform/forms/fragments/monitoring-section.toml index ad0108e..e2b0ecf 100644 --- a/.typedialog/platform/forms/fragments/monitoring-section.toml +++ b/.typedialog/platform/forms/fragments/monitoring-section.toml @@ -1,5 +1,7 @@ -# Monitoring Configuration Fragment -# Optional for all services +name = "monitoring_section" +description = "Monitoring Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -34,4 +36,5 @@ min = "${constraint.common.monitoring.metrics_interval.min}" name = "monitoring_metrics_interval" nickel_path = ["monitoring", "metrics", "interval"] prompt = "Metrics Collection Interval (seconds)" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/orchestrator/batch-section.toml b/.typedialog/platform/forms/fragments/orchestrator/batch-section.toml index fa72ed2..d24304c 100644 --- a/.typedialog/platform/forms/fragments/orchestrator/batch-section.toml +++ b/.typedialog/platform/forms/fragments/orchestrator/batch-section.toml @@ -1,4 +1,7 @@ -# Orchestrator Batch Workflow Configuration Fragment +name = "batch_section" +description = "Orchestrator Batch Workflow Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -15,7 +18,8 @@ min = "${constraint.orchestrator.batch.parallel_limit.min}" name = "batch_parallel_limit" nickel_path = ["batch", "parallel_limit"] prompt = "Parallel Limit" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 1800000 @@ -25,7 +29,8 @@ min = "${constraint.orchestrator.batch.operation_timeout.min}" name = "batch_operation_timeout" nickel_path = ["batch", "operation_timeout"] prompt = "Operation Timeout (ms)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = true @@ -43,7 +48,8 @@ min = 10 name = "batch_checkpoint_interval" nickel_path = ["batch", "checkpointing", "interval"] prompt = "Checkpoint Interval" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "batch_checkpointing_enabled == true" @@ -53,7 +59,8 @@ min = 1 name = "batch_checkpoint_max_checkpoints" nickel_path = ["batch", "checkpointing", "max_checkpoints"] prompt = "Max Checkpoints" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = true @@ -82,7 +89,8 @@ min = 1 name = "batch_rollback_max_depth" nickel_path = ["batch", "rollback", "max_rollback_depth"] prompt = "Max Rollback Depth" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = false diff --git a/.typedialog/platform/forms/fragments/orchestrator/extensions-section.toml b/.typedialog/platform/forms/fragments/orchestrator/extensions-section.toml index d3da111..ab42fb5 100644 --- a/.typedialog/platform/forms/fragments/orchestrator/extensions-section.toml +++ b/.typedialog/platform/forms/fragments/orchestrator/extensions-section.toml @@ -1,4 +1,7 @@ -# Orchestrator Extensions Configuration Fragment +name = "extensions_section" +description = "Orchestrator Extensions Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -65,7 +68,8 @@ min = 300 name = "extensions_discovery_interval" nickel_path = ["orchestrator", "extensions", "discovery_interval_seconds"] prompt = "Discovery Interval (seconds)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "auto_load_extensions == true" @@ -76,7 +80,8 @@ min = "${constraint.orchestrator.extensions.max_concurrent.min}" name = "extensions_max_concurrent" nickel_path = ["orchestrator", "extensions", "max_concurrent"] prompt = "Max Concurrent Extensions" -type = "number" +type = "custom" +custom_type = "Number" # Extension Execution Settings [[elements]] @@ -88,7 +93,8 @@ min = 1000 name = "extensions_init_timeout" nickel_path = ["orchestrator", "extensions", "init_timeout_ms"] prompt = "Init Timeout (ms)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "auto_load_extensions == true" @@ -117,7 +123,8 @@ min = 64 name = "extensions_sandbox_max_memory_mb" nickel_path = ["orchestrator", "extensions", "sandbox", "max_memory_mb"] prompt = "Max Memory (MB)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "auto_load_extensions == true && extensions_sandbox_enabled == true" @@ -128,7 +135,8 @@ min = 0.1 name = "extensions_sandbox_max_cpu" nickel_path = ["orchestrator", "extensions", "sandbox", "max_cpu"] prompt = "Max CPU Cores" -type = "number" +type = "custom" +custom_type = "Number" # Extension Versioning and Compatibility [[elements]] @@ -168,7 +176,8 @@ min = 5000 name = "extensions_health_check_interval" nickel_path = ["orchestrator", "extensions", "health_check", "interval_ms"] prompt = "Health Check Interval (ms)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "auto_load_extensions == true && extensions_health_check_enabled == true" @@ -179,4 +188,5 @@ min = 1 name = "extensions_health_check_failure_threshold" nickel_path = ["orchestrator", "extensions", "health_check", "failure_threshold"] prompt = "Failure Threshold" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/orchestrator/performance-section.toml b/.typedialog/platform/forms/fragments/orchestrator/performance-section.toml index a788b09..dc5e22d 100644 --- a/.typedialog/platform/forms/fragments/orchestrator/performance-section.toml +++ b/.typedialog/platform/forms/fragments/orchestrator/performance-section.toml @@ -1,4 +1,7 @@ -# Orchestrator Performance Configuration Fragment +name = "performance_section" +description = "Orchestrator Performance Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -44,7 +47,8 @@ min = 256 name = "memory_max_heap_mb" nickel_path = ["orchestrator", "performance", "memory_limits", "max_heap_mb"] prompt = "Max Heap Memory (MB)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "memory_limits_enabled == true" @@ -55,7 +59,8 @@ min = 128 name = "memory_initial_heap_mb" nickel_path = ["orchestrator", "performance", "memory_limits", "initial_heap_mb"] prompt = "Initial Heap Memory (MB)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "memory_limits_enabled == true" @@ -66,7 +71,8 @@ min = 50 name = "memory_gc_threshold_percent" nickel_path = ["orchestrator", "performance", "memory_limits", "gc_threshold_percent"] prompt = "GC Threshold (%)" -type = "number" +type = "custom" +custom_type = "Number" # Profiling Settings [[elements]] @@ -96,7 +102,8 @@ min = 10 name = "profiling_sample_rate" nickel_path = ["orchestrator", "performance", "profiling", "sample_rate_hz"] prompt = "Sampling Rate (Hz)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "profiling_enabled == true" @@ -135,7 +142,8 @@ min = 1 name = "profiling_memory_min_size_kb" nickel_path = ["orchestrator", "performance", "profiling", "memory_profiling", "min_alloc_kb"] prompt = "Min Allocation Size (KB)" -type = "number" +type = "custom" +custom_type = "Number" # Caching and Optimization [[elements]] @@ -155,7 +163,8 @@ min = 1000 name = "inline_cache_max_entries" nickel_path = ["orchestrator", "performance", "inline_cache", "max_entries"] prompt = "Max Cache Entries" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "inline_cache_enabled == true" @@ -166,7 +175,8 @@ min = 60 name = "inline_cache_ttl" nickel_path = ["orchestrator", "performance", "inline_cache", "ttl_seconds"] prompt = "Cache TTL (seconds)" -type = "number" +type = "custom" +custom_type = "Number" # Thread Pool Configuration [[elements]] @@ -177,7 +187,8 @@ min = 1 name = "thread_pool_size" nickel_path = ["orchestrator", "performance", "thread_pool", "size"] prompt = "Thread Pool Size" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 128 @@ -187,7 +198,8 @@ min = 8 name = "thread_pool_queue_size" nickel_path = ["orchestrator", "performance", "thread_pool", "queue_size"] prompt = "Work Queue Size" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = "work_stealing" @@ -216,7 +228,8 @@ min = 1 name = "async_io_worker_threads" nickel_path = ["orchestrator", "performance", "async_io", "worker_threads"] prompt = "I/O Worker Threads" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "async_io_enabled == true" @@ -227,4 +240,5 @@ min = 256 name = "async_io_max_in_flight" nickel_path = ["orchestrator", "performance", "async_io", "max_in_flight"] prompt = "Max I/O In Flight" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/orchestrator/queue-section.toml b/.typedialog/platform/forms/fragments/orchestrator/queue-section.toml index b35ddc5..ae29a0c 100644 --- a/.typedialog/platform/forms/fragments/orchestrator/queue-section.toml +++ b/.typedialog/platform/forms/fragments/orchestrator/queue-section.toml @@ -1,4 +1,7 @@ -# Orchestrator Queue Configuration Fragment +name = "queue_section" +description = "Orchestrator Queue Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -15,7 +18,8 @@ min = "${constraint.orchestrator.queue.concurrent_tasks.min}" name = "queue_max_concurrent_tasks" nickel_path = ["queue", "max_concurrent_tasks"] prompt = "Max Concurrent Tasks" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 3 @@ -25,7 +29,8 @@ min = "${constraint.orchestrator.queue.retry_attempts.min}" name = "queue_retry_attempts" nickel_path = ["queue", "retry_attempts"] prompt = "Retry Attempts" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 5000 @@ -35,7 +40,8 @@ min = "${constraint.orchestrator.queue.retry_delay.min}" name = "queue_retry_delay" nickel_path = ["queue", "retry_delay"] prompt = "Retry Delay (ms)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 3600000 @@ -45,7 +51,8 @@ min = "${constraint.orchestrator.queue.task_timeout.min}" name = "queue_task_timeout" nickel_path = ["queue", "task_timeout"] prompt = "Task Timeout (ms)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = true diff --git a/.typedialog/platform/forms/fragments/orchestrator/storage-section.toml b/.typedialog/platform/forms/fragments/orchestrator/storage-section.toml index 67f3239..c0f9683 100644 --- a/.typedialog/platform/forms/fragments/orchestrator/storage-section.toml +++ b/.typedialog/platform/forms/fragments/orchestrator/storage-section.toml @@ -1,4 +1,7 @@ -# Orchestrator Storage Configuration Fragment +name = "storage_section" +description = "Orchestrator Storage Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -98,7 +101,8 @@ min = 60 name = "storage_cache_ttl" nickel_path = ["orchestrator", "storage", "cache", "ttl"] prompt = "Cache TTL (seconds)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "storage_cache_enabled == true" @@ -109,7 +113,8 @@ min = 10 name = "storage_cache_max_entries" nickel_path = ["orchestrator", "storage", "cache", "max_entries"] prompt = "Max Cache Entries" -type = "number" +type = "custom" +custom_type = "Number" # Storage Compression Configuration [[elements]] @@ -139,7 +144,8 @@ min = 1 name = "storage_compression_level" nickel_path = ["orchestrator", "storage", "compression", "level"] prompt = "Compression Level" -type = "number" +type = "custom" +custom_type = "Number" # Storage Garbage Collection [[elements]] @@ -159,7 +165,8 @@ min = 3600 name = "storage_gc_retention" nickel_path = ["orchestrator", "storage", "gc", "retention_seconds"] prompt = "GC Retention (seconds)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "storage_gc_enabled == true" @@ -170,4 +177,5 @@ min = 300 name = "storage_gc_interval" nickel_path = ["orchestrator", "storage", "gc", "interval_seconds"] prompt = "GC Interval (seconds)" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/provisioning-daemon/actions.toml b/.typedialog/platform/forms/fragments/provisioning-daemon/actions.toml index 40902b8..b9bd288 100644 --- a/.typedialog/platform/forms/fragments/provisioning-daemon/actions.toml +++ b/.typedialog/platform/forms/fragments/provisioning-daemon/actions.toml @@ -1,4 +1,7 @@ -# Provisioning Daemon Actions Configuration Fragment +name = "actions" +description = "Provisioning Daemon Actions Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false diff --git a/.typedialog/platform/forms/fragments/provisioning-daemon/daemon.toml b/.typedialog/platform/forms/fragments/provisioning-daemon/daemon.toml index bacf0b3..a92023e 100644 --- a/.typedialog/platform/forms/fragments/provisioning-daemon/daemon.toml +++ b/.typedialog/platform/forms/fragments/provisioning-daemon/daemon.toml @@ -1,4 +1,7 @@ -# Provisioning Daemon Configuration Fragment +name = "daemon" +description = "Provisioning Daemon Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -23,7 +26,8 @@ min = 5 name = "daemon_poll_interval" nickel_path = ["provisioning_daemon", "daemon", "poll_interval"] prompt = "Poll Interval (seconds)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 4 @@ -33,4 +37,5 @@ min = 1 name = "daemon_max_workers" nickel_path = ["provisioning_daemon", "daemon", "max_workers"] prompt = "Max Workers" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/provisioning-daemon/health.toml b/.typedialog/platform/forms/fragments/provisioning-daemon/health.toml index ffe894b..94e2fe1 100644 --- a/.typedialog/platform/forms/fragments/provisioning-daemon/health.toml +++ b/.typedialog/platform/forms/fragments/provisioning-daemon/health.toml @@ -1,4 +1,7 @@ -# Provisioning Daemon Health Check Configuration Fragment +name = "health" +description = "Provisioning Daemon Health Check Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -15,7 +18,8 @@ min = 5000 name = "daemon_health_check_interval" nickel_path = ["provisioning_daemon", "health", "check_interval"] prompt = "Check Interval (ms)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 30000 @@ -25,7 +29,8 @@ min = 1000 name = "daemon_health_check_timeout" nickel_path = ["provisioning_daemon", "health", "timeout"] prompt = "Timeout (ms)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 3 @@ -35,4 +40,5 @@ min = 1 name = "daemon_health_failure_threshold" nickel_path = ["provisioning_daemon", "health", "failure_threshold"] prompt = "Failure Threshold" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/provisioning-daemon/logging.toml b/.typedialog/platform/forms/fragments/provisioning-daemon/logging.toml index 852b29e..486eae4 100644 --- a/.typedialog/platform/forms/fragments/provisioning-daemon/logging.toml +++ b/.typedialog/platform/forms/fragments/provisioning-daemon/logging.toml @@ -1,4 +1,7 @@ -# Provisioning Daemon Logging Configuration Fragment +name = "logging" +description = "Provisioning Daemon Logging Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false diff --git a/.typedialog/platform/forms/fragments/provisioning-daemon/workers.toml b/.typedialog/platform/forms/fragments/provisioning-daemon/workers.toml index 892c614..17284fc 100644 --- a/.typedialog/platform/forms/fragments/provisioning-daemon/workers.toml +++ b/.typedialog/platform/forms/fragments/provisioning-daemon/workers.toml @@ -1,4 +1,7 @@ -# Provisioning Daemon Worker Configuration Fragment +name = "workers" +description = "Provisioning Daemon Worker Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -15,7 +18,8 @@ min = 1 name = "daemon_worker_pool_size" nickel_path = ["provisioning_daemon", "workers", "pool_size"] prompt = "Pool Size" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 1000 @@ -25,7 +29,8 @@ min = 10 name = "daemon_worker_task_queue_size" nickel_path = ["provisioning_daemon", "workers", "task_queue_size"] prompt = "Queue Size" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 300000 @@ -35,4 +40,5 @@ min = 10000 name = "daemon_worker_timeout" nickel_path = ["provisioning_daemon", "workers", "timeout"] prompt = "Timeout (ms)" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/rag/embeddings.toml b/.typedialog/platform/forms/fragments/rag/embeddings.toml index 794a5f8..c292102 100644 --- a/.typedialog/platform/forms/fragments/rag/embeddings.toml +++ b/.typedialog/platform/forms/fragments/rag/embeddings.toml @@ -1,4 +1,7 @@ -# RAG Embeddings Configuration Fragment +name = "embeddings" +description = "RAG Embeddings Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -43,7 +46,8 @@ min = 1 name = "rag_embeddings_batch_size" nickel_path = ["rag", "embeddings", "batch_size"] prompt = "Batch Size" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] condition = "rag_embeddings_provider != 'local'" diff --git a/.typedialog/platform/forms/fragments/rag/ingestion.toml b/.typedialog/platform/forms/fragments/rag/ingestion.toml index a17732f..1389b90 100644 --- a/.typedialog/platform/forms/fragments/rag/ingestion.toml +++ b/.typedialog/platform/forms/fragments/rag/ingestion.toml @@ -1,4 +1,7 @@ -# RAG Document Ingestion Configuration Fragment +name = "ingestion" +description = "RAG Document Ingestion Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -31,7 +34,8 @@ min = 128 name = "rag_ingestion_chunk_size" nickel_path = ["rag", "ingestion", "chunk_size"] prompt = "Chunk Size" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 50 @@ -41,7 +45,8 @@ min = 0 name = "rag_ingestion_overlap" nickel_path = ["rag", "ingestion", "overlap"] prompt = "Chunk Overlap" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = "md, txt, toml" diff --git a/.typedialog/platform/forms/fragments/rag/llm.toml b/.typedialog/platform/forms/fragments/rag/llm.toml index ed31f32..0fef133 100644 --- a/.typedialog/platform/forms/fragments/rag/llm.toml +++ b/.typedialog/platform/forms/fragments/rag/llm.toml @@ -1,4 +1,7 @@ -# RAG Language Model Configuration Fragment +name = "llm" +description = "RAG Language Model Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -54,7 +57,8 @@ min = 0.0 name = "rag_llm_temperature" nickel_path = ["rag", "llm", "temperature"] prompt = "Temperature" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 2048 @@ -64,4 +68,5 @@ min = 1 name = "rag_llm_max_tokens" nickel_path = ["rag", "llm", "max_tokens"] prompt = "Max Tokens" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/rag/retrieval.toml b/.typedialog/platform/forms/fragments/rag/retrieval.toml index 9f1d4b2..5eb52d4 100644 --- a/.typedialog/platform/forms/fragments/rag/retrieval.toml +++ b/.typedialog/platform/forms/fragments/rag/retrieval.toml @@ -1,4 +1,7 @@ -# RAG Retrieval Configuration Fragment +name = "retrieval" +description = "RAG Retrieval Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -15,7 +18,8 @@ min = 1 name = "rag_retrieval_top_k" nickel_path = ["rag", "retrieval", "top_k"] prompt = "Top K Results" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 0.75 @@ -25,7 +29,8 @@ min = 0.0 name = "rag_retrieval_similarity_threshold" nickel_path = ["rag", "retrieval", "similarity_threshold"] prompt = "Similarity Threshold" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = false diff --git a/.typedialog/platform/forms/fragments/rag/vector-db.toml b/.typedialog/platform/forms/fragments/rag/vector-db.toml index bebe7cc..22587b1 100644 --- a/.typedialog/platform/forms/fragments/rag/vector-db.toml +++ b/.typedialog/platform/forms/fragments/rag/vector-db.toml @@ -1,4 +1,7 @@ -# RAG Vector Database Configuration Fragment +name = "vector_db" +description = "RAG Vector Database Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false diff --git a/.typedialog/platform/forms/fragments/server-section.toml b/.typedialog/platform/forms/fragments/server-section.toml index c0229e5..b587383 100644 --- a/.typedialog/platform/forms/fragments/server-section.toml +++ b/.typedialog/platform/forms/fragments/server-section.toml @@ -1,5 +1,7 @@ -# HTTP Server Configuration Fragment -# Used by all services: orchestrator, control-center, mcp-server +name = "server_section" +description = "HTTP Server Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -26,7 +28,8 @@ name = "server_port" nickel_path = ["server", "port"] prompt = "Server Port" required = true -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 4 @@ -36,7 +39,8 @@ min = "${constraint.common.server.workers.min}" name = "server_workers" nickel_path = ["server", "workers"] prompt = "Worker Threads" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 75 @@ -46,7 +50,8 @@ min = "${constraint.common.server.keep_alive.min}" name = "server_keep_alive" nickel_path = ["server", "keep_alive"] prompt = "Keep-Alive Timeout (seconds)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 100 @@ -56,7 +61,8 @@ min = "${constraint.common.server.max_connections.min}" name = "server_max_connections" nickel_path = ["server", "max_connections"] prompt = "Max Connections" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = 30000 @@ -65,7 +71,8 @@ min = 1000 name = "server_request_timeout" nickel_path = ["server", "request_timeout"] prompt = "Request Timeout (ms)" -type = "number" +type = "custom" +custom_type = "Number" [[elements]] default = true @@ -82,4 +89,5 @@ min = 1 name = "server_shutdown_timeout" nickel_path = ["server", "shutdown_timeout"] prompt = "Shutdown Timeout (seconds)" -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/vault-service/ha.toml b/.typedialog/platform/forms/fragments/vault-service/ha.toml index 2bde9a6..e32ac94 100644 --- a/.typedialog/platform/forms/fragments/vault-service/ha.toml +++ b/.typedialog/platform/forms/fragments/vault-service/ha.toml @@ -1,4 +1,7 @@ -# Vault Service High Availability Configuration Fragment +name = "ha" +description = "Vault Service High Availability Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false diff --git a/.typedialog/platform/forms/fragments/vault-service/mount.toml b/.typedialog/platform/forms/fragments/vault-service/mount.toml index 2bc0f9a..7ee7474 100644 --- a/.typedialog/platform/forms/fragments/vault-service/mount.toml +++ b/.typedialog/platform/forms/fragments/vault-service/mount.toml @@ -1,4 +1,7 @@ -# Vault Service Mount Point Configuration Fragment +name = "mount" +description = "Vault Service Mount Point Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false diff --git a/.typedialog/platform/forms/fragments/vault-service/server.toml b/.typedialog/platform/forms/fragments/vault-service/server.toml index 9e1431f..b2d879a 100644 --- a/.typedialog/platform/forms/fragments/vault-service/server.toml +++ b/.typedialog/platform/forms/fragments/vault-service/server.toml @@ -1,4 +1,7 @@ -# Vault Service Server Configuration Fragment +name = "server" +description = "Vault Service Server Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false @@ -25,4 +28,5 @@ name = "vault_server_port" nickel_path = ["vault_service", "server", "port"] prompt = "Server Port" required = true -type = "number" +type = "custom" +custom_type = "Number" diff --git a/.typedialog/platform/forms/fragments/vault-service/storage.toml b/.typedialog/platform/forms/fragments/vault-service/storage.toml index b0ee315..4e3ff1d 100644 --- a/.typedialog/platform/forms/fragments/vault-service/storage.toml +++ b/.typedialog/platform/forms/fragments/vault-service/storage.toml @@ -1,4 +1,7 @@ -# Vault Service Storage Configuration Fragment +name = "storage" +description = "Vault Service Storage Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false diff --git a/.typedialog/platform/forms/fragments/vault-service/tls.toml b/.typedialog/platform/forms/fragments/vault-service/tls.toml index e539075..7deb7cb 100644 --- a/.typedialog/platform/forms/fragments/vault-service/tls.toml +++ b/.typedialog/platform/forms/fragments/vault-service/tls.toml @@ -1,4 +1,7 @@ -# Vault Service TLS Configuration Fragment +name = "tls" +description = "Vault Service TLS Configuration Fragment" +display_mode = "complete" + [[elements]] border_bottom = false diff --git a/.typedialog/platform/forms/fragments/workspace-section.toml b/.typedialog/platform/forms/fragments/workspace-section.toml index 8252da4..ca1422d 100644 --- a/.typedialog/platform/forms/fragments/workspace-section.toml +++ b/.typedialog/platform/forms/fragments/workspace-section.toml @@ -1,5 +1,7 @@ -# Workspace Configuration Fragment -# Used by all services: orchestrator, control-center, mcp-server, installer +name = "workspace_section" +description = "Workspace Configuration Fragment" +display_mode = "complete" + [[elements]] help = "Name of the workspace this service will serve" diff --git a/.typedialog/platform/scripts/configure.nu b/.typedialog/platform/scripts/configure.nu index d1a2c94..cf8f4d2 100644 --- a/.typedialog/platform/scripts/configure.nu +++ b/.typedialog/platform/scripts/configure.nu @@ -53,10 +53,12 @@ export def main [ # Build TypeDialog command with nickel-roundtrip pattern let cmd_args: list = if $config_exists { # Load existing config, allow editing, save updated config with template - ["nickel-roundtrip", $config_path, $form_path, "--output", $config_path, "--template", $template_path] + # Args: nickel-roundtrip --output --ncl-template
+ ["nickel-roundtrip", "--output", $config_path, "--ncl-template", $template_path, $config_path, $form_path] } else { # Create new config from form with template - ["nickel-roundtrip", $form_path, "--output", $config_path, "--template", $template_path] + # Args: nickel-roundtrip --output --ncl-template + ["nickel-roundtrip", "--output", $config_path, "--ncl-template", $template_path, $form_path] } ansi print-working "Starting TypeDialog editor (backend: $backend)..." diff --git a/.typedialog/platform/scripts/paths.nu b/.typedialog/platform/scripts/paths.nu index dc95f9f..6e2973f 100644 --- a/.typedialog/platform/scripts/paths.nu +++ b/.typedialog/platform/scripts/paths.nu @@ -111,7 +111,7 @@ export def get-template-path [template_name: string]: nothing -> string { } export def get-output-config-path [service: string, mode: string]: nothing -> string { - (project-root) | path join "config" "runtime" "generated" $"($service).($mode).toml" + (project-root) | path join ".." "platform" "config" $"($service).($mode).toml" } export def validate-service [service: string]: nothing -> nothing { diff --git a/.typedialog/provisioning/configure.nu b/.typedialog/provisioning/configure.nu index d4295c1..4275015 100755 --- a/.typedialog/provisioning/configure.nu +++ b/.typedialog/provisioning/configure.nu @@ -61,7 +61,7 @@ def main [ # Determine project path let project_path = if ($project | is-empty) { $env.PWD } else { $project } - let tools_path = ($env.TOOLS_PATH? | default "/Users/Akasha/Tools") + let tools_path = ($env.TOOLS_PATH? | default ($env.HOME | path join "Tools")) let prov_dir = ($project_path | path join ".typedialog" "provisioning") # Verify provisioning is installed diff --git a/.woodpecker/ci.yml b/.woodpecker/ci.yml index be8aba9..b2a519d 100644 --- a/.woodpecker/ci.yml +++ b/.woodpecker/ci.yml @@ -1,84 +1,51 @@ -# Woodpecker CI Pipeline -# Equivalent to GitHub Actions CI workflow -# Generated by dev-system/ci +# Generated by ore workflow generate — layer: ci-standard +# Source: .ontology/workflow.ncl +# Do not edit manually — regenerate with: ore workflow generate --layer ci-standard when: event: [push, pull_request, manual] - branch: - - main - - develop steps: - # === LINTING === - - lint-rust: + rust-clippy-all: image: rust:latest commands: - - curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to /usr/local/bin - - rustup component add clippy - - cargo fmt --all -- --check - - cargo clippy --all-targets -- -D warnings + - cargo clippy --all-targets --all-features -- -D warnings - lint-bash: - image: koalaman/shellcheck-alpine:stable - commands: - - apk add --no-cache curl bash - - find . -name '*.sh' -type f ! -path './target/*' -exec shellcheck {} + - - lint-nickel: + nickel-typecheck: image: rust:latest commands: - cargo install nickel-lang-cli --locked - - find . -name '*.ncl' -type f ! -path './target/*' -exec nickel typecheck {} \; + - nickel typecheck - lint-nushell: + nushell-check: image: rust:latest commands: - cargo install nu --locked - - find . -name '*.nu' -type f ! -path './target/*' -exec nu --ide-check 100 {} \; + - find . -name '*.nu' ! -path '*/target/*' -print0 | xargs -0 -I\{\} nu --ide-check 100 \{\} - lint-markdown: - image: node:alpine - commands: - - npm install -g markdownlint-cli2 - - markdownlint-cli2 '**/*.md' '#node_modules' '#target' - - # === TESTING === - - test: + nextest-ci: image: rust:latest commands: - - cargo test --workspace --all-features - depends_on: - - lint-rust - - lint-bash - - lint-nickel - - lint-nushell - - lint-markdown + - cargo install cargo-nextest --locked + - cargo nextest run --all-features --workspace --profile ci --cargo-profile ci + depends_on: ["rust-clippy-all", "nickel-typecheck", "nushell-check"] + environment: + RUST_BACKTRACE: 1 - # === BUILD === - - build: - image: rust:latest - commands: - - cargo build --release - depends_on: - - test - - # === SECURITY === - - security-audit: - image: rust:latest - commands: - - cargo install cargo-audit --locked - - cargo audit --deny warnings - depends_on: - - lint-rust - - license-check: + deny-subset: image: rust:latest commands: - cargo install cargo-deny --locked - cargo deny check licenses advisories - depends_on: - - lint-rust + + docs-check: + image: rust:latest + commands: + - RUSTDOCFLAGS="-D rustdoc::broken-intra-doc-links -D rustdoc::private-intra-doc-links" cargo doc --no-deps --workspace --profile ci -q + depends_on: ["rust-clippy-all", "nickel-typecheck", "nushell-check"] + + build-release-native: + image: rust:latest + commands: + - cargo build --release --workspace + depends_on: ["rust-clippy-all", "nickel-typecheck", "nushell-check"] diff --git a/CHANGELOG.md b/CHANGELOG.md index d0d8e40..2b4107a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,10 +11,12 @@ **Constraints added/amended**: - `bash-wrapper-has-no-runner-reference` — now permits `provisioning-cli.nu` as transitional fallback -- `universal-fallback-is-transitional` — 22 unmapped commands are explicit migration debt; must be resolved before lazy-load architecture is considered complete +- `universal-fallback-is-transitional` — 22 unmapped commands are explicit migration debt; + must be resolved before lazy-load architecture is considered complete - `every-registry-command-has-thin-handler` — made directional (progress metric, not gate) -**Rejected approach**: Single-entry `provisioning-cli.nu` for hot paths — measured at 3.1s vs 0.08–0.15s for thin handlers. All 15 dispatcher wrappers fire at module-load regardless of invoked command. +**Rejected approach**: Single-entry `provisioning-cli.nu` for hot paths — measured at 3.1s vs 0.08–0.15s +for thin handlers. All 15 dispatcher wrappers fire at module-load regardless of invoked command. **Files**: `adrs/adr-025-unified-lazy-loading.ncl` @@ -88,7 +90,9 @@ ## 📋 Summary -Complete migration to Nickel-based infrastructure-as-code with consolidated configuration strategy. Legacy KCL schemas, deprecated config files, and redundant documentation removed. New project structure with `.cargo/`, `.github/`, and schema-driven configuration system. +Complete migration to Nickel-based infrastructure-as-code with consolidated configuration strategy. +Legacy KCL schemas, deprecated config files, and redundant documentation removed. +New project structure with `.cargo/`, `.github/`, and schema-driven configuration system. --- diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 084ffa9..670d007 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -2,7 +2,8 @@ ## Our Pledge -We, as members, contributors, and leaders, pledge to make participation in our project and community a harassment-free experience for everyone, regardless of: +We, as members, contributors, and leaders, pledge to make participation in our project and community +a harassment-free experience for everyone, regardless of: - Age - Body size @@ -44,7 +45,8 @@ Examples of unacceptable behavior include: ## Enforcement Responsibilities -Project maintainers are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate corrective action in response to unacceptable behavior. +Project maintainers are responsible for clarifying and enforcing our standards of acceptable behavior +and will take appropriate corrective action in response to unacceptable behavior. Maintainers have the right and responsibility to: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dc40771..92ec1e9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,8 @@ Thank you for your interest in contributing! This document provides guidelines a ## Code of Conduct -This project adheres to a Code of Conduct. By participating, you are expected to uphold this code. Please see [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) for details. +This project adheres to a Code of Conduct. By participating, you are expected to uphold this code. +Please see [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) for details. ## Getting Started @@ -121,7 +122,7 @@ Maintainers handle releases following semantic versioning: - MINOR: New features (backward compatible) - PATCH: Bug fixes -## Questions? +## Questions - Check existing documentation and issues - Ask in discussions or open an issue diff --git a/config/README.md b/config/README.md deleted file mode 100644 index d68ea87..0000000 --- a/config/README.md +++ /dev/null @@ -1,391 +0,0 @@ -# Platform Configuration Management - -This directory manages **runtime configurations** for provisioning platform services. - -## Structure - -```bash -provisioning/config/ -├── runtime/ # 🔒 PRIVATE (gitignored) -│ ├── .gitignore # Runtime files are private -│ ├── orchestrator.solo.ncl # Runtime config (editable) -│ ├── vault-service.multiuser.ncl # Runtime config (editable) -│ └── generated/ # 📄 Auto-generated TOMLs -│ ├── orchestrator.solo.toml # Exported from .ncl -│ └── vault-service.multiuser.toml -│ -├── examples/ # 📘 PUBLIC (reference) -│ ├── orchestrator.solo.example.ncl -│ └── orchestrator.enterprise.example.ncl -│ -├── README.md # This file -└── setup-platform-config.sh # ← See provisioning/scripts/setup-platform-config.sh -``` - -## Quick Start - -### 1. Setup Platform Configuration (First Time) - -```toml -# Interactive wizard (recommended) -./provisioning/scripts/setup-platform-config.sh - -# Or quick setup for all services in solo mode -./provisioning/scripts/setup-platform-config.sh --quick-mode --mode solo -``` - -### 2. Run Services - -```bash -# Service reads config from generated TOML -export ORCHESTRATOR_MODE=solo -cargo run -p orchestrator - -# Or with explicit config path -export ORCHESTRATOR_CONFIG=provisioning/config/runtime/generated/orchestrator.solo.toml -cargo run -p orchestrator -``` - -### 3. Update Configuration - -**Option A: Interactive (Recommended)** -```toml -# Update via TypeDialog UI -./provisioning/scripts/setup-platform-config.sh --service orchestrator --mode solo -``` - -**Option B: Manual Edit** -```bash -# Edit Nickel directly -vim provisioning/config/runtime/orchestrator.solo.ncl - -# ⚠️ CRITICAL: Regenerate TOML afterward -./provisioning/scripts/setup-platform-config.sh --generate-toml -``` - -## Configuration Layers - -```toml -📘 PUBLIC (provisioning/schemas/platform/) -├── schemas/ → Type contracts (Nickel) -├── defaults/ → Base configuration values -│ └── deployment/ → Mode-specific overlays (solo/multiuser/cicd/enterprise) -├── validators/ → Business logic validation -└── common/ - └── helpers.ncl → Merge functions - - ⬇️ COMPOSITION PROCESS ⬇️ - -🔒 PRIVATE (provisioning/config/runtime/) -├── orchestrator.solo.ncl ← User editable -│ (imports schemas + defaults + mode overlay) -│ (uses helpers.compose_config for merge) -│ -└── generated/ - └── orchestrator.solo.toml ← Auto-exported for Rust services - (generated by: nickel export --format toml) -``` - -## Key Concepts - -### Schema (Type Contract) -- **File**: `provisioning/schemas/platform/schemas/orchestrator.ncl` -- **Purpose**: Defines valid fields, types, constraints -- **Status**: 📘 PUBLIC, versioned, source of truth -- **Edit**: Rarely (architecture changes only) - -### Defaults (Base Values) -- **File**: `provisioning/schemas/platform/defaults/orchestrator-defaults.ncl` -- **Purpose**: Default values for all orchestrator settings -- **Status**: 📘 PUBLIC, versioned, part of product -- **Edit**: When changing default behavior - -### Mode Overlay (Tuning) -- **File**: `provisioning/schemas/platform/defaults/deployment/solo-defaults.ncl` -- **Purpose**: Mode-specific resource/behavior tuning -- **Status**: 📘 PUBLIC, versioned -- **Example**: solo mode uses 2 CPU, enterprise uses 16+ CPU - -### Runtime Config (User Customization) -- **File**: `provisioning/config/runtime/orchestrator.solo.ncl` -- **Purpose**: Actual deployment configuration (can be hand-edited) -- **Status**: 🔒 PRIVATE, gitignored -- **Edit**: Yes, use setup script or edit manually + regenerate TOML - -### Generated TOML (Service Consumption) -- **File**: `provisioning/config/runtime/generated/orchestrator.solo.toml` -- **Purpose**: What Rust services actually read -- **Status**: 🔒 PRIVATE, gitignored, auto-generated -- **Edit**: NO - regenerate from .ncl instead -- **Generation**: `nickel export --format toml ` - -## Workflows - -### Scenario 1: First-Time Setup - -```bash -# 1. Run setup script -./provisioning/scripts/setup-platform-config.sh - -# 2. Choose action (TypeDialog or Quick Mode) -# ↓ -# TypeDialog: User fills form → generates orchestrator.solo.ncl -# Quick Mode: Composes defaults + mode overlay → generates all 8 services - -# 3. Script auto-exports to TOML -# orchestrator.solo.ncl → orchestrator.solo.toml - -# 4. Service reads TOML -# cargo run -p orchestrator (reads generated/orchestrator.solo.toml) -``` - -### Scenario 2: Update Configuration - -```toml -# Option A: Interactive TypeDialog -./provisioning/scripts/setup-platform-config.sh - --service orchestrator - --mode solo - --backend web - -# Result: Updated orchestrator.solo.ncl + auto-exported TOML - -# Option B: Manual Edit -vim provisioning/config/runtime/orchestrator.solo.ncl - -# ⚠️ CRITICAL: Must regenerate TOML -./provisioning/scripts/setup-platform-config.sh --generate-toml - -# Result: Updated TOML in generated/ -``` - -### Scenario 3: Switch Deployment Mode - -```bash -# From solo to enterprise -./provisioning/scripts/setup-platform-config.sh --quick-mode --mode enterprise - -# Result: All 8 services configured for enterprise mode -# 16+ CPU, 32+ GB RAM, HA setup, KMS integration, etc. -``` - -### Scenario 4: Workspace-Specific Overrides - -```bash -workspace_librecloud/ -├── config/ -│ └── platform-overrides.ncl # Workspace customization -│ -# Example: -# { -# orchestrator.server.port = 9999, -# orchestrator.workspace.name = "librecloud", -# vault-service.storage.path = "./workspace_librecloud/data/vault" -# } -``` - -## Important Notes - -### ⚠️ Manual Edits Require TOML Regeneration - -If you edit `.ncl` files directly: - -```nickel -# 1. Edit the .ncl file -vim provisioning/config/runtime/orchestrator.solo.ncl - -# 2. ALWAYS regenerate TOML -./provisioning/scripts/setup-platform-config.sh --generate-toml - -# Service will NOT see your changes until TOML is regenerated -``` - -### 🔒 Private by Design - -Runtime configs are **gitignored** for good reasons: - -- **May contain secrets**: Encrypted credentials, API keys, tokens -- **Deployment-specific**: Different values per environment -- **User-customized**: Each developer/workspace has different needs -- **Not shared**: Don't commit locally-built configs - -### 📘 Schemas are Public - -Schema/defaults in `provisioning/schemas/` are **version-controlled**: - -- Product definition (part of releases) -- Shared across team -- Source of truth for config structure -- Can reference in documentation - -### 🔄 Idempotent Setup - -The setup script is safe to run multiple times: - -```bash -# Safe: Updates only what's needed -./provisioning/scripts/setup-platform-config.sh --quick-mode --mode enterprise - -# Safe: Doesn't overwrite unless --clean is used -./provisioning/scripts/setup-platform-config.sh --generate-toml - -# Use --clean to start fresh -./provisioning/scripts/setup-platform-config.sh --clean -``` - -## Service Configuration Paths - -Each service loads config using this priority: - -```toml -1. Environment variable: ORCHESTRATOR_CONFIG=/path/to/custom.toml -2. Mode-specific runtime: provisioning/config/runtime/generated/orchestrator.{MODE}.toml -3. Fallback defaults: provisioning/schemas/platform/defaults/orchestrator-defaults.ncl -``` - -## Configuration Composition (Technical) - -The setup script uses Nickel's `helpers.compose_config` function: - -```nickel -# Generated .ncl file imports: -let helpers = import "provisioning/schemas/platform/common/helpers.ncl" -let defaults = import "provisioning/schemas/platform/defaults/orchestrator-defaults.ncl" -let mode_config = import "provisioning/schemas/platform/defaults/deployment/solo-defaults.ncl" - -# Compose: base + mode overlay -helpers.compose_config defaults mode_config {} -# ^base ^mode overlay ^user overrides (empty if not customized) -``` - -This ensures: -- Type safety (validated by Nickel schema) -- Proper layering (base + mode + user) -- Reproducibility (same compose always produces same result) -- Extensibility (can add user layer via Nickel import) - -## Troubleshooting - -### Config Won't Generate TOML - -```toml -# Check Nickel syntax -nickel typecheck provisioning/config/runtime/orchestrator.solo.ncl - -# Check for schema import errors -nickel export --format json provisioning/config/runtime/orchestrator.solo.ncl - -# View detailed error message -nickel typecheck -i provisioning/config/runtime/orchestrator.solo.ncl 2>&1 | less -``` - -### Service Won't Start - -```bash -# Verify TOML exists -ls -la provisioning/config/runtime/generated/orchestrator.solo.toml - -# Verify TOML syntax -toml-cli validate provisioning/config/runtime/generated/orchestrator.solo.toml - -# Check service config loading -RUST_LOG=debug cargo run -p orchestrator 2>&1 | head -50 -``` - -### Wrong Configuration Being Used - -```toml -# Verify environment mode -echo $ORCHESTRATOR_MODE # Should be: solo, multiuser, cicd, or enterprise - -# Check which file service is reading -ORCHESTRATOR_CONFIG=provisioning/config/runtime/generated/orchestrator.solo.toml - cargo run -p orchestrator - -# Verify file modification time -ls -lah provisioning/config/runtime/generated/orchestrator.*.toml -``` - -## Integration Points - -### ⚠️ Provisioning Installer Status - -**Current Status**: Installer NOT YET IMPLEMENTED - -The `setup-platform-config.sh` script is a **standalone tool** that: -- ✅ Works independently from the provisioning installer -- ✅ Can be called manually for configuration setup -- ⏳ Will be integrated into the installer once it's implemented - -**For Now**: Use script manually before running services: - -```bash -# Manual setup (until installer is implemented) -cd /path/to/project-provisioning -./provisioning/scripts/setup-platform-config.sh --quick-mode --mode solo - -# Then run services -export ORCHESTRATOR_MODE=solo -cargo run -p orchestrator -``` - -### Future: Integration into Provisioning Installer - -Once `provisioning/scripts/install.sh` is implemented, it will automatically call this script: - -```bash -#!/bin/bash -# provisioning/scripts/install.sh (FUTURE - NOT YET IMPLEMENTED) - -# Pre-flight checks (verification of dependencies, paths, permissions) -check_dependencies() { - command -v nickel >/dev/null || { echo "Nickel required"; exit 1; } - command -v nu >/dev/null || { echo "Nushell required"; exit 1; } -} -check_dependencies - -# Install core provisioning system -echo "Installing provisioning system..." -# (install implementation details here) - -# Setup platform configurations -echo "Setting up platform configurations..." -./provisioning/scripts/setup-platform-config.sh --quick-mode --mode solo - -# Build and test platform services -echo "Building platform services..." -cargo build -p orchestrator -p control-center -p mcp-server - -# Verify services are operational -echo "Verification complete - services ready to run" -``` - -### CI/CD Pipeline Integration - -For automated CI/CD setups (can use now): - -```bash -#!/bin/bash -# ci/setup.sh - -# Setup configurations for CI/CD mode -cd /path/to/project-provisioning -./provisioning/scripts/setup-platform-config.sh - --quick-mode - --mode cicd - -# Result: All services configured for CI/CD mode -# (ephemeral, API-driven, fast cleanup, minimal resource footprint) - -# Run tests -cargo test --all - -# Deploy (CI/CD specific) -docker-compose -f provisioning/platform/infrastructure/docker/docker-compose.cicd.yml up -``` - ---- - -**Version**: 1.0.0 -**Last Updated**: 2026-01-05 -**Script Reference**: `provisioning/scripts/setup-platform-config.sh` diff --git a/config/ai.toml b/config/ai.toml deleted file mode 100644 index 015f3cc..0000000 --- a/config/ai.toml +++ /dev/null @@ -1,538 +0,0 @@ -# AI Integration Configuration for Provisioning Platform -# This file configures the AI system including LLM providers, RAG, MCP, and security policies. - -# ============================================================================ -# Core AI Configuration -# ============================================================================ - -[ai] -# Enable/disable AI features globally -enabled = true - -# LLM Provider Selection -# Options: "anthropic" | "openai" | "local" | "azure-openai" -provider = "anthropic" - -# Model Selection -# Anthropic: "claude-sonnet-4", "claude-opus-4", "claude-haiku-4" -# OpenAI: "gpt-4-turbo", "gpt-4", "gpt-3.5-turbo" -# Local: "llama-3-70b", "mistral-large", "codellama-34b" -model = "claude-sonnet-4" - -# Model Temperature (0.0-1.0) -# Lower = more deterministic, Higher = more creative -temperature = 0.7 - -# Maximum tokens for responses -max_tokens = 4096 - -# Request timeout (seconds) -timeout = 60 - -# ============================================================================ -# AI Features - Fine-Grained Control -# ============================================================================ - - [ai.features] - # AI-assisted form filling (typdialog-ai) - # Real-time suggestions and field value predictions - form_assistance = true - - # Natural language configuration generation (typdialog-prov-gen) - # Convert plain English to Nickel configs - config_generation = true - - # Autonomous AI agents (typdialog-ag) - # WARNING: Agents can execute multi-step workflows - # Recommended: false for production (enable per-use-case) - autonomous_agents = false - - # AI-powered troubleshooting - # Analyze logs and suggest fixes for failed deployments - troubleshooting = true - - # Configuration optimization - # AI reviews configs and suggests improvements - optimization = true - - # Validation error explanations - # AI explains Nickel validation errors in plain language - error_explanations = true - - # ============================================================================ - # LLM Provider Configuration - # ============================================================================ - - [ai.anthropic] - # Anthropic Claude API configuration - api_key = "env:ANTHROPIC_API_KEY" # Load from environment variable - api_url = "https://api.anthropic.com/v1" - max_retries = 3 - retry_delay_ms = 1000 - - # Rate limits (per minute) - max_requests_per_minute = 50 - max_tokens_per_minute = 100000 - - [ai.openai] - # OpenAI GPT-4 API configuration - api_key = "env:OPENAI_API_KEY" - api_url = "https://api.openai.com/v1" - max_retries = 3 - organization_id = "" # Optional - retry_delay_ms = 1000 - - # Rate limits (per minute) - max_requests_per_minute = 60 - max_tokens_per_minute = 150000 - - [ai.local] - # Local LLM configuration (Ollama, LlamaCpp, vLLM) - # Use for air-gapped deployments or privacy-critical scenarios - context_length = 8192 - model_path = "/opt/provisioning/models/llama-3-70b" - num_gpu_layers = 40 # GPU acceleration - server_url = "http://localhost:11434" # Ollama default - - # ============================================================================ - # Model Context Protocol (MCP) Server - # ============================================================================ - - [ai.mcp] - # MCP server configuration - enabled = true - max_retries = 3 - server_url = "http://localhost:9000" - timeout = 30 - - # Tool calling configuration - [ai.mcp.tools] - enabled = true - - # Available tools for LLM - # Tools provide structured actions the LLM can invoke - tools = [ - "nickel_validate", # Validate Nickel configuration - "schema_query", # Query Nickel schema information - "config_generate", # Generate configuration snippets - "cedar_check", # Check Cedar authorization policies - "deployment_status", # Query deployment status - "log_analyze", # Analyze deployment logs - ] - - # ============================================================================ - # Retrieval-Augmented Generation (RAG) - # ============================================================================ - - [ai.rag] - # Enable RAG system - enabled = true - - # Vector Store Configuration - # Options: "qdrant" | "milvus" | "pgvector" | "chromadb" - collection_name = "provisioning-knowledge" - vector_store = "qdrant" - vector_store_url = "http://localhost:6333" - - # Embedding Model - # OpenAI: "text-embedding-3-large", "text-embedding-3-small" - # Local: "all-MiniLM-L6-v2", "bge-large-en-v1.5" - embedding_api_key = "env:OPENAI_API_KEY" # For OpenAI embeddings - embedding_model = "text-embedding-3-large" - - # Document Chunking - chunk_overlap = 50 # Overlap between chunks - chunk_size = 512 # Characters per chunk - max_chunks_per_query = 10 # Top-k retrieval - - # ============================================================================ - # RAG Index Configuration - # ============================================================================ - - [ai.rag.index] - # What to index for RAG retrieval - - # Index Nickel schemas (RECOMMENDED: true) - # Provides AI with schema definitions and contracts - schemas = true - schemas_path = "provisioning/schemas" - - # Index documentation (RECOMMENDED: true) - # Provides AI with user guides and best practices - docs = true - docs_path = "docs" - - # Index past deployments (RECOMMENDED: true) - # AI learns from successful deployment patterns - deployments = true - deployments_path = "workspaces" - - # Index best practices (RECOMMENDED: true) - # Inject organizational patterns and conventions - best_practices = true - best_practices_path = ".claude/patterns" - - # Index deployment logs (WARNING: Privacy concerns) - # Logs may contain sensitive data, enable only if sanitized - logs = false - logs_retention_days = 30 - - # Reindexing schedule - auto_reindex = true - reindex_interval_hours = 24 - - # ============================================================================ - # Security and Access Control - # ============================================================================ - - [ai.security] - # Cedar policy store for AI access control - cedar_policy_store = "/etc/provisioning/cedar-policies/ai" - - # AI cannot suggest secret values (CRITICAL: keep true) - # AI can suggest secret names/paths but not retrieve actual secrets - max_secret_suggestions = 0 - - # Require human approval for critical operations (CRITICAL: keep true) - # Operations requiring approval: - # - Deployments to production - # - Configuration changes affecting security - # - Secret rotation - # - Infrastructure deletion - require_human_approval = true - - # Audit all AI operations (CRITICAL: keep true) - # Log every AI request, response, and action - audit_all_operations = true - - # Data sanitization before sending to LLM - # Remove sensitive data from prompts - [ai.security.sanitization] - sanitize_credentials = true # Remove passwords, API keys - sanitize_ip_addresses = false # Keep for troubleshooting - sanitize_pii = true # Remove personally identifiable info - sanitize_secrets = true # Remove secret values - - # Allowed data for LLM - allowed_data = [ - "nickel_schemas", # Schema definitions (public) - "documentation", # User docs (public) - "error_messages", # Validation errors (sanitized) - "resource_names", # Infrastructure resource identifiers - ] - - # Forbidden data for LLM (NEVER send to external LLM) - forbidden_data = [ - "secret_values", # Passwords, API keys, tokens - "private_keys", # SSH keys, TLS keys, encryption keys - "pii", # Email addresses, names, phone numbers - "credentials", # Authentication credentials - "session_tokens", # User session data - ] - - # ============================================================================ - # Rate Limiting and Cost Control - # ============================================================================ - - [ai.rate_limiting] - # Per-user rate limits - requests_per_day = 2000 - requests_per_hour = 500 - requests_per_minute = 60 - - # Token limits (to control LLM API costs) - tokens_per_day = 1000000 # 1M tokens/day - tokens_per_month = 30000000 # 30M tokens/month - - # Cost limits (USD) - cost_limit_per_day = "100.00" - cost_limit_per_month = "2000.00" - - # Alert thresholds - cost_alert_threshold = 0.8 # Alert at 80% of limit - - # Rate limit exceeded behavior - # Options: "queue" | "reject" | "throttle" - exceed_behavior = "queue" - max_queue_size = 100 - - # ============================================================================ - # Caching - # ============================================================================ - - [ai.caching] - # Enable response caching to reduce LLM API calls - enabled = true - - # Cache TTL (time-to-live) - ttl = "1h" - - # Cache backend - # Options: "redis" | "memcached" | "in-memory" - backend = "redis" - redis_url = "redis://localhost:6379" - - # Cache key strategy - # "prompt" = Cache by exact prompt (high precision, low hit rate) - # "semantic" = Cache by semantic similarity (lower precision, high hit rate) - cache_strategy = "semantic" - semantic_similarity_threshold = 0.95 - - # Cache statistics - log_cache_misses = false - track_hit_rate = true - - # ============================================================================ - # Observability and Monitoring - # ============================================================================ - - [ai.observability] - # Logging level for AI operations - # Options: "trace" | "debug" | "info" | "warn" | "error" - log_level = "info" - - # Trace all AI requests (detailed logging) - # WARNING: Generates large log volume - trace_all_requests = true - - # Store conversation history (for debugging and learning) - conversation_retention_days = 30 - store_conversations = true - - # Metrics collection - [ai.observability.metrics] - enabled = true - export_format = "prometheus" # "prometheus" | "opentelemetry" - export_port = 9090 - - # Metrics to collect - metrics = [ - "request_count", # Total AI requests - "request_duration", # Latency histogram - "token_usage", # Input/output tokens - "cost_tracking", # USD cost per request - "cache_hit_rate", # Cache effectiveness - "validation_success_rate", # Generated config validity - "human_approval_rate", # How often humans approve AI output - ] - - # Distributed tracing - [ai.observability.tracing] - enabled = true - jaeger_endpoint = "http://localhost:14268/api/traces" - sample_rate = 0.1 # Sample 10% of requests - - # ============================================================================ - # AI Agent Configuration (typdialog-ag) - # ============================================================================ - - [ai.agents] - # WARNING: Autonomous agents can execute multi-step workflows - # Enable with caution, only for trusted users - - # Enable AI agents globally - enabled = false - - # Maximum iterations per agent execution - # Prevents infinite loops - max_iterations = 20 - - # Agent timeout (seconds) - timeout = 300 - - # Require approval for each agent action (RECOMMENDED: true) - # If false, agent executes entire workflow autonomously - require_step_approval = true - - # Agent types - [ai.agents.types] - # Provisioning agent: End-to-end infrastructure setup - provisioning_agent = false - - # Troubleshooting agent: Diagnose and fix deployment issues - troubleshooting_agent = true - - # Optimization agent: Analyze and improve configurations - optimization_agent = true - - # Security audit agent: Review configs for vulnerabilities - security_audit_agent = true - - # ============================================================================ - # Configuration Generation (typdialog-prov-gen) - # ============================================================================ - - [ai.config_generation] - # Default schema for generated configs - default_schema = "workspace" - - # Validation mode - # "strict" = Reject any invalid config - # "permissive" = Allow configs with warnings - validation_mode = "strict" - - # Best practice injection - # Automatically add security/performance best practices - inject_best_practices = true - - # Template usage - # Use pre-defined templates as starting points - template_directory = "provisioning/templates" - use_templates = true - - # ============================================================================ - # Form Assistance (typdialog-ai) - # ============================================================================ - - [ai.form_assistance] - # Real-time suggestions as user types - real_time_suggestions = true - - # Minimum characters before triggering suggestions - min_chars_for_suggestions = 3 - - # Maximum suggestions per field - max_suggestions = 5 - - # Suggestion confidence threshold (0.0-1.0) - # Only show suggestions with confidence above threshold - confidence_threshold = 0.7 - - # Natural language form filling - # User can describe entire form in plain English - nl_form_filling = true - - # ============================================================================ - # Environment-Specific Overrides - # ============================================================================ - - # Development environment - [ai.environments.dev] - cost_limit_per_day = "10.00" - enabled = true - model = "gpt-4-turbo" - provider = "openai" # Cheaper for dev - require_human_approval = false # Faster iteration - - # Staging environment - [ai.environments.staging] - cost_limit_per_day = "50.00" - enabled = true - model = "claude-sonnet-4" - provider = "anthropic" - require_human_approval = true - - # Production environment - [ai.environments.production] - autonomous_agents = false # NEVER enable in production - cost_limit_per_day = "100.00" - enabled = true - model = "claude-sonnet-4" - provider = "anthropic" - require_human_approval = true # ALWAYS true for production - - # ============================================================================ - # Integration with Other Services - # ============================================================================ - - [ai.integration] - # Orchestrator integration - orchestrator_api_key = "env:ORCHESTRATOR_API_KEY" - orchestrator_url = "https://orchestrator.example.com" - - # SecretumVault integration (for secret name suggestions only) - secretum_vault_token = "env:VAULT_TOKEN" - secretum_vault_url = "https://vault.example.com:8200" - # AI can query secret names/paths but NEVER values - - # Typdialog Web UI integration - typdialog_url = "https://forms.provisioning.example.com" - typdialog_websocket_enabled = true - - # ============================================================================ - # Advanced Settings - # ============================================================================ - - [ai.advanced] - # Prompt engineering - system_prompt_template = "provisioning/ai/prompts/system.txt" - user_prompt_template = "provisioning/ai/prompts/user.txt" - - # Context window management - context_truncation_strategy = "sliding_window" # "sliding_window" | "summarize" - max_context_tokens = 100000 # Claude Sonnet 4 context window - - # Streaming responses - enable_streaming = true - stream_chunk_size = 100 # Characters per chunk - - # Concurrent requests - max_concurrent_requests = 10 - - # ============================================================================ - # Experimental Features (Use at Your Own Risk) - # ============================================================================ - - [ai.experimental] - # Multi-agent collaboration - # Multiple AI agents work together on complex tasks - multi_agent_collaboration = false - - # Reinforcement learning from human feedback (RLHF) - # Learn from user corrections to improve over time - rlhf_enabled = false - - # Fine-tuning on deployment history - # Train custom models on organization-specific patterns - fine_tuning = false - fine_tuning_dataset_path = "provisioning/ai/fine-tuning-data" - - # ============================================================================ - # Compliance and Legal - # ============================================================================ - - [ai.compliance] - # Data residency requirements - # Ensure LLM provider complies with data residency laws - data_residency = "us" # "us" | "eu" | "local" - - # GDPR compliance mode - gdpr_data_retention_days = 90 - gdpr_mode = false - - # SOC 2 compliance logging - soc2_logging = false - - # Terms of service acceptance - # Must explicitly accept LLM provider TOS - tos_accepted = false - tos_version = "2025-01-08" - - # IMPORTANT NOTES: - # - # 1. API Keys: NEVER hardcode API keys. Always use environment variables. - # Example: api_key = "env:ANTHROPIC_API_KEY" - # - # 2. Security: Keep require_human_approval = true for production. - # AI-generated configs must be reviewed by humans. - # - # 3. Costs: Monitor LLM API usage. Set appropriate cost_limit_per_day. - # Default limits are conservative but may need adjustment. - # - # 4. Privacy: For sensitive workloads, use local models (no external API calls). - # Set provider = "local" and configure local model path. - # - # 5. RAG Index: Regularly reindex to keep AI knowledge up-to-date. - # Set auto_reindex = true and adjust reindex_interval_hours. - # - # 6. Cedar Policies: Define fine-grained AI access control in Cedar. - # Location: /etc/provisioning/cedar-policies/ai - # - # 7. Audit Logs: AI operations are security-critical. Keep audit_all_operations = true. - # Logs stored in: /var/log/provisioning/ai-audit.log - # - # 8. Agents: Autonomous agents are powerful but risky. - # Enable only for specific use cases, never globally in production. - - # Version: 1.0 - # Last Updated: 2025-01-08 diff --git a/config/config.defaults.toml b/config/config.defaults.toml deleted file mode 100644 index d9b03cd..0000000 --- a/config/config.defaults.toml +++ /dev/null @@ -1,116 +0,0 @@ -# Provisioning Platform Default Configuration -# This file defines defaults for all provisioning system configuration - -# Documentation Configuration -[documentation] -# mdBook base URL for hosted documentation -# Set to empty string ("") to use local files only (default) -# Set to a URL when mdBook is hosted (e.g., "https://docs.provisioning.local") -mdbook_base_url = "" - -# Enable mdBook URL resolution -# When true and mdbook_base_url is set, CLI will show documentation URLs -# When false or mdbook_base_url empty, uses local files only -mdbook_enabled = false - -# Local documentation paths (relative to provisioning root) -docs_root = "docs/src" -guides_path = "docs/src/guides" -api_reference_path = "docs/src/api-reference" -architecture_path = "docs/src/architecture" - -# Help System Configuration -[help] -# Help system language/locale -# Options: "en-US", "es-ES", or other supported locales -# Falls back to English if locale not available -locale = "en-US" - -# Use internationalized help (Fluent-based) -# When true: Uses help_system_fluent.nu with translations -# When false: Uses help_system.nu with English-only help -use_fluent = false - -# Logging Configuration -[logging] -# Minimum log level: "off", "error", "warn", "info", "debug", "trace" -level = "info" - -# Log output format: "text" or "json" -format = "text" - -# Cache Configuration -[cache] -# Enable caching of parsed configurations -enabled = true - -# Cache directory (relative to provisioning root) -dir = ".cache/provisioning" - -# Cache TTL in seconds (0 = no expiration) -ttl = 3600 - -# Performance Configuration -[performance] -# Maximum parallel operations -max_parallel = 4 - -# Operation timeout in seconds -timeout = 300 - -# Network Configuration -[network] -# HTTP/REST service port -http_port = 8080 - -# MCP server port -mcp_port = 8081 - -# Orchestrator service port -orchestrator_port = 5000 - -# Security Configuration -[security] -# Enable strict mode (enforces all security checks) -strict_mode = false - -# TLS/SSL for service communication -enable_tls = false - -# Certificate paths (required if enable_tls = true) -cert_path = "" -key_path = "" - -# Environment-Specific Configuration -# ⚠️ DEPRECATED: Environments are now defined in Nickel (ADR-003: Nickel as Source of Truth) -# Location: provisioning/schemas/config/environments/main.ncl -# The loader attempts to load from Nickel first, then falls back to this TOML section -# This section is kept for backward compatibility only - DO NOT USE for new configurations -# -# [environments] -# [environments.dev] -# debug_enabled = true -# debug_log_level = "debug" -# [environments.prod] -# debug_enabled = false -# debug_log_level = "warn" - -# Configuration Notes -# -# 1. User Configuration Override -# Users can override these defaults by creating: -# ~/.config/provisioning/user_config.toml -# -# 2. Environment Variables -# Can override any setting with: PROVISIONING_
_ -# Example: PROVISIONING_DOCUMENTATION_MDBOOK_BASE_URL="https://docs.example.com" -# -# 3. Workspace Configuration -# Workspace-specific config in: workspace/config/provisioning-config.toml -# -# 4. Loading Hierarchy -# 1. CLI arguments (highest priority) -# 2. Environment variables -# 3. User config (~/.config/provisioning/user_config.toml) -# 4. Workspace config (workspace/config/provisioning-config.toml) -# 5. This file (lowest priority) diff --git a/config/examples/README.md b/config/examples/README.md deleted file mode 100644 index bbb1de5..0000000 --- a/config/examples/README.md +++ /dev/null @@ -1,494 +0,0 @@ -# Example Platform Service Configurations - -This directory contains reference configurations for platform services in different deployment modes. These examples show realistic settings and best practices for each mode. - -## What Are These Examples? - -These are **Nickel configuration files** (.ncl format) that demonstrate how to configure the provisioning platform services. They show: - -- Recommended settings for each deployment mode -- How to customize services for your environment -- Best practices for development, staging, and production -- Performance tuning for different scenarios -- Security settings appropriate to each mode - -## Directory Structure - -```bash -provisioning/config/examples/ -├── README.md # This file -├── orchestrator.solo.example.ncl # Development mode reference -├── orchestrator.multiuser.example.ncl # Team staging reference -└── orchestrator.enterprise.example.ncl # Production reference -``` - -## Deployment Modes - -### Solo Mode (Development) - -**File**: `orchestrator.solo.example.ncl` - -**Characteristics**: -- 2 CPU, 4GB RAM (lightweight) -- Single user/developer -- Local development machine -- Minimal resource consumption -- No TLS or authentication -- In-memory storage - -**When to use**: -- Local development -- Testing configurations -- Learning the platform -- CI/CD test environments - -**Key Settings**: -- workers: 2 -- max_concurrent_tasks: 2 -- max_memory: 1GB -- tls: disabled -- auth: disabled - -### Multiuser Mode (Team Staging) - -**File**: `orchestrator.multiuser.example.ncl` - -**Characteristics**: -- 4 CPU, 8GB RAM (moderate) -- Multiple concurrent users -- Team staging environment -- Production-like testing -- Basic TLS and token auth -- Filesystem storage with caching - -**When to use**: -- Team development -- Integration testing -- Staging environment -- Pre-production validation -- Multi-user environments - -**Key Settings**: -- workers: 4 -- max_concurrent_tasks: 10 -- max_memory: 4GB -- tls: enabled (certificates required) -- auth: token-based -- storage: filesystem with replication - -### Enterprise Mode (Production) - -**File**: `orchestrator.enterprise.example.ncl` - -**Characteristics**: -- 16+ CPU, 32+ GB RAM (high-performance) -- Multi-team, multi-workspace -- Production mission-critical -- Full redundancy and HA -- OAuth2/Enterprise auth -- Distributed storage with replication -- Full monitoring, tracing, audit - -**When to use**: -- Production deployment -- Mission-critical systems -- High-availability requirements -- Multi-tenant environments -- Compliance requirements (SOC2, ISO27001) - -**Key Settings**: -- workers: 16 -- max_concurrent_tasks: 100 -- max_memory: 32GB -- tls: mandatory (TLS 1.3) -- auth: OAuth2 (enterprise provider) -- storage: distributed with 3-way replication -- monitoring: comprehensive with tracing -- disaster_recovery: enabled -- compliance: SOC2, ISO27001 - -## How to Use These Examples - -### Step 1: Copy the Appropriate Example - -Choose the example that matches your deployment mode: - -```bash -# For development (solo) -cp provisioning/config/examples/orchestrator.solo.example.ncl - provisioning/config/runtime/orchestrator.solo.ncl - -# For team staging (multiuser) -cp provisioning/config/examples/orchestrator.multiuser.example.ncl - provisioning/config/runtime/orchestrator.multiuser.ncl - -# For production (enterprise) -cp provisioning/config/examples/orchestrator.enterprise.example.ncl - provisioning/config/runtime/orchestrator.enterprise.ncl -``` - -### Step 2: Customize for Your Environment - -Edit the copied file to match your specific setup: - -```bash -# Edit the configuration -vim provisioning/config/runtime/orchestrator.solo.ncl - -# Examples of customizations: -# - Change workspace path to your project -# - Adjust worker count based on CPU cores -# - Set your domain names and hostnames -# - Configure storage paths for your filesystem -# - Update certificate paths for production -# - Set logging endpoints for your infrastructure -``` - -### Step 3: Validate Configuration - -Verify the configuration is syntactically correct: - -```toml -# Check Nickel syntax -nickel typecheck provisioning/config/runtime/orchestrator.solo.ncl - -# View generated TOML -nickel export --format toml provisioning/config/runtime/orchestrator.solo.ncl -``` - -### Step 4: Generate TOML - -Export the Nickel configuration to TOML format for service consumption: - -```nickel -# Use setup script to generate TOML -./provisioning/scripts/setup-platform-config.sh --generate-toml - -# Or manually export -nickel export --format toml provisioning/config/runtime/orchestrator.solo.ncl > - provisioning/config/runtime/generated/orchestrator.solo.toml -``` - -### Step 5: Run Services - -Start your platform services with the generated configuration: - -```toml -# Set the deployment mode -export ORCHESTRATOR_MODE=solo - -# Run the orchestrator -cargo run -p orchestrator -``` - -## Configuration Reference - -### Solo Mode Example Settings - -```toml -server.workers = 2 -queue.max_concurrent_tasks = 2 -performance.max_memory = 1000 # 1GB max -security.tls.enabled = false # No TLS for local dev -security.auth.enabled = false # No auth for local dev -``` - -**Use case**: Single developer on local machine - -### Multiuser Mode Example Settings - -```toml -server.workers = 4 -queue.max_concurrent_tasks = 10 -performance.max_memory = 4000 # 4GB max -security.tls.enabled = true # Enable TLS -security.auth.type = "token" # Token-based auth -``` - -**Use case**: Team of 5-10 developers in staging - -### Enterprise Mode Example Settings - -```toml -server.workers = 16 -queue.max_concurrent_tasks = 100 -performance.max_memory = 32000 # 32GB max -security.tls.enabled = true # TLS 1.3 only -security.auth.type = "oauth2" # OAuth2 for enterprise -storage.replication.factor = 3 # 3-way replication -``` - -**Use case**: Production with 100+ users across multiple teams - -## Key Configuration Sections - -### Server Configuration - -Controls HTTP server behavior: - -```bash -server = { - host = "0.0.0.0", # Bind address - port = 9090, # Listen port - workers = 4, # Worker threads - max_connections = 200, # Concurrent connections - request_timeout = 30000, # Milliseconds -} -``` - -### Storage Configuration - -Controls data persistence: - -```bash -storage = { - backend = "filesystem", # filesystem or distributed - path = "/var/lib/provisioning/orchestrator/data", - cache.enabled = true, - replication.enabled = true, - replication.factor = 3, # 3-way replication for HA -} -``` - -### Queue Configuration - -Controls task queuing: - -```bash -queue = { - max_concurrent_tasks = 10, - retry_attempts = 3, - task_timeout = 3600000, # 1 hour in milliseconds - priority_queue = true, # Enable priority for tasks - metrics = true, # Enable queue metrics -} -``` - -### Security Configuration - -Controls authentication and encryption: - -```bash -security = { - tls = { - enabled = true, - cert_path = "/etc/provisioning/certs/cert.crt", - key_path = "/etc/provisioning/certs/key.key", - min_tls_version = "1.3", - }, - auth = { - enabled = true, - type = "oauth2", # oauth2, token, or none - provider = "okta", - }, - encryption = { - enabled = true, - algorithm = "aes-256-gcm", - }, -} -``` - -### Logging Configuration - -Controls log output and persistence: - -```bash -logging = { - level = "info", # debug, info, warning, error - format = "json", - output = "both", # stdout, file, or both - file = { - enabled = true, - path = "/var/log/orchestrator.log", - rotation.max_size = 104857600, # 100MB per file - }, -} -``` - -### Monitoring Configuration - -Controls observability and metrics: - -```bash -monitoring = { - enabled = true, - metrics.enabled = true, - health_check.enabled = true, - distributed_tracing.enabled = true, - audit_logging.enabled = true, -} -``` - -## Customization Examples - -### Example 1: Change Workspace Name - -Change the workspace identifier in solo mode: - -```bash -workspace = { - name = "myproject", - path = "./provisioning/data/orchestrator", -} -``` - -Instead of default "development", use "myproject". - -### Example 2: Custom Server Port - -Change server port from default 9090: - -```bash -server = { - port = 8888, -} -``` - -Useful if port 9090 is already in use. - -### Example 3: Enable TLS in Solo Mode - -Add TLS certificates to solo development: - -```bash -security = { - tls = { - enabled = true, - cert_path = "./certs/localhost.crt", - key_path = "./certs/localhost.key", - }, -} -``` - -Useful for testing TLS locally before production. - -### Example 4: Custom Storage Path - -Use custom storage location: - -```bash -storage = { - path = "/mnt/fast-storage/orchestrator/data", -} -``` - -Useful if you have fast SSD storage available. - -### Example 5: Increase Workers for Staging - -Increase from 4 to 8 workers in multiuser: - -```bash -server = { - workers = 8, -} -``` - -Useful when you have more CPU cores available. - -## Troubleshooting Configuration - -### Issue: "Configuration Won't Validate" - -```toml -# Check for Nickel syntax errors -nickel typecheck provisioning/config/runtime/orchestrator.solo.ncl - -# Get detailed error message -nickel typecheck -i provisioning/config/runtime/orchestrator.solo.ncl -``` - -The typecheck command will show exactly where the syntax error is. - -### Issue: "Service Won't Start" - -```bash -# Verify TOML was exported correctly -cat provisioning/config/runtime/generated/orchestrator.solo.toml | head -20 - -# Check TOML syntax is valid -toml-cli validate provisioning/config/runtime/generated/orchestrator.solo.toml -``` - -The TOML must be valid for the Rust service to parse it. - -### Issue: "Service Uses Wrong Configuration" - -```toml -# Verify deployment mode is set -echo $ORCHESTRATOR_MODE - -# Check which TOML file service reads -ls -lah provisioning/config/runtime/generated/orchestrator.*.toml - -# Verify TOML modification time is recent -stat provisioning/config/runtime/generated/orchestrator.solo.toml -``` - -The service reads from `orchestrator.{MODE}.toml` based on environment variable. - -## Best Practices - -### Development (Solo Mode) - -1. Start simple using the solo example as-is first -2. Iterate gradually, making one change at a time -3. Enable logging by setting level = "debug" for troubleshooting -4. Disable security features for local development (TLS/auth) -5. Store data in ./provisioning/data/ which is gitignored - -### Staging (Multiuser Mode) - -1. Mirror production settings to test realistically -2. Enable authentication even in staging to test auth flows -3. Enable TLS with valid certificates to test secure connections -4. Set up monitoring metrics and health checks -5. Plan worker count based on expected concurrent users - -### Production (Enterprise Mode) - -1. Follow the enterprise example as baseline configuration -2. Use secure vault for storing credentials and secrets -3. Enable redundancy with 3-way replication for HA -4. Enable full monitoring with distributed tracing -5. Test failover scenarios regularly -6. Enable audit logging for compliance -7. Enforce TLS 1.3 and certificate rotation - -## Migration Between Modes - -To upgrade from solo → multiuser → enterprise: - -```bash -# 1. Backup current configuration -cp provisioning/config/runtime/orchestrator.solo.ncl - provisioning/config/runtime/orchestrator.solo.ncl.bak - -# 2. Copy new example for target mode -cp provisioning/config/examples/orchestrator.multiuser.example.ncl - provisioning/config/runtime/orchestrator.multiuser.ncl - -# 3. Customize for your environment -vim provisioning/config/runtime/orchestrator.multiuser.ncl - -# 4. Validate and generate TOML -./provisioning/scripts/setup-platform-config.sh --generate-toml - -# 5. Update mode environment variable and restart -export ORCHESTRATOR_MODE=multiuser -cargo run -p orchestrator -``` - -## Related Documentation - -- **Platform Configuration Guide**: `provisioning/docs/src/getting-started/05-platform-configuration.md` -- **Configuration README**: `provisioning/config/README.md` -- **System Status**: `provisioning/config/SETUP_STATUS.md` -- **Setup Script Reference**: `provisioning/scripts/setup-platform-config.sh.md` -- **Advanced TypeDialog Guide**: `provisioning/docs/src/development/typedialog-platform-config-guide.md` - ---- - -**Version**: 1.0.0 -**Last Updated**: 2026-01-05 -**Status**: Ready to use diff --git a/config/examples/control-center.solo.example.ncl b/config/examples/control-center.solo.example.ncl deleted file mode 100644 index 19b2597..0000000 --- a/config/examples/control-center.solo.example.ncl +++ /dev/null @@ -1,15 +0,0 @@ -# Example: Control Center Service Configuration (Solo Development Mode) -# -# Control Center is the web UI and management console. -# Copy this file to provisioning/config/runtime/control-center.solo.ncl -# -# Generated: 2026-01-05 - -let helpers = import "../../schemas/platform/common/helpers.ncl" in -let defaults = import "../../schemas/platform/defaults/control-center-defaults.ncl" in -let mode_config = import "../../schemas/platform/defaults/deployment/solo-defaults.ncl" in - -# Solo mode composition -helpers.compose_config defaults mode_config { - # Optional: Customize for your development setup -} diff --git a/config/examples/control-center.solo.example.toml b/config/examples/control-center.solo.example.toml deleted file mode 100644 index 5fe0a3b..0000000 --- a/config/examples/control-center.solo.example.toml +++ /dev/null @@ -1,193 +0,0 @@ -[control_center.audit] -enabled = false -redact_sensitive = true - - [control_center.audit.storage] - immutable = false - retention_days = 90 - -[control_center.compliance] -enabled = false -encryption_required = false - - [control_center.compliance.data_retention] - audit_log_days = 2555 - policy_years = 7 - - [control_center.compliance.validation] - enabled = false - interval_hours = 24 - -[control_center.database] -backend = "rocksdb" -max_retries = "3" -path = "/var/lib/provisioning/control-center/data" -pool_size = 10 -retry = true -timeout = 30 - -[control_center.integrations.ldap] -enabled = false - -[control_center.integrations.oauth2] -enabled = false - -[control_center.integrations.webhooks] -enabled = false - -[control_center.logging] -format = "&" -level = "&" -outputs = ["stdout"] - - [control_center.logging.fields] - caller = false - hostname = true - pid = true - service_name = true - stack_trace = false - timestamp = true - - [control_center.logging.file] - compress = false - max_age = 30 - max_backups = 10 - max_size = 104857600 - path = "/var/log/provisioning/service.log" - - [control_center.logging.performance] - enabled = false - memory_info = false - slow_threshold = 1000 - - [control_center.logging.sampling] - enabled = false - initial = 100 - thereafter = 100 - - [control_center.logging.syslog] - protocol = "udp" - -[control_center.monitoring] -enabled = false - - [control_center.monitoring.alerting] - enabled = false - - [control_center.monitoring.health_check] - enabled = false - endpoint = "/health" - healthy_threshold = 2 - interval = 30 - timeout = 5000 - type = "&" - unhealthy_threshold = 3 - - [control_center.monitoring.metrics] - buffer_size = 1000 - enabled = false - interval = 60 - prometheus_path = "/metrics" - retention_days = 30 - - [control_center.monitoring.resources] - alert_threshold = 80 - cpu = false - disk = false - memory = false - network = false - - [control_center.monitoring.tracing] - enabled = false - sample_rate = 0.1 - -[control_center.policy] -enabled = true - - [control_center.policy.cache] - enabled = true - max_policies = 10000 - ttl = 3600 - - [control_center.policy.versioning] - enabled = true - max_versions = 20 - -[control_center.rbac] -attribute_based = false -default_role = "user" -dynamic_roles = false -enabled = true -hierarchy = true - - [control_center.rbac.roles] - admin = true - operator = true - viewer = true - -[control_center.security.cors] -allow_credentials = false -enabled = false - -[control_center.security.jwt] -algorithm = "HS256" -audience = "provisioning" -expiration = 3600 -issuer = "control-center" -refresh_expiration = 86400 -secret = "change_me_in_production" - -[control_center.security.mfa] -lockout_duration = 15 -max_attempts = "5" -methods = ["totp"] -required = false - -[control_center.security.rate_limiting] -enabled = false -max_requests = "1000" -window_seconds = 60 - -[control_center.security.rbac] -default_role = "user" -enabled = true -inheritance = true - -[control_center.security.session] -idle_timeout = 3600 -max_duration = 86400 -tracking = false - -[control_center.security.tls] -client_auth = false -enabled = false - -[control_center.server] -graceful_shutdown = true -host = "127.0.0.1" -keep_alive = 75 -max_connections = 100 -port = 8080 -request_timeout = 30000 -shutdown_timeout = 30 -workers = 4 - -[control_center.users] -audit_enabled = false -enabled = true - - [control_center.users.registration] - auto_assign_role = "user" - enabled = true - requires_approval = false - - [control_center.users.sessions] - absolute_timeout = 86400 - idle_timeout = 3600 - max_active = 5 - -[control_center.workspace] -enabled = true -multi_workspace = false -name = "default" -path = "/var/lib/provisioning/control-center" diff --git a/config/examples/extension-registry.enterprise.example.toml b/config/examples/extension-registry.enterprise.example.toml deleted file mode 100644 index c2744c3..0000000 --- a/config/examples/extension-registry.enterprise.example.toml +++ /dev/null @@ -1,86 +0,0 @@ -# Extension Registry Configuration - Enterprise Example -# High-availability, multi-source, multi-registry production deployment - -[server] -enable_compression = true -enable_cors = true -host = "0.0.0.0" -port = 8082 -workers = 8 - -# Primary internal Gitea instance -[[sources.gitea]] -id = "primary-internal-gitea" -organization = "platform-extensions" -timeout_seconds = 30 -token_path = "/etc/secrets/gitea-primary-token.txt" -url = "https://gitea.internal.company.com" -verify_ssl = true - -# Secondary internal Gitea (failover) -[[sources.gitea]] -id = "secondary-internal-gitea" -organization = "platform-extensions" -timeout_seconds = 30 -token_path = "/etc/secrets/gitea-secondary-token.txt" -url = "https://gitea-secondary.internal.company.com" -verify_ssl = true - -# Forgejo for community extensions -[[sources.forgejo]] -id = "enterprise-forgejo" -organization = "platform" -timeout_seconds = 30 -token_path = "/etc/secrets/forgejo-token.txt" -url = "https://forge.company.com" -verify_ssl = true - -# GitHub organization -[[sources.github]] -id = "company-github" -organization = "company-platform" -timeout_seconds = 30 -token_path = "/etc/secrets/github-token.txt" -verify_ssl = true - -# Primary enterprise OCI registry (Zot) -[[distributions.oci]] -id = "primary-oci-zot" -namespace = "platform/extensions" -registry = "zot.internal.company.com" -timeout_seconds = 30 -verify_ssl = true - -# Secondary enterprise OCI registry (Harbor) -[[distributions.oci]] -auth_token_path = "/etc/secrets/harbor-token.txt" -id = "secondary-oci-harbor" -namespace = "platform" -registry = "harbor.internal.company.com" -timeout_seconds = 30 -verify_ssl = true - -# Public Docker Hub for external distribution -[[distributions.oci]] -auth_token_path = "/etc/secrets/docker-hub-token.txt" -id = "public-docker-hub" -namespace = "company-open-source" -registry = "docker.io" -timeout_seconds = 30 -verify_ssl = true - -# Public GHCR for open-source projects -[[distributions.oci]] -auth_token_path = "/etc/secrets/ghcr-token.txt" -id = "public-ghcr" -namespace = "company-open-source" -registry = "ghcr.io" -timeout_seconds = 30 -verify_ssl = true - -# Caching configuration for high-traffic enterprise environment -[cache] -capacity = 5000 -enable_list_cache = true -enable_metadata_cache = true -ttl_seconds = 600 diff --git a/config/examples/extension-registry.multi-backend.example.toml b/config/examples/extension-registry.multi-backend.example.toml deleted file mode 100644 index 9001b6b..0000000 --- a/config/examples/extension-registry.multi-backend.example.toml +++ /dev/null @@ -1,89 +0,0 @@ -# Extension Registry Configuration - Multi-Backend Example -# This example demonstrates the new multi-instance architecture supporting -# multiple Git-based sources (Gitea, Forgejo, GitHub) and multiple OCI registries - -[server] -enable_compression = true -enable_cors = false -host = "0.0.0.0" -port = 8082 -workers = 4 - -# Multiple Git-based source backends -# Internal Gitea instance for private extensions -[[sources.gitea]] -id = "internal-gitea" -organization = "provisioning" -timeout_seconds = 30 -token_path = "/etc/secrets/gitea-internal-token.txt" -url = "https://gitea.internal.example.com" -verify_ssl = true - -# Public Gitea instance for community extensions -[[sources.gitea]] -id = "public-gitea" -organization = "provisioning-extensions" -timeout_seconds = 30 -token_path = "/etc/secrets/gitea-public-token.txt" -url = "https://gitea.public.example.com" -verify_ssl = true - -# Forgejo sources (Git-compatible) -[[sources.forgejo]] -id = "community-forgejo" -organization = "provisioning" -timeout_seconds = 30 -token_path = "/etc/secrets/forgejo-token.txt" -url = "https://forgejo.community.example.com" -verify_ssl = true - -# GitHub sources -[[sources.github]] -id = "org-github" -organization = "my-organization" -timeout_seconds = 30 -token_path = "/etc/secrets/github-token.txt" -verify_ssl = true - -# Multiple OCI distribution registries -# Internal Zot registry -[[distributions.oci]] -id = "internal-zot" -namespace = "provisioning/extensions" -registry = "zot.internal.example.com" -timeout_seconds = 30 -verify_ssl = true - -# Public Harbor registry -[[distributions.oci]] -auth_token_path = "/etc/secrets/harbor-token.txt" -id = "public-harbor" -namespace = "provisioning" -registry = "harbor.public.example.com" -timeout_seconds = 30 -verify_ssl = true - -# Docker Hub -[[distributions.oci]] -auth_token_path = "/etc/secrets/docker-hub-token.txt" -id = "docker-hub" -namespace = "myorg" -registry = "docker.io" -timeout_seconds = 30 -verify_ssl = true - -# GHCR (GitHub Container Registry) -[[distributions.oci]] -auth_token_path = "/etc/secrets/ghcr-token.txt" -id = "ghcr" -namespace = "my-organization" -registry = "ghcr.io" -timeout_seconds = 30 -verify_ssl = true - -# Caching configuration -[cache] -capacity = 1000 -enable_list_cache = true -enable_metadata_cache = true -ttl_seconds = 300 diff --git a/config/examples/extension-registry.solo.example.toml b/config/examples/extension-registry.solo.example.toml deleted file mode 100644 index 60757e4..0000000 --- a/config/examples/extension-registry.solo.example.toml +++ /dev/null @@ -1,25 +0,0 @@ -# Extension Registry Configuration - Solo/Minimal Example -# Minimal configuration for development or single-backend deployments -# Old single-instance format (auto-migrated to multi-instance on startup) - -[server] -enable_compression = true -enable_cors = false -host = "127.0.0.1" -port = 8082 -workers = 2 - -# Single Gitea backend (auto-migrated to sources.gitea[0]) -[gitea] -organization = "provisioning" -timeout_seconds = 30 -token_path = "/etc/secrets/gitea-token.txt" -url = "http://localhost:3000" -verify_ssl = false - -# Caching configuration -[cache] -capacity = 100 -enable_list_cache = true -enable_metadata_cache = true -ttl_seconds = 300 diff --git a/config/examples/orchestrator.enterprise.example.ncl b/config/examples/orchestrator.enterprise.example.ncl deleted file mode 100644 index 32ab307..0000000 --- a/config/examples/orchestrator.enterprise.example.ncl +++ /dev/null @@ -1,23 +0,0 @@ -# Example: Orchestrator Service Configuration (Enterprise Production Mode) -# -# This is a reference configuration showing typical settings for production deployment. -# Copy this file to provisioning/config/runtime/orchestrator.enterprise.ncl and customize -# as needed for your production environment. -# -# Enterprise mode (16+ CPU, 32+ GB RAM): -# - Production deployments -# - High availability and redundancy -# - Multi-team/multi-workspace -# - Mission-critical workloads -# - Full monitoring and security -# -# Generated: 2026-01-05 - -let helpers = import "../../schemas/platform/common/helpers.ncl" in -let defaults = import "../../schemas/platform/defaults/orchestrator-defaults.ncl" in -let mode_config = import "../../schemas/platform/defaults/deployment/enterprise-defaults.ncl" in - -# Enterprise mode composition: base defaults + mode overlay -helpers.compose_config defaults mode_config { - # Optional: Production overrides -} diff --git a/config/examples/orchestrator.enterprise.example.toml b/config/examples/orchestrator.enterprise.example.toml deleted file mode 100644 index a76830d..0000000 --- a/config/examples/orchestrator.enterprise.example.toml +++ /dev/null @@ -1,126 +0,0 @@ -[orchestrator.batch] -metrics = false -operation_timeout = 1800000 -parallel_limit = 5 - - [orchestrator.batch.checkpointing] - enabled = true - interval = 100 - max_checkpoints = 10 - - [orchestrator.batch.rollback] - enabled = true - max_rollback_depth = 5 - strategy = "checkpoint_based" - -[orchestrator.extensions] -auto_load = false -discovery_interval = 300 -max_concurrent = 5 -sandbox = true -timeout = 30000 - -[orchestrator.logging] -format = "&" -level = "&" -outputs = ["stdout"] - - [orchestrator.logging.fields] - caller = false - hostname = true - pid = true - service_name = true - stack_trace = false - timestamp = true - - [orchestrator.logging.file] - compress = false - max_age = 30 - max_backups = 10 - max_size = 104857600 - path = "/var/log/provisioning/service.log" - - [orchestrator.logging.performance] - enabled = false - memory_info = false - slow_threshold = 1000 - - [orchestrator.logging.sampling] - enabled = false - initial = 100 - thereafter = 100 - - [orchestrator.logging.syslog] - protocol = "udp" - -[orchestrator.monitoring] -enabled = false - - [orchestrator.monitoring.alerting] - enabled = false - - [orchestrator.monitoring.health_check] - enabled = false - endpoint = "/health" - healthy_threshold = 2 - interval = 30 - timeout = 5000 - type = "&" - unhealthy_threshold = 3 - - [orchestrator.monitoring.metrics] - buffer_size = 1000 - enabled = false - interval = 60 - prometheus_path = "/metrics" - retention_days = 30 - - [orchestrator.monitoring.resources] - alert_threshold = 80 - cpu = false - disk = false - memory = false - network = false - - [orchestrator.monitoring.tracing] - enabled = false - sample_rate = 0.1 - -[orchestrator.queue] -max_concurrent_tasks = 5 -metrics = false -persist = true -priority_queue = false -retry_attempts = 3 -retry_delay = 5000 -task_timeout = 3600000 - - [orchestrator.queue.dead_letter_queue] - enabled = true - max_size = 1000 - -[orchestrator.server] -graceful_shutdown = true -host = "127.0.0.1" -keep_alive = 75 -max_connections = 100 -port = 9090 -request_timeout = 30000 -shutdown_timeout = 30 -workers = 4 - -[orchestrator.storage] -backend = "filesystem" -path = "/var/lib/provisioning/orchestrator/data" - - [orchestrator.storage.cache] - enabled = true - eviction_policy = "lru" - ttl = 3600 - type = "in_memory" - -[orchestrator.workspace] -enabled = true -multi_workspace = false -name = "default" -path = "/var/lib/provisioning/orchestrator" diff --git a/config/examples/orchestrator.multiuser.example.ncl b/config/examples/orchestrator.multiuser.example.ncl deleted file mode 100644 index 7115519..0000000 --- a/config/examples/orchestrator.multiuser.example.ncl +++ /dev/null @@ -1,22 +0,0 @@ -# Example: Orchestrator Service Configuration (Multiuser Team Mode) -# -# This is a reference configuration showing typical settings for team staging. -# Copy this file to provisioning/config/runtime/orchestrator.multiuser.ncl and customize -# as needed for your environment. -# -# Multiuser mode (4 CPU, 8GB RAM): -# - Team staging environments -# - Multiple concurrent users -# - Moderate production-like testing -# - Integration testing -# -# Generated: 2026-01-05 - -let helpers = import "../../schemas/platform/common/helpers.ncl" in -let defaults = import "../../schemas/platform/defaults/orchestrator-defaults.ncl" in -let mode_config = import "../../schemas/platform/defaults/deployment/multiuser-defaults.ncl" in - -# Multiuser mode composition: base defaults + mode overlay -helpers.compose_config defaults mode_config { - # Optional: Custom overrides for your team environment -} diff --git a/config/examples/orchestrator.solo.example.ncl b/config/examples/orchestrator.solo.example.ncl deleted file mode 100644 index e600b35..0000000 --- a/config/examples/orchestrator.solo.example.ncl +++ /dev/null @@ -1,21 +0,0 @@ -# Example: Orchestrator Service Configuration (Solo Development Mode) -# -# This is a reference configuration showing typical settings for solo development. -# Copy this file to provisioning/config/runtime/orchestrator.solo.ncl and customize -# as needed for your environment. -# -# Solo mode (2 CPU, 4GB RAM): -# - Local development -# - Testing and validation -# - Single-user deployments -# -# Generated: 2026-01-05 - -let helpers = import "../../schemas/platform/common/helpers.ncl" in -let defaults = import "../../schemas/platform/defaults/orchestrator-defaults.ncl" in -let mode_config = import "../../schemas/platform/defaults/deployment/solo-defaults.ncl" in - -# Solo mode composition: base defaults + mode overlay -helpers.compose_config defaults mode_config { - # Optional: User customizations (empty for defaults) -} diff --git a/config/examples/orchestrator.solo.example.toml b/config/examples/orchestrator.solo.example.toml deleted file mode 100644 index a76830d..0000000 --- a/config/examples/orchestrator.solo.example.toml +++ /dev/null @@ -1,126 +0,0 @@ -[orchestrator.batch] -metrics = false -operation_timeout = 1800000 -parallel_limit = 5 - - [orchestrator.batch.checkpointing] - enabled = true - interval = 100 - max_checkpoints = 10 - - [orchestrator.batch.rollback] - enabled = true - max_rollback_depth = 5 - strategy = "checkpoint_based" - -[orchestrator.extensions] -auto_load = false -discovery_interval = 300 -max_concurrent = 5 -sandbox = true -timeout = 30000 - -[orchestrator.logging] -format = "&" -level = "&" -outputs = ["stdout"] - - [orchestrator.logging.fields] - caller = false - hostname = true - pid = true - service_name = true - stack_trace = false - timestamp = true - - [orchestrator.logging.file] - compress = false - max_age = 30 - max_backups = 10 - max_size = 104857600 - path = "/var/log/provisioning/service.log" - - [orchestrator.logging.performance] - enabled = false - memory_info = false - slow_threshold = 1000 - - [orchestrator.logging.sampling] - enabled = false - initial = 100 - thereafter = 100 - - [orchestrator.logging.syslog] - protocol = "udp" - -[orchestrator.monitoring] -enabled = false - - [orchestrator.monitoring.alerting] - enabled = false - - [orchestrator.monitoring.health_check] - enabled = false - endpoint = "/health" - healthy_threshold = 2 - interval = 30 - timeout = 5000 - type = "&" - unhealthy_threshold = 3 - - [orchestrator.monitoring.metrics] - buffer_size = 1000 - enabled = false - interval = 60 - prometheus_path = "/metrics" - retention_days = 30 - - [orchestrator.monitoring.resources] - alert_threshold = 80 - cpu = false - disk = false - memory = false - network = false - - [orchestrator.monitoring.tracing] - enabled = false - sample_rate = 0.1 - -[orchestrator.queue] -max_concurrent_tasks = 5 -metrics = false -persist = true -priority_queue = false -retry_attempts = 3 -retry_delay = 5000 -task_timeout = 3600000 - - [orchestrator.queue.dead_letter_queue] - enabled = true - max_size = 1000 - -[orchestrator.server] -graceful_shutdown = true -host = "127.0.0.1" -keep_alive = 75 -max_connections = 100 -port = 9090 -request_timeout = 30000 -shutdown_timeout = 30 -workers = 4 - -[orchestrator.storage] -backend = "filesystem" -path = "/var/lib/provisioning/orchestrator/data" - - [orchestrator.storage.cache] - enabled = true - eviction_policy = "lru" - ttl = 3600 - type = "in_memory" - -[orchestrator.workspace] -enabled = true -multi_workspace = false -name = "default" -path = "/var/lib/provisioning/orchestrator" diff --git a/config/examples/vault-service.solo.example.ncl b/config/examples/vault-service.solo.example.ncl deleted file mode 100644 index d459cb4..0000000 --- a/config/examples/vault-service.solo.example.ncl +++ /dev/null @@ -1,15 +0,0 @@ -# Example: Vault Service Configuration (Solo Development Mode) -# -# Vault Service handles secrets management and encryption. -# Copy this file to provisioning/config/runtime/vault-service.solo.ncl -# -# Generated: 2026-01-05 - -let helpers = import "../../schemas/platform/common/helpers.ncl" in -let defaults = import "../../schemas/platform/defaults/vault-service-defaults.ncl" in -let mode_config = import "../../schemas/platform/defaults/deployment/solo-defaults.ncl" in - -# Solo mode composition -helpers.compose_config defaults mode_config { - # Optional: Customize for your development setup -} diff --git a/core b/core index adb28be..85ab055 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit adb28be45a8c7ea2763da8b680bf719b0b128be7 +Subproject commit 85ab055ccb5cccea5a9ff04c7c4a0566a2de8c0d diff --git a/docs/.markdownlint-cli2.jsonc b/docs/.markdownlint-cli2.jsonc deleted file mode 100644 index 7866d7e..0000000 --- a/docs/.markdownlint-cli2.jsonc +++ /dev/null @@ -1,103 +0,0 @@ -// Markdownlint-cli2 Configuration -// Documentation quality enforcement aligned with CLAUDE.md guidelines -// See: https://github.com/igorshubovych/markdownlint-cli2 - -{ - "config": { - "default": true, - - // Headings - enforce proper hierarchy - "MD001": false, // heading-increment (relaxed - allow flexibility) - "MD026": { "punctuation": ".,;:!?" }, // heading-punctuation - - // Lists - enforce consistency - "MD004": { "style": "consistent" }, // ul-style (consistent list markers) - "MD005": false, // inconsistent-indentation (relaxed) - "MD007": { "indent": 2 }, // ul-indent - "MD029": false, // ol-prefix (allow flexible list numbering) - "MD030": { "ul_single": 1, "ol_single": 1, "ul_multi": 1, "ol_multi": 1 }, - - // Code blocks - fenced only - "MD046": { "style": "fenced" }, // code-block-style - // CRITICAL: MD040 only checks for missing language on opening fence. - // It does NOT catch malformed closing fences with language specifiers (e.g., ```plaintext). - // This is a CommonMark violation that must be caught by custom pre-commit hook. - // Pre-commit hook: check-malformed-fences (provisioning/core/.pre-commit-config.yaml) - // Script: provisioning/scripts/check-malformed-fences.nu - - // Formatting - strict whitespace - "MD009": true, // no-hard-tabs - "MD010": true, // hard-tabs - "MD011": true, // reversed-link-syntax - "MD018": true, // no-missing-space-atx - "MD019": true, // no-multiple-space-atx - "MD020": true, // no-missing-space-closed-atx - "MD021": true, // no-multiple-space-closed-atx - "MD023": true, // heading-starts-line - "MD027": true, // no-multiple-spaces-blockquote - "MD037": true, // no-space-in-emphasis - "MD039": true, // no-space-in-links - - // Trailing content - "MD012": false, // no-multiple-blanks (relaxed - allow formatting space) - "MD024": false, // no-duplicate-heading (too strict for docs) - "MD028": false, // no-blanks-blockquote (relaxed) - "MD031": false, // blanks-around-fences (too strict for technical docs) - "MD047": true, // single-trailing-newline - - // Links and references - "MD034": true, // no-bare-urls (links must be formatted) - "MD040": true, // fenced-code-language (code blocks need language) - "MD042": true, // no-empty-links - - // HTML - allow for documentation formatting and images - "MD033": { "allowed_elements": ["br", "hr", "details", "summary", "p", "img"] }, - - // Line length - relaxed for technical documentation - "MD013": { - "line_length": 150, - "heading_line_length": 150, - "code_block_line_length": 150, - "code_blocks": true, - "tables": true, - "headers": true, - "headers_line_length": 150, - "strict": false, - "stern": false - }, - - // Images - "MD045": true, // image-alt-text - - // Disable rules that conflict with relaxed style - "MD003": false, // consistent-indentation - "MD041": false, // first-line-heading - "MD025": false, // single-h1 / multiple-top-level-headings - "MD022": false, // blanks-around-headings (flexible spacing) - "MD032": false, // blanks-around-lists (flexible spacing) - "MD035": false, // hr-style (consistent) - "MD036": false, // no-emphasis-as-heading - "MD044": false, // proper-names - "MD060": true // table-column-style (enforce proper table formatting) - }, - - // Documentation patterns - "globs": [ - "docs/**/*.md", - "!docs/node_modules/**", - "!docs/build/**" - ], - - // Ignore build artifacts, external content, and operational directories - "ignores": [ - "node_modules/**", - "target/**", - ".git/**", - "build/**", - "dist/**", - ".coder/**", - ".claude/**", - ".wrks/**", - ".vale/**" - ] -} diff --git a/docs/book.toml b/docs/book.toml deleted file mode 100644 index 30bbee2..0000000 --- a/docs/book.toml +++ /dev/null @@ -1,48 +0,0 @@ -[book] -title = "Provisioning Platform Documentation" -authors = ["Provisioning Team"] -language = "en" -multilingual = false -src = "src" -description = "Enterprise-grade Infrastructure as Code platform - Complete documentation" - -[build] -build-dir = "book" -create-missing = true - -[output.html] -default-theme = "rust" -preferred-dark-theme = "navy" -smart-punctuation = true -mathjax-support = false -copy-fonts = true -no-section-label = false -git-repository-url = "https://github.com/your-org/provisioning" -git-repository-icon = "fa-github" -edit-url-template = "https://github.com/your-org/provisioning/edit/main/provisioning/docs/{path}" -site-url = "/provisioning/" - -[output.html.fold] -enable = true -level = 1 - -[output.html.search] -enable = true -limit-results = 30 -teaser-word-count = 30 -use-boolean-and = true -boost-title = 2 -boost-hierarchy = 1 -boost-paragraph = 1 -expand = true - -[output.html.playground] -editable = true -copyable = true -copy-js = true -line-numbers = true -runnable = false - -[preprocessor.links] - -[preprocessor.index] diff --git a/docs/book/.nojekyll b/docs/book/.nojekyll deleted file mode 100644 index f173110..0000000 --- a/docs/book/.nojekyll +++ /dev/null @@ -1 +0,0 @@ -This file makes sure that Github Pages doesn't process mdBook's output. diff --git a/docs/book/404.html b/docs/book/404.html deleted file mode 100644 index d54b4c4..0000000 --- a/docs/book/404.html +++ /dev/null @@ -1,238 +0,0 @@ - - - - - - Page not found - Provisioning Platform Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-

Keyboard shortcuts

-
-

Press or to navigate between chapters

-

Press S or / to search in the book

-

Press ? to show this help

-

Press Esc to hide this help

-
-
-
-
- - - - - - - - - - - - - -
- -
- - - - - - - - -
-
-

Document not found (404)

-

This URL is invalid, sorry. Please use the navigation bar or search to continue.

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- - diff --git a/docs/book/FontAwesome/css/font-awesome.css b/docs/book/FontAwesome/css/font-awesome.css deleted file mode 100644 index 540440c..0000000 --- a/docs/book/FontAwesome/css/font-awesome.css +++ /dev/null @@ -1,4 +0,0 @@ -/*! - * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/docs/book/FontAwesome/fonts/FontAwesome.ttf b/docs/book/FontAwesome/fonts/FontAwesome.ttf deleted file mode 100644 index 35acda2..0000000 Binary files a/docs/book/FontAwesome/fonts/FontAwesome.ttf and /dev/null differ diff --git a/docs/book/FontAwesome/fonts/fontawesome-webfont.eot b/docs/book/FontAwesome/fonts/fontawesome-webfont.eot deleted file mode 100644 index e9f60ca..0000000 Binary files a/docs/book/FontAwesome/fonts/fontawesome-webfont.eot and /dev/null differ diff --git a/docs/book/FontAwesome/fonts/fontawesome-webfont.svg b/docs/book/FontAwesome/fonts/fontawesome-webfont.svg deleted file mode 100644 index 52c0773..0000000 --- a/docs/book/FontAwesome/fonts/fontawesome-webfont.svg +++ /dev/null @@ -1,2671 +0,0 @@ - - - - -Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 - By ,,, -Copyright Dave Gandy 2016. All rights reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/book/FontAwesome/fonts/fontawesome-webfont.ttf b/docs/book/FontAwesome/fonts/fontawesome-webfont.ttf deleted file mode 100644 index 35acda2..0000000 Binary files a/docs/book/FontAwesome/fonts/fontawesome-webfont.ttf and /dev/null differ diff --git a/docs/book/FontAwesome/fonts/fontawesome-webfont.woff b/docs/book/FontAwesome/fonts/fontawesome-webfont.woff deleted file mode 100644 index 400014a..0000000 Binary files a/docs/book/FontAwesome/fonts/fontawesome-webfont.woff and /dev/null differ diff --git a/docs/book/FontAwesome/fonts/fontawesome-webfont.woff2 b/docs/book/FontAwesome/fonts/fontawesome-webfont.woff2 deleted file mode 100644 index 4d13fc6..0000000 Binary files a/docs/book/FontAwesome/fonts/fontawesome-webfont.woff2 and /dev/null differ diff --git a/docs/book/architecture/integration-patterns.html b/docs/book/architecture/integration-patterns.html deleted file mode 100644 index eee60d9..0000000 --- a/docs/book/architecture/integration-patterns.html +++ /dev/null @@ -1,296 +0,0 @@ - - - - - - Integration Patterns - Provisioning Platform Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-

Keyboard shortcuts

-
-

Press or to navigate between chapters

-

Press S or / to search in the book

-

Press ? to show this help

-

Press Esc to hide this help

-
-
-
-
- - - - - - - - - - - - - -
- -
- - - - - - - - -
-
-

Integration Patterns

-

Design patterns for extending and integrating with Provisioning.

-

1. Provider Integration Pattern

-

Pattern: Add a new cloud provider to Provisioning.

-

2. Task Service Integration Pattern

-

Pattern: Add infrastructure component.

-

3. Cluster Template Pattern

-

Pattern: Create pre-configured cluster template.

-

4. Batch Workflow Pattern

-

Pattern: Create automation workflow for complex operations.

-

5. Custom Extension Pattern

-

Pattern: Create custom Nushell library.

-

6. Authorization Policy Pattern

-

Pattern: Define fine-grained access control via Cedar.

-

7. Webhook Integration

-

Pattern: Trigger Provisioning from external systems.

-

8. Monitoring Integration

-

Pattern: Export metrics and logs to monitoring systems.

-

9. CI/CD Integration

-

Pattern: Use Provisioning in automated pipelines.

-

10. MCP Tool Integration

-

Pattern: Add AI-powered tool via MCP.

-

Integration Scenarios

-

Multi-Cloud Deployment

-

Deploy across UpCloud, AWS, and Hetzner in single workflow.

-

GitOps Workflow

-

Git changes trigger infrastructure updates via webhooks.

-

Self-Service Deployment

-

Non-technical users request infrastructure via natural language.

-

Best Practices

-
    -
  1. Use type-safe Nickel schemas
  2. -
  3. Implement proper error handling
  4. -
  5. Log all operations for audit trails
  6. -
  7. Test extensions before production
  8. -
  9. Document configuration & usage
  10. -
  11. Version extensions independently
  12. -
  13. Support backward compatibility
  14. -
  15. Validate inputs & encrypt credentials
  16. -
- - - -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- - diff --git a/docs/book/ayu-highlight.css b/docs/book/ayu-highlight.css deleted file mode 100644 index 32c9432..0000000 --- a/docs/book/ayu-highlight.css +++ /dev/null @@ -1,78 +0,0 @@ -/* -Based off of the Ayu theme -Original by Dempfi (https://github.com/dempfi/ayu) -*/ - -.hljs { - display: block; - overflow-x: auto; - background: #191f26; - color: #e6e1cf; -} - -.hljs-comment, -.hljs-quote { - color: #5c6773; - font-style: italic; -} - -.hljs-variable, -.hljs-template-variable, -.hljs-attribute, -.hljs-attr, -.hljs-regexp, -.hljs-link, -.hljs-selector-id, -.hljs-selector-class { - color: #ff7733; -} - -.hljs-number, -.hljs-meta, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params { - color: #ffee99; -} - -.hljs-string, -.hljs-bullet { - color: #b8cc52; -} - -.hljs-title, -.hljs-built_in, -.hljs-section { - color: #ffb454; -} - -.hljs-keyword, -.hljs-selector-tag, -.hljs-symbol { - color: #ff7733; -} - -.hljs-name { - color: #36a3d9; -} - -.hljs-tag { - color: #00568d; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} - -.hljs-addition { - color: #91b362; -} - -.hljs-deletion { - color: #d96c75; -} diff --git a/docs/book/book.js b/docs/book/book.js deleted file mode 100644 index 5df2096..0000000 --- a/docs/book/book.js +++ /dev/null @@ -1,818 +0,0 @@ -'use strict'; - -/* global default_theme, default_dark_theme, default_light_theme, hljs, ClipboardJS */ - -// Fix back button cache problem -window.onunload = function() { }; - -// Global variable, shared between modules -function playground_text(playground, hidden = true) { - const code_block = playground.querySelector('code'); - - if (window.ace && code_block.classList.contains('editable')) { - const editor = window.ace.edit(code_block); - return editor.getValue(); - } else if (hidden) { - return code_block.textContent; - } else { - return code_block.innerText; - } -} - -(function codeSnippets() { - function fetch_with_timeout(url, options, timeout = 6000) { - return Promise.race([ - fetch(url, options), - new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout)), - ]); - } - - const playgrounds = Array.from(document.querySelectorAll('.playground')); - if (playgrounds.length > 0) { - fetch_with_timeout('https://play.rust-lang.org/meta/crates', { - headers: { - 'Content-Type': 'application/json', - }, - method: 'POST', - mode: 'cors', - }) - .then(response => response.json()) - .then(response => { - // get list of crates available in the rust playground - const playground_crates = response.crates.map(item => item['id']); - playgrounds.forEach(block => handle_crate_list_update(block, playground_crates)); - }); - } - - function handle_crate_list_update(playground_block, playground_crates) { - // update the play buttons after receiving the response - update_play_button(playground_block, playground_crates); - - // and install on change listener to dynamically update ACE editors - if (window.ace) { - const code_block = playground_block.querySelector('code'); - if (code_block.classList.contains('editable')) { - const editor = window.ace.edit(code_block); - editor.addEventListener('change', () => { - update_play_button(playground_block, playground_crates); - }); - // add Ctrl-Enter command to execute rust code - editor.commands.addCommand({ - name: 'run', - bindKey: { - win: 'Ctrl-Enter', - mac: 'Ctrl-Enter', - }, - exec: _editor => run_rust_code(playground_block), - }); - } - } - } - - // updates the visibility of play button based on `no_run` class and - // used crates vs ones available on https://play.rust-lang.org - function update_play_button(pre_block, playground_crates) { - const play_button = pre_block.querySelector('.play-button'); - - // skip if code is `no_run` - if (pre_block.querySelector('code').classList.contains('no_run')) { - play_button.classList.add('hidden'); - return; - } - - // get list of `extern crate`'s from snippet - const txt = playground_text(pre_block); - const re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g; - const snippet_crates = []; - let item; - // eslint-disable-next-line no-cond-assign - while (item = re.exec(txt)) { - snippet_crates.push(item[1]); - } - - // check if all used crates are available on play.rust-lang.org - const all_available = snippet_crates.every(function(elem) { - return playground_crates.indexOf(elem) > -1; - }); - - if (all_available) { - play_button.classList.remove('hidden'); - } else { - play_button.classList.add('hidden'); - } - } - - function run_rust_code(code_block) { - let result_block = code_block.querySelector('.result'); - if (!result_block) { - result_block = document.createElement('code'); - result_block.className = 'result hljs language-bash'; - - code_block.append(result_block); - } - - const text = playground_text(code_block); - const classes = code_block.querySelector('code').classList; - let edition = '2015'; - classes.forEach(className => { - if (className.startsWith('edition')) { - edition = className.slice(7); - } - }); - const params = { - version: 'stable', - optimize: '0', - code: text, - edition: edition, - }; - - if (text.indexOf('#![feature') !== -1) { - params.version = 'nightly'; - } - - result_block.innerText = 'Running...'; - - fetch_with_timeout('https://play.rust-lang.org/evaluate.json', { - headers: { - 'Content-Type': 'application/json', - }, - method: 'POST', - mode: 'cors', - body: JSON.stringify(params), - }) - .then(response => response.json()) - .then(response => { - if (response.result.trim() === '') { - result_block.innerText = 'No output'; - result_block.classList.add('result-no-output'); - } else { - result_block.innerText = response.result; - result_block.classList.remove('result-no-output'); - } - }) - .catch(error => result_block.innerText = 'Playground Communication: ' + error.message); - } - - // Syntax highlighting Configuration - hljs.configure({ - tabReplace: ' ', // 4 spaces - languages: [], // Languages used for auto-detection - }); - - const code_nodes = Array - .from(document.querySelectorAll('code')) - // Don't highlight `inline code` blocks in headers. - .filter(function(node) { - return !node.parentElement.classList.contains('header'); - }); - - if (window.ace) { - // language-rust class needs to be removed for editable - // blocks or highlightjs will capture events - code_nodes - .filter(function(node) { - return node.classList.contains('editable'); - }) - .forEach(function(block) { - block.classList.remove('language-rust'); - }); - - code_nodes - .filter(function(node) { - return !node.classList.contains('editable'); - }) - .forEach(function(block) { - hljs.highlightBlock(block); - }); - } else { - code_nodes.forEach(function(block) { - hljs.highlightBlock(block); - }); - } - - // Adding the hljs class gives code blocks the color css - // even if highlighting doesn't apply - code_nodes.forEach(function(block) { - block.classList.add('hljs'); - }); - - Array.from(document.querySelectorAll('code.hljs')).forEach(function(block) { - - const lines = Array.from(block.querySelectorAll('.boring')); - // If no lines were hidden, return - if (!lines.length) { - return; - } - block.classList.add('hide-boring'); - - const buttons = document.createElement('div'); - buttons.className = 'buttons'; - buttons.innerHTML = ''; - - // add expand button - const pre_block = block.parentNode; - pre_block.insertBefore(buttons, pre_block.firstChild); - - pre_block.querySelector('.buttons').addEventListener('click', function(e) { - if (e.target.classList.contains('fa-eye')) { - e.target.classList.remove('fa-eye'); - e.target.classList.add('fa-eye-slash'); - e.target.title = 'Hide lines'; - e.target.setAttribute('aria-label', e.target.title); - - block.classList.remove('hide-boring'); - } else if (e.target.classList.contains('fa-eye-slash')) { - e.target.classList.remove('fa-eye-slash'); - e.target.classList.add('fa-eye'); - e.target.title = 'Show hidden lines'; - e.target.setAttribute('aria-label', e.target.title); - - block.classList.add('hide-boring'); - } - }); - }); - - if (window.playground_copyable) { - Array.from(document.querySelectorAll('pre code')).forEach(function(block) { - const pre_block = block.parentNode; - if (!pre_block.classList.contains('playground')) { - let buttons = pre_block.querySelector('.buttons'); - if (!buttons) { - buttons = document.createElement('div'); - buttons.className = 'buttons'; - pre_block.insertBefore(buttons, pre_block.firstChild); - } - - const clipButton = document.createElement('button'); - clipButton.className = 'clip-button'; - clipButton.title = 'Copy to clipboard'; - clipButton.setAttribute('aria-label', clipButton.title); - clipButton.innerHTML = ''; - - buttons.insertBefore(clipButton, buttons.firstChild); - } - }); - } - - // Process playground code blocks - Array.from(document.querySelectorAll('.playground')).forEach(function(pre_block) { - // Add play button - let buttons = pre_block.querySelector('.buttons'); - if (!buttons) { - buttons = document.createElement('div'); - buttons.className = 'buttons'; - pre_block.insertBefore(buttons, pre_block.firstChild); - } - - const runCodeButton = document.createElement('button'); - runCodeButton.className = 'fa fa-play play-button'; - runCodeButton.hidden = true; - runCodeButton.title = 'Run this code'; - runCodeButton.setAttribute('aria-label', runCodeButton.title); - - buttons.insertBefore(runCodeButton, buttons.firstChild); - runCodeButton.addEventListener('click', () => { - run_rust_code(pre_block); - }); - - if (window.playground_copyable) { - const copyCodeClipboardButton = document.createElement('button'); - copyCodeClipboardButton.className = 'clip-button'; - copyCodeClipboardButton.innerHTML = ''; - copyCodeClipboardButton.title = 'Copy to clipboard'; - copyCodeClipboardButton.setAttribute('aria-label', copyCodeClipboardButton.title); - - buttons.insertBefore(copyCodeClipboardButton, buttons.firstChild); - } - - const code_block = pre_block.querySelector('code'); - if (window.ace && code_block.classList.contains('editable')) { - const undoChangesButton = document.createElement('button'); - undoChangesButton.className = 'fa fa-history reset-button'; - undoChangesButton.title = 'Undo changes'; - undoChangesButton.setAttribute('aria-label', undoChangesButton.title); - - buttons.insertBefore(undoChangesButton, buttons.firstChild); - - undoChangesButton.addEventListener('click', function() { - const editor = window.ace.edit(code_block); - editor.setValue(editor.originalCode); - editor.clearSelection(); - }); - } - }); -})(); - -(function themes() { - const html = document.querySelector('html'); - const themeToggleButton = document.getElementById('theme-toggle'); - const themePopup = document.getElementById('theme-list'); - const themeColorMetaTag = document.querySelector('meta[name="theme-color"]'); - const themeIds = []; - themePopup.querySelectorAll('button.theme').forEach(function(el) { - themeIds.push(el.id); - }); - const stylesheets = { - ayuHighlight: document.querySelector('#ayu-highlight-css'), - tomorrowNight: document.querySelector('#tomorrow-night-css'), - highlight: document.querySelector('#highlight-css'), - }; - - function showThemes() { - themePopup.style.display = 'block'; - themeToggleButton.setAttribute('aria-expanded', true); - themePopup.querySelector('button#' + get_theme()).focus(); - } - - function updateThemeSelected() { - themePopup.querySelectorAll('.theme-selected').forEach(function(el) { - el.classList.remove('theme-selected'); - }); - const selected = get_saved_theme() ?? 'default_theme'; - let element = themePopup.querySelector('button#' + selected); - if (element === null) { - // Fall back in case there is no "Default" item. - element = themePopup.querySelector('button#' + get_theme()); - } - element.classList.add('theme-selected'); - } - - function hideThemes() { - themePopup.style.display = 'none'; - themeToggleButton.setAttribute('aria-expanded', false); - themeToggleButton.focus(); - } - - function get_saved_theme() { - let theme = null; - try { - theme = localStorage.getItem('mdbook-theme'); - } catch (e) { - // ignore error. - } - return theme; - } - - function delete_saved_theme() { - localStorage.removeItem('mdbook-theme'); - } - - function get_theme() { - const theme = get_saved_theme(); - if (theme === null || theme === undefined || !themeIds.includes(theme)) { - if (typeof default_dark_theme === 'undefined') { - // A customized index.hbs might not define this, so fall back to - // old behavior of determining the default on page load. - return default_theme; - } - return window.matchMedia('(prefers-color-scheme: dark)').matches - ? default_dark_theme - : default_light_theme; - } else { - return theme; - } - } - - let previousTheme = default_theme; - function set_theme(theme, store = true) { - let ace_theme; - - if (theme === 'coal' || theme === 'navy') { - stylesheets.ayuHighlight.disabled = true; - stylesheets.tomorrowNight.disabled = false; - stylesheets.highlight.disabled = true; - - ace_theme = 'ace/theme/tomorrow_night'; - } else if (theme === 'ayu') { - stylesheets.ayuHighlight.disabled = false; - stylesheets.tomorrowNight.disabled = true; - stylesheets.highlight.disabled = true; - ace_theme = 'ace/theme/tomorrow_night'; - } else { - stylesheets.ayuHighlight.disabled = true; - stylesheets.tomorrowNight.disabled = true; - stylesheets.highlight.disabled = false; - ace_theme = 'ace/theme/dawn'; - } - - setTimeout(function() { - themeColorMetaTag.content = getComputedStyle(document.documentElement).backgroundColor; - }, 1); - - if (window.ace && window.editors) { - window.editors.forEach(function(editor) { - editor.setTheme(ace_theme); - }); - } - - if (store) { - try { - localStorage.setItem('mdbook-theme', theme); - } catch (e) { - // ignore error. - } - } - - html.classList.remove(previousTheme); - html.classList.add(theme); - previousTheme = theme; - updateThemeSelected(); - } - - const query = window.matchMedia('(prefers-color-scheme: dark)'); - query.onchange = function() { - set_theme(get_theme(), false); - }; - - // Set theme. - set_theme(get_theme(), false); - - themeToggleButton.addEventListener('click', function() { - if (themePopup.style.display === 'block') { - hideThemes(); - } else { - showThemes(); - } - }); - - themePopup.addEventListener('click', function(e) { - let theme; - if (e.target.className === 'theme') { - theme = e.target.id; - } else if (e.target.parentElement.className === 'theme') { - theme = e.target.parentElement.id; - } else { - return; - } - if (theme === 'default_theme' || theme === null) { - delete_saved_theme(); - set_theme(get_theme(), false); - } else { - set_theme(theme); - } - }); - - themePopup.addEventListener('focusout', function(e) { - // e.relatedTarget is null in Safari and Firefox on macOS (see workaround below) - if (!!e.relatedTarget && - !themeToggleButton.contains(e.relatedTarget) && - !themePopup.contains(e.relatedTarget) - ) { - hideThemes(); - } - }); - - // Should not be needed, but it works around an issue on macOS & iOS: - // https://github.com/rust-lang/mdBook/issues/628 - document.addEventListener('click', function(e) { - if (themePopup.style.display === 'block' && - !themeToggleButton.contains(e.target) && - !themePopup.contains(e.target) - ) { - hideThemes(); - } - }); - - document.addEventListener('keydown', function(e) { - if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { - return; - } - if (!themePopup.contains(e.target)) { - return; - } - - let li; - switch (e.key) { - case 'Escape': - e.preventDefault(); - hideThemes(); - break; - case 'ArrowUp': - e.preventDefault(); - li = document.activeElement.parentElement; - if (li && li.previousElementSibling) { - li.previousElementSibling.querySelector('button').focus(); - } - break; - case 'ArrowDown': - e.preventDefault(); - li = document.activeElement.parentElement; - if (li && li.nextElementSibling) { - li.nextElementSibling.querySelector('button').focus(); - } - break; - case 'Home': - e.preventDefault(); - themePopup.querySelector('li:first-child button').focus(); - break; - case 'End': - e.preventDefault(); - themePopup.querySelector('li:last-child button').focus(); - break; - } - }); -})(); - -(function sidebar() { - const body = document.querySelector('body'); - const sidebar = document.getElementById('sidebar'); - const sidebarLinks = document.querySelectorAll('#sidebar a'); - const sidebarToggleButton = document.getElementById('sidebar-toggle'); - const sidebarToggleAnchor = document.getElementById('sidebar-toggle-anchor'); - const sidebarResizeHandle = document.getElementById('sidebar-resize-handle'); - let firstContact = null; - - function showSidebar() { - body.classList.remove('sidebar-hidden'); - body.classList.add('sidebar-visible'); - Array.from(sidebarLinks).forEach(function(link) { - link.setAttribute('tabIndex', 0); - }); - sidebarToggleButton.setAttribute('aria-expanded', true); - sidebar.setAttribute('aria-hidden', false); - try { - localStorage.setItem('mdbook-sidebar', 'visible'); - } catch (e) { - // Ignore error. - } - } - - function hideSidebar() { - body.classList.remove('sidebar-visible'); - body.classList.add('sidebar-hidden'); - Array.from(sidebarLinks).forEach(function(link) { - link.setAttribute('tabIndex', -1); - }); - sidebarToggleButton.setAttribute('aria-expanded', false); - sidebar.setAttribute('aria-hidden', true); - try { - localStorage.setItem('mdbook-sidebar', 'hidden'); - } catch (e) { - // Ignore error. - } - } - - // Toggle sidebar - sidebarToggleAnchor.addEventListener('change', function sidebarToggle() { - if (sidebarToggleAnchor.checked) { - const current_width = parseInt( - document.documentElement.style.getPropertyValue('--sidebar-target-width'), 10); - if (current_width < 150) { - document.documentElement.style.setProperty('--sidebar-target-width', '150px'); - } - showSidebar(); - } else { - hideSidebar(); - } - }); - - sidebarResizeHandle.addEventListener('mousedown', initResize, false); - - function initResize() { - window.addEventListener('mousemove', resize, false); - window.addEventListener('mouseup', stopResize, false); - body.classList.add('sidebar-resizing'); - } - function resize(e) { - let pos = e.clientX - sidebar.offsetLeft; - if (pos < 20) { - hideSidebar(); - } else { - if (body.classList.contains('sidebar-hidden')) { - showSidebar(); - } - pos = Math.min(pos, window.innerWidth - 100); - document.documentElement.style.setProperty('--sidebar-target-width', pos + 'px'); - } - } - //on mouseup remove windows functions mousemove & mouseup - function stopResize() { - body.classList.remove('sidebar-resizing'); - window.removeEventListener('mousemove', resize, false); - window.removeEventListener('mouseup', stopResize, false); - } - - document.addEventListener('touchstart', function(e) { - firstContact = { - x: e.touches[0].clientX, - time: Date.now(), - }; - }, { passive: true }); - - document.addEventListener('touchmove', function(e) { - if (!firstContact) { - return; - } - - const curX = e.touches[0].clientX; - const xDiff = curX - firstContact.x, - tDiff = Date.now() - firstContact.time; - - if (tDiff < 250 && Math.abs(xDiff) >= 150) { - if (xDiff >= 0 && firstContact.x < Math.min(document.body.clientWidth * 0.25, 300)) { - showSidebar(); - } else if (xDiff < 0 && curX < 300) { - hideSidebar(); - } - - firstContact = null; - } - }, { passive: true }); -})(); - -(function chapterNavigation() { - document.addEventListener('keydown', function(e) { - if (e.altKey || e.ctrlKey || e.metaKey) { - return; - } - if (window.search && window.search.hasFocus()) { - return; - } - const html = document.querySelector('html'); - - function next() { - const nextButton = document.querySelector('.nav-chapters.next'); - if (nextButton) { - window.location.href = nextButton.href; - } - } - function prev() { - const previousButton = document.querySelector('.nav-chapters.previous'); - if (previousButton) { - window.location.href = previousButton.href; - } - } - function showHelp() { - const container = document.getElementById('mdbook-help-container'); - const overlay = document.getElementById('mdbook-help-popup'); - container.style.display = 'flex'; - - // Clicking outside the popup will dismiss it. - const mouseHandler = event => { - if (overlay.contains(event.target)) { - return; - } - if (event.button !== 0) { - return; - } - event.preventDefault(); - event.stopPropagation(); - document.removeEventListener('mousedown', mouseHandler); - hideHelp(); - }; - - // Pressing esc will dismiss the popup. - const escapeKeyHandler = event => { - if (event.key === 'Escape') { - event.preventDefault(); - event.stopPropagation(); - document.removeEventListener('keydown', escapeKeyHandler, true); - hideHelp(); - } - }; - document.addEventListener('keydown', escapeKeyHandler, true); - document.getElementById('mdbook-help-container') - .addEventListener('mousedown', mouseHandler); - } - function hideHelp() { - document.getElementById('mdbook-help-container').style.display = 'none'; - } - - // Usually needs the Shift key to be pressed - switch (e.key) { - case '?': - e.preventDefault(); - showHelp(); - break; - } - - // Rest of the keys are only active when the Shift key is not pressed - if (e.shiftKey) { - return; - } - - switch (e.key) { - case 'ArrowRight': - e.preventDefault(); - if (html.dir === 'rtl') { - prev(); - } else { - next(); - } - break; - case 'ArrowLeft': - e.preventDefault(); - if (html.dir === 'rtl') { - next(); - } else { - prev(); - } - break; - } - }); -})(); - -(function clipboard() { - const clipButtons = document.querySelectorAll('.clip-button'); - - function hideTooltip(elem) { - elem.firstChild.innerText = ''; - elem.className = 'clip-button'; - } - - function showTooltip(elem, msg) { - elem.firstChild.innerText = msg; - elem.className = 'clip-button tooltipped'; - } - - const clipboardSnippets = new ClipboardJS('.clip-button', { - text: function(trigger) { - hideTooltip(trigger); - const playground = trigger.closest('pre'); - return playground_text(playground, false); - }, - }); - - Array.from(clipButtons).forEach(function(clipButton) { - clipButton.addEventListener('mouseout', function(e) { - hideTooltip(e.currentTarget); - }); - }); - - clipboardSnippets.on('success', function(e) { - e.clearSelection(); - showTooltip(e.trigger, 'Copied!'); - }); - - clipboardSnippets.on('error', function(e) { - showTooltip(e.trigger, 'Clipboard error!'); - }); -})(); - -(function scrollToTop() { - const menuTitle = document.querySelector('.menu-title'); - - menuTitle.addEventListener('click', function() { - document.scrollingElement.scrollTo({ top: 0, behavior: 'smooth' }); - }); -})(); - -(function controllMenu() { - const menu = document.getElementById('menu-bar'); - - (function controllPosition() { - let scrollTop = document.scrollingElement.scrollTop; - let prevScrollTop = scrollTop; - const minMenuY = -menu.clientHeight - 50; - // When the script loads, the page can be at any scroll (e.g. if you reforesh it). - menu.style.top = scrollTop + 'px'; - // Same as parseInt(menu.style.top.slice(0, -2), but faster - let topCache = menu.style.top.slice(0, -2); - menu.classList.remove('sticky'); - let stickyCache = false; // Same as menu.classList.contains('sticky'), but faster - document.addEventListener('scroll', function() { - scrollTop = Math.max(document.scrollingElement.scrollTop, 0); - // `null` means that it doesn't need to be updated - let nextSticky = null; - let nextTop = null; - const scrollDown = scrollTop > prevScrollTop; - const menuPosAbsoluteY = topCache - scrollTop; - if (scrollDown) { - nextSticky = false; - if (menuPosAbsoluteY > 0) { - nextTop = prevScrollTop; - } - } else { - if (menuPosAbsoluteY > 0) { - nextSticky = true; - } else if (menuPosAbsoluteY < minMenuY) { - nextTop = prevScrollTop + minMenuY; - } - } - if (nextSticky === true && stickyCache === false) { - menu.classList.add('sticky'); - stickyCache = true; - } else if (nextSticky === false && stickyCache === true) { - menu.classList.remove('sticky'); - stickyCache = false; - } - if (nextTop !== null) { - menu.style.top = nextTop + 'px'; - topCache = nextTop; - } - prevScrollTop = scrollTop; - }, { passive: true }); - })(); - (function controllBorder() { - function updateBorder() { - if (menu.offsetTop === 0) { - menu.classList.remove('bordered'); - } else { - menu.classList.add('bordered'); - } - } - updateBorder(); - document.addEventListener('scroll', updateBorder, { passive: true }); - })(); -})(); diff --git a/docs/book/clipboard.min.js b/docs/book/clipboard.min.js deleted file mode 100644 index 99561a0..0000000 --- a/docs/book/clipboard.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * clipboard.js v2.0.4 - * https://zenorocha.github.io/clipboard.js - * - * Licensed MIT © Zeno Rocha - */ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return function(n){var o={};function r(t){if(o[t])return o[t].exports;var e=o[t]={i:t,l:!1,exports:{}};return n[t].call(e.exports,e,e.exports,r),e.l=!0,e.exports}return r.m=n,r.c=o,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=0)}([function(t,e,n){"use strict";var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=function(){function o(t,e){for(var n=0;n .hljs { - color: var(--links); -} - -/* - body-container is necessary because mobile browsers don't seem to like - overflow-x on the body tag when there is a tag. -*/ -#body-container { - /* - This is used when the sidebar pushes the body content off the side of - the screen on small screens. Without it, dragging on mobile Safari - will want to reposition the viewport in a weird way. - */ - overflow-x: clip; -} - -/* Menu Bar */ - -#menu-bar, -#menu-bar-hover-placeholder { - z-index: 101; - margin: auto calc(0px - var(--page-padding)); -} -#menu-bar { - position: relative; - display: flex; - flex-wrap: wrap; - background-color: var(--bg); - border-block-end-color: var(--bg); - border-block-end-width: 1px; - border-block-end-style: solid; -} -#menu-bar.sticky, -#menu-bar-hover-placeholder:hover + #menu-bar, -#menu-bar:hover, -html.sidebar-visible #menu-bar { - position: -webkit-sticky; - position: sticky; - top: 0 !important; -} -#menu-bar-hover-placeholder { - position: sticky; - position: -webkit-sticky; - top: 0; - height: var(--menu-bar-height); -} -#menu-bar.bordered { - border-block-end-color: var(--table-border-color); -} -#menu-bar i, #menu-bar .icon-button { - position: relative; - padding: 0 8px; - z-index: 10; - line-height: var(--menu-bar-height); - cursor: pointer; - transition: color 0.5s; -} -@media only screen and (max-width: 420px) { - #menu-bar i, #menu-bar .icon-button { - padding: 0 5px; - } -} - -.icon-button { - border: none; - background: none; - padding: 0; - color: inherit; -} -.icon-button i { - margin: 0; -} - -.right-buttons { - margin: 0 15px; -} -.right-buttons a { - text-decoration: none; -} - -.left-buttons { - display: flex; - margin: 0 5px; -} -html:not(.js) .left-buttons button { - display: none; -} - -.menu-title { - display: inline-block; - font-weight: 200; - font-size: 2.4rem; - line-height: var(--menu-bar-height); - text-align: center; - margin: 0; - flex: 1; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -.menu-title { - cursor: pointer; -} - -.menu-bar, -.menu-bar:visited, -.nav-chapters, -.nav-chapters:visited, -.mobile-nav-chapters, -.mobile-nav-chapters:visited, -.menu-bar .icon-button, -.menu-bar a i { - color: var(--icons); -} - -.menu-bar i:hover, -.menu-bar .icon-button:hover, -.nav-chapters:hover, -.mobile-nav-chapters i:hover { - color: var(--icons-hover); -} - -/* Nav Icons */ - -.nav-chapters { - font-size: 2.5em; - text-align: center; - text-decoration: none; - - position: fixed; - top: 0; - bottom: 0; - margin: 0; - max-width: 150px; - min-width: 90px; - - display: flex; - justify-content: center; - align-content: center; - flex-direction: column; - - transition: color 0.5s, background-color 0.5s; -} - -.nav-chapters:hover { - text-decoration: none; - background-color: var(--theme-hover); - transition: background-color 0.15s, color 0.15s; -} - -.nav-wrapper { - margin-block-start: 50px; - display: none; -} - -.mobile-nav-chapters { - font-size: 2.5em; - text-align: center; - text-decoration: none; - width: 90px; - border-radius: 5px; - background-color: var(--sidebar-bg); -} - -/* Only Firefox supports flow-relative values */ -.previous { float: left; } -[dir=rtl] .previous { float: right; } - -/* Only Firefox supports flow-relative values */ -.next { - float: right; - right: var(--page-padding); -} -[dir=rtl] .next { - float: left; - right: unset; - left: var(--page-padding); -} - -/* Use the correct buttons for RTL layouts*/ -[dir=rtl] .previous i.fa-angle-left:before {content:"\f105";} -[dir=rtl] .next i.fa-angle-right:before { content:"\f104"; } - -@media only screen and (max-width: 1080px) { - .nav-wide-wrapper { display: none; } - .nav-wrapper { display: block; } -} - -/* sidebar-visible */ -@media only screen and (max-width: 1380px) { - #sidebar-toggle-anchor:checked ~ .page-wrapper .nav-wide-wrapper { display: none; } - #sidebar-toggle-anchor:checked ~ .page-wrapper .nav-wrapper { display: block; } -} - -/* Inline code */ - -:not(pre) > .hljs { - display: inline; - padding: 0.1em 0.3em; - border-radius: 3px; -} - -:not(pre):not(a) > .hljs { - color: var(--inline-code-color); - overflow-x: initial; -} - -a:hover > .hljs { - text-decoration: underline; -} - -pre { - position: relative; -} -pre > .buttons { - position: absolute; - z-index: 100; - right: 0px; - top: 2px; - margin: 0px; - padding: 2px 0px; - - color: var(--sidebar-fg); - cursor: pointer; - visibility: hidden; - opacity: 0; - transition: visibility 0.1s linear, opacity 0.1s linear; -} -pre:hover > .buttons { - visibility: visible; - opacity: 1 -} -pre > .buttons :hover { - color: var(--sidebar-active); - border-color: var(--icons-hover); - background-color: var(--theme-hover); -} -pre > .buttons i { - margin-inline-start: 8px; -} -pre > .buttons button { - cursor: inherit; - margin: 0px 5px; - padding: 4px 4px 3px 5px; - font-size: 23px; - - border-style: solid; - border-width: 1px; - border-radius: 4px; - border-color: var(--icons); - background-color: var(--theme-popup-bg); - transition: 100ms; - transition-property: color,border-color,background-color; - color: var(--icons); -} - -pre > .buttons button.clip-button { - padding: 2px 4px 0px 6px; -} -pre > .buttons button.clip-button::before { - /* clipboard image from octicons (https://github.com/primer/octicons/tree/v2.0.0) MIT license - */ - content: url('data:image/svg+xml,\ -\ -\ -'); - filter: var(--copy-button-filter); -} -pre > .buttons button.clip-button:hover::before { - filter: var(--copy-button-filter-hover); -} - -@media (pointer: coarse) { - pre > .buttons button { - /* On mobile, make it easier to tap buttons. */ - padding: 0.3rem 1rem; - } - - .sidebar-resize-indicator { - /* Hide resize indicator on devices with limited accuracy */ - display: none; - } -} -pre > code { - display: block; - padding: 1rem; -} - -/* FIXME: ACE editors overlap their buttons because ACE does absolute - positioning within the code block which breaks padding. The only solution I - can think of is to move the padding to the outer pre tag (or insert a div - wrapper), but that would require fixing a whole bunch of CSS rules. -*/ -.hljs.ace_editor { - padding: 0rem 0rem; -} - -pre > .result { - margin-block-start: 10px; -} - -/* Search */ - -#searchresults a { - text-decoration: none; -} - -mark { - border-radius: 2px; - padding-block-start: 0; - padding-block-end: 1px; - padding-inline-start: 3px; - padding-inline-end: 3px; - margin-block-start: 0; - margin-block-end: -1px; - margin-inline-start: -3px; - margin-inline-end: -3px; - background-color: var(--search-mark-bg); - transition: background-color 300ms linear; - cursor: pointer; -} - -mark.fade-out { - background-color: rgba(0,0,0,0) !important; - cursor: auto; -} - -.searchbar-outer { - margin-inline-start: auto; - margin-inline-end: auto; - max-width: var(--content-max-width); -} - -#searchbar { - width: 100%; - margin-block-start: 5px; - margin-block-end: 0; - margin-inline-start: auto; - margin-inline-end: auto; - padding: 10px 16px; - transition: box-shadow 300ms ease-in-out; - border: 1px solid var(--searchbar-border-color); - border-radius: 3px; - background-color: var(--searchbar-bg); - color: var(--searchbar-fg); -} -#searchbar:focus, -#searchbar.active { - box-shadow: 0 0 3px var(--searchbar-shadow-color); -} - -.searchresults-header { - font-weight: bold; - font-size: 1em; - padding-block-start: 18px; - padding-block-end: 0; - padding-inline-start: 5px; - padding-inline-end: 0; - color: var(--searchresults-header-fg); -} - -.searchresults-outer { - margin-inline-start: auto; - margin-inline-end: auto; - max-width: var(--content-max-width); - border-block-end: 1px dashed var(--searchresults-border-color); -} - -ul#searchresults { - list-style: none; - padding-inline-start: 20px; -} -ul#searchresults li { - margin: 10px 0px; - padding: 2px; - border-radius: 2px; -} -ul#searchresults li.focus { - background-color: var(--searchresults-li-bg); -} -ul#searchresults span.teaser { - display: block; - clear: both; - margin-block-start: 5px; - margin-block-end: 0; - margin-inline-start: 20px; - margin-inline-end: 0; - font-size: 0.8em; -} -ul#searchresults span.teaser em { - font-weight: bold; - font-style: normal; -} - -/* Sidebar */ - -.sidebar { - position: fixed; - left: 0; - top: 0; - bottom: 0; - width: var(--sidebar-width); - font-size: 0.875em; - box-sizing: border-box; - -webkit-overflow-scrolling: touch; - overscroll-behavior-y: contain; - background-color: var(--sidebar-bg); - color: var(--sidebar-fg); -} -.sidebar-iframe-inner { - --padding: 10px; - - background-color: var(--sidebar-bg); - padding: var(--padding); - margin: 0; - font-size: 1.4rem; - color: var(--sidebar-fg); - min-height: calc(100vh - var(--padding) * 2); -} -.sidebar-iframe-outer { - border: none; - height: 100%; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; -} -[dir=rtl] .sidebar { left: unset; right: 0; } -.sidebar-resizing { - -moz-user-select: none; - -webkit-user-select: none; - -ms-user-select: none; - user-select: none; -} -html:not(.sidebar-resizing) .sidebar { - transition: transform 0.3s; /* Animation: slide away */ -} -.sidebar code { - line-height: 2em; -} -.sidebar .sidebar-scrollbox { - overflow-y: auto; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - padding: 10px 10px; -} -.sidebar .sidebar-resize-handle { - position: absolute; - cursor: col-resize; - width: 0; - right: calc(var(--sidebar-resize-indicator-width) * -1); - top: 0; - bottom: 0; - display: flex; - align-items: center; -} - -.sidebar-resize-handle .sidebar-resize-indicator { - width: 100%; - height: 16px; - color: var(--icons); - margin-inline-start: var(--sidebar-resize-indicator-space); - display: flex; - align-items: center; - justify-content: flex-start; -} -.sidebar-resize-handle .sidebar-resize-indicator::before { - content: ""; - width: 2px; - height: 12px; - border-left: dotted 2px currentColor; -} -.sidebar-resize-handle .sidebar-resize-indicator::after { - content: ""; - width: 2px; - height: 16px; - border-left: dotted 2px currentColor; -} - -[dir=rtl] .sidebar .sidebar-resize-handle { - left: calc(var(--sidebar-resize-indicator-width) * -1); - right: unset; -} -.js .sidebar .sidebar-resize-handle { - cursor: col-resize; - width: calc(var(--sidebar-resize-indicator-width) - var(--sidebar-resize-indicator-space)); -} -/* sidebar-hidden */ -#sidebar-toggle-anchor:not(:checked) ~ .sidebar { - transform: translateX(calc(0px - var(--sidebar-width) - var(--sidebar-resize-indicator-width))); - z-index: -1; -} -[dir=rtl] #sidebar-toggle-anchor:not(:checked) ~ .sidebar { - transform: translateX(calc(var(--sidebar-width) + var(--sidebar-resize-indicator-width))); -} -.sidebar::-webkit-scrollbar { - background: var(--sidebar-bg); -} -.sidebar::-webkit-scrollbar-thumb { - background: var(--scrollbar); -} - -/* sidebar-visible */ -#sidebar-toggle-anchor:checked ~ .page-wrapper { - transform: translateX(calc(var(--sidebar-width) + var(--sidebar-resize-indicator-width))); -} -[dir=rtl] #sidebar-toggle-anchor:checked ~ .page-wrapper { - transform: translateX(calc(0px - var(--sidebar-width) - var(--sidebar-resize-indicator-width))); -} -@media only screen and (min-width: 620px) { - #sidebar-toggle-anchor:checked ~ .page-wrapper { - transform: none; - margin-inline-start: calc(var(--sidebar-width) + var(--sidebar-resize-indicator-width)); - } - [dir=rtl] #sidebar-toggle-anchor:checked ~ .page-wrapper { - transform: none; - } -} - -.chapter { - list-style: none outside none; - padding-inline-start: 0; - line-height: 2.2em; -} - -.chapter ol { - width: 100%; -} - -.chapter li { - display: flex; - color: var(--sidebar-non-existant); -} -.chapter li a { - display: block; - padding: 0; - text-decoration: none; - color: var(--sidebar-fg); -} - -.chapter li a:hover { - color: var(--sidebar-active); -} - -.chapter li a.active { - color: var(--sidebar-active); -} - -.chapter li > a.toggle { - cursor: pointer; - display: block; - margin-inline-start: auto; - padding: 0 10px; - user-select: none; - opacity: 0.68; -} - -.chapter li > a.toggle div { - transition: transform 0.5s; -} - -/* collapse the section */ -.chapter li:not(.expanded) + li > ol { - display: none; -} - -.chapter li.chapter-item { - line-height: 1.5em; - margin-block-start: 0.6em; -} - -.chapter li.expanded > a.toggle div { - transform: rotate(90deg); -} - -.spacer { - width: 100%; - height: 3px; - margin: 5px 0px; -} -.chapter .spacer { - background-color: var(--sidebar-spacer); -} - -@media (-moz-touch-enabled: 1), (pointer: coarse) { - .chapter li a { padding: 5px 0; } - .spacer { margin: 10px 0; } -} - -.section { - list-style: none outside none; - padding-inline-start: 20px; - line-height: 1.9em; -} - -/* Theme Menu Popup */ - -.theme-popup { - position: absolute; - left: 10px; - top: var(--menu-bar-height); - z-index: 1000; - border-radius: 4px; - font-size: 0.7em; - color: var(--fg); - background: var(--theme-popup-bg); - border: 1px solid var(--theme-popup-border); - margin: 0; - padding: 0; - list-style: none; - display: none; - /* Don't let the children's background extend past the rounded corners. */ - overflow: hidden; -} -[dir=rtl] .theme-popup { left: unset; right: 10px; } -.theme-popup .default { - color: var(--icons); -} -.theme-popup .theme { - width: 100%; - border: 0; - margin: 0; - padding: 2px 20px; - line-height: 25px; - white-space: nowrap; - text-align: start; - cursor: pointer; - color: inherit; - background: inherit; - font-size: inherit; -} -.theme-popup .theme:hover { - background-color: var(--theme-hover); -} - -.theme-selected::before { - display: inline-block; - content: "✓"; - margin-inline-start: -14px; - width: 14px; -} - -/* The container for the help popup that covers the whole window. */ -#mdbook-help-container { - /* Position and size for the whole window. */ - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - /* This uses flex layout (which is set in book.js), and centers the popup - in the window.*/ - display: none; - align-items: center; - justify-content: center; - z-index: 1000; - /* Dim out the book while the popup is visible. */ - background: var(--overlay-bg); -} - -/* The popup help box. */ -#mdbook-help-popup { - box-shadow: 0 4px 24px rgba(0,0,0,0.15); - min-width: 300px; - max-width: 500px; - width: 100%; - box-sizing: border-box; - display: flex; - flex-direction: column; - align-items: center; - background-color: var(--bg); - color: var(--fg); - border-width: 1px; - border-color: var(--theme-popup-border); - border-style: solid; - border-radius: 8px; - padding: 10px; -} - -.mdbook-help-title { - text-align: center; - /* mdbook's margin for h2 is way too large. */ - margin: 10px; -} diff --git a/docs/book/css/general.css b/docs/book/css/general.css deleted file mode 100644 index 9946cfc..0000000 --- a/docs/book/css/general.css +++ /dev/null @@ -1,279 +0,0 @@ -/* Base styles and content styles */ - -:root { - /* Browser default font-size is 16px, this way 1 rem = 10px */ - font-size: 62.5%; - color-scheme: var(--color-scheme); -} - -html { - font-family: "Open Sans", sans-serif; - color: var(--fg); - background-color: var(--bg); - text-size-adjust: none; - -webkit-text-size-adjust: none; -} - -body { - margin: 0; - font-size: 1.6rem; - overflow-x: hidden; -} - -code { - font-family: var(--mono-font) !important; - font-size: var(--code-font-size); - direction: ltr !important; -} - -/* make long words/inline code not x overflow */ -main { - overflow-wrap: break-word; -} - -/* make wide tables scroll if they overflow */ -.table-wrapper { - overflow-x: auto; -} - -/* Don't change font size in headers. */ -h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { - font-size: unset; -} - -.left { float: left; } -.right { float: right; } -.boring { opacity: 0.6; } -.hide-boring .boring { display: none; } -.hidden { display: none !important; } - -h2, h3 { margin-block-start: 2.5em; } -h4, h5 { margin-block-start: 2em; } - -.header + .header h3, -.header + .header h4, -.header + .header h5 { - margin-block-start: 1em; -} - -h1:target::before, -h2:target::before, -h3:target::before, -h4:target::before, -h5:target::before, -h6:target::before { - display: inline-block; - content: "»"; - margin-inline-start: -30px; - width: 30px; -} - -/* This is broken on Safari as of version 14, but is fixed - in Safari Technology Preview 117 which I think will be Safari 14.2. - https://bugs.webkit.org/show_bug.cgi?id=218076 -*/ -:target { - /* Safari does not support logical properties */ - scroll-margin-top: calc(var(--menu-bar-height) + 0.5em); -} - -.page { - outline: 0; - padding: 0 var(--page-padding); - margin-block-start: calc(0px - var(--menu-bar-height)); /* Compensate for the #menu-bar-hover-placeholder */ -} -.page-wrapper { - box-sizing: border-box; - background-color: var(--bg); -} -.no-js .page-wrapper, -.js:not(.sidebar-resizing) .page-wrapper { - transition: margin-left 0.3s ease, transform 0.3s ease; /* Animation: slide away */ -} -[dir=rtl] .js:not(.sidebar-resizing) .page-wrapper { - transition: margin-right 0.3s ease, transform 0.3s ease; /* Animation: slide away */ -} - -.content { - overflow-y: auto; - padding: 0 5px 50px 5px; -} -.content main { - margin-inline-start: auto; - margin-inline-end: auto; - max-width: var(--content-max-width); -} -.content p { line-height: 1.45em; } -.content ol { line-height: 1.45em; } -.content ul { line-height: 1.45em; } -.content a { text-decoration: none; } -.content a:hover { text-decoration: underline; } -.content img, .content video { max-width: 100%; } -.content .header:link, -.content .header:visited { - color: var(--fg); -} -.content .header:link, -.content .header:visited:hover { - text-decoration: none; -} - -table { - margin: 0 auto; - border-collapse: collapse; -} -table td { - padding: 3px 20px; - border: 1px var(--table-border-color) solid; -} -table thead { - background: var(--table-header-bg); -} -table thead td { - font-weight: 700; - border: none; -} -table thead th { - padding: 3px 20px; -} -table thead tr { - border: 1px var(--table-header-bg) solid; -} -/* Alternate background colors for rows */ -table tbody tr:nth-child(2n) { - background: var(--table-alternate-bg); -} - - -blockquote { - margin: 20px 0; - padding: 0 20px; - color: var(--fg); - background-color: var(--quote-bg); - border-block-start: .1em solid var(--quote-border); - border-block-end: .1em solid var(--quote-border); -} - -.warning { - margin: 20px; - padding: 0 20px; - border-inline-start: 2px solid var(--warning-border); -} - -.warning:before { - position: absolute; - width: 3rem; - height: 3rem; - margin-inline-start: calc(-1.5rem - 21px); - content: "ⓘ"; - text-align: center; - background-color: var(--bg); - color: var(--warning-border); - font-weight: bold; - font-size: 2rem; -} - -blockquote .warning:before { - background-color: var(--quote-bg); -} - -kbd { - background-color: var(--table-border-color); - border-radius: 4px; - border: solid 1px var(--theme-popup-border); - box-shadow: inset 0 -1px 0 var(--theme-hover); - display: inline-block; - font-size: var(--code-font-size); - font-family: var(--mono-font); - line-height: 10px; - padding: 4px 5px; - vertical-align: middle; -} - -sup { - /* Set the line-height for superscript and footnote references so that there - isn't an awkward space appearing above lines that contain the footnote. - - See https://github.com/rust-lang/mdBook/pull/2443#discussion_r1813773583 - for an explanation. - */ - line-height: 0; -} - -.footnote-definition { - font-size: 0.9em; -} -/* The default spacing for a list is a little too large. */ -.footnote-definition ul, -.footnote-definition ol { - padding-left: 20px; -} -.footnote-definition > li { - /* Required to position the ::before target */ - position: relative; -} -.footnote-definition > li:target { - scroll-margin-top: 50vh; -} -.footnote-reference:target { - scroll-margin-top: 50vh; -} -/* Draws a border around the footnote (including the marker) when it is selected. - TODO: If there are multiple linkbacks, highlight which one you just came - from so you know which one to click. -*/ -.footnote-definition > li:target::before { - border: 2px solid var(--footnote-highlight); - border-radius: 6px; - position: absolute; - top: -8px; - right: -8px; - bottom: -8px; - left: -32px; - pointer-events: none; - content: ""; -} -/* Pulses the footnote reference so you can quickly see where you left off reading. - This could use some improvement. -*/ -@media not (prefers-reduced-motion) { - .footnote-reference:target { - animation: fn-highlight 0.8s; - border-radius: 2px; - } - - @keyframes fn-highlight { - from { - background-color: var(--footnote-highlight); - } - } -} - -.tooltiptext { - position: absolute; - visibility: hidden; - color: #fff; - background-color: #333; - transform: translateX(-50%); /* Center by moving tooltip 50% of its width left */ - left: -8px; /* Half of the width of the icon */ - top: -35px; - font-size: 0.8em; - text-align: center; - border-radius: 6px; - padding: 5px 8px; - margin: 5px; - z-index: 1000; -} -.tooltipped .tooltiptext { - visibility: visible; -} - -.chapter li.part-title { - color: var(--sidebar-fg); - margin: 5px 0px; - font-weight: bold; -} - -.result-no-output { - font-style: italic; -} diff --git a/docs/book/css/print.css b/docs/book/css/print.css deleted file mode 100644 index 80ec3a5..0000000 --- a/docs/book/css/print.css +++ /dev/null @@ -1,50 +0,0 @@ - -#sidebar, -#menu-bar, -.nav-chapters, -.mobile-nav-chapters { - display: none; -} - -#page-wrapper.page-wrapper { - transform: none !important; - margin-inline-start: 0px; - overflow-y: initial; -} - -#content { - max-width: none; - margin: 0; - padding: 0; -} - -.page { - overflow-y: initial; -} - -code { - direction: ltr !important; -} - -pre > .buttons { - z-index: 2; -} - -a, a:visited, a:active, a:hover { - color: #4183c4; - text-decoration: none; -} - -h1, h2, h3, h4, h5, h6 { - page-break-inside: avoid; - page-break-after: avoid; -} - -pre, code { - page-break-inside: avoid; - white-space: pre-wrap; -} - -.fa { - display: none !important; -} diff --git a/docs/book/css/variables.css b/docs/book/css/variables.css deleted file mode 100644 index 5742d24..0000000 --- a/docs/book/css/variables.css +++ /dev/null @@ -1,330 +0,0 @@ - -/* Globals */ - -:root { - --sidebar-target-width: 300px; - --sidebar-width: min(var(--sidebar-target-width), 80vw); - --sidebar-resize-indicator-width: 8px; - --sidebar-resize-indicator-space: 2px; - --page-padding: 15px; - --content-max-width: 750px; - --menu-bar-height: 50px; - --mono-font: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace; - --code-font-size: 0.875em; /* please adjust the ace font size accordingly in editor.js */ -} - -/* Themes */ - -.ayu { - --bg: hsl(210, 25%, 8%); - --fg: #c5c5c5; - - --sidebar-bg: #14191f; - --sidebar-fg: #c8c9db; - --sidebar-non-existant: #5c6773; - --sidebar-active: #ffb454; - --sidebar-spacer: #2d334f; - - --scrollbar: var(--sidebar-fg); - - --icons: #737480; - --icons-hover: #b7b9cc; - - --links: #0096cf; - - --inline-code-color: #ffb454; - - --theme-popup-bg: #14191f; - --theme-popup-border: #5c6773; - --theme-hover: #191f26; - - --quote-bg: hsl(226, 15%, 17%); - --quote-border: hsl(226, 15%, 22%); - - --warning-border: #ff8e00; - - --table-border-color: hsl(210, 25%, 13%); - --table-header-bg: hsl(210, 25%, 28%); - --table-alternate-bg: hsl(210, 25%, 11%); - - --searchbar-border-color: #848484; - --searchbar-bg: #424242; - --searchbar-fg: #fff; - --searchbar-shadow-color: #d4c89f; - --searchresults-header-fg: #666; - --searchresults-border-color: #888; - --searchresults-li-bg: #252932; - --search-mark-bg: #e3b171; - - --color-scheme: dark; - - /* Same as `--icons` */ - --copy-button-filter: invert(45%) sepia(6%) saturate(621%) hue-rotate(198deg) brightness(99%) contrast(85%); - /* Same as `--sidebar-active` */ - --copy-button-filter-hover: invert(68%) sepia(55%) saturate(531%) hue-rotate(341deg) brightness(104%) contrast(101%); - - --footnote-highlight: #2668a6; - - --overlay-bg: rgba(33, 40, 48, 0.4); -} - -.coal { - --bg: hsl(200, 7%, 8%); - --fg: #98a3ad; - - --sidebar-bg: #292c2f; - --sidebar-fg: #a1adb8; - --sidebar-non-existant: #505254; - --sidebar-active: #3473ad; - --sidebar-spacer: #393939; - - --scrollbar: var(--sidebar-fg); - - --icons: #43484d; - --icons-hover: #b3c0cc; - - --links: #2b79a2; - - --inline-code-color: #c5c8c6; - - --theme-popup-bg: #141617; - --theme-popup-border: #43484d; - --theme-hover: #1f2124; - - --quote-bg: hsl(234, 21%, 18%); - --quote-border: hsl(234, 21%, 23%); - - --warning-border: #ff8e00; - - --table-border-color: hsl(200, 7%, 13%); - --table-header-bg: hsl(200, 7%, 28%); - --table-alternate-bg: hsl(200, 7%, 11%); - - --searchbar-border-color: #aaa; - --searchbar-bg: #b7b7b7; - --searchbar-fg: #000; - --searchbar-shadow-color: #aaa; - --searchresults-header-fg: #666; - --searchresults-border-color: #98a3ad; - --searchresults-li-bg: #2b2b2f; - --search-mark-bg: #355c7d; - - --color-scheme: dark; - - /* Same as `--icons` */ - --copy-button-filter: invert(26%) sepia(8%) saturate(575%) hue-rotate(169deg) brightness(87%) contrast(82%); - /* Same as `--sidebar-active` */ - --copy-button-filter-hover: invert(36%) sepia(70%) saturate(503%) hue-rotate(167deg) brightness(98%) contrast(89%); - - --footnote-highlight: #4079ae; - - --overlay-bg: rgba(33, 40, 48, 0.4); -} - -.light, html:not(.js) { - --bg: hsl(0, 0%, 100%); - --fg: hsl(0, 0%, 0%); - - --sidebar-bg: #fafafa; - --sidebar-fg: hsl(0, 0%, 0%); - --sidebar-non-existant: #aaaaaa; - --sidebar-active: #1f1fff; - --sidebar-spacer: #f4f4f4; - - --scrollbar: #8F8F8F; - - --icons: #747474; - --icons-hover: #000000; - - --links: #20609f; - - --inline-code-color: #301900; - - --theme-popup-bg: #fafafa; - --theme-popup-border: #cccccc; - --theme-hover: #e6e6e6; - - --quote-bg: hsl(197, 37%, 96%); - --quote-border: hsl(197, 37%, 91%); - - --warning-border: #ff8e00; - - --table-border-color: hsl(0, 0%, 95%); - --table-header-bg: hsl(0, 0%, 80%); - --table-alternate-bg: hsl(0, 0%, 97%); - - --searchbar-border-color: #aaa; - --searchbar-bg: #fafafa; - --searchbar-fg: #000; - --searchbar-shadow-color: #aaa; - --searchresults-header-fg: #666; - --searchresults-border-color: #888; - --searchresults-li-bg: #e4f2fe; - --search-mark-bg: #a2cff5; - - --color-scheme: light; - - /* Same as `--icons` */ - --copy-button-filter: invert(45.49%); - /* Same as `--sidebar-active` */ - --copy-button-filter-hover: invert(14%) sepia(93%) saturate(4250%) hue-rotate(243deg) brightness(99%) contrast(130%); - - --footnote-highlight: #7e7eff; - - --overlay-bg: rgba(200, 200, 205, 0.4); -} - -.navy { - --bg: hsl(226, 23%, 11%); - --fg: #bcbdd0; - - --sidebar-bg: #282d3f; - --sidebar-fg: #c8c9db; - --sidebar-non-existant: #505274; - --sidebar-active: #2b79a2; - --sidebar-spacer: #2d334f; - - --scrollbar: var(--sidebar-fg); - - --icons: #737480; - --icons-hover: #b7b9cc; - - --links: #2b79a2; - - --inline-code-color: #c5c8c6; - - --theme-popup-bg: #161923; - --theme-popup-border: #737480; - --theme-hover: #282e40; - - --quote-bg: hsl(226, 15%, 17%); - --quote-border: hsl(226, 15%, 22%); - - --warning-border: #ff8e00; - - --table-border-color: hsl(226, 23%, 16%); - --table-header-bg: hsl(226, 23%, 31%); - --table-alternate-bg: hsl(226, 23%, 14%); - - --searchbar-border-color: #aaa; - --searchbar-bg: #aeaec6; - --searchbar-fg: #000; - --searchbar-shadow-color: #aaa; - --searchresults-header-fg: #5f5f71; - --searchresults-border-color: #5c5c68; - --searchresults-li-bg: #242430; - --search-mark-bg: #a2cff5; - - --color-scheme: dark; - - /* Same as `--icons` */ - --copy-button-filter: invert(51%) sepia(10%) saturate(393%) hue-rotate(198deg) brightness(86%) contrast(87%); - /* Same as `--sidebar-active` */ - --copy-button-filter-hover: invert(46%) sepia(20%) saturate(1537%) hue-rotate(156deg) brightness(85%) contrast(90%); - - --footnote-highlight: #4079ae; - - --overlay-bg: rgba(33, 40, 48, 0.4); -} - -.rust { - --bg: hsl(60, 9%, 87%); - --fg: #262625; - - --sidebar-bg: #3b2e2a; - --sidebar-fg: #c8c9db; - --sidebar-non-existant: #505254; - --sidebar-active: #e69f67; - --sidebar-spacer: #45373a; - - --scrollbar: var(--sidebar-fg); - - --icons: #737480; - --icons-hover: #262625; - - --links: #2b79a2; - - --inline-code-color: #6e6b5e; - - --theme-popup-bg: #e1e1db; - --theme-popup-border: #b38f6b; - --theme-hover: #99908a; - - --quote-bg: hsl(60, 5%, 75%); - --quote-border: hsl(60, 5%, 70%); - - --warning-border: #ff8e00; - - --table-border-color: hsl(60, 9%, 82%); - --table-header-bg: #b3a497; - --table-alternate-bg: hsl(60, 9%, 84%); - - --searchbar-border-color: #aaa; - --searchbar-bg: #fafafa; - --searchbar-fg: #000; - --searchbar-shadow-color: #aaa; - --searchresults-header-fg: #666; - --searchresults-border-color: #888; - --searchresults-li-bg: #dec2a2; - --search-mark-bg: #e69f67; - - /* Same as `--icons` */ - --copy-button-filter: invert(51%) sepia(10%) saturate(393%) hue-rotate(198deg) brightness(86%) contrast(87%); - /* Same as `--sidebar-active` */ - --copy-button-filter-hover: invert(77%) sepia(16%) saturate(1798%) hue-rotate(328deg) brightness(98%) contrast(83%); - - --footnote-highlight: #d3a17a; - - --overlay-bg: rgba(150, 150, 150, 0.25); -} - -@media (prefers-color-scheme: dark) { - html:not(.js) { - --bg: hsl(200, 7%, 8%); - --fg: #98a3ad; - - --sidebar-bg: #292c2f; - --sidebar-fg: #a1adb8; - --sidebar-non-existant: #505254; - --sidebar-active: #3473ad; - --sidebar-spacer: #393939; - - --scrollbar: var(--sidebar-fg); - - --icons: #43484d; - --icons-hover: #b3c0cc; - - --links: #2b79a2; - - --inline-code-color: #c5c8c6; - - --theme-popup-bg: #141617; - --theme-popup-border: #43484d; - --theme-hover: #1f2124; - - --quote-bg: hsl(234, 21%, 18%); - --quote-border: hsl(234, 21%, 23%); - - --warning-border: #ff8e00; - - --table-border-color: hsl(200, 7%, 13%); - --table-header-bg: hsl(200, 7%, 28%); - --table-alternate-bg: hsl(200, 7%, 11%); - - --searchbar-border-color: #aaa; - --searchbar-bg: #b7b7b7; - --searchbar-fg: #000; - --searchbar-shadow-color: #aaa; - --searchresults-header-fg: #666; - --searchresults-border-color: #98a3ad; - --searchresults-li-bg: #2b2b2f; - --search-mark-bg: #355c7d; - - --color-scheme: dark; - - /* Same as `--icons` */ - --copy-button-filter: invert(26%) sepia(8%) saturate(575%) hue-rotate(169deg) brightness(87%) contrast(82%); - /* Same as `--sidebar-active` */ - --copy-button-filter-hover: invert(36%) sepia(70%) saturate(503%) hue-rotate(167deg) brightness(98%) contrast(89%); - } -} diff --git a/docs/book/development/build-system.html b/docs/book/development/build-system.html deleted file mode 100644 index fd95dc3..0000000 --- a/docs/book/development/build-system.html +++ /dev/null @@ -1,608 +0,0 @@ - - - - - - Build System - Provisioning Platform Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-

Keyboard shortcuts

-
-

Press or to navigate between chapters

-

Press S or / to search in the book

-

Press ? to show this help

-

Press Esc to hide this help

-
-
-
-
- - - - - - - - - - - - - -
- -
- - - - - - - - -
-
-

Build System

-

Building, testing, and packaging the Provisioning platform and extensions with Cargo, Just, and Nickel.

-

Build Tools

-
- - - - -
ToolPurposeVersion Required
CargoRust compilation and testingLatest stable
JustTask runner for common operationsLatest
NickelSchema validation and type checking1.15.1+
NushellScript execution and testing0.109.0+
-
-

Building Platform Services

-

Build All Services

-
# Build all Rust services in release mode
-cd provisioning/platform
-cargo build --release --workspace
-
-# Or using just task runner
-just build-platform
-
-

Binary outputs in target/release/:

-
    -
  • provisioning-orchestrator
  • -
  • provisioning-control-center
  • -
  • provisioning-vault-service
  • -
  • provisioning-installer
  • -
-

Build Individual Service

-
# Orchestrator service
-cd provisioning/platform/crates/orchestrator
-cargo build --release
-
-# Control Center service
-cd provisioning/platform/crates/control-center
-cargo build --release
-
-# Development build (faster compilation)
-cargo build
-
-

Testing

-

Run All Tests

-
# Rust unit and integration tests
-cargo test --workspace
-
-# Nushell script tests
-just test-nushell
-
-# Complete test suite
-just test-all
-
-

Test Specific Component

-
# Test orchestrator crate
-cargo test -p provisioning-orchestrator
-
-# Test with output visible
-cargo test -p provisioning-orchestrator -- --nocapture
-
-# Test specific function
-cargo test -p provisioning-orchestrator test_workflow_creation
-
-# Run tests matching pattern
-cargo test workflow
-
-

Security Tests

-
# Run 350+ security test cases
-cargo test -p security --test '*'
-
-# Specific security component
-cargo test -p security authentication
-cargo test -p security authorization
-cargo test -p security kms
-
-

Code Quality

-

Formatting

-
# Format all Rust code
-cargo fmt --all
-
-# Check formatting without modifying
-cargo fmt --all -- --check
-
-# Format Nickel schemas
-nickel fmt provisioning/schemas/**/*.ncl
-
-

Linting

-
# Run Clippy linter
-cargo clippy --all -- -D warnings
-
-# Auto-fix Clippy warnings
-cargo clippy --all --fix
-
-# Clippy with all features enabled
-cargo clippy --all --all-features -- -D warnings
-
-

Nickel Validation

-
# Type check Nickel schemas
-nickel typecheck provisioning/schemas/main.ncl
-
-# Evaluate schema
-nickel eval provisioning/schemas/main.ncl
-
-# Format Nickel files
-nickel fmt provisioning/schemas/**/*.ncl
-
-

Continuous Integration

-

The platform uses automated CI workflows for quality assurance.

-

GitHub Actions Pipeline

-

Key CI jobs:

-
1. Rust Build and Test
-   - cargo build --release --workspace
-   - cargo test --workspace
-   - cargo clippy --all -- -D warnings
-
-2. Nushell Validation
-   - nu --check core/cli/provisioning
-   - Run Nushell test suite
-
-3. Nickel Schema Validation
-   - nickel typecheck schemas/main.ncl
-   - Validate all schema files
-
-4. Security Tests
-   - Run 350+ security test cases
-   - Vulnerability scanning
-
-5. Documentation Build
-   - mdbook build docs
-   - Markdown linting
-
-

Packaging and Distribution

-

Create Release Package

-
# Build optimized binaries
-cargo build --release --workspace
-
-# Strip debug symbols (reduce binary size)
-strip target/release/provisioning-orchestrator
-strip target/release/provisioning-control-center
-
-# Create distribution archive
-just package
-
-

Package Structure

-
provisioning-5.0.0-linux-x86_64.tar.gz
-├── bin/
-│   ├── provisioning                    # Main CLI
-│   ├── provisioning-orchestrator       # Orchestrator service
-│   ├── provisioning-control-center     # Control Center
-│   ├── provisioning-vault-service      # Vault service
-│   └── provisioning-installer          # Platform installer
-├── lib/
-│   └── nulib/                          # Nushell libraries
-├── schemas/                            # Nickel schemas
-├── config/
-│   └── config.defaults.toml            # Default configuration
-├── systemd/
-│   └── *.service                       # Systemd unit files
-└── README.md
-
-

Cross-Platform Builds

-

Supported Targets

-
# Linux x86_64 (primary platform)
-cargo build --release --target x86_64-unknown-linux-gnu
-
-# Linux ARM64 (Raspberry Pi, cloud ARM instances)
-cargo build --release --target aarch64-unknown-linux-gnu
-
-# macOS x86_64
-cargo build --release --target x86_64-apple-darwin
-
-# macOS ARM64 (Apple Silicon)
-cargo build --release --target aarch64-apple-darwin
-
-

Cross-Compilation Setup

-
# Add target architectures
-rustup target add x86_64-unknown-linux-gnu
-rustup target add aarch64-unknown-linux-gnu
-
-# Install cross-compilation tool
-cargo install cross
-
-# Cross-compile with Docker
-cross build --release --target aarch64-unknown-linux-gnu
-
-

Just Task Runner

-

Common build tasks in justfile:

-
# Build all components
-build-all: build-platform build-plugins
-
-# Build platform services
-build-platform:
-    cd platform && cargo build --release --workspace
-
-# Run all tests
-test: test-rust test-nushell test-integration
-
-# Test Rust code
-test-rust:
-    cargo test --workspace
-
-# Test Nushell scripts
-test-nushell:
-    nu scripts/test/test_all.nu
-
-# Format all code
-fmt:
-    cargo fmt --all
-    nickel fmt schemas/**/*.ncl
-
-# Lint all code
-lint:
-    cargo clippy --all -- -D warnings
-    nickel typecheck schemas/main.ncl
-
-# Create release package
-package:
-    ./scripts/package.nu
-
-# Clean build artifacts
-clean:
-    cargo clean
-    rm -rf target/
-
-

Usage examples:

-
just build-all     # Build everything
-just test          # Run all tests
-just fmt           # Format code
-just lint          # Run linters
-just package       # Create distribution
-just clean         # Remove artifacts
-
-

Performance Optimization

-

Release Builds

-
# Cargo.toml
-[profile.release]
-opt-level = 3              # Maximum optimization
-lto = "fat"                # Link-time optimization
-codegen-units = 1          # Better optimization, slower compile
-strip = true               # Strip debug symbols
-panic = "abort"            # Smaller binary size
-
-

Build Time Optimization

-
# Cargo.toml
-[profile.dev]
-opt-level = 1              # Basic optimization
-incremental = true         # Faster recompilation
-
-

Speed up compilation:

-
# Use faster linker (Linux)
-sudo apt install lld
-export RUSTFLAGS="-C link-arg=-fuse-ld=lld"
-
-# Parallel compilation
-cargo build -j 8
-
-# Use cargo-watch for auto-rebuild
-cargo install cargo-watch
-cargo watch -x build
-
-

Development Workflow

- -
# 1. Start development
-just clean
-just build-all
-
-# 2. Make changes to code
-
-# 3. Test changes quickly
-cargo check                # Fast syntax check
-cargo test <specific-test> # Test specific functionality
-
-# 4. Full validation before commit
-just fmt
-just lint
-just test
-
-# 5. Create package for testing
-just package
-
-

Hot Reload Development

-
# Auto-rebuild on file changes
-cargo watch -x build
-
-# Auto-test on changes
-cargo watch -x test
-
-# Run service with auto-reload
-cargo watch -x 'run --bin provisioning-orchestrator'
-
-

Debugging Builds

-

Debug Information

-
# Build with full debug info
-cargo build
-
-# Build with debug info in release mode
-cargo build --release --profile release-with-debug
-
-# Run with backtraces
-RUST_BACKTRACE=1 cargo run
-RUST_BACKTRACE=full cargo run
-
-

Build Verbosity

-
# Verbose build output
-cargo build -vv
-
-# Show build commands
-cargo build -vvv
-
-# Show timing information
-cargo build --timings
-
-

Dependency Tree

-
# View dependency tree
-cargo tree
-
-# Duplicate dependencies
-cargo tree --duplicates
-
-# Build graph visualization
-cargo depgraph | dot -Tpng > deps.png
-
-

Best Practices

-
    -
  • Always run just test before committing
  • -
  • Use cargo fmt and cargo clippy for code quality
  • -
  • Test on multiple platforms before release
  • -
  • Strip binaries for production distributions
  • -
  • Version binaries with semantic versioning
  • -
  • Cache dependencies in CI/CD
  • -
  • Use release profile for production builds
  • -
  • Document build requirements in README
  • -
  • Automate common tasks with Just
  • -
  • Keep build times reasonable (<5 min)
  • -
-

Troubleshooting

-

Common Build Issues

-

Compilation fails with linker error:

-
# Install build dependencies
-sudo apt install build-essential pkg-config libssl-dev
-
-

Out of memory during build:

-
# Reduce parallel jobs
-cargo build -j 2
-
-# Use more swap space
-sudo fallocate -l 8G /swapfile
-sudo mkswap /swapfile
-sudo swapon /swapfile
-
-

Clippy warnings:

-
# Fix automatically where possible
-cargo clippy --all --fix
-
-# Allow specific lints temporarily
-#[allow(clippy::too_many_arguments)]
-
- -
    -
  • Testing - Testing strategies and procedures
  • -
  • Contributing - Contribution guidelines including build requirements
  • -
- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- - diff --git a/docs/book/elasticlunr.min.js b/docs/book/elasticlunr.min.js deleted file mode 100644 index 06cc9b3..0000000 --- a/docs/book/elasticlunr.min.js +++ /dev/null @@ -1,10 +0,0 @@ -/** - * elasticlunr - http://weixsong.github.io - * Lightweight full-text search engine in Javascript for browser search and offline search. - 0.9.5 - * - * Copyright (C) 2017 Oliver Nightingale - * Copyright (C) 2017 Wei Song - * MIT Licensed - * @license - */ -!function(){function e(e){if(null===e||"object"!=typeof e)return e;var t=e.constructor();for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t}var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.9.5",lunr=t,t.utils={},t.utils.warn=function(e){return function(t){e.console&&console.warn&&console.warn(t)}}(this),t.utils.toString=function(e){return void 0===e||null===e?"":e.toString()},t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var e=Array.prototype.slice.call(arguments),t=e.pop(),n=e;if("function"!=typeof t)throw new TypeError("last argument must be a function");n.forEach(function(e){this.hasHandler(e)||(this.events[e]=[]),this.events[e].push(t)},this)},t.EventEmitter.prototype.removeListener=function(e,t){if(this.hasHandler(e)){var n=this.events[e].indexOf(t);-1!==n&&(this.events[e].splice(n,1),0==this.events[e].length&&delete this.events[e])}},t.EventEmitter.prototype.emit=function(e){if(this.hasHandler(e)){var t=Array.prototype.slice.call(arguments,1);this.events[e].forEach(function(e){e.apply(void 0,t)},this)}},t.EventEmitter.prototype.hasHandler=function(e){return e in this.events},t.tokenizer=function(e){if(!arguments.length||null===e||void 0===e)return[];if(Array.isArray(e)){var n=e.filter(function(e){return null===e||void 0===e?!1:!0});n=n.map(function(e){return t.utils.toString(e).toLowerCase()});var i=[];return n.forEach(function(e){var n=e.split(t.tokenizer.seperator);i=i.concat(n)},this),i}return e.toString().trim().toLowerCase().split(t.tokenizer.seperator)},t.tokenizer.defaultSeperator=/[\s\-]+/,t.tokenizer.seperator=t.tokenizer.defaultSeperator,t.tokenizer.setSeperator=function(e){null!==e&&void 0!==e&&"object"==typeof e&&(t.tokenizer.seperator=e)},t.tokenizer.resetSeperator=function(){t.tokenizer.seperator=t.tokenizer.defaultSeperator},t.tokenizer.getSeperator=function(){return t.tokenizer.seperator},t.Pipeline=function(){this._queue=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in t.Pipeline.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[n]=e},t.Pipeline.getRegisteredFunction=function(e){return e in t.Pipeline.registeredFunctions!=!0?null:t.Pipeline.registeredFunctions[e]},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var i=t.Pipeline.getRegisteredFunction(e);if(!i)throw new Error("Cannot load un-registered function: "+e);n.add(i)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._queue.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._queue.indexOf(e);if(-1===i)throw new Error("Cannot find existingFn");this._queue.splice(i+1,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._queue.indexOf(e);if(-1===i)throw new Error("Cannot find existingFn");this._queue.splice(i,0,n)},t.Pipeline.prototype.remove=function(e){var t=this._queue.indexOf(e);-1!==t&&this._queue.splice(t,1)},t.Pipeline.prototype.run=function(e){for(var t=[],n=e.length,i=this._queue.length,o=0;n>o;o++){for(var r=e[o],s=0;i>s&&(r=this._queue[s](r,o,e),void 0!==r&&null!==r);s++);void 0!==r&&null!==r&&t.push(r)}return t},t.Pipeline.prototype.reset=function(){this._queue=[]},t.Pipeline.prototype.get=function(){return this._queue},t.Pipeline.prototype.toJSON=function(){return this._queue.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.DocumentStore,this.index={},this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var e=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,e)},t.Index.prototype.off=function(e,t){return this.eventEmitter.removeListener(e,t)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;n._fields=e.fields,n._ref=e.ref,n.documentStore=t.DocumentStore.load(e.documentStore),n.pipeline=t.Pipeline.load(e.pipeline),n.index={};for(var i in e.index)n.index[i]=t.InvertedIndex.load(e.index[i]);return n},t.Index.prototype.addField=function(e){return this._fields.push(e),this.index[e]=new t.InvertedIndex,this},t.Index.prototype.setRef=function(e){return this._ref=e,this},t.Index.prototype.saveDocument=function(e){return this.documentStore=new t.DocumentStore(e),this},t.Index.prototype.addDoc=function(e,n){if(e){var n=void 0===n?!0:n,i=e[this._ref];this.documentStore.addDoc(i,e),this._fields.forEach(function(n){var o=this.pipeline.run(t.tokenizer(e[n]));this.documentStore.addFieldLength(i,n,o.length);var r={};o.forEach(function(e){e in r?r[e]+=1:r[e]=1},this);for(var s in r){var u=r[s];u=Math.sqrt(u),this.index[n].addToken(s,{ref:i,tf:u})}},this),n&&this.eventEmitter.emit("add",e,this)}},t.Index.prototype.removeDocByRef=function(e){if(e&&this.documentStore.isDocStored()!==!1&&this.documentStore.hasDoc(e)){var t=this.documentStore.getDoc(e);this.removeDoc(t,!1)}},t.Index.prototype.removeDoc=function(e,n){if(e){var n=void 0===n?!0:n,i=e[this._ref];this.documentStore.hasDoc(i)&&(this.documentStore.removeDoc(i),this._fields.forEach(function(n){var o=this.pipeline.run(t.tokenizer(e[n]));o.forEach(function(e){this.index[n].removeToken(e,i)},this)},this),n&&this.eventEmitter.emit("remove",e,this))}},t.Index.prototype.updateDoc=function(e,t){var t=void 0===t?!0:t;this.removeDocByRef(e[this._ref],!1),this.addDoc(e,!1),t&&this.eventEmitter.emit("update",e,this)},t.Index.prototype.idf=function(e,t){var n="@"+t+"/"+e;if(Object.prototype.hasOwnProperty.call(this._idfCache,n))return this._idfCache[n];var i=this.index[t].getDocFreq(e),o=1+Math.log(this.documentStore.length/(i+1));return this._idfCache[n]=o,o},t.Index.prototype.getFields=function(){return this._fields.slice()},t.Index.prototype.search=function(e,n){if(!e)return[];e="string"==typeof e?{any:e}:JSON.parse(JSON.stringify(e));var i=null;null!=n&&(i=JSON.stringify(n));for(var o=new t.Configuration(i,this.getFields()).get(),r={},s=Object.keys(e),u=0;u0&&t.push(e);for(var i in n)"docs"!==i&&"df"!==i&&this.expandToken(e+i,t,n[i]);return t},t.InvertedIndex.prototype.toJSON=function(){return{root:this.root}},t.Configuration=function(e,n){var e=e||"";if(void 0==n||null==n)throw new Error("fields should not be null");this.config={};var i;try{i=JSON.parse(e),this.buildUserConfig(i,n)}catch(o){t.utils.warn("user configuration parse failed, will use default configuration"),this.buildDefaultConfig(n)}},t.Configuration.prototype.buildDefaultConfig=function(e){this.reset(),e.forEach(function(e){this.config[e]={boost:1,bool:"OR",expand:!1}},this)},t.Configuration.prototype.buildUserConfig=function(e,n){var i="OR",o=!1;if(this.reset(),"bool"in e&&(i=e.bool||i),"expand"in e&&(o=e.expand||o),"fields"in e)for(var r in e.fields)if(n.indexOf(r)>-1){var s=e.fields[r],u=o;void 0!=s.expand&&(u=s.expand),this.config[r]={boost:s.boost||0===s.boost?s.boost:1,bool:s.bool||i,expand:u}}else t.utils.warn("field name in user configuration not found in index instance fields");else this.addAllFields2UserConfig(i,o,n)},t.Configuration.prototype.addAllFields2UserConfig=function(e,t,n){n.forEach(function(n){this.config[n]={boost:1,bool:e,expand:t}},this)},t.Configuration.prototype.get=function(){return this.config},t.Configuration.prototype.reset=function(){this.config={}},lunr.SortedSet=function(){this.length=0,this.elements=[]},lunr.SortedSet.load=function(e){var t=new this;return t.elements=e,t.length=e.length,t},lunr.SortedSet.prototype.add=function(){var e,t;for(e=0;e1;){if(r===e)return o;e>r&&(t=o),r>e&&(n=o),i=n-t,o=t+Math.floor(i/2),r=this.elements[o]}return r===e?o:-1},lunr.SortedSet.prototype.locationFor=function(e){for(var t=0,n=this.elements.length,i=n-t,o=t+Math.floor(i/2),r=this.elements[o];i>1;)e>r&&(t=o),r>e&&(n=o),i=n-t,o=t+Math.floor(i/2),r=this.elements[o];return r>e?o:e>r?o+1:void 0},lunr.SortedSet.prototype.intersect=function(e){for(var t=new lunr.SortedSet,n=0,i=0,o=this.length,r=e.length,s=this.elements,u=e.elements;;){if(n>o-1||i>r-1)break;s[n]!==u[i]?s[n]u[i]&&i++:(t.add(s[n]),n++,i++)}return t},lunr.SortedSet.prototype.clone=function(){var e=new lunr.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},lunr.SortedSet.prototype.union=function(e){var t,n,i;this.length>=e.length?(t=this,n=e):(t=e,n=this),i=t.clone();for(var o=0,r=n.toArray();o - - - - diff --git a/docs/book/fonts/OPEN-SANS-LICENSE.txt b/docs/book/fonts/OPEN-SANS-LICENSE.txt deleted file mode 100644 index d645695..0000000 --- a/docs/book/fonts/OPEN-SANS-LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/docs/book/fonts/SOURCE-CODE-PRO-LICENSE.txt b/docs/book/fonts/SOURCE-CODE-PRO-LICENSE.txt deleted file mode 100644 index efc001f..0000000 --- a/docs/book/fonts/SOURCE-CODE-PRO-LICENSE.txt +++ /dev/null @@ -1,93 +0,0 @@ -Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -http://scripts.sil.org/OFL - - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/docs/book/fonts/fonts.css b/docs/book/fonts/fonts.css deleted file mode 100644 index 698e1e1..0000000 --- a/docs/book/fonts/fonts.css +++ /dev/null @@ -1,100 +0,0 @@ -/* Open Sans is licensed under the Apache License, Version 2.0. See http://www.apache.org/licenses/LICENSE-2.0 */ -/* Source Code Pro is under the Open Font License. See https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL */ - -/* open-sans-300 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 300; - src: local('Open Sans Light'), local('OpenSans-Light'), - url('../fonts/open-sans-v17-all-charsets-300.woff2') format('woff2'); -} - -/* open-sans-300italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Open Sans'; - font-style: italic; - font-weight: 300; - src: local('Open Sans Light Italic'), local('OpenSans-LightItalic'), - url('../fonts/open-sans-v17-all-charsets-300italic.woff2') format('woff2'); -} - -/* open-sans-regular - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 400; - src: local('Open Sans Regular'), local('OpenSans-Regular'), - url('../fonts/open-sans-v17-all-charsets-regular.woff2') format('woff2'); -} - -/* open-sans-italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Open Sans'; - font-style: italic; - font-weight: 400; - src: local('Open Sans Italic'), local('OpenSans-Italic'), - url('../fonts/open-sans-v17-all-charsets-italic.woff2') format('woff2'); -} - -/* open-sans-600 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 600; - src: local('Open Sans SemiBold'), local('OpenSans-SemiBold'), - url('../fonts/open-sans-v17-all-charsets-600.woff2') format('woff2'); -} - -/* open-sans-600italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Open Sans'; - font-style: italic; - font-weight: 600; - src: local('Open Sans SemiBold Italic'), local('OpenSans-SemiBoldItalic'), - url('../fonts/open-sans-v17-all-charsets-600italic.woff2') format('woff2'); -} - -/* open-sans-700 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 700; - src: local('Open Sans Bold'), local('OpenSans-Bold'), - url('../fonts/open-sans-v17-all-charsets-700.woff2') format('woff2'); -} - -/* open-sans-700italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Open Sans'; - font-style: italic; - font-weight: 700; - src: local('Open Sans Bold Italic'), local('OpenSans-BoldItalic'), - url('../fonts/open-sans-v17-all-charsets-700italic.woff2') format('woff2'); -} - -/* open-sans-800 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 800; - src: local('Open Sans ExtraBold'), local('OpenSans-ExtraBold'), - url('../fonts/open-sans-v17-all-charsets-800.woff2') format('woff2'); -} - -/* open-sans-800italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Open Sans'; - font-style: italic; - font-weight: 800; - src: local('Open Sans ExtraBold Italic'), local('OpenSans-ExtraBoldItalic'), - url('../fonts/open-sans-v17-all-charsets-800italic.woff2') format('woff2'); -} - -/* source-code-pro-500 - latin_vietnamese_latin-ext_greek_cyrillic-ext_cyrillic */ -@font-face { - font-family: 'Source Code Pro'; - font-style: normal; - font-weight: 500; - src: url('../fonts/source-code-pro-v11-all-charsets-500.woff2') format('woff2'); -} diff --git a/docs/book/fonts/open-sans-v17-all-charsets-300.woff2 b/docs/book/fonts/open-sans-v17-all-charsets-300.woff2 deleted file mode 100644 index 9f51be3..0000000 Binary files a/docs/book/fonts/open-sans-v17-all-charsets-300.woff2 and /dev/null differ diff --git a/docs/book/fonts/open-sans-v17-all-charsets-300italic.woff2 b/docs/book/fonts/open-sans-v17-all-charsets-300italic.woff2 deleted file mode 100644 index 2f54544..0000000 Binary files a/docs/book/fonts/open-sans-v17-all-charsets-300italic.woff2 and /dev/null differ diff --git a/docs/book/fonts/open-sans-v17-all-charsets-600.woff2 b/docs/book/fonts/open-sans-v17-all-charsets-600.woff2 deleted file mode 100644 index f503d55..0000000 Binary files a/docs/book/fonts/open-sans-v17-all-charsets-600.woff2 and /dev/null differ diff --git a/docs/book/fonts/open-sans-v17-all-charsets-600italic.woff2 b/docs/book/fonts/open-sans-v17-all-charsets-600italic.woff2 deleted file mode 100644 index c99aabe..0000000 Binary files a/docs/book/fonts/open-sans-v17-all-charsets-600italic.woff2 and /dev/null differ diff --git a/docs/book/fonts/open-sans-v17-all-charsets-700.woff2 b/docs/book/fonts/open-sans-v17-all-charsets-700.woff2 deleted file mode 100644 index 421a1ab..0000000 Binary files a/docs/book/fonts/open-sans-v17-all-charsets-700.woff2 and /dev/null differ diff --git a/docs/book/fonts/open-sans-v17-all-charsets-700italic.woff2 b/docs/book/fonts/open-sans-v17-all-charsets-700italic.woff2 deleted file mode 100644 index 12ce3d2..0000000 Binary files a/docs/book/fonts/open-sans-v17-all-charsets-700italic.woff2 and /dev/null differ diff --git a/docs/book/fonts/open-sans-v17-all-charsets-800.woff2 b/docs/book/fonts/open-sans-v17-all-charsets-800.woff2 deleted file mode 100644 index c94a223..0000000 Binary files a/docs/book/fonts/open-sans-v17-all-charsets-800.woff2 and /dev/null differ diff --git a/docs/book/fonts/open-sans-v17-all-charsets-800italic.woff2 b/docs/book/fonts/open-sans-v17-all-charsets-800italic.woff2 deleted file mode 100644 index eed7d3c..0000000 Binary files a/docs/book/fonts/open-sans-v17-all-charsets-800italic.woff2 and /dev/null differ diff --git a/docs/book/fonts/open-sans-v17-all-charsets-italic.woff2 b/docs/book/fonts/open-sans-v17-all-charsets-italic.woff2 deleted file mode 100644 index 398b68a..0000000 Binary files a/docs/book/fonts/open-sans-v17-all-charsets-italic.woff2 and /dev/null differ diff --git a/docs/book/fonts/open-sans-v17-all-charsets-regular.woff2 b/docs/book/fonts/open-sans-v17-all-charsets-regular.woff2 deleted file mode 100644 index 8383e94..0000000 Binary files a/docs/book/fonts/open-sans-v17-all-charsets-regular.woff2 and /dev/null differ diff --git a/docs/book/fonts/source-code-pro-v11-all-charsets-500.woff2 b/docs/book/fonts/source-code-pro-v11-all-charsets-500.woff2 deleted file mode 100644 index 7222456..0000000 Binary files a/docs/book/fonts/source-code-pro-v11-all-charsets-500.woff2 and /dev/null differ diff --git a/docs/book/guides/from-scratch.html b/docs/book/guides/from-scratch.html deleted file mode 100644 index 9cafdd8..0000000 --- a/docs/book/guides/from-scratch.html +++ /dev/null @@ -1,988 +0,0 @@ - - - - - - From Scratch Guide - Provisioning Platform Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-

Keyboard shortcuts

-
-

Press or to navigate between chapters

-

Press S or / to search in the book

-

Press ? to show this help

-

Press Esc to hide this help

-
-
-
-
- - - - - - - - - - - - - -
- -
- - - - - - - - -
-
-

From Scratch Guide

-

Complete walkthrough from zero to production-ready infrastructure deployment using the Provisioning platform. This guide covers installation, configuration, -workspace setup, infrastructure definition, and deployment workflows.

-

Overview

-

This guide walks you through:

-
    -
  • Installing prerequisites and the Provisioning platform
  • -
  • Configuring cloud provider credentials
  • -
  • Creating your first workspace
  • -
  • Defining infrastructure using Nickel
  • -
  • Deploying servers and task services
  • -
  • Setting up Kubernetes clusters
  • -
  • Implementing security best practices
  • -
  • Monitoring and maintaining infrastructure
  • -
-

Time commitment: 2-3 hours for complete setup -Prerequisites: Linux or macOS, terminal access, cloud provider account (optional)

-

Phase 1: Installation

-

System Prerequisites

-

Ensure your system meets minimum requirements:

-
# Check OS (Linux or macOS)
-uname -s
-
-# Verify available disk space (minimum 10GB recommended)
-df -h ~
-
-# Check internet connectivity
-ping -c 3 github.com
-
-

Install Required Tools

-

Nushell (Required)

-
# macOS
-brew install nushell
-
-# Linux
-cargo install nu
-
-# Verify installation
-nu --version  # Expected: 0.109.1+
-
-

Nickel (Required)

-
# macOS
-brew install nickel
-
-# Linux
-cargo install nickel-lang-cli
-
-# Verify installation
-nickel --version  # Expected: 1.15.1+
-
-

Additional Tools

-
# SOPS for secrets management
-brew install sops  # macOS
-# or download from  [https://github.com/getsops/sops/releases](https://github.com/getsops/sops/releases)
-
-# Age for encryption
-brew install age  # macOS
-cargo install age  # Linux
-
-# K9s for Kubernetes management (optional)
-brew install derailed/k9s/k9s
-
-# Verify installations
-sops --version    # Expected: 3.10.2+
-age --version     # Expected: 1.2.1+
-k9s version       # Expected: 0.50.6+
-
-

Install Provisioning Platform

- -
# Download and run installer
-INSTALL_URL="https://raw.githubusercontent.com/yourusername/provisioning/main/install.sh"
-curl -sSL "$INSTALL_URL" | bash
-
-# Follow prompts to configure installation directory and path
-# Default: ~/.local/bin/provisioning
-
-

Installer performs:

-
    -
  • Downloads latest platform binaries
  • -
  • Installs CLI to system PATH
  • -
  • Creates default configuration structure
  • -
  • Validates dependencies
  • -
  • Runs health check
  • -
-

Option 2: Build from Source

-
# Clone repository
-git clone  [https://github.com/yourusername/provisioning.git](https://github.com/yourusername/provisioning.git)
-cd provisioning
-
-# Build core CLI
-cd provisioning/core
-cargo build --release
-
-# Install to local bin
-cp target/release/provisioning ~/.local/bin/
-
-# Add to PATH (add to ~/.bashrc or ~/.zshrc)
-export PATH="$HOME/.local/bin:$PATH"
-
-# Verify installation
-provisioning version
-
-

Platform Health Check

-
# Verify installation
-provisioning setup check
-
-# Expected output:
-# ✓ Nushell 0.109.1 installed
-# ✓ Nickel 1.15.1 installed
-# ✓ SOPS 3.10.2 installed
-# ✓ Age 1.2.1 installed
-# ✓ Provisioning CLI installed
-# ✓ Configuration directory created
-# Platform ready for use
-
-

Phase 2: Initial Configuration

-

Generate User Configuration

-
# Create user configuration directory
-mkdir -p ~/.config/provisioning
-
-# Generate default user config
-provisioning setup init-user-config
-
-

Generated configuration structure:

-
~/.config/provisioning/
-├── user_config.yaml      # User preferences and workspace registry
-├── credentials/          # Provider credentials (encrypted)
-├── age/                  # Age encryption keys
-└── cache/                # CLI cache
-
-

Configure Encryption

-
# Generate Age key pair for secrets
-age-keygen -o ~/.config/provisioning/age/provisioning.key
-
-# Store public key
-age-keygen -y ~/.config/provisioning/age/provisioning.key > ~/.config/provisioning/age/provisioning.pub
-
-# Configure SOPS to use Age
-cat > ~/.config/sops/config.yaml <<EOF
-creation_rules:
-  - path_regex: \.secret\.(yam| l tom| l json)$
-    age: $(cat ~/.config/provisioning/age/provisioning.pub)
-EOF
-
-

Provider Credentials

-

Configure credentials for your chosen cloud provider.

-

UpCloud Configuration

-
# Edit user config
-nano ~/.config/provisioning/user_config.yaml
-
-# Add provider credentials
-cat >> ~/.config/provisioning/user_config.yaml <<EOF
-providers:
-  upcloud:
-    username: "your-upcloud-username"
-    password_env: "UPCLOUD_PASSWORD"  # Read from environment variable
-    default_zone: "de-fra1"
-EOF
-
-# Set environment variable (add to ~/.bashrc or ~/.zshrc)
-export UPCLOUD_PASSWORD="your-upcloud-password"
-
-

AWS Configuration

-
# Add AWS credentials to user config
-cat >> ~/.config/provisioning/user_config.yaml <<EOF
-providers:
-  aws:
-    access_key_id_env: "AWS_ACCESS_KEY_ID"
-    secret_access_key_env: "AWS_SECRET_ACCESS_KEY"
-    default_region: "eu-west-1"
-EOF
-
-# Set environment variables
-export AWS_ACCESS_KEY_ID="your-access-key-id"
-export AWS_SECRET_ACCESS_KEY="your-secret-access-key"
-
-

Local Provider (Development)

-
# Configure local provider for testing
-cat >> ~/.config/provisioning/user_config.yaml <<EOF
-providers:
-  local:
-    backend: "docker"  # or "podman", "libvirt"
-    storage_path: "$HOME/.local/share/provisioning/local"
-EOF
-
-# Ensure Docker is running
-docker info
-
-

Validate Configuration

-
# Validate user configuration
-provisioning validate config
-
-# Test provider connectivity
-provisioning providers
-
-# Expected output:
-# PROVIDER    STATUS     REGION/ZONE
-# upcloud     connected  de-fra1
-# local       ready      localhost
-
-

Phase 3: Create First Workspace

-

Initialize Workspace

-
# Create workspace for first project
-provisioning workspace init my-first-project
-
-# Navigate to workspace
-cd workspace_my_first_project
-
-# Verify structure
-ls -la
-
-

Workspace structure created:

-
workspace_my_first_project/
-├── infra/                   # Infrastructure definitions (Nickel)
-├── config/                  # Workspace configuration
-│   ├── provisioning.yaml    # Workspace metadata
-│   ├── dev-defaults.toml    # Development defaults
-│   ├── test-defaults.toml   # Testing defaults
-│   └── prod-defaults.toml   # Production defaults
-├── extensions/              # Workspace-specific extensions
-│   ├── providers/
-│   ├── taskservs/
-│   └── workflows/
-└── runtime/                 # State and logs (gitignored)
-    ├── state/
-    ├── checkpoints/
-    └── logs/
-
-

Configure Workspace

-
# Edit workspace metadata
-nano config/provisioning.yaml
-
-

Example workspace configuration:

-
workspace:
-  name: my-first-project
-  description: Learning Provisioning platform
-  environment: development
-  created: 2026-01-16T10:00:00Z
-
-defaults:
-  provider: local
-  region: localhost
-  confirmation_required: false
-
-versioning:
-  nushell: "0.109.1"
-  nickel: "1.15.1"
-  kubernetes: "1.29.0"
-
-

Phase 4: Define Infrastructure

-

Simple Server Configuration

-

Create your first infrastructure definition using Nickel:

-
# Create server definition
-cat > infra/simple-server.ncl <<'EOF'
-{
-  metadata = {
-    name = "simple-server"
-    provider = "local"
-    environment = 'development
-  }
-
-  infrastructure = {
-    servers = [
-      {
-        name = "dev-web-01"
-        plan = "small"
-        zone = "localhost"
-        disk_size_gb = 25
-        backup_enabled = false
-        role = 'standalone
-      }
-    ]
-  }
-
-  services = {
-    taskservs = ["containerd"]
-  }
-}
-EOF
-
-

Validate Infrastructure Schema

-
# Type-check Nickel schema
-nickel typecheck infra/simple-server.ncl
-
-# Validate against platform contracts
-provisioning validate config --infra simple-server
-
-# Preview deployment
-provisioning server create --check --infra simple-server
-
-

Expected output:

-
Infrastructure Plan: simple-server
-Provider: local
-Environment: development
-
-Servers to create:
-  - dev-web-01 (small, standalone)
-    Disk: 25 GB
-    Backup: disabled
-
-Task services:
-  - containerd
-
-Estimated resources:
-  CPU: 1 core
-  RAM: 1 GB
-  Disk: 25 GB
-
-Validation: PASSED
-
-

Deploy Infrastructure

-
# Create server
-provisioning server create --infra simple-server --yes
-
-# Monitor deployment
-provisioning server status dev-web-01
-
-

Deployment progress:

-
Creating server: dev-web-01...
-  [████████████████████████] 100% - Container created
-  [████████████████████████] 100% - Network configured
-  [████████████████████████] 100% - SSH ready
-
-Server dev-web-01 created successfully
-IP Address: 172.17.0.2
-Status: running
-Provider: local (docker)
-
-

Install Task Service

-
# Install containerd
-provisioning taskserv create containerd --infra simple-server
-
-# Verify installation
-provisioning taskserv status containerd
-
-

Installation output:

-
Installing containerd on dev-web-01...
-  [████████████████████████] 100% - Dependencies resolved
-  [████████████████████████] 100% - Containerd installed
-  [████████████████████████] 100% - Service started
-  [████████████████████████] 100% - Health check passed
-
-Containerd installed successfully
-Version: 1.7.0
-Runtime: runc
-
-

Verify Deployment

-
# SSH into server
-provisioning server ssh dev-web-01
-
-# Inside server - verify containerd
-sudo systemctl status containerd
-sudo ctr version
-
-# Exit server
-exit
-
-# List all resources
-provisioning server list
-provisioning taskserv list
-
-

Phase 5: Kubernetes Cluster Deployment

-

Define Kubernetes Infrastructure

-
# Create Kubernetes cluster definition
-cat > infra/k8s-cluster.ncl <<'EOF'
-{
-  metadata = {
-    name = "k8s-dev-cluster"
-    provider = "local"
-    environment = 'development
-  }
-
-  infrastructure = {
-    servers = [
-      {
-        name = "k8s-control-01"
-        plan = "medium"
-        role = 'control
-        zone = "localhost"
-        disk_size_gb = 50
-      }
-      {
-        name = "k8s-worker-01"
-        plan = "medium"
-        role = 'worker
-        zone = "localhost"
-        disk_size_gb = 50
-      }
-      {
-        name = "k8s-worker-02"
-        plan = "medium"
-        role = 'worker
-        zone = "localhost"
-        disk_size_gb = 50
-      }
-    ]
-  }
-
-  services = {
-    taskservs = ["containerd", "etcd", "kubernetes", "cilium"]
-  }
-
-  kubernetes = {
-    version = "1.29.0"
-    pod_cidr = "10.244.0.0/16"
-    service_cidr = "10.96.0.0/12"
-    container_runtime = "containerd"
-    cri_socket = "/run/containerd/containerd.sock"
-  }
-}
-EOF
-
-

Validate Kubernetes Configuration

-
# Type-check schema
-nickel typecheck infra/k8s-cluster.ncl
-
-# Validate configuration
-provisioning validate config --infra k8s-cluster
-
-# Preview deployment
-provisioning cluster create --check --infra k8s-cluster
-
-

Deploy Kubernetes Cluster

-
# Create cluster infrastructure
-provisioning cluster create --infra k8s-cluster --yes
-
-# Monitor cluster deployment
-provisioning cluster status k8s-dev-cluster
-
-

Cluster deployment phases:

-
Phase 1: Creating servers...
-  [████████████████████████] 100% - 3/3 servers created
-
-Phase 2: Installing containerd...
-  [████████████████████████] 100% - 3/3 nodes ready
-
-Phase 3: Installing etcd...
-  [████████████████████████] 100% - Control plane ready
-
-Phase 4: Installing Kubernetes...
-  [████████████████████████] 100% - API server available
-  [████████████████████████] 100% - Workers joined
-
-Phase 5: Installing Cilium CNI...
-  [████████████████████████] 100% - Network ready
-
-Kubernetes cluster deployed successfully
-Cluster: k8s-dev-cluster
-Control plane: k8s-control-01
-Workers: k8s-worker-01, k8s-worker-02
-
-

Access Kubernetes Cluster

-
# Get kubeconfig
-provisioning cluster kubeconfig k8s-dev-cluster > ~/.kube/config-dev
-
-# Set KUBECONFIG
-export KUBECONFIG=~/.kube/config-dev
-
-# Verify cluster
-kubectl get nodes
-
-# Expected output:
-# NAME              STATUS   ROLES           AGE   VERSION
-# k8s-control-01    Ready    control-plane   5m    v1.29.0
-# k8s-worker-01     Ready    <none>          4m    v1.29.0
-# k8s-worker-02     Ready    <none>          4m    v1.29.0
-
-# Use K9s for interactive management
-k9s
-
-

Phase 6: Security Configuration

-

Enable Audit Logging

-
# Configure audit logging
-cat > config/audit-config.toml <<EOF
-[audit]
-enabled = true
-log_path = "runtime/logs/audit"
-retention_days = 90
-level = "info"
-
-[audit.filters]
-include_commands = ["server create", "server delete", "cluster deploy"]
-exclude_users = []
-EOF
-
-

Configure SOPS for Secrets

-
# Create secrets file
-cat > config/secrets.secret.yaml <<EOF
-database:
-  password: "changeme-db-password"
-  admin_user: "admin"
-
-kubernetes:
-  service_account_key: "changeme-sa-key"
-EOF
-
-# Encrypt secrets with SOPS
-sops -e -i config/secrets.secret.yaml
-
-# Verify encryption
-cat config/secrets.secret.yaml  # Should show encrypted content
-
-# Decrypt when needed
-sops -d config/secrets.secret.yaml
-
-

Enable MFA (Optional)

-
# Enable multi-factor authentication
-provisioning security mfa enable
-
-# Scan QR code with authenticator app
-# Enter verification code
-
-

Configure RBAC

-
# Create role definition
-cat > config/rbac-roles.yaml <<EOF
-roles:
-  - name: developer
-    permissions:
-      - server:read
-      - server:create
-      - taskserv:read
-      - taskserv:install
-    deny:
-      - cluster:delete
-      - config:modify
-
-  - name: operator
-    permissions:
-      - "*:read"
-      - server:*
-      - taskserv:*
-      - cluster:read
-      - cluster:deploy
-
-  - name: admin
-    permissions:
-      - "*:*"
-EOF
-
-

Phase 7: Multi-Cloud Deployment

-

Define Multi-Cloud Infrastructure

-
# Create multi-cloud definition
-cat > infra/multi-cloud.ncl <<'EOF'
-{
-  batch_workflow = {
-    operations = [
-      {
-        id = "upcloud-frontend"
-        provider = "upcloud"
-        region = "de-fra1"
-        servers = [
-          {name = "upcloud-web-01", plan = "medium", role = 'web}
-        ]
-        taskservs = ["containerd", "nginx"]
-      }
-      {
-        id = "aws-backend"
-        provider = "aws"
-        region = "eu-west-1"
-        servers = [
-          {name = "aws-api-01", plan = "t3.medium", role = 'api}
-        ]
-        taskservs = ["containerd", "docker"]
-        dependencies = ["upcloud-frontend"]
-      }
-      {
-        id = "local-database"
-        provider = "local"
-        region = "localhost"
-        servers = [
-          {name = "local-db-01", plan = "large", role = 'database}
-        ]
-        taskservs = ["postgresql"]
-      }
-    ]
-    parallel_limit = 2
-  }
-}
-EOF
-
-

Deploy Multi-Cloud Infrastructure

-
# Submit batch workflow
-provisioning batch submit infra/multi-cloud.ncl
-
-# Monitor workflow progress
-provisioning batch status
-
-# View detailed operation status
-provisioning batch operations
-
-

Phase 8: Monitoring and Maintenance

-

Platform Health Monitoring

-
# Check platform health
-provisioning health
-
-# View service status
-provisioning service status orchestrator
-provisioning service status control-center
-
-# View logs
-provisioning logs --service orchestrator --tail 100
-
-

Infrastructure Monitoring

-
# List all servers
-provisioning server list --all-workspaces
-
-# Show server details
-provisioning server info k8s-control-01
-
-# Check task service status
-provisioning taskserv list
-provisioning taskserv health containerd
-
-

Backup Configuration

-
# Create backup
-provisioning backup create --type full --output ~/backups/provisioning-$(date +%Y%m%d).tar.gz
-
-# Schedule automatic backups
-provisioning backup schedule daily --time "02:00" --retention 7
-
-

Phase 9: Advanced Workflows

-

Custom Workflow Creation

-
# Create custom workflow
-cat > extensions/workflows/deploy-app.ncl <<'EOF'
-{
-  workflow = {
-    name = "deploy-application"
-    description = "Deploy application to Kubernetes"
-
-    steps = [
-      {
-        name = "build-image"
-        action = "docker-build"
-        params = {dockerfile = "Dockerfile", tag = "myapp:latest"}
-      }
-      {
-        name = "push-image"
-        action = "docker-push"
-        params = {image = "myapp:latest", registry = "registry.example.com"}
-        depends_on = ["build-image"]
-      }
-      {
-        name = "deploy-k8s"
-        action = "kubectl-apply"
-        params = {manifest = "k8s/deployment.yaml"}
-        depends_on = ["push-image"]
-      }
-      {
-        name = "verify-deployment"
-        action = "kubectl-rollout-status"
-        params = {deployment = "myapp"}
-        depends_on = ["deploy-k8s"]
-      }
-    ]
-  }
-}
-EOF
-
-

Execute Custom Workflow

-
# Run workflow
-provisioning workflow run deploy-application
-
-# Monitor workflow
-provisioning workflow status deploy-application
-
-# View workflow history
-provisioning workflow history
-
-

Troubleshooting

-

Common Issues

-

Server Creation Fails

-
# Enable debug logging
-provisioning --debug server create --infra simple-server
-
-# Check provider connectivity
-provisioning providers
-
-# Validate credentials
-provisioning validate config
-
-

Task Service Installation Fails

-
# Check server connectivity
-provisioning server ssh dev-web-01
-
-# Verify dependencies
-provisioning taskserv check-deps containerd
-
-# Retry installation
-provisioning taskserv create containerd --force
-
-

Cluster Deployment Fails

-
# Check cluster status
-provisioning cluster status k8s-dev-cluster
-
-# View cluster logs
-provisioning cluster logs k8s-dev-cluster
-
-# Reset and retry
-provisioning cluster reset k8s-dev-cluster
-provisioning cluster create --infra k8s-cluster
-
-

Next Steps

-

Production Deployment

- -

Advanced Features

- -

Learning Resources

- -

Summary

-

You’ve completed the from-scratch guide and learned:

-
    -
  • Platform installation and configuration
  • -
  • Provider credential setup
  • -
  • Workspace creation and management
  • -
  • Infrastructure definition with Nickel
  • -
  • Server and task service deployment
  • -
  • Kubernetes cluster deployment
  • -
  • Security configuration
  • -
  • Multi-cloud deployment
  • -
  • Monitoring and maintenance
  • -
  • Custom workflow creation
  • -
-

Your Provisioning platform is now ready for production use.

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- - diff --git a/docs/book/highlight.css b/docs/book/highlight.css deleted file mode 100644 index 352c79b..0000000 --- a/docs/book/highlight.css +++ /dev/null @@ -1,83 +0,0 @@ -/* - * An increased contrast highlighting scheme loosely based on the - * "Base16 Atelier Dune Light" theme by Bram de Haan - * (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune) - * Original Base16 color scheme by Chris Kempson - * (https://github.com/chriskempson/base16) - */ - -/* Comment */ -.hljs-comment, -.hljs-quote { - color: #575757; -} - -/* Red */ -.hljs-variable, -.hljs-template-variable, -.hljs-attribute, -.hljs-attr, -.hljs-tag, -.hljs-name, -.hljs-regexp, -.hljs-link, -.hljs-name, -.hljs-selector-id, -.hljs-selector-class { - color: #d70025; -} - -/* Orange */ -.hljs-number, -.hljs-meta, -.hljs-built_in, -.hljs-builtin-name, -.hljs-literal, -.hljs-type, -.hljs-params { - color: #b21e00; -} - -/* Green */ -.hljs-string, -.hljs-symbol, -.hljs-bullet { - color: #008200; -} - -/* Blue */ -.hljs-title, -.hljs-section { - color: #0030f2; -} - -/* Purple */ -.hljs-keyword, -.hljs-selector-tag { - color: #9d00ec; -} - -.hljs { - display: block; - overflow-x: auto; - background: #f6f7f6; - color: #000; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} - -.hljs-addition { - color: #22863a; - background-color: #f0fff4; -} - -.hljs-deletion { - color: #b31d28; - background-color: #ffeef0; -} diff --git a/docs/book/highlight.js b/docs/book/highlight.js deleted file mode 100644 index 27e7be7..0000000 --- a/docs/book/highlight.js +++ /dev/null @@ -1,54 +0,0 @@ -/* - Highlight.js 10.1.1 (93fd0d73) - License: BSD-3-Clause - Copyright (c) 2006-2020, Ivan Sagalaev -*/ -var hljs=function(){"use strict";function e(n){Object.freeze(n);var t="function"==typeof n;return Object.getOwnPropertyNames(n).forEach((function(r){!Object.hasOwnProperty.call(n,r)||null===n[r]||"object"!=typeof n[r]&&"function"!=typeof n[r]||t&&("caller"===r||"callee"===r||"arguments"===r)||Object.isFrozen(n[r])||e(n[r])})),n}class n{constructor(e){void 0===e.data&&(e.data={}),this.data=e.data}ignoreMatch(){this.ignore=!0}}function t(e){return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}function r(e,...n){var t={};for(const n in e)t[n]=e[n];return n.forEach((function(e){for(const n in e)t[n]=e[n]})),t}function a(e){return e.nodeName.toLowerCase()}var i=Object.freeze({__proto__:null,escapeHTML:t,inherit:r,nodeStream:function(e){var n=[];return function e(t,r){for(var i=t.firstChild;i;i=i.nextSibling)3===i.nodeType?r+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:r,node:i}),r=e(i,r),a(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:r,node:i}));return r}(e,0),n},mergeStreams:function(e,n,r){var i=0,s="",o=[];function l(){return e.length&&n.length?e[0].offset!==n[0].offset?e[0].offset"}function u(e){s+=""}function d(e){("start"===e.event?c:u)(e.node)}for(;e.length||n.length;){var g=l();if(s+=t(r.substring(i,g[0].offset)),i=g[0].offset,g===e){o.reverse().forEach(u);do{d(g.splice(0,1)[0]),g=l()}while(g===e&&g.length&&g[0].offset===i);o.reverse().forEach(c)}else"start"===g[0].event?o.push(g[0].node):o.pop(),d(g.splice(0,1)[0])}return s+t(r.substr(i))}});const s="",o=e=>!!e.kind;class l{constructor(e,n){this.buffer="",this.classPrefix=n.classPrefix,e.walk(this)}addText(e){this.buffer+=t(e)}openNode(e){if(!o(e))return;let n=e.kind;e.sublanguage||(n=`${this.classPrefix}${n}`),this.span(n)}closeNode(e){o(e)&&(this.buffer+=s)}value(){return this.buffer}span(e){this.buffer+=``}}class c{constructor(){this.rootNode={children:[]},this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){this.top.children.push(e)}openNode(e){const n={kind:e,children:[]};this.add(n),this.stack.push(n)}closeNode(){if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,n){return"string"==typeof n?e.addText(n):n.children&&(e.openNode(n),n.children.forEach(n=>this._walk(e,n)),e.closeNode(n)),e}static _collapse(e){"string"!=typeof e&&e.children&&(e.children.every(e=>"string"==typeof e)?e.children=[e.children.join("")]:e.children.forEach(e=>{c._collapse(e)}))}}class u extends c{constructor(e){super(),this.options=e}addKeyword(e,n){""!==e&&(this.openNode(n),this.addText(e),this.closeNode())}addText(e){""!==e&&this.add(e)}addSublanguage(e,n){const t=e.root;t.kind=n,t.sublanguage=!0,this.add(t)}toHTML(){return new l(this,this.options).value()}finalize(){return!0}}function d(e){return e?"string"==typeof e?e:e.source:null}const g="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",h={begin:"\\\\[\\s\\S]",relevance:0},f={className:"string",begin:"'",end:"'",illegal:"\\n",contains:[h]},p={className:"string",begin:'"',end:'"',illegal:"\\n",contains:[h]},b={begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},m=function(e,n,t={}){var a=r({className:"comment",begin:e,end:n,contains:[]},t);return a.contains.push(b),a.contains.push({className:"doctag",begin:"(?:TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):",relevance:0}),a},v=m("//","$"),x=m("/\\*","\\*/"),E=m("#","$");var _=Object.freeze({__proto__:null,IDENT_RE:"[a-zA-Z]\\w*",UNDERSCORE_IDENT_RE:"[a-zA-Z_]\\w*",NUMBER_RE:"\\b\\d+(\\.\\d+)?",C_NUMBER_RE:g,BINARY_NUMBER_RE:"\\b(0b[01]+)",RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",SHEBANG:(e={})=>{const n=/^#![ ]*\//;return e.binary&&(e.begin=function(...e){return e.map(e=>d(e)).join("")}(n,/.*\b/,e.binary,/\b.*/)),r({className:"meta",begin:n,end:/$/,relevance:0,"on:begin":(e,n)=>{0!==e.index&&n.ignoreMatch()}},e)},BACKSLASH_ESCAPE:h,APOS_STRING_MODE:f,QUOTE_STRING_MODE:p,PHRASAL_WORDS_MODE:b,COMMENT:m,C_LINE_COMMENT_MODE:v,C_BLOCK_COMMENT_MODE:x,HASH_COMMENT_MODE:E,NUMBER_MODE:{className:"number",begin:"\\b\\d+(\\.\\d+)?",relevance:0},C_NUMBER_MODE:{className:"number",begin:g,relevance:0},BINARY_NUMBER_MODE:{className:"number",begin:"\\b(0b[01]+)",relevance:0},CSS_NUMBER_MODE:{className:"number",begin:"\\b\\d+(\\.\\d+)?(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",relevance:0},REGEXP_MODE:{begin:/(?=\/[^/\n]*\/)/,contains:[{className:"regexp",begin:/\//,end:/\/[gimuy]*/,illegal:/\n/,contains:[h,{begin:/\[/,end:/\]/,relevance:0,contains:[h]}]}]},TITLE_MODE:{className:"title",begin:"[a-zA-Z]\\w*",relevance:0},UNDERSCORE_TITLE_MODE:{className:"title",begin:"[a-zA-Z_]\\w*",relevance:0},METHOD_GUARD:{begin:"\\.\\s*[a-zA-Z_]\\w*",relevance:0},END_SAME_AS_BEGIN:function(e){return Object.assign(e,{"on:begin":(e,n)=>{n.data._beginMatch=e[1]},"on:end":(e,n)=>{n.data._beginMatch!==e[1]&&n.ignoreMatch()}})}}),N="of and for in not or if then".split(" ");function w(e,n){return n?+n:function(e){return N.includes(e.toLowerCase())}(e)?0:1}const R=t,y=r,{nodeStream:k,mergeStreams:O}=i,M=Symbol("nomatch");return function(t){var a=[],i={},s={},o=[],l=!0,c=/(^(<[^>]+>|\t|)+|\n)/gm,g="Could not find the language '{}', did you forget to load/include a language module?";const h={disableAutodetect:!0,name:"Plain text",contains:[]};var f={noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:null,__emitter:u};function p(e){return f.noHighlightRe.test(e)}function b(e,n,t,r){var a={code:n,language:e};S("before:highlight",a);var i=a.result?a.result:m(a.language,a.code,t,r);return i.code=a.code,S("after:highlight",i),i}function m(e,t,a,s){var o=t;function c(e,n){var t=E.case_insensitive?n[0].toLowerCase():n[0];return Object.prototype.hasOwnProperty.call(e.keywords,t)&&e.keywords[t]}function u(){null!=y.subLanguage?function(){if(""!==A){var e=null;if("string"==typeof y.subLanguage){if(!i[y.subLanguage])return void O.addText(A);e=m(y.subLanguage,A,!0,k[y.subLanguage]),k[y.subLanguage]=e.top}else e=v(A,y.subLanguage.length?y.subLanguage:null);y.relevance>0&&(I+=e.relevance),O.addSublanguage(e.emitter,e.language)}}():function(){if(!y.keywords)return void O.addText(A);let e=0;y.keywordPatternRe.lastIndex=0;let n=y.keywordPatternRe.exec(A),t="";for(;n;){t+=A.substring(e,n.index);const r=c(y,n);if(r){const[e,a]=r;O.addText(t),t="",I+=a,O.addKeyword(n[0],e)}else t+=n[0];e=y.keywordPatternRe.lastIndex,n=y.keywordPatternRe.exec(A)}t+=A.substr(e),O.addText(t)}(),A=""}function h(e){return e.className&&O.openNode(e.className),y=Object.create(e,{parent:{value:y}})}function p(e){return 0===y.matcher.regexIndex?(A+=e[0],1):(L=!0,0)}var b={};function x(t,r){var i=r&&r[0];if(A+=t,null==i)return u(),0;if("begin"===b.type&&"end"===r.type&&b.index===r.index&&""===i){if(A+=o.slice(r.index,r.index+1),!l){const n=Error("0 width match regex");throw n.languageName=e,n.badRule=b.rule,n}return 1}if(b=r,"begin"===r.type)return function(e){var t=e[0],r=e.rule;const a=new n(r),i=[r.__beforeBegin,r["on:begin"]];for(const n of i)if(n&&(n(e,a),a.ignore))return p(t);return r&&r.endSameAsBegin&&(r.endRe=RegExp(t.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),"m")),r.skip?A+=t:(r.excludeBegin&&(A+=t),u(),r.returnBegin||r.excludeBegin||(A=t)),h(r),r.returnBegin?0:t.length}(r);if("illegal"===r.type&&!a){const e=Error('Illegal lexeme "'+i+'" for mode "'+(y.className||"")+'"');throw e.mode=y,e}if("end"===r.type){var s=function(e){var t=e[0],r=o.substr(e.index),a=function e(t,r,a){let i=function(e,n){var t=e&&e.exec(n);return t&&0===t.index}(t.endRe,a);if(i){if(t["on:end"]){const e=new n(t);t["on:end"](r,e),e.ignore&&(i=!1)}if(i){for(;t.endsParent&&t.parent;)t=t.parent;return t}}if(t.endsWithParent)return e(t.parent,r,a)}(y,e,r);if(!a)return M;var i=y;i.skip?A+=t:(i.returnEnd||i.excludeEnd||(A+=t),u(),i.excludeEnd&&(A=t));do{y.className&&O.closeNode(),y.skip||y.subLanguage||(I+=y.relevance),y=y.parent}while(y!==a.parent);return a.starts&&(a.endSameAsBegin&&(a.starts.endRe=a.endRe),h(a.starts)),i.returnEnd?0:t.length}(r);if(s!==M)return s}if("illegal"===r.type&&""===i)return 1;if(B>1e5&&B>3*r.index)throw Error("potential infinite loop, way more iterations than matches");return A+=i,i.length}var E=T(e);if(!E)throw console.error(g.replace("{}",e)),Error('Unknown language: "'+e+'"');var _=function(e){function n(n,t){return RegExp(d(n),"m"+(e.case_insensitive?"i":"")+(t?"g":""))}class t{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(e,n){n.position=this.position++,this.matchIndexes[this.matchAt]=n,this.regexes.push([n,e]),this.matchAt+=function(e){return RegExp(e.toString()+"|").exec("").length-1}(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null);const e=this.regexes.map(e=>e[1]);this.matcherRe=n(function(e,n="|"){for(var t=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./,r=0,a="",i=0;i0&&(a+=n),a+="(";o.length>0;){var l=t.exec(o);if(null==l){a+=o;break}a+=o.substring(0,l.index),o=o.substring(l.index+l[0].length),"\\"===l[0][0]&&l[1]?a+="\\"+(+l[1]+s):(a+=l[0],"("===l[0]&&r++)}a+=")"}return a}(e),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex;const n=this.matcherRe.exec(e);if(!n)return null;const t=n.findIndex((e,n)=>n>0&&void 0!==e),r=this.matchIndexes[t];return n.splice(0,t),Object.assign(n,r)}}class a{constructor(){this.rules=[],this.multiRegexes=[],this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){if(this.multiRegexes[e])return this.multiRegexes[e];const n=new t;return this.rules.slice(e).forEach(([e,t])=>n.addRule(e,t)),n.compile(),this.multiRegexes[e]=n,n}considerAll(){this.regexIndex=0}addRule(e,n){this.rules.push([e,n]),"begin"===n.type&&this.count++}exec(e){const n=this.getMatcher(this.regexIndex);n.lastIndex=this.lastIndex;const t=n.exec(e);return t&&(this.regexIndex+=t.position+1,this.regexIndex===this.count&&(this.regexIndex=0)),t}}function i(e,n){const t=e.input[e.index-1],r=e.input[e.index+e[0].length];"."!==t&&"."!==r||n.ignoreMatch()}if(e.contains&&e.contains.includes("self"))throw Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");return function t(s,o){const l=s;if(s.compiled)return l;s.compiled=!0,s.__beforeBegin=null,s.keywords=s.keywords||s.beginKeywords;let c=null;if("object"==typeof s.keywords&&(c=s.keywords.$pattern,delete s.keywords.$pattern),s.keywords&&(s.keywords=function(e,n){var t={};return"string"==typeof e?r("keyword",e):Object.keys(e).forEach((function(n){r(n,e[n])})),t;function r(e,r){n&&(r=r.toLowerCase()),r.split(" ").forEach((function(n){var r=n.split("|");t[r[0]]=[e,w(r[0],r[1])]}))}}(s.keywords,e.case_insensitive)),s.lexemes&&c)throw Error("ERR: Prefer `keywords.$pattern` to `mode.lexemes`, BOTH are not allowed. (see mode reference) ");return l.keywordPatternRe=n(s.lexemes||c||/\w+/,!0),o&&(s.beginKeywords&&(s.begin="\\b("+s.beginKeywords.split(" ").join("|")+")(?=\\b|\\s)",s.__beforeBegin=i),s.begin||(s.begin=/\B|\b/),l.beginRe=n(s.begin),s.endSameAsBegin&&(s.end=s.begin),s.end||s.endsWithParent||(s.end=/\B|\b/),s.end&&(l.endRe=n(s.end)),l.terminator_end=d(s.end)||"",s.endsWithParent&&o.terminator_end&&(l.terminator_end+=(s.end?"|":"")+o.terminator_end)),s.illegal&&(l.illegalRe=n(s.illegal)),void 0===s.relevance&&(s.relevance=1),s.contains||(s.contains=[]),s.contains=[].concat(...s.contains.map((function(e){return function(e){return e.variants&&!e.cached_variants&&(e.cached_variants=e.variants.map((function(n){return r(e,{variants:null},n)}))),e.cached_variants?e.cached_variants:function e(n){return!!n&&(n.endsWithParent||e(n.starts))}(e)?r(e,{starts:e.starts?r(e.starts):null}):Object.isFrozen(e)?r(e):e}("self"===e?s:e)}))),s.contains.forEach((function(e){t(e,l)})),s.starts&&t(s.starts,o),l.matcher=function(e){const n=new a;return e.contains.forEach(e=>n.addRule(e.begin,{rule:e,type:"begin"})),e.terminator_end&&n.addRule(e.terminator_end,{type:"end"}),e.illegal&&n.addRule(e.illegal,{type:"illegal"}),n}(l),l}(e)}(E),N="",y=s||_,k={},O=new f.__emitter(f);!function(){for(var e=[],n=y;n!==E;n=n.parent)n.className&&e.unshift(n.className);e.forEach(e=>O.openNode(e))}();var A="",I=0,S=0,B=0,L=!1;try{for(y.matcher.considerAll();;){B++,L?L=!1:(y.matcher.lastIndex=S,y.matcher.considerAll());const e=y.matcher.exec(o);if(!e)break;const n=x(o.substring(S,e.index),e);S=e.index+n}return x(o.substr(S)),O.closeAllNodes(),O.finalize(),N=O.toHTML(),{relevance:I,value:N,language:e,illegal:!1,emitter:O,top:y}}catch(n){if(n.message&&n.message.includes("Illegal"))return{illegal:!0,illegalBy:{msg:n.message,context:o.slice(S-100,S+100),mode:n.mode},sofar:N,relevance:0,value:R(o),emitter:O};if(l)return{illegal:!1,relevance:0,value:R(o),emitter:O,language:e,top:y,errorRaised:n};throw n}}function v(e,n){n=n||f.languages||Object.keys(i);var t=function(e){const n={relevance:0,emitter:new f.__emitter(f),value:R(e),illegal:!1,top:h};return n.emitter.addText(e),n}(e),r=t;return n.filter(T).filter(I).forEach((function(n){var a=m(n,e,!1);a.language=n,a.relevance>r.relevance&&(r=a),a.relevance>t.relevance&&(r=t,t=a)})),r.language&&(t.second_best=r),t}function x(e){return f.tabReplace||f.useBR?e.replace(c,e=>"\n"===e?f.useBR?"
":e:f.tabReplace?e.replace(/\t/g,f.tabReplace):e):e}function E(e){let n=null;const t=function(e){var n=e.className+" ";n+=e.parentNode?e.parentNode.className:"";const t=f.languageDetectRe.exec(n);if(t){var r=T(t[1]);return r||(console.warn(g.replace("{}",t[1])),console.warn("Falling back to no-highlight mode for this block.",e)),r?t[1]:"no-highlight"}return n.split(/\s+/).find(e=>p(e)||T(e))}(e);if(p(t))return;S("before:highlightBlock",{block:e,language:t}),f.useBR?(n=document.createElement("div")).innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n"):n=e;const r=n.textContent,a=t?b(t,r,!0):v(r),i=k(n);if(i.length){const e=document.createElement("div");e.innerHTML=a.value,a.value=O(i,k(e),r)}a.value=x(a.value),S("after:highlightBlock",{block:e,result:a}),e.innerHTML=a.value,e.className=function(e,n,t){var r=n?s[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),e.includes(r)||a.push(r),a.join(" ").trim()}(e.className,t,a.language),e.result={language:a.language,re:a.relevance,relavance:a.relevance},a.second_best&&(e.second_best={language:a.second_best.language,re:a.second_best.relevance,relavance:a.second_best.relevance})}const N=()=>{if(!N.called){N.called=!0;var e=document.querySelectorAll("pre code");a.forEach.call(e,E)}};function T(e){return e=(e||"").toLowerCase(),i[e]||i[s[e]]}function A(e,{languageName:n}){"string"==typeof e&&(e=[e]),e.forEach(e=>{s[e]=n})}function I(e){var n=T(e);return n&&!n.disableAutodetect}function S(e,n){var t=e;o.forEach((function(e){e[t]&&e[t](n)}))}Object.assign(t,{highlight:b,highlightAuto:v,fixMarkup:x,highlightBlock:E,configure:function(e){f=y(f,e)},initHighlighting:N,initHighlightingOnLoad:function(){window.addEventListener("DOMContentLoaded",N,!1)},registerLanguage:function(e,n){var r=null;try{r=n(t)}catch(n){if(console.error("Language definition for '{}' could not be registered.".replace("{}",e)),!l)throw n;console.error(n),r=h}r.name||(r.name=e),i[e]=r,r.rawDefinition=n.bind(null,t),r.aliases&&A(r.aliases,{languageName:e})},listLanguages:function(){return Object.keys(i)},getLanguage:T,registerAliases:A,requireLanguage:function(e){var n=T(e);if(n)return n;throw Error("The '{}' language is required, but not loaded.".replace("{}",e))},autoDetection:I,inherit:y,addPlugin:function(e){o.push(e)}}),t.debugMode=function(){l=!1},t.safeMode=function(){l=!0},t.versionString="10.1.1";for(const n in _)"object"==typeof _[n]&&e(_[n]);return Object.assign(t,_),t}({})}();"object"==typeof exports&&"undefined"!=typeof module&&(module.exports=hljs); -hljs.registerLanguage("apache",function(){"use strict";return function(e){var n={className:"number",begin:"\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?"};return{name:"Apache config",aliases:["apacheconf"],case_insensitive:!0,contains:[e.HASH_COMMENT_MODE,{className:"section",begin:"",contains:[n,{className:"number",begin:":\\d{1,5}"},e.inherit(e.QUOTE_STRING_MODE,{relevance:0})]},{className:"attribute",begin:/\w+/,relevance:0,keywords:{nomarkup:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{end:/$/,relevance:0,keywords:{literal:"on off all deny allow"},contains:[{className:"meta",begin:"\\s\\[",end:"\\]$"},{className:"variable",begin:"[\\$%]\\{",end:"\\}",contains:["self",{className:"number",begin:"[\\$%]\\d+"}]},n,{className:"number",begin:"\\d+"},e.QUOTE_STRING_MODE]}}],illegal:/\S/}}}()); -hljs.registerLanguage("bash",function(){"use strict";return function(e){const s={};Object.assign(s,{className:"variable",variants:[{begin:/\$[\w\d#@][\w\d_]*/},{begin:/\$\{/,end:/\}/,contains:[{begin:/:-/,contains:[s]}]}]});const t={className:"subst",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]},n={className:"string",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,s,t]};t.contains.push(n);const a={begin:/\$\(\(/,end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},e.NUMBER_MODE,s]},i=e.SHEBANG({binary:"(fish|bash|zsh|sh|csh|ksh|tcsh|dash|scsh)",relevance:10}),c={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{name:"Bash",aliases:["sh","zsh"],keywords:{$pattern:/\b-?[a-z\._]+\b/,keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},contains:[i,e.SHEBANG(),c,a,e.HASH_COMMENT_MODE,n,{className:"",begin:/\\"/},{className:"string",begin:/'/,end:/'/},s]}}}()); -hljs.registerLanguage("c-like",function(){"use strict";return function(e){function t(e){return"(?:"+e+")?"}var n="(decltype\\(auto\\)|"+t("[a-zA-Z_]\\w*::")+"[a-zA-Z_]\\w*"+t("<.*?>")+")",r={className:"keyword",begin:"\\b[a-z\\d_]*_t\\b"},a={className:"string",variants:[{begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)",end:"'",illegal:"."},e.END_SAME_AS_BEGIN({begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},i={className:"number",variants:[{begin:"\\b(0b[01']+)"},{begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],relevance:0},s={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{"meta-keyword":"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include"},contains:[{begin:/\\\n/,relevance:0},e.inherit(a,{className:"meta-string"}),{className:"meta-string",begin:/<.*?>/,end:/$/,illegal:"\\n"},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},o={className:"title",begin:t("[a-zA-Z_]\\w*::")+e.IDENT_RE,relevance:0},c=t("[a-zA-Z_]\\w*::")+e.IDENT_RE+"\\s*\\(",l={keyword:"int float while private char char8_t char16_t char32_t catch import module export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using asm case typeid wchar_t short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignas alignof constexpr consteval constinit decltype concept co_await co_return co_yield requires noexcept static_assert thread_local restrict final override atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong new throw return and and_eq bitand bitor compl not not_eq or or_eq xor xor_eq",built_in:"std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr _Bool complex _Complex imaginary _Imaginary",literal:"true false nullptr NULL"},d=[r,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,i,a],_={variants:[{begin:/=/,end:/;/},{begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}],keywords:l,contains:d.concat([{begin:/\(/,end:/\)/,keywords:l,contains:d.concat(["self"]),relevance:0}]),relevance:0},u={className:"function",begin:"("+n+"[\\*&\\s]+)+"+c,returnBegin:!0,end:/[{;=]/,excludeEnd:!0,keywords:l,illegal:/[^\w\s\*&:<>]/,contains:[{begin:"decltype\\(auto\\)",keywords:l,relevance:0},{begin:c,returnBegin:!0,contains:[o],relevance:0},{className:"params",begin:/\(/,end:/\)/,keywords:l,relevance:0,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,a,i,r,{begin:/\(/,end:/\)/,keywords:l,relevance:0,contains:["self",e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,a,i,r]}]},r,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,s]};return{aliases:["c","cc","h","c++","h++","hpp","hh","hxx","cxx"],keywords:l,disableAutodetect:!0,illegal:"",keywords:l,contains:["self",r]},{begin:e.IDENT_RE+"::",keywords:l},{className:"class",beginKeywords:"class struct",end:/[{;:]/,contains:[{begin://,contains:["self"]},e.TITLE_MODE]}]),exports:{preprocessor:s,strings:a,keywords:l}}}}()); -hljs.registerLanguage("c",function(){"use strict";return function(e){var n=e.getLanguage("c-like").rawDefinition();return n.name="C",n.aliases=["c","h"],n}}()); -hljs.registerLanguage("coffeescript",function(){"use strict";const e=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],n=["true","false","null","undefined","NaN","Infinity"],a=[].concat(["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],["arguments","this","super","console","window","document","localStorage","module","global"],["Intl","DataView","Number","Math","Date","String","RegExp","Object","Function","Boolean","Error","Symbol","Set","Map","WeakSet","WeakMap","Proxy","Reflect","JSON","Promise","Float64Array","Int16Array","Int32Array","Int8Array","Uint16Array","Uint32Array","Float32Array","Array","Uint8Array","Uint8ClampedArray","ArrayBuffer"],["EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"]);return function(r){var t={keyword:e.concat(["then","unless","until","loop","by","when","and","or","is","isnt","not"]).filter((e=>n=>!e.includes(n))(["var","const","let","function","static"])).join(" "),literal:n.concat(["yes","no","on","off"]).join(" "),built_in:a.concat(["npm","print"]).join(" ")},i="[A-Za-z$_][0-9A-Za-z$_]*",s={className:"subst",begin:/#\{/,end:/}/,keywords:t},o=[r.BINARY_NUMBER_MODE,r.inherit(r.C_NUMBER_MODE,{starts:{end:"(\\s*/)?",relevance:0}}),{className:"string",variants:[{begin:/'''/,end:/'''/,contains:[r.BACKSLASH_ESCAPE]},{begin:/'/,end:/'/,contains:[r.BACKSLASH_ESCAPE]},{begin:/"""/,end:/"""/,contains:[r.BACKSLASH_ESCAPE,s]},{begin:/"/,end:/"/,contains:[r.BACKSLASH_ESCAPE,s]}]},{className:"regexp",variants:[{begin:"///",end:"///",contains:[s,r.HASH_COMMENT_MODE]},{begin:"//[gim]{0,3}(?=\\W)",relevance:0},{begin:/\/(?![ *]).*?(?![\\]).\/[gim]{0,3}(?=\W)/}]},{begin:"@"+i},{subLanguage:"javascript",excludeBegin:!0,excludeEnd:!0,variants:[{begin:"```",end:"```"},{begin:"`",end:"`"}]}];s.contains=o;var c=r.inherit(r.TITLE_MODE,{begin:i}),l={className:"params",begin:"\\([^\\(]",returnBegin:!0,contains:[{begin:/\(/,end:/\)/,keywords:t,contains:["self"].concat(o)}]};return{name:"CoffeeScript",aliases:["coffee","cson","iced"],keywords:t,illegal:/\/\*/,contains:o.concat([r.COMMENT("###","###"),r.HASH_COMMENT_MODE,{className:"function",begin:"^\\s*"+i+"\\s*=\\s*(\\(.*\\))?\\s*\\B[-=]>",end:"[-=]>",returnBegin:!0,contains:[c,l]},{begin:/[:\(,=]\s*/,relevance:0,contains:[{className:"function",begin:"(\\(.*\\))?\\s*\\B[-=]>",end:"[-=]>",returnBegin:!0,contains:[l]}]},{className:"class",beginKeywords:"class",end:"$",illegal:/[:="\[\]]/,contains:[{beginKeywords:"extends",endsWithParent:!0,illegal:/[:="\[\]]/,contains:[c]},c]},{begin:i+":",end:":",returnBegin:!0,returnEnd:!0,relevance:0}])}}}()); -hljs.registerLanguage("cpp",function(){"use strict";return function(e){var t=e.getLanguage("c-like").rawDefinition();return t.disableAutodetect=!1,t.name="C++",t.aliases=["cc","c++","h++","hpp","hh","hxx","cxx"],t}}()); -hljs.registerLanguage("csharp",function(){"use strict";return function(e){var n={keyword:"abstract as base bool break byte case catch char checked const continue decimal default delegate do double enum event explicit extern finally fixed float for foreach goto if implicit in int interface internal is lock long object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this try typeof uint ulong unchecked unsafe ushort using virtual void volatile while add alias ascending async await by descending dynamic equals from get global group into join let nameof on orderby partial remove select set value var when where yield",literal:"null false true"},i=e.inherit(e.TITLE_MODE,{begin:"[a-zA-Z](\\.?\\w)*"}),a={className:"number",variants:[{begin:"\\b(0b[01']+)"},{begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],relevance:0},s={className:"string",begin:'@"',end:'"',contains:[{begin:'""'}]},t=e.inherit(s,{illegal:/\n/}),l={className:"subst",begin:"{",end:"}",keywords:n},r=e.inherit(l,{illegal:/\n/}),c={className:"string",begin:/\$"/,end:'"',illegal:/\n/,contains:[{begin:"{{"},{begin:"}}"},e.BACKSLASH_ESCAPE,r]},o={className:"string",begin:/\$@"/,end:'"',contains:[{begin:"{{"},{begin:"}}"},{begin:'""'},l]},g=e.inherit(o,{illegal:/\n/,contains:[{begin:"{{"},{begin:"}}"},{begin:'""'},r]});l.contains=[o,c,s,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.C_BLOCK_COMMENT_MODE],r.contains=[g,c,t,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.inherit(e.C_BLOCK_COMMENT_MODE,{illegal:/\n/})];var d={variants:[o,c,s,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},E={begin:"<",end:">",contains:[{beginKeywords:"in out"},i]},_=e.IDENT_RE+"(<"+e.IDENT_RE+"(\\s*,\\s*"+e.IDENT_RE+")*>)?(\\[\\])?",b={begin:"@"+e.IDENT_RE,relevance:0};return{name:"C#",aliases:["cs","c#"],keywords:n,illegal:/::/,contains:[e.COMMENT("///","$",{returnBegin:!0,contains:[{className:"doctag",variants:[{begin:"///",relevance:0},{begin:"\x3c!--|--\x3e"},{begin:""}]}]}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"meta",begin:"#",end:"$",keywords:{"meta-keyword":"if else elif endif define undef warning error line region endregion pragma checksum"}},d,a,{beginKeywords:"class interface",end:/[{;=]/,illegal:/[^\s:,]/,contains:[{beginKeywords:"where class"},i,E,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{beginKeywords:"namespace",end:/[{;=]/,illegal:/[^\s:]/,contains:[i,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"meta",begin:"^\\s*\\[",excludeBegin:!0,end:"\\]",excludeEnd:!0,contains:[{className:"meta-string",begin:/"/,end:/"/}]},{beginKeywords:"new return throw await else",relevance:0},{className:"function",begin:"("+_+"\\s+)+"+e.IDENT_RE+"\\s*(\\<.+\\>)?\\s*\\(",returnBegin:!0,end:/\s*[{;=]/,excludeEnd:!0,keywords:n,contains:[{begin:e.IDENT_RE+"\\s*(\\<.+\\>)?\\s*\\(",returnBegin:!0,contains:[e.TITLE_MODE,E],relevance:0},{className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:n,relevance:0,contains:[d,a,e.C_BLOCK_COMMENT_MODE]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},b]}}}()); -hljs.registerLanguage("css",function(){"use strict";return function(e){var n={begin:/(?:[A-Z\_\.\-]+|--[a-zA-Z0-9_-]+)\s*:/,returnBegin:!0,end:";",endsWithParent:!0,contains:[{className:"attribute",begin:/\S/,end:":",excludeEnd:!0,starts:{endsWithParent:!0,excludeEnd:!0,contains:[{begin:/[\w-]+\(/,returnBegin:!0,contains:[{className:"built_in",begin:/[\w-]+/},{begin:/\(/,end:/\)/,contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.CSS_NUMBER_MODE]}]},e.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,e.C_BLOCK_COMMENT_MODE,{className:"number",begin:"#[0-9A-Fa-f]+"},{className:"meta",begin:"!important"}]}}]};return{name:"CSS",case_insensitive:!0,illegal:/[=\/|'\$]/,contains:[e.C_BLOCK_COMMENT_MODE,{className:"selector-id",begin:/#[A-Za-z0-9_-]+/},{className:"selector-class",begin:/\.[A-Za-z0-9_-]+/},{className:"selector-attr",begin:/\[/,end:/\]/,illegal:"$",contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},{className:"selector-pseudo",begin:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{begin:"@(page|font-face)",lexemes:"@[a-z-]+",keywords:"@page @font-face"},{begin:"@",end:"[{;]",illegal:/:/,returnBegin:!0,contains:[{className:"keyword",begin:/@\-?\w[\w]*(\-\w+)*/},{begin:/\s/,endsWithParent:!0,excludeEnd:!0,relevance:0,keywords:"and or not only",contains:[{begin:/[a-z-]+:/,className:"attribute"},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.CSS_NUMBER_MODE]}]},{className:"selector-tag",begin:"[a-zA-Z-][a-zA-Z0-9_-]*",relevance:0},{begin:"{",end:"}",illegal:/\S/,contains:[e.C_BLOCK_COMMENT_MODE,n]}]}}}()); -hljs.registerLanguage("diff",function(){"use strict";return function(e){return{name:"Diff",aliases:["patch"],contains:[{className:"meta",relevance:10,variants:[{begin:/^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},{begin:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{begin:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{className:"comment",variants:[{begin:/Index: /,end:/$/},{begin:/={3,}/,end:/$/},{begin:/^\-{3}/,end:/$/},{begin:/^\*{3} /,end:/$/},{begin:/^\+{3}/,end:/$/},{begin:/^\*{15}$/}]},{className:"addition",begin:"^\\+",end:"$"},{className:"deletion",begin:"^\\-",end:"$"},{className:"addition",begin:"^\\!",end:"$"}]}}}()); -hljs.registerLanguage("go",function(){"use strict";return function(e){var n={keyword:"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune",literal:"true false iota nil",built_in:"append cap close complex copy imag len make new panic print println real recover delete"};return{name:"Go",aliases:["golang"],keywords:n,illegal:"e(n)).join("")}return function(a){var s={className:"number",relevance:0,variants:[{begin:/([\+\-]+)?[\d]+_[\d_]+/},{begin:a.NUMBER_RE}]},i=a.COMMENT();i.variants=[{begin:/;/,end:/$/},{begin:/#/,end:/$/}];var t={className:"variable",variants:[{begin:/\$[\w\d"][\w\d_]*/},{begin:/\$\{(.*?)}/}]},r={className:"literal",begin:/\bon|off|true|false|yes|no\b/},l={className:"string",contains:[a.BACKSLASH_ESCAPE],variants:[{begin:"'''",end:"'''",relevance:10},{begin:'"""',end:'"""',relevance:10},{begin:'"',end:'"'},{begin:"'",end:"'"}]},c={begin:/\[/,end:/\]/,contains:[i,r,t,l,s,"self"],relevance:0},g="("+[/[A-Za-z0-9_-]+/,/"(\\"|[^"])*"/,/'[^']*'/].map(n=>e(n)).join("|")+")";return{name:"TOML, also INI",aliases:["toml"],case_insensitive:!0,illegal:/\S/,contains:[i,{className:"section",begin:/\[+/,end:/\]+/},{begin:n(g,"(\\s*\\.\\s*",g,")*",n("(?=",/\s*=\s*[^#\s]/,")")),className:"attr",starts:{end:/$/,contains:[i,c,r,t,l,s]}}]}}}()); -hljs.registerLanguage("java",function(){"use strict";function e(e){return e?"string"==typeof e?e:e.source:null}function n(e){return a("(",e,")?")}function a(...n){return n.map(n=>e(n)).join("")}function s(...n){return"("+n.map(n=>e(n)).join("|")+")"}return function(e){var t="false synchronized int abstract float private char boolean var static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports do",i={className:"meta",begin:"@[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*",contains:[{begin:/\(/,end:/\)/,contains:["self"]}]},r=e=>a("[",e,"]+([",e,"_]*[",e,"]+)?"),c={className:"number",variants:[{begin:`\\b(0[bB]${r("01")})[lL]?`},{begin:`\\b(0${r("0-7")})[dDfFlL]?`},{begin:a(/\b0[xX]/,s(a(r("a-fA-F0-9"),/\./,r("a-fA-F0-9")),a(r("a-fA-F0-9"),/\.?/),a(/\./,r("a-fA-F0-9"))),/([pP][+-]?(\d+))?/,/[fFdDlL]?/)},{begin:a(/\b/,s(a(/\d*\./,r("\\d")),r("\\d")),/[eE][+-]?[\d]+[dDfF]?/)},{begin:a(/\b/,r(/\d/),n(/\.?/),n(r(/\d/)),/[dDfFlL]?/)}],relevance:0};return{name:"Java",aliases:["jsp"],keywords:t,illegal:/<\/|#/,contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{begin:/\w+@/,relevance:0},{className:"doctag",begin:"@[A-Za-z]+"}]}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"class",beginKeywords:"class interface",end:/[{;=]/,excludeEnd:!0,keywords:"class interface",illegal:/[:"\[\]]/,contains:[{beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"new throw return else",relevance:0},{className:"function",begin:"([À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*(<[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*(\\s*,\\s*[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*)*>)?\\s+)+"+e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,end:/[{;=]/,excludeEnd:!0,keywords:t,contains:[{begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0,contains:[e.UNDERSCORE_TITLE_MODE]},{className:"params",begin:/\(/,end:/\)/,keywords:t,relevance:0,contains:[i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},c,i]}}}()); -hljs.registerLanguage("javascript",function(){"use strict";const e=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],n=["true","false","null","undefined","NaN","Infinity"],a=[].concat(["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],["arguments","this","super","console","window","document","localStorage","module","global"],["Intl","DataView","Number","Math","Date","String","RegExp","Object","Function","Boolean","Error","Symbol","Set","Map","WeakSet","WeakMap","Proxy","Reflect","JSON","Promise","Float64Array","Int16Array","Int32Array","Int8Array","Uint16Array","Uint32Array","Float32Array","Array","Uint8Array","Uint8ClampedArray","ArrayBuffer"],["EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"]);function s(e){return r("(?=",e,")")}function r(...e){return e.map(e=>(function(e){return e?"string"==typeof e?e:e.source:null})(e)).join("")}return function(t){var i="[A-Za-z$_][0-9A-Za-z$_]*",c={begin:/<[A-Za-z0-9\\._:-]+/,end:/\/[A-Za-z0-9\\._:-]+>|\/>/},o={$pattern:"[A-Za-z$_][0-9A-Za-z$_]*",keyword:e.join(" "),literal:n.join(" "),built_in:a.join(" ")},l={className:"number",variants:[{begin:"\\b(0[bB][01]+)n?"},{begin:"\\b(0[oO][0-7]+)n?"},{begin:t.C_NUMBER_RE+"n?"}],relevance:0},E={className:"subst",begin:"\\$\\{",end:"\\}",keywords:o,contains:[]},d={begin:"html`",end:"",starts:{end:"`",returnEnd:!1,contains:[t.BACKSLASH_ESCAPE,E],subLanguage:"xml"}},g={begin:"css`",end:"",starts:{end:"`",returnEnd:!1,contains:[t.BACKSLASH_ESCAPE,E],subLanguage:"css"}},u={className:"string",begin:"`",end:"`",contains:[t.BACKSLASH_ESCAPE,E]};E.contains=[t.APOS_STRING_MODE,t.QUOTE_STRING_MODE,d,g,u,l,t.REGEXP_MODE];var b=E.contains.concat([{begin:/\(/,end:/\)/,contains:["self"].concat(E.contains,[t.C_BLOCK_COMMENT_MODE,t.C_LINE_COMMENT_MODE])},t.C_BLOCK_COMMENT_MODE,t.C_LINE_COMMENT_MODE]),_={className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,contains:b};return{name:"JavaScript",aliases:["js","jsx","mjs","cjs"],keywords:o,contains:[t.SHEBANG({binary:"node",relevance:5}),{className:"meta",relevance:10,begin:/^\s*['"]use (strict|asm)['"]/},t.APOS_STRING_MODE,t.QUOTE_STRING_MODE,d,g,u,t.C_LINE_COMMENT_MODE,t.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{className:"doctag",begin:"@[A-Za-z]+",contains:[{className:"type",begin:"\\{",end:"\\}",relevance:0},{className:"variable",begin:i+"(?=\\s*(-)|$)",endsParent:!0,relevance:0},{begin:/(?=[^\n])\s/,relevance:0}]}]}),t.C_BLOCK_COMMENT_MODE,l,{begin:r(/[{,\n]\s*/,s(r(/(((\/\/.*)|(\/\*(.|\n)*\*\/))\s*)*/,i+"\\s*:"))),relevance:0,contains:[{className:"attr",begin:i+s("\\s*:"),relevance:0}]},{begin:"("+t.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*",keywords:"return throw case",contains:[t.C_LINE_COMMENT_MODE,t.C_BLOCK_COMMENT_MODE,t.REGEXP_MODE,{className:"function",begin:"(\\([^(]*(\\([^(]*(\\([^(]*\\))?\\))?\\)|"+t.UNDERSCORE_IDENT_RE+")\\s*=>",returnBegin:!0,end:"\\s*=>",contains:[{className:"params",variants:[{begin:t.UNDERSCORE_IDENT_RE},{className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:o,contains:b}]}]},{begin:/,/,relevance:0},{className:"",begin:/\s/,end:/\s*/,skip:!0},{variants:[{begin:"<>",end:""},{begin:c.begin,end:c.end}],subLanguage:"xml",contains:[{begin:c.begin,end:c.end,skip:!0,contains:["self"]}]}],relevance:0},{className:"function",beginKeywords:"function",end:/\{/,excludeEnd:!0,contains:[t.inherit(t.TITLE_MODE,{begin:i}),_],illegal:/\[|%/},{begin:/\$[(.]/},t.METHOD_GUARD,{className:"class",beginKeywords:"class",end:/[{;=]/,excludeEnd:!0,illegal:/[:"\[\]]/,contains:[{beginKeywords:"extends"},t.UNDERSCORE_TITLE_MODE]},{beginKeywords:"constructor",end:/\{/,excludeEnd:!0},{begin:"(get|set)\\s+(?="+i+"\\()",end:/{/,keywords:"get set",contains:[t.inherit(t.TITLE_MODE,{begin:i}),{begin:/\(\)/},_]}],illegal:/#(?!!)/}}}()); -hljs.registerLanguage("json",function(){"use strict";return function(n){var e={literal:"true false null"},i=[n.C_LINE_COMMENT_MODE,n.C_BLOCK_COMMENT_MODE],t=[n.QUOTE_STRING_MODE,n.C_NUMBER_MODE],a={end:",",endsWithParent:!0,excludeEnd:!0,contains:t,keywords:e},l={begin:"{",end:"}",contains:[{className:"attr",begin:/"/,end:/"/,contains:[n.BACKSLASH_ESCAPE],illegal:"\\n"},n.inherit(a,{begin:/:/})].concat(i),illegal:"\\S"},s={begin:"\\[",end:"\\]",contains:[n.inherit(a)],illegal:"\\S"};return t.push(l,s),i.forEach((function(n){t.push(n)})),{name:"JSON",contains:t,keywords:e,illegal:"\\S"}}}()); -hljs.registerLanguage("kotlin",function(){"use strict";return function(e){var n={keyword:"abstract as val var vararg get set class object open private protected public noinline crossinline dynamic final enum if else do while for when throw try catch finally import package is in fun override companion reified inline lateinit init interface annotation data sealed internal infix operator out by constructor super tailrec where const inner suspend typealias external expect actual trait volatile transient native default",built_in:"Byte Short Char Int Long Boolean Float Double Void Unit Nothing",literal:"true false null"},a={className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"@"},i={className:"subst",begin:"\\${",end:"}",contains:[e.C_NUMBER_MODE]},s={className:"variable",begin:"\\$"+e.UNDERSCORE_IDENT_RE},t={className:"string",variants:[{begin:'"""',end:'"""(?=[^"])',contains:[s,i]},{begin:"'",end:"'",illegal:/\n/,contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"',illegal:/\n/,contains:[e.BACKSLASH_ESCAPE,s,i]}]};i.contains.push(t);var r={className:"meta",begin:"@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*"+e.UNDERSCORE_IDENT_RE+")?"},l={className:"meta",begin:"@"+e.UNDERSCORE_IDENT_RE,contains:[{begin:/\(/,end:/\)/,contains:[e.inherit(t,{className:"meta-string"})]}]},c=e.COMMENT("/\\*","\\*/",{contains:[e.C_BLOCK_COMMENT_MODE]}),o={variants:[{className:"type",begin:e.UNDERSCORE_IDENT_RE},{begin:/\(/,end:/\)/,contains:[]}]},d=o;return d.variants[1].contains=[o],o.variants[1].contains=[d],{name:"Kotlin",aliases:["kt"],keywords:n,contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{className:"doctag",begin:"@[A-Za-z]+"}]}),e.C_LINE_COMMENT_MODE,c,{className:"keyword",begin:/\b(break|continue|return|this)\b/,starts:{contains:[{className:"symbol",begin:/@\w+/}]}},a,r,l,{className:"function",beginKeywords:"fun",end:"[(]|$",returnBegin:!0,excludeEnd:!0,keywords:n,illegal:/fun\s+(<.*>)?[^\s\(]+(\s+[^\s\(]+)\s*=/,relevance:5,contains:[{begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0,contains:[e.UNDERSCORE_TITLE_MODE]},{className:"type",begin://,keywords:"reified",relevance:0},{className:"params",begin:/\(/,end:/\)/,endsParent:!0,keywords:n,relevance:0,contains:[{begin:/:/,end:/[=,\/]/,endsWithParent:!0,contains:[o,e.C_LINE_COMMENT_MODE,c],relevance:0},e.C_LINE_COMMENT_MODE,c,r,l,t,e.C_NUMBER_MODE]},c]},{className:"class",beginKeywords:"class interface trait",end:/[:\{(]|$/,excludeEnd:!0,illegal:"extends implements",contains:[{beginKeywords:"public protected internal private constructor"},e.UNDERSCORE_TITLE_MODE,{className:"type",begin://,excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:/[,:]\s*/,end:/[<\(,]|$/,excludeBegin:!0,returnEnd:!0},r,l]},t,{className:"meta",begin:"^#!/usr/bin/env",end:"$",illegal:"\n"},{className:"number",begin:"\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",relevance:0}]}}}()); -hljs.registerLanguage("less",function(){"use strict";return function(e){var n="([\\w-]+|@{[\\w-]+})",a=[],s=[],t=function(e){return{className:"string",begin:"~?"+e+".*?"+e}},r=function(e,n,a){return{className:e,begin:n,relevance:a}},i={begin:"\\(",end:"\\)",contains:s,relevance:0};s.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,t("'"),t('"'),e.CSS_NUMBER_MODE,{begin:"(url|data-uri)\\(",starts:{className:"string",end:"[\\)\\n]",excludeEnd:!0}},r("number","#[0-9A-Fa-f]+\\b"),i,r("variable","@@?[\\w-]+",10),r("variable","@{[\\w-]+}"),r("built_in","~?`[^`]*?`"),{className:"attribute",begin:"[\\w-]+\\s*:",end:":",returnBegin:!0,excludeEnd:!0},{className:"meta",begin:"!important"});var c=s.concat({begin:"{",end:"}",contains:a}),l={beginKeywords:"when",endsWithParent:!0,contains:[{beginKeywords:"and not"}].concat(s)},o={begin:n+"\\s*:",returnBegin:!0,end:"[;}]",relevance:0,contains:[{className:"attribute",begin:n,end:":",excludeEnd:!0,starts:{endsWithParent:!0,illegal:"[<=$]",relevance:0,contains:s}}]},g={className:"keyword",begin:"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b",starts:{end:"[;{}]",returnEnd:!0,contains:s,relevance:0}},d={className:"variable",variants:[{begin:"@[\\w-]+\\s*:",relevance:15},{begin:"@[\\w-]+"}],starts:{end:"[;}]",returnEnd:!0,contains:c}},b={variants:[{begin:"[\\.#:&\\[>]",end:"[;{}]"},{begin:n,end:"{"}],returnBegin:!0,returnEnd:!0,illegal:"[<='$\"]",relevance:0,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,l,r("keyword","all\\b"),r("variable","@{[\\w-]+}"),r("selector-tag",n+"%?",0),r("selector-id","#"+n),r("selector-class","\\."+n,0),r("selector-tag","&",0),{className:"selector-attr",begin:"\\[",end:"\\]"},{className:"selector-pseudo",begin:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{begin:"\\(",end:"\\)",contains:c},{begin:"!important"}]};return a.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,g,d,o,b),{name:"Less",case_insensitive:!0,illegal:"[=>'/<($\"]",contains:a}}}()); -hljs.registerLanguage("lua",function(){"use strict";return function(e){var t={begin:"\\[=*\\[",end:"\\]=*\\]",contains:["self"]},a=[e.COMMENT("--(?!\\[=*\\[)","$"),e.COMMENT("--\\[=*\\[","\\]=*\\]",{contains:[t],relevance:10})];return{name:"Lua",keywords:{$pattern:e.UNDERSCORE_IDENT_RE,literal:"true false nil",keyword:"and break do else elseif end for goto if in local not or repeat return then until while",built_in:"_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len __gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall arg self coroutine resume yield status wrap create running debug getupvalue debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv io lines write close flush open output type read stderr stdin input stdout popen tmpfile math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower table setn insert getn foreachi maxn foreach concat sort remove"},contains:a.concat([{className:"function",beginKeywords:"function",end:"\\)",contains:[e.inherit(e.TITLE_MODE,{begin:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),{className:"params",begin:"\\(",endsWithParent:!0,contains:a}].concat(a)},e.C_NUMBER_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"string",begin:"\\[=*\\[",end:"\\]=*\\]",contains:[t],relevance:5}])}}}()); -hljs.registerLanguage("makefile",function(){"use strict";return function(e){var i={className:"variable",variants:[{begin:"\\$\\("+e.UNDERSCORE_IDENT_RE+"\\)",contains:[e.BACKSLASH_ESCAPE]},{begin:/\$[@%`]+/}]}]}]};return{name:"HTML, XML",aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"],case_insensitive:!0,contains:[{className:"meta",begin:"",relevance:10,contains:[a,i,t,s,{begin:"\\[",end:"\\]",contains:[{className:"meta",begin:"",contains:[a,s,i,t]}]}]},e.COMMENT("\x3c!--","--\x3e",{relevance:10}),{begin:"<\\!\\[CDATA\\[",end:"\\]\\]>",relevance:10},n,{className:"meta",begin:/<\?xml/,end:/\?>/,relevance:10},{className:"tag",begin:")",end:">",keywords:{name:"style"},contains:[c],starts:{end:"",returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag",begin:")",end:">",keywords:{name:"script"},contains:[c],starts:{end:"<\/script>",returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{className:"tag",begin:"",contains:[{className:"name",begin:/[^\/><\s]+/,relevance:0},c]}]}}}()); -hljs.registerLanguage("markdown",function(){"use strict";return function(n){const e={begin:"<",end:">",subLanguage:"xml",relevance:0},a={begin:"\\[.+?\\][\\(\\[].*?[\\)\\]]",returnBegin:!0,contains:[{className:"string",begin:"\\[",end:"\\]",excludeBegin:!0,returnEnd:!0,relevance:0},{className:"link",begin:"\\]\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0},{className:"symbol",begin:"\\]\\[",end:"\\]",excludeBegin:!0,excludeEnd:!0}],relevance:10},i={className:"strong",contains:[],variants:[{begin:/_{2}/,end:/_{2}/},{begin:/\*{2}/,end:/\*{2}/}]},s={className:"emphasis",contains:[],variants:[{begin:/\*(?!\*)/,end:/\*/},{begin:/_(?!_)/,end:/_/,relevance:0}]};i.contains.push(s),s.contains.push(i);var c=[e,a];return i.contains=i.contains.concat(c),s.contains=s.contains.concat(c),{name:"Markdown",aliases:["md","mkdown","mkd"],contains:[{className:"section",variants:[{begin:"^#{1,6}",end:"$",contains:c=c.concat(i,s)},{begin:"(?=^.+?\\n[=-]{2,}$)",contains:[{begin:"^[=-]*$"},{begin:"^",end:"\\n",contains:c}]}]},e,{className:"bullet",begin:"^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)",end:"\\s+",excludeEnd:!0},i,s,{className:"quote",begin:"^>\\s+",contains:c,end:"$"},{className:"code",variants:[{begin:"(`{3,})(.|\\n)*?\\1`*[ ]*"},{begin:"(~{3,})(.|\\n)*?\\1~*[ ]*"},{begin:"```",end:"```+[ ]*$"},{begin:"~~~",end:"~~~+[ ]*$"},{begin:"`.+?`"},{begin:"(?=^( {4}|\\t))",contains:[{begin:"^( {4}|\\t)",end:"(\\n)$"}],relevance:0}]},{begin:"^[-\\*]{3,}",end:"$"},a,{begin:/^\[[^\n]+\]:/,returnBegin:!0,contains:[{className:"symbol",begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0},{className:"link",begin:/:\s*/,end:/$/,excludeBegin:!0}]}]}}}()); -hljs.registerLanguage("nginx",function(){"use strict";return function(e){var n={className:"variable",variants:[{begin:/\$\d+/},{begin:/\$\{/,end:/}/},{begin:"[\\$\\@]"+e.UNDERSCORE_IDENT_RE}]},a={endsWithParent:!0,keywords:{$pattern:"[a-z/_]+",literal:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},relevance:0,illegal:"=>",contains:[e.HASH_COMMENT_MODE,{className:"string",contains:[e.BACKSLASH_ESCAPE,n],variants:[{begin:/"/,end:/"/},{begin:/'/,end:/'/}]},{begin:"([a-z]+):/",end:"\\s",endsWithParent:!0,excludeEnd:!0,contains:[n]},{className:"regexp",contains:[e.BACKSLASH_ESCAPE,n],variants:[{begin:"\\s\\^",end:"\\s|{|;",returnEnd:!0},{begin:"~\\*?\\s+",end:"\\s|{|;",returnEnd:!0},{begin:"\\*(\\.[a-z\\-]+)+"},{begin:"([a-z\\-]+\\.)+\\*"}]},{className:"number",begin:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{className:"number",begin:"\\b\\d+[kKmMgGdshdwy]*\\b",relevance:0},n]};return{name:"Nginx config",aliases:["nginxconf"],contains:[e.HASH_COMMENT_MODE,{begin:e.UNDERSCORE_IDENT_RE+"\\s+{",returnBegin:!0,end:"{",contains:[{className:"section",begin:e.UNDERSCORE_IDENT_RE}],relevance:0},{begin:e.UNDERSCORE_IDENT_RE+"\\s",end:";|{",returnBegin:!0,contains:[{className:"attribute",begin:e.UNDERSCORE_IDENT_RE,starts:a}],relevance:0}],illegal:"[^\\s\\}]"}}}()); -hljs.registerLanguage("objectivec",function(){"use strict";return function(e){var n=/[a-zA-Z@][a-zA-Z0-9_]*/,_={$pattern:n,keyword:"@interface @class @protocol @implementation"};return{name:"Objective-C",aliases:["mm","objc","obj-c"],keywords:{$pattern:n,keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required @encode @package @import @defs @compatibility_alias __bridge __bridge_transfer __bridge_retained __bridge_retain __covariant __contravariant __kindof _Nonnull _Nullable _Null_unspecified __FUNCTION__ __PRETTY_FUNCTION__ __attribute__ getter setter retain unsafe_unretained nonnull nullable null_unspecified null_resettable class instancetype NS_DESIGNATED_INITIALIZER NS_UNAVAILABLE NS_REQUIRES_SUPER NS_RETURNS_INNER_POINTER NS_INLINE NS_AVAILABLE NS_DEPRECATED NS_ENUM NS_OPTIONS NS_SWIFT_UNAVAILABLE NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END NS_REFINED_FOR_SWIFT NS_SWIFT_NAME NS_SWIFT_NOTHROW NS_DURING NS_HANDLER NS_ENDHANDLER NS_VALUERETURN NS_VOIDRETURN",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},illegal:"/,end:/$/,illegal:"\\n"},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"class",begin:"("+_.keyword.split(" ").join("|")+")\\b",end:"({|$)",excludeEnd:!0,keywords:_,contains:[e.UNDERSCORE_TITLE_MODE]},{begin:"\\."+e.UNDERSCORE_IDENT_RE,relevance:0}]}}}()); -hljs.registerLanguage("perl",function(){"use strict";return function(e){var n={$pattern:/[\w.]+/,keyword:"getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qq fileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmget sub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedir ioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when"},t={className:"subst",begin:"[$@]\\{",end:"\\}",keywords:n},s={begin:"->{",end:"}"},r={variants:[{begin:/\$\d/},{begin:/[\$%@](\^\w\b|#\w+(::\w+)*|{\w+}|\w+(::\w*)*)/},{begin:/[\$%@][^\s\w{]/,relevance:0}]},i=[e.BACKSLASH_ESCAPE,t,r],a=[r,e.HASH_COMMENT_MODE,e.COMMENT("^\\=\\w","\\=cut",{endsWithParent:!0}),s,{className:"string",contains:i,variants:[{begin:"q[qwxr]?\\s*\\(",end:"\\)",relevance:5},{begin:"q[qwxr]?\\s*\\[",end:"\\]",relevance:5},{begin:"q[qwxr]?\\s*\\{",end:"\\}",relevance:5},{begin:"q[qwxr]?\\s*\\|",end:"\\|",relevance:5},{begin:"q[qwxr]?\\s*\\<",end:"\\>",relevance:5},{begin:"qw\\s+q",end:"q",relevance:5},{begin:"'",end:"'",contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"'},{begin:"`",end:"`",contains:[e.BACKSLASH_ESCAPE]},{begin:"{\\w+}",contains:[],relevance:0},{begin:"-?\\w+\\s*\\=\\>",contains:[],relevance:0}]},{className:"number",begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",relevance:0},{begin:"(\\/\\/|"+e.RE_STARTERS_RE+"|\\b(split|return|print|reverse|grep)\\b)\\s*",keywords:"split return print reverse grep",relevance:0,contains:[e.HASH_COMMENT_MODE,{className:"regexp",begin:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",relevance:10},{className:"regexp",begin:"(m|qr)?/",end:"/[a-z]*",contains:[e.BACKSLASH_ESCAPE],relevance:0}]},{className:"function",beginKeywords:"sub",end:"(\\s*\\(.*?\\))?[;{]",excludeEnd:!0,relevance:5,contains:[e.TITLE_MODE]},{begin:"-\\w\\b",relevance:0},{begin:"^__DATA__$",end:"^__END__$",subLanguage:"mojolicious",contains:[{begin:"^@@.*",end:"$",className:"comment"}]}];return t.contains=a,s.contains=a,{name:"Perl",aliases:["pl","pm"],keywords:n,contains:a}}}()); -hljs.registerLanguage("php",function(){"use strict";return function(e){var r={begin:"\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*"},t={className:"meta",variants:[{begin:/<\?php/,relevance:10},{begin:/<\?[=]?/},{begin:/\?>/}]},a={className:"string",contains:[e.BACKSLASH_ESCAPE,t],variants:[{begin:'b"',end:'"'},{begin:"b'",end:"'"},e.inherit(e.APOS_STRING_MODE,{illegal:null}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null})]},n={variants:[e.BINARY_NUMBER_MODE,e.C_NUMBER_MODE]},i={keyword:"__CLASS__ __DIR__ __FILE__ __FUNCTION__ __LINE__ __METHOD__ __NAMESPACE__ __TRAIT__ die echo exit include include_once print require require_once array abstract and as binary bool boolean break callable case catch class clone const continue declare default do double else elseif empty enddeclare endfor endforeach endif endswitch endwhile eval extends final finally float for foreach from global goto if implements instanceof insteadof int integer interface isset iterable list new object or private protected public real return string switch throw trait try unset use var void while xor yield",literal:"false null true",built_in:"Error|0 AppendIterator ArgumentCountError ArithmeticError ArrayIterator ArrayObject AssertionError BadFunctionCallException BadMethodCallException CachingIterator CallbackFilterIterator CompileError Countable DirectoryIterator DivisionByZeroError DomainException EmptyIterator ErrorException Exception FilesystemIterator FilterIterator GlobIterator InfiniteIterator InvalidArgumentException IteratorIterator LengthException LimitIterator LogicException MultipleIterator NoRewindIterator OutOfBoundsException OutOfRangeException OuterIterator OverflowException ParentIterator ParseError RangeException RecursiveArrayIterator RecursiveCachingIterator RecursiveCallbackFilterIterator RecursiveDirectoryIterator RecursiveFilterIterator RecursiveIterator RecursiveIteratorIterator RecursiveRegexIterator RecursiveTreeIterator RegexIterator RuntimeException SeekableIterator SplDoublyLinkedList SplFileInfo SplFileObject SplFixedArray SplHeap SplMaxHeap SplMinHeap SplObjectStorage SplObserver SplObserver SplPriorityQueue SplQueue SplStack SplSubject SplSubject SplTempFileObject TypeError UnderflowException UnexpectedValueException ArrayAccess Closure Generator Iterator IteratorAggregate Serializable Throwable Traversable WeakReference Directory __PHP_Incomplete_Class parent php_user_filter self static stdClass"};return{aliases:["php","php3","php4","php5","php6","php7"],case_insensitive:!0,keywords:i,contains:[e.HASH_COMMENT_MODE,e.COMMENT("//","$",{contains:[t]}),e.COMMENT("/\\*","\\*/",{contains:[{className:"doctag",begin:"@[A-Za-z]+"}]}),e.COMMENT("__halt_compiler.+?;",!1,{endsWithParent:!0,keywords:"__halt_compiler"}),{className:"string",begin:/<<<['"]?\w+['"]?$/,end:/^\w+;?$/,contains:[e.BACKSLASH_ESCAPE,{className:"subst",variants:[{begin:/\$\w+/},{begin:/\{\$/,end:/\}/}]}]},t,{className:"keyword",begin:/\$this\b/},r,{begin:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{className:"function",beginKeywords:"fn function",end:/[;{]/,excludeEnd:!0,illegal:"[$%\\[]",contains:[e.UNDERSCORE_TITLE_MODE,{className:"params",begin:"\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0,keywords:i,contains:["self",r,e.C_BLOCK_COMMENT_MODE,a,n]}]},{className:"class",beginKeywords:"class interface",end:"{",excludeEnd:!0,illegal:/[:\(\$"]/,contains:[{beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"namespace",end:";",illegal:/[\.']/,contains:[e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"use",end:";",contains:[e.UNDERSCORE_TITLE_MODE]},{begin:"=>"},a,n]}}}()); -hljs.registerLanguage("php-template",function(){"use strict";return function(n){return{name:"PHP template",subLanguage:"xml",contains:[{begin:/<\?(php|=)?/,end:/\?>/,subLanguage:"php",contains:[{begin:"/\\*",end:"\\*/",skip:!0},{begin:'b"',end:'"',skip:!0},{begin:"b'",end:"'",skip:!0},n.inherit(n.APOS_STRING_MODE,{illegal:null,className:null,contains:null,skip:!0}),n.inherit(n.QUOTE_STRING_MODE,{illegal:null,className:null,contains:null,skip:!0})]}]}}}()); -hljs.registerLanguage("plaintext",function(){"use strict";return function(t){return{name:"Plain text",aliases:["text","txt"],disableAutodetect:!0}}}()); -hljs.registerLanguage("properties",function(){"use strict";return function(e){var n="[ \\t\\f]*",t="("+n+"[:=]"+n+"|[ \\t\\f]+)",a="([^\\\\:= \\t\\f\\n]|\\\\.)+",s={end:t,relevance:0,starts:{className:"string",end:/$/,relevance:0,contains:[{begin:"\\\\\\n"}]}};return{name:".properties",case_insensitive:!0,illegal:/\S/,contains:[e.COMMENT("^\\s*[!#]","$"),{begin:"([^\\\\\\W:= \\t\\f\\n]|\\\\.)+"+t,returnBegin:!0,contains:[{className:"attr",begin:"([^\\\\\\W:= \\t\\f\\n]|\\\\.)+",endsParent:!0,relevance:0}],starts:s},{begin:a+t,returnBegin:!0,relevance:0,contains:[{className:"meta",begin:a,endsParent:!0,relevance:0}],starts:s},{className:"attr",relevance:0,begin:a+n+"$"}]}}}()); -hljs.registerLanguage("python",function(){"use strict";return function(e){var n={keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10",built_in:"Ellipsis NotImplemented",literal:"False None True"},a={className:"meta",begin:/^(>>>|\.\.\.) /},i={className:"subst",begin:/\{/,end:/\}/,keywords:n,illegal:/#/},s={begin:/\{\{/,relevance:0},r={className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{begin:/(u|b)?r?'''/,end:/'''/,contains:[e.BACKSLASH_ESCAPE,a],relevance:10},{begin:/(u|b)?r?"""/,end:/"""/,contains:[e.BACKSLASH_ESCAPE,a],relevance:10},{begin:/(fr|rf|f)'''/,end:/'''/,contains:[e.BACKSLASH_ESCAPE,a,s,i]},{begin:/(fr|rf|f)"""/,end:/"""/,contains:[e.BACKSLASH_ESCAPE,a,s,i]},{begin:/(u|r|ur)'/,end:/'/,relevance:10},{begin:/(u|r|ur)"/,end:/"/,relevance:10},{begin:/(b|br)'/,end:/'/},{begin:/(b|br)"/,end:/"/},{begin:/(fr|rf|f)'/,end:/'/,contains:[e.BACKSLASH_ESCAPE,s,i]},{begin:/(fr|rf|f)"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,s,i]},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},l={className:"number",relevance:0,variants:[{begin:e.BINARY_NUMBER_RE+"[lLjJ]?"},{begin:"\\b(0o[0-7]+)[lLjJ]?"},{begin:e.C_NUMBER_RE+"[lLjJ]?"}]},t={className:"params",variants:[{begin:/\(\s*\)/,skip:!0,className:null},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,contains:["self",a,l,r,e.HASH_COMMENT_MODE]}]};return i.contains=[r,l,a],{name:"Python",aliases:["py","gyp","ipython"],keywords:n,illegal:/(<\/|->|\?)|=>/,contains:[a,l,{beginKeywords:"if",relevance:0},r,e.HASH_COMMENT_MODE,{variants:[{className:"function",beginKeywords:"def"},{className:"class",beginKeywords:"class"}],end:/:/,illegal:/[${=;\n,]/,contains:[e.UNDERSCORE_TITLE_MODE,t,{begin:/->/,endsWithParent:!0,keywords:"None"}]},{className:"meta",begin:/^[\t ]*@/,end:/$/},{begin:/\b(print|exec)\(/}]}}}()); -hljs.registerLanguage("python-repl",function(){"use strict";return function(n){return{aliases:["pycon"],contains:[{className:"meta",starts:{end:/ |$/,starts:{end:"$",subLanguage:"python"}},variants:[{begin:/^>>>(?=[ ]|$)/},{begin:/^\.\.\.(?=[ ]|$)/}]}]}}}()); -hljs.registerLanguage("ruby",function(){"use strict";return function(e){var n="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",a={keyword:"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",literal:"true false nil"},s={className:"doctag",begin:"@[A-Za-z]+"},i={begin:"#<",end:">"},r=[e.COMMENT("#","$",{contains:[s]}),e.COMMENT("^\\=begin","^\\=end",{contains:[s],relevance:10}),e.COMMENT("^__END__","\\n$")],c={className:"subst",begin:"#\\{",end:"}",keywords:a},t={className:"string",contains:[e.BACKSLASH_ESCAPE,c],variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/`/,end:/`/},{begin:"%[qQwWx]?\\(",end:"\\)"},{begin:"%[qQwWx]?\\[",end:"\\]"},{begin:"%[qQwWx]?{",end:"}"},{begin:"%[qQwWx]?<",end:">"},{begin:"%[qQwWx]?/",end:"/"},{begin:"%[qQwWx]?%",end:"%"},{begin:"%[qQwWx]?-",end:"-"},{begin:"%[qQwWx]?\\|",end:"\\|"},{begin:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/},{begin:/<<[-~]?'?(\w+)(?:.|\n)*?\n\s*\1\b/,returnBegin:!0,contains:[{begin:/<<[-~]?'?/},e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/,contains:[e.BACKSLASH_ESCAPE,c]})]}]},b={className:"params",begin:"\\(",end:"\\)",endsParent:!0,keywords:a},d=[t,i,{className:"class",beginKeywords:"class module",end:"$|;",illegal:/=/,contains:[e.inherit(e.TITLE_MODE,{begin:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{begin:"<\\s*",contains:[{begin:"("+e.IDENT_RE+"::)?"+e.IDENT_RE}]}].concat(r)},{className:"function",beginKeywords:"def",end:"$|;",contains:[e.inherit(e.TITLE_MODE,{begin:n}),b].concat(r)},{begin:e.IDENT_RE+"::"},{className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"(\\!|\\?)?:",relevance:0},{className:"symbol",begin:":(?!\\s)",contains:[t,{begin:n}],relevance:0},{className:"number",begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",relevance:0},{begin:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{className:"params",begin:/\|/,end:/\|/,keywords:a},{begin:"("+e.RE_STARTERS_RE+"|unless)\\s*",keywords:"unless",contains:[i,{className:"regexp",contains:[e.BACKSLASH_ESCAPE,c],illegal:/\n/,variants:[{begin:"/",end:"/[a-z]*"},{begin:"%r{",end:"}[a-z]*"},{begin:"%r\\(",end:"\\)[a-z]*"},{begin:"%r!",end:"![a-z]*"},{begin:"%r\\[",end:"\\][a-z]*"}]}].concat(r),relevance:0}].concat(r);c.contains=d,b.contains=d;var g=[{begin:/^\s*=>/,starts:{end:"$",contains:d}},{className:"meta",begin:"^([>?]>|[\\w#]+\\(\\w+\\):\\d+:\\d+>|(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>)",starts:{end:"$",contains:d}}];return{name:"Ruby",aliases:["rb","gemspec","podspec","thor","irb"],keywords:a,illegal:/\/\*/,contains:r.concat(g).concat(d)}}}()); -hljs.registerLanguage("rust",function(){"use strict";return function(e){var n="([ui](8|16|32|64|128|size)|f(32|64))?",t="drop i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize f32 f64 str char bool Box Option Result String Vec Copy Send Sized Sync Drop Fn FnMut FnOnce ToOwned Clone Debug PartialEq PartialOrd Eq Ord AsRef AsMut Into From Default Iterator Extend IntoIterator DoubleEndedIterator ExactSizeIterator SliceConcatExt ToString assert! assert_eq! bitflags! bytes! cfg! col! concat! concat_idents! debug_assert! debug_assert_eq! env! panic! file! format! format_args! include_bin! include_str! line! local_data_key! module_path! option_env! print! println! select! stringify! try! unimplemented! unreachable! vec! write! writeln! macro_rules! assert_ne! debug_assert_ne!";return{name:"Rust",aliases:["rs"],keywords:{$pattern:e.IDENT_RE+"!?",keyword:"abstract as async await become box break const continue crate do dyn else enum extern false final fn for if impl in let loop macro match mod move mut override priv pub ref return self Self static struct super trait true try type typeof unsafe unsized use virtual where while yield",literal:"true false Some None Ok Err",built_in:t},illegal:""}]}}}()); -hljs.registerLanguage("scss",function(){"use strict";return function(e){var t={className:"variable",begin:"(\\$[a-zA-Z-][a-zA-Z0-9_-]*)\\b"},i={className:"number",begin:"#[0-9A-Fa-f]+"};return e.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,e.C_BLOCK_COMMENT_MODE,{name:"SCSS",case_insensitive:!0,illegal:"[=/|']",contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"selector-id",begin:"\\#[A-Za-z0-9_-]+",relevance:0},{className:"selector-class",begin:"\\.[A-Za-z0-9_-]+",relevance:0},{className:"selector-attr",begin:"\\[",end:"\\]",illegal:"$"},{className:"selector-tag",begin:"\\b(a|abbr|acronym|address|area|article|aside|audio|b|base|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|command|datalist|dd|del|details|dfn|div|dl|dt|em|embed|fieldset|figcaption|figure|footer|form|frame|frameset|(h[1-6])|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|keygen|label|legend|li|link|map|mark|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|samp|script|section|select|small|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|ul|var|video)\\b",relevance:0},{className:"selector-pseudo",begin:":(visited|valid|root|right|required|read-write|read-only|out-range|optional|only-of-type|only-child|nth-of-type|nth-last-of-type|nth-last-child|nth-child|not|link|left|last-of-type|last-child|lang|invalid|indeterminate|in-range|hover|focus|first-of-type|first-line|first-letter|first-child|first|enabled|empty|disabled|default|checked|before|after|active)"},{className:"selector-pseudo",begin:"::(after|before|choices|first-letter|first-line|repeat-index|repeat-item|selection|value)"},t,{className:"attribute",begin:"\\b(src|z-index|word-wrap|word-spacing|word-break|width|widows|white-space|visibility|vertical-align|unicode-bidi|transition-timing-function|transition-property|transition-duration|transition-delay|transition|transform-style|transform-origin|transform|top|text-underline-position|text-transform|text-shadow|text-rendering|text-overflow|text-indent|text-decoration-style|text-decoration-line|text-decoration-color|text-decoration|text-align-last|text-align|tab-size|table-layout|right|resize|quotes|position|pointer-events|perspective-origin|perspective|page-break-inside|page-break-before|page-break-after|padding-top|padding-right|padding-left|padding-bottom|padding|overflow-y|overflow-x|overflow-wrap|overflow|outline-width|outline-style|outline-offset|outline-color|outline|orphans|order|opacity|object-position|object-fit|normal|none|nav-up|nav-right|nav-left|nav-index|nav-down|min-width|min-height|max-width|max-height|mask|marks|margin-top|margin-right|margin-left|margin-bottom|margin|list-style-type|list-style-position|list-style-image|list-style|line-height|letter-spacing|left|justify-content|initial|inherit|ime-mode|image-orientation|image-resolution|image-rendering|icon|hyphens|height|font-weight|font-variant-ligatures|font-variant|font-style|font-stretch|font-size-adjust|font-size|font-language-override|font-kerning|font-feature-settings|font-family|font|float|flex-wrap|flex-shrink|flex-grow|flex-flow|flex-direction|flex-basis|flex|filter|empty-cells|display|direction|cursor|counter-reset|counter-increment|content|column-width|column-span|column-rule-width|column-rule-style|column-rule-color|column-rule|column-gap|column-fill|column-count|columns|color|clip-path|clip|clear|caption-side|break-inside|break-before|break-after|box-sizing|box-shadow|box-decoration-break|bottom|border-width|border-top-width|border-top-style|border-top-right-radius|border-top-left-radius|border-top-color|border-top|border-style|border-spacing|border-right-width|border-right-style|border-right-color|border-right|border-radius|border-left-width|border-left-style|border-left-color|border-left|border-image-width|border-image-source|border-image-slice|border-image-repeat|border-image-outset|border-image|border-color|border-collapse|border-bottom-width|border-bottom-style|border-bottom-right-radius|border-bottom-left-radius|border-bottom-color|border-bottom|border|background-size|background-repeat|background-position|background-origin|background-image|background-color|background-clip|background-attachment|background-blend-mode|background|backface-visibility|auto|animation-timing-function|animation-play-state|animation-name|animation-iteration-count|animation-fill-mode|animation-duration|animation-direction|animation-delay|animation|align-self|align-items|align-content)\\b",illegal:"[^\\s]"},{begin:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b"},{begin:":",end:";",contains:[t,i,e.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,{className:"meta",begin:"!important"}]},{begin:"@(page|font-face)",lexemes:"@[a-z-]+",keywords:"@page @font-face"},{begin:"@",end:"[{;]",returnBegin:!0,keywords:"and or not only",contains:[{begin:"@[a-z-]+",className:"keyword"},t,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,i,e.CSS_NUMBER_MODE]}]}}}()); -hljs.registerLanguage("shell",function(){"use strict";return function(s){return{name:"Shell Session",aliases:["console"],contains:[{className:"meta",begin:"^\\s{0,3}[/\\w\\d\\[\\]()@-]*[>%$#]",starts:{end:"$",subLanguage:"bash"}}]}}}()); -hljs.registerLanguage("sql",function(){"use strict";return function(e){var t=e.COMMENT("--","$");return{name:"SQL",case_insensitive:!0,illegal:/[<>{}*]/,contains:[{beginKeywords:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke comment values with",end:/;/,endsWithParent:!0,keywords:{$pattern:/[\w\.]+/,keyword:"as abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias all allocate allow alter always analyze ancillary and anti any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound bucket buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain explode export export_set extended extent external external_1 external_2 externally extract failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force foreign form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour hours http id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists keep keep_duplicates key keys kill language large last last_day last_insert_id last_value lateral lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minutes minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notnull notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second seconds section securefile security seed segment select self semi sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime table tables tablespace tablesample tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unnest unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace window with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek",literal:"true false null unknown",built_in:"array bigint binary bit blob bool boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text time timestamp tinyint varchar varchar2 varying void"},contains:[{className:"string",begin:"'",end:"'",contains:[{begin:"''"}]},{className:"string",begin:'"',end:'"',contains:[{begin:'""'}]},{className:"string",begin:"`",end:"`"},e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE,t,e.HASH_COMMENT_MODE]},e.C_BLOCK_COMMENT_MODE,t,e.HASH_COMMENT_MODE]}}}()); -hljs.registerLanguage("swift",function(){"use strict";return function(e){var i={keyword:"#available #colorLiteral #column #else #elseif #endif #file #fileLiteral #function #if #imageLiteral #line #selector #sourceLocation _ __COLUMN__ __FILE__ __FUNCTION__ __LINE__ Any as as! as? associatedtype associativity break case catch class continue convenience default defer deinit didSet do dynamic dynamicType else enum extension fallthrough false fileprivate final for func get guard if import in indirect infix init inout internal is lazy left let mutating nil none nonmutating open operator optional override postfix precedence prefix private protocol Protocol public repeat required rethrows return right self Self set static struct subscript super switch throw throws true try try! try? Type typealias unowned var weak where while willSet",literal:"true false nil",built_in:"abs advance alignof alignofValue anyGenerator assert assertionFailure bridgeFromObjectiveC bridgeFromObjectiveCUnconditional bridgeToObjectiveC bridgeToObjectiveCUnconditional c compactMap contains count countElements countLeadingZeros debugPrint debugPrintln distance dropFirst dropLast dump encodeBitsAsWords enumerate equal fatalError filter find getBridgedObjectiveCType getVaList indices insertionSort isBridgedToObjectiveC isBridgedVerbatimToObjectiveC isUniquelyReferenced isUniquelyReferencedNonObjC join lazy lexicographicalCompare map max maxElement min minElement numericCast overlaps partition posix precondition preconditionFailure print println quickSort readLine reduce reflect reinterpretCast reverse roundUpToAlignment sizeof sizeofValue sort split startsWith stride strideof strideofValue swap toString transcode underestimateCount unsafeAddressOf unsafeBitCast unsafeDowncast unsafeUnwrap unsafeReflect withExtendedLifetime withObjectAtPlusZero withUnsafePointer withUnsafePointerToObject withUnsafeMutablePointer withUnsafeMutablePointers withUnsafePointer withUnsafePointers withVaList zip"},n=e.COMMENT("/\\*","\\*/",{contains:["self"]}),t={className:"subst",begin:/\\\(/,end:"\\)",keywords:i,contains:[]},a={className:"string",contains:[e.BACKSLASH_ESCAPE,t],variants:[{begin:/"""/,end:/"""/},{begin:/"/,end:/"/}]},r={className:"number",begin:"\\b([\\d_]+(\\.[\\deE_]+)?|0x[a-fA-F0-9_]+(\\.[a-fA-F0-9p_]+)?|0b[01_]+|0o[0-7_]+)\\b",relevance:0};return t.contains=[r],{name:"Swift",keywords:i,contains:[a,e.C_LINE_COMMENT_MODE,n,{className:"type",begin:"\\b[A-Z][\\wÀ-ʸ']*[!?]"},{className:"type",begin:"\\b[A-Z][\\wÀ-ʸ']*",relevance:0},r,{className:"function",beginKeywords:"func",end:"{",excludeEnd:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/[A-Za-z$_][0-9A-Za-z$_]*/}),{begin://},{className:"params",begin:/\(/,end:/\)/,endsParent:!0,keywords:i,contains:["self",r,a,e.C_BLOCK_COMMENT_MODE,{begin:":"}],illegal:/["']/}],illegal:/\[|%/},{className:"class",beginKeywords:"struct protocol class extension enum",keywords:i,end:"\\{",excludeEnd:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/[A-Za-z$_][\u00C0-\u02B80-9A-Za-z$_]*/})]},{className:"meta",begin:"(@discardableResult|@warn_unused_result|@exported|@lazy|@noescape|@NSCopying|@NSManaged|@objc|@objcMembers|@convention|@required|@noreturn|@IBAction|@IBDesignable|@IBInspectable|@IBOutlet|@infix|@prefix|@postfix|@autoclosure|@testable|@available|@nonobjc|@NSApplicationMain|@UIApplicationMain|@dynamicMemberLookup|@propertyWrapper)\\b"},{beginKeywords:"import",end:/$/,contains:[e.C_LINE_COMMENT_MODE,n]}]}}}()); -hljs.registerLanguage("typescript",function(){"use strict";const e=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],n=["true","false","null","undefined","NaN","Infinity"],a=[].concat(["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],["arguments","this","super","console","window","document","localStorage","module","global"],["Intl","DataView","Number","Math","Date","String","RegExp","Object","Function","Boolean","Error","Symbol","Set","Map","WeakSet","WeakMap","Proxy","Reflect","JSON","Promise","Float64Array","Int16Array","Int32Array","Int8Array","Uint16Array","Uint32Array","Float32Array","Array","Uint8Array","Uint8ClampedArray","ArrayBuffer"],["EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"]);return function(r){var t={$pattern:"[A-Za-z$_][0-9A-Za-z$_]*",keyword:e.concat(["type","namespace","typedef","interface","public","private","protected","implements","declare","abstract","readonly"]).join(" "),literal:n.join(" "),built_in:a.concat(["any","void","number","boolean","string","object","never","enum"]).join(" ")},s={className:"meta",begin:"@[A-Za-z$_][0-9A-Za-z$_]*"},i={className:"number",variants:[{begin:"\\b(0[bB][01]+)n?"},{begin:"\\b(0[oO][0-7]+)n?"},{begin:r.C_NUMBER_RE+"n?"}],relevance:0},o={className:"subst",begin:"\\$\\{",end:"\\}",keywords:t,contains:[]},c={begin:"html`",end:"",starts:{end:"`",returnEnd:!1,contains:[r.BACKSLASH_ESCAPE,o],subLanguage:"xml"}},l={begin:"css`",end:"",starts:{end:"`",returnEnd:!1,contains:[r.BACKSLASH_ESCAPE,o],subLanguage:"css"}},E={className:"string",begin:"`",end:"`",contains:[r.BACKSLASH_ESCAPE,o]};o.contains=[r.APOS_STRING_MODE,r.QUOTE_STRING_MODE,c,l,E,i,r.REGEXP_MODE];var d={begin:"\\(",end:/\)/,keywords:t,contains:["self",r.QUOTE_STRING_MODE,r.APOS_STRING_MODE,r.NUMBER_MODE]},u={className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:t,contains:[r.C_LINE_COMMENT_MODE,r.C_BLOCK_COMMENT_MODE,s,d]};return{name:"TypeScript",aliases:["ts"],keywords:t,contains:[r.SHEBANG(),{className:"meta",begin:/^\s*['"]use strict['"]/},r.APOS_STRING_MODE,r.QUOTE_STRING_MODE,c,l,E,r.C_LINE_COMMENT_MODE,r.C_BLOCK_COMMENT_MODE,i,{begin:"("+r.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*",keywords:"return throw case",contains:[r.C_LINE_COMMENT_MODE,r.C_BLOCK_COMMENT_MODE,r.REGEXP_MODE,{className:"function",begin:"(\\([^(]*(\\([^(]*(\\([^(]*\\))?\\))?\\)|"+r.UNDERSCORE_IDENT_RE+")\\s*=>",returnBegin:!0,end:"\\s*=>",contains:[{className:"params",variants:[{begin:r.UNDERSCORE_IDENT_RE},{className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:t,contains:d.contains}]}]}],relevance:0},{className:"function",beginKeywords:"function",end:/[\{;]/,excludeEnd:!0,keywords:t,contains:["self",r.inherit(r.TITLE_MODE,{begin:"[A-Za-z$_][0-9A-Za-z$_]*"}),u],illegal:/%/,relevance:0},{beginKeywords:"constructor",end:/[\{;]/,excludeEnd:!0,contains:["self",u]},{begin:/module\./,keywords:{built_in:"module"},relevance:0},{beginKeywords:"module",end:/\{/,excludeEnd:!0},{beginKeywords:"interface",end:/\{/,excludeEnd:!0,keywords:"interface extends"},{begin:/\$[(.]/},{begin:"\\."+r.IDENT_RE,relevance:0},s,d]}}}()); -hljs.registerLanguage("yaml",function(){"use strict";return function(e){var n="true false yes no null",a="[\\w#;/?:@&=+$,.~*\\'()[\\]]+",s={className:"string",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/\S+/}],contains:[e.BACKSLASH_ESCAPE,{className:"template-variable",variants:[{begin:"{{",end:"}}"},{begin:"%{",end:"}"}]}]},i=e.inherit(s,{variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/[^\s,{}[\]]+/}]}),l={end:",",endsWithParent:!0,excludeEnd:!0,contains:[],keywords:n,relevance:0},t={begin:"{",end:"}",contains:[l],illegal:"\\n",relevance:0},g={begin:"\\[",end:"\\]",contains:[l],illegal:"\\n",relevance:0},b=[{className:"attr",variants:[{begin:"\\w[\\w :\\/.-]*:(?=[ \t]|$)"},{begin:'"\\w[\\w :\\/.-]*":(?=[ \t]|$)'},{begin:"'\\w[\\w :\\/.-]*':(?=[ \t]|$)"}]},{className:"meta",begin:"^---s*$",relevance:10},{className:"string",begin:"[\\|>]([0-9]?[+-])?[ ]*\\n( *)[\\S ]+\\n(\\2[\\S ]+\\n?)*"},{begin:"<%[%=-]?",end:"[%-]?%>",subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:"!\\w+!"+a},{className:"type",begin:"!<"+a+">"},{className:"type",begin:"!"+a},{className:"type",begin:"!!"+a},{className:"meta",begin:"&"+e.UNDERSCORE_IDENT_RE+"$"},{className:"meta",begin:"\\*"+e.UNDERSCORE_IDENT_RE+"$"},{className:"bullet",begin:"\\-(?=[ ]|$)",relevance:0},e.HASH_COMMENT_MODE,{beginKeywords:n,keywords:{literal:n}},{className:"number",begin:"\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b"},{className:"number",begin:e.C_NUMBER_RE+"\\b"},t,g,s],c=[...b];return c.pop(),c.push(i),l.contains=c,{name:"YAML",case_insensitive:!0,aliases:["yml","YAML"],contains:b}}}()); -hljs.registerLanguage("armasm",function(){"use strict";return function(s){const e={variants:[s.COMMENT("^[ \\t]*(?=#)","$",{relevance:0,excludeBegin:!0}),s.COMMENT("[;@]","$",{relevance:0}),s.C_LINE_COMMENT_MODE,s.C_BLOCK_COMMENT_MODE]};return{name:"ARM Assembly",case_insensitive:!0,aliases:["arm"],keywords:{$pattern:"\\.?"+s.IDENT_RE,meta:".2byte .4byte .align .ascii .asciz .balign .byte .code .data .else .end .endif .endm .endr .equ .err .exitm .extern .global .hword .if .ifdef .ifndef .include .irp .long .macro .rept .req .section .set .skip .space .text .word .arm .thumb .code16 .code32 .force_thumb .thumb_func .ltorg ALIAS ALIGN ARM AREA ASSERT ATTR CN CODE CODE16 CODE32 COMMON CP DATA DCB DCD DCDU DCDO DCFD DCFDU DCI DCQ DCQU DCW DCWU DN ELIF ELSE END ENDFUNC ENDIF ENDP ENTRY EQU EXPORT EXPORTAS EXTERN FIELD FILL FUNCTION GBLA GBLL GBLS GET GLOBAL IF IMPORT INCBIN INCLUDE INFO KEEP LCLA LCLL LCLS LTORG MACRO MAP MEND MEXIT NOFP OPT PRESERVE8 PROC QN READONLY RELOC REQUIRE REQUIRE8 RLIST FN ROUT SETA SETL SETS SN SPACE SUBT THUMB THUMBX TTL WHILE WEND ",built_in:"r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 pc lr sp ip sl sb fp a1 a2 a3 a4 v1 v2 v3 v4 v5 v6 v7 v8 f0 f1 f2 f3 f4 f5 f6 f7 p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 q0 q1 q2 q3 q4 q5 q6 q7 q8 q9 q10 q11 q12 q13 q14 q15 cpsr_c cpsr_x cpsr_s cpsr_f cpsr_cx cpsr_cxs cpsr_xs cpsr_xsf cpsr_sf cpsr_cxsf spsr_c spsr_x spsr_s spsr_f spsr_cx spsr_cxs spsr_xs spsr_xsf spsr_sf spsr_cxsf s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 s13 s14 s15 s16 s17 s18 s19 s20 s21 s22 s23 s24 s25 s26 s27 s28 s29 s30 s31 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 d14 d15 d16 d17 d18 d19 d20 d21 d22 d23 d24 d25 d26 d27 d28 d29 d30 d31 {PC} {VAR} {TRUE} {FALSE} {OPT} {CONFIG} {ENDIAN} {CODESIZE} {CPU} {FPU} {ARCHITECTURE} {PCSTOREOFFSET} {ARMASM_VERSION} {INTER} {ROPI} {RWPI} {SWST} {NOSWST} . @"},contains:[{className:"keyword",begin:"\\b(adc|(qd?|sh?|u[qh]?)?add(8|16)?|usada?8|(q|sh?|u[qh]?)?(as|sa)x|and|adrl?|sbc|rs[bc]|asr|b[lx]?|blx|bxj|cbn?z|tb[bh]|bic|bfc|bfi|[su]bfx|bkpt|cdp2?|clz|clrex|cmp|cmn|cpsi[ed]|cps|setend|dbg|dmb|dsb|eor|isb|it[te]{0,3}|lsl|lsr|ror|rrx|ldm(([id][ab])|f[ds])?|ldr((s|ex)?[bhd])?|movt?|mvn|mra|mar|mul|[us]mull|smul[bwt][bt]|smu[as]d|smmul|smmla|mla|umlaal|smlal?([wbt][bt]|d)|mls|smlsl?[ds]|smc|svc|sev|mia([bt]{2}|ph)?|mrr?c2?|mcrr2?|mrs|msr|orr|orn|pkh(tb|bt)|rbit|rev(16|sh)?|sel|[su]sat(16)?|nop|pop|push|rfe([id][ab])?|stm([id][ab])?|str(ex)?[bhd]?|(qd?)?sub|(sh?|q|u[qh]?)?sub(8|16)|[su]xt(a?h|a?b(16)?)|srs([id][ab])?|swpb?|swi|smi|tst|teq|wfe|wfi|yield)(eq|ne|cs|cc|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al|hs|lo)?[sptrx]?(?=\\s)"},e,s.QUOTE_STRING_MODE,{className:"string",begin:"'",end:"[^\\\\]'",relevance:0},{className:"title",begin:"\\|",end:"\\|",illegal:"\\n",relevance:0},{className:"number",variants:[{begin:"[#$=]?0x[0-9a-f]+"},{begin:"[#$=]?0b[01]+"},{begin:"[#$=]\\d+"},{begin:"\\b\\d+"}],relevance:0},{className:"symbol",variants:[{begin:"^[ \\t]*[a-z_\\.\\$][a-z0-9_\\.\\$]+:"},{begin:"^[a-z_\\.\\$][a-z0-9_\\.\\$]+"},{begin:"[=#]\\w+"}],relevance:0}]}}}()); -hljs.registerLanguage("d",function(){"use strict";return function(e){var a={$pattern:e.UNDERSCORE_IDENT_RE,keyword:"abstract alias align asm assert auto body break byte case cast catch class const continue debug default delete deprecated do else enum export extern final finally for foreach foreach_reverse|10 goto if immutable import in inout int interface invariant is lazy macro mixin module new nothrow out override package pragma private protected public pure ref return scope shared static struct super switch synchronized template this throw try typedef typeid typeof union unittest version void volatile while with __FILE__ __LINE__ __gshared|10 __thread __traits __DATE__ __EOF__ __TIME__ __TIMESTAMP__ __VENDOR__ __VERSION__",built_in:"bool cdouble cent cfloat char creal dchar delegate double dstring float function idouble ifloat ireal long real short string ubyte ucent uint ulong ushort wchar wstring",literal:"false null true"},d="((0|[1-9][\\d_]*)|0[bB][01_]+|0[xX]([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*))",n="\\\\(['\"\\?\\\\abfnrtv]|u[\\dA-Fa-f]{4}|[0-7]{1,3}|x[\\dA-Fa-f]{2}|U[\\dA-Fa-f]{8})|&[a-zA-Z\\d]{2,};",t={className:"number",begin:"\\b"+d+"(L|u|U|Lu|LU|uL|UL)?",relevance:0},_={className:"number",begin:"\\b(((0[xX](([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)\\.([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)|\\.?([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*))[pP][+-]?(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d))|((0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)(\\.\\d*|([eE][+-]?(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)))|\\d+\\.(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)|\\.(0|[1-9][\\d_]*)([eE][+-]?(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d))?))([fF]|L|i|[fF]i|Li)?|"+d+"(i|[fF]i|Li))",relevance:0},r={className:"string",begin:"'("+n+"|.)",end:"'",illegal:"."},i={className:"string",begin:'"',contains:[{begin:n,relevance:0}],end:'"[cwd]?'},s=e.COMMENT("\\/\\+","\\+\\/",{contains:["self"],relevance:10});return{name:"D",keywords:a,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,s,{className:"string",begin:'x"[\\da-fA-F\\s\\n\\r]*"[cwd]?',relevance:10},i,{className:"string",begin:'[rq]"',end:'"[cwd]?',relevance:5},{className:"string",begin:"`",end:"`[cwd]?"},{className:"string",begin:'q"\\{',end:'\\}"'},_,t,r,{className:"meta",begin:"^#!",end:"$",relevance:5},{className:"meta",begin:"#(line)",end:"$",relevance:5},{className:"keyword",begin:"@[a-zA-Z_][a-zA-Z_\\d]*"}]}}}()); -hljs.registerLanguage("handlebars",function(){"use strict";function e(...e){return e.map(e=>(function(e){return e?"string"==typeof e?e:e.source:null})(e)).join("")}return function(n){const a={"builtin-name":"action bindattr collection component concat debugger each each-in get hash if in input link-to loc log lookup mut outlet partial query-params render template textarea unbound unless view with yield"},t=/\[.*?\]/,s=/[^\s!"#%&'()*+,.\/;<=>@\[\\\]^`{|}~]+/,i=e("(",/'.*?'/,"|",/".*?"/,"|",t,"|",s,"|",/\.|\//,")+"),r=e("(",t,"|",s,")(?==)"),l={begin:i,lexemes:/[\w.\/]+/},c=n.inherit(l,{keywords:{literal:"true false undefined null"}}),o={begin:/\(/,end:/\)/},m={className:"attr",begin:r,relevance:0,starts:{begin:/=/,end:/=/,starts:{contains:[n.NUMBER_MODE,n.QUOTE_STRING_MODE,n.APOS_STRING_MODE,c,o]}}},d={contains:[n.NUMBER_MODE,n.QUOTE_STRING_MODE,n.APOS_STRING_MODE,{begin:/as\s+\|/,keywords:{keyword:"as"},end:/\|/,contains:[{begin:/\w+/}]},m,c,o],returnEnd:!0},g=n.inherit(l,{className:"name",keywords:a,starts:n.inherit(d,{end:/\)/})});o.contains=[g];const u=n.inherit(l,{keywords:a,className:"name",starts:n.inherit(d,{end:/}}/})}),b=n.inherit(l,{keywords:a,className:"name"}),h=n.inherit(l,{className:"name",keywords:a,starts:n.inherit(d,{end:/}}/})});return{name:"Handlebars",aliases:["hbs","html.hbs","html.handlebars","htmlbars"],case_insensitive:!0,subLanguage:"xml",contains:[{begin:/\\\{\{/,skip:!0},{begin:/\\\\(?=\{\{)/,skip:!0},n.COMMENT(/\{\{!--/,/--\}\}/),n.COMMENT(/\{\{!/,/\}\}/),{className:"template-tag",begin:/\{\{\{\{(?!\/)/,end:/\}\}\}\}/,contains:[u],starts:{end:/\{\{\{\{\//,returnEnd:!0,subLanguage:"xml"}},{className:"template-tag",begin:/\{\{\{\{\//,end:/\}\}\}\}/,contains:[b]},{className:"template-tag",begin:/\{\{#/,end:/\}\}/,contains:[u]},{className:"template-tag",begin:/\{\{(?=else\}\})/,end:/\}\}/,keywords:"else"},{className:"template-tag",begin:/\{\{\//,end:/\}\}/,contains:[b]},{className:"template-variable",begin:/\{\{\{/,end:/\}\}\}/,contains:[h]},{className:"template-variable",begin:/\{\{/,end:/\}\}/,contains:[h]}]}}}()); -hljs.registerLanguage("haskell",function(){"use strict";return function(e){var n={variants:[e.COMMENT("--","$"),e.COMMENT("{-","-}",{contains:["self"]})]},i={className:"meta",begin:"{-#",end:"#-}"},a={className:"meta",begin:"^#",end:"$"},s={className:"type",begin:"\\b[A-Z][\\w']*",relevance:0},l={begin:"\\(",end:"\\)",illegal:'"',contains:[i,a,{className:"type",begin:"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},e.inherit(e.TITLE_MODE,{begin:"[_a-z][\\w']*"}),n]};return{name:"Haskell",aliases:["hs"],keywords:"let in if then else case of where do module import hiding qualified type data newtype deriving class instance as default infix infixl infixr foreign export ccall stdcall cplusplus jvm dotnet safe unsafe family forall mdo proc rec",contains:[{beginKeywords:"module",end:"where",keywords:"module where",contains:[l,n],illegal:"\\W\\.|;"},{begin:"\\bimport\\b",end:"$",keywords:"import qualified as hiding",contains:[l,n],illegal:"\\W\\.|;"},{className:"class",begin:"^(\\s*)?(class|instance)\\b",end:"where",keywords:"class family instance where",contains:[s,l,n]},{className:"class",begin:"\\b(data|(new)?type)\\b",end:"$",keywords:"data family type newtype deriving",contains:[i,s,l,{begin:"{",end:"}",contains:l.contains},n]},{beginKeywords:"default",end:"$",contains:[s,l,n]},{beginKeywords:"infix infixl infixr",end:"$",contains:[e.C_NUMBER_MODE,n]},{begin:"\\bforeign\\b",end:"$",keywords:"foreign import export ccall stdcall cplusplus jvm dotnet safe unsafe",contains:[s,e.QUOTE_STRING_MODE,n]},{className:"meta",begin:"#!\\/usr\\/bin\\/env runhaskell",end:"$"},i,a,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,s,e.inherit(e.TITLE_MODE,{begin:"^[_a-z][\\w']*"}),n,{begin:"->|<-"}]}}}()); -hljs.registerLanguage("julia",function(){"use strict";return function(e){var r="[A-Za-z_\\u00A1-\\uFFFF][A-Za-z_0-9\\u00A1-\\uFFFF]*",t={$pattern:r,keyword:"in isa where baremodule begin break catch ccall const continue do else elseif end export false finally for function global if import importall let local macro module quote return true try using while type immutable abstract bitstype typealias ",literal:"true false ARGS C_NULL DevNull ENDIAN_BOM ENV I Inf Inf16 Inf32 Inf64 InsertionSort JULIA_HOME LOAD_PATH MergeSort NaN NaN16 NaN32 NaN64 PROGRAM_FILE QuickSort RoundDown RoundFromZero RoundNearest RoundNearestTiesAway RoundNearestTiesUp RoundToZero RoundUp STDERR STDIN STDOUT VERSION catalan e|0 eu|0 eulergamma golden im nothing pi γ π φ ",built_in:"ANY AbstractArray AbstractChannel AbstractFloat AbstractMatrix AbstractRNG AbstractSerializer AbstractSet AbstractSparseArray AbstractSparseMatrix AbstractSparseVector AbstractString AbstractUnitRange AbstractVecOrMat AbstractVector Any ArgumentError Array AssertionError Associative Base64DecodePipe Base64EncodePipe Bidiagonal BigFloat BigInt BitArray BitMatrix BitVector Bool BoundsError BufferStream CachingPool CapturedException CartesianIndex CartesianRange Cchar Cdouble Cfloat Channel Char Cint Cintmax_t Clong Clonglong ClusterManager Cmd CodeInfo Colon Complex Complex128 Complex32 Complex64 CompositeException Condition ConjArray ConjMatrix ConjVector Cptrdiff_t Cshort Csize_t Cssize_t Cstring Cuchar Cuint Cuintmax_t Culong Culonglong Cushort Cwchar_t Cwstring DataType Date DateFormat DateTime DenseArray DenseMatrix DenseVecOrMat DenseVector Diagonal Dict DimensionMismatch Dims DirectIndexString Display DivideError DomainError EOFError EachLine Enum Enumerate ErrorException Exception ExponentialBackOff Expr Factorization FileMonitor Float16 Float32 Float64 Function Future GlobalRef GotoNode HTML Hermitian IO IOBuffer IOContext IOStream IPAddr IPv4 IPv6 IndexCartesian IndexLinear IndexStyle InexactError InitError Int Int128 Int16 Int32 Int64 Int8 IntSet Integer InterruptException InvalidStateException Irrational KeyError LabelNode LinSpace LineNumberNode LoadError LowerTriangular MIME Matrix MersenneTwister Method MethodError MethodTable Module NTuple NewvarNode NullException Nullable Number ObjectIdDict OrdinalRange OutOfMemoryError OverflowError Pair ParseError PartialQuickSort PermutedDimsArray Pipe PollingFileWatcher ProcessExitedException Ptr QuoteNode RandomDevice Range RangeIndex Rational RawFD ReadOnlyMemoryError Real ReentrantLock Ref Regex RegexMatch RemoteChannel RemoteException RevString RoundingMode RowVector SSAValue SegmentationFault SerializationState Set SharedArray SharedMatrix SharedVector Signed SimpleVector Slot SlotNumber SparseMatrixCSC SparseVector StackFrame StackOverflowError StackTrace StepRange StepRangeLen StridedArray StridedMatrix StridedVecOrMat StridedVector String SubArray SubString SymTridiagonal Symbol Symmetric SystemError TCPSocket Task Text TextDisplay Timer Tridiagonal Tuple Type TypeError TypeMapEntry TypeMapLevel TypeName TypeVar TypedSlot UDPSocket UInt UInt128 UInt16 UInt32 UInt64 UInt8 UndefRefError UndefVarError UnicodeError UniformScaling Union UnionAll UnitRange Unsigned UpperTriangular Val Vararg VecElement VecOrMat Vector VersionNumber Void WeakKeyDict WeakRef WorkerConfig WorkerPool "},a={keywords:t,illegal:/<\//},n={className:"subst",begin:/\$\(/,end:/\)/,keywords:t},o={className:"variable",begin:"\\$"+r},i={className:"string",contains:[e.BACKSLASH_ESCAPE,n,o],variants:[{begin:/\w*"""/,end:/"""\w*/,relevance:10},{begin:/\w*"/,end:/"\w*/}]},l={className:"string",contains:[e.BACKSLASH_ESCAPE,n,o],begin:"`",end:"`"},s={className:"meta",begin:"@"+r};return a.name="Julia",a.contains=[{className:"number",begin:/(\b0x[\d_]*(\.[\d_]*)?|0x\.\d[\d_]*)p[-+]?\d+|\b0[box][a-fA-F0-9][a-fA-F0-9_]*|(\b\d[\d_]*(\.[\d_]*)?|\.\d[\d_]*)([eEfF][-+]?\d+)?/,relevance:0},{className:"string",begin:/'(.|\\[xXuU][a-zA-Z0-9]+)'/},i,l,s,{className:"comment",variants:[{begin:"#=",end:"=#",relevance:10},{begin:"#",end:"$"}]},e.HASH_COMMENT_MODE,{className:"keyword",begin:"\\b(((abstract|primitive)\\s+)type|(mutable\\s+)?struct)\\b"},{begin:/<:/}],n.contains=a.contains,a}}()); -hljs.registerLanguage("nim",function(){"use strict";return function(e){return{name:"Nim",aliases:["nim"],keywords:{keyword:"addr and as asm bind block break case cast const continue converter discard distinct div do elif else end enum except export finally for from func generic if import in include interface is isnot iterator let macro method mixin mod nil not notin object of or out proc ptr raise ref return shl shr static template try tuple type using var when while with without xor yield",literal:"shared guarded stdin stdout stderr result true false",built_in:"int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 float float32 float64 bool char string cstring pointer expr stmt void auto any range array openarray varargs seq set clong culong cchar cschar cshort cint csize clonglong cfloat cdouble clongdouble cuchar cushort cuint culonglong cstringarray semistatic"},contains:[{className:"meta",begin:/{\./,end:/\.}/,relevance:10},{className:"string",begin:/[a-zA-Z]\w*"/,end:/"/,contains:[{begin:/""/}]},{className:"string",begin:/([a-zA-Z]\w*)?"""/,end:/"""/},e.QUOTE_STRING_MODE,{className:"type",begin:/\b[A-Z]\w+\b/,relevance:0},{className:"number",relevance:0,variants:[{begin:/\b(0[xX][0-9a-fA-F][_0-9a-fA-F]*)('?[iIuU](8|16|32|64))?/},{begin:/\b(0o[0-7][_0-7]*)('?[iIuUfF](8|16|32|64))?/},{begin:/\b(0(b|B)[01][_01]*)('?[iIuUfF](8|16|32|64))?/},{begin:/\b(\d[_\d]*)('?[iIuUfF](8|16|32|64))?/}]},e.HASH_COMMENT_MODE]}}}()); -hljs.registerLanguage("nix",function(){"use strict";return function(e){var n={keyword:"rec with let in inherit assert if else then",literal:"true false or and null",built_in:"import abort baseNameOf dirOf isNull builtins map removeAttrs throw toString derivation"},i={className:"subst",begin:/\$\{/,end:/}/,keywords:n},t={className:"string",contains:[i],variants:[{begin:"''",end:"''"},{begin:'"',end:'"'}]},s=[e.NUMBER_MODE,e.HASH_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,t,{begin:/[a-zA-Z0-9-_]+(\s*=)/,returnBegin:!0,relevance:0,contains:[{className:"attr",begin:/\S+/}]}];return i.contains=s,{name:"Nix",aliases:["nixos"],keywords:n,contains:s}}}()); -hljs.registerLanguage("r",function(){"use strict";return function(e){var n="([a-zA-Z]|\\.[a-zA-Z.])[a-zA-Z0-9._]*";return{name:"R",contains:[e.HASH_COMMENT_MODE,{begin:n,keywords:{$pattern:n,keyword:"function if in break next repeat else for return switch while try tryCatch stop warning require library attach detach source setMethod setGeneric setGroupGeneric setClass ...",literal:"NULL NA TRUE FALSE T F Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10"},relevance:0},{className:"number",begin:"0[xX][0-9a-fA-F]+[Li]?\\b",relevance:0},{className:"number",begin:"\\d+(?:[eE][+\\-]?\\d*)?L\\b",relevance:0},{className:"number",begin:"\\d+\\.(?!\\d)(?:i\\b)?",relevance:0},{className:"number",begin:"\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b",relevance:0},{className:"number",begin:"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b",relevance:0},{begin:"`",end:"`",relevance:0},{className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{begin:'"',end:'"'},{begin:"'",end:"'"}]}]}}}()); -hljs.registerLanguage("scala",function(){"use strict";return function(e){var n={className:"subst",variants:[{begin:"\\$[A-Za-z0-9_]+"},{begin:"\\${",end:"}"}]},a={className:"string",variants:[{begin:'"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{begin:'"""',end:'"""',relevance:10},{begin:'[a-z]+"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE,n]},{className:"string",begin:'[a-z]+"""',end:'"""',contains:[n],relevance:10}]},s={className:"type",begin:"\\b[A-Z][A-Za-z0-9_]*",relevance:0},t={className:"title",begin:/[^0-9\n\t "'(),.`{}\[\]:;][^\n\t "'(),.`{}\[\]:;]+|[^0-9\n\t "'(),.`{}\[\]:;=]/,relevance:0},i={className:"class",beginKeywords:"class object trait type",end:/[:={\[\n;]/,excludeEnd:!0,contains:[{beginKeywords:"extends with",relevance:10},{begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0,relevance:0,contains:[s]},{className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,relevance:0,contains:[s]},t]},l={className:"function",beginKeywords:"def",end:/[:={\[(\n;]/,excludeEnd:!0,contains:[t]};return{name:"Scala",keywords:{literal:"true false null",keyword:"type yield lazy override def with val var sealed abstract private trait object if forSome for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws implicit"},contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,a,{className:"symbol",begin:"'\\w[\\w\\d_]*(?!')"},s,l,i,e.C_NUMBER_MODE,{className:"meta",begin:"@[A-Za-z]+"}]}}}()); -hljs.registerLanguage("x86asm",function(){"use strict";return function(s){return{name:"Intel x86 Assembly",case_insensitive:!0,keywords:{$pattern:"[.%]?"+s.IDENT_RE,keyword:"lock rep repe repz repne repnz xaquire xrelease bnd nobnd aaa aad aam aas adc add and arpl bb0_reset bb1_reset bound bsf bsr bswap bt btc btr bts call cbw cdq cdqe clc cld cli clts cmc cmp cmpsb cmpsd cmpsq cmpsw cmpxchg cmpxchg486 cmpxchg8b cmpxchg16b cpuid cpu_read cpu_write cqo cwd cwde daa das dec div dmint emms enter equ f2xm1 fabs fadd faddp fbld fbstp fchs fclex fcmovb fcmovbe fcmove fcmovnb fcmovnbe fcmovne fcmovnu fcmovu fcom fcomi fcomip fcomp fcompp fcos fdecstp fdisi fdiv fdivp fdivr fdivrp femms feni ffree ffreep fiadd ficom ficomp fidiv fidivr fild fimul fincstp finit fist fistp fisttp fisub fisubr fld fld1 fldcw fldenv fldl2e fldl2t fldlg2 fldln2 fldpi fldz fmul fmulp fnclex fndisi fneni fninit fnop fnsave fnstcw fnstenv fnstsw fpatan fprem fprem1 fptan frndint frstor fsave fscale fsetpm fsin fsincos fsqrt fst fstcw fstenv fstp fstsw fsub fsubp fsubr fsubrp ftst fucom fucomi fucomip fucomp fucompp fxam fxch fxtract fyl2x fyl2xp1 hlt ibts icebp idiv imul in inc incbin insb insd insw int int01 int1 int03 int3 into invd invpcid invlpg invlpga iret iretd iretq iretw jcxz jecxz jrcxz jmp jmpe lahf lar lds lea leave les lfence lfs lgdt lgs lidt lldt lmsw loadall loadall286 lodsb lodsd lodsq lodsw loop loope loopne loopnz loopz lsl lss ltr mfence monitor mov movd movq movsb movsd movsq movsw movsx movsxd movzx mul mwait neg nop not or out outsb outsd outsw packssdw packsswb packuswb paddb paddd paddsb paddsiw paddsw paddusb paddusw paddw pand pandn pause paveb pavgusb pcmpeqb pcmpeqd pcmpeqw pcmpgtb pcmpgtd pcmpgtw pdistib pf2id pfacc pfadd pfcmpeq pfcmpge pfcmpgt pfmax pfmin pfmul pfrcp pfrcpit1 pfrcpit2 pfrsqit1 pfrsqrt pfsub pfsubr pi2fd pmachriw pmaddwd pmagw pmulhriw pmulhrwa pmulhrwc pmulhw pmullw pmvgezb pmvlzb pmvnzb pmvzb pop popa popad popaw popf popfd popfq popfw por prefetch prefetchw pslld psllq psllw psrad psraw psrld psrlq psrlw psubb psubd psubsb psubsiw psubsw psubusb psubusw psubw punpckhbw punpckhdq punpckhwd punpcklbw punpckldq punpcklwd push pusha pushad pushaw pushf pushfd pushfq pushfw pxor rcl rcr rdshr rdmsr rdpmc rdtsc rdtscp ret retf retn rol ror rdm rsdc rsldt rsm rsts sahf sal salc sar sbb scasb scasd scasq scasw sfence sgdt shl shld shr shrd sidt sldt skinit smi smint smintold smsw stc std sti stosb stosd stosq stosw str sub svdc svldt svts swapgs syscall sysenter sysexit sysret test ud0 ud1 ud2b ud2 ud2a umov verr verw fwait wbinvd wrshr wrmsr xadd xbts xchg xlatb xlat xor cmove cmovz cmovne cmovnz cmova cmovnbe cmovae cmovnb cmovb cmovnae cmovbe cmovna cmovg cmovnle cmovge cmovnl cmovl cmovnge cmovle cmovng cmovc cmovnc cmovo cmovno cmovs cmovns cmovp cmovpe cmovnp cmovpo je jz jne jnz ja jnbe jae jnb jb jnae jbe jna jg jnle jge jnl jl jnge jle jng jc jnc jo jno js jns jpo jnp jpe jp sete setz setne setnz seta setnbe setae setnb setnc setb setnae setcset setbe setna setg setnle setge setnl setl setnge setle setng sets setns seto setno setpe setp setpo setnp addps addss andnps andps cmpeqps cmpeqss cmpleps cmpless cmpltps cmpltss cmpneqps cmpneqss cmpnleps cmpnless cmpnltps cmpnltss cmpordps cmpordss cmpunordps cmpunordss cmpps cmpss comiss cvtpi2ps cvtps2pi cvtsi2ss cvtss2si cvttps2pi cvttss2si divps divss ldmxcsr maxps maxss minps minss movaps movhps movlhps movlps movhlps movmskps movntps movss movups mulps mulss orps rcpps rcpss rsqrtps rsqrtss shufps sqrtps sqrtss stmxcsr subps subss ucomiss unpckhps unpcklps xorps fxrstor fxrstor64 fxsave fxsave64 xgetbv xsetbv xsave xsave64 xsaveopt xsaveopt64 xrstor xrstor64 prefetchnta prefetcht0 prefetcht1 prefetcht2 maskmovq movntq pavgb pavgw pextrw pinsrw pmaxsw pmaxub pminsw pminub pmovmskb pmulhuw psadbw pshufw pf2iw pfnacc pfpnacc pi2fw pswapd maskmovdqu clflush movntdq movnti movntpd movdqa movdqu movdq2q movq2dq paddq pmuludq pshufd pshufhw pshuflw pslldq psrldq psubq punpckhqdq punpcklqdq addpd addsd andnpd andpd cmpeqpd cmpeqsd cmplepd cmplesd cmpltpd cmpltsd cmpneqpd cmpneqsd cmpnlepd cmpnlesd cmpnltpd cmpnltsd cmpordpd cmpordsd cmpunordpd cmpunordsd cmppd comisd cvtdq2pd cvtdq2ps cvtpd2dq cvtpd2pi cvtpd2ps cvtpi2pd cvtps2dq cvtps2pd cvtsd2si cvtsd2ss cvtsi2sd cvtss2sd cvttpd2pi cvttpd2dq cvttps2dq cvttsd2si divpd divsd maxpd maxsd minpd minsd movapd movhpd movlpd movmskpd movupd mulpd mulsd orpd shufpd sqrtpd sqrtsd subpd subsd ucomisd unpckhpd unpcklpd xorpd addsubpd addsubps haddpd haddps hsubpd hsubps lddqu movddup movshdup movsldup clgi stgi vmcall vmclear vmfunc vmlaunch vmload vmmcall vmptrld vmptrst vmread vmresume vmrun vmsave vmwrite vmxoff vmxon invept invvpid pabsb pabsw pabsd palignr phaddw phaddd phaddsw phsubw phsubd phsubsw pmaddubsw pmulhrsw pshufb psignb psignw psignd extrq insertq movntsd movntss lzcnt blendpd blendps blendvpd blendvps dppd dpps extractps insertps movntdqa mpsadbw packusdw pblendvb pblendw pcmpeqq pextrb pextrd pextrq phminposuw pinsrb pinsrd pinsrq pmaxsb pmaxsd pmaxud pmaxuw pminsb pminsd pminud pminuw pmovsxbw pmovsxbd pmovsxbq pmovsxwd pmovsxwq pmovsxdq pmovzxbw pmovzxbd pmovzxbq pmovzxwd pmovzxwq pmovzxdq pmuldq pmulld ptest roundpd roundps roundsd roundss crc32 pcmpestri pcmpestrm pcmpistri pcmpistrm pcmpgtq popcnt getsec pfrcpv pfrsqrtv movbe aesenc aesenclast aesdec aesdeclast aesimc aeskeygenassist vaesenc vaesenclast vaesdec vaesdeclast vaesimc vaeskeygenassist vaddpd vaddps vaddsd vaddss vaddsubpd vaddsubps vandpd vandps vandnpd vandnps vblendpd vblendps vblendvpd vblendvps vbroadcastss vbroadcastsd vbroadcastf128 vcmpeq_ospd vcmpeqpd vcmplt_ospd vcmpltpd vcmple_ospd vcmplepd vcmpunord_qpd vcmpunordpd vcmpneq_uqpd vcmpneqpd vcmpnlt_uspd vcmpnltpd vcmpnle_uspd vcmpnlepd vcmpord_qpd vcmpordpd vcmpeq_uqpd vcmpnge_uspd vcmpngepd vcmpngt_uspd vcmpngtpd vcmpfalse_oqpd vcmpfalsepd vcmpneq_oqpd vcmpge_ospd vcmpgepd vcmpgt_ospd vcmpgtpd vcmptrue_uqpd vcmptruepd vcmplt_oqpd vcmple_oqpd vcmpunord_spd vcmpneq_uspd vcmpnlt_uqpd vcmpnle_uqpd vcmpord_spd vcmpeq_uspd vcmpnge_uqpd vcmpngt_uqpd vcmpfalse_ospd vcmpneq_ospd vcmpge_oqpd vcmpgt_oqpd vcmptrue_uspd vcmppd vcmpeq_osps vcmpeqps vcmplt_osps vcmpltps vcmple_osps vcmpleps vcmpunord_qps vcmpunordps vcmpneq_uqps vcmpneqps vcmpnlt_usps vcmpnltps vcmpnle_usps vcmpnleps vcmpord_qps vcmpordps vcmpeq_uqps vcmpnge_usps vcmpngeps vcmpngt_usps vcmpngtps vcmpfalse_oqps vcmpfalseps vcmpneq_oqps vcmpge_osps vcmpgeps vcmpgt_osps vcmpgtps vcmptrue_uqps vcmptrueps vcmplt_oqps vcmple_oqps vcmpunord_sps vcmpneq_usps vcmpnlt_uqps vcmpnle_uqps vcmpord_sps vcmpeq_usps vcmpnge_uqps vcmpngt_uqps vcmpfalse_osps vcmpneq_osps vcmpge_oqps vcmpgt_oqps vcmptrue_usps vcmpps vcmpeq_ossd vcmpeqsd vcmplt_ossd vcmpltsd vcmple_ossd vcmplesd vcmpunord_qsd vcmpunordsd vcmpneq_uqsd vcmpneqsd vcmpnlt_ussd vcmpnltsd vcmpnle_ussd vcmpnlesd vcmpord_qsd vcmpordsd vcmpeq_uqsd vcmpnge_ussd vcmpngesd vcmpngt_ussd vcmpngtsd vcmpfalse_oqsd vcmpfalsesd vcmpneq_oqsd vcmpge_ossd vcmpgesd vcmpgt_ossd vcmpgtsd vcmptrue_uqsd vcmptruesd vcmplt_oqsd vcmple_oqsd vcmpunord_ssd vcmpneq_ussd vcmpnlt_uqsd vcmpnle_uqsd vcmpord_ssd vcmpeq_ussd vcmpnge_uqsd vcmpngt_uqsd vcmpfalse_ossd vcmpneq_ossd vcmpge_oqsd vcmpgt_oqsd vcmptrue_ussd vcmpsd vcmpeq_osss vcmpeqss vcmplt_osss vcmpltss vcmple_osss vcmpless vcmpunord_qss vcmpunordss vcmpneq_uqss vcmpneqss vcmpnlt_usss vcmpnltss vcmpnle_usss vcmpnless vcmpord_qss vcmpordss vcmpeq_uqss vcmpnge_usss vcmpngess vcmpngt_usss vcmpngtss vcmpfalse_oqss vcmpfalsess vcmpneq_oqss vcmpge_osss vcmpgess vcmpgt_osss vcmpgtss vcmptrue_uqss vcmptruess vcmplt_oqss vcmple_oqss vcmpunord_sss vcmpneq_usss vcmpnlt_uqss vcmpnle_uqss vcmpord_sss vcmpeq_usss vcmpnge_uqss vcmpngt_uqss vcmpfalse_osss vcmpneq_osss vcmpge_oqss vcmpgt_oqss vcmptrue_usss vcmpss vcomisd vcomiss vcvtdq2pd vcvtdq2ps vcvtpd2dq vcvtpd2ps vcvtps2dq vcvtps2pd vcvtsd2si vcvtsd2ss vcvtsi2sd vcvtsi2ss vcvtss2sd vcvtss2si vcvttpd2dq vcvttps2dq vcvttsd2si vcvttss2si vdivpd vdivps vdivsd vdivss vdppd vdpps vextractf128 vextractps vhaddpd vhaddps vhsubpd vhsubps vinsertf128 vinsertps vlddqu vldqqu vldmxcsr vmaskmovdqu vmaskmovps vmaskmovpd vmaxpd vmaxps vmaxsd vmaxss vminpd vminps vminsd vminss vmovapd vmovaps vmovd vmovq vmovddup vmovdqa vmovqqa vmovdqu vmovqqu vmovhlps vmovhpd vmovhps vmovlhps vmovlpd vmovlps vmovmskpd vmovmskps vmovntdq vmovntqq vmovntdqa vmovntpd vmovntps vmovsd vmovshdup vmovsldup vmovss vmovupd vmovups vmpsadbw vmulpd vmulps vmulsd vmulss vorpd vorps vpabsb vpabsw vpabsd vpacksswb vpackssdw vpackuswb vpackusdw vpaddb vpaddw vpaddd vpaddq vpaddsb vpaddsw vpaddusb vpaddusw vpalignr vpand vpandn vpavgb vpavgw vpblendvb vpblendw vpcmpestri vpcmpestrm vpcmpistri vpcmpistrm vpcmpeqb vpcmpeqw vpcmpeqd vpcmpeqq vpcmpgtb vpcmpgtw vpcmpgtd vpcmpgtq vpermilpd vpermilps vperm2f128 vpextrb vpextrw vpextrd vpextrq vphaddw vphaddd vphaddsw vphminposuw vphsubw vphsubd vphsubsw vpinsrb vpinsrw vpinsrd vpinsrq vpmaddwd vpmaddubsw vpmaxsb vpmaxsw vpmaxsd vpmaxub vpmaxuw vpmaxud vpminsb vpminsw vpminsd vpminub vpminuw vpminud vpmovmskb vpmovsxbw vpmovsxbd vpmovsxbq vpmovsxwd vpmovsxwq vpmovsxdq vpmovzxbw vpmovzxbd vpmovzxbq vpmovzxwd vpmovzxwq vpmovzxdq vpmulhuw vpmulhrsw vpmulhw vpmullw vpmulld vpmuludq vpmuldq vpor vpsadbw vpshufb vpshufd vpshufhw vpshuflw vpsignb vpsignw vpsignd vpslldq vpsrldq vpsllw vpslld vpsllq vpsraw vpsrad vpsrlw vpsrld vpsrlq vptest vpsubb vpsubw vpsubd vpsubq vpsubsb vpsubsw vpsubusb vpsubusw vpunpckhbw vpunpckhwd vpunpckhdq vpunpckhqdq vpunpcklbw vpunpcklwd vpunpckldq vpunpcklqdq vpxor vrcpps vrcpss vrsqrtps vrsqrtss vroundpd vroundps vroundsd vroundss vshufpd vshufps vsqrtpd vsqrtps vsqrtsd vsqrtss vstmxcsr vsubpd vsubps vsubsd vsubss vtestps vtestpd vucomisd vucomiss vunpckhpd vunpckhps vunpcklpd vunpcklps vxorpd vxorps vzeroall vzeroupper pclmullqlqdq pclmulhqlqdq pclmullqhqdq pclmulhqhqdq pclmulqdq vpclmullqlqdq vpclmulhqlqdq vpclmullqhqdq vpclmulhqhqdq vpclmulqdq vfmadd132ps vfmadd132pd vfmadd312ps vfmadd312pd vfmadd213ps vfmadd213pd vfmadd123ps vfmadd123pd vfmadd231ps vfmadd231pd vfmadd321ps vfmadd321pd vfmaddsub132ps vfmaddsub132pd vfmaddsub312ps vfmaddsub312pd vfmaddsub213ps vfmaddsub213pd vfmaddsub123ps vfmaddsub123pd vfmaddsub231ps vfmaddsub231pd vfmaddsub321ps vfmaddsub321pd vfmsub132ps vfmsub132pd vfmsub312ps vfmsub312pd vfmsub213ps vfmsub213pd vfmsub123ps vfmsub123pd vfmsub231ps vfmsub231pd vfmsub321ps vfmsub321pd vfmsubadd132ps vfmsubadd132pd vfmsubadd312ps vfmsubadd312pd vfmsubadd213ps vfmsubadd213pd vfmsubadd123ps vfmsubadd123pd vfmsubadd231ps vfmsubadd231pd vfmsubadd321ps vfmsubadd321pd vfnmadd132ps vfnmadd132pd vfnmadd312ps vfnmadd312pd vfnmadd213ps vfnmadd213pd vfnmadd123ps vfnmadd123pd vfnmadd231ps vfnmadd231pd vfnmadd321ps vfnmadd321pd vfnmsub132ps vfnmsub132pd vfnmsub312ps vfnmsub312pd vfnmsub213ps vfnmsub213pd vfnmsub123ps vfnmsub123pd vfnmsub231ps vfnmsub231pd vfnmsub321ps vfnmsub321pd vfmadd132ss vfmadd132sd vfmadd312ss vfmadd312sd vfmadd213ss vfmadd213sd vfmadd123ss vfmadd123sd vfmadd231ss vfmadd231sd vfmadd321ss vfmadd321sd vfmsub132ss vfmsub132sd vfmsub312ss vfmsub312sd vfmsub213ss vfmsub213sd vfmsub123ss vfmsub123sd vfmsub231ss vfmsub231sd vfmsub321ss vfmsub321sd vfnmadd132ss vfnmadd132sd vfnmadd312ss vfnmadd312sd vfnmadd213ss vfnmadd213sd vfnmadd123ss vfnmadd123sd vfnmadd231ss vfnmadd231sd vfnmadd321ss vfnmadd321sd vfnmsub132ss vfnmsub132sd vfnmsub312ss vfnmsub312sd vfnmsub213ss vfnmsub213sd vfnmsub123ss vfnmsub123sd vfnmsub231ss vfnmsub231sd vfnmsub321ss vfnmsub321sd rdfsbase rdgsbase rdrand wrfsbase wrgsbase vcvtph2ps vcvtps2ph adcx adox rdseed clac stac xstore xcryptecb xcryptcbc xcryptctr xcryptcfb xcryptofb montmul xsha1 xsha256 llwpcb slwpcb lwpval lwpins vfmaddpd vfmaddps vfmaddsd vfmaddss vfmaddsubpd vfmaddsubps vfmsubaddpd vfmsubaddps vfmsubpd vfmsubps vfmsubsd vfmsubss vfnmaddpd vfnmaddps vfnmaddsd vfnmaddss vfnmsubpd vfnmsubps vfnmsubsd vfnmsubss vfrczpd vfrczps vfrczsd vfrczss vpcmov vpcomb vpcomd vpcomq vpcomub vpcomud vpcomuq vpcomuw vpcomw vphaddbd vphaddbq vphaddbw vphadddq vphaddubd vphaddubq vphaddubw vphaddudq vphadduwd vphadduwq vphaddwd vphaddwq vphsubbw vphsubdq vphsubwd vpmacsdd vpmacsdqh vpmacsdql vpmacssdd vpmacssdqh vpmacssdql vpmacsswd vpmacssww vpmacswd vpmacsww vpmadcsswd vpmadcswd vpperm vprotb vprotd vprotq vprotw vpshab vpshad vpshaq vpshaw vpshlb vpshld vpshlq vpshlw vbroadcasti128 vpblendd vpbroadcastb vpbroadcastw vpbroadcastd vpbroadcastq vpermd vpermpd vpermps vpermq vperm2i128 vextracti128 vinserti128 vpmaskmovd vpmaskmovq vpsllvd vpsllvq vpsravd vpsrlvd vpsrlvq vgatherdpd vgatherqpd vgatherdps vgatherqps vpgatherdd vpgatherqd vpgatherdq vpgatherqq xabort xbegin xend xtest andn bextr blci blcic blsi blsic blcfill blsfill blcmsk blsmsk blsr blcs bzhi mulx pdep pext rorx sarx shlx shrx tzcnt tzmsk t1mskc valignd valignq vblendmpd vblendmps vbroadcastf32x4 vbroadcastf64x4 vbroadcasti32x4 vbroadcasti64x4 vcompresspd vcompressps vcvtpd2udq vcvtps2udq vcvtsd2usi vcvtss2usi vcvttpd2udq vcvttps2udq vcvttsd2usi vcvttss2usi vcvtudq2pd vcvtudq2ps vcvtusi2sd vcvtusi2ss vexpandpd vexpandps vextractf32x4 vextractf64x4 vextracti32x4 vextracti64x4 vfixupimmpd vfixupimmps vfixupimmsd vfixupimmss vgetexppd vgetexpps vgetexpsd vgetexpss vgetmantpd vgetmantps vgetmantsd vgetmantss vinsertf32x4 vinsertf64x4 vinserti32x4 vinserti64x4 vmovdqa32 vmovdqa64 vmovdqu32 vmovdqu64 vpabsq vpandd vpandnd vpandnq vpandq vpblendmd vpblendmq vpcmpltd vpcmpled vpcmpneqd vpcmpnltd vpcmpnled vpcmpd vpcmpltq vpcmpleq vpcmpneqq vpcmpnltq vpcmpnleq vpcmpq vpcmpequd vpcmpltud vpcmpleud vpcmpnequd vpcmpnltud vpcmpnleud vpcmpud vpcmpequq vpcmpltuq vpcmpleuq vpcmpnequq vpcmpnltuq vpcmpnleuq vpcmpuq vpcompressd vpcompressq vpermi2d vpermi2pd vpermi2ps vpermi2q vpermt2d vpermt2pd vpermt2ps vpermt2q vpexpandd vpexpandq vpmaxsq vpmaxuq vpminsq vpminuq vpmovdb vpmovdw vpmovqb vpmovqd vpmovqw vpmovsdb vpmovsdw vpmovsqb vpmovsqd vpmovsqw vpmovusdb vpmovusdw vpmovusqb vpmovusqd vpmovusqw vpord vporq vprold vprolq vprolvd vprolvq vprord vprorq vprorvd vprorvq vpscatterdd vpscatterdq vpscatterqd vpscatterqq vpsraq vpsravq vpternlogd vpternlogq vptestmd vptestmq vptestnmd vptestnmq vpxord vpxorq vrcp14pd vrcp14ps vrcp14sd vrcp14ss vrndscalepd vrndscaleps vrndscalesd vrndscaless vrsqrt14pd vrsqrt14ps vrsqrt14sd vrsqrt14ss vscalefpd vscalefps vscalefsd vscalefss vscatterdpd vscatterdps vscatterqpd vscatterqps vshuff32x4 vshuff64x2 vshufi32x4 vshufi64x2 kandnw kandw kmovw knotw kortestw korw kshiftlw kshiftrw kunpckbw kxnorw kxorw vpbroadcastmb2q vpbroadcastmw2d vpconflictd vpconflictq vplzcntd vplzcntq vexp2pd vexp2ps vrcp28pd vrcp28ps vrcp28sd vrcp28ss vrsqrt28pd vrsqrt28ps vrsqrt28sd vrsqrt28ss vgatherpf0dpd vgatherpf0dps vgatherpf0qpd vgatherpf0qps vgatherpf1dpd vgatherpf1dps vgatherpf1qpd vgatherpf1qps vscatterpf0dpd vscatterpf0dps vscatterpf0qpd vscatterpf0qps vscatterpf1dpd vscatterpf1dps vscatterpf1qpd vscatterpf1qps prefetchwt1 bndmk bndcl bndcu bndcn bndmov bndldx bndstx sha1rnds4 sha1nexte sha1msg1 sha1msg2 sha256rnds2 sha256msg1 sha256msg2 hint_nop0 hint_nop1 hint_nop2 hint_nop3 hint_nop4 hint_nop5 hint_nop6 hint_nop7 hint_nop8 hint_nop9 hint_nop10 hint_nop11 hint_nop12 hint_nop13 hint_nop14 hint_nop15 hint_nop16 hint_nop17 hint_nop18 hint_nop19 hint_nop20 hint_nop21 hint_nop22 hint_nop23 hint_nop24 hint_nop25 hint_nop26 hint_nop27 hint_nop28 hint_nop29 hint_nop30 hint_nop31 hint_nop32 hint_nop33 hint_nop34 hint_nop35 hint_nop36 hint_nop37 hint_nop38 hint_nop39 hint_nop40 hint_nop41 hint_nop42 hint_nop43 hint_nop44 hint_nop45 hint_nop46 hint_nop47 hint_nop48 hint_nop49 hint_nop50 hint_nop51 hint_nop52 hint_nop53 hint_nop54 hint_nop55 hint_nop56 hint_nop57 hint_nop58 hint_nop59 hint_nop60 hint_nop61 hint_nop62 hint_nop63",built_in:"ip eip rip al ah bl bh cl ch dl dh sil dil bpl spl r8b r9b r10b r11b r12b r13b r14b r15b ax bx cx dx si di bp sp r8w r9w r10w r11w r12w r13w r14w r15w eax ebx ecx edx esi edi ebp esp eip r8d r9d r10d r11d r12d r13d r14d r15d rax rbx rcx rdx rsi rdi rbp rsp r8 r9 r10 r11 r12 r13 r14 r15 cs ds es fs gs ss st st0 st1 st2 st3 st4 st5 st6 st7 mm0 mm1 mm2 mm3 mm4 mm5 mm6 mm7 xmm0 xmm1 xmm2 xmm3 xmm4 xmm5 xmm6 xmm7 xmm8 xmm9 xmm10 xmm11 xmm12 xmm13 xmm14 xmm15 xmm16 xmm17 xmm18 xmm19 xmm20 xmm21 xmm22 xmm23 xmm24 xmm25 xmm26 xmm27 xmm28 xmm29 xmm30 xmm31 ymm0 ymm1 ymm2 ymm3 ymm4 ymm5 ymm6 ymm7 ymm8 ymm9 ymm10 ymm11 ymm12 ymm13 ymm14 ymm15 ymm16 ymm17 ymm18 ymm19 ymm20 ymm21 ymm22 ymm23 ymm24 ymm25 ymm26 ymm27 ymm28 ymm29 ymm30 ymm31 zmm0 zmm1 zmm2 zmm3 zmm4 zmm5 zmm6 zmm7 zmm8 zmm9 zmm10 zmm11 zmm12 zmm13 zmm14 zmm15 zmm16 zmm17 zmm18 zmm19 zmm20 zmm21 zmm22 zmm23 zmm24 zmm25 zmm26 zmm27 zmm28 zmm29 zmm30 zmm31 k0 k1 k2 k3 k4 k5 k6 k7 bnd0 bnd1 bnd2 bnd3 cr0 cr1 cr2 cr3 cr4 cr8 dr0 dr1 dr2 dr3 dr8 tr3 tr4 tr5 tr6 tr7 r0 r1 r2 r3 r4 r5 r6 r7 r0b r1b r2b r3b r4b r5b r6b r7b r0w r1w r2w r3w r4w r5w r6w r7w r0d r1d r2d r3d r4d r5d r6d r7d r0h r1h r2h r3h r0l r1l r2l r3l r4l r5l r6l r7l r8l r9l r10l r11l r12l r13l r14l r15l db dw dd dq dt ddq do dy dz resb resw resd resq rest resdq reso resy resz incbin equ times byte word dword qword nosplit rel abs seg wrt strict near far a32 ptr",meta:"%define %xdefine %+ %undef %defstr %deftok %assign %strcat %strlen %substr %rotate %elif %else %endif %if %ifmacro %ifctx %ifidn %ifidni %ifid %ifnum %ifstr %iftoken %ifempty %ifenv %error %warning %fatal %rep %endrep %include %push %pop %repl %pathsearch %depend %use %arg %stacksize %local %line %comment %endcomment .nolist __FILE__ __LINE__ __SECT__ __BITS__ __OUTPUT_FORMAT__ __DATE__ __TIME__ __DATE_NUM__ __TIME_NUM__ __UTC_DATE__ __UTC_TIME__ __UTC_DATE_NUM__ __UTC_TIME_NUM__ __PASS__ struc endstruc istruc at iend align alignb sectalign daz nodaz up down zero default option assume public bits use16 use32 use64 default section segment absolute extern global common cpu float __utf16__ __utf16le__ __utf16be__ __utf32__ __utf32le__ __utf32be__ __float8__ __float16__ __float32__ __float64__ __float80m__ __float80e__ __float128l__ __float128h__ __Infinity__ __QNaN__ __SNaN__ Inf NaN QNaN SNaN float8 float16 float32 float64 float80m float80e float128l float128h __FLOAT_DAZ__ __FLOAT_ROUND__ __FLOAT__"},contains:[s.COMMENT(";","$",{relevance:0}),{className:"number",variants:[{begin:"\\b(?:([0-9][0-9_]*)?\\.[0-9_]*(?:[eE][+-]?[0-9_]+)?|(0[Xx])?[0-9][0-9_]*\\.?[0-9_]*(?:[pP](?:[+-]?[0-9_]+)?)?)\\b",relevance:0},{begin:"\\$[0-9][0-9A-Fa-f]*",relevance:0},{begin:"\\b(?:[0-9A-Fa-f][0-9A-Fa-f_]*[Hh]|[0-9][0-9_]*[DdTt]?|[0-7][0-7_]*[QqOo]|[0-1][0-1_]*[BbYy])\\b"},{begin:"\\b(?:0[Xx][0-9A-Fa-f_]+|0[DdTt][0-9_]+|0[QqOo][0-7_]+|0[BbYy][0-1_]+)\\b"}]},s.QUOTE_STRING_MODE,{className:"string",variants:[{begin:"'",end:"[^\\\\]'"},{begin:"`",end:"[^\\\\]`"}],relevance:0},{className:"symbol",variants:[{begin:"^\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\s+label)"},{begin:"^\\s*%%[A-Za-z0-9_$#@~.?]*:"}],relevance:0},{className:"subst",begin:"%[0-9]+",relevance:0},{className:"subst",begin:"%!S+",relevance:0},{className:"meta",begin:/^\s*\.[\w_-]+/}]}}}()); diff --git a/docs/book/index.html b/docs/book/index.html deleted file mode 100644 index 277093a..0000000 --- a/docs/book/index.html +++ /dev/null @@ -1,313 +0,0 @@ - - - - - - Introduction - Provisioning Platform Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-

Keyboard shortcuts

-
-

Press or to navigate between chapters

-

Press S or / to search in the book

-

Press ? to show this help

-

Press Esc to hide this help

-
-
-
-
- - - - - - - - - - - - - -
- -
- - - - - - - - -
-
-

- Provisioning Logo -

-

- Provisioning -

-

Provisioning Platform Documentation

-

Welcome to the Provisioning Platform documentation. This is an enterprise-grade Infrastructure -as Code (IaC) platform built with Rust, Nushell, and Nickel.

-

What is Provisioning

-

Provisioning is a comprehensive infrastructure automation platform that manages complete -infrastructure lifecycles across multiple cloud providers. The platform emphasizes type-safety, -configuration-driven design, and workspace-first organization.

-

Key Features

-
    -
  • Workspace Management: Default mode for organizing infrastructure, settings, schemas, and extensions
  • -
  • Type-Safe Configuration: Nickel-based configuration system with validation and contracts
  • -
  • Multi-Cloud Support: Unified interface for AWS, UpCloud, and local providers
  • -
  • Modular CLI Architecture: 111+ commands with 84% code reduction through modularity
  • -
  • Batch Workflow Engine: Orchestrate complex multi-cloud operations
  • -
  • Complete Security System: Authentication, authorization, encryption, and compliance
  • -
  • Extensible Architecture: Custom providers, task services, and plugins
  • -
-

Getting Started

-

New users should start with:

-
    -
  1. Prerequisites - System requirements and dependencies
  2. -
  3. Installation - Install the platform
  4. -
  5. Quick Start - 5-minute deployment tutorial
  6. -
  7. First Deployment - Comprehensive walkthrough
  8. -
-

Documentation Structure

-
    -
  • Getting Started: Installation and initial setup
  • -
  • User Guides: Workflow tutorials and best practices
  • -
  • Infrastructure as Code: Nickel configuration and schema reference
  • -
  • Platform Features: Core capabilities and systems
  • -
  • Operations: Deployment, monitoring, and maintenance
  • -
  • Security: Complete security system documentation
  • -
  • Development: Extension and plugin development
  • -
  • API Reference: REST API and CLI command reference
  • -
  • Architecture: System design and ADRs
  • -
  • Examples: Practical use cases and patterns
  • -
  • Troubleshooting: Problem-solving guides
  • -
-

Core Technologies

-
    -
  • Rust: Platform services and performance-critical components
  • -
  • Nushell: Scripting, CLI, and automation
  • -
  • Nickel: Type-safe infrastructure configuration
  • -
  • SecretumVault: Secrets management integration
  • -
-

Workspace-First Approach

-

Provisioning uses workspaces as the default organizational unit. A workspace contains:

-
    -
  • Infrastructure definitions (Nickel schemas)
  • -
  • Environment-specific settings
  • -
  • Custom extensions and providers
  • -
  • Deployment state and metadata
  • -
-

All operations work within workspace context, providing isolation and consistency.

-

Support and Community

-
    -
  • Issues: Report bugs and request features on GitHub
  • -
  • Documentation: This documentation site
  • -
  • Examples: See the Examples section
  • -
-

License

-

See project LICENSE file for details.

- -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- - diff --git a/docs/book/mark.min.js b/docs/book/mark.min.js deleted file mode 100644 index 1636231..0000000 --- a/docs/book/mark.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*!*************************************************** -* mark.js v8.11.1 -* https://markjs.io/ -* Copyright (c) 2014–2018, Julian Kühnel -* Released under the MIT license https://git.io/vwTVl -*****************************************************/ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Mark=t()}(this,function(){"use strict";var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},t=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},n=function(){function e(e,t){for(var n=0;n1&&void 0!==arguments[1])||arguments[1],i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:5e3;t(this,e),this.ctx=n,this.iframes=r,this.exclude=i,this.iframesTimeout=o}return n(e,[{key:"getContexts",value:function(){var e=[];return(void 0!==this.ctx&&this.ctx?NodeList.prototype.isPrototypeOf(this.ctx)?Array.prototype.slice.call(this.ctx):Array.isArray(this.ctx)?this.ctx:"string"==typeof this.ctx?Array.prototype.slice.call(document.querySelectorAll(this.ctx)):[this.ctx]:[]).forEach(function(t){var n=e.filter(function(e){return e.contains(t)}).length>0;-1!==e.indexOf(t)||n||e.push(t)}),e}},{key:"getIframeContents",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){},r=void 0;try{var i=e.contentWindow;if(r=i.document,!i||!r)throw new Error("iframe inaccessible")}catch(e){n()}r&&t(r)}},{key:"isIframeBlank",value:function(e){var t="about:blank",n=e.getAttribute("src").trim();return e.contentWindow.location.href===t&&n!==t&&n}},{key:"observeIframeLoad",value:function(e,t,n){var r=this,i=!1,o=null,a=function a(){if(!i){i=!0,clearTimeout(o);try{r.isIframeBlank(e)||(e.removeEventListener("load",a),r.getIframeContents(e,t,n))}catch(e){n()}}};e.addEventListener("load",a),o=setTimeout(a,this.iframesTimeout)}},{key:"onIframeReady",value:function(e,t,n){try{"complete"===e.contentWindow.document.readyState?this.isIframeBlank(e)?this.observeIframeLoad(e,t,n):this.getIframeContents(e,t,n):this.observeIframeLoad(e,t,n)}catch(e){n()}}},{key:"waitForIframes",value:function(e,t){var n=this,r=0;this.forEachIframe(e,function(){return!0},function(e){r++,n.waitForIframes(e.querySelector("html"),function(){--r||t()})},function(e){e||t()})}},{key:"forEachIframe",value:function(t,n,r){var i=this,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},a=t.querySelectorAll("iframe"),s=a.length,c=0;a=Array.prototype.slice.call(a);var u=function(){--s<=0&&o(c)};s||u(),a.forEach(function(t){e.matches(t,i.exclude)?u():i.onIframeReady(t,function(e){n(t)&&(c++,r(e)),u()},u)})}},{key:"createIterator",value:function(e,t,n){return document.createNodeIterator(e,t,n,!1)}},{key:"createInstanceOnIframe",value:function(t){return new e(t.querySelector("html"),this.iframes)}},{key:"compareNodeIframe",value:function(e,t,n){if(e.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_PRECEDING){if(null===t)return!0;if(t.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_FOLLOWING)return!0}return!1}},{key:"getIteratorNode",value:function(e){var t=e.previousNode();return{prevNode:t,node:null===t?e.nextNode():e.nextNode()&&e.nextNode()}}},{key:"checkIframeFilter",value:function(e,t,n,r){var i=!1,o=!1;return r.forEach(function(e,t){e.val===n&&(i=t,o=e.handled)}),this.compareNodeIframe(e,t,n)?(!1!==i||o?!1===i||o||(r[i].handled=!0):r.push({val:n,handled:!0}),!0):(!1===i&&r.push({val:n,handled:!1}),!1)}},{key:"handleOpenIframes",value:function(e,t,n,r){var i=this;e.forEach(function(e){e.handled||i.getIframeContents(e.val,function(e){i.createInstanceOnIframe(e).forEachNode(t,n,r)})})}},{key:"iterateThroughNodes",value:function(e,t,n,r,i){for(var o,a=this,s=this.createIterator(t,e,r),c=[],u=[],l=void 0,h=void 0;void 0,o=a.getIteratorNode(s),h=o.prevNode,l=o.node;)this.iframes&&this.forEachIframe(t,function(e){return a.checkIframeFilter(l,h,e,c)},function(t){a.createInstanceOnIframe(t).forEachNode(e,function(e){return u.push(e)},r)}),u.push(l);u.forEach(function(e){n(e)}),this.iframes&&this.handleOpenIframes(c,e,n,r),i()}},{key:"forEachNode",value:function(e,t,n){var r=this,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},o=this.getContexts(),a=o.length;a||i(),o.forEach(function(o){var s=function(){r.iterateThroughNodes(e,o,t,n,function(){--a<=0&&i()})};r.iframes?r.waitForIframes(o,s):s()})}}],[{key:"matches",value:function(e,t){var n="string"==typeof t?[t]:t,r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector;if(r){var i=!1;return n.every(function(t){return!r.call(e,t)||(i=!0,!1)}),i}return!1}}]),e}(),o=function(){function e(n){t(this,e),this.opt=r({},{diacritics:!0,synonyms:{},accuracy:"partially",caseSensitive:!1,ignoreJoiners:!1,ignorePunctuation:[],wildcards:"disabled"},n)}return n(e,[{key:"create",value:function(e){return"disabled"!==this.opt.wildcards&&(e=this.setupWildcardsRegExp(e)),e=this.escapeStr(e),Object.keys(this.opt.synonyms).length&&(e=this.createSynonymsRegExp(e)),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),this.opt.diacritics&&(e=this.createDiacriticsRegExp(e)),e=this.createMergedBlanksRegExp(e),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.createJoinersRegExp(e)),"disabled"!==this.opt.wildcards&&(e=this.createWildcardsRegExp(e)),e=this.createAccuracyRegExp(e),new RegExp(e,"gm"+(this.opt.caseSensitive?"":"i"))}},{key:"escapeStr",value:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}},{key:"createSynonymsRegExp",value:function(e){var t=this.opt.synonyms,n=this.opt.caseSensitive?"":"i",r=this.opt.ignoreJoiners||this.opt.ignorePunctuation.length?"\0":"";for(var i in t)if(t.hasOwnProperty(i)){var o=t[i],a="disabled"!==this.opt.wildcards?this.setupWildcardsRegExp(i):this.escapeStr(i),s="disabled"!==this.opt.wildcards?this.setupWildcardsRegExp(o):this.escapeStr(o);""!==a&&""!==s&&(e=e.replace(new RegExp("("+this.escapeStr(a)+"|"+this.escapeStr(s)+")","gm"+n),r+"("+this.processSynonyms(a)+"|"+this.processSynonyms(s)+")"+r))}return e}},{key:"processSynonyms",value:function(e){return(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),e}},{key:"setupWildcardsRegExp",value:function(e){return(e=e.replace(/(?:\\)*\?/g,function(e){return"\\"===e.charAt(0)?"?":""})).replace(/(?:\\)*\*/g,function(e){return"\\"===e.charAt(0)?"*":""})}},{key:"createWildcardsRegExp",value:function(e){var t="withSpaces"===this.opt.wildcards;return e.replace(/\u0001/g,t?"[\\S\\s]?":"\\S?").replace(/\u0002/g,t?"[\\S\\s]*?":"\\S*")}},{key:"setupIgnoreJoinersRegExp",value:function(e){return e.replace(/[^(|)\\]/g,function(e,t,n){var r=n.charAt(t+1);return/[(|)\\]/.test(r)||""===r?e:e+"\0"})}},{key:"createJoinersRegExp",value:function(e){var t=[],n=this.opt.ignorePunctuation;return Array.isArray(n)&&n.length&&t.push(this.escapeStr(n.join(""))),this.opt.ignoreJoiners&&t.push("\\u00ad\\u200b\\u200c\\u200d"),t.length?e.split(/\u0000+/).join("["+t.join("")+"]*"):e}},{key:"createDiacriticsRegExp",value:function(e){var t=this.opt.caseSensitive?"":"i",n=this.opt.caseSensitive?["aàáảãạăằắẳẵặâầấẩẫậäåāą","AÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćč","CÇĆČ","dđď","DĐĎ","eèéẻẽẹêềếểễệëěēę","EÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïī","IÌÍỈĨỊÎÏĪ","lł","LŁ","nñňń","NÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøō","OÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rř","RŘ","sšśșş","SŠŚȘŞ","tťțţ","TŤȚŢ","uùúủũụưừứửữựûüůū","UÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿ","YÝỲỶỸỴŸ","zžżź","ZŽŻŹ"]:["aàáảãạăằắẳẵặâầấẩẫậäåāąAÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćčCÇĆČ","dđďDĐĎ","eèéẻẽẹêềếểễệëěēęEÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïīIÌÍỈĨỊÎÏĪ","lłLŁ","nñňńNÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøōOÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rřRŘ","sšśșşSŠŚȘŞ","tťțţTŤȚŢ","uùúủũụưừứửữựûüůūUÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿYÝỲỶỸỴŸ","zžżźZŽŻŹ"],r=[];return e.split("").forEach(function(i){n.every(function(n){if(-1!==n.indexOf(i)){if(r.indexOf(n)>-1)return!1;e=e.replace(new RegExp("["+n+"]","gm"+t),"["+n+"]"),r.push(n)}return!0})}),e}},{key:"createMergedBlanksRegExp",value:function(e){return e.replace(/[\s]+/gim,"[\\s]+")}},{key:"createAccuracyRegExp",value:function(e){var t=this,n=this.opt.accuracy,r="string"==typeof n?n:n.value,i="";switch(("string"==typeof n?[]:n.limiters).forEach(function(e){i+="|"+t.escapeStr(e)}),r){case"partially":default:return"()("+e+")";case"complementary":return"()([^"+(i="\\s"+(i||this.escapeStr("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~¡¿")))+"]*"+e+"[^"+i+"]*)";case"exactly":return"(^|\\s"+i+")("+e+")(?=$|\\s"+i+")"}}}]),e}(),a=function(){function a(e){t(this,a),this.ctx=e,this.ie=!1;var n=window.navigator.userAgent;(n.indexOf("MSIE")>-1||n.indexOf("Trident")>-1)&&(this.ie=!0)}return n(a,[{key:"log",value:function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"debug",r=this.opt.log;this.opt.debug&&"object"===(void 0===r?"undefined":e(r))&&"function"==typeof r[n]&&r[n]("mark.js: "+t)}},{key:"getSeparatedKeywords",value:function(e){var t=this,n=[];return e.forEach(function(e){t.opt.separateWordSearch?e.split(" ").forEach(function(e){e.trim()&&-1===n.indexOf(e)&&n.push(e)}):e.trim()&&-1===n.indexOf(e)&&n.push(e)}),{keywords:n.sort(function(e,t){return t.length-e.length}),length:n.length}}},{key:"isNumeric",value:function(e){return Number(parseFloat(e))==e}},{key:"checkRanges",value:function(e){var t=this;if(!Array.isArray(e)||"[object Object]"!==Object.prototype.toString.call(e[0]))return this.log("markRanges() will only accept an array of objects"),this.opt.noMatch(e),[];var n=[],r=0;return e.sort(function(e,t){return e.start-t.start}).forEach(function(e){var i=t.callNoMatchOnInvalidRanges(e,r),o=i.start,a=i.end;i.valid&&(e.start=o,e.length=a-o,n.push(e),r=a)}),n}},{key:"callNoMatchOnInvalidRanges",value:function(e,t){var n=void 0,r=void 0,i=!1;return e&&void 0!==e.start?(r=(n=parseInt(e.start,10))+parseInt(e.length,10),this.isNumeric(e.start)&&this.isNumeric(e.length)&&r-t>0&&r-n>0?i=!0:(this.log("Ignoring invalid or overlapping range: "+JSON.stringify(e)),this.opt.noMatch(e))):(this.log("Ignoring invalid range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:n,end:r,valid:i}}},{key:"checkWhitespaceRanges",value:function(e,t,n){var r=void 0,i=!0,o=n.length,a=t-o,s=parseInt(e.start,10)-a;return(r=(s=s>o?o:s)+parseInt(e.length,10))>o&&(r=o,this.log("End range automatically set to the max value of "+o)),s<0||r-s<0||s>o||r>o?(i=!1,this.log("Invalid range: "+JSON.stringify(e)),this.opt.noMatch(e)):""===n.substring(s,r).replace(/\s+/g,"")&&(i=!1,this.log("Skipping whitespace only range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:s,end:r,valid:i}}},{key:"getTextNodes",value:function(e){var t=this,n="",r=[];this.iterator.forEachNode(NodeFilter.SHOW_TEXT,function(e){r.push({start:n.length,end:(n+=e.textContent).length,node:e})},function(e){return t.matchesExclude(e.parentNode)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT},function(){e({value:n,nodes:r})})}},{key:"matchesExclude",value:function(e){return i.matches(e,this.opt.exclude.concat(["script","style","title","head","html"]))}},{key:"wrapRangeInTextNode",value:function(e,t,n){var r=this.opt.element?this.opt.element:"mark",i=e.splitText(t),o=i.splitText(n-t),a=document.createElement(r);return a.setAttribute("data-markjs","true"),this.opt.className&&a.setAttribute("class",this.opt.className),a.textContent=i.textContent,i.parentNode.replaceChild(a,i),o}},{key:"wrapRangeInMappedTextNode",value:function(e,t,n,r,i){var o=this;e.nodes.every(function(a,s){var c=e.nodes[s+1];if(void 0===c||c.start>t){if(!r(a.node))return!1;var u=t-a.start,l=(n>a.end?a.end:n)-a.start,h=e.value.substr(0,a.start),f=e.value.substr(l+a.start);if(a.node=o.wrapRangeInTextNode(a.node,u,l),e.value=h+f,e.nodes.forEach(function(t,n){n>=s&&(e.nodes[n].start>0&&n!==s&&(e.nodes[n].start-=l),e.nodes[n].end-=l)}),n-=l,i(a.node.previousSibling,a.start),!(n>a.end))return!1;t=a.end}return!0})}},{key:"wrapGroups",value:function(e,t,n,r){return r((e=this.wrapRangeInTextNode(e,t,t+n)).previousSibling),e}},{key:"separateGroups",value:function(e,t,n,r,i){for(var o=t.length,a=1;a-1&&r(t[a],e)&&(e=this.wrapGroups(e,s,t[a].length,i))}return e}},{key:"wrapMatches",value:function(e,t,n,r,i){var o=this,a=0===t?0:t+1;this.getTextNodes(function(t){t.nodes.forEach(function(t){t=t.node;for(var i=void 0;null!==(i=e.exec(t.textContent))&&""!==i[a];){if(o.opt.separateGroups)t=o.separateGroups(t,i,a,n,r);else{if(!n(i[a],t))continue;var s=i.index;if(0!==a)for(var c=1;c - - - - - Provisioning Platform Documentation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-

Keyboard shortcuts

-
-

Press or to navigate between chapters

-

Press S or / to search in the book

-

Press ? to show this help

-

Press Esc to hide this help

-
-
-
-
- - - - - - - - - - - - - -
- -
- - - - - - - - -
-
-

- Provisioning Logo -

-

- Provisioning -

-

Provisioning Platform Documentation

-

Welcome to the Provisioning Platform documentation. This is an enterprise-grade Infrastructure -as Code (IaC) platform built with Rust, Nushell, and Nickel.

-

What is Provisioning

-

Provisioning is a comprehensive infrastructure automation platform that manages complete -infrastructure lifecycles across multiple cloud providers. The platform emphasizes type-safety, -configuration-driven design, and workspace-first organization.

-

Key Features

-
    -
  • Workspace Management: Default mode for organizing infrastructure, settings, schemas, and extensions
  • -
  • Type-Safe Configuration: Nickel-based configuration system with validation and contracts
  • -
  • Multi-Cloud Support: Unified interface for AWS, UpCloud, and local providers
  • -
  • Modular CLI Architecture: 111+ commands with 84% code reduction through modularity
  • -
  • Batch Workflow Engine: Orchestrate complex multi-cloud operations
  • -
  • Complete Security System: Authentication, authorization, encryption, and compliance
  • -
  • Extensible Architecture: Custom providers, task services, and plugins
  • -
-

Getting Started

-

New users should start with:

-
    -
  1. Prerequisites - System requirements and dependencies
  2. -
  3. Installation - Install the platform
  4. -
  5. Quick Start - 5-minute deployment tutorial
  6. -
  7. First Deployment - Comprehensive walkthrough
  8. -
-

Documentation Structure

-
    -
  • Getting Started: Installation and initial setup
  • -
  • User Guides: Workflow tutorials and best practices
  • -
  • Infrastructure as Code: Nickel configuration and schema reference
  • -
  • Platform Features: Core capabilities and systems
  • -
  • Operations: Deployment, monitoring, and maintenance
  • -
  • Security: Complete security system documentation
  • -
  • Development: Extension and plugin development
  • -
  • API Reference: REST API and CLI command reference
  • -
  • Architecture: System design and ADRs
  • -
  • Examples: Practical use cases and patterns
  • -
  • Troubleshooting: Problem-solving guides
  • -
-

Core Technologies

-
    -
  • Rust: Platform services and performance-critical components
  • -
  • Nushell: Scripting, CLI, and automation
  • -
  • Nickel: Type-safe infrastructure configuration
  • -
  • SecretumVault: Secrets management integration
  • -
-

Workspace-First Approach

-

Provisioning uses workspaces as the default organizational unit. A workspace contains:

-
    -
  • Infrastructure definitions (Nickel schemas)
  • -
  • Environment-specific settings
  • -
  • Custom extensions and providers
  • -
  • Deployment state and metadata
  • -
-

All operations work within workspace context, providing isolation and consistency.

-

Support and Community

-
    -
  • Issues: Report bugs and request features on GitHub
  • -
  • Documentation: This documentation site
  • -
  • Examples: See the Examples section
  • -
-

License

-

See project LICENSE file for details.

-

Getting Started

-

Your journey to infrastructure automation starts here. This section guides you from zero to your first successful deployment in minutes.

-

Overview

-

Getting started with Provisioning involves:

-
    -
  • Verifying prerequisites - System requirements, tools, cloud accounts
  • -
  • Installing platform - Binary or container installation
  • -
  • Initial configuration - Environment setup, credentials, workspaces
  • -
  • First deployment - Deploy actual infrastructure in 5 minutes
  • -
  • Verification - Validate everything is working correctly
  • -
-

By the end of this section, you’ll have a running Provisioning installation and have deployed your first infrastructure.

-

Quick Start Guides

-

Starting from Scratch

-
    -
  • -

    Prerequisites - System requirements (Nushell 0.109.1+, Docker/Podman optional), cloud account setup, tool installation.

    -
  • -
  • -

    Installation - Step-by-step installation: binary download, container, or source build with platform verification.

    -
  • -
  • -

    Quick Start - 5-minute guide: install → configure → deploy infrastructure (requires 5 minutes and your AWS/UpCloud credentials).

    -
  • -
  • -

    First Deployment - Deploy your first infrastructure: create workspace, configure provider, deploy resources, verify success.

    -
  • -
  • -

    Verification - Validate installation: check system health, test CLI commands, verify cloud integration, confirm resource creation.

    -
  • -
-

What You’ll Learn

-

By completing this section, you’ll know how to:

-
    -
  1. ✅ Install and configure Provisioning
  2. -
  3. ✅ Create your first workspace
  4. -
  5. ✅ Configure cloud providers (AWS, UpCloud, Hetzner, etc.)
  6. -
  7. ✅ Write simple Nickel infrastructure definitions
  8. -
  9. ✅ Deploy infrastructure using Provisioning
  10. -
  11. ✅ Verify and manage deployed resources
  12. -
-

Prerequisites Checklist

-

Before starting, verify you have:

-
    -
  • -Linux, macOS, or Windows with WSL2
  • -
  • -Nushell 0.109.1 or newer (nu --version)
  • -
  • -2GB+ RAM and 100MB disk space
  • -
  • -Internet connectivity
  • -
  • -Cloud account (AWS, UpCloud, Hetzner, or local demo mode)
  • -
  • -Access credentials or API tokens for cloud provider
  • -
-

Missing something? See Prerequisites for detailed instructions.

-

5-Minute Quick Start

-

If you’re impatient, here’s the ultra-quick path:

-
# 1. Install (2 minutes)
-curl -fsSL  [https://provisioning.io/install.sh](https://provisioning.io/install.sh) | sh
-
-# 2. Verify installation (30 seconds)
-provisioning --version
-provisioning status
-
-# 3. Create workspace (30 seconds)
-provisioning workspace create --name demo
-
-# 4. Add cloud provider (1 minute)
-provisioning config set --workspace demo \
-  providers.aws.region us-east-1 \
-  providers.aws.credentials_source aws_iam
-
-# 5. Deploy infrastructure (1 minute)
-provisioning deploy --workspace demo \
-  --config examples/simple-instance.ncl
-
-# 6. Verify (30 seconds)
-provisioning resource list --workspace demo
-
-

For detailed walkthrough, see Quick Start.

-

Installation Methods

- -
# Download and extract
-curl -fsSL  [https://provisioning.io/provisioning-latest-linux.tar.gz](https://provisioning.io/provisioning-latest-linux.tar.gz) | tar xz
-sudo mv provisioning /usr/local/bin/
-provisioning --version
-
-

Option 2: Container

-
docker run -it provisioning/provisioning:latest \
-  provisioning --version
-
-

Option 3: Build from Source

-
git clone  [https://github.com/provisioning/provisioning.git](https://github.com/provisioning/provisioning.git)
-cd provisioning
-cargo build --release
-./target/release/provisioning --version
-
-

See Installation for detailed instructions.

-

Next Steps After Installation

-
    -
  1. Read Quick Start - 5-minute walkthrough
  2. -
  3. Complete First Deployment - Deploy real infrastructure
  4. -
  5. Run Verification - Validate system health
  6. -
  7. Move to Guides - Learn advanced features
  8. -
  9. Explore Examples - Real-world scenarios
  10. -
-

Common Questions

-

Q: How long does installation take? -A: 5-10 minutes including cloud credential setup.

-

Q: What if I don’t have a cloud account? -A: Try our demo provider in local mode - no cloud account needed.

-

Q: Can I use Provisioning offline? -A: Yes, with local provider. Cloud operations require internet.

-

Q: What’s the learning curve? -A: 30 minutes for basics, days to master advanced features.

-

Q: Where do I get help? -A: See Getting Help or Troubleshooting.

-

Architecture Overview

-

Provisioning works in these steps:

-
1. Install Platform
-   ↓
-2. Create Workspace
-   ↓
-3. Add Cloud Provider Credentials
-   ↓
-4. Write Nickel Configuration
-   ↓
-5. Deploy Infrastructure
-   ↓
-6. Monitor & Manage
-
-

What’s Next

-

After getting started:

- -

Getting Help

-

If you get stuck:

-
    -
  1. Check Troubleshooting
  2. -
  3. Review Guides for similar scenarios
  4. -
  5. Search Examples for your use case
  6. -
  7. Ask in community forums or open a GitHub issue
  8. -
- -
    -
  • Full Guides → See provisioning/docs/src/guides/
  • -
  • Examples → See provisioning/docs/src/examples/
  • -
  • Architecture → See provisioning/docs/src/architecture/
  • -
  • Features → See provisioning/docs/src/features/
  • -
  • API Reference → See provisioning/docs/src/api-reference/
  • -
-

Prerequisites

-

Before installing the Provisioning platform, ensure your system meets the following requirements.

-

Required Software

-

Nushell 0.109.1+

-

Nushell is the primary shell and scripting environment for the platform.

-

Installation:

-
# macOS (Homebrew)
-brew install nushell
-
-# Linux (Cargo)
-cargo install nu
-
-# From source
-git clone  [https://github.com/nushell/nushell](https://github.com/nushell/nushell)
-cd nushell
-cargo install --path .
-
-

Verify installation:

-
nu --version
-# Should show: 0.109.1 or higher
-
-

Nickel 1.15.1+

-

Nickel is the infrastructure-as-code language providing type-safe configuration with lazy evaluation.

-

Installation:

-
# macOS (Homebrew)
-brew install nickel
-
-# Linux (Cargo)
-cargo install nickel-lang-cli
-
-# From source
-git clone  [https://github.com/tweag/nickel](https://github.com/tweag/nickel)
-cd nickel
-cargo install --path cli
-
-

Verify installation:

-
nickel --version
-# Should show: 1.15.1 or higher
-
-

SOPS 3.10.2+

-

SOPS (Secrets OPerationS) provides encrypted configuration and secrets management.

-

Installation:

-
# macOS (Homebrew)
-brew install sops
-
-# Linux (binary download)
-wget  [https://github.com/getsops/sops/releases/download/v3.10.2/sops-v3.10.2.linux.amd64](https://github.com/getsops/sops/releases/download/v3.10.2/sops-v3.10.2.linux.amd64)
-sudo mv sops-v3.10.2.linux.amd64 /usr/local/bin/sops
-sudo chmod +x /usr/local/bin/sops
-
-

Verify installation:

-
sops --version
-# Should show: 3.10.2 or higher
-
-

Age 1.2.1+

-

Age provides modern encryption for secrets used by SOPS.

-

Installation:

-
# macOS (Homebrew)
-brew install age
-
-# Linux (binary download)
-wget  [https://github.com/FiloSottile/age/releases/download/v1.2.1/age-v1.2.1-linux-amd64.tar.gz](https://github.com/FiloSottile/age/releases/download/v1.2.1/age-v1.2.1-linux-amd64.tar.gz)
-tar xzf age-v1.2.1-linux-amd64.tar.gz
-sudo mv age/age /usr/local/bin/
-sudo chmod +x /usr/local/bin/age
-
-

Verify installation:

-
age --version
-# Should show: 1.2.1 or higher
-
-

K9s 0.50.6+

-

K9s provides a terminal UI for managing Kubernetes clusters.

-

Installation:

-
# macOS (Homebrew)
-brew install derailed/k9s/k9s
-
-# Linux (binary download)
-wget  [https://github.com/derailed/k9s/releases/download/v0.50.6/k9s_Linux_amd64.tar.gz](https://github.com/derailed/k9s/releases/download/v0.50.6/k9s_Linux_amd64.tar.gz)
-tar xzf k9s_Linux_amd64.tar.gz
-sudo mv k9s /usr/local/bin/
-
-

Verify installation:

-
k9s version
-# Should show: 0.50.6 or higher
-
-

Optional Software

-

mdBook

-

For building and serving local documentation.

-
# Install with Cargo
-cargo install mdbook
-
-# Verify
-mdbook --version
-
-

Docker or Podman

-

Container runtime for test environments and local development.

-
# Docker (macOS)
-brew install --cask docker
-
-# Podman (Linux)
-sudo apt-get install podman
-
-# Verify
-docker --version
-# or
-podman --version
-
-

Cargo (Rust)

-

Required for building platform services and native plugins.

-
# Install Rust and Cargo
-curl --proto '=https' --tlsv1.2 -sSf  [https://sh.rustup.rs](https://sh.rustup.rs) | sh
-
-# Verify
-cargo --version
-
-

Git

-

Version control for workspace management and configuration.

-
# Most systems have Git pre-installed
-git --version
-
-# Install if needed (macOS)
-brew install git
-
-# Install if needed (Linux)
-sudo apt-get install git
-
-

System Requirements

-

Minimum Hardware

-

Development Workstation:

-
    -
  • CPU: 2 cores
  • -
  • RAM: 4 GB
  • -
  • Disk: 20 GB available space
  • -
  • Network: Internet connection for provider APIs
  • -
-

Production Control Plane:

-
    -
  • CPU: 4 cores
  • -
  • RAM: 8 GB
  • -
  • Disk: 50 GB available space (SSD recommended)
  • -
  • Network: Stable internet connection, public IP optional
  • -
-

Supported Operating Systems

-

Primary Support:

-
    -
  • macOS 12.0+ (Monterey or newer)
  • -
  • Linux distributions with kernel 5.0+ -
      -
    • Ubuntu 20.04 LTS or newer
    • -
    • Debian 11 or newer
    • -
    • Fedora 35 or newer
    • -
    • RHEL 8 or newer
    • -
    -
  • -
-

Limited Support:

-
    -
  • Windows 10/11 via WSL2 (Windows Subsystem for Linux)
  • -
-

Network Requirements

-

Outbound Access:

-
    -
  • HTTPS (443) to cloud provider APIs
  • -
  • HTTPS (443) to GitHub (for version updates)
  • -
  • SSH (22) for server management
  • -
-

Inbound Access (optional, for platform services):

-
    -
  • Port 8080: HTTP API
  • -
  • Port 8081: MCP server
  • -
  • Port 5000: Orchestrator service
  • -
-

Cloud Provider Access

-

At least one cloud provider account with API credentials:

-

UpCloud:

-
    -
  • API username and password
  • -
  • Account with sufficient quota for servers
  • -
-

AWS:

-
    -
  • AWS Access Key ID and Secret Access Key
  • -
  • IAM permissions for EC2, VPC, EBS operations
  • -
  • Account with sufficient EC2 quota
  • -
-

Local Provider:

-
    -
  • Docker or Podman installed
  • -
  • Sufficient local system resources
  • -
-

Permission Requirements

-

User Permissions

-

Standard User (recommended):

-
    -
  • Read/write access to workspace directory
  • -
  • Ability to create symlinks for CLI installation
  • -
  • SSH key generation capability
  • -
-

Administrative Tasks (optional):

-
    -
  • Installing CLI to /usr/local/bin (requires sudo)
  • -
  • Installing system-wide dependencies
  • -
  • Configuring system services
  • -
-

File System Permissions

-
# Workspace directory
-chmod 755 ~/provisioning-workspace
-
-# Configuration files
-chmod 600 ~/.config/provisioning/user_config.yaml
-chmod 600 ~/.ssh/provisioning_*
-
-# Executable permissions for CLI
-chmod +x /path/to/provisioning/core/cli/provisioning
-
-

Verification Checklist

-

Before proceeding to installation, verify all prerequisites:

-
# Check required tools
-nu --version              # 0.109.1+
-nickel --version          # 1.15.1+
-sops --version            # 3.10.2+
-age --version             # 1.2.1+
-k9s version               # 0.50.6+
-
-# Check optional tools
-mdbook --version          # Latest
-docker --version          # Latest
-cargo --version           # Latest
-git --version             # Latest
-
-# Verify system resources
-nproc                     # CPU cores (2+ minimum)
-free -h                   # RAM (4GB+ minimum)
-df -h ~                   # Disk space (20GB+ minimum)
-
-# Test network connectivity
-curl -I  [https://api.github.com](https://api.github.com)
-curl -I  [https://hub.upcloud.com](https://hub.upcloud.com)  # UpCloud API
-curl -I  [https://ec2.amazonaws.com](https://ec2.amazonaws.com)  # AWS API
-
-

Next Steps

-

Once all prerequisites are met, proceed to:

- -

Installation

-

This guide covers installing the Provisioning platform on your system.

-

Prerequisites

-

Ensure all prerequisites are met before proceeding.

-

Installation Steps

-

Step 1: Clone the Repository

-
# Clone the provisioning repository
-git clone  [https://github.com/your-org/project-provisioning](https://github.com/your-org/project-provisioning)
-cd project-provisioning
-
-

Step 2: Add CLI to PATH

-

The CLI can be installed globally or run directly from the repository.

-

Option A: Symbolic Link (Recommended):

-
# Create symbolic link to /usr/local/bin
-ln -sf "$(pwd)/provisioning/core/cli/provisioning" /usr/local/bin/provisioning
-
-# Verify installation
-provisioning version
-
-

Option B: PATH Environment Variable:

-
# Add to ~/.bashrc, ~/.zshrc, or ~/.config/nushell/env.nu
-export PATH="$PATH:/path/to/project-provisioning/provisioning/core/cli"
-
-# Reload shell configuration
-source ~/.bashrc  # or ~/.zshrc
-
-

Option C: Direct Execution:

-
# Run directly from repository (no installation needed)
-./provisioning/core/cli/provisioning version
-
-

Step 3: Verify Installation

-
# Check CLI is accessible
-provisioning version
-
-# Show environment configuration
-provisioning env
-
-# Display help
-provisioning help
-
-

Expected output:

-
Provisioning Platform
-CLI Version: (current version)
-Nushell: 0.109.1+
-Nickel: 1.15.1+
-
-

Step 4: Initialize Configuration

-

Generate default configuration files:

-
# Create user configuration directory
-mkdir -p ~/.config/provisioning
-
-# Initialize default user configuration (optional)
-provisioning config init
-
-

This creates ~/.config/provisioning/user_config.yaml with sensible defaults.

-

Step 5: Configure Cloud Provider Credentials

-

Configure credentials for at least one cloud provider.

-

UpCloud:

-
# ~/.config/provisioning/user_config.yaml
-providers:
-  upcloud:
-    username: "your-username"
-    password: "your-password"  # Use SOPS for encryption in production
-    default_zone: "de-fra1"
-
-

AWS:

-
# ~/.config/provisioning/user_config.yaml
-providers:
-  aws:
-    access_key_id: "AKIA..."
-    secret_access_key: "..."  # Use SOPS for encryption in production
-    default_region: "us-east-1"
-
-

Local Provider (no credentials required):

-
# ~/.config/provisioning/user_config.yaml
-providers:
-  local:
-    container_runtime: "docker"  # or "podman"
-
- -

Use SOPS to encrypt sensitive configuration:

-
# Generate Age encryption key
-age-keygen -o ~/.config/provisioning/age-key.txt
-
-# Extract public key
-export AGE_PUBLIC_KEY=$(grep "public key:" ~/.config/provisioning/age-key.txt | cut -d: -f2 | tr -d ' ')
-
-# Create .sops.yaml configuration
-cat > ~/.config/provisioning/.sops.yaml <<EOF
-creation_rules:
-  - path_regex: .*user_config\.yaml$
-    age: $AGE_PUBLIC_KEY
-EOF
-
-# Encrypt configuration file
-sops -e -i ~/.config/provisioning/user_config.yaml
-
-

Decrypting (automatic with SOPS):

-
# Set Age key path
-export SOPS_AGE_KEY_FILE=~/.config/provisioning/age-key.txt
-
-# SOPS will automatically decrypt when accessed
-provisioning config show
-
-

Step 7: Validate Configuration

-
# Validate all configuration files
-provisioning validate config
-
-# Check provider connectivity
-provisioning providers
-
-# Show complete environment
-provisioning allenv
-
-

Optional: Install Platform Services

-

Platform services provide additional capabilities like orchestration and web UI.

-

Orchestrator Service (Rust)

-
# Build orchestrator
-cd provisioning/platform/orchestrator
-cargo build --release
-
-# Start orchestrator
-./target/release/orchestrator --port 5000
-
-

Control Center (Web UI)

-
# Build control center
-cd provisioning/platform/control-center
-cargo build --release
-
-# Start control center
-./target/release/control-center --port 8080
-
-

Native Plugins (Performance)

-

Install Nushell plugins for 10-50x performance improvements:

-
# Build and register plugins
-cd provisioning/core/plugins
-
-# Auth plugin
-cargo build --release --package nu_plugin_auth
-nu -c "register target/release/nu_plugin_auth"
-
-# KMS plugin
-cargo build --release --package nu_plugin_kms
-nu -c "register target/release/nu_plugin_kms"
-
-# Orchestrator plugin
-cargo build --release --package nu_plugin_orchestrator
-nu -c "register target/release/nu_plugin_orchestrator"
-
-# Verify plugins are registered
-nu -c "plugin list"
-
-

Workspace Initialization

-

Create your first workspace for managing infrastructure:

-
# Initialize new workspace
-provisioning workspace init my-project
-cd my-project
-
-# Verify workspace structure
-ls -la
-
-

Expected workspace structure:

-
my-project/
-├── infra/          # Infrastructure Nickel schemas
-├── config/         # Workspace configuration
-├── extensions/     # Custom extensions
-└── runtime/        # Runtime data and state
-
-

Troubleshooting

-

Common Issues

-

CLI not found after installation:

-
# Verify symlink was created
-ls -l /usr/local/bin/provisioning
-
-# Check PATH includes /usr/local/bin
-echo $PATH
-
-# Try direct path
-/usr/local/bin/provisioning version
-
-

Permission denied when creating symlink:

-
# Use sudo for system-wide installation
-sudo ln -sf "$(pwd)/provisioning/core/cli/provisioning" /usr/local/bin/provisioning
-
-# Or use user-local bin directory
-mkdir -p ~/.local/bin
-ln -sf "$(pwd)/provisioning/core/cli/provisioning" ~/.local/bin/provisioning
-export PATH="$PATH:$HOME/.local/bin"
-
-

Nushell version mismatch:

-
# Check Nushell version
-nu --version
-
-# Update Nushell
-brew upgrade nushell  # macOS
-cargo install nu --force  # Linux
-
-

Nickel not found:

-
# Install Nickel
-brew install nickel  # macOS
-cargo install nickel-lang-cli  # Linux
-
-# Verify
-nickel --version
-
-

Verification

-

Confirm successful installation:

-
# Complete installation check
-provisioning version      # CLI version
-provisioning env          # Environment configuration
-provisioning providers    # Available cloud providers
-provisioning validate config  # Configuration validation
-provisioning help         # Help system
-
-

Next Steps

-

Once installation is complete:

- -

Quick Start

-

Deploy your first infrastructure in 5 minutes using the Provisioning platform.

-

Prerequisites

- -

5-Minute Deployment

-

Step 1: Create Workspace (30 seconds)

-
# Initialize workspace
-provisioning workspace init quickstart-demo
-cd quickstart-demo
-
-

Workspace structure created:

-
quickstart-demo/
-├── infra/       # Infrastructure definitions
-├── config/      # Workspace configuration
-├── extensions/  # Custom providers/taskservs
-└── runtime/     # State and logs
-
-

Step 2: Define Infrastructure (1 minute)

-

Create a simple server configuration using Nickel:

-
# Create infrastructure schema
-cat > infra/demo-server.ncl <<'EOF'
-{
-  metadata = {
-    name = "demo-server"
-    provider = "local"  # Use local provider for quick demo
-    environment = "development"
-  }
-
-  infrastructure = {
-    servers = [
-      {
-        name = "web-01"
-        plan = "small"
-        role = "web"
-      }
-    ]
-  }
-
-  services = {
-    taskservs = ["containerd"]  # Simple container runtime
-  }
-}
-EOF
-
-

Using UpCloud or AWS? Change provider:

-
metadata.provider = "upcloud"  # or "aws"
-
-

Step 3: Validate Configuration (30 seconds)

-
# Validate Nickel schema
-nickel typecheck infra/demo-server.ncl
-
-# Validate provisioning configuration
-provisioning validate config
-
-# Preview what will be created
-provisioning server create --check --infra demo-server
-
-

Expected output:

-
Infrastructure Plan: demo-server
-Provider: local
-Servers to create: 1
-  - web-01 (small, role: web)
-Task services: containerd
-
-Estimated resources:
-  CPU: 2 cores
-  RAM: 2 GB
-  Disk: 10 GB
-
-

Step 4: Create Infrastructure (2 minutes)

-
# Create server
-provisioning server create --infra demo-server --yes
-
-# Monitor progress
-provisioning server status web-01
-
-

Progress indicators:

-
Creating server: web-01...
-  [████████████████████████] 100% - Server provisioned
-  [████████████████████████] 100% - SSH configured
-  [████████████████████████] 100% - Network ready
-
-Server web-01 created successfully
-IP Address: 10.0.1.10
-Status: running
-
-

Step 5: Install Task Service (1 minute)

-
# Install containerd
-provisioning taskserv create containerd --infra demo-server
-
-# Verify installation
-provisioning taskserv status containerd
-
-

Output:

-
Installing containerd on web-01...
-  [████████████████████████] 100% - Dependencies resolved
-  [████████████████████████] 100% - Containerd installed
-  [████████████████████████] 100% - Service started
-  [████████████████████████] 100% - Health check passed
-
-Containerd v1.7.0 installed successfully
-
-

Step 6: Verify Deployment (30 seconds)

-
# SSH into server
-provisioning server ssh web-01
-
-# Inside server - verify containerd
-sudo systemctl status containerd
-sudo ctr version
-
-# Exit server
-exit
-
-

What You’ve Accomplished

-

In 5 minutes, you’ve:

-
    -
  • Created a workspace for infrastructure management
  • -
  • Defined infrastructure using type-safe Nickel schemas
  • -
  • Validated configuration before deployment
  • -
  • Provisioned a server on your chosen provider
  • -
  • Installed and configured containerd
  • -
  • Verified the deployment
  • -
-

Common Workflows

-

List Resources

-
# List all servers
-provisioning server list
-
-# List task services
-provisioning taskserv list
-
-# Show workspace info
-provisioning workspace info
-
-

Modify Infrastructure

-
# Edit infrastructure schema
-nano infra/demo-server.ncl
-
-# Validate changes
-provisioning validate config --infra demo-server
-
-# Apply changes
-provisioning server update --infra demo-server
-
-

Cleanup

-
# Remove task service
-provisioning taskserv delete containerd --infra demo-server
-
-# Delete server
-provisioning server delete web-01 --yes
-
-# Remove workspace
-cd ..
-rm -rf quickstart-demo
-
-

Next Steps

-

Deploy Kubernetes

-

Ready for something more complex?

-
# infra/kubernetes-cluster.ncl
-{
-  metadata = {
-    name = "k8s-cluster"
-    provider = "upcloud"
-  }
-
-  infrastructure = {
-    servers = [
-      {name = "control-01", plan = "medium", role = "control"}
-      {name = "worker-01", plan = "large", role = "worker"}
-      {name = "worker-02", plan = "large", role = "worker"}
-    ]
-  }
-
-  services = {
-    taskservs = ["kubernetes", "cilium", "rook-ceph"]
-  }
-}
-
-
provisioning server create --infra kubernetes-cluster --yes
-provisioning taskserv create kubernetes --infra kubernetes-cluster
-
-

Multi-Cloud Deployment

-

Deploy to multiple providers simultaneously:

-
# infra/multi-cloud.ncl
-{
-  batch_workflow = {
-    operations = [
-      {
-        id = "aws-cluster"
-        provider = "aws"
-        servers = [{name = "aws-web-01", plan = "t3.medium"}]
-      }
-      {
-        id = "upcloud-cluster"
-        provider = "upcloud"
-        servers = [{name = "upcloud-web-01", plan = "medium"}]
-      }
-    ]
-  }
-}
-
-
provisioning batch submit infra/multi-cloud.ncl
-
-

Use Interactive Guides

-

Access built-in guides for comprehensive walkthroughs:

-
# Quick command reference
-provisioning sc
-
-# Complete from-scratch guide
-provisioning guide from-scratch
-
-# Customization patterns
-provisioning guide customize
-
-

Troubleshooting Quick Issues

-

Server creation fails

-
# Check provider connectivity
-provisioning providers
-
-# Validate credentials
-provisioning validate config
-
-# Enable debug mode
-provisioning --debug server create --infra demo-server
-
-

Task service installation fails

-
# Check server connectivity
-provisioning server ssh web-01
-
-# Verify dependencies
-provisioning taskserv check-deps containerd
-
-# Retry installation
-provisioning taskserv create containerd --infra demo-server --force
-
-

Configuration validation errors

-
# Check Nickel syntax
-nickel typecheck infra/demo-server.ncl
-
-# Show detailed validation errors
-provisioning validate config --verbose
-
-# View configuration
-provisioning config show
-
-

Reference

-

Essential Commands

-
# Workspace management
-provisioning workspace init <name>
-provisioning workspace list
-provisioning workspace switch <name>
-
-# Server operations
-provisioning server create --infra <name>
-provisioning server list
-provisioning server status <hostname>
-provisioning server ssh <hostname>
-provisioning server delete <hostname>
-
-# Task service operations
-provisioning taskserv create <service> --infra <name>
-provisioning taskserv list
-provisioning taskserv status <service>
-provisioning taskserv delete <service>
-
-# Configuration
-provisioning config show
-provisioning validate config
-provisioning env
-
-

Quick Reference

-
# Shortcut for fastest reference
-provisioning sc
-
-

Further Reading

- -

First Deployment

-

Comprehensive walkthrough deploying production-ready infrastructure with the Provisioning platform.

-

Overview

-

This guide walks through deploying a complete Kubernetes cluster with storage and networking -on a cloud provider. You’ll learn workspace management, Nickel schema structure, provider -configuration, dependency resolution, and validation workflows.

-

Deployment Architecture

-

What we’ll build:

-
    -
  • 3-node Kubernetes cluster (1 control plane, 2 workers)
  • -
  • Cilium CNI for networking
  • -
  • Rook-Ceph for persistent storage
  • -
  • Container runtime (containerd)
  • -
  • Automated dependency resolution
  • -
  • Health monitoring
  • -
-

Prerequisites

-
    -
  • Platform installed
  • -
  • Cloud provider credentials configured (UpCloud or AWS recommended)
  • -
  • 30-60 minutes for complete deployment
  • -
-

Part 1: Workspace Setup

-

Create Workspace

-
# Initialize production workspace
-provisioning workspace init production-k8s
-cd production-k8s
-
-# Verify structure
-ls -la
-
-

Workspace contains:

-
production-k8s/
-├── infra/       # Infrastructure Nickel schemas
-├── config/      # Workspace configuration
-├── extensions/  # Custom providers/taskservs
-└── runtime/     # State and logs
-
-

Configure Workspace

-
# Edit workspace configuration
-cat > config/provisioning-config.yaml <<'EOF'
-workspace:
-  name: production-k8s
-  environment: production
-
-defaults:
-  provider: upcloud  # or aws
-  region: de-fra1    # UpCloud Frankfurt
-  ssh_key_path: ~/.ssh/provisioning_production
-
-servers:
-  default_plan: medium
-  auto_backup: true
-
-logging:
-  level: info
-  format: text
-EOF
-
-

Part 2: Infrastructure Definition

-

Define Nickel Schema

-

Create infrastructure definition with type-safe Nickel:

-
# Create Kubernetes cluster schema
-cat > infra/k8s-cluster.ncl <<'EOF'
-{
-  metadata = {
-    name = "k8s-prod"
-    provider = "upcloud"
-    environment = "production"
-    version = "1.0.0"
-  }
-
-  infrastructure = {
-    servers = [
-      {
-        name = "k8s-control-01"
-        plan = "medium"      # 4 CPU, 8 GB RAM
-        role = "control"
-        zone = "de-fra1"
-        disk_size_gb = 50
-        backup_enabled = true
-      }
-      {
-        name = "k8s-worker-01"
-        plan = "large"       # 8 CPU, 16 GB RAM
-        role = "worker"
-        zone = "de-fra1"
-        disk_size_gb = 100
-        backup_enabled = true
-      }
-      {
-        name = "k8s-worker-02"
-        plan = "large"
-        role = "worker"
-        zone = "de-fra1"
-        disk_size_gb = 100
-        backup_enabled = true
-      }
-    ]
-  }
-
-  services = {
-    taskservs = [
-      "containerd"     # Container runtime (dependency)
-      "etcd"           # Key-value store (dependency)
-      "kubernetes"     # Core orchestration
-      "cilium"         # CNI networking
-      "rook-ceph"      # Persistent storage
-    ]
-  }
-
-  kubernetes = {
-    version = "1.28.0"
-    pod_cidr = "10.244.0.0/16"
-    service_cidr = "10.96.0.0/12"
-    container_runtime = "containerd"
-    cri_socket = "/run/containerd/containerd.sock"
-  }
-
-  networking = {
-    cni = "cilium"
-    enable_network_policy = true
-    enable_encryption = true
-  }
-
-  storage = {
-    provider = "rook-ceph"
-    replicas = 3
-    storage_class = "ceph-rbd"
-  }
-}
-EOF
-
-

Validate Schema

-
# Type-check Nickel schema
-nickel typecheck infra/k8s-cluster.ncl
-
-# Validate against provisioning contracts
-provisioning validate config --infra k8s-cluster
-
-

Expected output:

-
Schema validation: PASSED
-  - Syntax: Valid Nickel
-  - Type safety: All contracts satisfied
-  - Dependencies: Resolved (5 taskservs)
-  - Provider: upcloud (credentials found)
-
-

Part 3: Preview and Validation

-

Preview Infrastructure

-
# Dry-run to see what will be created
-provisioning server create --check --infra k8s-cluster
-
-

Output shows:

-
Infrastructure Plan: k8s-prod
-Provider: upcloud
-Region: de-fra1
-
-Servers to create: 3
-  - k8s-control-01 (medium, 4 CPU, 8 GB RAM, 50 GB disk)
-  - k8s-worker-01 (large, 8 CPU, 16 GB RAM, 100 GB disk)
-  - k8s-worker-02 (large, 8 CPU, 16 GB RAM, 100 GB disk)
-
-Task services: 5 (with dependencies resolved)
-  1. containerd (dependency for kubernetes)
-  2. etcd (dependency for kubernetes)
-  3. kubernetes
-  4. cilium (requires kubernetes)
-  5. rook-ceph (requires kubernetes)
-
-Estimated monthly cost: $xxx.xx
-Estimated deployment time: 15-20 minutes
-
-WARNING: Production deployment - ensure backup enabled
-
-

Dependency Graph

-
# Visualize dependency resolution
-provisioning taskserv dependencies kubernetes --graph
-
-

Shows:

-
kubernetes
-├── containerd (required)
-├── etcd (required)
-└── cni (cilium) (soft dependency)
-
-cilium
-└── kubernetes (required)
-
-rook-ceph
-└── kubernetes (required)
-
-

Part 4: Server Provisioning

-

Create Servers

-
# Create all servers in parallel
-provisioning server create --infra k8s-cluster --yes
-
-

Progress tracking:

-
Creating 3 servers...
-  k8s-control-01: [████████████████████████] 100%
-  k8s-worker-01:  [████████████████████████] 100%
-  k8s-worker-02:  [████████████████████████] 100%
-
-Servers created: 3/3
-SSH configured: 3/3
-Network ready: 3/3
-
-Servers available:
-  k8s-control-01: 94.237.x.x (running)
-  k8s-worker-01:  94.237.x.x (running)
-  k8s-worker-02:  94.237.x.x (running)
-
-

Verify Server Access

-
# Test SSH connectivity
-provisioning server ssh k8s-control-01 -- uname -a
-
-# Check all servers
-provisioning server list
-
-

Part 5: Service Installation

-

Install Task Services

-
# Install all task services (automatic dependency resolution)
-provisioning taskserv create kubernetes --infra k8s-cluster
-
-

Installation flow (automatic):

-
Resolving dependencies...
-  containerd → etcd → kubernetes → cilium, rook-ceph
-
-Installing task services: 5
-
-[1/5] Installing containerd...
-  k8s-control-01: [████████████████████████] 100%
-  k8s-worker-01:  [████████████████████████] 100%
-  k8s-worker-02:  [████████████████████████] 100%
-
-[2/5] Installing etcd...
-  k8s-control-01: [████████████████████████] 100%
-
-[3/5] Installing kubernetes...
-  Control plane init: [████████████████████████] 100%
-  Worker join: [████████████████████████] 100%
-  Cluster ready: [████████████████████████] 100%
-
-[4/5] Installing cilium...
-  CNI deployment: [████████████████████████] 100%
-  Network policies: [████████████████████████] 100%
-
-[5/5] Installing rook-ceph...
-  Operator: [████████████████████████] 100%
-  Cluster: [████████████████████████] 100%
-  Storage class: [████████████████████████] 100%
-
-All task services installed successfully
-
-

Verify Kubernetes Cluster

-
# SSH to control plane
-provisioning server ssh k8s-control-01
-
-# Check cluster status
-kubectl get nodes
-kubectl get pods --all-namespaces
-kubectl get storageclass
-
-

Expected output:

-
NAME              STATUS   ROLES    AGE   VERSION
-k8s-control-01    Ready    control-plane  5m   v1.28.0
-k8s-worker-01     Ready    <none>   4m   v1.28.0
-k8s-worker-02     Ready    <none>   4m   v1.28.0
-
-NAMESPACE     NAME                                READY   STATUS
-kube-system   cilium-xxxxx                        1/1     Running
-kube-system   cilium-operator-xxxxx               1/1     Running
-kube-system   etcd-k8s-control-01                 1/1     Running
-rook-ceph     rook-ceph-operator-xxxxx            1/1     Running
-
-NAME              PROVISIONER
-ceph-rbd          rook-ceph.rbd.csi.ceph.com
-
-

Part 6: Deployment Verification

-

Health Checks

-
# Platform-level health check
-provisioning cluster status k8s-cluster
-
-# Individual service health
-provisioning taskserv status kubernetes
-provisioning taskserv status cilium
-provisioning taskserv status rook-ceph
-
-

Test Application Deployment

-
# Deploy test application on K8s cluster
-cat <<EOF | kubectl apply -f -
-apiVersion: v1
-kind: PersistentVolumeClaim
-metadata:
-  name: test-pvc
-spec:
-  storageClassName: ceph-rbd
-  accessModes:
-    - ReadWriteOnce
-  resources:
-    requests:
-      storage: 1Gi
----
-apiVersion: apps/v1
-kind: Deployment
-metadata:
-  name: test-nginx
-spec:
-  replicas: 2
-  selector:
-    matchLabels:
-      app: nginx
-  template:
-    metadata:
-      labels:
-        app: nginx
-    spec:
-      containers:
-      - name: nginx
-        image: nginx:latest
-        volumeMounts:
-        - name: storage
-          mountPath: /usr/share/nginx/html
-      volumes:
-      - name: storage
-        persistentVolumeClaim:
-          claimName: test-pvc
-EOF
-
-# Verify deployment
-kubectl get deployment test-nginx
-kubectl get pods -l app=nginx
-kubectl get pvc test-pvc
-
-

Network Policy Test

-
# Verify Cilium network policies work
-kubectl exec -it <pod-name> -- curl  [http://test-nginx](http://test-nginx)
-
-

Part 7: State Management

-

View State

-
# Show current workspace state
-provisioning workspace info
-
-# List all resources
-provisioning server list
-provisioning taskserv list
-
-# Export state for backup
-provisioning workspace export > k8s-cluster-state.json
-
-

Configuration Backup

-
# Backup workspace configuration
-tar -czf k8s-cluster-backup.tar.gz infra/ config/ runtime/
-
-# Store securely (encrypted)
-sops -e k8s-cluster-backup.tar.gz > k8s-cluster-backup.tar.gz.enc
-
-

What You’ve Learned

-

This deployment demonstrated:

-
    -
  • Workspace creation and configuration
  • -
  • Nickel schema structure for infrastructure-as-code
  • -
  • Type-safe configuration validation
  • -
  • Automatic dependency resolution
  • -
  • Multi-server provisioning
  • -
  • Task service installation with health checks
  • -
  • Kubernetes cluster deployment
  • -
  • Storage and networking configuration
  • -
  • Verification and testing workflows
  • -
  • State management and backup
  • -
-

Next Steps

- -

Verification

-

Validate the Provisioning platform installation and infrastructure health.

-

Installation Verification

-

CLI and Core Tools

-
# Check CLI version
-provisioning version
-
-# Verify Nushell
-nu --version  # 0.109.1+
-
-# Verify Nickel
-nickel --version  # 1.15.1+
-
-# Check SOPS and Age
-sops --version  # 3.10.2+
-age --version   # 1.2.1+
-
-# Verify K9s
-k9s version  # 0.50.6+
-
-

Configuration Validation

-
# Validate all configuration files
-provisioning validate config
-
-# Check environment
-provisioning env
-
-# Show all configuration
-provisioning allenv
-
-

Expected output:

-
Configuration validation: PASSED
-  - User config: ~/.config/provisioning/user_config.yaml ✓
-  - System defaults: provisioning/config/config.defaults.toml ✓
-  - Provider credentials: configured ✓
-
-

Provider Connectivity

-
# List available providers
-provisioning providers
-
-# Test provider connection (UpCloud example)
-provisioning provider test upcloud
-
-# Test provider connection (AWS example)
-provisioning provider test aws
-
-

Workspace Verification

-

Workspace Structure

-
# List workspaces
-provisioning workspace list
-
-# Show current workspace
-provisioning workspace current
-
-# Verify workspace structure
-ls -la <workspace-name>/
-
-

Expected structure:

-
workspace-name/
-├── infra/          # Infrastructure Nickel schemas
-├── config/         # Workspace configuration
-├── extensions/     # Custom extensions
-└── runtime/        # State and logs
-
-

Workspace Configuration

-
# Show workspace configuration
-provisioning config show
-
-# Validate workspace-specific config
-provisioning validate config --workspace <name>
-
-

Infrastructure Verification

-

Server Health

-
# List all servers
-provisioning server list
-
-# Check server status
-provisioning server status <hostname>
-
-# Test SSH connectivity
-provisioning server ssh <hostname> -- echo "Connection successful"
-
-

Task Service Health

-
# List installed task services
-provisioning taskserv list
-
-# Check service status
-provisioning taskserv status <service-name>
-
-# Verify service health
-provisioning taskserv health <service-name>
-
-

Cluster Health

-

For Kubernetes clusters:

-
# SSH to control plane
-provisioning server ssh <control-hostname>
-
-# Check cluster nodes
-kubectl get nodes
-
-# Check system pods
-kubectl get pods -n kube-system
-
-# Check cluster info
-kubectl cluster-info
-
-

Platform Services Verification

-

Orchestrator Service

-
# Check orchestrator status
-curl  [http://localhost:5000/health](http://localhost:5000/health)
-
-# View orchestrator version
-curl  [http://localhost:5000/version](http://localhost:5000/version)
-
-# List active workflows
-provisioning workflow list
-
-

Expected response:

-
{
-  "status": "healthy",
-  "version": "x.x.x",
-  "uptime": "2h 15m"
-}
-
-

Control Center

-
# Check control center
-curl  [http://localhost:8080/health](http://localhost:8080/health)
-
-# Access web UI
-open  [http://localhost:8080](http://localhost:8080)  # macOS
-xdg-open  [http://localhost:8080](http://localhost:8080)  # Linux
-
-

Native Plugins

-
# List registered plugins
-nu -c "plugin list"
-
-# Verify plugins loaded
-nu -c "plugin use nu_plugin_auth; plugin use nu_plugin_kms; plugin use nu_plugin_orchestrator"
-
-

Security Verification

-

Secrets Management

-
# Verify SOPS configuration
-cat ~/.config/provisioning/.sops.yaml
-
-# Test encryption/decryption
-echo "test secret" > /tmp/test-secret.txt
-sops -e /tmp/test-secret.txt > /tmp/test-secret.enc
-sops -d /tmp/test-secret.enc
-rm /tmp/test-secret.*
-
-

SSH Keys

-
# Verify SSH keys exist
-ls -la ~/.ssh/provisioning_*
-
-# Test SSH key permissions
-ls -l ~/.ssh/provisioning_* | awk '{print $1}'
-# Should show: -rw------- (600)
-
-

Encrypted Configuration

-
# Verify user config encryption
-file ~/.config/provisioning/user_config.yaml
-
-# Should show: SOPS encrypted data or YAML
-
-

Troubleshooting Common Issues

-

CLI Not Found

-
# Check PATH
-echo $PATH | tr ':' '
-' | grep provisioning
-
-# Verify symlink
-ls -l /usr/local/bin/provisioning
-
-# Try direct execution
-/path/to/project-provisioning/provisioning/core/cli/provisioning version
-
-

Provider Authentication Fails

-
# Verify credentials are set
-provisioning config show | grep -A5 providers
-
-# Test with debug mode
-provisioning --debug provider test <provider-name>
-
-# Check network connectivity
-ping -c 3 api.upcloud.com  # UpCloud
-ping -c 3 ec2.amazonaws.com  # AWS
-
-

Nickel Schema Errors

-
# Type-check schema
-nickel typecheck <schema-file>.ncl
-
-# Validate with verbose output
-provisioning validate config --verbose
-
-# Format Nickel file
-nickel fmt <schema-file>.ncl
-
-

Server SSH Fails

-
# Verify SSH key
-ssh-add -l | grep provisioning
-
-# Test direct SSH
-ssh -i ~/.ssh/provisioning_rsa root@<server-ip>
-
-# Check server status
-provisioning server status <hostname>
-
-

Task Service Installation Fails

-
# Check dependencies
-provisioning taskserv dependencies <service>
-
-# Verify server has resources
-provisioning server ssh <hostname> -- df -h
-provisioning server ssh <hostname> -- free -h
-
-# Enable debug mode
-provisioning --debug taskserv create <service>
-
-

Health Check Checklist

-

Complete verification checklist:

-
# Core tools
-[x] Nushell 0.109.1+
-[x] Nickel 1.15.1+
-[x] SOPS 3.10.2+
-[x] Age 1.2.1+
-[x] K9s 0.50.6+
-
-# Configuration
-[x] User config valid
-[x] Provider credentials configured
-[x] Workspace initialized
-
-# Provider connectivity
-[x] Provider API accessible
-[x] Authentication successful
-
-# Infrastructure (if deployed)
-[x] Servers running
-[x] SSH connectivity working
-[x] Task services installed
-[x] Cluster healthy
-
-# Platform services (if running)
-[x] Orchestrator responsive
-[x] Control center accessible
-[x] Plugins registered
-
-# Security
-[x] Secrets encrypted
-[x] SSH keys secured
-[x] Configuration protected
-
-

Performance Verification

-

Response Times

-
# CLI response time
-time provisioning version
-
-# Provider API response time
-time provisioning provider test <provider>
-
-# Orchestrator response time
-time curl  [http://localhost:5000/health](http://localhost:5000/health)
-
-

Acceptable ranges:

-
    -
  • CLI commands: <1 second
  • -
  • Provider API: <3 seconds
  • -
  • Orchestrator API: <100ms
  • -
-

Resource Usage

-
# Check system resources
-htop  # Interactive process viewer
-
-# Check disk usage
-df -h
-
-# Check memory usage
-free -h
-
-

Next Steps

-

Once verification is complete:

- -

Setup & Configuration

-

Post-installation configuration and system setup for the Provisioning platform.

-

Overview

-

After installation, setup configures your system and prepares workspaces for infrastructure deployment.

-

Setup encompasses three critical phases:

-
    -
  1. Initial Setup - Environment detection, dependency verification, directory creation
  2. -
  3. Workspace Setup - Create workspaces, configure providers, initialize schemas
  4. -
  5. Configuration - Provider credentials, system settings, profiles, validation
  6. -
-

This process validates prerequisites, detects your environment, and bootstraps your first workspace.

-

Quick Setup

-

Get up and running in 3 commands:

-
# 1. Complete initial setup (detects system, creates dirs, validates dependencies)
-provisioning setup initial
-
-# 2. Create first workspace (for your infrastructure)
-provisioning workspace create --name production
-
-# 3. Add cloud provider credentials (AWS, UpCloud, Hetzner, etc.)
-provisioning config set --workspace production \
-  extensions.providers.aws.enabled true \
-  extensions.providers.aws.config.region us-east-1
-
-# 4. Verify configuration is valid
-provisioning validate config
-
-

Setup Process Explained

-

The setup system automatically:

-
    -
  1. System Detection - Detects OS (Linux, macOS, Windows), CPU architecture, RAM, disk space
  2. -
  3. Dependency Verification - Validates Nushell, Nickel, SOPS, Age, K9s installation
  4. -
  5. Directory Structure - Creates ~/.provisioning/, ~/.config/provisioning/, workspace directories
  6. -
  7. Configuration Creation - Initializes default configuration, security settings, profiles
  8. -
  9. Workspace Bootstrap - Creates default workspace with basic configuration
  10. -
  11. Health Checks - Validates installation, runs diagnostic tests
  12. -
-

All steps are logged and can be verified with provisioning status.

-

Setup Configuration Guides

-

Starting Fresh

-
    -
  • -

    Initial Setup - First-time system setup: detection, validation, directory -creation, default configuration, health checks.

    -
  • -
  • -

    Workspace Setup - Create and initialize workspaces: creation, -provider configuration, schema management, local customization.

    -
  • -
  • -

    Configuration Management - Configure system: providers, credentials, -profiles, environment variables, validation rules.

    -
  • -
-

Setup Profiles

-

Pre-configured setup profiles for different use cases:

-

Developer Profile

-
provisioning setup profile --profile developer
-# Configures for local development with demo provider
-
-

Production Profile

-
provisioning setup profile --profile production
-# Configures for production with security hardening
-
-

Custom Profile

-
provisioning setup profile --custom
-# Interactive setup with customization
-
-

Directory Structure Created

-

Setup creates this directory structure:

-
~/.provisioning/
-├── workspaces/           # Workspace data
-├── cache/                # Build and dependency cache
-├── plugins/              # Installed Nushell plugins
-└── detectors/            # Custom detectors
-
-~/.config/provisioning/
-├── config.toml          # Main configuration
-├── providers/           # Provider credentials
-├── secrets/             # Encrypted secrets (via SOPS)
-└── profiles/            # Setup profiles
-
-

Quick Setup Verification

-
# Check system status
-provisioning status
-
-# Verify all dependencies
-provisioning setup verify-dependencies
-
-# Test cloud provider connection
-provisioning provider test --name aws
-
-# Validate configuration
-provisioning validate config
-
-# Run health checks
-provisioning health check
-
-

Environment-Specific Setup

-

For Single Workspace (Simple)

-
    -
  1. Run Initial Setup
  2. -
  3. Create one workspace
  4. -
  5. Configure provider
  6. -
  7. Done!
  8. -
-

For Multiple Workspaces (Team)

-
    -
  1. Run Initial Setup
  2. -
  3. Create multiple workspaces per team
  4. -
  5. Configure shared providers
  6. -
  7. Set up workspace-specific schemas
  8. -
-

For Multi-Cloud (Enterprise)

-
    -
  1. Run Initial Setup with production profile
  2. -
  3. Create workspace per environment (dev, staging, prod)
  4. -
  5. Configure multiple cloud providers
  6. -
  7. Enable audit logging and security features
  8. -
-

Configuration Hierarchy

-

Configurations load in priority order:

-
1. Command-line arguments       (highest)
-2. Environment variables        (PROVISIONING_*)
-3. User profile config         (~/.config/provisioning/)
-4. Workspace config            (workspace/config/)
-5. System defaults             (provisioning/config/)
-                               (lowest)
-
-

Common Setup Tasks

-

Add a Cloud Provider

-
provisioning config set --workspace production \
-  extensions.providers.aws.config.region us-east-1 \
-  extensions.providers.aws.config.credentials_source aws_iam
-
-

Configure Secrets Storage

-
provisioning config set \
-  security.secrets.backend secretumvault \
-  security.secrets.url  [http://localhost:8200](http://localhost:8200)
-
-

Enable Audit Logging

-
provisioning config set \
-  security.audit.enabled true \
-  security.audit.retention_days 2555
-
-

Set Up Multi-Tenancy

-
# Create separate workspaces per tenant
-provisioning workspace create --name tenant-1
-provisioning workspace create --name tenant-2
-
-# Each workspace has isolated configuration
-
-

Setup Validation

-

After setup, validate everything works:

-
# Run complete validation suite
-provisioning setup validate-all
-
-# Or check specific components
-provisioning setup validate-system       # OS, dependencies
-provisioning setup validate-directories  # Directory structure
-provisioning setup validate-config       # Configuration syntax
-provisioning setup validate-providers    # Cloud provider connectivity
-provisioning setup validate-security     # Security settings
-
-

Troubleshooting Setup

-

If setup fails:

-
    -
  1. Check logs - provisioning setup logs --tail 20
  2. -
  3. Verify dependencies - provisioning setup verify-dependencies
  4. -
  5. Reset configuration - provisioning setup reset --workspace <name>
  6. -
  7. Run diagnostics - provisioning diagnose setup
  8. -
  9. Check documentation - See Troubleshooting
  10. -
-

Next Steps After Setup

-

After initial setup completes:

-
    -
  1. Create workspaces - See Workspace Setup
  2. -
  3. Configure providers - See Configuration Management
  4. -
  5. Deploy infrastructure - See Getting Started
  6. -
  7. Learn features - See Features
  8. -
  9. Explore examples - See Examples
  10. -
- -
    -
  • Getting Started → See provisioning/docs/src/getting-started/
  • -
  • Features → See provisioning/docs/src/features/
  • -
  • Configuration Guide → See provisioning/docs/src/infrastructure/
  • -
  • Troubleshooting → See provisioning/docs/src/troubleshooting/
  • -
-

Initial Setup

-

Configure Provisioning after installation.

-

Overview

-

Initial setup validates your environment and prepares Provisioning for workspace -creation. The setup process performs system detection, dependency verification, and -configuration initialization.

-

Prerequisites

-

Before initial setup, ensure:

-
    -
  1. Provisioning CLI installed and in PATH
  2. -
  3. Nushell 0.109.0+ installed
  4. -
  5. Nickel installed
  6. -
  7. SOPS 3.10.2+ installed
  8. -
  9. Age 1.2.1+ installed
  10. -
  11. K9s 0.50.6+ installed (for Kubernetes)
  12. -
-

Verify installation:

-
provisioning version
-nu --version
-nickel --version
-sops --version
-age --version
-
-

Setup Profiles

-

Provisioning provides configuration profiles for different use cases:

-

1. Developer Profile

-

For local development and testing:

-
provisioning setup profile --profile developer
-
-

Includes:

-
    -
  • Local provider (simulation environment)
  • -
  • Development workspace
  • -
  • Test environment configuration
  • -
  • Debug logging enabled
  • -
  • No MFA required
  • -
  • Workspace directory: ~/.provisioning-dev/
  • -
-

2. Production Profile

-

For production deployments:

-
provisioning setup profile --profile production
-
-

Includes:

-
    -
  • Encrypted configuration
  • -
  • Strict validation rules
  • -
  • MFA enabled
  • -
  • Audit logging enabled
  • -
  • Workspace directory: /opt/provisioning/
  • -
-

3. CI/CD Profile

-

For unattended automation:

-
provisioning setup profile --profile cicd
-
-

Includes:

-
    -
  • Headless mode (no TUI prompts)
  • -
  • Service account authentication
  • -
  • Automated backups
  • -
  • Policy enforcement
  • -
  • Unattended upgrade support
  • -
-

Configuration Detection

-

The setup system automatically detects:

-
# System detection
-OS:            $(uname -s)
-CPU:           $(lscpu | grep 'CPU(s)' | awk '{print $NF}')
-RAM:           $(free -h | grep Mem | awk '{print $2}')
-Architecture:  $(uname -m)
-
-

The system adapts configuration based on detected resources:

-
- - - - - - -
Detected ResourceConfiguration
2-4 CPU coresSolo (single-instance) mode
4-8 CPU coresMultiUser mode (small cluster)
8+ CPU coresCICD or Enterprise mode
4GB RAMMinimal services only
8GB RAMStandard setup
16GB+ RAMFull feature set
-
-

Setup Steps

-

Step 1: Validate Environment

-
provisioning setup validate
-
-

Checks:

-
    -
  • ✅ All dependencies installed
  • -
  • ✅ Permission levels
  • -
  • ✅ Network connectivity
  • -
  • ✅ Disk space (minimum 20GB recommended)
  • -
-

Step 2: Initialize Configuration

-
provisioning setup init
-
-

Creates:

-
    -
  • ~/.config/provisioning/ - User configuration directory
  • -
  • ~/.config/provisioning/user_config.yaml - User settings
  • -
  • ~/.provisioning/workspaces/ - Workspace registry
  • -
-

Step 3: Configure Providers

-
provisioning setup providers
-
-

Interactive configuration for:

-
    -
  • UpCloud (API key, endpoint)
  • -
  • AWS (Access key, secret, region)
  • -
  • Hetzner (API token)
  • -
  • Local (No configuration required)
  • -
-

Store credentials securely:

-
# Credentials are encrypted with SOPS + Age
-~/.config/provisioning/.secrets/providers.enc.yaml
-
-

Step 4: Configure Security

-
provisioning setup security
-
-

Sets up:

-
    -
  • JWT secret for authentication
  • -
  • KMS backend (local, Cosmian, AWS KMS)
  • -
  • Encryption keys
  • -
  • Certificate authorities
  • -
-

Step 5: Verify Installation

-
provisioning verify
-
-

Checks:

-
    -
  • ✅ All components running
  • -
  • ✅ Provider connectivity
  • -
  • ✅ Configuration validity
  • -
  • ✅ Security systems operational
  • -
-

User Configuration

-

User configuration is stored in ~/.config/provisioning/user_config.yaml:

-
# User preferences
-user:
-  name: "Your Name"
-  email: "[your@email.com](mailto:your@email.com)"
-  default_region: "us-east-1"
-
-# Workspace settings
-workspaces:
-  active: "my-project"
-  directory: "~/.provisioning/workspaces/"
-  registry:
-    my-project:
-      path: "/home/user/.provisioning/workspaces/workspace_my_project"
-      created: "2026-01-16T10:30:00Z"
-      template: "default"
-
-# Provider defaults
-providers:
-  default: "upcloud"
-  upcloud:
-    endpoint: " [https://api.upcloud.com"](https://api.upcloud.com")
-  aws:
-    region: "us-east-1"
-
-# Security settings
-security:
-  mfa_enabled: false
-  kms_backend: "local"
-  encryption: "aes-256-gcm"
-
-# Display options
-ui:
-  theme: "dark"
-  table_format: "compact"
-  colors: true
-
-# Logging
-logging:
-  level: "info"
-  output: "console"
-  file: "~/.provisioning/logs/provisioning.log"
-
-

Environment Variables

-

Override settings with environment variables:

-
# Provider selection
-export PROVISIONING_PROVIDER=aws
-
-# Workspace selection
-export PROVISIONING_WORKSPACE=my-project
-
-# Logging
-export PROVISIONING_LOG_LEVEL=debug
-
-# Configuration path
-export PROVISIONING_CONFIG=~/.config/provisioning/
-
-# KMS endpoint
-export PROVISIONING_KMS_ENDPOINT= [http://localhost:8080](http://localhost:8080)
-
-

Troubleshooting

-

Missing Dependencies

-
# Install missing tools
-brew install nushell nickel sops age k9s
-
-# Verify
-provisioning setup validate
-
-

Permission Errors

-
# Fix directory permissions
-chmod 700 ~/.config/provisioning/
-chmod 600 ~/.config/provisioning/user_config.yaml
-
-

Provider Connection Failed

-
# Test provider connectivity
-provisioning providers test upcloud --verbose
-
-# Verify credentials
-cat ~/.config/provisioning/.secrets/providers.enc.yaml
-
-

Next Steps

-

After initial setup:

-
    -
  1. Create workspace
  2. -
  3. Configure infrastructure
  4. -
  5. Deploy first cluster
  6. -
-

Workspace Setup

-

Create and initialize your first Provisioning workspace.

-

Overview

-

A workspace is the default organizational unit for all infrastructure work in Provisioning. -It groups infrastructure definitions, configurations, extensions, and runtime data in an -isolated environment.

-

Workspace Structure

-

Every workspace follows a consistent directory structure:

-
workspace_my_project/
-├── config/                     # Workspace configuration
-│   ├── workspace.ncl           # Workspace definition (Nickel)
-│   ├── provisioning.yaml       # Workspace metadata
-│   ├── dev-defaults.toml       # Development environment settings
-│   ├── test-defaults.toml      # Testing environment settings
-│   └── prod-defaults.toml      # Production environment settings
-│
-├── infra/                      # Infrastructure definitions
-│   ├── servers.ncl             # Server configurations
-│   ├── clusters.ncl            # Cluster definitions
-│   ├── networks.ncl            # Network configurations
-│   └── batch-workflows.ncl     # Batch workflow definitions
-│
-├── extensions/                 # Workspace-specific extensions (optional)
-│   ├── providers/              # Custom providers
-│   ├── taskservs/              # Custom task services
-│   ├── clusters/               # Custom cluster templates
-│   └── workflows/              # Custom workflow definitions
-│
-└── runtime/                    # Runtime data (gitignored)
-    ├── state/                  # Infrastructure state files
-    ├── checkpoints/            # Workflow checkpoints
-    ├── logs/                   # Operation logs
-    └── generated/              # Generated configuration files
-
-

Creating a Workspace

-

Method 1: From Built-in Template

-
# Create from default template
-provisioning workspace init my-project
-
-# Create from specific template
-provisioning workspace init my-k8s --template kubernetes-ha
-
-# Create with custom path
-provisioning workspace init my-project --path /custom/location
-
-

Method 2: From Git Repository

-
# Clone infrastructure repository
-git clone  [https://github.com/org/infra-repo.git](https://github.com/org/infra-repo.git) my-infra
-cd my-infra
-
-# Import as workspace
-provisioning workspace init . --import
-
-

Available Templates

-

Provisioning includes templates for common use cases:

-
- - - - - - -
TemplateDescriptionUse Case
defaultMinimal structureGeneral-purpose infrastructure
kubernetes-haHA Kubernetes (3 control planes)Production Kubernetes deployments
developmentDev-optimized with Docker ComposeLocal testing and development
multi-cloudMultiple provider configsMulti-cloud deployments
database-clusterDatabase-focusedDatabase infrastructure
cicdCI/CD pipeline configsAutomated deployment pipelines
-
-

List available templates:

-
provisioning workspace templates
-
-# Show template details
-provisioning workspace template show kubernetes-ha
-
-

Switching Workspaces

-

List All Workspaces

-
provisioning workspace list
-
-# Example output:
-NAME              PATH                           LAST_USED          STATUS
-my-project        ~/.provisioning/workspace_my   2026-01-16 10:30   Active
-dev-env           ~/.provisioning/workspace_dev  2026-01-15 15:45
-production        ~/.provisioning/workspace_prod 2026-01-10 09:00
-
-

Switch to a Workspace

-
# Switch workspace
-provisioning workspace switch my-project
-
-# Verify switch
-provisioning workspace status
-
-# Quick switch (shortcut)
-provisioning ws switch dev-env
-
-

When you switch workspaces:

-
    -
  • Active workspace marker updates in user configuration
  • -
  • Environment variables update for current session
  • -
  • CLI prompt changes (if configured)
  • -
  • Last-used timestamp updates
  • -
-

Workspace Registry

-

The workspace registry is stored in user configuration:

-
# ~/.config/provisioning/user_config.yaml
-workspaces:
-  active: my-project
-  registry:
-    my-project:
-      path: ~/.provisioning/workspaces/workspace_my_project
-      created: 2026-01-16T10:30:00Z
-      last_used: 2026-01-16T14:20:00Z
-      template: default
-
-

Configuring Workspace

-

Workspace Definition (workspace.ncl)

-
# workspace.ncl - Workspace configuration
-
-{
-  # Workspace metadata
-  name = "my-project"
-  description = "My infrastructure project"
-  version = "1.0.0"
-
-  # Environment settings
-  environment = 'production
-
-  # Default provider
-  provider = "upcloud"
-
-  # Region preferences
-  region = "de-fra1"
-
-  # Workspace-specific providers (override defaults)
-  providers = {
-    upcloud = {
-      endpoint = " [https://api.upcloud.com"](https://api.upcloud.com")
-      region = "de-fra1"
-    }
-    aws = {
-      region = "us-east-1"
-    }
-  }
-
-  # Extensions (inherit from provisioning/extensions/)
-  extensions = {
-    providers = ["upcloud", "aws"]
-    taskservs = ["kubernetes", "docker", "postgres"]
-    clusters = ["web", "oci-reg"]
-  }
-}
-
-

Environment-Specific Configuration

-

Create environment-specific configuration files:

-
# Development environment
-config/dev-defaults.toml:
-[server]
-plan = "small"
-backup_enabled = false
-
-# Production environment
-config/prod-defaults.toml:
-[server]
-plan = "large"
-backup_enabled = true
-monitoring_enabled = true
-
-

Use environment selection:

-
# Deploy to development
-PROVISIONING_ENV=dev provisioning server create
-
-# Deploy to production (stricter validation)
-PROVISIONING_ENV=prod provisioning server create --validate
-
-

Workspace Metadata (provisioning.yaml)

-
name: "my-project"
-version: "1.0.0"
-created: "2026-01-16T10:30:00Z"
-owner: "team-infra"
-
-# Provider configuration
-providers:
-  default: "upcloud"
-  upcloud:
-    api_endpoint: " [https://api.upcloud.com"](https://api.upcloud.com")
-    region: "de-fra1"
-  aws:
-    region: "us-east-1"
-
-# Workspace features
-features:
-  workspace_switching: true
-  batch_workflows: true
-  test_environment: true
-  security_system: true
-
-# Validation rules
-validation:
-  strict: true
-  check_dependencies: true
-  validate_certificates: true
-
-# Backup settings
-backup:
-  enabled: true
-  frequency: "daily"
-  retention_days: 30
-
-

Initializing Infrastructure

-

Step 1: Create Infrastructure Definition

-

Create infra/servers.ncl:

-
let defaults = import "defaults.ncl" in
-
-{
-  servers = [
-    defaults.make_server {
-      name = "web-01"
-      plan = "medium"
-      region = "de-fra1"
-    }
-    defaults.make_server {
-      name = "db-01"
-      plan = "large"
-      region = "de-fra1"
-      backup_enabled = true
-    }
-  ]
-}
-
-

Step 2: Validate Configuration

-
# Validate Nickel configuration
-nickel typecheck infra/servers.ncl
-
-# Export and validate
-nickel export infra/servers.ncl | provisioning validate config
-
-# Verbose validation
-provisioning validate config --verbose
-
-

Step 3: Export Configuration

-
# Export Nickel to TOML (generated output)
-nickel export --format toml infra/servers.ncl > infra/servers.toml
-
-# The .toml files are auto-generated, don't edit directly
-
-

Workspace Security

-

Securing Credentials

-

Credentials are encrypted with SOPS + Age:

-
# Initialize secrets
-provisioning sops init
-
-# Create encrypted secrets file
-provisioning sops create .secrets/providers.enc.yaml
-
-# Encrypt existing credentials
-sops -e -i infra/credentials.toml
-
-

Git Workflow

-

Version control best practices:

-
# COMMIT (shared with team)
-infra/**/*.ncl              # Infrastructure definitions
-config/*.toml               # Environment configurations
-config/provisioning.yaml    # Workspace metadata
-extensions/**/*             # Custom extensions
-
-# GITIGNORE (never commit)
-config/local-overrides.toml # Local user settings
-runtime/**/*                # Runtime data and state
-**/*.secret                 # Credential files
-**/*.enc                    # Encrypted files (if not decrypted locally)
-
-

Multi-Workspace Strategies

-

Strategy 1: Separate Workspaces Per Environment

-
# Create dedicated workspaces
-provisioning workspace init myapp-dev
-provisioning workspace init myapp-staging
-provisioning workspace init myapp-prod
-
-# Each workspace is completely isolated
-provisioning ws switch myapp-prod
-provisioning server create  # Creates in prod only
-
-

Pros: Complete isolation, different credentials, independent state -Cons: More workspace management, configuration duplication

-

Strategy 2: Single Workspace, Multiple Environments

-
# Single workspace with environment configs
-provisioning workspace init myapp
-
-# Deploy to different environments
-PROVISIONING_ENV=dev provisioning server create
-PROVISIONING_ENV=staging provisioning server create
-PROVISIONING_ENV=prod provisioning server create
-
-

Pros: Shared configuration, easier maintenance -Cons: Shared credentials, risk of cross-environment mistakes

-

Strategy 3: Hybrid Approach

-
# Dev workspace for experimentation
-provisioning workspace init myapp-dev
-
-# Prod workspace for production only
-provisioning workspace init myapp-prod
-
-# Use environment flags within workspaces
-provisioning ws switch myapp-prod
-PROVISIONING_ENV=prod provisioning cluster deploy
-
-

Pros: Balances isolation and convenience -Cons: More complex to explain to teams

-

Workspace Validation

-

Before deploying infrastructure:

-
# Validate entire workspace
-provisioning validate workspace
-
-# Validate specific configuration
-provisioning validate config --infra servers.ncl
-
-# Validate with strict rules
-provisioning validate config --strict
-
-

Troubleshooting

-

Workspace Not Found

-
# Re-register workspace
-provisioning workspace register /path/to/workspace
-
-# Or create new workspace
-provisioning workspace init my-project
-
-

Permission Errors

-
# Fix workspace permissions
-chmod 755 ~/.provisioning/workspaces/workspace_*
-chmod 644 ~/.provisioning/workspaces/workspace_*/config/*
-
-

Configuration Validation Errors

-
# Check configuration syntax
-nickel typecheck infra/*.ncl
-
-# Inspect generated TOML
-nickel export infra/*.ncl | jq '.'
-
-# Debug configuration loading
-provisioning config validate --verbose
-
-

Next Steps

-
    -
  1. Configure infrastructure
  2. -
  3. Deploy servers
  4. -
  5. Create batch workflows
  6. -
-

Configuration Management

-

Configure Provisioning providers, credentials, and system settings.

-

Overview

-

Provisioning uses a hierarchical configuration system with 5 layers of precedence. -Configuration is type-safe via Nickel schemas and can be overridden at multiple levels.

-

Configuration Hierarchy

-
1. Runtime Arguments        (Highest Priority)
-   ↓ (CLI flags: --provider upcloud)
-2. Environment Variables
-   ↓ (PROVISIONING_PROVIDER=upcloud)
-3. Workspace Configuration
-   ↓ (workspace/config/provisioning.yaml)
-4. Environment Defaults
-   ↓ (workspace/config/prod-defaults.toml)
-5. System Defaults          (Lowest Priority)
-   ├─ User Config (~/.config/provisioning/user_config.yaml)
-   └─ Platform Defaults (provisioning/config/config.defaults.toml)
-
-

Configuration Sources

-

1. System Defaults

-

Built-in defaults for all Provisioning settings:

-

Location: provisioning/config/config.defaults.toml

-
# Default provider
-[providers]
-default = "local"
-
-# Default server configuration
-[server]
-plan = "small"
-region = "us-east-1"
-zone = "a"
-backup_enabled = false
-monitoring = false
-
-# Default workspace
-[workspace]
-directory = "~/.provisioning/workspaces/"
-
-# Logging
-[logging]
-level = "info"
-output = "console"
-
-# Security
-[security]
-mfa_enabled = false
-encryption = "aes-256-gcm"
-
-

2. User Configuration

-

User-level settings in home directory:

-

Location: ~/.config/provisioning/user_config.yaml

-
user:
-  name: "Your Name"
-  email: "[user@example.com](mailto:user@example.com)"
-
-providers:
-  default: "upcloud"
-  upcloud:
-    endpoint: " [https://api.upcloud.com"](https://api.upcloud.com")
-    api_key: "${UPCLOUD_API_KEY}"
-  aws:
-    region: "us-east-1"
-    profile: "default"
-
-workspace:
-  directory: "~/.provisioning/workspaces/"
-  default: "my-project"
-
-logging:
-  level: "info"
-  file: "~/.provisioning/logs/provisioning.log"
-
-

3. Workspace Configuration

-

Workspace-specific settings:

-

Location: workspace/config/provisioning.yaml

-
name: "my-project"
-environment: "production"
-
-providers:
-  default: "upcloud"
-  upcloud:
-    region: "de-fra1"
-    endpoint: " [https://api.upcloud.com"](https://api.upcloud.com")
-
-validation:
-  strict: true
-  require_approval: false
-
-

4. Environment Defaults

-

Environment-specific configuration files:

-

Files:

-
    -
  • workspace/config/dev-defaults.toml - Development
  • -
  • workspace/config/test-defaults.toml - Testing
  • -
  • workspace/config/prod-defaults.toml - Production
  • -
-

Example prod-defaults.toml:

-
# Production environment overrides
-[server]
-plan = "large"
-backup_enabled = true
-monitoring = true
-high_availability = true
-
-[security]
-mfa_enabled = true
-require_approval = true
-
-[workspace]
-require_version_tag = true
-require_changelog = true
-
-

5. Runtime Arguments

-

Command-line flags with highest priority:

-
# Override provider
-provisioning --provider aws server create
-
-# Override configuration
-provisioning --config /custom/config.yaml
-
-# Override environment
-provisioning --env production
-
-# Combined
-provisioning --provider aws --env production --format json server list
-
-

Provider Configuration

-

Supported Providers

-
- - - - -
ProviderStatusConfiguration
UpCloud✅ ActiveAPI endpoint, credentials
AWS✅ ActiveRegion, access keys, profile
Hetzner✅ ActiveAPI token, datacenter
Local✅ ActiveDirectory path (no credentials)
-
-

Configuring UpCloud

-

Interactive setup:

-
provisioning setup providers
-
-

Or manually in ~/.config/provisioning/user_config.yaml:

-
providers:
-  default: "upcloud"
-  upcloud:
-    endpoint: " [https://api.upcloud.com"](https://api.upcloud.com")
-    api_key: "${UPCLOUD_API_KEY}"
-    api_secret: "${UPCLOUD_API_SECRET}"
-
-

Store credentials securely:

-
# Set environment variables
-export UPCLOUD_API_KEY="your-api-key"
-export UPCLOUD_API_SECRET="your-api-secret"
-
-# Or use SOPS for encrypted storage
-provisioning sops set providers.upcloud.api_key "your-api-key"
-
-

Configuring AWS

-
providers:
-  aws:
-    region: "us-east-1"
-    access_key_id: "${AWS_ACCESS_KEY_ID}"
-    secret_access_key: "${AWS_SECRET_ACCESS_KEY}"
-    profile: "default"
-
-

Set environment variables:

-
export AWS_ACCESS_KEY_ID="your-access-key"
-export AWS_SECRET_ACCESS_KEY="your-secret-key"
-export AWS_REGION="us-east-1"
-
-

Configuring Hetzner

-
providers:
-  hetzner:
-    api_token: "${HETZNER_API_TOKEN}"
-    datacenter: "nbg1-dc3"
-
-

Set environment:

-
export HETZNER_API_TOKEN="your-api-token"
-
-

Testing Provider Connectivity

-
# Test provider connectivity
-provisioning providers test upcloud
-
-# Verbose output
-provisioning providers test aws --verbose
-
-# Test all configured providers
-provisioning providers test --all
-
-

Global Configuration Accessors

-

Provisioning provides 476+ configuration accessors for accessing settings:

-
# Access configuration values
-let config = (provisioning config load)
-
-# Provider settings
-$config.providers.default
-$config.providers.upcloud.endpoint
-$config.providers.aws.region
-
-# Workspace settings
-$config.workspace.directory
-$config.workspace.default
-
-# Server defaults
-$config.server.plan
-$config.server.region
-$config.server.backup_enabled
-
-# Security settings
-$config.security.mfa_enabled
-$config.security.encryption
-
-

Credential Management

-

Encrypted Credentials

-

Use SOPS + Age for encrypted secrets:

-
# Initialize SOPS configuration
-provisioning sops init
-
-# Create encrypted credentials file
-provisioning sops create .secrets/providers.enc.yaml
-
-# Edit encrypted file
-provisioning sops edit .secrets/providers.enc.yaml
-
-# Decrypt for local use
-provisioning sops decrypt .secrets/providers.enc.yaml > .secrets/providers.toml
-
-

Using Environment Variables

-

Override credentials at runtime:

-
# Provider credentials
-export PROVISIONING_PROVIDER=aws
-export AWS_ACCESS_KEY_ID="your-key"
-export AWS_SECRET_ACCESS_KEY="your-secret"
-export AWS_REGION="us-east-1"
-
-# Execute command
-provisioning server create
-
-

KMS Integration

-

For enterprise deployments, use KMS backends:

-
# Configure KMS backend
-provisioning kms init --backend cosmian
-
-# Store credentials in KMS
-provisioning kms set providers.upcloud.api_key "value"
-
-# Decrypt on-demand
-provisioning kms get providers.upcloud.api_key
-
-

Configuration Validation

-

Validate Configuration

-
# Validate all configuration
-provisioning validate config
-
-# Validate specific section
-provisioning validate config --section providers
-
-# Strict validation
-provisioning validate config --strict
-
-# Verbose output
-provisioning validate config --verbose
-
-

Validate Infrastructure

-
# Validate infrastructure schemas
-provisioning validate infra
-
-# Validate specific file
-provisioning validate infra workspace/infra/servers.ncl
-
-# Type-check with Nickel
-nickel typecheck workspace/infra/servers.ncl
-
-

Configuration Merging

-

Configuration is merged from all layers respecting priority:

-
# View final merged configuration
-provisioning config show
-
-# Export merged configuration
-provisioning config export --format yaml
-
-# Show configuration source
-provisioning config debug --keys providers.default
-
-

Working with Configurations

-

Export Configuration

-
# Export as YAML
-provisioning config export --format yaml > config.yaml
-
-# Export as JSON
-provisioning config export --format json | jq '.'
-
-# Export as TOML
-provisioning config export --format toml > config.toml
-
-

Import Configuration

-
# Import from file
-provisioning config import --file config.yaml
-
-# Merge with existing
-provisioning config merge --file config.yaml
-
-

Reset Configuration

-
# Reset to defaults
-provisioning config reset
-
-# Reset specific section
-provisioning config reset --section providers
-
-# Backup before reset
-provisioning config backup
-
-

Environment Variables

-

Common environment variables for overriding configuration:

-
# Provider selection
-export PROVISIONING_PROVIDER=upcloud
-export PROVISIONING_PROVIDER_UPCLOUD_ENDPOINT= [https://api.upcloud.com](https://api.upcloud.com)
-
-# Workspace
-export PROVISIONING_WORKSPACE=my-project
-export PROVISIONING_WORKSPACE_DIRECTORY=~/.provisioning/workspaces/
-
-# Environment
-export PROVISIONING_ENV=production
-
-# Logging
-export PROVISIONING_LOG_LEVEL=debug
-export PROVISIONING_LOG_FILE=~/.provisioning/logs/provisioning.log
-
-# Configuration path
-export PROVISIONING_CONFIG=~/.config/provisioning/
-
-# KMS endpoint
-export PROVISIONING_KMS_ENDPOINT= [http://localhost:8080](http://localhost:8080)
-
-# Feature flags
-export PROVISIONING_FEATURE_BATCH_WORKFLOWS=true
-export PROVISIONING_FEATURE_TEST_ENVIRONMENT=true
-
-

Best Practices

-

1. Secure Credentials

-
# NEVER commit credentials
-echo "config/local-overrides.toml" >> .gitignore
-echo ".secrets/" >> .gitignore
-
-# Use SOPS for shared secrets
-provisioning sops encrypt config/credentials.toml
-git add config/credentials.enc.toml
-
-# Use environment variables for local overrides
-export PROVISIONING_PROVIDER_UPCLOUD_API_KEY="your-key"
-
-

2. Environment-Specific Configuration

-
# Development uses different credentials
-PROVISIONING_ENV=dev provisioning workspace switch myapp-dev
-
-# Production uses restricted credentials
-PROVISIONING_ENV=prod provisioning workspace switch myapp-prod
-
-

3. Configuration Documentation

-

Document your configuration choices:

-
# provisioning.yaml
-configuration:
-  provider: "upcloud"
-  reason: "Primary European cloud"
-
-  backup_strategy: "daily"
-  reason: "Compliance requirement"
-
-  monitoring: "enabled"
-  reason: "SLA monitoring"
-
-

4. Regular Validation

-
# Validate before deployment
-provisioning validate config --strict
-
-# Export and inspect
-provisioning config export --format yaml | less
-
-# Test provider connectivity
-provisioning providers test --all
-
-

Troubleshooting

-

Configuration Not Loading

-
# Check configuration file
-cat ~/.config/provisioning/user_config.yaml
-
-# Validate YAML syntax
-yamllint ~/.config/provisioning/user_config.yaml
-
-# Debug configuration loading
-provisioning config show --verbose
-
-

Provider Connection Failed

-
# Check provider configuration
-provisioning config show --section providers
-
-# Test connectivity
-provisioning providers test upcloud --verbose
-
-# Check credentials
-provisioning kms get providers.upcloud.api_key
-
-

Environment Variable Conflicts

-
# Check environment variables
-env | grep PROVISIONING
-
-# Unset conflicting variables
-unset PROVISIONING_PROVIDER
-
-# Set correct values
-export PROVISIONING_PROVIDER=aws
-export AWS_REGION=us-east-1
-
-

Next Steps

-
    -
  1. Create workspace
  2. -
  3. Deploy infrastructure
  4. -
  5. Configure batch workflows
  6. -
-

- Provisioning Logo -

-

- Provisioning -

-

User Guides

-

Step-by-step guides for common workflows, best practices, and advanced operational -scenarios using the Provisioning platform.

-

Overview

-

This section provides practical guides for:

-
    -
  • Getting started - From-scratch deployment and initial setup
  • -
  • Organization - Workspace management and multi-cloud strategies
  • -
  • Automation - Advanced workflow orchestration and GitOps
  • -
  • Operations - Disaster recovery, secrets rotation, cost governance
  • -
  • Integration - Hybrid cloud setup, zero-trust networks, legacy migration
  • -
  • Scaling - Multi-tenant environments, high availability, performance optimization
  • -
-

Each guide includes step-by-step instructions, configuration examples, troubleshooting, and best practices.

-

Getting Started

-

I’m completely new to Provisioning

-

Start with: From Scratch Guide - Complete walkthrough from installation through first deployment with explanations and examples.

-

I want to organize infrastructure

-

Read: Workspace Management - Best practices for organizing workspaces, isolation, and multi-team setup.

-

Core Workflow Guides

-
    -
  • -

    From Scratch Guide - Installation, workspace creation, -first deployment step-by-step

    -
  • -
  • -

    Workspace Management - Organization best -practices, multi-tenancy, collaboration, customization, schemas

    -
  • -
  • -

    Multi-Cloud Deployment - Deploy across -AWS, UpCloud, Hetzner with abstraction and failover

    -
  • -
-

- Multi-Cloud Deployment AWS UpCloud Hetzner Provider Abstraction -

- -

- Deployment Pipeline Dev Staging Canary Production with Validation Gates -

-

Advanced Operational Guides

- -

Enterprise Features

- -

Quick Navigation

-

I need to

-

Deploy infrastructure quicklyFrom Scratch Guide

-

Organize multiple workspacesWorkspace Management

-

Deploy across cloudsMulti-Cloud Deployment

-

Build complex workflowsAdvanced Workflow Orchestration

-

Set up GitOpsGitOps Infrastructure Deployment

-

Handle disastersDisaster Recovery Guide

-

Rotate secrets safelySecrets Rotation Strategy

-

Connect on-premise to cloudHybrid Cloud Deployment

-

Design secure networksAdvanced Networking

-

Build custom extensionsCustom Extensions

-

Migrate legacy systemsLegacy System Migration

-

Guide Structure

-

Each guide follows this pattern:

-
    -
  1. Overview - What you’ll accomplish
  2. -
  3. Prerequisites - What you need before starting
  4. -
  5. Architecture - Visual diagram of the solution
  6. -
  7. Step-by-Step - Detailed instructions with examples
  8. -
  9. Configuration - Full Nickel configuration examples
  10. -
  11. Verification - How to validate the deployment
  12. -
  13. Troubleshooting - Common issues and solutions
  14. -
  15. Next Steps - How to extend or customize
  16. -
  17. Best Practices - Lessons learned and recommendations
  18. -
-

Learning Paths

-

Path 1: I’m new to Provisioning (Day 1)

-
    -
  1. From Scratch Guide - Basic setup
  2. -
  3. Workspace Management - Organization
  4. -
  5. Multi-Cloud Deployment - Multi-cloud
  6. -
-

Path 2: I need production-ready setup (Week 1)

-
    -
  1. Workspace Management - Organization
  2. -
  3. GitOps Infrastructure Deployment - Automation
  4. -
  5. Disaster Recovery Guide - Resilience
  6. -
  7. Secrets Rotation Strategy - Security
  8. -
  9. Advanced Networking - Enterprise networking
  10. -
-

Path 3: I’m migrating from legacy (Month-long project)

-
    -
  1. Legacy System Migration - Migration plan
  2. -
  3. Advanced Workflow Orchestration - Complex deployments
  4. -
  5. Hybrid Cloud Deployment - Coexistence
  6. -
  7. GitOps Infrastructure Deployment - Continuous deployment
  8. -
  9. Disaster Recovery Guide - Failover strategies
  10. -
-

Path 4: I’m building a platform (Team project)

-
    -
  1. Custom Extensions - Build extensions
  2. -
  3. Workspace Management - Multi-tenant setup
  4. -
  5. Advanced Workflow Orchestration - Complex workflows
  6. -
  7. GitOps Infrastructure Deployment - CD/GitOps
  8. -
  9. Secrets Rotation Strategy - Security at scale
  10. -
- -
    -
  • Getting Started → See provisioning/docs/src/getting-started/
  • -
  • Examples → See provisioning/docs/src/examples/
  • -
  • Features → See provisioning/docs/src/features/
  • -
  • Operations → See provisioning/docs/src/operations/
  • -
  • Development → See provisioning/docs/src/development/
  • -
-

From Scratch Guide

-

Complete walkthrough from zero to production-ready infrastructure deployment using the Provisioning platform. This guide covers installation, configuration, -workspace setup, infrastructure definition, and deployment workflows.

-

Overview

-

This guide walks you through:

-
    -
  • Installing prerequisites and the Provisioning platform
  • -
  • Configuring cloud provider credentials
  • -
  • Creating your first workspace
  • -
  • Defining infrastructure using Nickel
  • -
  • Deploying servers and task services
  • -
  • Setting up Kubernetes clusters
  • -
  • Implementing security best practices
  • -
  • Monitoring and maintaining infrastructure
  • -
-

Time commitment: 2-3 hours for complete setup -Prerequisites: Linux or macOS, terminal access, cloud provider account (optional)

-

Phase 1: Installation

-

System Prerequisites

-

Ensure your system meets minimum requirements:

-
# Check OS (Linux or macOS)
-uname -s
-
-# Verify available disk space (minimum 10GB recommended)
-df -h ~
-
-# Check internet connectivity
-ping -c 3 github.com
-
-

Install Required Tools

-

Nushell (Required)

-
# macOS
-brew install nushell
-
-# Linux
-cargo install nu
-
-# Verify installation
-nu --version  # Expected: 0.109.1+
-
-

Nickel (Required)

-
# macOS
-brew install nickel
-
-# Linux
-cargo install nickel-lang-cli
-
-# Verify installation
-nickel --version  # Expected: 1.15.1+
-
-

Additional Tools

-
# SOPS for secrets management
-brew install sops  # macOS
-# or download from  [https://github.com/getsops/sops/releases](https://github.com/getsops/sops/releases)
-
-# Age for encryption
-brew install age  # macOS
-cargo install age  # Linux
-
-# K9s for Kubernetes management (optional)
-brew install derailed/k9s/k9s
-
-# Verify installations
-sops --version    # Expected: 3.10.2+
-age --version     # Expected: 1.2.1+
-k9s version       # Expected: 0.50.6+
-
-

Install Provisioning Platform

- -
# Download and run installer
-INSTALL_URL="https://raw.githubusercontent.com/yourusername/provisioning/main/install.sh"
-curl -sSL "$INSTALL_URL" | bash
-
-# Follow prompts to configure installation directory and path
-# Default: ~/.local/bin/provisioning
-
-

Installer performs:

-
    -
  • Downloads latest platform binaries
  • -
  • Installs CLI to system PATH
  • -
  • Creates default configuration structure
  • -
  • Validates dependencies
  • -
  • Runs health check
  • -
-

Option 2: Build from Source

-
# Clone repository
-git clone  [https://github.com/yourusername/provisioning.git](https://github.com/yourusername/provisioning.git)
-cd provisioning
-
-# Build core CLI
-cd provisioning/core
-cargo build --release
-
-# Install to local bin
-cp target/release/provisioning ~/.local/bin/
-
-# Add to PATH (add to ~/.bashrc or ~/.zshrc)
-export PATH="$HOME/.local/bin:$PATH"
-
-# Verify installation
-provisioning version
-
-

Platform Health Check

-
# Verify installation
-provisioning setup check
-
-# Expected output:
-# ✓ Nushell 0.109.1 installed
-# ✓ Nickel 1.15.1 installed
-# ✓ SOPS 3.10.2 installed
-# ✓ Age 1.2.1 installed
-# ✓ Provisioning CLI installed
-# ✓ Configuration directory created
-# Platform ready for use
-
-

Phase 2: Initial Configuration

-

Generate User Configuration

-
# Create user configuration directory
-mkdir -p ~/.config/provisioning
-
-# Generate default user config
-provisioning setup init-user-config
-
-

Generated configuration structure:

-
~/.config/provisioning/
-├── user_config.yaml      # User preferences and workspace registry
-├── credentials/          # Provider credentials (encrypted)
-├── age/                  # Age encryption keys
-└── cache/                # CLI cache
-
-

Configure Encryption

-
# Generate Age key pair for secrets
-age-keygen -o ~/.config/provisioning/age/provisioning.key
-
-# Store public key
-age-keygen -y ~/.config/provisioning/age/provisioning.key > ~/.config/provisioning/age/provisioning.pub
-
-# Configure SOPS to use Age
-cat > ~/.config/sops/config.yaml <<EOF
-creation_rules:
-  - path_regex: \.secret\.(yam| l tom| l json)$
-    age: $(cat ~/.config/provisioning/age/provisioning.pub)
-EOF
-
-

Provider Credentials

-

Configure credentials for your chosen cloud provider.

-

UpCloud Configuration

-
# Edit user config
-nano ~/.config/provisioning/user_config.yaml
-
-# Add provider credentials
-cat >> ~/.config/provisioning/user_config.yaml <<EOF
-providers:
-  upcloud:
-    username: "your-upcloud-username"
-    password_env: "UPCLOUD_PASSWORD"  # Read from environment variable
-    default_zone: "de-fra1"
-EOF
-
-# Set environment variable (add to ~/.bashrc or ~/.zshrc)
-export UPCLOUD_PASSWORD="your-upcloud-password"
-
-

AWS Configuration

-
# Add AWS credentials to user config
-cat >> ~/.config/provisioning/user_config.yaml <<EOF
-providers:
-  aws:
-    access_key_id_env: "AWS_ACCESS_KEY_ID"
-    secret_access_key_env: "AWS_SECRET_ACCESS_KEY"
-    default_region: "eu-west-1"
-EOF
-
-# Set environment variables
-export AWS_ACCESS_KEY_ID="your-access-key-id"
-export AWS_SECRET_ACCESS_KEY="your-secret-access-key"
-
-

Local Provider (Development)

-
# Configure local provider for testing
-cat >> ~/.config/provisioning/user_config.yaml <<EOF
-providers:
-  local:
-    backend: "docker"  # or "podman", "libvirt"
-    storage_path: "$HOME/.local/share/provisioning/local"
-EOF
-
-# Ensure Docker is running
-docker info
-
-

Validate Configuration

-
# Validate user configuration
-provisioning validate config
-
-# Test provider connectivity
-provisioning providers
-
-# Expected output:
-# PROVIDER    STATUS     REGION/ZONE
-# upcloud     connected  de-fra1
-# local       ready      localhost
-
-

Phase 3: Create First Workspace

-

Initialize Workspace

-
# Create workspace for first project
-provisioning workspace init my-first-project
-
-# Navigate to workspace
-cd workspace_my_first_project
-
-# Verify structure
-ls -la
-
-

Workspace structure created:

-
workspace_my_first_project/
-├── infra/                   # Infrastructure definitions (Nickel)
-├── config/                  # Workspace configuration
-│   ├── provisioning.yaml    # Workspace metadata
-│   ├── dev-defaults.toml    # Development defaults
-│   ├── test-defaults.toml   # Testing defaults
-│   └── prod-defaults.toml   # Production defaults
-├── extensions/              # Workspace-specific extensions
-│   ├── providers/
-│   ├── taskservs/
-│   └── workflows/
-└── runtime/                 # State and logs (gitignored)
-    ├── state/
-    ├── checkpoints/
-    └── logs/
-
-

Configure Workspace

-
# Edit workspace metadata
-nano config/provisioning.yaml
-
-

Example workspace configuration:

-
workspace:
-  name: my-first-project
-  description: Learning Provisioning platform
-  environment: development
-  created: 2026-01-16T10:00:00Z
-
-defaults:
-  provider: local
-  region: localhost
-  confirmation_required: false
-
-versioning:
-  nushell: "0.109.1"
-  nickel: "1.15.1"
-  kubernetes: "1.29.0"
-
-

Phase 4: Define Infrastructure

-

Simple Server Configuration

-

Create your first infrastructure definition using Nickel:

-
# Create server definition
-cat > infra/simple-server.ncl <<'EOF'
-{
-  metadata = {
-    name = "simple-server"
-    provider = "local"
-    environment = 'development
-  }
-
-  infrastructure = {
-    servers = [
-      {
-        name = "dev-web-01"
-        plan = "small"
-        zone = "localhost"
-        disk_size_gb = 25
-        backup_enabled = false
-        role = 'standalone
-      }
-    ]
-  }
-
-  services = {
-    taskservs = ["containerd"]
-  }
-}
-EOF
-
-

Validate Infrastructure Schema

-
# Type-check Nickel schema
-nickel typecheck infra/simple-server.ncl
-
-# Validate against platform contracts
-provisioning validate config --infra simple-server
-
-# Preview deployment
-provisioning server create --check --infra simple-server
-
-

Expected output:

-
Infrastructure Plan: simple-server
-Provider: local
-Environment: development
-
-Servers to create:
-  - dev-web-01 (small, standalone)
-    Disk: 25 GB
-    Backup: disabled
-
-Task services:
-  - containerd
-
-Estimated resources:
-  CPU: 1 core
-  RAM: 1 GB
-  Disk: 25 GB
-
-Validation: PASSED
-
-

Deploy Infrastructure

-
# Create server
-provisioning server create --infra simple-server --yes
-
-# Monitor deployment
-provisioning server status dev-web-01
-
-

Deployment progress:

-
Creating server: dev-web-01...
-  [████████████████████████] 100% - Container created
-  [████████████████████████] 100% - Network configured
-  [████████████████████████] 100% - SSH ready
-
-Server dev-web-01 created successfully
-IP Address: 172.17.0.2
-Status: running
-Provider: local (docker)
-
-

Install Task Service

-
# Install containerd
-provisioning taskserv create containerd --infra simple-server
-
-# Verify installation
-provisioning taskserv status containerd
-
-

Installation output:

-
Installing containerd on dev-web-01...
-  [████████████████████████] 100% - Dependencies resolved
-  [████████████████████████] 100% - Containerd installed
-  [████████████████████████] 100% - Service started
-  [████████████████████████] 100% - Health check passed
-
-Containerd installed successfully
-Version: 1.7.0
-Runtime: runc
-
-

Verify Deployment

-
# SSH into server
-provisioning server ssh dev-web-01
-
-# Inside server - verify containerd
-sudo systemctl status containerd
-sudo ctr version
-
-# Exit server
-exit
-
-# List all resources
-provisioning server list
-provisioning taskserv list
-
-

Phase 5: Kubernetes Cluster Deployment

-

Define Kubernetes Infrastructure

-
# Create Kubernetes cluster definition
-cat > infra/k8s-cluster.ncl <<'EOF'
-{
-  metadata = {
-    name = "k8s-dev-cluster"
-    provider = "local"
-    environment = 'development
-  }
-
-  infrastructure = {
-    servers = [
-      {
-        name = "k8s-control-01"
-        plan = "medium"
-        role = 'control
-        zone = "localhost"
-        disk_size_gb = 50
-      }
-      {
-        name = "k8s-worker-01"
-        plan = "medium"
-        role = 'worker
-        zone = "localhost"
-        disk_size_gb = 50
-      }
-      {
-        name = "k8s-worker-02"
-        plan = "medium"
-        role = 'worker
-        zone = "localhost"
-        disk_size_gb = 50
-      }
-    ]
-  }
-
-  services = {
-    taskservs = ["containerd", "etcd", "kubernetes", "cilium"]
-  }
-
-  kubernetes = {
-    version = "1.29.0"
-    pod_cidr = "10.244.0.0/16"
-    service_cidr = "10.96.0.0/12"
-    container_runtime = "containerd"
-    cri_socket = "/run/containerd/containerd.sock"
-  }
-}
-EOF
-
-

Validate Kubernetes Configuration

-
# Type-check schema
-nickel typecheck infra/k8s-cluster.ncl
-
-# Validate configuration
-provisioning validate config --infra k8s-cluster
-
-# Preview deployment
-provisioning cluster create --check --infra k8s-cluster
-
-

Deploy Kubernetes Cluster

-
# Create cluster infrastructure
-provisioning cluster create --infra k8s-cluster --yes
-
-# Monitor cluster deployment
-provisioning cluster status k8s-dev-cluster
-
-

Cluster deployment phases:

-
Phase 1: Creating servers...
-  [████████████████████████] 100% - 3/3 servers created
-
-Phase 2: Installing containerd...
-  [████████████████████████] 100% - 3/3 nodes ready
-
-Phase 3: Installing etcd...
-  [████████████████████████] 100% - Control plane ready
-
-Phase 4: Installing Kubernetes...
-  [████████████████████████] 100% - API server available
-  [████████████████████████] 100% - Workers joined
-
-Phase 5: Installing Cilium CNI...
-  [████████████████████████] 100% - Network ready
-
-Kubernetes cluster deployed successfully
-Cluster: k8s-dev-cluster
-Control plane: k8s-control-01
-Workers: k8s-worker-01, k8s-worker-02
-
-

Access Kubernetes Cluster

-
# Get kubeconfig
-provisioning cluster kubeconfig k8s-dev-cluster > ~/.kube/config-dev
-
-# Set KUBECONFIG
-export KUBECONFIG=~/.kube/config-dev
-
-# Verify cluster
-kubectl get nodes
-
-# Expected output:
-# NAME              STATUS   ROLES           AGE   VERSION
-# k8s-control-01    Ready    control-plane   5m    v1.29.0
-# k8s-worker-01     Ready    <none>          4m    v1.29.0
-# k8s-worker-02     Ready    <none>          4m    v1.29.0
-
-# Use K9s for interactive management
-k9s
-
-

Phase 6: Security Configuration

-

Enable Audit Logging

-
# Configure audit logging
-cat > config/audit-config.toml <<EOF
-[audit]
-enabled = true
-log_path = "runtime/logs/audit"
-retention_days = 90
-level = "info"
-
-[audit.filters]
-include_commands = ["server create", "server delete", "cluster deploy"]
-exclude_users = []
-EOF
-
-

Configure SOPS for Secrets

-
# Create secrets file
-cat > config/secrets.secret.yaml <<EOF
-database:
-  password: "changeme-db-password"
-  admin_user: "admin"
-
-kubernetes:
-  service_account_key: "changeme-sa-key"
-EOF
-
-# Encrypt secrets with SOPS
-sops -e -i config/secrets.secret.yaml
-
-# Verify encryption
-cat config/secrets.secret.yaml  # Should show encrypted content
-
-# Decrypt when needed
-sops -d config/secrets.secret.yaml
-
-

Enable MFA (Optional)

-
# Enable multi-factor authentication
-provisioning security mfa enable
-
-# Scan QR code with authenticator app
-# Enter verification code
-
-

Configure RBAC

-
# Create role definition
-cat > config/rbac-roles.yaml <<EOF
-roles:
-  - name: developer
-    permissions:
-      - server:read
-      - server:create
-      - taskserv:read
-      - taskserv:install
-    deny:
-      - cluster:delete
-      - config:modify
-
-  - name: operator
-    permissions:
-      - "*:read"
-      - server:*
-      - taskserv:*
-      - cluster:read
-      - cluster:deploy
-
-  - name: admin
-    permissions:
-      - "*:*"
-EOF
-
-

Phase 7: Multi-Cloud Deployment

-

Define Multi-Cloud Infrastructure

-
# Create multi-cloud definition
-cat > infra/multi-cloud.ncl <<'EOF'
-{
-  batch_workflow = {
-    operations = [
-      {
-        id = "upcloud-frontend"
-        provider = "upcloud"
-        region = "de-fra1"
-        servers = [
-          {name = "upcloud-web-01", plan = "medium", role = 'web}
-        ]
-        taskservs = ["containerd", "nginx"]
-      }
-      {
-        id = "aws-backend"
-        provider = "aws"
-        region = "eu-west-1"
-        servers = [
-          {name = "aws-api-01", plan = "t3.medium", role = 'api}
-        ]
-        taskservs = ["containerd", "docker"]
-        dependencies = ["upcloud-frontend"]
-      }
-      {
-        id = "local-database"
-        provider = "local"
-        region = "localhost"
-        servers = [
-          {name = "local-db-01", plan = "large", role = 'database}
-        ]
-        taskservs = ["postgresql"]
-      }
-    ]
-    parallel_limit = 2
-  }
-}
-EOF
-
-

Deploy Multi-Cloud Infrastructure

-
# Submit batch workflow
-provisioning batch submit infra/multi-cloud.ncl
-
-# Monitor workflow progress
-provisioning batch status
-
-# View detailed operation status
-provisioning batch operations
-
-

Phase 8: Monitoring and Maintenance

-

Platform Health Monitoring

-
# Check platform health
-provisioning health
-
-# View service status
-provisioning service status orchestrator
-provisioning service status control-center
-
-# View logs
-provisioning logs --service orchestrator --tail 100
-
-

Infrastructure Monitoring

-
# List all servers
-provisioning server list --all-workspaces
-
-# Show server details
-provisioning server info k8s-control-01
-
-# Check task service status
-provisioning taskserv list
-provisioning taskserv health containerd
-
-

Backup Configuration

-
# Create backup
-provisioning backup create --type full --output ~/backups/provisioning-$(date +%Y%m%d).tar.gz
-
-# Schedule automatic backups
-provisioning backup schedule daily --time "02:00" --retention 7
-
-

Phase 9: Advanced Workflows

-

Custom Workflow Creation

-
# Create custom workflow
-cat > extensions/workflows/deploy-app.ncl <<'EOF'
-{
-  workflow = {
-    name = "deploy-application"
-    description = "Deploy application to Kubernetes"
-
-    steps = [
-      {
-        name = "build-image"
-        action = "docker-build"
-        params = {dockerfile = "Dockerfile", tag = "myapp:latest"}
-      }
-      {
-        name = "push-image"
-        action = "docker-push"
-        params = {image = "myapp:latest", registry = "registry.example.com"}
-        depends_on = ["build-image"]
-      }
-      {
-        name = "deploy-k8s"
-        action = "kubectl-apply"
-        params = {manifest = "k8s/deployment.yaml"}
-        depends_on = ["push-image"]
-      }
-      {
-        name = "verify-deployment"
-        action = "kubectl-rollout-status"
-        params = {deployment = "myapp"}
-        depends_on = ["deploy-k8s"]
-      }
-    ]
-  }
-}
-EOF
-
-

Execute Custom Workflow

-
# Run workflow
-provisioning workflow run deploy-application
-
-# Monitor workflow
-provisioning workflow status deploy-application
-
-# View workflow history
-provisioning workflow history
-
-

Troubleshooting

-

Common Issues

-

Server Creation Fails

-
# Enable debug logging
-provisioning --debug server create --infra simple-server
-
-# Check provider connectivity
-provisioning providers
-
-# Validate credentials
-provisioning validate config
-
-

Task Service Installation Fails

-
# Check server connectivity
-provisioning server ssh dev-web-01
-
-# Verify dependencies
-provisioning taskserv check-deps containerd
-
-# Retry installation
-provisioning taskserv create containerd --force
-
-

Cluster Deployment Fails

-
# Check cluster status
-provisioning cluster status k8s-dev-cluster
-
-# View cluster logs
-provisioning cluster logs k8s-dev-cluster
-
-# Reset and retry
-provisioning cluster reset k8s-dev-cluster
-provisioning cluster create --infra k8s-cluster
-
-

Next Steps

-

Production Deployment

- -

Advanced Features

- -

Learning Resources

- -

Summary

-

You’ve completed the from-scratch guide and learned:

-
    -
  • Platform installation and configuration
  • -
  • Provider credential setup
  • -
  • Workspace creation and management
  • -
  • Infrastructure definition with Nickel
  • -
  • Server and task service deployment
  • -
  • Kubernetes cluster deployment
  • -
  • Security configuration
  • -
  • Multi-cloud deployment
  • -
  • Monitoring and maintenance
  • -
  • Custom workflow creation
  • -
-

Your Provisioning platform is now ready for production use.

-

Workspace Management

-

Multi-Cloud Deployment

-

Comprehensive guide to deploying and managing infrastructure across multiple cloud providers -using the Provisioning platform. This guide covers strategies, patterns, and real-world examples -for building resilient multi-cloud architectures.

-

Overview

-

Multi-cloud deployment enables:

-
    -
  • Vendor independence - Avoid lock-in to single cloud provider
  • -
  • Geographic distribution - Deploy closer to users worldwide
  • -
  • Resilience - Survive provider outages or regional failures
  • -
  • Cost optimization - Leverage competitive pricing across providers
  • -
  • Compliance - Meet data residency and sovereignty requirements
  • -
  • Performance - Optimize latency through strategic placement
  • -
-

Multi-Cloud Strategies

-

Strategy 1: Primary-Backup Architecture

-

One provider serves production traffic, another provides disaster recovery.

-

Use cases:

-
    -
  • Cost-conscious deployments
  • -
  • Regulatory backup requirements
  • -
  • Testing multi-cloud capabilities
  • -
-

Example topology:

-
Primary (UpCloud EU)          Backup (AWS US)
-├── Production workloads      ├── Standby replicas
-├── Active databases          ├── Read-only databases
-├── Live traffic              └── Failover ready
-└── Real-time sync ────────────>
-
-

Pros: Simple management, lower costs, proven failover -Cons: Backup resources underutilized, sync lag

-

Strategy 2: Active-Active Architecture

-

Multiple providers serve production traffic simultaneously.

-

Use cases:

-
    -
  • High availability requirements
  • -
  • Global user base
  • -
  • Zero-downtime deployments
  • -
-

Example topology:

-
UpCloud (EU)                  AWS (US)                      Local (Development)
-├── EU traffic                ├── US traffic                ├── Testing
-├── Primary database          ├── Primary database          ├── CI/CD
-└── Global load balancer ←────┴──────────────────────────────┘
-
-

Pros: Maximum availability, optimized latency, full utilization -Cons: Complex management, higher costs, data consistency challenges

-

Strategy 3: Specialized Workload Distribution

-

Different providers for different workload types based on strengths.

-

Use cases:

-
    -
  • Heterogeneous workloads
  • -
  • Cost optimization
  • -
  • Leveraging provider-specific services
  • -
-

Example topology:

-
UpCloud                       AWS                           Local
-├── Compute-intensive         ├── Object storage (S3)       ├── Development
-├── Kubernetes clusters       ├── Managed databases (RDS)   └── Testing
-└── High-performance VMs      └── Serverless (Lambda)
-
-

Pros: Optimize for provider strengths, cost-effective, flexible -Cons: Complex integration, vendor-specific knowledge required

-

Strategy 4: Compliance-Driven Architecture

-

Provider selection based on regulatory and data residency requirements.

-

Use cases:

-
    -
  • GDPR compliance
  • -
  • Data sovereignty
  • -
  • Industry regulations (HIPAA, PCI-DSS)
  • -
-

Example topology:

-
UpCloud (EU - GDPR)           AWS (US - FedRAMP)            On-Premises (Sensitive)
-├── EU customer data          ├── US customer data          ├── PII storage
-├── GDPR-compliant            ├── US compliance             └── Encrypted backups
-└── Regional processing       └── Federal workloads
-
-

Pros: Meets compliance requirements, data sovereignty -Cons: Geographic constraints, complex data management

-

Infrastructure Definition

-

Multi-Provider Server Configuration

-

Define servers across multiple providers using Nickel:

-
# infra/multi-cloud-servers.ncl
-{
-  metadata = {
-    name = "multi-cloud-infrastructure"
-    environment = 'production
-  }
-
-  infrastructure = {
-    servers = [
-      # UpCloud servers (EU region)
-      {
-        name = "upcloud-web-01"
-        provider = "upcloud"
-        zone = "de-fra1"
-        plan = "medium"
-        role = 'web
-        backup_enabled = true
-        tags = ["frontend", "europe"]
-      }
-      {
-        name = "upcloud-web-02"
-        provider = "upcloud"
-        zone = "fi-hel1"
-        plan = "medium"
-        role = 'web
-        backup_enabled = true
-        tags = ["frontend", "europe"]
-      }
-
-      # AWS servers (US region)
-      {
-        name = "aws-api-01"
-        provider = "aws"
-        zone = "us-east-1a"
-        plan = "t3.large"
-        role = 'api
-        backup_enabled = true
-        tags = ["backend", "americas"]
-      }
-      {
-        name = "aws-api-02"
-        provider = "aws"
-        zone = "us-west-2a"
-        plan = "t3.large"
-        role = 'api
-        backup_enabled = true
-        tags = ["backend", "americas"]
-      }
-
-      # Local provider (development/testing)
-      {
-        name = "local-test-01"
-        provider = "local"
-        zone = "localhost"
-        plan = "small"
-        role = 'test
-        backup_enabled = false
-        tags = ["testing", "development"]
-      }
-    ]
-  }
-
-  networking = {
-    vpn_mesh = true
-    cross_provider_routing = true
-    dns_strategy = 'geo_distributed
-  }
-}
-
-

Batch Workflow for Multi-Cloud

-

Use batch workflows for orchestrated multi-cloud deployments:

-
# infra/multi-cloud-batch.ncl
-{
-  batch_workflow = {
-    name = "global-deployment"
-    description = "Deploy infrastructure across three cloud providers"
-
-    operations = [
-      {
-        id = "upcloud-eu"
-        provider = "upcloud"
-        region = "de-fra1"
-        servers = [
-          {name = "upcloud-web-01", plan = "medium", role = 'web}
-          {name = "upcloud-db-01", plan = "large", role = 'database}
-        ]
-        taskservs = ["containerd", "nginx", "postgresql"]
-        priority = 1
-      }
-
-      {
-        id = "aws-us"
-        provider = "aws"
-        region = "us-east-1"
-        servers = [
-          {name = "aws-api-01", plan = "t3.large", role = 'api}
-          {name = "aws-cache-01", plan = "t3.medium", role = 'cache}
-        ]
-        taskservs = ["containerd", "docker", "redis"]
-        dependencies = ["upcloud-eu"]
-        priority = 2
-      }
-
-      {
-        id = "local-dev"
-        provider = "local"
-        region = "localhost"
-        servers = [
-          {name = "local-test-01", plan = "small", role = 'test}
-        ]
-        taskservs = ["containerd"]
-        priority = 3
-      }
-    ]
-
-    execution = {
-      parallel_limit = 2
-      retry_failed = true
-      max_retries = 3
-      checkpoint_enabled = true
-    }
-  }
-}
-
-

Deployment Patterns

-

Pattern 1: Sequential Deployment

-

Deploy providers one at a time to minimize risk.

-
# Deploy to primary provider first
-provisioning batch submit infra/upcloud-primary.ncl
-
-# Verify primary deployment
-provisioning server list --provider upcloud
-provisioning server status upcloud-web-01
-
-# Deploy to secondary provider
-provisioning batch submit infra/aws-secondary.ncl
-
-# Verify secondary deployment
-provisioning server list --provider aws
-
-

Advantages:

-
    -
  • Controlled rollout
  • -
  • Easy troubleshooting
  • -
  • Clear rollback path
  • -
-

Disadvantages:

-
    -
  • Slower deployment
  • -
  • Sequential dependencies
  • -
-

Pattern 2: Parallel Deployment

-

Deploy to multiple providers simultaneously for speed.

-
# Submit multi-cloud batch workflow
-provisioning batch submit infra/multi-cloud-batch.ncl
-
-# Monitor all operations
-provisioning batch status
-
-# Check progress per provider
-provisioning batch operations --filter provider=upcloud
-provisioning batch operations --filter provider=aws
-
-

Advantages:

-
    -
  • Fast deployment
  • -
  • Efficient resource usage
  • -
  • Parallel testing
  • -
-

Disadvantages:

-
    -
  • Complex failure handling
  • -
  • Resource contention
  • -
  • Harder troubleshooting
  • -
-

Pattern 3: Blue-Green Multi-Cloud

-

Deploy new infrastructure in parallel, then switch traffic.

-
# infra/blue-green-multi-cloud.ncl
-{
-  deployment = {
-    strategy = 'blue_green
-
-    blue_environment = {
-      upcloud = {servers = [{name = "upcloud-web-01-blue", role = 'web}]}
-      aws = {servers = [{name = "aws-api-01-blue", role = 'api}]}
-    }
-
-    green_environment = {
-      upcloud = {servers = [{name = "upcloud-web-01-green", role = 'web}]}
-      aws = {servers = [{name = "aws-api-01-green", role = 'api}]}
-    }
-
-    traffic_switch = {
-      type = 'dns
-      validation_required = true
-      rollback_timeout_seconds = 300
-    }
-  }
-}
-
-
# Deploy green environment
-provisioning deployment create --infra blue-green-multi-cloud --target green
-
-# Validate green environment
-provisioning deployment validate green
-
-# Switch traffic to green
-provisioning deployment switch-traffic green
-
-# Decommission blue environment
-provisioning deployment delete blue
-
-

Network Configuration

-

Cross-Provider VPN Mesh

-

Connect servers across providers using VPN mesh:

-
# infra/vpn-mesh.ncl
-{
-  networking = {
-    vpn_mesh = {
-      enabled = true
-      encryption = 'wireguard
-
-      peers = [
-        {
-          name = "upcloud-gateway"
-          provider = "upcloud"
-          public_ip = "auto"
-          private_subnet = "10.0.1.0/24"
-        }
-        {
-          name = "aws-gateway"
-          provider = "aws"
-          public_ip = "auto"
-          private_subnet = "10.0.2.0/24"
-        }
-        {
-          name = "local-gateway"
-          provider = "local"
-          public_ip = "192.168.1.1"
-          private_subnet = "10.0.3.0/24"
-        }
-      ]
-
-      routing = {
-        dynamic_routes = true
-        bgp_enabled = false
-        static_routes = [
-          {from = "10.0.1.0/24", to = "10.0.2.0/24", via = "aws-gateway"}
-          {from = "10.0.2.0/24", to = "10.0.1.0/24", via = "upcloud-gateway"}
-        ]
-      }
-    }
-  }
-}
-
-

Global DNS Configuration

-

Configure geo-distributed DNS for optimal routing:

-
# infra/global-dns.ncl
-{
-  dns = {
-    provider = 'cloudflare  # or 'route53, 'custom
-
-    zones = [
-      {
-        name = "example.com"
-        type = 'primary
-
-        records = [
-          {
-            name = "eu"
-            type = 'A
-            ttl = 300
-            values = ["upcloud-web-01.ip", "upcloud-web-02.ip"]
-            geo_location = 'europe
-          }
-          {
-            name = "us"
-            type = 'A
-            ttl = 300
-            values = ["aws-api-01.ip", "aws-api-02.ip"]
-            geo_location = 'americas
-          }
-          {
-            name = "@"
-            type = 'CNAME
-            ttl = 60
-            value = "global-lb.example.com"
-            geo_routing = 'latency_based
-          }
-        ]
-      }
-    ]
-
-    health_checks = [
-      {target = "upcloud-web-01", interval_seconds = 30}
-      {target = "aws-api-01", interval_seconds = 30}
-    ]
-  }
-}
-
-

Data Replication

-

Database Replication Across Providers

-

Configure cross-provider database replication:

-
# infra/database-replication.ncl
-{
-  databases = {
-    postgresql = {
-      primary = {
-        provider = "upcloud"
-        server = "upcloud-db-01"
-        version = "15"
-        replication_role = 'primary
-      }
-
-      replicas = [
-        {
-          provider = "aws"
-          server = "aws-db-replica-01"
-          version = "15"
-          replication_role = 'replica
-          replication_lag_max_seconds = 30
-          failover_priority = 1
-        }
-        {
-          provider = "local"
-          server = "local-db-backup-01"
-          version = "15"
-          replication_role = 'replica
-          replication_lag_max_seconds = 300
-          failover_priority = 2
-        }
-      ]
-
-      replication = {
-        method = 'streaming
-        ssl_required = true
-        compression = true
-        conflict_resolution = 'primary_wins
-      }
-    }
-  }
-}
-
-

Object Storage Sync

-

Synchronize object storage across providers:

-
# Configure cross-provider storage sync
-cat > infra/storage-sync.ncl <<'EOF'
-{
-  storage = {
-    sync_policy = {
-      source = {
-        provider = "upcloud"
-        bucket = "primary-storage"
-        region = "de-fra1"
-      }
-
-      destinations = [
-        {
-          provider = "aws"
-          bucket = "backup-storage"
-          region = "us-east-1"
-          sync_interval_minutes = 15
-        }
-      ]
-
-      filters = {
-        include_patterns = ["*.pdf", "*.jpg", "backups/*"]
-        exclude_patterns = ["temp/*", "*.tmp"]
-      }
-
-      conflict_resolution = 'timestamp_wins
-    }
-  }
-}
-EOF
-
-

Kubernetes Multi-Cloud

-

Cluster Federation

-

Deploy Kubernetes clusters across providers with federation:

-
# infra/k8s-federation.ncl
-{
-  kubernetes_federation = {
-    clusters = [
-      {
-        name = "upcloud-eu-cluster"
-        provider = "upcloud"
-        region = "de-fra1"
-        control_plane_count = 3
-        worker_count = 5
-        version = "1.29.0"
-      }
-      {
-        name = "aws-us-cluster"
-        provider = "aws"
-        region = "us-east-1"
-        control_plane_count = 3
-        worker_count = 5
-        version = "1.29.0"
-      }
-    ]
-
-    federation = {
-      enabled = true
-      control_plane_cluster = "upcloud-eu-cluster"
-
-      networking = {
-        cluster_mesh = true
-        service_discovery = 'dns
-        cross_cluster_load_balancing = true
-      }
-
-      workload_distribution = {
-        strategy = 'geo_aware
-        prefer_local = true
-        failover_enabled = true
-      }
-    }
-  }
-}
-
-

Multi-Cluster Deployments

-

Deploy applications across multiple Kubernetes clusters:

-
# k8s/multi-cluster-deployment.yaml
-apiVersion: v1
-kind: Namespace
-metadata:
-  name: multi-cloud-app
----
-apiVersion: apps/v1
-kind: Deployment
-metadata:
-  name: web-frontend
-  namespace: multi-cloud-app
-  labels:
-    app: frontend
-    region: europe
-spec:
-  replicas: 3
-  selector:
-    matchLabels:
-      app: frontend
-  template:
-    metadata:
-      labels:
-        app: frontend
-    spec:
-      containers:
-      - name: nginx
-        image: nginx:latest
-        ports:
-        - containerPort: 80
-
-
# Deploy to multiple clusters
-export UPCLOUD_KUBECONFIG=~/.kube/config-upcloud
-export AWS_KUBECONFIG=~/.kube/config-aws
-
-kubectl --kubeconfig $UPCLOUD_KUBECONFIG apply -f k8s/multi-cluster-deployment.yaml
-kubectl --kubeconfig $AWS_KUBECONFIG apply -f k8s/multi-cluster-deployment.yaml
-
-# Verify deployments
-kubectl --kubeconfig $UPCLOUD_KUBECONFIG get pods -n multi-cloud-app
-kubectl --kubeconfig $AWS_KUBECONFIG get pods -n multi-cloud-app
-
-

Cost Optimization

-

Provider Selection by Workload

-

Optimize costs by choosing the most cost-effective provider per workload:

-
# infra/cost-optimized.ncl
-{
-  cost_optimization = {
-    workloads = [
-      {
-        name = "compute-intensive"
-        provider = "upcloud"  # Best compute pricing
-        plan = "large"
-        count = 10
-      }
-      {
-        name = "storage-heavy"
-        provider = "aws"  # Best storage pricing with S3
-        plan = "medium"
-        count = 5
-        storage_type = 's3
-      }
-      {
-        name = "development"
-        provider = "local"  # Zero cost
-        plan = "small"
-        count = 3
-      }
-    ]
-
-    budget_limits = {
-      monthly_max_usd = 5000
-      alerts = [
-        {threshold_percent = 75, notify = "[ops-team@example.com](mailto:ops-team@example.com)"}
-        {threshold_percent = 90, notify = "[finance@example.com](mailto:finance@example.com)"}
-      ]
-    }
-  }
-}
-
-

Reserved Instance Strategy

-

Leverage reserved instances for predictable workloads:

-
# Configure reserved instances
-cat > infra/reserved-instances.ncl <<'EOF'
-{
-  reserved_instances = {
-    upcloud = {
-      commitment = 'yearly
-      instances = [
-        {plan = "medium", count = 5}
-        {plan = "large", count = 2}
-      ]
-    }
-
-    aws = {
-      commitment = 'yearly
-      instances = [
-        {type = "t3.large", count = 3}
-        {type = "t3.xlarge", count = 1}
-      ]
-      savings_plan = true
-    }
-  }
-}
-EOF
-
-

Monitoring Multi-Cloud

-

Centralized Monitoring

-

Deploy unified monitoring across providers:

-
# infra/monitoring.ncl
-{
-  monitoring = {
-    prometheus = {
-      enabled = true
-      federation = true
-
-      instances = [
-        {provider = "upcloud", region = "de-fra1"}
-        {provider = "aws", region = "us-east-1"}
-      ]
-
-      scrape_configs = [
-        {
-          job_name = "upcloud-nodes"
-          static_configs = [{targets = ["upcloud-*.internal:9100"]}]
-        }
-        {
-          job_name = "aws-nodes"
-          static_configs = [{targets = ["aws-*.internal:9100"]}]
-        }
-      ]
-
-      remote_write = {
-        url = " [https://central-prometheus.example.com/api/v1/write"](https://central-prometheus.example.com/api/v1/write")
-        compression = true
-      }
-    }
-
-    grafana = {
-      enabled = true
-      dashboards = ["multi-cloud-overview", "per-provider", "cost-analysis"]
-      alerts = ["high-latency", "provider-down", "budget-exceeded"]
-    }
-  }
-}
-
-

Disaster Recovery

-

Cross-Provider Failover

-

Configure automatic failover between providers:

-
# infra/disaster-recovery.ncl
-{
-  disaster_recovery = {
-    primary_provider = "upcloud"
-    secondary_provider = "aws"
-
-    failover_triggers = [
-      {condition = 'provider_unavailable, action = 'switch_to_secondary}
-      {condition = 'health_check_failed, threshold = 3, action = 'switch_to_secondary}
-      {condition = 'latency_exceeded, threshold_ms = 1000, action = 'switch_to_secondary}
-    ]
-
-    failover_process = {
-      dns_ttl_seconds = 60
-      health_check_interval_seconds = 10
-      automatic = true
-      notification_channels = ["email", "slack"]
-    }
-
-    backup_strategy = {
-      frequency = 'daily
-      retention_days = 30
-      cross_region = true
-      cross_provider = true
-    }
-  }
-}
-
-

Best Practices

-

Configuration Management

-
    -
  • Use Nickel for all infrastructure definitions
  • -
  • Version control all configuration files
  • -
  • Use workspace per environment (dev/staging/prod)
  • -
  • Implement configuration validation before deployment
  • -
  • Maintain provider abstraction where possible
  • -
-

Security

-
    -
  • Encrypt cross-provider communication (VPN, TLS)
  • -
  • Use separate credentials per provider
  • -
  • Implement RBAC consistently across providers
  • -
  • Enable audit logging on all providers
  • -
  • Encrypt data at rest and in transit
  • -
-

Deployment

-
    -
  • Test in single-provider environment first
  • -
  • Use batch workflows for complex multi-cloud deployments
  • -
  • Enable checkpoints for long-running deployments
  • -
  • Implement progressive rollout strategies
  • -
  • Maintain rollback procedures
  • -
-

Monitoring

-
    -
  • Centralize logs and metrics
  • -
  • Monitor cross-provider network latency
  • -
  • Track costs per provider
  • -
  • Alert on provider-specific failures
  • -
  • Measure failover readiness
  • -
-

Cost Management

-
    -
  • Regular cost audits per provider
  • -
  • Use reserved instances for predictable loads
  • -
  • Implement budget alerts
  • -
  • Optimize data transfer costs
  • -
  • Consider spot instances for non-critical workloads
  • -
-

Troubleshooting

-

Provider Connectivity Issues

-
# Test provider connectivity
-provisioning providers
-
-# Test specific provider
-provisioning provider test upcloud
-provisioning provider test aws
-
-# Debug network connectivity
-provisioning network test --from upcloud-web-01 --to aws-api-01
-
-

Cross-Provider Communication Failures

-
# Check VPN mesh status
-provisioning network vpn-status
-
-# Test cross-provider routes
-provisioning network trace-route --from upcloud-web-01 --to aws-api-01
-
-# Verify firewall rules
-provisioning network firewall-check --provider upcloud
-provisioning network firewall-check --provider aws
-
-

Data Replication Lag

-
# Check replication status
-provisioning database replication-status postgresql
-
-# Force replication sync
-provisioning database sync --source upcloud-db-01 --target aws-db-replica-01
-
-# View replication lag metrics
-provisioning database metrics --metric replication_lag
-
-

See Also

- -

Custom Extensions

-

Create custom providers, task services, and clusters to extend the Provisioning platform for your specific infrastructure needs.

-

Overview

-

Extensions allow you to:

-
    -
  • Add support for new cloud providers
  • -
  • Create custom task services for specialized software
  • -
  • Define cluster templates for common deployment patterns
  • -
  • Integrate with proprietary infrastructure
  • -
-

Extension Types

-

Providers

-

Cloud or infrastructure backend integrations.

-

Use Cases: Custom private cloud, bare metal provisioning, proprietary APIs

-

Task Services

-

Installable software components.

-

Use Cases: Internal applications, specialized databases, custom monitoring

-

Clusters

-

Coordinated service groups.

-

Use Cases: Standard deployment patterns, application stacks, reference architectures

-

Creating a Custom Provider

-

Directory Structure

-
provisioning/extensions/providers/my-provider/
-├── provider.ncl          # Provider schema
-├── resources/
-│   ├── server.nu        # Server operations
-│   ├── network.nu       # Network operations
-│   └── storage.nu       # Storage operations
-└── README.md
-
-

Provider Schema (provider.ncl)

-
{
-  name = "my-provider",
-  description = "Custom infrastructure provider",
-
-  config_schema = {
-    api_endpoint | String,
-    api_key | String,
-    region | String | default = "default",
-    timeout_seconds | Number | default = 300,
-  },
-
-  capabilities = {
-    servers = true,
-    networks = true,
-    storage = true,
-    load_balancers = false,
-  }
-}
-
-

Server Operations (resources/server.nu)

-
# Create server
-export def "server create" [
-  name: string
-  plan: string
-  --zone: string = "default"
-] {
-  let config = $env.PROVIDER_CONFIG | from json
-
-  # Call provider API
-  http post $"($config.api_endpoint)/servers" {
-    name: $name,
-    plan: $plan,
-    zone: $zone
-  } | from json
-}
-
-# Delete server
-export def "server delete" [name: string] {
-  let config = $env.PROVIDER_CONFIG | from json
-  http delete $"($config.api_endpoint)/servers/($name)"
-}
-
-# List servers
-export def "server list" [] {
-  let config = $env.PROVIDER_CONFIG | from json
-  http get $"($config.api_endpoint)/servers" | from json
-}
-
-

Creating a Custom Task Service

-

Directory Structure

-
provisioning/extensions/taskservs/my-service/
-├── service.ncl           # Service schema
-├── install.nu            # Installation script
-├── configure.nu          # Configuration script
-├── health-check.nu       # Health validation
-└── README.md
-
-

Service Schema (service.ncl)

-
{
-  name = "my-service",
-  version = "1.0.0",
-  description = "Custom service deployment",
-
-  dependencies = ["kubernetes"],
-
-  config_schema = {
-    replicas | Number | default = 3,
-    port | Number | default = 8080,
-    storage_size_gb | Number | default = 10,
-    image | String,
-  }
-}
-
-

Installation Script (install.nu)

-
export def "taskserv install" [config: record] {
-  print $"Installing ($config.name)..."
-
-  # Create namespace
-  kubectl create namespace $config.name
-
-  # Deploy application
-  kubectl apply -f - <<EOF
-apiVersion: apps/v1
-kind: Deployment
-metadata:
-  name: ($config.name)
-  namespace: ($config.name)
-spec:
-  replicas: ($config.replicas)
-  template:
-    spec:
-      containers:
-      - name: app
-        image: ($config.image)
-        ports:
-        - containerPort: ($config.port)
-EOF
-
-  {status: "installed"}
-}
-
-

Health Check (health-check.nu)

-
export def "taskserv health" [name: string] {
-  let pods = (kubectl get pods -n $name -o json | from json)
-
-  let ready = ($pods.items | all | { | p $p.status.phase == "Running"})
-
-  if $ready {
-    {status: "healthy", ready_pods: ($pods.items | length)}
-  } else {
-    {status: "unhealthy", reason: "pods not running"}
-  }
-}
-
-

Creating a Custom Cluster

-

Directory Structure

-
provisioning/extensions/clusters/my-cluster/
-├── cluster.ncl           # Cluster definition
-├── deploy.nu             # Deployment script
-└── README.md
-
-

Cluster Schema (cluster.ncl)

-
{
-  name = "my-cluster",
-  version = "1.0.0",
-  description = "Custom application stack",
-
-  components = {
-    servers = [
-      {name = "app", count = 3, plan = 'medium},
-      {name = "db", count = 1, plan = 'large},
-    ],
-    services = ["nginx", "postgresql", "redis"],
-  },
-
-  config_schema = {
-    domain | String,
-    app_replicas | Number | default = 3,
-    db_storage_gb | Number | default = 100,
-  }
-}
-
-

Testing Extensions

-

Local Testing

-
# Test provider operations
-provisioning provider test my-provider --local
-
-# Test task service installation
-provisioning taskserv install my-service --dry-run
-
-# Validate cluster definition
-provisioning cluster validate my-cluster
-
-

Integration Testing

-
# Create test workspace
-provisioning workspace create test-extensions
-
-# Deploy extension
-provisioning extension deploy my-provider
-
-# Test deployment
-provisioning server create test-server --provider my-provider
-
-

Extension Best Practices

-
    -
  1. Define clear schemas - Use Nickel contracts for type safety
  2. -
  3. Implement health checks - Validate service state
  4. -
  5. Handle errors gracefully - Return structured error messages
  6. -
  7. Document configuration - Provide clear examples
  8. -
  9. Version extensions - Track compatibility
  10. -
  11. Test thoroughly - Unit and integration tests
  12. -
-

Publishing Extensions

-

Extension Registry

-

Share extensions with the community:

-
# Package extension
-provisioning extension package my-provider
-
-# Publish to registry
-provisioning extension publish my-provider --registry community
-
-

Private Registry

-

Host internal extensions:

-
# Configure private registry
-provisioning config set extension_registry  [https://registry.internal](https://registry.internal)
-
-# Publish privately
-provisioning extension publish my-provider --private
-
-

Examples

-

Custom Database Provider

-

Provider for proprietary database platform:

-
{
-  name = "mydb-provider",
-  capabilities = {databases = true},
-  config_schema = {
-    cluster_endpoint | String,
-    admin_token | String,
-  }
-}
-
-

Monitoring Stack Service

-

Complete monitoring deployment:

-
{
-  name = "monitoring-stack",
-  dependencies = ["prometheus", "grafana", "loki"],
-  config_schema = {
-    retention_days | Number | default = 30,
-    alert_email | String,
-  }
-}
-
-

Troubleshooting

-

Extension Not Loading

-
# Verify extension structure
-provisioning extension validate my-extension
-
-# Check logs
-provisioning logs extension-loader --tail 100
-
-

Deployment Failures

-
# Enable debug logging
-export PROVISIONING_LOG_LEVEL=debug
-provisioning taskserv install my-service
-
-# Check service logs
-provisioning taskserv logs my-service
-
-

References

- -

Disaster Recovery

-

Comprehensive disaster recovery procedures for the Provisioning platform and managed infrastructure.

-

Overview

-

Disaster recovery (DR) ensures business continuity through:

-
    -
  • Automated backups
  • -
  • Point-in-time recovery
  • -
  • Multi-region failover
  • -
  • Data replication
  • -
  • DR testing procedures
  • -
-

Recovery Objectives

-

RTO (Recovery Time Objective)

-

Target time to restore service:

-
    -
  • Critical Services: < 1 hour
  • -
  • Production Infrastructure: < 4 hours
  • -
  • Development Environment: < 24 hours
  • -
-

RPO (Recovery Point Objective)

-

Maximum acceptable data loss:

-
    -
  • Production Databases: < 5 minutes (continuous replication)
  • -
  • Configuration: < 1 hour (hourly backups)
  • -
  • Workspace State: < 15 minutes (incremental backups)
  • -
-

Backup Strategy

-

Automated Backups

-

Configure automatic backups:

-
{
-  backup = {
-    enabled = true,
-    schedule = "0 */6 * * *",  # Every 6 hours
-    retention_days = 30,
-
-    targets = [
-      {type = 'workspace_state, enabled = true},
-      {type = 'infrastructure_config, enabled = true},
-      {type = 'platform_data, enabled = true},
-    ],
-
-    storage = {
-      backend = 's3,
-      bucket = "provisioning-backups",
-      encryption = true,
-    }
-  }
-}
-
-

Backup Types

-

Full Backups:

-
# Full platform backup
-provisioning backup create --type full --name "pre-upgrade-$(date +%Y%m%d)"
-
-# Full workspace backup
-provisioning workspace backup production --full
-
-

Incremental Backups:

-
# Incremental backup (changed files only)
-provisioning backup create --type incremental
-
-# Automated incremental
-provisioning config set backup.incremental_enabled true
-
-

Snapshot Backups:

-
# Infrastructure snapshot
-provisioning infrastructure snapshot --name "stable-v2"
-
-# Database snapshot
-provisioning taskserv backup postgresql --snapshot
-
-

Data Replication

-

Cross-Region Replication

-

Replicate to secondary region:

-
{
-  replication = {
-    enabled = true,
-    mode = 'async,
-
-    primary = {region = "eu-west-1", provider = 'aws},
-    secondary = {region = "us-east-1", provider = 'aws},
-
-    replication_lag_max_seconds = 300,
-  }
-}
-
-

Database Replication

-
# Configure database replication
-provisioning taskserv configure postgresql --replication \
-  --primary db-eu-west-1 \
-  --standby db-us-east-1 \
-  --sync-mode async
-
-

Disaster Scenarios

-

Complete Region Failure

-

Procedure:

-
    -
  1. Detect Failure:
  2. -
-
# Check region health
-provisioning health check --region eu-west-1
-
-
    -
  1. Initiate Failover:
  2. -
-
# Promote secondary region
-provisioning disaster-recovery failover --to us-east-1 --confirm
-
-# Verify services
-provisioning health check --all
-
-
    -
  1. Update DNS:
  2. -
-
# Point traffic to secondary region
-provisioning dns update --region us-east-1
-
-
    -
  1. Monitor:
  2. -
-
# Watch recovery progress
-provisioning disaster-recovery status --follow
-
-

Data Corruption

-

Procedure:

-
    -
  1. Identify Corruption:
  2. -
-
# Validate data integrity
-provisioning validate data --workspace production
-
-
    -
  1. Find Clean Backup:
  2. -
-
# List available backups
-provisioning backup list --before "2024-01-15 10:00"
-
-# Verify backup integrity
-provisioning backup verify backup-20240115-0900
-
-
    -
  1. Restore from Backup:
  2. -
-
# Restore to point in time
-provisioning restore --backup backup-20240115-0900 \
-  --workspace production --confirm
-
-

Platform Service Failure

-

Procedure:

-
    -
  1. Identify Failed Service:
  2. -
-
# Check platform health
-provisioning platform health
-
-# Service logs
-provisioning platform logs orchestrator --tail 100
-
-
    -
  1. Restart Service:
  2. -
-
# Restart failed service
-provisioning platform restart orchestrator
-
-# Verify health
-provisioning platform health orchestrator
-
-
    -
  1. Restore from Backup (if needed):
  2. -
-
# Restore service data
-provisioning platform restore orchestrator \
-  --from-backup latest
-
-

Failover Procedures

-

Automated Failover

-

Configure automatic failover:

-
{
-  failover = {
-    enabled = true,
-    health_check_interval_seconds = 30,
-    failure_threshold = 3,
-
-    primary = {region = "eu-west-1"},
-    secondary = {region = "us-east-1"},
-
-    auto_failback = false,  # Manual failback
-  }
-}
-
-

Manual Failover

-
# Initiate manual failover
-provisioning disaster-recovery failover \
-  --from eu-west-1 \
-  --to us-east-1 \
-  --verify-replication \
-  --confirm
-
-# Verify failover
-provisioning disaster-recovery verify
-
-# Update routing
-provisioning disaster-recovery update-routing
-
-

Recovery Procedures

-

Workspace Recovery

-
# List workspace backups
-provisioning workspace backups production
-
-# Restore workspace
-provisioning workspace restore production \
-  --backup backup-20240115-1200 \
-  --target-region us-east-1
-
-# Verify recovery
-provisioning workspace validate production
-
-

Infrastructure Recovery

-
# Restore infrastructure from Nickel config
-provisioning infrastructure restore \
-  --config workspace/infra/production.ncl \
-  --region us-east-1
-
-# Restore from snapshot
-provisioning infrastructure restore \
-  --snapshot infra-snapshot-20240115
-
-# Verify deployment
-provisioning infrastructure validate
-
-

Platform Recovery

-
# Reinstall platform services
-provisioning platform install --region us-east-1
-
-# Restore platform data
-provisioning platform restore --from-backup latest
-
-# Verify platform health
-provisioning platform health --all
-
-

DR Testing

-

Test Schedule

-
    -
  • Monthly: Backup restore test
  • -
  • Quarterly: Regional failover drill
  • -
  • Annually: Full DR simulation
  • -
-

Backup Restore Test

-
# Create test workspace
-provisioning workspace create dr-test-$(date +%Y%m%d)
-
-# Restore latest backup
-provisioning workspace restore dr-test --backup latest
-
-# Validate restore
-provisioning workspace validate dr-test
-
-# Cleanup
-provisioning workspace delete dr-test --yes
-
-

Failover Drill

-
# Simulate regional failure
-provisioning disaster-recovery simulate-failure \
-  --region eu-west-1 \
-  --duration 30m
-
-# Monitor automated failover
-provisioning disaster-recovery status --follow
-
-# Validate services in secondary region
-provisioning health check --region us-east-1 --all
-
-# Manual failback after drill
-provisioning disaster-recovery failback --to eu-west-1
-
-

Monitoring and Alerts

-

Backup Monitoring

-
# Check backup status
-provisioning backup status
-
-# Verify backup integrity
-provisioning backup verify --all --schedule daily
-
-# Alert on backup failures
-provisioning alert create backup-failure \
-  --condition "backup.status == 'failed'" \
-  --notify [ops@example.com](mailto:ops@example.com)
-
-

Replication Monitoring

-
# Check replication lag
-provisioning replication status
-
-# Alert on lag exceeding threshold
-provisioning alert create replication-lag \
-  --condition "replication.lag_seconds > 300" \
-  --notify [ops@example.com](mailto:ops@example.com)
-
-

Best Practices

-
    -
  1. Regular testing - Test DR procedures quarterly
  2. -
  3. Automated backups - Never rely on manual backups
  4. -
  5. Multiple regions - Geographic redundancy
  6. -
  7. Monitor replication - Track replication lag
  8. -
  9. Document procedures - Keep runbooks updated
  10. -
  11. Encrypt backups - Protect backup data
  12. -
  13. Verify restores - Test backup integrity
  14. -
  15. Automate failover - Reduce recovery time
  16. -
-

References

- -

- Provisioning Logo -

-

- Provisioning -

-

Infrastructure as Code

-

Define and manage infrastructure using Nickel, the type-safe configuration -language that serves as Provisioning’s source of truth.

-

Overview

-

Provisioning’s infrastructure definition system provides:

-
    -
  • Type-safe configuration via Nickel language with mandatory schema validation and contract enforcement
  • -
  • Complete provider support for AWS, UpCloud, Hetzner, Kubernetes, on-premise, and custom platforms
  • -
  • 50+ task services for specialized infrastructure operations (databases, monitoring, logging, networking)
  • -
  • Pre-built clusters for common patterns (web, OCI registry, cache, distributed computing)
  • -
  • Batch workflows with DAG scheduling, parallel execution, and multi-cloud orchestration
  • -
  • Schema validation with inheritance, merging, and contracts ensuring correctness
  • -
  • Configuration composition with includes, profiles, and environment-specific overrides
  • -
  • Version management with semantic versioning and deprecation paths
  • -
-

All infrastructure is defined in Nickel (never TOML) ensuring compile-time correctness and runtime safety.

-

Infrastructure Configuration Guides

-

Core Configuration

-
    -
  • Nickel Guide - Syntax, types, contracts, lazy -evaluation, record merging, patterns, best practices for IaC
  • -
-

- Nickel Validation Flow Type Checking Contract Validation -

-
    -
  • Configuration System - Hierarchical loading, -environment variables, profiles, composition, inheritance, validation
  • -
-

- Configuration Loading Hierarchy Priority CLI Env User Workspace System -

-
    -
  • Schemas Reference - Contracts, types, -validation rules, inheritance, composition, custom schema development
  • -
-

Resources and Operations

-
    -
  • -

    Providers Guide - AWS, UpCloud, Hetzner, Kubernetes, -on-premise, demo with capabilities, resources, examples

    -
  • -
  • -

    Task Services Guide - 50+ services: databases, -monitoring, logging, networking, CI/CD, storage

    -
  • -
  • -

    Clusters Guide - Web cluster (3-tier), OCI registry, -cache cluster, distributed computing, Kubernetes operators

    -
  • -
  • -

    Batch Workflows - DAG-based scheduling, parallel -execution, logic, error handling, multi-cloud, state management

    -
  • -
-

- Batch Workflow DAG Execution Parallel Tasks Dependencies -

-

Advanced Topics

- -

- Workspace Hierarchy Structure Config Infra Schemas Extensions -

-
    -
  • -

    Version Management - Semantic versioning, -dependency resolution, compatibility, deprecation, upgrade workflows

    -
  • -
  • -

    Performance Optimization - Configuration -caching, lazy evaluation, parallel validation, incremental updates

    -
  • -
-

Nickel as Source of Truth

-

Critical principle: Nickel is the source of truth for ALL infrastructure definitions.

-
    -
  • Nickel: Type-safe, validated, enforced, source of truth
  • -
  • TOML: Generated output only, never hand-edited
  • -
  • JSON/YAML: Generated output only, never source definitions
  • -
  • KCL: Deprecated, completely replaced by Nickel
  • -
-

This ensures:

-
    -
  1. Compile-time validation - Errors caught before deployment
  2. -
  3. Schema enforcement - All configurations conform to contracts
  4. -
  5. Type safety - No runtime configuration errors
  6. -
  7. IDE support - Type hints and autocompletion via schema
  8. -
  9. Evolution - Breaking changes detected and reported
  10. -
-

Configuration Hierarchy

-

Configurations load in order of precedence:

-
1. Command-line arguments       (highest priority)
-2. Environment variables        (PROVISIONING_*)
-3. User configuration          (~/.config/provisioning/user.nickel)
-4. Workspace configuration     (workspace/config/main.nickel)
-5. Infrastructure schemas      (provisioning/schemas/)
-6. System defaults            (provisioning/config/defaults.toml)
-                               (lowest priority)
-
-

Quick Start Paths

-

I’m new to Nickel

-

Start with Nickel Guide - language syntax, type system, functions, patterns with infrastructure examples.

-

I need to define infrastructure

-

Read Configuration System - how configurations load, compose, and validate.

-

I want to use AWS/UpCloud/Hetzner

-

See Providers Guide - capabilities, resources, configuration examples for each cloud.

-

I need databases, monitoring, logging

-

Check Task Services Guide - 50+ services with configuration examples.

-

I want to deploy web applications

-

Review Clusters Guide - pre-built 3-tier web cluster, load balancer, database, caching.

-

I need multi-cloud workflows

-

Learn Batch Workflows - DAG scheduling across multiple providers.

-

I need multi-tenant setup

-

Study Multi-Tenancy Patterns - isolation, billing, resource management.

-

Example Nickel Configuration

-
{
-  extensions = {
-    providers = [
-      {
-        name = "aws",
-        version = "1.2.3",
-        enabled = true,
-        config = {
-          region = "us-east-1",
-          credentials_source = "aws_iam"
-        }
-      }
-    ]
-  },
-
-  infrastructure = {
-    networks = [
-      {
-        name = "main",
-        provider = "aws",
-        cidr = "10.0.0.0/16",
-        subnets = [
-          { cidr = "10.0.1.0/24", availability_zone = "us-east-1a" },
-          { cidr = "10.0.2.0/24", availability_zone = "us-east-1b" }
-        ]
-      }
-    ],
-
-    instances = [
-      {
-        name = "web-server-1",
-        provider = "aws",
-        instance_type = "t3.large",
-        image = "ubuntu-22.04",
-        network = "main",
-        subnet = "10.0.1.0/24"
-      }
-    ]
-  }
-}
-
-

Schema Contracts

-

All infrastructure must conform to schemas. Schemas define:

-
    -
  • Required fields - Must be provided
  • -
  • Type constraints - Values must match type
  • -
  • Field contracts - Custom validation logic
  • -
  • Defaults - Applied automatically
  • -
  • Documentation - Inline help and examples
  • -
-

Validation and Testing

-

Before deploying:

-
    -
  1. Schema validation - provisioning validate config
  2. -
  3. Syntax checking - provisioning validate syntax
  4. -
  5. Policy checks - Custom policy validation
  6. -
  7. Unit tests - Test configuration logic
  8. -
  9. Integration tests - Dry-run with actual providers
  10. -
- -
    -
  • Provisioning Schemas → See provisioning/schemas/ in codebase
  • -
  • Configuration Examples → See provisioning/docs/src/examples/
  • -
  • Provider Examples → See provisioning/docs/src/examples/aws-deployment-examples.md
  • -
  • Task Services → See provisioning/extensions/ in codebase
  • -
  • API Reference → See provisioning/docs/src/api-reference/
  • -
-

Nickel Guide

-

Comprehensive guide to using Nickel as the infrastructure-as-code language for the Provisioning platform.

-

Critical Principle: Nickel is Source of Truth

-

TYPE-SAFETY ALWAYS REQUIRED: ALL configurations MUST be type-safe and validated via Nickel. -TOML is NOT acceptable as source of truth. Validation is NOT optional, NOT “progressive”, -NOT “production-only”. This applies to ALL profiles (developer, production, cicd).

-

Nickel is the PRIMARY IaC language. TOML files are GENERATED OUTPUT ONLY, never the source.

-

Why Nickel

-

Nickel provides:

-
    -
  • Type Safety: Static type checking catches errors before deployment
  • -
  • Lazy Evaluation: Efficient configuration composition and merging
  • -
  • Contract System: Schema validation with gradual typing
  • -
  • Record Merging: Powerful composition without duplication
  • -
  • LSP Support: IDE integration for autocomplete and validation
  • -
  • Human-Readable: Clear syntax for infrastructure definition
  • -
-

Installation

-
# macOS (Homebrew)
-brew install nickel
-
-# Linux (Cargo)
-cargo install nickel-lang-cli
-
-# Verify installation
-nickel --version  # 1.15.1+
-
-

Core Concepts

-

Records and Fields

-

Records are the fundamental data structure in Nickel:

-
{
-  name = "my-server"
-  plan = "medium"
-  zone = "de-fra1"
-}
-
-

Type Annotations

-

Add type safety with contracts:

-
{
-  name : String = "my-server"
-  plan : String = "medium"
-  cpu_count : Number = 4
-  enabled : Bool = true
-}
-
-

Record Merging

-

Compose configurations by merging records:

-
let base_config = {
-  provider = "upcloud"
-  region = "de-fra1"
-} in
-
-let server_config = base_config & {
-  name = "web-01"
-  plan = "medium"
-} in
-
-server_config
-
-

Result:

-
{
-  provider = "upcloud"
-  region = "de-fra1"
-  name = "web-01"
-  plan = "medium"
-}
-
-

Contracts (Schema Validation)

-

Define contracts to validate structure:

-
let ServerContract = {
-  name | String
-  plan | String | default = "small"
-  zone | String | default = "de-fra1"
-  cpu | Number | optional
-} in
-
-{
-  name = "my-server"
-  plan = "large"
-} | ServerContract
-
-

Three-File Pattern (Provisioning Standard)

-

The platform uses a standardized three-file pattern for all schemas:

-

1. contracts.ncl - Type Definitions

-

Defines the schema contracts:

-
# contracts.ncl
-{
-  Server = {
-    name | String
-    plan | String | default = "small"
-    zone | String | default = "de-fra1"
-    disk_size_gb | Number | default = 25
-    backup_enabled | Bool | default = false
-    role | | [ 'control, 'worker, 'standalone | ] | optional
-  }
-
-  Infrastructure = {
-    servers | Array Server
-    provider | String
-    environment | | [ 'development, 'staging, 'production | ]
-  }
-}
-
-

2. defaults.ncl - Default Values

-

Provides sensible defaults:

-
# defaults.ncl
-{
-  server = {
-    name = "unnamed-server"
-    plan = "small"
-    zone = "de-fra1"
-    disk_size_gb = 25
-    backup_enabled = false
-  }
-
-  infrastructure = {
-    servers = []
-    provider = "local"
-    environment = 'development
-  }
-}
-
-

3. main.ncl - Entry Point

-

Combines contracts and defaults, provides makers:

-
# main.ncl
-let contracts_lib = import "./contracts.ncl" in
-let defaults_lib = import "./defaults.ncl" in
-
-{
-  # Direct access to defaults (for inspection)
-  defaults = defaults_lib
-
-  # Convenience makers (90% of use cases)
-  make_server | not_exported = fun overrides =>
-    defaults_lib.server & overrides
-
-  make_infrastructure | not_exported = fun overrides =>
-    defaults_lib.infrastructure & overrides
-
-  # Default instances (bare defaults)
-  DefaultServer = defaults_lib.server
-  DefaultInfrastructure = defaults_lib.infrastructure
-}
-
-

Usage Example

-
# user-infra.ncl
-let infra_lib = import "provisioning/schemas/infrastructure/main.ncl" in
-
-infra_lib.make_infrastructure {
-  provider = "upcloud"
-  environment = 'production
-  servers = [
-    infra_lib.make_server {
-      name = "web-01"
-      plan = "medium"
-      backup_enabled = true
-    }
-    infra_lib.make_server {
-      name = "web-02"
-      plan = "medium"
-      backup_enabled = true
-    }
-  ]
-}
-
-

Hybrid Interface Pattern

-

Records can be used both as functions (makers) and as plain data:

-
let config_lib = import "./config.ncl" in
-
-# Use as function (with overrides)
-let custom_config = config_lib.make_server { name = "custom" } in
-
-# Use as plain data (defaults)
-let default_config = config_lib.DefaultServer in
-
-{
-  custom = custom_config
-  default = default_config
-}
-
-

Record Merging Strategies

-

Priority Merging (Default)

-
let base = { a = 1, b = 2 } in
-let override = { b = 3, c = 4 } in
-base & override
-# Result: { a = 1, b = 3, c = 4 }
-
-

Recursive Merging

-
let base = {
-  server = { cpu = 2, ram = 4 }
-} in
-
-let override = {
-  server = { ram = 8, disk = 100 }
-} in
-
-std.record.merge_all [base, override]
-# Result: { server = { cpu = 2, ram = 8, disk = 100 } }
-
-

Lazy Evaluation

-

Nickel evaluates expressions lazily, only when needed:

-
let expensive_computation = std.string.join " " ["a", "b", "c"] in
-
-{
-  # Only evaluated when accessed
-  computed_field = expensive_computation
-
-  # Conditional evaluation
-  conditional = if environment == 'production then
-    expensive_computation
-  else
-    "dev-value"
-}
-
-

Schema Organization

-

The platform organizes Nickel schemas by domain:

-
provisioning/schemas/
-├── main.ncl                  # Top-level entry point
-├── config/                   # Configuration schemas
-│   ├── settings/
-│   │   ├── main.ncl
-│   │   ├── contracts.ncl
-│   │   └── defaults.ncl
-│   └── defaults/
-│       ├── main.ncl
-│       ├── contracts.ncl
-│       └── defaults.ncl
-├── infrastructure/           # Infrastructure definitions
-│   ├── servers/
-│   ├── networks/
-│   └── storage/
-├── deployment/               # Deployment schemas
-├── services/                 # Service configurations
-├── operations/               # Operational schemas
-└── generator/                # Runtime schema generation
-
-

Type System

-

Primitive Types

-
{
-  string_field : String = "text"
-  number_field : Number = 42
-  bool_field : Bool = true
-}
-
-

Array Types

-
{
-  names : Array String = ["alice", "bob", "charlie"]
-  ports : Array Number = [80, 443, 8080]
-}
-
-

Enum Types

-
{
-  environment : | [ 'development, 'staging, 'production | ] = 'production
-  role : | [ 'control, 'worker, 'standalone | ] = 'worker
-}
-
-

Optional Fields

-
{
-  required_field : String = "value"
-  optional_field : String | optional
-}
-
-

Default Values

-
{
-  with_default : String | default = "default-value"
-}
-
-

Validation Patterns

-

Runtime Validation

-
let validate_plan = fun plan =>
-  if plan == "small" | | plan == "medium" | | plan == "large" then
-    plan
-  else
-    std.fail "Invalid plan: must be small, medium, or large"
-in
-
-{
-  plan = validate_plan "medium"
-}
-
-

Contract-Based Validation

-
let PlanContract = | [ 'small, 'medium, 'large | ] in
-
-{
-  plan | PlanContract = 'medium
-}
-
-

Real-World Examples

-

Simple Server Configuration

-
{
-  metadata = {
-    name = "demo-server"
-    provider = "upcloud"
-    environment = 'development
-  }
-
-  infrastructure = {
-    servers = [
-      {
-        name = "web-01"
-        plan = "medium"
-        zone = "de-fra1"
-        disk_size_gb = 50
-        backup_enabled = true
-        role = 'standalone
-      }
-    ]
-  }
-
-  services = {
-    taskservs = ["containerd", "docker"]
-  }
-}
-
-

Kubernetes Cluster Configuration

-
{
-  metadata = {
-    name = "k8s-prod"
-    provider = "upcloud"
-    environment = 'production
-  }
-
-  infrastructure = {
-    servers = [
-      {
-        name = "k8s-control-01"
-        plan = "medium"
-        role = 'control
-        zone = "de-fra1"
-        disk_size_gb = 50
-        backup_enabled = true
-      }
-      {
-        name = "k8s-worker-01"
-        plan = "large"
-        role = 'worker
-        zone = "de-fra1"
-        disk_size_gb = 100
-        backup_enabled = true
-      }
-      {
-        name = "k8s-worker-02"
-        plan = "large"
-        role = 'worker
-        zone = "de-fra1"
-        disk_size_gb = 100
-        backup_enabled = true
-      }
-    ]
-  }
-
-  services = {
-    taskservs = ["containerd", "etcd", "kubernetes", "cilium", "rook-ceph"]
-  }
-
-  kubernetes = {
-    version = "1.28.0"
-    pod_cidr = "10.244.0.0/16"
-    service_cidr = "10.96.0.0/12"
-    container_runtime = "containerd"
-    cri_socket = "/run/containerd/containerd.sock"
-  }
-}
-
-

Multi-Provider Batch Workflow

-
{
-  batch_workflow = {
-    operations = [
-      {
-        id = "aws-cluster"
-        provider = "aws"
-        region = "us-east-1"
-        servers = [
-          { name = "aws-web-01", plan = "t3.medium" }
-        ]
-      }
-      {
-        id = "upcloud-cluster"
-        provider = "upcloud"
-        region = "de-fra1"
-        servers = [
-          { name = "upcloud-web-01", plan = "medium" }
-        ]
-        dependencies = ["aws-cluster"]
-      }
-    ]
-    parallel_limit = 2
-  }
-}
-
-

Validation Workflow

-

Type-Check Schema

-
# Check syntax and types
-nickel typecheck infra/my-cluster.ncl
-
-# Export to JSON (validates during export)
-nickel export infra/my-cluster.ncl
-
-# Export to TOML (generated output only)
-nickel export --format toml infra/my-cluster.ncl > config.toml
-
-

Platform Validation

-
# Validate against platform contracts
-provisioning validate config --infra my-cluster
-
-# Verbose validation
-provisioning validate config --verbose
-
-

IDE Integration

-

Language Server (nickel-lang-lsp)

-

Install LSP for IDE support:

-
# Install LSP server
-cargo install nickel-lang-lsp
-
-# Configure your editor (VS Code example)
-# Install "Nickel" extension from marketplace
-
-

Features:

-
    -
  • Syntax highlighting
  • -
  • Type checking on save
  • -
  • Autocomplete
  • -
  • Hover documentation
  • -
  • Go to definition
  • -
-

VS Code Configuration

-
{
-  "nickel.lsp.command": "nickel-lang-lsp",
-  "nickel.lsp.args": ["--stdio"],
-  "nickel.format.onSave": true
-}
-
-

Common Patterns

-

Environment-Specific Configuration

-
let env_configs = {
-  development = {
-    plan = "small"
-    backup_enabled = false
-  }
-  production = {
-    plan = "large"
-    backup_enabled = true
-  }
-} in
-
-let environment = 'production in
-
-{
-  servers = [
-    env_configs.%{std.string.from_enum environment} & {
-      name = "server-01"
-    }
-  ]
-}
-
-

Configuration Composition

-
let base_server = {
-  zone = "de-fra1"
-  backup_enabled = false
-} in
-
-let prod_overrides = {
-  backup_enabled = true
-  disk_size_gb = 100
-} in
-
-{
-  servers = [
-    base_server & { name = "dev-01" }
-    base_server & prod_overrides & { name = "prod-01" }
-  ]
-}
-
-

Migration from TOML

-

TOML is ONLY for generated output. Source is always Nickel.

-
# Generate TOML from Nickel (if needed for external tools)
-nickel export --format toml infra/cluster.ncl > cluster.toml
-
-# NEVER edit cluster.toml directly - edit cluster.ncl instead
-
-

Best Practices

-
    -
  1. Use Three-File Pattern: Separate contracts, defaults, and main entry
  2. -
  3. Type Everything: Add type annotations for all fields
  4. -
  5. Validate Early: Run nickel typecheck before deployment
  6. -
  7. Use Makers: Leverage maker functions for composition
  8. -
  9. Document Contracts: Add comments explaining schema requirements
  10. -
  11. Avoid Duplication: Use record merging and defaults
  12. -
  13. Test Locally: Export and verify before deploying
  14. -
  15. Version Schemas: Track schema changes in version control
  16. -
-

Debugging

-

Type Errors

-
# Detailed type error messages
-nickel typecheck --color always infra/cluster.ncl
-
-

Schema Inspection

-
# Export to JSON for inspection
-nickel export infra/cluster.ncl | jq '.'
-
-# Check specific field
-nickel export infra/cluster.ncl | jq '.metadata'
-
-

Format Code

-
# Auto-format Nickel files
-nickel fmt infra/cluster.ncl
-
-# Check formatting without modifying
-nickel fmt --check infra/cluster.ncl
-
-

Next Steps

- -

Configuration System

-

The Provisioning platform uses a hierarchical configuration system with Nickel as the source of -truth for infrastructure definitions and TOML/YAML for application settings.

-

Configuration Hierarchy

-

Configuration is loaded in order of precedence (highest to lowest):

-
1. Runtime Arguments    - CLI flags (--config, --workspace, etc.)
-2. Environment Variables - PROVISIONING_* environment variables
-3. User Configuration   - ~/.config/provisioning/user_config.yaml
-4. Infrastructure Config - Nickel schemas in workspace/provisioning
-5. System Defaults      - provisioning/config/config.defaults.toml
-
-

Later sources override earlier ones, allowing flexible configuration management across environments.

-

Configuration Files

-

System Defaults

-

Located at provisioning/config/config.defaults.toml:

-
[general]
-log_level = "info"
-workspace_root = "./workspaces"
-
-[providers]
-default_provider = "local"
-
-[orchestrator]
-max_parallel_tasks = 4
-checkpoint_enabled = true
-
-

User Configuration

-

Located at ~/.config/provisioning/user_config.yaml:

-
general:
-  preferred_editor: nvim
-  default_workspace: production
-
-providers:
-  upcloud:
-    default_zone: fi-hel1
-  aws:
-    default_region: eu-west-1
-
-

Workspace Configuration

-

Nickel-based infrastructure configuration in workspace directories:

-
workspace/
-├── config/
-│   ├── main.ncl           # Workspace configuration
-│   ├── providers.ncl      # Provider definitions
-│   └── variables.ncl      # Workspace variables
-├── infra/
-│   └── servers.ncl        # Infrastructure definitions
-└── .workspace/
-    └── metadata.toml      # Workspace metadata
-
-

Environment Variables

-

All configuration can be overridden via environment variables:

-
export PROVISIONING_LOG_LEVEL=debug
-export PROVISIONING_WORKSPACE=production
-export PROVISIONING_PROVIDER=upcloud
-export PROVISIONING_DRY_RUN=true
-
-

Variable naming: PROVISIONING_<SECTION>_<KEY> (uppercase with underscores).

-

Configuration Accessors

-

The platform provides 476+ configuration accessors for programmatic access:

-
# Get configuration value
-provisioning config get general.log_level
-
-# Set configuration value (workspace-scoped)
-provisioning config set providers.default_provider upcloud
-
-# List all configuration
-provisioning config list
-
-# Validate configuration
-provisioning config validate
-
-

Profiles

-

Configuration supports profiles for different environments:

-
[profiles.development]
-log_level = "debug"
-dry_run = true
-
-[profiles.production]
-log_level = "warn"
-dry_run = false
-checkpoint_enabled = true
-
-

Activate profile:

-
provisioning --profile production deploy
-
-

Inheritance and Overrides

-

Workspace configurations inherit from system defaults:

-
# workspace/config/main.ncl
-let parent = import "../../provisioning/schemas/defaults.ncl" in
-parent & {
-  # Override specific values
-  general.log_level = "debug",
-  providers.default_provider = "aws",
-}
-
-

Secrets Management

-

Sensitive configuration is encrypted using SOPS/Age:

-
# Encrypt configuration
-sops --encrypt --age <public-key> secrets.yaml > secrets.enc.yaml
-
-# Decrypt and use
-provisioning deploy --secrets secrets.enc.yaml
-
-

Integration with SecretumVault for enterprise secrets management (see Secrets Management).

-

Configuration Validation

-

All Nickel-based configuration is validated before use:

-
# Validate workspace configuration
-provisioning config validate
-
-# Check schema compliance
-nickel export --format json workspace/config/main.ncl
-
-

Type-safety is mandatory - invalid configuration is rejected at load time.

-

Best Practices

-
    -
  1. Use Nickel for infrastructure - Type-safe, validated infrastructure definitions
  2. -
  3. Use TOML for application settings - Simple key-value configuration
  4. -
  5. Encrypt secrets - Never commit unencrypted credentials
  6. -
  7. Document overrides - Comment why values differ from defaults
  8. -
  9. Validate before deploy - Always run config validate before deployment
  10. -
  11. Version control - Track configuration changes in Git
  12. -
  13. Profile separation - Isolate development/staging/production configs
  14. -
-

Troubleshooting

-

Configuration Not Loading

-

Check precedence order:

-
# Show effective configuration
-provisioning config show --debug
-
-# Trace configuration loading
-PROVISIONING_LOG_LEVEL=trace provisioning config list
-
-

Schema Validation Failures

-
# Check Nickel syntax
-nickel typecheck workspace/config/main.ncl
-
-# Export and inspect
-nickel export workspace/config/main.ncl
-
-

Environment Variable Issues

-
# List all PROVISIONING_* variables
-env | grep PROVISIONING_
-
-# Clear all provisioning env vars
-unset $(env | grep PROVISIONING_ | cut -d= -f1 | xargs)
-
-

References

- -

Schemas Reference

-

Provisioning uses Nickel schemas for type-safe infrastructure definitions. This reference documents the schema organization, structure, and usage patterns.

-

Schema Organization

-

Schemas are organized in provisioning/schemas/:

-
provisioning/schemas/
-├── main.ncl                 # Root schema entry point
-├── lib/
-│   ├── contracts.ncl        # Type contracts and validators
-│   ├── functions.ncl        # Helper functions
-│   └── types.ncl            # Common type definitions
-├── config/
-│   ├── providers.ncl        # Provider configuration schemas
-│   ├── settings.ncl         # Platform settings schemas
-│   └── workspace.ncl        # Workspace configuration schemas
-├── infrastructure/
-│   ├── servers.ncl          # Server resource schemas
-│   ├── networks.ncl         # Network resource schemas
-│   └── storage.ncl          # Storage resource schemas
-├── operations/
-│   ├── deployment.ncl       # Deployment workflow schemas
-│   └── lifecycle.ncl        # Resource lifecycle schemas
-├── services/
-│   ├── kubernetes.ncl       # Kubernetes schemas
-│   └── databases.ncl        # Database schemas
-└── integrations/
-    ├── cloud_providers.ncl  # Cloud provider integrations
-    └── external_services.ncl # External service integrations
-
-

Core Contracts

-

Server Contract

-
let Server = {
-  name
-    | doc "Server identifier (must be unique)"
-    | String,
-
-  plan
-    | doc "Server size (small, medium, large, xlarge)"
-    | | [ 'small, 'medium, 'large, 'xlarge | ],
-
-  provider
-    | doc "Cloud provider (upcloud, aws, local)"
-    | | [ 'upcloud, 'aws, 'local | ],
-
-  zone
-    | doc "Availability zone"
-    | String
-    | optional,
-
-  ip_address
-    | doc "Public IP address"
-    | String
-    | optional,
-
-  storage
-    | doc "Storage configuration"
-    | Array StorageConfig
-    | default = [],
-
-  metadata
-    | doc "Custom metadata tags"
-    | {_ : String}
-    | default = {},
-}
-
-

Network Contract

-
let Network = {
-  name
-    | doc "Network identifier"
-    | String,
-
-  cidr
-    | doc "CIDR block (e.g., 10.0.0.0/16)"
-    | String
-    | std.string.is_match_regex "^([0-9]{1,3}\\.){3}[0-9]{1,3}/[0-9]{1,2}$",
-
-  subnets
-    | doc "Subnet definitions"
-    | Array Subnet,
-
-  routing
-    | doc "Routing configuration"
-    | RoutingConfig
-    | optional,
-}
-
-

Storage Contract

-
let StorageConfig = {
-  size_gb
-    | doc "Storage size in GB"
-    | Number
-    | std.number.greater 0,
-
-  type
-    | doc "Storage type"
-    | | [ 'ssd, 'hdd, 'nvme | ],
-
-  mount_point
-    | doc "Mount path"
-    | String
-    | optional,
-
-  encrypted
-    | doc "Enable encryption"
-    | Bool
-    | default = false,
-}
-
-

Workspace Schema

-

Workspace configuration schema:

-
let WorkspaceConfig = {
-  name
-    | doc "Workspace identifier"
-    | String,
-
-  environment
-    | doc "Environment type"
-    | | [ 'development, 'staging, 'production | ],
-
-  providers
-    | doc "Enabled providers"
-    | Array | [ 'upcloud, 'aws, 'local | ]
-    | default = ['local],
-
-  infrastructure
-    | doc "Infrastructure definitions"
-    | {
-        servers | Array Server | default = [],
-        networks | Array Network | default = [],
-        storage | Array StorageConfig | default = [],
-      },
-
-  settings
-    | doc "Workspace-specific settings"
-    | {_ : _}
-    | default = {},
-}
-
-

Provider Schemas

-

UpCloud Provider

-
let UpCloudConfig = {
-  username
-    | doc "UpCloud username"
-    | String,
-
-  password
-    | doc "UpCloud password (encrypted)"
-    | String,
-
-  default_zone
-    | doc "Default zone"
-    | | [ 'fi-hel1, 'fi-hel2, 'de-fra1, 'uk-lon1, 'us-chi1, 'us-sjo1 | ]
-    | default = 'fi-hel1,
-
-  timeout_seconds
-    | doc "API timeout"
-    | Number
-    | default = 300,
-}
-
-

AWS Provider

-
let AWSConfig = {
-  access_key_id
-    | doc "AWS access key"
-    | String,
-
-  secret_access_key
-    | doc "AWS secret key (encrypted)"
-    | String,
-
-  default_region
-    | doc "Default AWS region"
-    | String
-    | default = "eu-west-1",
-
-  assume_role_arn
-    | doc "IAM role ARN"
-    | String
-    | optional,
-}
-
-

Service Schemas

-

Kubernetes Schema

-
let KubernetesCluster = {
-  name
-    | doc "Cluster name"
-    | String,
-
-  version
-    | doc "Kubernetes version"
-    | String
-    | std.string.is_match_regex "^v[0-9]+\\.[0-9]+\\.[0-9]+$",
-
-  control_plane
-    | doc "Control plane configuration"
-    | {
-        nodes | Number | std.number.greater 0,
-        plan | | [ 'small, 'medium, 'large | ],
-      },
-
-  workers
-    | doc "Worker node pools"
-    | Array NodePool,
-
-  networking
-    | doc "Network configuration"
-    | {
-        pod_cidr | String,
-        service_cidr | String,
-        cni | | [ 'calico, 'cilium, 'flannel | ] | default = 'cilium,
-      },
-
-  addons
-    | doc "Cluster addons"
-    | Array | [ 'metrics-server, 'ingress-nginx, 'cert-manager | ]
-    | default = [],
-}
-
-

Validation Functions

-

Custom validation functions in lib/contracts.ncl:

-
let is_valid_hostname = fun name =>
-  std.string.is_match_regex "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$" name
-in
-
-let is_valid_port = fun port =>
-  std.number.is_integer port && port >= 1 && port <= 65535
-in
-
-let is_valid_email = fun email =>
-  std.string.is_match_regex "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$" email
-in
-
-

Merging and Composition

-

Schemas support composition through record merging:

-
let base_server = {
-  plan = 'medium,
-  provider = 'upcloud,
-  storage = [],
-}
-
-let production_server = base_server & {
-  plan = 'large,
-  storage = [{size_gb = 100, type = 'ssd}],
-}
-
-

Contract Enforcement

-

Type checking is enforced at load time:

-
# Typecheck schema
-nickel typecheck provisioning/schemas/main.ncl
-
-# Export with validation
-nickel export --format json workspace/infra/servers.ncl
-
-

Invalid configurations are rejected before deployment.

-

Best Practices

-
    -
  1. Define contracts first - Start with type contracts before implementation
  2. -
  3. Use enums for choices - Leverage | [ 'option1, 'option2 | ] for fixed sets
  4. -
  5. Document everything - Use |doc "description" annotations
  6. -
  7. Validate early - Run nickel typecheck before deployment
  8. -
  9. Compose, don’t duplicate - Use record merging for common patterns
  10. -
  11. Version schemas - Track schema changes alongside infrastructure
  12. -
  13. Test contracts - Validate edge cases and constraints
  14. -
-

References

- -

Providers

-

Providers are abstraction layers for interacting with cloud platforms and local infrastructure. -Provisioning supports multiple providers through a unified interface.

-

Available Providers

-

UpCloud Provider

-

Production-ready cloud provider for European infrastructure.

-

Configuration:

-
{
-  providers.upcloud = {
-    username = "your-username",
-    password = std.secret "UPCLOUD_PASSWORD",
-    default_zone = 'fi-hel1,
-    timeout_seconds = 300,
-  }
-}
-
-

Supported zones:

-
    -
  • fi-hel1, fi-hel2 - Helsinki, Finland
  • -
  • de-fra1 - Frankfurt, Germany
  • -
  • uk-lon1 - London, UK
  • -
  • us-chi1 - Chicago, USA
  • -
  • us-sjo1 - San Jose, USA
  • -
-

Resources: Servers, networks, storage, firewalls, load balancers

-

AWS Provider

-

Amazon Web Services integration for global cloud infrastructure.

-

Configuration:

-
{
-  providers.aws = {
-    access_key_id = std.secret "AWS_ACCESS_KEY_ID",
-    secret_access_key = std.secret "AWS_SECRET_ACCESS_KEY",
-    default_region = "eu-west-1",
-  }
-}
-
-

Resources: EC2, VPCs, EBS, security groups, RDS, S3

-

Local Provider

-

Local infrastructure for development and testing.

-

Configuration:

-
{
-  providers.local = {
-    backend = 'libvirt,  # or 'docker, 'podman
-    storage_pool = "/var/lib/libvirt/images",
-  }
-}
-
-

Backends: libvirt (KVM/QEMU), docker, podman

-

Multi-Cloud Deployments

-

Deploy infrastructure across multiple providers:

-
{
-  servers = [
-    {name = "web-frontend", provider = 'upcloud, zone = "fi-hel1", plan = 'medium},
-    {name = "api-backend", provider = 'aws, zone = "eu-west-1a", plan = 't3.large},
-  ]
-}
-
-

Provider Abstraction

-

Abstract resource definitions work across providers:

-
let server_config = fun name provider => {
-  name = name,
-  provider = provider,
-  plan = 'medium,  # Automatically translated per provider
-  storage = [{size_gb = 50, type = 'ssd}],
-}
-
-

Plan translation:

-
- - - - -
AbstractUpCloudAWSLocal
small1xCPU-1GBt3.micro1 vCPU
medium2xCPU-4GBt3.medium2 vCPU
large4xCPU-8GBt3.large4 vCPU
xlarge8xCPU-16GBt3.xlarge8 vCPU
-
-

Best Practices

-
    -
  1. Use abstract plans - Avoid provider-specific instance types
  2. -
  3. Encrypt credentials - Always use encrypted secrets for API keys
  4. -
  5. Test locally first - Validate configurations with local provider
  6. -
  7. Document provider choices - Comment why specific providers are used
  8. -
  9. Monitor costs - Track cloud provider spending
  10. -
-

References

- -

Task Services

-

Task services are installable infrastructure components that provide specific functionality. -Provisioning includes 30+ task services for databases, orchestration, monitoring, and more.

-

Categories

-

Kubernetes & Container Orchestration

-

kubernetes - Complete Kubernetes cluster deployment

-
    -
  • Control plane setup
  • -
  • Worker node pools
  • -
  • CNI configuration (Calico, Cilium, Flannel)
  • -
  • Addon management (metrics-server, ingress-nginx, cert-manager)
  • -
-

containerd - Container runtime configuration

-
    -
  • Systemd integration
  • -
  • Storage driver configuration
  • -
  • Runtime class support
  • -
-

docker - Docker engine installation

-
    -
  • Docker Compose integration
  • -
  • Registry configuration
  • -
-

Databases

-

postgresql - PostgreSQL database server

-
    -
  • Replication setup
  • -
  • Backup automation
  • -
  • Performance tuning
  • -
-

mysql - MySQL/MariaDB deployment

-
    -
  • Cluster configuration
  • -
  • Backup strategies
  • -
-

mongodb - MongoDB database

-
    -
  • Replica sets
  • -
  • Sharding configuration
  • -
-

redis - Redis in-memory store

-
    -
  • Persistence configuration
  • -
  • Cluster mode
  • -
-

Storage

-

rook-ceph - Cloud-native storage orchestrator

-
    -
  • Block storage (RBD)
  • -
  • Object storage (S3-compatible)
  • -
  • Shared filesystem (CephFS)
  • -
-

minio - S3-compatible object storage

-
    -
  • Distributed mode
  • -
  • Versioning and lifecycle policies
  • -
-

Monitoring & Observability

-

prometheus - Metrics collection and alerting

-
    -
  • Service discovery
  • -
  • Alerting rules
  • -
  • Long-term storage
  • -
-

grafana - Metrics visualization

-
    -
  • Dashboard provisioning
  • -
  • Data source configuration
  • -
-

loki - Log aggregation system

-
    -
  • Log collection
  • -
  • Query language
  • -
-

Networking

-

cilium - eBPF-based networking and security

-
    -
  • Network policies
  • -
  • Load balancing
  • -
  • Service mesh capabilities
  • -
-

calico - Network policy engine

-
    -
  • BGP networking
  • -
  • IP-in-IP tunneling
  • -
-

nginx - Web server and reverse proxy

-
    -
  • Load balancing
  • -
  • TLS termination
  • -
-

Security

-

vault - Secrets management (HashiCorp Vault)

-
    -
  • Secret storage
  • -
  • Dynamic secrets
  • -
  • Encryption as a service
  • -
-

cert-manager - TLS certificate automation

-
    -
  • Let’s Encrypt integration
  • -
  • Certificate renewal
  • -
-

Task Service Definition

-

Task services are defined in provisioning/extensions/taskservs/:

-
taskservs/
-└── kubernetes/
-    ├── service.ncl           # Service schema
-    ├── install.nu            # Installation script
-    ├── configure.nu          # Configuration script
-    ├── health-check.nu       # Health validation
-    └── README.md
-
-

Using Task Services

-

Installation

-
{
-  task_services = [
-    {
-      name = "kubernetes",
-      version = "v1.28.0",
-      config = {
-        control_plane = {nodes = 3, plan = 'medium},
-        workers = [{name = "pool-1", nodes = 3, plan = 'large}],
-        networking = {cni = 'cilium},
-      }
-    },
-    {
-      name = "prometheus",
-      version = "latest",
-      config = {retention = "30d", storage_size_gb = 100}
-    }
-  ]
-}
-
-

CLI Commands

-
# List available task services
-provisioning taskserv list
-
-# Show task service details
-provisioning taskserv show kubernetes
-
-# Install task service
-provisioning taskserv install kubernetes
-
-# Check task service health
-provisioning taskserv health kubernetes
-
-# Uninstall task service
-provisioning taskserv uninstall kubernetes
-
-

Custom Task Services

-

Create custom task services:

-
provisioning/extensions/taskservs/my-service/
-├── service.ncl           # Service definition
-├── install.nu            # Installation logic
-├── configure.nu          # Configuration logic
-├── health-check.nu       # Health checks
-└── README.md
-
-

service.ncl schema:

-
{
-  name = "my-service",
-  version = "1.0.0",
-  description = "Custom service description",
-  dependencies = ["kubernetes"],  # Optional dependencies
-  config_schema = {
-    port | Number | default = 8080,
-    replicas | Number | default = 3,
-  }
-}
-
-

install.nu implementation:

-
export def "taskserv install" [config: record] {
-  # Installation logic
-  print $"Installing ($config.name)..."
-
-  # Deploy resources
-  kubectl apply -f deployment.yaml
-
-  {status: "installed"}
-}
-
-

Task Service Lifecycle

-
    -
  1. Validation - Check dependencies and configuration
  2. -
  3. Installation - Execute install script
  4. -
  5. Configuration - Apply service configuration
  6. -
  7. Health Check - Verify service is running
  8. -
  9. Ready - Service available for use
  10. -
-

Dependencies

-

Task services can declare dependencies:

-
{
-  name = "grafana",
-  dependencies = ["prometheus"],  # Installed first
-}
-
-

Provisioning automatically resolves dependency order.

-

Health Checks

-

Each task service provides health validation:

-
export def "taskserv health" [] {
-  let pods = (kubectl get pods -l app=my-service -o json | from json)
-
-  if ($pods.items | all | { | p $p.status.phase == "Running"}) {
-    {status: "healthy"}
-  } else {
-    {status: "unhealthy", reason: "pods not running"}
-  }
-}
-
-

Best Practices

-
    -
  1. Define schemas - Use Nickel schemas for task service configuration
  2. -
  3. Declare dependencies - Explicit dependency declaration
  4. -
  5. Idempotent installs - Installation should be repeatable
  6. -
  7. Health checks - Implement comprehensive health validation
  8. -
  9. Version pinning - Specify exact versions for reproducibility
  10. -
  11. Document configuration - Provide clear configuration examples
  12. -
-

References

- -

Clusters

-

Clusters are coordinated groups of services deployed together. Provisioning provides cluster definitions for common deployment patterns.

-

Available Clusters

-

Web Cluster

-

Production-ready web application deployment with load balancing, TLS, and monitoring.

-

Components:

-
    -
  • Nginx load balancer
  • -
  • Application servers (configurable count)
  • -
  • PostgreSQL database
  • -
  • Redis cache
  • -
  • Prometheus monitoring
  • -
  • Let’s Encrypt TLS certificates
  • -
-

Configuration:

-
{
-  clusters = [{
-    name = "web-production",
-    type = 'web,
-    config = {
-      app_servers = 3,
-      load_balancer = {
-        public_ip = true,
-        tls_enabled = true,
-        domain = "example.com"
-      },
-      database = {
-        size = 'medium,
-        replicas = 2,
-        backup_enabled = true
-      },
-      cache = {
-        size = 'small,
-        persistence = true
-      }
-    }
-  }]
-}
-
-

OCI Registry Cluster

-

Private container registry with S3-compatible storage and authentication.

-

Components:

-
    -
  • Harbor registry
  • -
  • MinIO object storage
  • -
  • PostgreSQL database
  • -
  • Redis cache
  • -
  • TLS termination
  • -
-

Configuration:

-
{
-  clusters = [{
-    name = "registry-private",
-    type = 'oci_registry,
-    config = {
-      domain = "registry.example.com",
-      storage = {
-        backend = 'minio,
-        size_gb = 500,
-        replicas = 3
-      },
-      authentication = {
-        method = 'ldap,  # or 'database, 'oidc
-        admin_password = std.secret "REGISTRY_ADMIN_PASSWORD"
-      }
-    }
-  }]
-}
-
-

Kubernetes Cluster

-

Multi-node Kubernetes cluster with networking, storage, and monitoring.

-

Components:

-
    -
  • Control plane nodes
  • -
  • Worker node pools
  • -
  • Cilium CNI
  • -
  • Rook-Ceph storage
  • -
  • Metrics server
  • -
  • Ingress controller
  • -
-

Configuration:

-
{
-  clusters = [{
-    name = "k8s-production",
-    type = 'kubernetes,
-    config = {
-      control_plane = {
-        nodes = 3,
-        plan = 'medium,
-        high_availability = true
-      },
-      node_pools = [
-        {
-          name = "general",
-          nodes = 5,
-          plan = 'large,
-          labels = {workload = "general"}
-        },
-        {
-          name = "gpu",
-          nodes = 2,
-          plan = 'xlarge,
-          labels = {workload = "ml"}
-        }
-      ],
-      networking = {
-        cni = 'cilium,
-        pod_cidr = "10.42.0.0/16",
-        service_cidr = "10.43.0.0/16"
-      },
-      storage = {
-        provider = 'rook-ceph,
-        default_storage_class = "ceph-block"
-      }
-    }
-  }]
-}
-
-

Cluster Deployment

-

CLI Commands

-
# List available cluster types
-provisioning cluster types
-
-# Show cluster configuration template
-provisioning cluster template web
-
-# Deploy cluster
-provisioning cluster deploy web-production
-
-# Check cluster health
-provisioning cluster health web-production
-
-# Scale cluster
-provisioning cluster scale web-production --app-servers 5
-
-# Destroy cluster
-provisioning cluster destroy web-production
-
-

Deployment Lifecycle

-
    -
  1. Validation - Validate cluster configuration
  2. -
  3. Infrastructure - Provision servers, networks, storage
  4. -
  5. Services - Install and configure task services
  6. -
  7. Integration - Connect services together
  8. -
  9. Health Check - Verify cluster health
  10. -
  11. Ready - Cluster operational
  12. -
-

Cluster Orchestration

-

Clusters use dependency graphs for orchestration:

-
Web Cluster Dependency Graph:
-
-servers ──┐
-          ├──> database ──┐
-networks ─┘               ├──> app_servers ──> load_balancer
-                          │
-                          ├──> cache ──────────┘
-                          │
-                          └──> monitoring
-
-

Services are deployed in dependency order with parallel execution where possible.

-

Custom Cluster Definitions

-

Create custom cluster types:

-
provisioning/extensions/clusters/
-└── my-cluster/
-    ├── cluster.ncl           # Cluster definition
-    ├── deploy.nu             # Deployment script
-    ├── health-check.nu       # Health validation
-    └── README.md
-
-

cluster.ncl schema:

-
{
-  name = "my-cluster",
-  version = "1.0.0",
-  description = "Custom cluster type",
-  components = {
-    servers = [{name = "app", count = 3, plan = 'medium}],
-    services = ["nginx", "postgresql", "redis"],
-  },
-  config_schema = {
-    domain | String,
-    replicas | Number | default = 3,
-  }
-}
-
-

Cluster Management

-

Scaling

-

Scale cluster components:

-
# Scale application servers
-provisioning cluster scale web-production --component app_servers --count 5
-
-# Scale database replicas
-provisioning cluster scale web-production --component database --replicas 3
-
-

Updates

-

Rolling updates without downtime:

-
# Update application version
-provisioning cluster update web-production --app-version 2.0.0
-
-# Update infrastructure (e.g., server plans)
-provisioning cluster update web-production --plan large
-
-

Backup and Recovery

-
# Create cluster backup
-provisioning cluster backup web-production
-
-# Restore from backup
-provisioning cluster restore web-production --backup 2024-01-15-snapshot
-
-# List backups
-provisioning cluster backups web-production
-
-

Monitoring

-

Cluster health monitoring:

-
# Overall cluster health
-provisioning cluster health web-production
-
-# Component health
-provisioning cluster health web-production --component database
-
-# Metrics
-provisioning cluster metrics web-production
-
-

Health checks validate:

-
    -
  • All services running
  • -
  • Network connectivity
  • -
  • Storage availability
  • -
  • Resource utilization
  • -
-

Best Practices

-
    -
  1. Use predefined clusters - Leverage built-in cluster types
  2. -
  3. Define dependencies - Explicit service dependencies
  4. -
  5. Implement health checks - Comprehensive validation
  6. -
  7. Plan for scaling - Design clusters for horizontal scaling
  8. -
  9. Automate backups - Regular backup schedules
  10. -
  11. Monitor resources - Track resource utilization
  12. -
  13. Test disaster recovery - Validate backup/restore procedures
  14. -
-

References

- -

Batch Workflows

-

Batch workflows orchestrate complex multi-step operations across multiple clouds and services with -dependency resolution, parallel execution, and checkpoint recovery.

-

Overview

-

Batch workflows enable:

-
    -
  • Multi-cloud infrastructure orchestration
  • -
  • Complex deployment pipelines
  • -
  • Dependency-driven execution
  • -
  • Parallel task execution
  • -
  • Checkpoint and recovery
  • -
  • Rollback on failures
  • -
-

Workflow Definition

-

Workflows are defined in Nickel:

-
{
-  workflows = [{
-    name = "multi-cloud-deployment",
-    description = "Deploy application across UpCloud and AWS",
-    steps = [
-      {
-        name = "provision-upcloud",
-        type = 'provision,
-        provider = 'upcloud,
-        resources = {
-          servers = [{name = "web-eu", plan = 'medium, zone = "fi-hel1"}]
-        }
-      },
-      {
-        name = "provision-aws",
-        type = 'provision,
-        provider = 'aws,
-        resources = {
-          servers = [{name = "web-us", plan = 't3.medium, zone = "us-east-1a"}]
-        }
-      },
-      {
-        name = "deploy-application",
-        type = 'task,
-        depends_on = ["provision-upcloud", "provision-aws"],
-        tasks = ["install-kubernetes", "deploy-app"]
-      },
-      {
-        name = "configure-dns",
-        type = 'configure,
-        depends_on = ["deploy-application"],
-        config = {
-          records = [
-            {name = "eu.example.com", target = "web-eu"},
-            {name = "us.example.com", target = "web-us"}
-          ]
-        }
-      }
-    ],
-    rollback_on_failure = true,
-    checkpoint_enabled = true
-  }]
-}
-
-

Dependency Resolution

-

Workflows automatically resolve dependencies:

-
Execution Graph:
-
-provision-upcloud ──┐
-                    ├──> deploy-application ──> configure-dns
-provision-aws ──────┘
-
-

Steps provision-upcloud and provision-aws run in parallel. deploy-application waits for both to complete.

-

Step Types

-

Provision Steps

-

Create infrastructure resources:

-
{
-  name = "create-servers",
-  type = 'provision,
-  provider = 'upcloud,
-  resources = {
-    servers = [...],
-    networks = [...],
-    storage = [...]
-  }
-}
-
-

Task Steps

-

Execute task services:

-
{
-  name = "install-k8s",
-  type = 'task,
-  tasks = ["kubernetes", "helm", "monitoring"]
-}
-
-

Configure Steps

-

Apply configuration changes:

-
{
-  name = "setup-networking",
-  type = 'configure,
-  config = {
-    firewalls = [...],
-    routes = [...],
-    dns = [...]
-  }
-}
-
-

Validate Steps

-

Verify conditions before proceeding:

-
{
-  name = "health-check",
-  type = 'validate,
-  checks = [
-    {type = 'http, url = " [https://app.example.com",](https://app.example.com",) expected_status = 200},
-    {type = 'command, command = "kubectl get nodes", expected_output = "Ready"}
-  ]
-}
-
-

Execution Control

-

Parallel Execution

-

Steps without dependencies run in parallel:

-
steps = [
-  {name = "provision-eu", ...},  # Runs in parallel
-  {name = "provision-us", ...},  # Runs in parallel
-  {name = "provision-asia", ...} # Runs in parallel
-]
-
-

Configure parallelism:

-
{
-  max_parallel_tasks = 4,  # Max concurrent steps
-  timeout_seconds = 3600   # Step timeout
-}
-
-

Conditional Execution

-

Execute steps based on conditions:

-
{
-  name = "scale-up",
-  type = 'task,
-  condition = {
-    type = 'expression,
-    expression = "cpu_usage > 80"
-  }
-}
-
-

Retry Logic

-

Automatically retry failed steps:

-
{
-  name = "deploy-app",
-  type = 'task,
-  retry = {
-    max_attempts = 3,
-    backoff = 'exponential,  # or 'linear, 'constant
-    initial_delay_seconds = 10
-  }
-}
-
-

Checkpoint and Recovery

-

Checkpointing

-

Workflows automatically checkpoint state:

-
# Enable checkpointing
-provisioning workflow run multi-cloud --checkpoint
-
-# Checkpoint saved at each step completion
-
-

Recovery

-

Resume from last successful checkpoint:

-
# Workflow failed at step 3
-# Resume from checkpoint
-provisioning workflow resume multi-cloud --from-checkpoint latest
-
-# Resume from specific checkpoint
-provisioning workflow resume multi-cloud --checkpoint-id abc123
-
-

Rollback

-

Automatic Rollback

-

Rollback on failure:

-
{
-  rollback_on_failure = true,
-  rollback_steps = [
-    {name = "destroy-resources", type = 'destroy},
-    {name = "restore-config", type = 'restore}
-  ]
-}
-
-

Manual Rollback

-
# Rollback to previous state
-provisioning workflow rollback multi-cloud
-
-# Rollback to specific checkpoint
-provisioning workflow rollback multi-cloud --checkpoint-id abc123
-
-

Workflow Management

-

CLI Commands

-
# List workflows
-provisioning workflow list
-
-# Show workflow details
-provisioning workflow show multi-cloud
-
-# Run workflow
-provisioning workflow run multi-cloud
-
-# Check workflow status
-provisioning workflow status multi-cloud
-
-# View workflow logs
-provisioning workflow logs multi-cloud
-
-# Cancel running workflow
-provisioning workflow cancel multi-cloud
-
-

Workflow State

-

Workflows track execution state:

-
    -
  • pending - Not yet started
  • -
  • running - Currently executing
  • -
  • completed - Successfully finished
  • -
  • failed - Execution failed
  • -
  • rolling_back - Performing rollback
  • -
  • cancelled - Manually cancelled
  • -
-

Advanced Features

-

Dynamic Workflows

-

Generate workflows programmatically:

-
let regions = ["fi-hel1", "de-fra1", "uk-lon1"] in
-{
-  steps = std.array.map (fun region => {
-    name = "provision-" ++ region,
-    type = 'provision,
-    resources = {servers = [{zone = region, ...}]}
-  }) regions
-}
-
-

Workflow Templates

-

Reusable workflow templates:

-
let DeploymentTemplate = fun app_name regions => {
-  name = "deploy-" ++ app_name,
-  steps = std.array.map (fun region => {
-    name = "deploy-" ++ region,
-    type = 'task,
-    tasks = ["deploy-app"],
-    config = {app_name = app_name, region = region}
-  }) regions
-}
-
-# Use template
-{
-  workflows = [
-    DeploymentTemplate "frontend" ["eu", "us"],
-    DeploymentTemplate "backend" ["eu", "us", "asia"]
-  ]
-}
-
-

Notifications

-

Send notifications on workflow events:

-
{
-  notifications = {
-    on_success = {
-      type = 'slack,
-      webhook_url = std.secret "SLACK_WEBHOOK",
-      message = "Deployment completed successfully"
-    },
-    on_failure = {
-      type = 'email,
-      to = ["[ops@example.com](mailto:ops@example.com)"],
-      subject = "Workflow failed"
-    }
-  }
-}
-
-

Best Practices

-
    -
  1. Define dependencies explicitly - Clear dependency graph
  2. -
  3. Enable checkpointing - Critical for long-running workflows
  4. -
  5. Implement rollback - Always have rollback strategy
  6. -
  7. Use validation steps - Verify state before proceeding
  8. -
  9. Configure retries - Handle transient failures
  10. -
  11. Monitor execution - Track workflow progress
  12. -
  13. Test workflows - Validate with dry-run mode
  14. -
-

Troubleshooting

-

Workflow Stuck

-
# Check workflow status
-provisioning workflow status <workflow> --verbose
-
-# View logs
-provisioning workflow logs <workflow> --tail 100
-
-# Cancel and restart
-provisioning workflow cancel <workflow>
-provisioning workflow run <workflow>
-
-

Step Failures

-
# View failed step details
-provisioning workflow show <workflow> --step <step-name>
-
-# Retry failed step
-provisioning workflow retry <workflow> --step <step-name>
-
-# Skip failed step
-provisioning workflow skip <workflow> --step <step-name>
-
-

References

- -

Version Management

-

Nickel-based version management for infrastructure components, providers, and task services ensures consistent, reproducible deployments.

-

Overview

-

Version management in Provisioning:

-
    -
  • Nickel schemas define version constraints
  • -
  • Semantic versioning (semver) support
  • -
  • Version locking for reproducibility
  • -
  • Compatibility validation
  • -
  • Update strategies
  • -
-

Version Constraints

-

Define version requirements in Nickel:

-
{
-  task_services = [
-    {
-      name = "kubernetes",
-      version = ">=1.28.0, <1.30.0",  # Range constraint
-    },
-    {
-      name = "prometheus",
-      version = "~2.45.0",  # Patch versions allowed
-    },
-    {
-      name = "grafana",
-      version = "^10.0.0",  # Minor versions allowed
-    },
-    {
-      name = "nginx",
-      version = "1.25.3",  # Exact version
-    }
-  ]
-}
-
-

Constraint Operators

-
- - - - - - - - -
OperatorMeaningExampleMatches
=Exact version=1.28.01.28.0 only
>=Greater or equal>=1.28.01.28.0, 1.29.0, 2.0.0
<=Less or equal<=1.30.01.28.0, 1.30.0
>Greater than>1.28.01.29.0, 2.0.0
<Less than<1.30.01.28.0, 1.29.0
~Patch updates~1.28.01.28.x
^Minor updates^1.28.01.x.x
,AND constraint>=1.28, <1.301.28.x, 1.29.x
-
-

Version Locking

-

Generate lock file for reproducible deployments:

-
# Generate lock file
-provisioning version lock
-
-# Creates versions.lock.ncl with exact versions
-
-

versions.lock.ncl:

-
{
-  task_services = {
-    kubernetes = "1.28.3",
-    prometheus = "2.45.2",
-    grafana = "10.0.5",
-    nginx = "1.25.3"
-  },
-  providers = {
-    upcloud = "1.2.0",
-    aws = "3.5.1"
-  }
-}
-
-

Use lock file:

-
let locked = import "versions.lock.ncl" in
-{
-  task_services = [
-    {name = "kubernetes", version = locked.task_services.kubernetes}
-  ]
-}
-
-

Version Updates

-

Check for Updates

-
# Check available updates
-provisioning version check
-
-# Show outdated components
-provisioning version outdated
-
-

Output:

-
Component    Current  Latest   Update Available
-kubernetes   1.28.0   1.29.2   Minor update
-prometheus   2.45.0   2.47.0   Minor update
-grafana      10.0.0   11.0.0   Major update (breaking)
-
-

Update Strategies

-

Conservative (patch only):

-
{
-  update_policy = 'conservative,  # Only patch updates
-}
-
-

Moderate (minor updates):

-
{
-  update_policy = 'moderate,  # Patch + minor updates
-}
-
-

Aggressive (all updates):

-
{
-  update_policy = 'aggressive,  # All updates including major
-}
-
-

Performing Updates

-
# Update all components (respecting constraints)
-provisioning version update
-
-# Update specific component
-provisioning version update kubernetes
-
-# Update to specific version
-provisioning version update kubernetes --version 1.29.0
-
-# Dry-run (show what would update)
-provisioning version update --dry-run
-
-

Compatibility Validation

-

Validate version compatibility:

-
# Check compatibility
-provisioning version validate
-
-# Check specific component
-provisioning version validate kubernetes
-
-

Compatibility rules defined in schemas:

-
{
-  name = "grafana",
-  version = "10.0.0",
-  compatibility = {
-    prometheus = ">=2.40.0",  # Requires Prometheus 2.40+
-    kubernetes = ">=1.24.0"   # Requires Kubernetes 1.24+
-  }
-}
-
-

Version Resolution

-

When multiple constraints conflict, resolution strategy:

-
    -
  1. Exact version - Highest priority
  2. -
  3. Compatibility constraints - From dependencies
  4. -
  5. User constraints - From configuration
  6. -
  7. Latest compatible - Within constraints
  8. -
-

Example resolution:

-
# Component A requires: kubernetes >=1.28.0
-# Component B requires: kubernetes <1.30.0
-# User specifies: kubernetes ^1.28.0
-
-# Resolved: kubernetes 1.29.x (latest compatible)
-
-

Pinning Versions

-

Pin critical components:

-
{
-  task_services = [
-    {
-      name = "kubernetes",
-      version = "1.28.3",
-      pinned = true  # Never auto-update
-    }
-  ]
-}
-
-

Version Rollback

-

Rollback to previous versions:

-
# Show version history
-provisioning version history
-
-# Rollback to previous version
-provisioning version rollback kubernetes
-
-# Rollback to specific version
-provisioning version rollback kubernetes --version 1.28.0
-
-

Best Practices

-
    -
  1. Use version constraints - Avoid latest tag
  2. -
  3. Lock versions - Generate and commit lock files
  4. -
  5. Test updates - Validate in non-production first
  6. -
  7. Pin critical components - Prevent unexpected updates
  8. -
  9. Document compatibility - Specify version requirements
  10. -
  11. Monitor updates - Track new releases
  12. -
  13. Gradual rollout - Update incrementally
  14. -
-

Version Metadata

-

Access version information programmatically:

-
# Show component versions
-provisioning version list
-
-# Export versions to JSON
-provisioning version export --format json
-
-# Compare versions
-provisioning version compare <component> <version1> <version2>
-
-

Integration with CI/CD

-
# .gitlab-ci.yml example
-deploy:
-  script:
-    - provisioning version lock --verify  # Verify lock file
-    - provisioning version validate       # Check compatibility
-    - provisioning deploy                 # Deploy with locked versions
-
-

Troubleshooting

-

Version Conflicts

-
# Show dependency tree
-provisioning version tree
-
-# Identify conflicting constraints
-provisioning version conflicts
-
-

Update Failures

-
# Check why update failed
-provisioning version update kubernetes --verbose
-
-# Force update (override constraints)
-provisioning version update kubernetes --force --version 1.30.0
-
-

References

- -

- Provisioning Logo -

-

- Provisioning -

-

Platform Features

-

Complete documentation for the 12 core Provisioning platform capabilities -enabling enterprise infrastructure as code across multiple clouds.

-

Overview

-

Provisioning provides comprehensive features for:

-
    -
  • Workspace organization - Primary mode for grouping infrastructure, configs, schemas, and extensions with complete isolation
  • -
  • Intelligent CLI - Modular architecture with 80+ keyboard shortcuts, decentralized command registration, 84% code reduction
  • -
  • Type-safe configuration - Nickel as source of truth for all infrastructure definitions with mandatory validation
  • -
  • Batch operations - DAG scheduling, parallel execution, multi-cloud workflows with dependency resolution
  • -
  • Hybrid orchestration - Execute across Rust and Nushell with file-based persistence and atomic operations
  • -
  • Interactive guides - Step-by-step guided infrastructure deployment with validation and error recovery
  • -
  • Testing framework - Container-based test environments for validating infrastructure configurations
  • -
  • Platform installer - TUI and unattended installation with provider setup and configuration management
  • -
  • Security system - Complete v4.0.0 with authentication, authorization, encryption, secrets management, audit logging
  • -
  • Daemon acceleration - 50x performance improvement for script-heavy workloads via persistent Rust process
  • -
  • Intelligent detection - Automated analysis detecting cost, compliance, performance, security, and reliability issues
  • -
  • Extension registry - Central marketplace for providers, task services, plugins, and clusters with versioning
  • -
-

Feature Guides

-

Organization and Management

-
    -
  • -

    Workspace Management - Workspace mode, grouping, -multi-tenancy, isolation, customization

    -
  • -
  • -

    CLI Architecture - Modular design, 80+ shortcuts, -decentralized registration, dynamic subcommands, 84% code reduction

    -
  • -
  • -

    Configuration System - Nickel type-safe -configuration, hierarchical loading, profiles, validation

    -
  • -
-

Workflow and Operations

-
    -
  • -

    Batch Workflows - DAG scheduling, parallel -execution, conditional logic, error handling, multi-cloud, dependency resolution

    -
  • -
  • -

    Orchestrator System - Hybrid Rust/Nushell, -file-based persistence, atomic operations, event-driven

    -
  • -
  • -

    Provisioning Daemon - TCP service, 50x -performance, connection pooling, LRU caching, graceful shutdown

    -
  • -
-

Developer and Automation Features

-
    -
  • -

    Interactive Guides - Guided deployment, prompts, -validation, error recovery, progress tracking

    -
  • -
  • -

    Test Environment - Container-based testing, -sandbox isolation, validation, integration testing

    -
  • -
  • -

    Extension Registry - Marketplace for -providers, task services, plugins, clusters, versioning, dependencies

    -
  • -
-

Platform Capabilities

-
    -
  • -

    Platform Installer - TUI and unattended modes, -provider setup, workspace creation, configuration management

    -
  • -
  • -

    Security System - v4.0.0: JWT/OAuth, Cedar RBAC, -MFA, audit logging, encryption, secrets management

    -
  • -
  • -

    Detector System - Cost optimization, compliance, -performance analysis, security detection, reliability assessment

    -
  • -
  • -

    Nushell Plugins - 17 plugins: tera, nickel, fluentd, -secretumvault, 10-50x performance gains

    -
  • -
  • -

    Version Management - Semantic versioning, -dependency resolution, compatibility, deprecation, upgrade workflows

    -
  • -
-

Feature Categories

-
- - - - - - - - -
CategoryFeaturesUse Case
CoreWorkspace Management, CLI Architecture, Configuration SystemOrganization, command discovery, type-safety
OperationsBatch Workflows, Orchestrator, Version ManagementMulti-cloud, DAG scheduling, persistence
PerformanceProvisioning Daemon, Nushell PluginsScript acceleration, 10-50x speedup
Quality & TestingTest Environment, Extension RegistryConfiguration validation, distribution
Setup & InstallationPlatform InstallerInstallation, initial configuration
IntelligenceDetector SystemAnalysis, anomaly detection, cost optimization
SecuritySecurity System, Complete v4.0.0Authentication, authorization, encryption
User ExperienceInteractive GuidesGuided deployment, learning
-
-

Quick Navigation

-

I want to organize my infrastructure

-

Start with Workspace Management - primary organizational mode with isolation and customization.

-

I want faster command execution

-

Use Provisioning Daemon - 50x performance improvement for scripts through persistent process and caching.

-

I want to automate deployment

-

Learn Batch Workflows - DAG scheduling and multi-cloud orchestration with error handling.

-

I need to ensure security

-

Review Security System - complete authentication, authorization, encryption, audit logging.

-

I want to validate configurations

-

Check Test Environment - container-based sandbox testing and policy validation.

-

I need to extend capabilities

-

See Extension Registry - marketplace for providers, task services, plugins, clusters.

-

I need to find infrastructure issues

-

Use Detector System - automated cost, compliance, performance, and security analysis.

-

Integration with Platform

-

All features are integrated via:

-
    -
  • CLI commands - Invoke from Nushell or bash
  • -
  • REST APIs - Integrate with external systems
  • -
  • Nushell scripting - Build custom automation
  • -
  • Nickel configuration - Type-safe definitions
  • -
  • Extensions - Add custom providers and services
  • -
- -
    -
  • Architecture Details → See provisioning/docs/src/architecture/
  • -
  • Development Guides → See provisioning/docs/src/development/
  • -
  • API Reference → See provisioning/docs/src/api-reference/
  • -
  • Operation Guides → See provisioning/docs/src/operations/
  • -
  • Security Details → See provisioning/docs/src/security/
  • -
  • Practical Examples → See provisioning/docs/src/examples/
  • -
-

Workspace Management

-

Workspaces are the default organizational unit for all infrastructure work in Provisioning. -Every infrastructure project, deployment environment, or isolated configuration lives within a -workspace. This workspace-first approach provides clean separation between projects, -environments, and teams while enabling rapid context switching.

-

Overview

-

A workspace is an isolated environment that groups together:

-
    -
  • Infrastructure definitions - Nickel schemas, server configs, cluster definitions
  • -
  • Configuration settings - Environment-specific settings, provider credentials, user preferences
  • -
  • Runtime data - State files, checkpoints, logs, generated configurations
  • -
  • Extensions - Custom providers, task services, workflow templates
  • -
-

The workspace system enforces that all infrastructure operations (server creation, task service -installation, cluster deployment) require an active workspace. This prevents accidental -cross-project modifications and ensures configuration isolation.

-

Why Workspace-First

-

Traditional infrastructure tools often mix configurations across projects, leading to:

-
    -
  • Accidental deployments to wrong environments
  • -
  • Configuration drift between dev/staging/production
  • -
  • Credential leakage across projects
  • -
  • Difficulty tracking infrastructure boundaries
  • -
-

Provisioning’s workspace-first approach solves these problems by making workspace boundaries explicit and enforced at the CLI level.

-

Workspace Structure

-

Every workspace follows a consistent directory structure:

-
workspace_my_project/
-├── infra/                    # Infrastructure definitions (Nickel schemas)
-│   ├── my-cluster.ncl        # Cluster definition
-│   ├── servers.ncl           # Server configurations
-│   └── batch-workflows.ncl   # Batch workflow definitions
-│
-├── config/                   # Workspace configuration
-│   ├── local-overrides.toml  # User-specific overrides (gitignored)
-│   ├── dev-defaults.toml     # Development environment defaults
-│   ├── test-defaults.toml    # Testing environment defaults
-│   ├── prod-defaults.toml    # Production environment defaults
-│   └── provisioning.yaml     # Workspace metadata and settings
-│
-├── extensions/               # Workspace-specific extensions
-│   ├── providers/            # Custom cloud providers
-│   ├── taskservs/            # Custom task services
-│   ├── clusters/             # Custom cluster templates
-│   └── workflows/            # Custom workflow definitions
-│
-└── runtime/                  # Runtime data (gitignored)
-    ├── state/                # Infrastructure state files
-    ├── checkpoints/          # Workflow checkpoints
-    ├── logs/                 # Operation logs
-    └── generated/            # Generated configuration files
-
-

Configuration Hierarchy

-

Workspace configurations follow a 5-layer hierarchy:

-
1. System Defaults       (provisioning/config/config.defaults.toml)
-   ↓ overridden by
-2. User Config           (~/.config/provisioning/user_config.yaml)
-   ↓ overridden by
-3. Workspace Config      (workspace/config/provisioning.yaml)
-   ↓ overridden by
-4. Environment Config    (workspace/config/{dev,test,prod}-defaults.toml)
-   ↓ overridden by
-5. Runtime Flags         (--flag value)
-
-

This hierarchy ensures sensible defaults while allowing granular control at every level.

-

Core Commands

-

Creating Workspaces

-
# Create new workspace
-provisioning workspace init my-project
-
-# Create workspace with specific location
-provisioning workspace init my-project --path /custom/location
-
-# Create from template
-provisioning workspace init my-project --template kubernetes-ha
-
-

Listing Workspaces

-
# List all workspaces
-provisioning workspace list
-
-# Show active workspace
-provisioning workspace status
-
-# List with details
-provisioning workspace list --verbose
-
-

Example output:

-
NAME              PATH                                 LAST_USED           STATUS
-my-project        /workspaces/workspace_my_project     2026-01-15 10:30    Active
-dev-env           /workspaces/workspace_dev_env        2026-01-14 15:45
-production        /workspaces/workspace_production     2026-01-10 09:00
-
-

Switching Workspaces

-
# Switch to different workspace (single command)
-provisioning workspace switch my-project
-
-# Switch with validation
-provisioning workspace switch production --validate
-
-# Quick switch using shortcut
-provisioning ws switch dev-env
-
-

Workspace switching updates:

-
    -
  • Active workspace marker in user configuration
  • -
  • Environment variables for current session
  • -
  • CLI prompt indicator (if configured)
  • -
  • Last-used timestamp
  • -
-

Deleting Workspaces

-
# Delete workspace (requires confirmation)
-provisioning workspace delete old-project
-
-# Force delete without confirmation
-provisioning workspace delete old-project --force
-
-# Delete but keep backups
-provisioning workspace delete old-project --backup
-
-

Deletion safety:

-
    -
  • Requires explicit confirmation unless --force is used
  • -
  • Optionally creates backup before deletion
  • -
  • Validates no active operations are running
  • -
  • Updates workspace registry
  • -
-

Workspace Registry

-

The workspace registry is stored in user configuration and tracks all workspaces:

-
# ~/.config/provisioning/user_config.yaml
-workspaces:
-  active: my-project
-  registry:
-    my-project:
-      path: /workspaces/workspace_my_project
-      created: 2026-01-15T10:30:00Z
-      last_used: 2026-01-15T14:20:00Z
-      template: default
-    dev-env:
-      path: /workspaces/workspace_dev_env
-      created: 2026-01-10T08:00:00Z
-      last_used: 2026-01-14T15:45:00Z
-      template: development
-
-

This centralized registry enables:

-
    -
  • Fast workspace discovery
  • -
  • Usage tracking and statistics
  • -
  • Workspace templates
  • -
  • Path resolution
  • -
-

Workspace Enforcement

-

The CLI enforces workspace requirements for all infrastructure operations:

-

Workspace-exempt commands (work without active workspace):

-
    -
  • provisioning help
  • -
  • provisioning version
  • -
  • provisioning workspace *
  • -
  • provisioning guide *
  • -
  • provisioning setup *
  • -
  • provisioning providers (list only)
  • -
-

Workspace-required commands (require active workspace):

-
    -
  • provisioning server create
  • -
  • provisioning taskserv install
  • -
  • provisioning cluster deploy
  • -
  • provisioning batch submit
  • -
  • All infrastructure modification operations
  • -
-

If no workspace is active, workspace-required commands fail with:

-
Error: No active workspace
-Please activate or create a workspace:
-  provisioning workspace init <name>
-  provisioning workspace switch <name>
-
-

This enforcement prevents accidental infrastructure modifications outside workspace boundaries.

-

Workspace Templates

-

Templates provide pre-configured workspace structures for common use cases:

-

Available Templates

-
- - - - - - -
TemplateDescriptionUse Case
defaultMinimal workspace structureGeneral purpose infrastructure
kubernetes-haHA Kubernetes setup with 3 control planesProduction Kubernetes deployments
developmentDev-optimized with Docker ComposeLocal testing and development
multi-cloudMultiple provider configurationsMulti-cloud deployments
database-clusterDatabase-focused with backup configsDatabase infrastructure
cicdCI/CD pipeline configurationsAutomated deployment pipelines
-
-

Using Templates

-
# Create from template
-provisioning workspace init my-k8s --template kubernetes-ha
-
-# List available templates
-provisioning workspace templates
-
-# Show template details
-provisioning workspace template show kubernetes-ha
-
-

Templates pre-populate:

-
    -
  • Infrastructure Nickel schemas
  • -
  • Provider configurations
  • -
  • Environment-specific defaults
  • -
  • Example workflow definitions
  • -
  • README with usage instructions
  • -
-

Multi-Environment Workflows

-

Workspaces excel at managing multiple environments:

-

Strategy 1: Separate Workspaces Per Environment

-
# Create dedicated workspaces
-provisioning workspace init myapp-dev
-provisioning workspace init myapp-staging
-provisioning workspace init myapp-prod
-
-# Switch between environments
-provisioning ws switch myapp-dev
-provisioning server create      # Creates in dev
-
-provisioning ws switch myapp-prod
-provisioning server create      # Creates in prod (isolated)
-
-

Pros: Complete isolation, different credentials, independent state -Cons: More workspace management, duplicate configuration

-

Strategy 2: Single Workspace, Multiple Environments

-
# Single workspace with environment configs
-provisioning workspace init myapp
-
-# Deploy to different environments using flags
-PROVISIONING_ENV=dev provisioning server create
-PROVISIONING_ENV=staging provisioning server create
-PROVISIONING_ENV=prod provisioning server create
-
-

Pros: Shared configuration, easier to maintain -Cons: Shared credentials, risk of cross-environment mistakes

-

Strategy 3: Hybrid Approach

-
# Dev workspace for experimentation
-provisioning workspace init myapp-dev
-
-# Prod workspace for production only
-provisioning workspace init myapp-prod
-
-# Use environment flags within workspaces
-provisioning ws switch myapp-prod
-PROVISIONING_ENV=prod provisioning cluster deploy
-
-

Pros: Balances isolation and convenience -Cons: More complex to explain to teams

-

Best Practices

-

Naming Conventions

-
# Good names (descriptive, unique)
-workspace_librecloud_production
-workspace_myapp_dev
-workspace_k8s_staging
-
-# Avoid (ambiguous, generic)
-workspace_test
-workspace_1
-workspace_temp
-
-

Configuration Management

-
# Version control: Commit these files
-infra/**/*.ncl                    # Infrastructure definitions
-config/*-defaults.toml             # Environment defaults
-config/provisioning.yaml           # Workspace metadata
-extensions/**/*                    # Custom extensions
-
-# Gitignore: Never commit these
-config/local-overrides.toml        # User-specific overrides
-runtime/**/*                       # Runtime data and state
-**/*.secret                        # Credential files
-
-

Environment Separation

-
# Use dedicated workspaces for production
-provisioning workspace init myapp-prod --template production
-
-# Enable extra validation for production
-provisioning ws switch myapp-prod
-provisioning config set validation.strict true
-provisioning config set confirmation.required true
-
-

Team Collaboration

-
# Share workspace structure via git
-git clone repo/myapp-infrastructure
-cd myapp-infrastructure
-provisioning workspace init . --import
-
-# Each team member creates local-overrides.toml
-cat > config/local-overrides.toml <<EOF
-[user]
-default_region = "us-east-1"
-confirmation_required = true
-EOF
-
-

Troubleshooting

-

No Active Workspace Error

-
Error: No active workspace
-
-

Solution:

-
# List workspaces
-provisioning workspace list
-
-# Switch to workspace
-provisioning workspace switch <name>
-
-# Or create new workspace
-provisioning workspace init <name>
-
-

Workspace Not Found

-
Error: Workspace 'my-project' not found in registry
-
-

Solution:

-
# Re-register workspace
-provisioning workspace register /path/to/workspace_my_project
-
-# Or recreate workspace
-provisioning workspace init my-project
-
-

Workspace Path Doesn’t Exist

-
Error: Workspace path '/workspaces/workspace_my_project' does not exist
-
-

Solution:

-
# Remove invalid entry
-provisioning workspace unregister my-project
-
-# Re-create workspace
-provisioning workspace init my-project
-
-

Integration with Other Features

-

Batch Workflows

-

Workspaces provide the context for batch workflow execution:

-
provisioning ws switch production
-provisioning batch submit infra/batch-workflows.ncl
-
-

Batch workflows access workspace-specific:

-
    -
  • Infrastructure definitions
  • -
  • Provider credentials
  • -
  • Configuration settings
  • -
  • State management
  • -
-

Test Environments

-

Test environments inherit workspace configuration:

-
provisioning ws switch dev
-provisioning test quick kubernetes
-# Uses dev workspace's configuration and providers
-
-

Version Management

-

Workspace configurations can specify tool versions:

-
# workspace/infra/versions.ncl
-{
-  tools = {
-    nushell = "0.109.1"
-    nickel = "1.15.1"
-    kubernetes = "1.29.0"
-  }
-}
-
-

Provisioning validates versions match workspace requirements.

-

See Also

- -

CLI Architecture

-

The Provisioning CLI provides a unified command-line interface for all infrastructure -operations. It features 111+ commands organized into 7 domain-focused modules with 80+ -shortcuts for improved productivity. The modular architecture achieved 84% code reduction -while improving maintainability and extensibility.

-

Overview

-

The CLI architecture uses domain-driven design, separating concerns across modules. This -refactoring reduced the main entry point from monolithic code to 211 lines. The architecture -improves discoverability and enables rapid feature development.

-

- CLI Architecture Modular Design Decentralized Command Registration -

-

Key Metrics

-
- - - - - -
MetricBeforeAfterImprovement
Main CLI lines1,32921184% reduction
Command domains1 (monolithic)7 (modular)7x organization
Commands~50111+122% increase
Shortcuts080+New capability
Help categories07Improved discovery
-
-

Domain Architecture

-

The CLI is organized into 7 domain-focused modules:

-

1. Infrastructure Domain

-

Commands: Server, TaskServ, Cluster, Infra management

-
# Server operations
-provisioning server create
-provisioning server list
-provisioning server delete
-provisioning server ssh <hostname>
-
-# Task service operations
-provisioning taskserv install kubernetes
-provisioning taskserv list
-provisioning taskserv remove kubernetes
-
-# Cluster operations
-provisioning cluster deploy my-cluster
-provisioning cluster status my-cluster
-provisioning cluster scale my-cluster --nodes 5
-
-

Shortcuts: s (server), t/task (taskserv), cl (cluster), i (infra)

-

2. Orchestration Domain

-

Commands: Workflow, Batch, Orchestrator management

-
# Workflow operations
-provisioning workflow list
-provisioning workflow status <id>
-provisioning workflow cancel <id>
-
-# Batch operations
-provisioning batch submit infra/batch-workflows.ncl
-provisioning batch monitor <workflow-id>
-provisioning batch list
-
-# Orchestrator management
-provisioning orchestrator start
-provisioning orchestrator status
-provisioning orchestrator logs
-
-

Shortcuts: wf/flow (workflow), bat (batch), orch (orchestrator)

-

3. Development Domain

-

Commands: Module, Layer, Version, Pack management

-
# Module operations
-provisioning module create my-module
-provisioning module list
-provisioning module test my-module
-
-# Layer operations
-provisioning layer add <name>
-provisioning layer list
-
-# Versioning
-provisioning version bump minor
-provisioning version list
-
-# Packaging
-provisioning pack create my-extension
-provisioning pack publish my-extension
-
-

Shortcuts: mod (module), l (layer), v (version), p (pack)

-

4. Workspace Domain

-

Commands: Workspace management, templates

-
# Workspace operations
-provisioning workspace init my-project
-provisioning workspace list
-provisioning workspace switch my-project
-provisioning workspace delete old-project
-
-# Template operations
-provisioning workspace template list
-provisioning workspace template show kubernetes-ha
-
-

Shortcuts: ws (workspace)

-

5. Configuration Domain

-

Commands: Config, Environment, Validate, Setup

-
# Configuration operations
-provisioning config get servers.default_plan
-provisioning config set servers.default_plan large
-provisioning config validate
-
-# Environment operations
-provisioning env
-provisioning allenv
-
-# Setup operations
-provisioning setup profile --profile developer
-provisioning setup versions
-
-# Validation
-provisioning validate config
-provisioning validate infra
-provisioning validate nickel workspace/infra/my-cluster.ncl
-
-

Shortcuts: cfg (config), val (validate), st (setup)

-

6. Utilities Domain

-

Commands: SSH, SOPS, Cache, Plugin management

-
# SSH operations
-provisioning ssh server-01
-provisioning ssh server-01 -- uptime
-
-# SOPS operations
-provisioning sops encrypt config.yaml
-provisioning sops decrypt config.enc.yaml
-
-# Cache operations
-provisioning cache clear
-provisioning cache stats
-
-# Plugin operations
-provisioning plugin list
-provisioning plugin install nu_plugin_auth
-provisioning plugin update
-
-

Shortcuts: sops, cache, plug (plugin)

-

7. Generation Domain

-

Commands: Generate code, configs, docs

-
# Code generation
-provisioning generate provider upcloud-new
-provisioning generate taskserv postgresql
-provisioning generate cluster k8s-ha
-
-# Config generation
-provisioning generate config --profile production
-provisioning generate nickel --template kubernetes
-
-# Documentation generation
-provisioning generate docs
-
-

Shortcuts: g/gen (generate)

-

Command Shortcuts

-

The CLI provides 80+ shortcuts for improved productivity:

-

Infrastructure Shortcuts

-
- - - - -
Full CommandShortcutsExample
serversprovisioning s list
taskservt, taskprovisioning t install kubernetes
clusterclprovisioning cl deploy my-cluster
infrastructurei, infraprovisioning i list
-
-

Orchestration Shortcuts

-
- - - -
Full CommandShortcutsExample
workflowwf, flowprovisioning wf list
batchbatprovisioning bat submit workflow.ncl
orchestratororchprovisioning orch status
-
-

Development Shortcuts

-
- - - - -
Full CommandShortcutsExample
modulemodprovisioning mod list
layerlprovisioning l add base
versionvprovisioning v bump minor
packpprovisioning p create extension
-
-

Configuration Shortcuts

-
- - - - - -
Full CommandShortcutsExample
workspacewsprovisioning ws switch prod
configcfgprovisioning cfg get servers.plan
validatevalprovisioning val config
setupstprovisioning st profile --profile dev
environmentenvprovisioning env
-
-

Utility Shortcuts

-
- - -
Full CommandShortcutsExample
generateg, genprovisioning g provider aws-new
pluginplugprovisioning plug list
-
-

Quick Reference Shortcuts

-
- - - -
Full CommandShortcutsPurpose
shortcutsscShow shortcuts reference
guide-Interactive guides
howto-Quick how-to guides
-
-

Bi-Directional Help System

-

The CLI features a bi-directional help system that works in both directions:

-
# Both of these work identically
-provisioning help workspace
-provisioning workspace help
-
-# Shortcuts also work
-provisioning help ws
-provisioning ws help
-
-# Category help
-provisioning help infrastructure
-provisioning help orchestration
-
-

This flexibility improves discoverability and aligns with natural user expectations.

-

Centralized Flag Handling

-

All global flags are handled consistently across all commands:

-

Global Flags

-
- - - - - - - -
FlagShortPurposeExample
--debug-dEnable debug modeprovisioning --debug server create
--check-cDry-run mode (no changes)provisioning --check server delete
--yes-yAuto-confirm operationsprovisioning --yes cluster delete
--infra-iSpecify infrastructureprovisioning --infra my-cluster server list
--verbose-vVerbose outputprovisioning --verbose workflow list
--quiet-qMinimal outputprovisioning --quiet batch submit
--format-fOutput format (json/yaml/table)provisioning --format json server list
-
-

Command-Specific Flags

-
# Server creation flags
-provisioning server create --plan large --region us-east-1 --zone a
-
-# TaskServ installation flags
-provisioning taskserv install kubernetes --version 1.29.0 --ha
-
-# Cluster deployment flags
-provisioning cluster deploy --replicas 3 --storage 100GB
-
-# Batch workflow flags
-provisioning batch submit workflow.ncl --parallel 5 --timeout 3600
-
-

Command Discovery

-

Categorized Help

-

The help system organizes commands by domain:

-
provisioning help
-
-# Output shows categorized commands:
-Infrastructure Commands:
-  server        Manage servers (shortcuts: s)
-  taskserv      Manage task services (shortcuts: t, task)
-  cluster       Manage clusters (shortcuts: cl)
-
-Orchestration Commands:
-  workflow      Manage workflows (shortcuts: wf, flow)
-  batch         Batch operations (shortcuts: bat)
-  orchestrator  Orchestrator management (shortcuts: orch)
-
-Configuration Commands:
-  workspace     Workspace management (shortcuts: ws)
-  config        Configuration management (shortcuts: cfg)
-  validate      Validation operations (shortcuts: val)
-  setup         System setup (shortcuts: st)
-
-

Quick Reference

-
# Fastest command reference
-provisioning sc
-
-# Shows comprehensive shortcuts table with examples
-
-

Interactive Guides

-
# Step-by-step guides
-provisioning guide from-scratch      # Complete deployment guide
-provisioning guide quickstart         # Command shortcuts reference
-provisioning guide customize          # Customization patterns
-
-

Command Routing

-

The CLI uses a sophisticated dispatcher for command routing:

-
# provisioning/core/nulib/main_provisioning/dispatcher.nu
-
-# Route command to appropriate handler
-export def dispatch [
-    command: string
-    args: list<string>
-] {
-    match $command {
-        # Infrastructure domain
-        "server" | "s" => { route-to-handler "infrastructure" "server" $args }
-        "taskserv" | "t" | "task" => { route-to-handler "infrastructure" "taskserv" $args }
-        "cluster" | "cl" => { route-to-handler "infrastructure" "cluster" $args }
-
-        # Orchestration domain
-        "workflow" | "wf" | "flow" => { route-to-handler "orchestration" "workflow" $args }
-        "batch" | "bat" => { route-to-handler "orchestration" "batch" $args }
-
-        # Configuration domain
-        "workspace" | "ws" => { route-to-handler "configuration" "workspace" $args }
-        "config" | "cfg" => { route-to-handler "configuration" "config" $args }
-    }
-}
-
-

This routing enables:

-
    -
  • Consistent error handling
  • -
  • Centralized logging
  • -
  • Workspace enforcement
  • -
  • Permission checks
  • -
  • Audit trail
  • -
-

Command Implementation Pattern

-

All commands follow a consistent implementation pattern:

-
# Example: provisioning/core/nulib/main_provisioning/commands/server.nu
-
-# Main command handler
-export def main [
-    operation: string    # create, list, delete, etc.
-    --check             # Dry-run mode
-    --yes               # Auto-confirm
-] {
-    # 1. Validate workspace requirement
-    enforce-workspace-requirement "server" $operation
-
-    # 2. Load configuration
-    let config = load-config
-
-    # 3. Parse operation
-    match $operation {
-        "create" => { create-server $args $config --check=$check --yes=$yes }
-        "list" => { list-servers $config }
-        "delete" => { delete-server $args $config --yes=$yes }
-        "ssh" => { ssh-to-server $args $config }
-        _ => { error $"Unknown server operation: ($operation)" }
-    }
-
-    # 4. Log operation (audit trail)
-    log-operation "server" $operation $args
-}
-
-

This pattern ensures:

-
    -
  • Consistent behavior
  • -
  • Proper error handling
  • -
  • Configuration integration
  • -
  • Workspace enforcement
  • -
  • Audit logging
  • -
-

Modular Structure

-

The CLI codebase is organized for maintainability:

-
provisioning/core/
-├── cli/
-│   └── provisioning           # Main CLI entry point (211 lines)
-│
-├── nulib/
-│   ├── main_provisioning/
-│   │   ├── dispatcher.nu      # Command routing (central dispatch)
-│   │   ├── flags.nu           # Centralized flag handling
-│   │   ├── help_system_fluent.nu  # Categorized help with i18n
-│   │   │
-│   │   └── commands/          # Domain-specific command handlers
-│   │       ├── infrastructure/
-│   │       │   ├── server.nu
-│   │       │   ├── taskserv.nu
-│   │       │   └── cluster.nu
-│   │       │
-│   │       ├── orchestration/
-│   │       │   ├── workflow.nu
-│   │       │   ├── batch.nu
-│   │       │   └── orchestrator.nu
-│   │       │
-│   │       ├── configuration/
-│   │       │   ├── workspace.nu
-│   │       │   ├── config.nu
-│   │       │   └── validate.nu
-│   │       │
-│   │       └── utilities/
-│   │           ├── ssh.nu
-│   │           ├── sops.nu
-│   │           └── cache.nu
-│   │
-│   └── lib_provisioning/      # Core libraries (used by commands)
-│       ├── config/
-│       ├── providers/
-│       ├── workspace/
-│       └── utils/
-
-

This structure enables:

-
    -
  • Clear separation of concerns
  • -
  • Easy addition of new commands
  • -
  • Testable command handlers
  • -
  • Reusable core libraries
  • -
-

Internationalization

-

The CLI supports multiple languages via Fluent catalog:

-
# Automatic locale detection
-export LANG=es_ES.UTF-8
-provisioning help    # Shows Spanish help if es-ES catalog exists
-
-# Supported locales
-en-US (default)      # English
-es-ES                # Spanish
-fr-FR                # French
-de-DE                # German
-
-

Catalog structure:

-
provisioning/locales/
-├── en-US/
-│   └── help.ftl      # English help strings
-├── es-ES/
-│   └── help.ftl      # Spanish help strings
-└── de-DE/
-    └── help.ftl      # German help strings
-
-

Extension Points

-

The modular architecture provides clean extension points:

-

Adding New Commands

-
# 1. Create command handler
-provisioning/core/nulib/main_provisioning/commands/my_new_command.nu
-
-# 2. Register in dispatcher
-# provisioning/core/nulib/main_provisioning/dispatcher.nu
-"my-command" | "mc" => { route-to-handler "utilities" "my-command" $args }
-
-# 3. Add help entry
-# provisioning/locales/en-US/help.ftl
-my-command-help = Manage my new feature
-
-# 4. Command is now available
-provisioning my-command <operation>
-provisioning mc <operation>  # Shortcut also works
-
-

Adding New Domains

-
# 1. Create domain directory
-provisioning/core/nulib/main_provisioning/commands/my_domain/
-
-# 2. Add domain commands
-my_domain/
-├── command1.nu
-├── command2.nu
-└── command3.nu
-
-# 3. Register domain in dispatcher
-
-# 4. Add domain help category
-
-# Domain is now available with all commands
-
-

Command Aliases

-

The CLI supports command aliases for common operations:

-
# Defined in user configuration
-# ~/.config/provisioning/user_config.yaml
-aliases:
-  deploy: "cluster deploy"
-  list-all: "server list && taskserv list && cluster list"
-  quick-test: "test quick kubernetes"
-
-# Usage
-provisioning deploy my-cluster     # Expands to: cluster deploy my-cluster
-provisioning list-all              # Runs multiple commands
-provisioning quick-test            # Runs test with preset
-
-

Best Practices

-

Using Shortcuts Effectively

-
# Development workflow (frequent commands)
-provisioning ws switch dev          # Switch to dev workspace
-provisioning s list                 # Quick server list
-provisioning t install postgres     # Install task service
-provisioning cl status my-cluster   # Check cluster status
-
-# Production workflow (explicit commands for clarity)
-provisioning workspace switch production
-provisioning server create --plan large --check
-provisioning cluster deploy critical-cluster --yes
-
-

Dry-Run Before Execution

-
# Always check before dangerous operations
-provisioning --check server delete old-servers
-provisioning --check cluster delete test-cluster
-
-# If output looks good, run for real
-provisioning --yes server delete old-servers
-
-

Using Output Formats

-
# JSON output for scripting
-provisioning --format json server list | jq '.[] | select(.status == "running")'
-
-# YAML output for readability
-provisioning --format yaml cluster status my-cluster
-
-# Table output for humans (default)
-provisioning server list
-
-

Performance Optimizations

-

The modular architecture enables several performance optimizations:

-

Lazy Loading

-

Commands are loaded on-demand, reducing startup time:

-
# Only loads server command module when needed
-provisioning server list    # Fast startup (loads server.nu only)
-
-

Command Caching

-

Frequently-used commands benefit from caching:

-
# First run: ~200ms (loads modules, config)
-provisioning server list
-
-# Subsequent runs: ~50ms (cached config, loaded modules)
-provisioning server list
-
-

Parallel Execution

-

Batch operations execute in parallel:

-
# Executes server creation in parallel (up to configured limit)
-provisioning batch submit multi-server-workflow.ncl --parallel 10
-
-

Troubleshooting

-

Command Not Found

-
Error: Unknown command 'servr'
-Did you mean: server (s)
-
-

The CLI provides helpful suggestions for typos.

-

Missing Workspace

-
Error: No active workspace
-Please activate or create a workspace:
-  provisioning workspace init <name>
-  provisioning workspace switch <name>
-
-

Workspace enforcement prevents accidental operations.

-

Permission Denied

-
Error: Operation requires admin permissions
-Please run with elevated privileges or contact administrator
-
-

Permission system prevents unauthorized operations.

-

See Also

- -

Configuration System

-

Batch Workflows

-

Orchestrator

-

Interactive Guides

-

Test Environment

-

Platform Installer

-

Security System

-

Version Management

-

Nushell Plugins

-

Provisioning includes 17 high-performance native Rust plugins for Nushell, providing 10-50x -speed improvements over HTTP APIs. Plugins handle critical functionality: templates, configuration, -encryption, orchestration, and secrets management.

-

Overview

-

Performance Benefits

-

Plugins provide significant performance improvements for frequently-used operations:

-
- - - - - -
PluginSpeed ImprovementUse Case
nu_plugin_tera10-15x fasterTemplate rendering
nu_plugin_nickel5-8x fasterConfiguration processing
nu_plugin_orchestrator30-50x fasterQuery orchestrator state
nu_plugin_kms10x fasterEncryption/decryption
nu_plugin_auth5x fasterAuthentication operations
-
-

Installation

-

All plugins install automatically with Provisioning:

-
# Automatic installation during setup
-provisioning install
-
-# Or manual installation
-cd /path/to/provisioning
-./scripts/install-plugins.nu
-
-# Verify installation
-provisioning plugins list
-
-

Plugin Management

-
# List installed plugins with versions
-provisioning plugins list
-
-# Check plugin status
-provisioning plugins status
-
-# Update all plugins
-provisioning plugins update --all
-
-# Update specific plugin
-provisioning plugins update nu_plugin_tera
-
-# Remove plugin
-provisioning plugins remove nu_plugin_tera
-
-

Core Plugins (Priority)

-

1. nu_plugin_tera

-

Template Rendering Engine

-

Nushell plugin for Tera template processing (Jinja2-style syntax).

-
# Install
-provisioning plugins install nu_plugin_tera
-
-# Usage in Nushell
-let template = "Hello {{ name }}!"
-let context = { name: "World" }
-$template | tera render $context
-# Output: "Hello World!"
-
-

Features:

-
    -
  • Jinja2-compatible syntax
  • -
  • Built-in filters and functions
  • -
  • Template inheritance
  • -
  • Macro support
  • -
  • Custom filters via Rust
  • -
-

Performance: 10-15x faster than HTTP template service

-

Use Cases:

-
    -
  • Generating infrastructure configurations
  • -
  • Creating dynamic scripts
  • -
  • Building deployment templates
  • -
  • Rendering documentation
  • -
-

Example: Generate infrastructure config:

-
let infra_template = "
-{
-  servers = [
-    {% for server in servers %}
-    {
-      name = \"{{ server.name }}\"
-      cpu = {{ server.cpu }}
-      memory = {{ server.memory }}
-    }
-    {% if not loop.last %},{% endif %}
-    {% endfor %}
-  ]
-}
-"
-
-let servers = [
-  { name: "web-01", cpu: 4, memory: 8 }
-  { name: "web-02", cpu: 4, memory: 8 }
-]
-
-$infra_template | tera render { servers: $servers }
-
-
-

2. nu_plugin_nickel

-

Nickel Configuration Plugin

-

Native Nickel compilation and validation in Nushell.

-
# Install
-provisioning plugins install nu_plugin_nickel
-
-# Usage in Nushell
-let nickel_code = '{ name = "server", cpu = 4 }'
-$nickel_code | nickel eval
-# Output: { name: "server", cpu: 4 }
-
-

Features:

-
    -
  • Parse and evaluate Nickel expressions
  • -
  • Type checking and validation
  • -
  • Schema enforcement
  • -
  • Merge configurations
  • -
  • Generate JSON/YAML output
  • -
-

Performance: 5-8x faster than CLI invocation

-

Use Cases:

-
    -
  • Validate infrastructure definitions
  • -
  • Process Nickel schemas
  • -
  • Merge configuration files
  • -
  • Generate typed configurations
  • -
-

Example: Validate and merge configs:

-
let base_config = open base.ncl | nickel eval
-let env_config = open prod-defaults.ncl | nickel eval
-
-let merged = $base_config | nickel merge $env_config
-$merged | nickel validate --schema infrastructure-schema.ncl
-
-
-

3. nu_plugin_fluent

-

Internationalization (i18n) Plugin

-

Fluent translation system for multi-language support.

-
# Install
-provisioning plugins install nu_plugin_fluent
-
-# Usage in Nushell
-fluent load "./locales"
-fluent set-locale "es-ES"
-fluent get "help-infra-server-create"
-# Output: "Crear un nuevo servidor"
-
-

Features:

-
    -
  • Load Fluent catalogs (.ftl files)
  • -
  • Dynamic locale switching
  • -
  • Pluralization support
  • -
  • Fallback chains
  • -
  • Translation coverage reports
  • -
-

Performance: Native Rust implementation, <1ms per translation

-

Use Cases:

-
    -
  • CLI help text in multiple languages
  • -
  • Form labels and prompts
  • -
  • Error messages
  • -
  • Interactive guides
  • -
-

Supported Locales:

-
    -
  • en-US (English)
  • -
  • es-ES (Spanish)
  • -
  • pt-BR (Portuguese - planned)
  • -
  • fr-FR (French - planned)
  • -
  • ja-JP (Japanese - planned)
  • -
-

Example: Multi-language help system:

-
fluent load "provisioning/locales"
-
-# Spanish help
-fluent set-locale "es-ES"
-fluent get "help-main-title"    # "SISTEMA DE PROVISIÓN"
-
-# English help (fallback)
-fluent set-locale "fr-FR"
-fluent get "help-main-title"    # Falls back to "PROVISIONING SYSTEM"
-
-
-

4. nu_plugin_secretumvault

-

Post-Quantum Cryptography Vault

-

SecretumVault integration for quantum-resistant secret storage.

-
# Install
-provisioning plugins install nu_plugin_secretumvault
-
-# Usage in Nushell
-secretumvault-plugin store "api-key" "secret-value"
-let key = secretumvault-plugin retrieve "api-key"
-secretumvault-plugin delete "api-key"
-
-

Features:

-
    -
  • CRYSTALS-Kyber encryption (post-quantum)
  • -
  • Hybrid encryption (PQC + AES-256)
  • -
  • Secure credential injection
  • -
  • Key rotation
  • -
  • Audit logging
  • -
-

Performance: <100ms for encrypt/decrypt operations

-

Use Cases:

-
    -
  • Store infrastructure credentials
  • -
  • Manage API keys
  • -
  • Handle database passwords
  • -
  • Secure configuration values
  • -
-

Example: Secure credential management:

-
# Store credentials in vault
-secretumvault-plugin store "aws-access-key" "AKIAIOSFODNN7EXAMPLE"
-secretumvault-plugin store "aws-secret-key" "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
-
-# Retrieve for use
-let aws_key = secretumvault-plugin retrieve "aws-access-key"
-provisioning aws configure --access-key $aws_key
-
-
-

Performance Plugins

-

5. nu_plugin_orchestrator

-

Orchestrator State Query Plugin

-

High-speed queries to orchestrator state and workflow data.

-
# Install
-provisioning plugins install nu_plugin_orchestrator
-
-# Usage in Nushell
-orchestrator query workflows --filter status=running
-orchestrator query tasks --limit 100
-orchestrator query checkpoints --workflow deploy-k8s
-
-

Performance: 30-50x faster than HTTP API

-

Queries:

-
    -
  • Workflows (list, status, logs)
  • -
  • Tasks (state, duration, dependencies)
  • -
  • Checkpoints (recovery points)
  • -
  • History (audit trail)
  • -
-

Example: Monitor running workflows:

-
let running = orchestrator query workflows --filter status=running
-$running | each { | w |
-  print $"Workflow: ($w.name) - ($w.progress)%"
-}
-
-
-

6. nu_plugin_kms

-

Key Management System (Encryption) Plugin

-

Fast encryption/decryption with KMS backends.

-
# Install
-provisioning plugins install nu_plugin_kms
-
-# Usage in Nushell
-let encrypted = "secret-data" | kms encrypt --algorithm aes-256-gcm
-$encrypted | kms decrypt
-
-

Performance: 10x faster than external KMS calls, 5ms encryption

-

Supported Algorithms:

-
    -
  • AES-256-GCM
  • -
  • ChaCha20-Poly1305
  • -
  • Kyber (post-quantum)
  • -
  • Falcon (signatures)
  • -
-

Features:

-
    -
  • Symmetric encryption
  • -
  • Key derivation (Argon2id, PBKDF2)
  • -
  • Authenticated encryption
  • -
  • HSM integration (optional)
  • -
-

Example: Encrypt infrastructure secrets:

-
let config = open infrastructure.ncl
-let encrypted = $config | kms encrypt --key master-key
-
-# Decrypt when needed
-let decrypted = $encrypted | kms decrypt --key master-key
-$decrypted | nickel eval
-
-
-

7. nu_plugin_auth

-

Authentication Plugin

-

Multi-method authentication with keyring integration.

-
# Install
-provisioning plugins install nu_plugin_auth
-
-# Usage in Nushell
-let token = auth login --method jwt --provider openid
-auth set-token $token
-auth verify-token
-
-

Performance: 5x faster local authentication

-

Features:

-
    -
  • JWT token generation and validation
  • -
  • OAuth2 support
  • -
  • SAML support
  • -
  • OS keyring integration
  • -
  • MFA support
  • -
-

Methods:

-
    -
  • JWT (JSON Web Tokens)
  • -
  • OAuth2 (GitHub, Google, Microsoft)
  • -
  • SAML
  • -
  • LDAP
  • -
  • Local keyring
  • -
-

Example: Authenticate and store credentials:

-
# Login and get token
-let token = auth login --method oauth2 --provider github
-auth set-token $token --store-keyring
-
-# Verify authentication
-auth verify-token      # Check if token valid
-auth whoami            # Show current user
-
-
-

Utility Plugins

-

8. nu_plugin_hashes

-

Cryptographic Hashing Plugin

-

Multiple hash algorithms for data integrity.

-
# Install
-provisioning plugins install nu_plugin_hashes
-
-# Usage in Nushell
-"data" | hashes sha256
-"data" | hashes blake3
-
-

Algorithms:

-
    -
  • SHA256, SHA512
  • -
  • BLAKE3
  • -
  • MD5 (legacy)
  • -
  • SHA1 (legacy)
  • -
-
-

9. nu_plugin_highlight

-

Syntax Highlighting Plugin

-

Code syntax highlighting for display and logging.

-
# Install
-provisioning plugins install nu_plugin_highlight
-
-# Usage in Nushell
-open script.sh | highlight --language bash
-open config.ncl | highlight --language nickel
-
-

Languages:

-
    -
  • Bash/Shell
  • -
  • Nickel
  • -
  • YAML
  • -
  • JSON
  • -
  • Rust
  • -
  • SQL
  • -
  • Others
  • -
-
-

10. nu_plugin_image

-

Image Processing Plugin

-

Image manipulation and format conversion.

-
# Install
-provisioning plugins install nu_plugin_image
-
-# Usage in Nushell
-open diagram.png | image resize --width 800 --height 600
-open logo.jpg | image convert --format webp
-
-

Operations:

-
    -
  • Resize, crop, rotate
  • -
  • Format conversion
  • -
  • Compression
  • -
  • Metadata extraction
  • -
-
-

11. nu_plugin_clipboard

-

Clipboard Management Plugin

-

Read/write system clipboard.

-
# Install
-provisioning plugins install nu_plugin_clipboard
-
-# Usage in Nushell
-"api-key" | clipboard copy
-clipboard paste
-
-

Features:

-
    -
  • Copy to clipboard
  • -
  • Paste from clipboard
  • -
  • Manage clipboard history
  • -
  • Cross-platform support
  • -
-
-

12. nu_plugin_desktop_notifications

-

Desktop Notifications Plugin

-

System notifications for long-running operations.

-
# Install
-provisioning plugins install nu_plugin_desktop_notifications
-
-# Usage in Nushell
-notifications notify "Deployment completed" --type success
-notifications notify "Errors detected" --type error
-
-

Features:

-
    -
  • Success, warning, error notifications
  • -
  • Custom titles and messages
  • -
  • Sound alerts
  • -
-
-

13. nu_plugin_qr_maker

-

QR Code Generator Plugin

-

Generate QR codes for configuration sharing.

-
# Install
-provisioning plugins install nu_plugin_qr_maker
-
-# Usage in Nushell
-" [https://example.com/config"](https://example.com/config") | qr-maker generate --output config.png
-"workspace-setup-command" | qr-maker generate --ascii
-
-
-

14. nu_plugin_port_extension

-

Port/Network Utilities Plugin

-

Network port management and diagnostics.

-
# Install
-provisioning plugins install nu_plugin_port_extension
-
-# Usage in Nushell
-port-extension list-open --port 8080
-port-extension check-available --port 9000
-
-
-

Legacy/Secondary Plugins

-

15. nu_plugin_kcl

-

KCL Configuration Plugin (DEPRECATED)

-

Legacy KCL support (Nickel is preferred).

-

⚠️ Status: Deprecated - Use nu_plugin_nickel instead

-
# Install
-provisioning plugins install nu_plugin_kcl
-
-# Usage (not recommended)
-let config = open config.kcl | kcl eval
-
-
-

16. api_nu_plugin_kcl

-

KCL API Plugin (DEPRECATED)

-

HTTP API wrapper for KCL.

-

⚠️ Status: Deprecated - Use nu_plugin_nickel instead

-
-

17. _nu_plugin_inquire (Historical)

-

Interactive Prompts Plugin (HISTORICAL)

-

Old inquiry/prompt system, replaced by TypeDialog.

-

⚠️ Status: Historical/archived

-
-

Plugin Installation & Management

-

Installation Methods

-

Automatic with Provisioning:

-
provisioning install
-# Installs all recommended plugins automatically
-
-

Selective Installation:

-
# Install specific plugins
-provisioning plugins install nu_plugin_tera nu_plugin_nickel nu_plugin_secretumvault
-
-# Install plugin category
-provisioning plugins install --category core          # Essential plugins
-provisioning plugins install --category performance   # Performance plugins
-provisioning plugins install --category utilities     # Utility plugins
-
-

Manual Installation:

-
# Build and install from source
-cd /Users/Akasha/project-provisioning/plugins/nushell-plugins/nu_plugin_tera
-cargo install --path .
-
-# Then load in Nushell
-plugin add nu_plugin_tera
-
-

Configuration

-

Plugin Loading in Nushell:

-
# In env.nu or config.nu
-plugin add nu_plugin_tera
-plugin add nu_plugin_nickel
-plugin add nu_plugin_secretumvault
-plugin add nu_plugin_fluent
-plugin add nu_plugin_auth
-plugin add nu_plugin_kms
-plugin add nu_plugin_orchestrator
-
-# And more...
-
-

Plugin Status:

-
# Check all plugins
-provisioning plugins list
-
-# Check specific plugin
-provisioning plugins status nu_plugin_tera
-
-# Detailed information
-provisioning plugins info nu_plugin_tera --verbose
-
-

Best Practices

-

Use Plugins When

-
    -
  • ✅ Processing large amounts of data (templates, config)
  • -
  • ✅ Sensitive operations (encryption, secrets)
  • -
  • ✅ Frequent operations (queries, auth)
  • -
  • ✅ Performance critical paths
  • -
-

Fallback to HTTP API When

-
    -
  • ❌ Plugin not installed (automatic fallback)
  • -
  • ❌ Older Nushell version incompatible
  • -
  • ❌ Special features only in API
  • -
-
# Plugins have automatic fallback
-# If nu_plugin_tera not available, uses HTTP API automatically
-let template = "{{ name }}" | tera render { name: "test" }
-# Works either way
-
-

Troubleshooting

-

Plugin Not Loading

-
# Reload Nushell
-nu
-
-# Check plugin errors
-plugin list --debug
-
-# Reinstall plugin
-provisioning plugins remove nu_plugin_tera
-provisioning plugins install nu_plugin_tera
-
-

Performance Issues

-
# Check plugin status
-provisioning plugins status
-
-# Monitor plugin usage
-provisioning monitor plugins
-
-# Profile plugin calls
-provisioning profile nu_plugin_tera
-
- - -

Multilingual Support

-

Provisioning includes comprehensive multilingual support for help text, forms, and -interactive interfaces. The system uses Mozilla Fluent for translations with automatic -fallback chains.

-

Supported Languages

-

Currently supported with 100% translation coverage:

-
- - - - - -
LanguageLocaleStatusStrings
English (US)en-US✅ Complete245
Spanish (Spain)es-ES✅ Complete245
Portuguese (Brazil)pt-BR🔄 Planned-
French (France)fr-FR🔄 Planned-
Japanese (Japan)ja-JP🔄 Planned-
-
-

Coverage Requirement: 95% of strings translated to critical locales (en-US, es-ES).

-

Using Different Languages

-

Setting Language via Environment Variable

-

Select language using the LANG environment variable:

-
# English (default)
-provisioning help infrastructure
-
-# Spanish
-LANG=es_ES provisioning help infrastructure
-
-# Fallback to English if locale not available
-LANG=fr_FR provisioning help infrastructure
-# Output: English (en-US) [fallback chain]
-
-

Locale Resolution

-

Language selection follows this order:

-
    -
  1. Check LANG environment variable (e.g., es_ES)
  2. -
  3. Match to configured locale (es-ES)
  4. -
  5. If not found, follow fallback chain (es-ES → en-US)
  6. -
  7. Default to en-US if no match
  8. -
-

Format: LANG uses underscore (es_ES), locales use hyphen (es-ES). System handles conversion automatically.

-

Translation System Architecture

-

Mozilla Fluent Format

-

All translations use Mozilla Fluent (.ftl files), which provides:

-
    -
  • Simple Syntax: Key-value pairs with rich formatting
  • -
  • Pluralization: Support for language-specific plural rules
  • -
  • Attributes: Multiple values per key for contextual translation
  • -
  • Automatic Fallback: Chain resolution when keys missing
  • -
  • Extensibility: Support for custom formatting functions
  • -
-

Example Fluent syntax:

-
help-infra-server-create = Create a new server
-form-database_type-option-postgres = PostgreSQL (Recommended)
-form-replicas-prompt = Number of replicas
-form-replicas-help = How many replicas to run
-
-

File Organization

-
provisioning/locales/
-├── i18n-config.toml              # Central i18n configuration
-├── en-US/                         # English base language
-│   ├── help.ftl                  # Help system strings (65 keys)
-│   └── forms.ftl                 # Form strings (180 keys)
-└── es-ES/                         # Spanish translations
-    ├── help.ftl                  # Help system translations
-    └── forms.ftl                 # Form translations
-
-

String Categories:

-
    -
  • help.ftl (65 strings): Help text, menu items, category descriptions, error messages
  • -
  • forms.ftl (180 strings): Form labels, placeholders, help text, options
  • -
-

Help System Translations

-

Help system provides multi-language support for all command categories:

-

Categories Covered

-
- - - - - - - - -
CategoryCoverageExample Keys
Infrastructure✅ 21 stringsserver commands, taskserv, clusters, VMs
Orchestration✅ 18 stringsworkflows, batch operations, orchestrator
Workspace✅ Completeworkspace management, templates
Setup✅ Completesystem configuration, initialization
Authentication✅ CompleteJWT, MFA, sessions
Platform✅ Completeservices, Control Center, MCP
Development✅ Completemodules, versions, plugins
Utilities✅ Completeproviders, SOPS, SSH
-
-

Example: Help Output in Spanish

-
$ LANG=es_ES provisioning help infrastructure
-SERVIDOR E INFRAESTRUCTURA
-Gestión de servidores, taskserv, clusters, VM e infraestructura.
-
-COMANDOS DE SERVIDOR
-  server create         Crear un nuevo servidor
-  server delete         Eliminar un servidor existente
-  server list           Listar todos los servidores
-  server status         Ver estado de un servidor
-
-COMANDOS DE TASKSERV
-  taskserv create       Crear un nuevo servicio de tarea
-  taskserv delete       Eliminar un servicio de tarea
-  taskserv configure    Configurar un servicio de tarea
-  taskserv status       Ver estado del servicio de tarea
-
-

Form Translations (TypeDialog Integration)

-

Interactive forms automatically use the selected language:

-

Setup Form

-

Project information, database configuration, API settings, deployment options, security, etc.

-
# English form
-$ provisioning setup profile
-📦 Project name: [my-app]
-
-# Spanish form
-$ LANG=es_ES provisioning setup profile
-📦 Nombre del proyecto: [mi-app]
-
-

Translated Form Fields

-

Each form field has four translated strings:

-
- - - - -
ComponentPurposeExample en-USExample es-ES
promptField label“Project name”“Nombre del proyecto”
helpHelper text“Project name (lowercase alphanumeric with hyphens)”“Nombre del proyecto (minúsculas alfanuméricas con guiones)”
placeholderExample value“my-app”“mi-app”
optionDropdown choice“PostgreSQL (Recommended)”“PostgreSQL (Recomendado)”
-
-

Supported Forms

-
    -
  • Unified Setup: Project info, database, API, deployment, security, terms
  • -
  • Authentication: Login form (username, password, remember me, forgot password)
  • -
  • Setup Wizard: Quick/standard/advanced modes
  • -
  • MFA Enrollment: TOTP, SMS, backup codes, device management
  • -
  • Infrastructure: Delete confirmations, resource prompts, data retention
  • -
-

Fallback Chain Configuration

-

When a translation string is missing, the system automatically falls back to the parent locale:

-
# From i18n-config.toml
-[fallback_chains]
-es-ES = ["en-US"]
-pt-BR = ["pt-PT", "es-ES", "en-US"]
-fr-FR = ["en-US"]
-ja-JP = ["en-US"]
-
-

Resolution Example:

-
    -
  1. User requests Spanish (es-ES): provisioning help
  2. -
  3. Look for string in es-ES/help.ftl
  4. -
  5. If missing, fallback to en-US (help-infra-server-create = "Create a new server")
  6. -
  7. If still missing, use literal key name as display text
  8. -
-

Adding New Languages

-

1. Add Locale Configuration

-

Edit provisioning/locales/i18n-config.toml:

-
[locales.pt-BR]
-name = "Portuguese (Brazil)"
-direction = "ltr"
-plurals = 2
-decimal_separator = ","
-thousands_separator = "."
-date_format = "DD/MM/YYYY"
-
-[fallback_chains]
-pt-BR = ["pt-PT", "es-ES", "en-US"]
-
-

Configuration Fields:

-
    -
  • name: Display name of locale
  • -
  • direction: Text direction (ltr/rtl)
  • -
  • plurals: Number of plural forms (1-6 depending on language)
  • -
  • decimal_separator: Locale-specific decimal format
  • -
  • thousands_separator: Number formatting
  • -
  • date_format: Locale-specific date format
  • -
  • currency_symbol: Currency symbol (optional)
  • -
  • currency_position: “prefix” or “suffix” (optional)
  • -
-

2. Create Locale Directory

-
mkdir -p provisioning/locales/pt-BR
-
-

3. Create Translation Files

-

Copy English files as base:

-
cp provisioning/locales/en-US/help.ftl provisioning/locales/pt-BR/help.ftl
-cp provisioning/locales/en-US/forms.ftl provisioning/locales/pt-BR/forms.ftl
-
-

4. Translate Strings

-

Edit pt-BR/help.ftl and pt-BR/forms.ftl with translated content. Follow naming conventions:

-
# Help strings: help-{category}-{element}
-help-infra-server-create = Criar um novo servidor
-
-# Form prompts: form-{element}-prompt
-form-project_name-prompt = Nome do projeto
-
-# Form help: form-{element}-help
-form-project_name-help = Nome do projeto (alfanumérico minúsculo com hífens)
-
-# Form options: form-{element}-option-{value}
-form-database_type-option-postgres = PostgreSQL (Recomendado)
-
-

5. Validate Translation

-

Check coverage and syntax:

-
# Validate Fluent file syntax
-provisioning i18n validate --locale pt-BR
-
-# Check translation coverage
-provisioning i18n coverage --locale pt-BR
-
-# List missing translations
-provisioning i18n missing --locale pt-BR
-
-

6. Update Documentation

-

Document new language support in translations_status.md.

-

Validation & Quality Standards

-

Translation Quality Rules

-

Naming Conventions (REQUIRED):

-
    -
  • Help strings: help-{category}-{element} (e.g., help-infra-server-create)
  • -
  • Form prompts: form-{element}-prompt (e.g., form-project_name-prompt)
  • -
  • Form help: form-{element}-help (e.g., form-project_name-help)
  • -
  • Form placeholders: form-{element}-placeholder
  • -
  • Form options: form-{element}-option-{value} (e.g., form-database_type-option-postgres)
  • -
  • Section headers: section-{name}-title
  • -
-

Coverage Requirements:

-
    -
  • Critical Locales: en-US, es-ES require 95% minimum coverage
  • -
  • Warning Threshold: 80% triggers warnings during build
  • -
  • Incomplete Locales: 0% coverage allowed (inherit via fallback chain)
  • -
-

Testing Localization

-

Test translations via different methods:

-
# Test help system in Spanish
-LANG=es_ES provisioning help infrastructure
-
-# Test form display in Spanish
-LANG=es_ES provisioning setup profile
-
-# Validate all translation files
-provisioning i18n validate --all
-
-# Generate coverage report
-provisioning i18n coverage --format=json > coverage.json
-
-

Implementation Details

-

TypeDialog Integration

-

TypeDialog forms reference Fluent keys via locales_path configuration:

-
# In form.toml
-locales_path = "../../../locales"
-
-[[elements]]
-name = "project_name"
-prompt = "form-project_name-prompt"    # References: locales/*/forms.ftl
-help = "form-project_name-help"
-placeholder = "form-project_name-placeholder"
-
-

Resolution Process:

-
    -
  1. Read locales_path from form configuration
  2. -
  3. Check LANG environment variable (converted to locale format: es_ES → es-ES)
  4. -
  5. Load Fluent file (e.g., locales/es-ES/forms.ftl)
  6. -
  7. Resolve string key → value
  8. -
  9. If key missing, follow fallback chain
  10. -
  11. If still missing, use literal key name
  12. -
-

Help System Integration

-

Help system uses Fluent catalog loader in provisioning/core/nulib/main_provisioning/help_system.nu:

-
# Load help strings for current locale
-let help_strings = (load_fluent_catalog $locale)
-
-# Display localized help text
-print ($help_strings | get help-infrastructure-title)
-
-

Maintenance

-

Adding New Translations

-

When new help text or forms are added:

-
    -
  1. Add English strings to en-US/help.ftl or en-US/forms.ftl
  2. -
  3. Add Spanish translations to es-ES/help.ftl or es-ES/forms.ftl
  4. -
  5. Run validation: provisioning i18n validate
  6. -
  7. Update translations_status.md with new counts
  8. -
  9. If coverage drops below 95%, fix before release
  10. -
-

Updating Existing Translations

-

To modify existing translated string:

-
    -
  1. Edit key in en-US/*.ftl and all locale-specific files
  2. -
  3. Run validation to ensure consistency
  4. -
  5. Test in both languages: LANG=en_US provisioning help and LANG=es_ES provisioning help
  6. -
-

Current Translation Status

-

Last Updated: 2026-01-13 | Status: 100% Complete

-

String Count

-
- - - -
Componenten-USes-ESStatus
Help System6565✅ Complete
Forms180180✅ Complete
Total245245✅ Complete
-
-

Features Enabled

-
- - - - - - -
FeatureStatusPurpose
Pluralization✅ EnabledSupport language-specific plural rules
Number Formatting✅ EnabledLocale-specific number/currency formatting
Date Formatting✅ EnabledLocale-specific date display
Fallback Chains✅ EnabledAutomatic fallback to English
Gender Agreement⚠️ DisabledNot needed for Spanish help strings
RTL Support⚠️ DisabledNo RTL languages configured yet
-
- - -

- Provisioning Logo -

-

- Provisioning -

-

Operations

-

Production deployment, monitoring, maintenance, and operational best practices for running -Provisioning infrastructure at scale.

-

Overview

-

This section covers everything needed to operate Provisioning in production:

-
    -
  • Deployment strategies - Single-cloud, multi-cloud, hybrid with zero-downtime updates
  • -
  • Service management - Microservice lifecycle, scaling, health checks, failover
  • -
  • Observability - Metrics (Prometheus), logs (ELK), traces (Jaeger), dashboards
  • -
  • Incident response - Detection, triage, remediation, postmortem automation
  • -
  • Backup & recovery - Strategies, testing, disaster recovery, point-in-time restore
  • -
  • Performance optimization - Profiling, caching, scaling, resource optimization
  • -
  • Troubleshooting - Debugging, log analysis, diagnostic tools, support
  • -
-

Operational Guides

-

Deployment and Management

-
    -
  • -

    Deployment Modes - Single-cloud, multi-cloud, hybrid, canary, blue-green, rolling updates with zero downtime.

    -
  • -
  • -

    Service Management - Microservice lifecycle, scaling policies, health checks, graceful shutdown, rolling restarts.

    -
  • -
  • -

    Platform Installer - TUI and unattended installation, provider setup, workspace creation, post-install configuration.

    -
  • -
-

Monitoring and Observability

-

- Monitoring Stack Prometheus Grafana Fluentd ElasticSearch Alertmanager -

-
    -
  • -

    Monitoring Setup - Prometheus metrics, Grafana -dashboards, alerting rules, SLO monitoring, 12 microservices

    -
  • -
  • -

    Logging and Analysis - Centralized logging with ELK Stack, log aggregation, filtering, searching, performance analysis.

    -
  • -
  • -

    Distributed Tracing - Jaeger integration, span collection, trace visualization, latency analysis across microservices.

    -
  • -
-

Resilience and Recovery

-
    -
  • -

    Incident Response - Severity -levels, triage, investigation, mitigation, escalation, postmortem

    -
  • -
  • -

    Backup Strategies - Full, incremental, PITR backups with RTO/RPO targets, testing procedures, recovery workflows.

    -
  • -
  • -

    Disaster Recovery - DR planning, failover procedures, failback strategies, RTO/RPO targets, testing schedules.

    -
  • -
-

- Disaster Recovery Topology Multi-Region Failover Primary Backup -

- -

Troubleshooting

-
    -
  • -

    Troubleshooting Guide - Common issues, debugging techniques, log analysis, diagnostic tools, support resources.

    -
  • -
  • -

    Platform Health - Health check procedures, system status, component status, SLO metrics, error budgets.

    -
  • -
-

Operational Workflows

-

I’m deploying to production

-

Follow: Deployment ModesService ManagementMonitoring Setup

-

I need to monitor infrastructure

-

Setup: Monitoring Setup for metrics, Logging and Analysis for logs, Distributed Tracing for traces

-

I’m experiencing an incident

-

Execute: Incident Response with triage, investigation, mitigation, escalation

-

I need to backup and recover

-

Implement: Backup Strategies with testing, Disaster Recovery for major outages

-

I need to optimize performance

-

Follow: Performance Optimization for profiling and tuning

-

I need help troubleshooting

-

Consult: Troubleshooting Guide for common issues and solutions

-

Deployment Architecture

-
Development
-  ↓
-Staging (test all)
-  ↓
-Canary (1% traffic)
-  ↓
-Rolling (increase % gradually)
-  ↓
-Production (100%)
-
-

SLO Targets

-
- - - - - -
ServiceAvailabilityP99 LatencyError Budget
API Gateway99.99%<100ms4m 26s/month
Orchestrator99.9%<500ms43m 46s/month
Control-Center99.95%<300ms21m 56s/month
Detector99.5%<2s3h 36s/month
All Others99.9%<1s43m 46s/month
-
-

Monitoring Stack

-
    -
  • Metrics - Prometheus (15s scrape interval, 15d retention)
  • -
  • Logs - ELK Stack (Elasticsearch, Logstash, Kibana) with 30d retention
  • -
  • Traces - Jaeger (sampling 10%, 24h retention)
  • -
  • Dashboards - Grafana with pre-built dashboards per microservice
  • -
  • Alerting - AlertManager with escalation rules and notification channels
  • -
-

Operational Commands

-
# Check system health
-provisioning status health
-
-# View metrics
-provisioning metrics view --service orchestrator
-
-# Check SLO status
-provisioning slo status
-
-# Run diagnostics
-provisioning diagnose system
-
-# Backup infrastructure
-provisioning backup create --name daily-$(date +%Y%m%d)
-
-# Restore from backup
-provisioning backup restore --backup-id backup-id
-
- -
    -
  • Architecture → See provisioning/docs/src/architecture/
  • -
  • Features → See provisioning/docs/src/features/
  • -
  • Development → See provisioning/docs/src/development/
  • -
  • Security → See provisioning/docs/src/security/
  • -
  • Examples → See provisioning/docs/src/examples/
  • -
-

Deployment Modes

-

The Provisioning platform supports three deployment modes designed for different operational -contexts: interactive TUI for guided setup, headless CLI for automation, and unattended mode -for CI/CD pipelines.

-

Overview

-

Deployment modes determine how the platform installer and orchestrator interact with the environment:

-
- - - -
ModeUse CaseUser InteractionConfigurationRollback
Interactive TUIFirst-time setup, explorationFull interactive terminal UIGuided wizardManual intervention
Headless CLIScripted automationCommand-line flags onlyPre-configured filesAutomatic checkpoint
UnattendedCI/CD pipelinesZero interactionConfig file requiredAutomatic rollback
-
-

Interactive TUI Mode

-

Beautiful terminal user interface for guided platform installation and configuration.

-

When to Use

-
    -
  • First-time platform installation
  • -
  • Exploring configuration options
  • -
  • Learning platform features
  • -
  • Development and testing environments
  • -
  • Manual infrastructure provisioning
  • -
-

Features

-

Seven interactive screens with real-time validation:

-
    -
  1. Welcome Screen - Platform overview and prerequisites check
  2. -
  3. Deployment Mode Selection - Solo, MultiUser, CICD, Enterprise
  4. -
  5. Component Selection - Choose platform services to install
  6. -
  7. Configuration Builder - Interactive settings editor
  8. -
  9. Provider Setup - Cloud provider credentials and configuration
  10. -
  11. Review and Confirm - Summary before installation
  12. -
  13. Installation Progress - Real-time tracking with checkpoint recovery
  14. -
-

Starting Interactive Mode

-
# Launch interactive installer
-provisioning-installer
-
-# Or via main CLI
-provisioning install --mode tui
-
- -
Tab/Shift+Tab - Navigate fields
-Enter - Select/confirm
-Esc - Cancel/go back
-Arrow keys - Navigate lists
-Space - Toggle checkboxes
-Ctrl+C - Exit installer
-
-

Headless CLI Mode

-

Command-line interface for scripted automation without graphical interface.

-

When to Use

-
    -
  • Automated deployment scripts
  • -
  • Remote server installation via SSH
  • -
  • Reproducible infrastructure provisioning
  • -
  • Configuration management systems
  • -
  • Batch deployments across multiple servers
  • -
-

Features

-
    -
  • Non-interactive installation
  • -
  • Configuration via command-line flags
  • -
  • Pre-validation of all inputs
  • -
  • Structured JSON/YAML output
  • -
  • Exit codes for script integration
  • -
  • Checkpoint-based recovery
  • -
-

Command Syntax

-
provisioning-installer --headless \
-  --mode <sol| o multiuse| r cic| d enterprise> \
-  --components <comma-separated-list> \
-  --storage-path <path> \
-  --database <backend> \
-  --log-level <level> \
-  [--yes] \
-  [--config <file>]
-
-

Example Deployments

-

Solo developer setup:

-
provisioning-installer --headless \
-  --mode solo \
-  --components orchestrator,control-center \
-  --yes
-
-

CI/CD pipeline deployment:

-
provisioning-installer --headless \
-  --mode cicd \
-  --components orchestrator,vault-service \
-  --database surrealdb \
-  --yes
-
-

Enterprise production deployment:

-
provisioning-installer --headless \
-  --mode enterprise \
-  --config /etc/provisioning/enterprise.toml \
-  --yes
-
-

Unattended Mode

-

Zero-interaction deployment for fully automated CI/CD pipelines.

-

When to Use

-
    -
  • Continuous integration pipelines
  • -
  • Continuous deployment workflows
  • -
  • Infrastructure as Code provisioning
  • -
  • Automated testing environments
  • -
  • Container image builds
  • -
  • Cloud instance initialization
  • -
-

Requirements

-
    -
  1. Configuration file must exist and be valid
  2. -
  3. All required dependencies must be installed
  4. -
  5. Sufficient system resources must be available
  6. -
  7. Network connectivity to required services
  8. -
  9. Appropriate file system permissions
  10. -
-

Command Syntax

-
provisioning-installer --unattended --config <config-file>
-
-

Example CI/CD Integrations

-

GitHub Actions workflow:

-
name: Deploy Provisioning Platform
-on:
-  push:
-    branches: [main]
-
-jobs:
-  deploy:
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v3
-
-      - name: Install prerequisites
-        run: |
-          curl -sSL  [https://install.nushell.sh](https://install.nushell.sh) | sh
-          curl -sSL  [https://install.nickel-lang.org](https://install.nickel-lang.org) | sh
-
-      - name: Deploy provisioning platform
-        env:
-          PROVISIONING_DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
-          UPCLOUD_API_TOKEN: ${{ secrets.UPCLOUD_TOKEN }}
-        run: |
-          provisioning-installer --unattended --config ci-config.toml
-
-      - name: Verify deployment
-        run: |
-          curl -f  [http://localhost:8080/health](http://localhost:8080/health) | | exit 1
-
-

Resource Requirements by Mode

-

Solo Mode

-

Minimum: 2 CPU, 4GB RAM, 20GB disk -Recommended: 4 CPU, 8GB RAM, 50GB disk

-

MultiUser Mode

-

Minimum: 4 CPU, 8GB RAM, 50GB disk -Recommended: 8 CPU, 16GB RAM, 100GB disk

-

CICD Mode

-

Minimum: 8 CPU, 16GB RAM, 100GB disk -Recommended: 16 CPU, 32GB RAM, 500GB disk

-

Enterprise Mode

-

Minimum: 16 CPU, 32GB RAM, 500GB disk -Recommended: 32+ CPU, 64GB+ RAM, 1TB+ disk

-

Choosing the Right Mode

-
- - - - - - -
ScenarioRecommended ModeRationale
First-time installationInteractive TUIGuided setup with validation
Manual production setupInteractive TUIReview all settings before deployment
Ansible playbookHeadless CLIScriptable without GUI
Remote server via SSHHeadless CLIWorks without terminal UI
GitHub ActionsUnattendedZero interaction, strict validation
Docker image buildUnattendedNon-interactive environment
-
-

Best Practices

-

Interactive TUI Mode

-
    -
  • Review all configuration screens carefully
  • -
  • Save configuration for later reuse
  • -
  • Document custom settings
  • -
-

Headless CLI Mode

-
    -
  • Test configuration on development environment first
  • -
  • Use --check flag for dry-run validation
  • -
  • Store configurations in version control
  • -
  • Use environment variables for sensitive data
  • -
-

Unattended Mode

-
    -
  • Validate configuration files extensively before CI/CD deployment
  • -
  • Test rollback behavior in non-production environments
  • -
  • Monitor installation logs in real-time
  • -
  • Set up alerting for installation failures
  • -
  • Use idempotent operations to allow retry
  • -
- - -

Service Management

-

Managing the nine core platform services that power the Provisioning infrastructure automation platform.

-

Platform Services Overview

-

The platform consists of nine microservices providing execution, management, and supporting infrastructure:

-
- - - - - - - - - -
ServicePurposePortLanguageStatus
orchestratorWorkflow execution and task scheduling8080Rust + NushellProduction
control-centerBackend management API with RBAC8081RustProduction
control-center-uiWeb-based management interface8082WebProduction
mcp-serverAI-powered configuration assistance8083NushellActive
ai-serviceMachine learning and anomaly detection8084RustActive
vault-serviceSecrets management and KMS8085RustProduction
extension-registryOCI registry for extensions8086RustPlanned
api-gatewayUnified REST API routing8087RustPlanned
provisioning-daemonBackground service coordination8088RustDevelopment
-
-

Service Lifecycle Management

-

Starting Services

-

Systemd management (production):

-
# Start individual service
-sudo systemctl start provisioning-orchestrator
-
-# Start all platform services
-sudo systemctl start provisioning-*
-
-# Enable automatic start on boot
-sudo systemctl enable provisioning-orchestrator
-sudo systemctl enable provisioning-control-center
-sudo systemctl enable provisioning-vault-service
-
-

Manual start (development):

-
# Orchestrator
-cd provisioning/platform/crates/orchestrator
-cargo run --release
-
-# Control Center
-cd provisioning/platform/crates/control-center
-cargo run --release
-
-# MCP Server
-cd provisioning/platform/crates/mcp-server
-nu run.nu
-
-

Stopping Services

-
# Stop individual service
-sudo systemctl stop provisioning-orchestrator
-
-# Stop all platform services
-sudo systemctl stop provisioning-*
-
-# Graceful shutdown with 30-second timeout
-sudo systemctl stop --timeout 30 provisioning-orchestrator
-
-

Restarting Services

-
# Restart after configuration changes
-sudo systemctl restart provisioning-orchestrator
-
-# Reload configuration without restart
-sudo systemctl reload provisioning-control-center
-
-

Checking Service Status

-
# Status of all services
-systemctl status provisioning-*
-
-# Detailed status
-provisioning platform status
-
-# Health check endpoints
-curl  [http://localhost:8080/health](http://localhost:8080/health)  # Orchestrator
-curl  [http://localhost:8081/health](http://localhost:8081/health)  # Control Center
-curl  [http://localhost:8085/health](http://localhost:8085/health)  # Vault Service
-
-

Service Configuration

-

Configuration Files

-

Each service reads configuration from hierarchical sources:

-
/etc/provisioning/config.toml           # System defaults
-~/.config/provisioning/user_config.yaml # User overrides
-workspace/config/provisioning.yaml      # Workspace config
-
-

Orchestrator Configuration

-
# /etc/provisioning/orchestrator.toml
-[server]
-host = "0.0.0.0"
-port = 8080
-workers = 8
-
-[storage]
-persistence_dir = "/var/lib/provisioning/orchestrator"
-checkpoint_interval = 30
-
-[execution]
-max_parallel_tasks = 100
-retry_attempts = 3
-retry_backoff = "exponential"
-
-[api]
-enable_rest = true
-enable_grpc = false
-auth_required = true
-
-

Control Center Configuration

-
# /etc/provisioning/control-center.toml
-[server]
-host = "0.0.0.0"
-port = 8081
-
-[auth]
-jwt_algorithm = "RS256"
-access_token_ttl = 900
-refresh_token_ttl = 604800
-
-[rbac]
-policy_dir = "/etc/provisioning/policies"
-reload_interval = 60
-
-

Vault Service Configuration

-
# /etc/provisioning/vault-service.toml
-[vault]
-backend = "secretumvault"
-url = " [http://localhost:8200"](http://localhost:8200")
-token_env = "VAULT_TOKEN"
-
-[kms]
-envelope_encryption = true
-key_rotation_days = 90
-
-

Service Dependencies

-

Understanding service dependencies for proper startup order:

-
Database (SurrealDB)
-  ↓
-orchestrator (requires database)
-  ↓
-vault-service (requires orchestrator)
-  ↓
-control-center (requires orchestrator + vault)
-  ↓
-control-center-ui (requires control-center)
-  ↓
-mcp-server (requires control-center)
-  ↓
-ai-service (requires mcp-server)
-
-

Systemd handles dependencies automatically:

-
# /etc/systemd/system/provisioning-control-center.service
-[Unit]
-Description=Provisioning Control Center
-After=provisioning-orchestrator.service
-Requires=provisioning-orchestrator.service
-
-

Service Health Monitoring

-

Health Check Endpoints

-

All services expose /health endpoints:

-
# Check orchestrator health
-curl  [http://localhost:8080/health](http://localhost:8080/health)
-
-# Expected response
-{
-  "status": "healthy",
-  "version": "5.0.0",
-  "uptime_seconds": 3600,
-  "database": "connected",
-  "active_workflows": 5,
-  "queued_tasks": 12
-}
-
-

Automated Health Monitoring

-

Use systemd watchdog for automatic restart on failure:

-
# /etc/systemd/system/provisioning-orchestrator.service
-[Service]
-WatchdogSec=30
-Restart=on-failure
-RestartSec=10
-
-

Monitor with provisioning CLI:

-
# Continuous health monitoring
-provisioning platform monitor --interval 5
-
-# Alert on unhealthy services
-provisioning platform monitor --alert-email [ops@example.com](mailto:ops@example.com)
-
-

Log Management

-

Log Locations

-

Systemd services log to journald:

-
# View orchestrator logs
-sudo journalctl -u provisioning-orchestrator -f
-
-# View last hour of logs
-sudo journalctl -u provisioning-orchestrator --since "1 hour ago"
-
-# View errors only
-sudo journalctl -u provisioning-orchestrator -p err
-
-# Export logs to file
-sudo journalctl -u provisioning-* > platform-logs.txt
-
-

File-based logs:

-
/var/log/provisioning/orchestrator.log
-/var/log/provisioning/control-center.log
-/var/log/provisioning/vault-service.log
-
-

Log Rotation

-

Configure logrotate for file-based logs:

-
# /etc/logrotate.d/provisioning
-/var/log/provisioning/*.log {
-    daily
-    rotate 30
-    compress
-    delaycompress
-    missingok
-    notifempty
-    create 0644 provisioning provisioning
-    sharedscripts
-    postrotate
-        systemctl reload provisioning-* | | true
-    endscript
-}
-
-

Log Levels

-

Configure log verbosity:

-
# Set log level via environment
-export PROVISIONING_LOG_LEVEL=debug
-sudo systemctl restart provisioning-orchestrator
-
-# Or in configuration
-provisioning config set logging.level debug
-
-

Log levels: trace, debug, info, warn, error

-

Performance Tuning

-

Orchestrator Performance

-

Adjust worker threads and task limits:

-
[execution]
-max_parallel_tasks = 200  # Increase for high throughput
-worker_threads = 16       # Match CPU cores
-task_queue_size = 1000
-
-[performance]
-enable_metrics = true
-metrics_interval = 10
-
-

Database Connection Pooling

-
[database]
-max_connections = 100
-min_connections = 10
-connection_timeout = 30
-idle_timeout = 600
-
-

Memory Limits

-

Set memory limits via systemd:

-
[Service]
-MemoryMax=4G
-MemoryHigh=3G
-
-

Service Updates and Upgrades

-

Zero-Downtime Upgrades

-

Rolling upgrade procedure:

-
# 1. Deploy new version alongside old version
-sudo cp provisioning-orchestrator /usr/local/bin/provisioning-orchestrator-new
-
-# 2. Update systemd service to use new binary
-sudo systemctl daemon-reload
-
-# 3. Graceful restart
-sudo systemctl reload provisioning-orchestrator
-
-

Version Management

-

Check running versions:

-
provisioning platform versions
-
-# Output:
-# orchestrator: 5.0.0
-# control-center: 5.0.0
-# vault-service: 4.0.0
-
-

Rollback Procedure

-
# 1. Stop new version
-sudo systemctl stop provisioning-orchestrator
-
-# 2. Restore previous binary
-sudo cp /usr/local/bin/provisioning-orchestrator.backup \
-       /usr/local/bin/provisioning-orchestrator
-
-# 3. Start service with previous version
-sudo systemctl start provisioning-orchestrator
-
-

Security Hardening

-

Service Isolation

-

Run services with dedicated users:

-
# Create service user
-sudo useradd -r -s /usr/sbin/nologin provisioning
-
-# Set ownership
-sudo chown -R provisioning:provisioning /var/lib/provisioning
-sudo chown -R provisioning:provisioning /etc/provisioning
-
-

Systemd service configuration:

-
[Service]
-User=provisioning
-Group=provisioning
-NoNewPrivileges=true
-PrivateTmp=true
-ProtectSystem=strict
-ProtectHome=true
-
-

Network Security

-

Restrict service access with firewall:

-
# Allow only localhost access
-sudo ufw allow from 127.0.0.1 to any port 8080
-sudo ufw allow from 127.0.0.1 to any port 8081
-
-# Or use systemd socket activation
-
-

Troubleshooting Services

-

Service Won’t Start

-

Check service status and logs:

-
systemctl status provisioning-orchestrator
-journalctl -u provisioning-orchestrator -n 100
-
-

Common issues:

-
    -
  • Port already in use: Check with lsof -i :8080
  • -
  • Configuration error: Validate with provisioning validate config
  • -
  • Missing dependencies: Check with ldd /usr/local/bin/provisioning-orchestrator
  • -
  • Permission issues: Verify file ownership
  • -
-

High Resource Usage

-

Monitor resource consumption:

-
# CPU and memory usage
-systemctl status provisioning-orchestrator
-
-# Detailed metrics
-provisioning platform metrics --service orchestrator
-
-

Adjust limits:

-
# Increase memory limit
-sudo systemctl set-property provisioning-orchestrator MemoryMax=8G
-
-# Reduce parallel tasks
-provisioning config set execution.max_parallel_tasks 50
-sudo systemctl restart provisioning-orchestrator
-
-

Service Crashes

-

Enable core dumps for debugging:

-
# Enable core dumps
-sudo sysctl -w kernel.core_pattern=/var/crash/core.%e.%p
-ulimit -c unlimited
-
-# Analyze crash
-sudo coredumpctl list
-sudo coredumpctl debug
-
-

Service Metrics

-

Prometheus Integration

-

Services expose Prometheus metrics:

-
# Orchestrator metrics
-curl  [http://localhost:8080/metrics](http://localhost:8080/metrics)
-
-# Example metrics:
-# provisioning_workflows_total 1234
-# provisioning_workflows_active 5
-# provisioning_tasks_queued 12
-# provisioning_tasks_completed 9876
-
-

Grafana Dashboards

-

Import pre-built dashboards:

-
provisioning monitoring install-dashboards
-
-

Dashboards available at http://localhost:3000

-

Best Practices

-

Service Management

-
    -
  • Use systemd for production deployments
  • -
  • Enable automatic restart on failure
  • -
  • Monitor health endpoints continuously
  • -
  • Set appropriate resource limits
  • -
  • Implement log rotation
  • -
  • Regular backup of service data
  • -
-

Configuration Management

-
    -
  • Version control all configuration files
  • -
  • Use hierarchical configuration for flexibility
  • -
  • Validate configuration before applying
  • -
  • Document all custom settings
  • -
  • Use environment variables for secrets
  • -
-

Monitoring and Alerting

-
    -
  • Monitor all service health endpoints
  • -
  • Set up alerts for service failures
  • -
  • Track key performance metrics
  • -
  • Review logs regularly
  • -
  • Establish incident response procedures
  • -
- - -

Monitoring

-

Comprehensive observability stack for the Provisioning platform using Prometheus, Grafana, and custom metrics.

-

Monitoring Stack Overview

-

The platform monitoring system consists of:

-
- - - - - -
ComponentPurposePortStatus
PrometheusMetrics collection and storage9090Production
GrafanaVisualization and dashboards3000Production
LokiLog aggregation3100Active
AlertmanagerAlert routing and notification9093Production
Node ExporterSystem metrics9100Production
-
-

Quick Start

-

Install monitoring stack:

-
# Install all monitoring components
-provisioning monitoring install
-
-# Install specific components
-provisioning monitoring install --components prometheus,grafana
-
-# Start monitoring services
-provisioning monitoring start
-
-

Access dashboards:

- -

Prometheus Configuration

-

Service Discovery

-

Prometheus automatically discovers platform services:

-
# /etc/provisioning/prometheus/prometheus.yml
-global:
-  scrape_interval: 15s
-  evaluation_interval: 15s
-
-scrape_configs:
-  - job_name: 'provisioning-orchestrator'
-    static_configs:
-      - targets: ['localhost:8080']
-    metrics_path: '/metrics'
-
-  - job_name: 'provisioning-control-center'
-    static_configs:
-      - targets: ['localhost:8081']
-
-  - job_name: 'provisioning-vault-service'
-    static_configs:
-      - targets: ['localhost:8085']
-
-  - job_name: 'node-exporter'
-    static_configs:
-      - targets: ['localhost:9100']
-
-

Retention Configuration

-
global:
-  external_labels:
-    cluster: 'provisioning-production'
-
-# Storage retention
-storage:
-  tsdb:
-    retention.time: 30d
-    retention.size: 50GB
-
-

Key Metrics

-

Platform Metrics

-

Orchestrator metrics:

-
provisioning_workflows_total - Total workflows created
-provisioning_workflows_active - Currently active workflows
-provisioning_workflows_completed - Successfully completed workflows
-provisioning_workflows_failed - Failed workflows
-provisioning_tasks_queued - Tasks in queue
-provisioning_tasks_running - Currently executing tasks
-provisioning_tasks_completed - Total completed tasks
-provisioning_checkpoint_recoveries - Checkpoint recovery count
-
-

Control Center metrics:

-
provisioning_api_requests_total - Total API requests
-provisioning_api_requests_duration_seconds - Request latency histogram
-provisioning_auth_attempts_total - Authentication attempts
-provisioning_auth_failures_total - Failed authentication attempts
-provisioning_rbac_denials_total - Authorization denials
-
-

Vault Service metrics:

-
provisioning_secrets_operations_total - Secret operations count
-provisioning_kms_encryptions_total - Encryption operations
-provisioning_kms_decryptions_total - Decryption operations
-provisioning_kms_latency_seconds - KMS operation latency
-
-

System Metrics

-

Node Exporter provides system-level metrics:

-
node_cpu_seconds_total - CPU time per core
-node_memory_MemAvailable_bytes - Available memory
-node_disk_io_time_seconds_total - Disk I/O time
-node_network_receive_bytes_total - Network RX bytes
-node_network_transmit_bytes_total - Network TX bytes
-node_filesystem_avail_bytes - Available disk space
-
-

Grafana Dashboards

-

Pre-built Dashboards

-

Import platform dashboards:

-
# Install all pre-built dashboards
-provisioning monitoring install-dashboards
-
-# List available dashboards
-provisioning monitoring list-dashboards
-
-

Available dashboards:

-
    -
  1. Platform Overview - High-level system status
  2. -
  3. Orchestrator Performance - Workflow and task metrics
  4. -
  5. Control Center API - API request metrics and latency
  6. -
  7. Vault Service KMS - Encryption operations and performance
  8. -
  9. System Resources - CPU, memory, disk, network
  10. -
  11. Security Events - Authentication, authorization, audit logs
  12. -
  13. Database Performance - SurrealDB metrics
  14. -
-

Custom Dashboard Creation

-

Create custom dashboards via Grafana UI or provisioning:

-
{
-  "dashboard": {
-    "title": "Custom Infrastructure Dashboard",
-    "panels": [
-      {
-        "title": "Active Workflows",
-        "targets": [
-          {
-            "expr": "provisioning_workflows_active",
-            "legendFormat": "Active Workflows"
-          }
-        ],
-        "type": "graph"
-      }
-    ]
-  }
-}
-
-

Save dashboard:

-
provisioning monitoring export-dashboard --id 1 --output custom-dashboard.json
-
-

Alerting

-

Alert Rules

-

Configure alert rules in Prometheus:

-
# /etc/provisioning/prometheus/alerts/provisioning.yml
-groups:
-  - name: provisioning_alerts
-    interval: 30s
-    rules:
-      - alert: OrchestratorDown
-        expr: up{job="provisioning-orchestrator"} == 0
-        for: 1m
-        labels:
-          severity: critical
-        annotations:
-          summary: "Orchestrator service is down"
-          description: "Orchestrator has been down for more than 1 minute"
-
-      - alert: HighWorkflowFailureRate
-        expr: |
-          rate(provisioning_workflows_failed[5m]) /
-          rate(provisioning_workflows_total[5m]) > 0.1
-        for: 5m
-        labels:
-          severity: warning
-        annotations:
-          summary: "High workflow failure rate"
-          description: "More than 10% of workflows are failing"
-
-      - alert: DatabaseConnectionLoss
-        expr: provisioning_database_connected == 0
-        for: 30s
-        labels:
-          severity: critical
-        annotations:
-          summary: "Database connection lost"
-
-      - alert: HighMemoryUsage
-        expr: |
-          (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) > 0.9
-        for: 5m
-        labels:
-          severity: warning
-        annotations:
-          summary: "High memory usage"
-          description: "Memory usage is above 90%"
-
-      - alert: DiskSpaceLow
-        expr: |
-          (node_filesystem_avail_bytes{mountpoint="/var/lib/provisioning"} /
-           node_filesystem_size_bytes{mountpoint="/var/lib/provisioning"}) < 0.1
-        for: 5m
-        labels:
-          severity: warning
-        annotations:
-          summary: "Low disk space"
-          description: "Less than 10% disk space available"
-
-

Alertmanager Configuration

-

Route alerts to appropriate channels:

-
# /etc/provisioning/alertmanager/alertmanager.yml
-global:
-  resolve_timeout: 5m
-
-route:
-  group_by: ['alertname', 'severity']
-  group_wait: 10s
-  group_interval: 10s
-  repeat_interval: 12h
-  receiver: 'team-email'
-
-  routes:
-    - match:
-        severity: critical
-      receiver: 'pagerduty'
-      continue: true
-
-    - match:
-        severity: warning
-      receiver: 'slack'
-
-receivers:
-  - name: 'team-email'
-    email_configs:
-      - to: '[ops@example.com](mailto:ops@example.com)'
-        from: '[alerts@provisioning.example.com](mailto:alerts@provisioning.example.com)'
-        smarthost: 'smtp.example.com:587'
-
-  - name: 'pagerduty'
-    pagerduty_configs:
-      - service_key: '<pagerduty-key>'
-
-  - name: 'slack'
-    slack_configs:
-      - api_url: '<slack-webhook-url>'
-        channel: '#provisioning-alerts'
-
-

Test alerts:

-
# Send test alert
-provisioning monitoring test-alert --severity critical
-
-# Silence alerts temporarily
-provisioning monitoring silence --duration 2h --reason "Maintenance window"
-
-

Log Aggregation with Loki

-

Loki Configuration

-
# /etc/provisioning/loki/loki.yml
-auth_enabled: false
-
-server:
-  http_listen_port: 3100
-
-ingester:
-  lifecycler:
-    ring:
-      kvstore:
-        store: inmemory
-      replication_factor: 1
-
-schema_config:
-  configs:
-    - from: 2024-01-01
-      store: boltdb-shipper
-      object_store: filesystem
-      schema: v11
-      index:
-        prefix: index_
-        period: 24h
-
-storage_config:
-  boltdb_shipper:
-    active_index_directory: /var/lib/loki/boltdb-shipper-active
-    cache_location: /var/lib/loki/boltdb-shipper-cache
-  filesystem:
-    directory: /var/lib/loki/chunks
-
-limits_config:
-  retention_period: 720h  # 30 days
-
-

Promtail for Log Shipping

-
# /etc/provisioning/promtail/promtail.yml
-server:
-  http_listen_port: 9080
-
-positions:
-  filename: /tmp/positions.yaml
-
-clients:
-  - url:  [http://localhost:3100/loki/api/v1/push](http://localhost:3100/loki/api/v1/push)
-
-scrape_configs:
-  - job_name: system
-    static_configs:
-      - targets:
-          - localhost
-        labels:
-          job: varlogs
-          __path__: /var/log/provisioning/*.log
-
-  - job_name: journald
-    journal:
-      max_age: 12h
-      labels:
-        job: systemd-journal
-    relabel_configs:
-      - source_labels: ['__journal__systemd_unit']
-        target_label: 'unit'
-
-

Query logs in Grafana:

-
{job="varlogs"} | = "error"
-{unit="provisioning-orchestrator.service"} | = "workflow" | json
-
-

Tracing with Tempo

-

Distributed Tracing

-

Enable OpenTelemetry tracing in services:

-
# /etc/provisioning/config.toml
-[tracing]
-enabled = true
-exporter = "otlp"
-endpoint = "localhost:4317"
-service_name = "provisioning-orchestrator"
-
-

Tempo configuration:

-
# /etc/provisioning/tempo/tempo.yml
-server:
-  http_listen_port: 3200
-
-distributor:
-  receivers:
-    otlp:
-      protocols:
-        grpc:
-          endpoint: 0.0.0.0:4317
-
-storage:
-  trace:
-    backend: local
-    local:
-      path: /var/lib/tempo/traces
-
-query_frontend:
-  search:
-    enabled: true
-
-

View traces in Grafana or Tempo UI.

-

Performance Monitoring

-

Query Performance

-

Monitor slow queries:

-
# 95th percentile API latency
-histogram_quantile(0.95,
-  rate(provisioning_api_requests_duration_seconds_bucket[5m])
-)
-
-# Slow workflows (>60s)
-provisioning_workflow_duration_seconds > 60
-
-

Resource Monitoring

-

Track resource utilization:

-
# CPU usage per service
-rate(process_cpu_seconds_total{job=~"provisioning-.*"}[5m]) * 100
-
-# Memory usage per service
-process_resident_memory_bytes{job=~"provisioning-.*"}
-
-# Disk I/O rate
-rate(node_disk_io_time_seconds_total[5m])
-
-

Custom Metrics

-

Adding Custom Metrics

-

Rust services use prometheus crate:

-
use prometheus::{Counter, Histogram, Registry};
-
-// Create metrics
-let workflow_counter = Counter::new(
-    "provisioning_custom_workflows",
-    "Custom workflow counter"
-)?;
-
-let task_duration = Histogram::with_opts(
-    HistogramOpts::new("provisioning_task_duration", "Task duration")
-        .buckets(vec![0.1, 0.5, 1.0, 5.0, 10.0])
-)?;
-
-// Register metrics
-registry.register(Box::new(workflow_counter))?;
-registry.register(Box::new(task_duration))?;
-
-// Use metrics
-workflow_counter.inc();
-task_duration.observe(duration_seconds);
-

Nushell scripts export metrics:

-
# Export metrics in Prometheus format
-def export-metrics [] {
-    [
-        "# HELP provisioning_custom_metric Custom metric"
-        "# TYPE provisioning_custom_metric counter"
-        $"provisioning_custom_metric (get-metric-value)"
-    ] | str join "
-"
-}
-
-

Monitoring Best Practices

-
    -
  • Set appropriate scrape intervals (15-60s)
  • -
  • Configure retention based on compliance requirements
  • -
  • Use labels for multi-dimensional metrics
  • -
  • Create dashboards for key business metrics
  • -
  • Set up alerts for critical failures only
  • -
  • Document alert thresholds and runbooks
  • -
  • Review and tune alerts regularly
  • -
  • Use recording rules for expensive queries
  • -
  • Archive long-term metrics to object storage
  • -
- - -

Backup & Recovery

-

Comprehensive backup strategies and disaster recovery procedures for the Provisioning platform.

-

Overview

-

The platform backup strategy covers:

-
    -
  • Platform service data and state
  • -
  • Database backups (SurrealDB)
  • -
  • Configuration files and secrets
  • -
  • Infrastructure definitions
  • -
  • Workflow checkpoints and history
  • -
  • Audit logs and compliance data
  • -
-

Backup Components

-

Critical Data

-
- - - - - - - -
ComponentLocationBackup PriorityRecovery Time
Database/var/lib/provisioning/databaseCritical< 15 min
Orchestrator State/var/lib/provisioning/orchestratorCritical< 5 min
Configuration/etc/provisioningHigh< 5 min
SecretsSOPS-encrypted filesCritical< 5 min
Audit Logs/var/log/provisioning/auditCompliance< 30 min
Workspace Dataworkspace/High< 15 min
Infrastructure Schemasprovisioning/schemasHigh< 10 min
-
-

Backup Strategies

-

Full Backup

-

Complete system backup including all components:

-
# Create full backup
-provisioning backup create --type full --output /backups/full-$(date +%Y%m%d).tar.gz
-
-# Full backup includes:
-# - Database dump
-# - Service configuration
-# - Workflow state
-# - Audit logs
-# - User data
-
-

Contents of full backup:

-
full-20260116.tar.gz
-├── database/
-│   └── surrealdb-dump.sql
-├── config/
-│   ├── provisioning.toml
-│   ├── orchestrator.toml
-│   └── control-center.toml
-├── state/
-│   ├── workflows/
-│   └── checkpoints/
-├── logs/
-│   └── audit/
-├── workspace/
-│   ├── infra/
-│   └── config/
-└── metadata.json
-
-

Incremental Backup

-

Backup only changed data since last backup:

-
# Incremental backup (faster, smaller)
-provisioning backup create --type incremental --since-backup full-20260116
-
-# Incremental backup includes:
-# - New workflows since last backup
-# - Configuration changes
-# - New audit log entries
-# - Modified workspace files
-
-

Continuous Backup

-

Real-time backup of critical data:

-
# Enable continuous backup
-provisioning backup enable-continuous --destination s3://backups/continuous
-
-# WAL archiving for database
-# Real-time checkpoint backup
-# Audit log streaming
-
-

Backup Commands

-

Create Backup

-
# Full backup to local directory
-provisioning backup create --type full --output /backups
-
-# Incremental backup
-provisioning backup create --type incremental
-
-# Backup specific components
-provisioning backup create --components database,config
-
-# Compressed backup
-provisioning backup create --compress gzip
-
-# Encrypted backup
-provisioning backup create --encrypt --key-file /etc/provisioning/backup.key
-
-

List Backups

-
# List all backups
-provisioning backup list
-
-# Output:
-# NAME                  TYPE         SIZE    DATE                STATUS
-# full-20260116        Full         2.5GB   2026-01-16 10:00   Complete
-# incr-20260116-1200   Incremental  150MB   2026-01-16 12:00   Complete
-# full-20260115        Full         2.4GB   2026-01-15 10:00   Complete
-
-

Restore Backup

-
# Restore full backup
-provisioning backup restore --backup full-20260116 --confirm
-
-# Restore specific components
-provisioning backup restore --backup full-20260116 --components database
-
-# Point-in-time restore
-provisioning backup restore --timestamp "2026-01-16 09:30:00"
-
-# Dry-run restore
-provisioning backup restore --backup full-20260116 --dry-run
-
-

Verify Backup

-
# Verify backup integrity
-provisioning backup verify --backup full-20260116
-
-# Test restore in isolated environment
-provisioning backup test-restore --backup full-20260116
-
-

Automated Backup Scheduling

-

Cron-based Backups

-
# Install backup cron jobs
-provisioning backup schedule install
-
-# Default schedule:
-# Full backup: Daily at 2 AM
-# Incremental: Every 6 hours
-# Cleanup old backups: Weekly
-
-

Crontab entries:

-
# Full daily backup
-0 2 * * * /usr/local/bin/provisioning backup create --type full --output /backups
-
-# Incremental every 6 hours
-0 */6 * * * /usr/local/bin/provisioning backup create --type incremental
-
-# Cleanup backups older than 30 days
-0 3 * * 0 /usr/local/bin/provisioning backup cleanup --older-than 30d
-
-

Systemd Timer-based Backups

-
# /etc/systemd/system/provisioning-backup.timer
-[Unit]
-Description=Provisioning Platform Backup Timer
-
-[Timer]
-OnCalendar=daily
-OnCalendar=02:00
-Persistent=true
-
-[Install]
-WantedBy=timers.target
-
-
# /etc/systemd/system/provisioning-backup.service
-[Unit]
-Description=Provisioning Platform Backup
-
-[Service]
-Type=oneshot
-ExecStart=/usr/local/bin/provisioning backup create --type full
-User=provisioning
-
-

Enable timer:

-
sudo systemctl enable provisioning-backup.timer
-sudo systemctl start provisioning-backup.timer
-
-

Backup Destinations

-

Local Filesystem

-
# Backup to local directory
-provisioning backup create --output /mnt/backups
-
-

Remote Storage

-

S3-compatible storage:

-
# Backup to S3
-provisioning backup create --destination s3://my-bucket/backups \
-  --s3-region us-east-1
-
-# Backup to MinIO
-provisioning backup create --destination s3://backups \
-  --s3-endpoint  [http://minio.local:9000](http://minio.local:9000)
-
-

Network filesystem:

-
# Backup to NFS mount
-provisioning backup create --output /mnt/nfs/backups
-
-# Backup to SMB share
-provisioning backup create --output /mnt/smb/backups
-
-

Off-site Backup

-

Rsync to remote server:

-
# Backup and sync to remote
-provisioning backup create --output /backups
-rsync -avz /backups/ backup-server:/backups/provisioning/
-
-

Database Backup

-

SurrealDB Backup

-
# Export database
-surreal export --conn  [http://localhost:8000](http://localhost:8000) \
-  --user root --pass root \
-  --ns provisioning --db main \
-  /backups/database-$(date +%Y%m%d).surql
-
-# Import database
-surreal import --conn  [http://localhost:8000](http://localhost:8000) \
-  --user root --pass root \
-  --ns provisioning --db main \
-  /backups/database-20260116.surql
-
-

Automated Database Backups

-
# Enable automatic database backups
-provisioning backup database enable --interval daily
-
-# Backup with point-in-time recovery
-provisioning backup database create --enable-pitr
-
-

Disaster Recovery

-

Recovery Procedures

-

Complete platform recovery from backup:

-
# 1. Stop all services
-sudo systemctl stop provisioning-*
-
-# 2. Restore database
-provisioning backup restore --backup full-20260116 --components database
-
-# 3. Restore configuration
-provisioning backup restore --backup full-20260116 --components config
-
-# 4. Restore service state
-provisioning backup restore --backup full-20260116 --components state
-
-# 5. Verify data integrity
-provisioning validate-installation
-
-# 6. Start services
-sudo systemctl start provisioning-*
-
-# 7. Verify services
-provisioning platform status
-
-

Recovery Time Objectives

-
- - - - -
ScenarioRTORPOProcedure
Service failure5 min0Restart service from checkpoint
Database corruption15 min6 hoursRestore from incremental backup
Complete data loss30 min24 hoursRestore from full backup
Site disaster2 hours24 hoursRestore from off-site backup
-
-

Point-in-Time Recovery

-

Restore to specific timestamp:

-
# List available recovery points
-provisioning backup list-recovery-points
-
-# Restore to specific time
-provisioning backup restore --timestamp "2026-01-16 09:30:00"
-
-# Recovery with workflow replay
-provisioning backup restore --timestamp "2026-01-16 09:30:00" --replay-workflows
-
-

Backup Encryption

-

SOPS Encryption

-

Encrypt backups with SOPS:

-
# Create encrypted backup
-provisioning backup create --encrypt sops --key-file /etc/provisioning/age.key
-
-# Restore encrypted backup
-provisioning backup restore --backup encrypted-20260116.tar.gz.enc \
-  --decrypt sops --key-file /etc/provisioning/age.key
-
-

Age Encryption

-
# Generate age key pair
-age-keygen -o /etc/provisioning/backup-key.txt
-
-# Create encrypted backup with age
-provisioning backup create --encrypt age --recipient "age1..."
-
-# Decrypt and restore
-age -d -i /etc/provisioning/backup-key.txt backup.tar.gz.age | \
-  provisioning backup restore --stdin
-
-

Backup Retention

-

Retention Policies

-
# /etc/provisioning/backup-retention.toml
-[retention]
-# Keep daily backups for 7 days
-daily = 7
-
-# Keep weekly backups for 4 weeks
-weekly = 4
-
-# Keep monthly backups for 12 months
-monthly = 12
-
-# Keep yearly backups for 7 years (compliance)
-yearly = 7
-
-

Apply retention policy:

-
# Cleanup old backups according to policy
-provisioning backup cleanup --policy /etc/provisioning/backup-retention.toml
-
-

Backup Monitoring

-

Backup Alerts

-

Configure alerts for backup failures:

-
# Prometheus alert for failed backups
-- alert: BackupFailed
-  expr: provisioning_backup_status{status="failed"} > 0
-  for: 5m
-  labels:
-    severity: critical
-  annotations:
-    summary: "Backup failed"
-    description: "Backup has failed, investigate immediately"
-
-

Backup Metrics

-

Monitor backup health:

-
# Backup success rate
-provisioning_backup_success_rate{type="full"} 1.0
-
-# Time since last backup
-time() - provisioning_backup_last_success_timestamp > 86400
-
-# Backup size trend
-increase(provisioning_backup_size_bytes[7d])
-
-

Testing Recovery Procedures

-

Regular DR Drills

-
# Automated disaster recovery test
-provisioning backup test-recovery --backup full-20260116 \
-  --test-environment isolated
-
-# Steps performed:
-# 1. Spin up isolated test environment
-# 2. Restore backup
-# 3. Verify data integrity
-# 4. Run smoke tests
-# 5. Generate test report
-# 6. Teardown test environment
-
-

Schedule monthly DR tests:

-
# Monthly disaster recovery drill
-0 4 1 * * /usr/local/bin/provisioning backup test-recovery --latest
-
-

Best Practices

-
    -
  • Implement 3-2-1 backup rule: 3 copies, 2 different media, 1 off-site
  • -
  • Encrypt all backups containing sensitive data
  • -
  • Test restore procedures regularly (monthly minimum)
  • -
  • Monitor backup success/failure metrics
  • -
  • Automate backup verification
  • -
  • Document recovery procedures and RTO/RPO
  • -
  • Maintain off-site backups for disaster recovery
  • -
  • Use incremental backups to reduce storage costs
  • -
  • Version control infrastructure schemas separately
  • -
  • Retain audit logs per compliance requirements (7 years)
  • -
- - -

Upgrading Provisioning

-

Upgrade Provisioning to a new version with minimal downtime and automatic rollback support.

-

Overview

-

Provisioning supports two upgrade strategies:

-
    -
  1. In-Place Upgrade - Update existing installation
  2. -
  3. Side-by-Side Upgrade - Run new version alongside old, switch when ready
  4. -
-

Both strategies support automatic rollback on failure.

-

Before Upgrading

-

Check Current Version

-
provisioning version
-
-# Example output:
-# Provisioning v5.0.0
-# Nushell 0.109.0
-# Nickel 1.15.1
-# SOPS 3.10.2
-# Age 1.2.1
-
-

Backup Configuration

-
# Backup entire workspace
-provisioning workspace backup
-
-# Backup specific configuration
-provisioning config backup
-
-# Backup state
-provisioning state backup
-
-

Check Changelog

-
# View latest changes
-provisioning changelog
-
-# Check upgrade path
-provisioning version --check-upgrade
-
-# Show upgrade recommendations
-provisioning upgrade --check
-
-

Verify System Health

-
# Health check
-provisioning health check
-
-# Check all services
-provisioning platform health
-
-# Verify provider connectivity
-provisioning providers test --all
-
-# Validate configuration
-provisioning validate config --strict
-
-

Upgrade Methods

-

Method 1: In-Place Upgrade

-

Upgrade the existing installation with zero downtime:

-
# Check upgrade compatibility
-provisioning upgrade --check
-
-# List breaking changes
-provisioning upgrade --breaking-changes
-
-# Show migration guide (if any)
-provisioning upgrade --show-migration
-
-# Perform upgrade
-provisioning upgrade
-
-

Process:

-
    -
  1. Validate current installation
  2. -
  3. Download new version
  4. -
  5. Run migration scripts (if needed)
  6. -
  7. Restart services
  8. -
  9. Verify health
  10. -
  11. Keep old version for rollback (24 hours)
  12. -
-

Method 2: Side-by-Side Upgrade

-

Run new version alongside old version for testing:

-
# Create staging installation
-provisioning upgrade --staging --version v5.1.0
-
-# Test new version
-provisioning --staging server list
-
-# Run test suite
-provisioning --staging test suite
-
-# Switch to new version
-provisioning upgrade --activate
-
-# Remove old version (after confirmation)
-provisioning upgrade --cleanup-old
-
-

Advantages:

-
    -
  • Test new version before switching
  • -
  • Zero downtime during upgrade
  • -
  • Easy rollback to previous version
  • -
  • Run both versions simultaneously
  • -
-

Upgrade Process

-

Step 1: Pre-Upgrade Checks

-
# Check system requirements
-provisioning setup validate
-
-# Verify dependencies are up-to-date
-provisioning version --check-dependencies
-
-# Check disk space (minimum 2GB required)
-df -h /
-
-# Verify all services healthy
-provisioning platform health
-
-

Step 2: Backup Data

-
# Backup entire workspace
-provisioning workspace backup --compress
-
-# Backup orchestrator state
-provisioning orchestrator backup
-
-# Backup configuration
-provisioning config backup
-
-# Verify backup
-provisioning backup list
-provisioning backup verify --latest
-
-

Step 3: Download New Version

-
# Check available versions
-provisioning version --available
-
-# Download specific version
-provisioning upgrade --download v5.1.0
-
-# Verify download
-provisioning upgrade --verify-download v5.1.0
-
-# Check size
-provisioning upgrade --show-size v5.1.0
-
-

Step 4: Run Migration Scripts

-
# Show required migrations
-provisioning upgrade --show-migrations
-
-# Test migration (dry-run)
-provisioning upgrade --dry-run
-
-# Run migrations
-provisioning upgrade --migrate
-
-# Verify migration
-provisioning upgrade --verify-migration
-
-

Step 5: Perform Upgrade

-
# Stop orchestrator gracefully
-provisioning orchestrator stop --graceful
-
-# Install new version
-provisioning upgrade --install
-
-# Verify installation
-provisioning version
-provisioning validate config
-
-# Start services
-provisioning orchestrator start
-
-

Step 6: Verify Upgrade

-
# Check version
-provisioning version
-
-# Health check
-provisioning health check
-
-# Run test suite
-provisioning test quick
-
-# Verify provider connectivity
-provisioning providers test --all
-
-# Check orchestrator status
-provisioning orchestrator status
-
-

Breaking Changes

-

Some upgrades may include breaking changes. Check before upgrading:

-
# List breaking changes
-provisioning upgrade --breaking-changes
-
-# Show migration guide
-provisioning upgrade --migration-guide v5.1.0
-
-# Generate migration script
-provisioning upgrade --generate-migration v5.1.0 > migrate.nu
-
-

Common Migration Scenarios

-

Scenario 1: Configuration Format Change

-

If configuration format changes (e.g., TOML → YAML):

-
# Export old format
-provisioning config export --format toml > config.old.toml
-
-# Run migration
-provisioning upgrade --migrate-config
-
-# Verify new format
-provisioning config export --format yaml | head -20
-
-

Scenario 2: Schema Updates

-

If infrastructure schemas change:

-
# Validate against new schema
-nickel typecheck workspace/infra/*.ncl
-
-# Update schemas if needed
-provisioning upgrade --update-schemas
-
-# Regenerate configurations
-provisioning config regenerate
-
-# Validate updated config
-provisioning validate config --strict
-
-

Scenario 3: Provider API Changes

-

If provider APIs change:

-
# Test provider connectivity with new version
-provisioning providers test upcloud --verbose
-
-# Check provider configuration
-provisioning config show --section providers.upcloud
-
-# Update provider configuration if needed
-provisioning providers configure upcloud
-
-# Verify connectivity
-provisioning server list
-
-

Rollback Procedure

-

Automatic Rollback

-

If upgrade fails, automatic rollback occurs:

-
# Monitor rollback progress
-provisioning upgrade --watch
-
-# Check rollback status
-provisioning upgrade --status
-
-# View rollback logs
-provisioning upgrade --logs
-
-

Manual Rollback

-

If needed, manually rollback to previous version:

-
# List available versions for rollback
-provisioning upgrade --rollback-candidates
-
-# Rollback to specific version
-provisioning upgrade --rollback v5.0.0
-
-# Verify rollback
-provisioning version
-provisioning platform health
-
-# Restore from backup
-provisioning backup restore --backup-id=<id>
-
-

Batch Workflow Handling

-

If you have running batch workflows:

-
# Check running workflows
-provisioning workflow list --status running
-
-# Graceful shutdown (wait for completion)
-provisioning workflow shutdown --graceful
-
-# Force shutdown (immediate)
-provisioning workflow shutdown --force
-
-# Resume workflows after upgrade
-provisioning workflow resume
-
-

Troubleshooting Upgrades

-

Upgrade Hangs

-
# Check logs
-tail -f ~/.provisioning/logs/upgrade.log
-
-# Monitor process
-provisioning upgrade --monitor
-
-# Stop upgrade gracefully
-provisioning upgrade --stop --graceful
-
-# Force stop
-provisioning upgrade --stop --force
-
-

Migration Failure

-
# Check migration logs
-provisioning upgrade --migration-logs
-
-# Rollback to previous version
-provisioning upgrade --rollback
-
-# Restore from backup
-provisioning backup restore
-
-

Service Won’t Start

-
# Check service logs
-provisioning platform logs
-
-# Verify configuration
-provisioning validate config --strict
-
-# Restore configuration from backup
-provisioning config restore
-
-# Restart services
-provisioning orchestrator start
-
-

Upgrade Scheduling

-

Schedule Automated Upgrade

-
# Schedule upgrade for specific time
-provisioning upgrade --schedule "2026-01-20T02:00:00"
-
-# Schedule for next maintenance window
-provisioning upgrade --schedule-next-maintenance
-
-# Cancel scheduled upgrade
-provisioning upgrade --cancel-scheduled
-
-

Unattended Upgrade

-

For CI/CD environments:

-
# Non-interactive upgrade
-provisioning upgrade --yes --no-confirm
-
-# Upgrade with timeout
-provisioning upgrade --timeout 3600
-
-# Skip backup
-provisioning upgrade --skip-backup
-
-# Continue even if health checks fail
-provisioning upgrade --force-upgrade
-
-

Version Management

-

Version Constraints

-

Pin versions for workspace reproducibility:

-
# workspace/versions.ncl
-{
-  provisioning = "5.0.0"
-  nushell = "0.109.0"
-  nickel = "1.15.1"
-  sops = "3.10.2"
-  age = "1.2.1"
-}
-
-

Enforce version constraints:

-
# Check version compliance
-provisioning version --check-constraints
-
-# Enforce constraint
-provisioning version --strict-mode
-
-

Vendor Versions

-

Pin provider and task service versions:

-
# workspace/infra/versions.ncl
-{
-  providers = {
-    upcloud = "2.0.0"
-    aws = "5.0.0"
-  }
-  taskservs = {
-    kubernetes = "1.28.0"
-    postgres = "14.0"
-  }
-}
-
-

Best Practices

-

1. Plan Upgrades

-
    -
  • Schedule during maintenance windows
  • -
  • Test in staging first
  • -
  • Communicate with team
  • -
  • Have rollback plan ready
  • -
-

2. Backup Everything

-
# Complete backup before upgrade
-provisioning workspace backup --compress
-provisioning config backup
-provisioning state backup
-
-

3. Test Before Upgrading

-
# Use side-by-side upgrade to test
-provisioning upgrade --staging
-provisioning test suite
-
-

4. Monitor After Upgrade

-
# Watch orchestrator
-provisioning orchestrator status --watch
-
-# Monitor platform health
-provisioning platform monitor
-
-# Check logs
-tail -f ~/.provisioning/logs/provisioning.log
-
-

5. Document Changes

-
# Record what changed
-provisioning upgrade --changelog > UPGRADE.md
-
-# Update team documentation
-# Update runbooks
-# Update dashboards
-
-

Upgrade Policies

-

Automatic Updates

-

Enable automatic updates:

-
# ~/.config/provisioning/user_config.yaml
-upgrade:
-  auto_update: true
-  check_interval: "daily"
-  update_channel: "stable"
-  auto_backup: true
-
-

Update Channels

-

Choose update channel:

-
# Stable releases (recommended)
-provisioning upgrade --channel stable
-
-# Beta releases
-provisioning upgrade --channel beta
-
-# Development (nightly)
-provisioning upgrade --channel development
-
- - -

Troubleshooting

-

Common issues, debugging procedures, and resolution strategies for the Provisioning platform.

-

Quick Diagnosis

-

Run platform diagnostics:

-
# Comprehensive health check
-provisioning diagnose
-
-# Check specific component
-provisioning diagnose --component orchestrator
-
-# Generate diagnostic report
-provisioning diagnose --report /tmp/diagnostics.txt
-
-

Common Issues

-

Services Won’t Start

-

Symptom: Service fails to start or crashes immediately

-

Diagnosis:

-
# Check service status
-systemctl status provisioning-orchestrator
-
-# View recent logs
-journalctl -u provisioning-orchestrator -n 100 --no-pager
-
-# Check configuration
-provisioning validate config
-
-

Common Causes:

-
    -
  1. Port already in use
  2. -
-
# Find process using port
-lsof -i :8080
-
-# Kill conflicting process or change port in config
-
-
    -
  1. Configuration error
  2. -
-
# Validate configuration
-provisioning validate config --strict
-
-# Check for syntax errors
-nickel typecheck /etc/provisioning/config.ncl
-
-
    -
  1. Missing dependencies
  2. -
-
# Check binary dependencies
-ldd /usr/local/bin/provisioning-orchestrator
-
-# Install missing libraries
-sudo apt install <missing-library>
-
-
    -
  1. Permission issues
  2. -
-
# Fix ownership
-sudo chown -R provisioning:provisioning /var/lib/provisioning
-sudo chown -R provisioning:provisioning /etc/provisioning
-
-# Fix permissions
-sudo chmod 750 /var/lib/provisioning
-sudo chmod 640 /etc/provisioning/*.toml
-
-

Database Connection Failures

-

Symptom: Services can’t connect to SurrealDB

-

Diagnosis:

-
# Check database status
-systemctl status surrealdb
-
-# Test database connectivity
-curl  [http://localhost:8000/health](http://localhost:8000/health)
-
-# Check database logs
-journalctl -u surrealdb -n 50
-
-

Resolution:

-
# Restart database
-sudo systemctl restart surrealdb
-
-# Verify connection string in config
-provisioning config get database.url
-
-# Test manual connection
-surreal sql --conn  [http://localhost:8000](http://localhost:8000) --user root --pass root
-
-

High Resource Usage

-

Symptom: Service consuming excessive CPU or memory

-

Diagnosis:

-
# Monitor resource usage
-top -p $(pgrep provisioning-orchestrator)
-
-# Detailed metrics
-provisioning platform metrics --service orchestrator
-
-# Check for resource leaks
-
-

Resolution:

-
# Adjust worker threads
-provisioning config set execution.worker_threads 4
-
-# Reduce parallel tasks
-provisioning config set execution.max_parallel_tasks 50
-
-# Increase memory limit
-sudo systemctl set-property provisioning-orchestrator MemoryMax=8G
-
-# Restart service
-sudo systemctl restart provisioning-orchestrator
-
-

Workflow Failures

-

Symptom: Workflows fail or hang

-

Diagnosis:

-
# List failed workflows
-provisioning workflow list --status failed
-
-# View workflow details
-provisioning workflow show <workflow-id>
-
-# Check workflow logs
-provisioning workflow logs <workflow-id>
-
-# Inspect checkpoint state
-provisioning workflow checkpoints <workflow-id>
-
-

Common Issues:

-
    -
  1. Provider API errors
  2. -
-
# Check provider credentials
-provisioning provider validate upcloud
-
-# Test provider connectivity
-provisioning provider test upcloud
-
-
    -
  1. Dependency resolution failures
  2. -
-
# Validate infrastructure schema
-provisioning validate infra my-cluster.ncl
-
-# Check task service dependencies
-provisioning taskserv deps kubernetes
-
-
    -
  1. Timeout issues
  2. -
-
# Increase timeout
-provisioning config set workflows.task_timeout 600
-
-# Enable detailed logging
-provisioning config set logging.level debug
-
-

Network Connectivity Issues

-

Symptom: Can’t reach external services or cloud providers

-

Diagnosis:

-
# Test network connectivity
-ping -c 3 upcloud.com
-
-# Check DNS resolution
-nslookup api.upcloud.com
-
-# Test HTTPS connectivity
-curl -v  [https://api.upcloud.com](https://api.upcloud.com)
-
-# Check proxy settings
-env | grep -i proxy
-
-

Resolution:

-
# Configure proxy if needed
-export HTTPS_PROXY= [http://proxy.example.com:8080](http://proxy.example.com:8080)
-provisioning config set network.proxy  [http://proxy.example.com:8080](http://proxy.example.com:8080)
-
-# Verify firewall rules
-sudo ufw status
-
-# Check routing
-ip route show
-
-

Authentication Failures

-

Symptom: API requests fail with 401 Unauthorized

-

Diagnosis:

-
# Check JWT token
-provisioning auth status
-
-# Verify user credentials
-provisioning auth whoami
-
-# Check authentication logs
-journalctl -u provisioning-control-center | grep "auth"
-
-

Resolution:

-
# Refresh authentication token
-provisioning auth login --username admin
-
-# Reset user password
-provisioning auth reset-password --username admin
-
-# Verify MFA configuration
-provisioning auth mfa status
-
-

Debugging Workflows

-

Enable Debug Logging

-
# Enable debug mode
-export PROVISIONING_LOG_LEVEL=debug
-provisioning workflow create my-cluster --debug
-
-# Or in configuration
-provisioning config set logging.level debug
-sudo systemctl restart provisioning-orchestrator
-
-

Workflow State Inspection

-
# View workflow state
-provisioning workflow state <workflow-id>
-
-# Export workflow state to JSON
-provisioning workflow state <workflow-id> --format json > workflow-state.json
-
-# Inspect checkpoints
-provisioning workflow checkpoints <workflow-id>
-
-

Manual Workflow Retry

-
# Retry failed workflow from last checkpoint
-provisioning workflow retry <workflow-id>
-
-# Retry from specific checkpoint
-provisioning workflow retry <workflow-id> --from-checkpoint 3
-
-# Force retry (skip validation)
-provisioning workflow retry <workflow-id> --force
-
-

Performance Troubleshooting

-

Slow Workflow Execution

-

Diagnosis:

-
# Profile workflow execution
-provisioning workflow profile <workflow-id>
-
-# Identify bottlenecks
-provisioning workflow analyze <workflow-id>
-
-

Optimization:

-
# Increase parallelism
-provisioning config set execution.max_parallel_tasks 200
-
-# Optimize database queries
-provisioning database analyze
-
-# Add caching
-provisioning config set cache.enabled true
-
-

Database Performance Issues

-

Diagnosis:

-
# Check database metrics
-curl  [http://localhost:8000/metrics](http://localhost:8000/metrics)
-
-# Identify slow queries
-provisioning database slow-queries
-
-# Check connection pool
-provisioning database pool-status
-
-

Optimization:

-
# Increase connection pool
-provisioning config set database.max_connections 200
-
-# Add indexes
-provisioning database create-indexes
-
-# Optimize vacuum settings
-provisioning database vacuum
-
-

Log Analysis

-

Centralized Log Viewing

-
# View all platform logs
-journalctl -u provisioning-* -f
-
-# Filter by severity
-journalctl -u provisioning-* -p err
-
-# Export logs for analysis
-journalctl -u provisioning-* --since "1 hour ago" > /tmp/logs.txt
-
-

Structured Log Queries

-

Using Loki with LogQL:

-
# Find errors in orchestrator
-{job="provisioning-orchestrator"} | = "ERROR"
-
-# Workflow failures
-{job="provisioning-orchestrator"} | json | status="failed"
-
-# API request latency over 1s
-{job="provisioning-control-center"} | json | duration > 1
-
-

Log Correlation

-
# Correlate logs by request ID
-journalctl -u provisioning-* | grep "request_id=abc123"
-
-# Trace workflow execution
-provisioning workflow trace <workflow-id>
-
-

Advanced Debugging

-

Enable Rust Backtrace

-
# Enable backtrace for Rust services
-export RUST_BACKTRACE=1
-sudo systemctl restart provisioning-orchestrator
-
-# Full backtrace
-export RUST_BACKTRACE=full
-
-

Core Dump Analysis

-
# Enable core dumps
-sudo sysctl -w kernel.core_pattern=/var/crash/core.%e.%p
-ulimit -c unlimited
-
-# Analyze core dump
-sudo coredumpctl list
-sudo coredumpctl debug <pid>
-
-# In gdb:
-(gdb) bt
-(gdb) info threads
-(gdb) thread apply all bt
-
-

Network Traffic Analysis

-
# Capture API traffic
-sudo tcpdump -i any -w /tmp/api-traffic.pcap port 8080
-
-# Analyze with tshark
-tshark -r /tmp/api-traffic.pcap -Y "http"
-
-

Getting Help

-

Collect Diagnostic Information

-
# Generate comprehensive diagnostic report
-provisioning diagnose --full --output /tmp/diagnostics.tar.gz
-
-# Report includes:
-# - Service status
-# - Configuration files
-# - Recent logs (last 1000 lines per service)
-# - Resource usage metrics
-# - Database status
-# - Network connectivity tests
-# - Workflow states
-
-

Support Channels

-
    -
  1. Check documentation: provisioning help <topic>
  2. -
  3. Search logs: journalctl -u provisioning-*
  4. -
  5. Review monitoring dashboards: http://localhost:3000
  6. -
  7. Run diagnostics: provisioning diagnose
  8. -
  9. Contact support with diagnostic report
  10. -
-

Preventive Measures

-
    -
  • Enable comprehensive monitoring and alerting
  • -
  • Implement regular health checks
  • -
  • Maintain up-to-date documentation
  • -
  • Test disaster recovery procedures monthly
  • -
  • Keep platform and dependencies updated
  • -
  • Review logs regularly for warning signs
  • -
  • Monitor resource utilization trends
  • -
  • Validate configuration changes before applying
  • -
- - -

Platform Health

-

Health monitoring, status checks, and system integrity validation for the Provisioning platform.

-

Health Check Overview

-

The platform provides multiple levels of health monitoring:

-
- - - - -
LevelScopeFrequencyResponse Time
Service HealthIndividual service statusEvery 10s< 100ms
System HealthOverall platform statusEvery 30s< 500ms
Infrastructure HealthManaged resourcesEvery 60s< 2s
Dependency HealthExternal servicesEvery 60s< 1s
-
-

Quick Health Check

-
# Check overall platform health
-provisioning health
-
-# Output:
-# ✓ Orchestrator: healthy (uptime: 5d 3h)
-# ✓ Control Center: healthy
-# ✓ Vault Service: healthy
-# ✓ Database: healthy (connections: 45/100)
-# ✓ Network: healthy
-# ✗ MCP Server: degraded (high latency)
-
-# Exit code: 0 = healthy, 1 = degraded, 2 = unhealthy
-
-

Service Health Endpoints

-

All services expose /health endpoints returning standardized responses.

-

Orchestrator Health

-
curl  [http://localhost:8080/health](http://localhost:8080/health)
-
-
{
-  "status": "healthy",
-  "version": "5.0.0",
-  "uptime_seconds": 432000,
-  "checks": {
-    "database": "healthy",
-    "file_system": "healthy",
-    "memory": "healthy"
-  },
-  "metrics": {
-    "active_workflows": 12,
-    "queued_tasks": 45,
-    "completed_tasks": 9876,
-    "worker_threads": 8
-  },
-  "timestamp": "2026-01-16T10:30:00Z"
-}
-
-

Health status values:

-
    -
  • healthy - Service operating normally
  • -
  • degraded - Service functional with reduced capacity
  • -
  • unhealthy - Service not functioning
  • -
-

Control Center Health

-
curl  [http://localhost:8081/health](http://localhost:8081/health)
-
-
{
-  "status": "healthy",
-  "version": "5.0.0",
-  "checks": {
-    "database": "healthy",
-    "orchestrator": "healthy",
-    "vault": "healthy",
-    "auth": "healthy"
-  },
-  "metrics": {
-    "active_sessions": 23,
-    "api_requests_per_second": 156,
-    "p95_latency_ms": 45
-  }
-}
-
-

Vault Service Health

-
curl  [http://localhost:8085/health](http://localhost:8085/health)
-
-
{
-  "status": "healthy",
-  "checks": {
-    "kms_backend": "healthy",
-    "encryption": "healthy",
-    "key_rotation": "healthy"
-  },
-  "metrics": {
-    "active_secrets": 234,
-    "encryption_ops_per_second": 50,
-    "kms_latency_ms": 3
-  }
-}
-
-

System Health Checks

-

Comprehensive Health Check

-
# Run all health checks
-provisioning health check --all
-
-# Check specific components
-provisioning health check --components orchestrator,database,network
-
-# Output detailed report
-provisioning health check --detailed --output /tmp/health-report.json
-
-

Health Check Components

-

Platform health checking verifies:

-
    -
  1. Service Availability - All services responding
  2. -
  3. Database Connectivity - SurrealDB reachable and responsive
  4. -
  5. Filesystem Health - Disk space and I/O performance
  6. -
  7. Network Connectivity - Internal and external connectivity
  8. -
  9. Resource Utilization - CPU, memory, disk within limits
  10. -
  11. Dependency Status - External services available
  12. -
  13. Security Status - Authentication and encryption functional
  14. -
-

Database Health

-
# Check database health
-provisioning health database
-
-# Output:
-# ✓ Connection: healthy (latency: 2ms)
-# ✓ Disk usage: 45% (22GB / 50GB)
-# ✓ Active connections: 45 / 100
-# ✓ Query performance: healthy (avg: 15ms)
-# ✗ Replication: warning (lag: 5s)
-
-

Detailed database metrics:

-
# Connection pool status
-provisioning database pool-status
-
-# Slow query analysis
-provisioning database slow-queries --threshold 1000ms
-
-# Storage usage
-provisioning database storage-stats
-
-

Filesystem Health

-
# Check disk space and I/O
-provisioning health filesystem
-
-# Output:
-# ✓ Root filesystem: 65% used (325GB / 500GB)
-# ✓ Data filesystem: 45% used (225GB / 500GB)
-# ✓ I/O latency: healthy (avg: 5ms)
-# ✗ Inodes: warning (85% used)
-
-

Check specific paths:

-
# Check data directory
-df -h /var/lib/provisioning
-
-# Check I/O performance
-iostat -x 1 5
-
-

Network Health

-
# Check network connectivity
-provisioning health network
-
-# Test external connectivity
-provisioning health network --external
-
-# Test provider connectivity
-provisioning health network --provider upcloud
-
-

Network health checks:

-
    -
  • Internal service-to-service connectivity
  • -
  • DNS resolution
  • -
  • External API reachability (cloud providers)
  • -
  • Network latency and packet loss
  • -
  • Firewall rules validation
  • -
-

Resource Monitoring

-

CPU Health

-
# Check CPU utilization
-provisioning health cpu
-
-# Per-service CPU usage
-provisioning platform metrics --metric cpu_usage
-
-# Alert if CPU > 90% for 5 minutes
-
-

Monitor CPU load:

-
# System load average
-uptime
-
-# Per-process CPU
-top -b -n 1 | grep provisioning
-
-

Memory Health

-
# Check memory utilization
-provisioning health memory
-
-# Memory breakdown by service
-provisioning platform metrics --metric memory_usage
-
-# Detect memory leaks
-provisioning health memory --leak-detection
-
-

Memory metrics:

-
# Available memory
-free -h
-
-# Per-service memory
-ps aux | grep provisioning | awk '{sum+=$6} END {print sum/1024 " MB"}'
-
-

Disk Health

-
# Check disk health
-provisioning health disk
-
-# SMART status (if available)
-sudo smartctl -H /dev/sda
-
-

Automated Health Monitoring

-

Health Check Service

-

Enable continuous health monitoring:

-
# Start health monitor
-provisioning health monitor --interval 30
-
-# Monitor with alerts
-provisioning health monitor --interval 30 --alert-email [ops@example.com](mailto:ops@example.com)
-
-# Monitor specific components
-provisioning health monitor --components orchestrator,database --interval 10
-
-

Systemd Health Monitoring

-

Systemd watchdog for automatic restart on failure:

-
# /etc/systemd/system/provisioning-orchestrator.service
-[Service]
-Type=notify
-WatchdogSec=30
-Restart=on-failure
-RestartSec=10
-StartLimitIntervalSec=300
-StartLimitBurst=5
-
-

Service sends periodic health status:

-
// Rust service code
-sd_notify::notify(true, &[NotifyState::Watchdog])?;
-

Health Dashboards

-

Grafana Health Dashboard

-

Import platform health dashboard:

-
provisioning monitoring install-dashboard --name platform-health
-
-

Dashboard panels:

-
    -
  • Service status indicators
  • -
  • Resource utilization gauges
  • -
  • Error rate graphs
  • -
  • Latency histograms
  • -
  • Workflow success rate
  • -
  • Database connection pool
  • -
-

Access: http://localhost:3000/d/platform-health

-

CLI Health Dashboard

-

Real-time health monitoring in terminal:

-
# Interactive health dashboard
-provisioning health dashboard
-
-# Auto-refresh every 5 seconds
-provisioning health dashboard --refresh 5
-
-

Health Alerts

-

Prometheus Alert Rules

-
# Platform health alerts
-groups:
-  - name: platform_health
-    rules:
-      - alert: ServiceUnhealthy
-        expr: up{job=~"provisioning-.*"} == 0
-        for: 1m
-        labels:
-          severity: critical
-        annotations:
-          summary: "Service is unhealthy"
-
-      - alert: HighMemoryUsage
-        expr: process_resident_memory_bytes > 4e9
-        for: 5m
-        labels:
-          severity: warning
-
-      - alert: DatabaseConnectionPoolExhausted
-        expr: database_connection_pool_active / database_connection_pool_max > 0.9
-        for: 2m
-        labels:
-          severity: critical
-
-

Health Check Notifications

-

Configure health check notifications:

-
# /etc/provisioning/health.toml
-[notifications]
-enabled = true
-
-[notifications.email]
-enabled = true
-smtp_server = "smtp.example.com"
-from = "[health@provisioning.example.com](mailto:health@provisioning.example.com)"
-to = ["[ops@example.com](mailto:ops@example.com)"]
-
-[notifications.slack]
-enabled = true
-webhook_url = " [https://hooks.slack.com/services/..."](https://hooks.slack.com/services/...")
-channel = "#provisioning-health"
-
-[notifications.pagerduty]
-enabled = true
-service_key = "..."
-
-

Dependency Health

-

External Service Health

-

Check health of dependencies:

-
# Check cloud provider API
-provisioning health dependency upcloud
-
-# Check vault service
-provisioning health dependency vault
-
-# Check all dependencies
-provisioning health dependency --all
-
-

Dependency health includes:

-
    -
  • API reachability
  • -
  • Authentication validity
  • -
  • API quota/rate limits
  • -
  • Service degradation status
  • -
-

Third-party Service Monitoring

-

Monitor integrated services:

-
# Kubernetes cluster health (if managing K8s)
-provisioning health kubernetes
-
-# Database replication health
-provisioning health database --replication
-
-# Secret store health
-provisioning health secrets
-
-

Health Metrics

-

Key metrics tracked for health monitoring:

-

Service Metrics

-
provisioning_service_up{service="orchestrator"} 1
-provisioning_service_health_status{service="orchestrator"} 1
-provisioning_service_uptime_seconds{service="orchestrator"} 432000
-
-

Resource Metrics

-
provisioning_cpu_usage_percent 45
-provisioning_memory_usage_bytes 2.5e9
-provisioning_disk_usage_percent{mount="/var/lib/provisioning"} 45
-provisioning_network_errors_total 0
-
-

Performance Metrics

-
provisioning_api_latency_p50_ms 25
-provisioning_api_latency_p95_ms 85
-provisioning_api_latency_p99_ms 150
-provisioning_workflow_duration_seconds 45
-
-

Health Best Practices

-
    -
  • Monitor all critical services continuously
  • -
  • Set appropriate alert thresholds
  • -
  • Test alert notifications regularly
  • -
  • Maintain health check runbooks
  • -
  • Review health metrics weekly
  • -
  • Establish health baselines
  • -
  • Automate remediation where possible
  • -
  • Document health status definitions
  • -
  • Integrate health checks with CI/CD
  • -
  • Monitor upstream dependencies
  • -
-

Troubleshooting Unhealthy State

-

When health check fails:

-
# 1. Identify unhealthy component
-provisioning health check --detailed
-
-# 2. View component logs
-journalctl -u provisioning-<component> -n 100
-
-# 3. Check resource availability
-provisioning health resources
-
-# 4. Restart unhealthy service
-sudo systemctl restart provisioning-<component>
-
-# 5. Verify recovery
-provisioning health check
-
-# 6. Review recent changes
-git log --since="1 day ago" -- /etc/provisioning/
-
- - -

- Provisioning Logo -

-

- Provisioning -

-

Security System

-

Enterprise-grade security infrastructure with 12 integrated components providing -authentication, authorization, encryption, and compliance.

-

Overview

-

The Provisioning platform security system delivers comprehensive protection across all layers of -the infrastructure automation platform. Built for enterprise deployments, it provides defense-in-depth -through multiple security controls working together.

-

Security Architecture

-

The security system is organized into 12 core components:

-
- - - - - - - - - - - - -
ComponentPurposeKey Features
AuthenticationUser identity verificationJWT tokens, session management, multi-provider auth
AuthorizationAccess control enforcementCedar policy engine, RBAC, fine-grained permissions
MFAMulti-factor authenticationTOTP, WebAuthn/FIDO2, backup codes
Audit LoggingComprehensive audit trails7-year retention, 5 export formats, compliance reporting
KMSKey management5 KMS backends, envelope encryption, key rotation
Secrets ManagementSecure secret storageSecretumVault integration, SOPS/Age, dynamic secrets
EncryptionData protectionAt-rest and in-transit encryption, AES-256-GCM
Secure CommunicationNetwork securityTLS/mTLS, certificate management, secure channels
Certificate ManagementPKI operationsCA management, certificate issuance, rotation
ComplianceRegulatory adherenceSOC2, GDPR, HIPAA, policy enforcement
Security TestingValidation framework350+ tests, vulnerability scanning, penetration testing
Break-GlassEmergency accessMulti-party approval, audit trails, time-limited access
-
-

Security Layers

-

Layer 1: Identity and Access

-

- Authentication Flow JWT OAuth MFA Token Refresh Session -

-
    -
  • Authentication: Verify user identity with JWT tokens and Argon2id password hashing
  • -
-

- Authorization Cedar Policy Engine RBAC Permit Deny Evaluation -

-
    -
  • Authorization: Enforce access control with Cedar policies and RBAC
  • -
  • MFA: Add second factor with TOTP or FIDO2 hardware keys
  • -
-

Layer 2: Data Protection

-

- Encryption Layers At-Rest In-Transit Post-Quantum Secrets Management -

-
    -
  • Encryption: Protect data at rest with AES-256-GCM and in transit with TLS 1.3
  • -
  • Secrets Management: Store secrets securely in SecretumVault with automatic rotation
  • -
  • KMS: Manage encryption keys with envelope encryption across 5 backend options
  • -
-

Layer 3: Network Security

-
    -
  • Secure Communication: Enforce TLS/mTLS for all service-to-service communication
  • -
  • Certificate Management: Automate certificate lifecycle with cert-manager integration
  • -
  • Network Policies: Control traffic flow with Kubernetes NetworkPolicies
  • -
-

Layer 4: Compliance and Monitoring

-
    -
  • Audit Logging: Record all security events with 7-year retention
  • -
  • Compliance: Validate against SOC2, GDPR, and HIPAA frameworks
  • -
  • Security Testing: Continuous validation with automated security test suite
  • -
-

Performance Characteristics

-
    -
  • Authentication Overhead: Less than 20ms per request with JWT verification
  • -
  • Authorization Decision: Less than 10ms with Cedar policy evaluation
  • -
  • Encryption Operations: Less than 5ms with KMS-backed envelope encryption
  • -
  • Audit Logging: Asynchronous with zero blocking on critical path
  • -
  • MFA Verification: Less than 100ms for TOTP, less than 500ms for WebAuthn
  • -
-

Security Standards

-

The security system adheres to industry standards and best practices:

-
    -
  • OWASP Top 10: Protection against common web vulnerabilities
  • -
  • NIST Cybersecurity Framework: Aligned with identify, protect, detect, respond, recover
  • -
  • Zero Trust Architecture: Never trust, always verify principle
  • -
  • Defense in Depth: Multiple layers of security controls
  • -
  • Least Privilege: Minimal access rights for users and services
  • -
  • Secure by Default: Security controls enabled out of the box
  • -
-

Component Integration

-

All security components work together as a cohesive system:

-
┌─────────────────────────────────────────────────────────────┐
-│                    User Request                             │
-└──────────────────────┬──────────────────────────────────────┘
-                       │
-                       ▼
-┌─────────────────────────────────────────────────────────────┐
-│  Authentication (JWT + Session)                             │
-│  ↓                                                           │
-│  Authorization (Cedar Policies)                             │
-│  ↓                                                           │
-│  MFA Verification (if required)                             │
-└──────────────────────┬──────────────────────────────────────┘
-                       │
-                       ▼
-┌─────────────────────────────────────────────────────────────┐
-│  Audit Logging (Record all actions)                         │
-└──────────────────────┬──────────────────────────────────────┘
-                       │
-                       ▼
-┌─────────────────────────────────────────────────────────────┐
-│  Secure Communication (TLS/mTLS)                            │
-│  ↓                                                           │
-│  Data Access (Encrypted with KMS)                           │
-│  ↓                                                           │
-│  Secrets Retrieved (SecretumVault)                          │
-└──────────────────────┬──────────────────────────────────────┘
-                       │
-                       ▼
-┌─────────────────────────────────────────────────────────────┐
-│  Compliance Validation (SOC2/GDPR checks)                   │
-└──────────────────────┬──────────────────────────────────────┘
-                       │
-                       ▼
-┌─────────────────────────────────────────────────────────────┐
-│                    Response                                 │
-└─────────────────────────────────────────────────────────────┘
-
-

Security Configuration

-

Security settings are managed through hierarchical configuration:

-
# Security defaults in config/security.toml
-[security]
-auth_enabled = true
-mfa_required = true
-audit_enabled = true
-encryption_at_rest = true
-tls_min_version = "1.3"
-
-[security.jwt]
-algorithm = "RS256"
-access_token_ttl = 900        # 15 minutes
-refresh_token_ttl = 604800    # 7 days
-
-[security.mfa]
-totp_enabled = true
-webauthn_enabled = true
-backup_codes_count = 10
-
-[security.kms]
-backend = "secretumvault"
-envelope_encryption = true
-key_rotation_days = 90
-
-[security.audit]
-retention_days = 2555         # 7 years
-export_formats = ["json", "csv", "parquet", "sqlite", "syslog"]
-
-[security.compliance]
-frameworks = ["soc2", "gdpr", "hipaa"]
-policy_enforcement = "strict"
-
-

Quick Start

-

Enable security system for your deployment:

-
# Enable all security features
-provisioning config set security.enabled true
-
-# Configure authentication
-provisioning config set security.auth.jwt_algorithm RS256
-provisioning config set security.auth.mfa_required true
-
-# Set up SecretumVault integration
-provisioning config set security.secrets.backend secretumvault
-provisioning config set security.secrets.url  [http://localhost:8200](http://localhost:8200)
-
-# Enable audit logging
-provisioning config set security.audit.enabled true
-provisioning config set security.audit.retention_days 2555
-
-# Configure compliance framework
-provisioning config set security.compliance.frameworks soc2,gdpr
-
-# Verify security configuration
-provisioning security validate
-
-

Documentation Structure

-

This security documentation is organized into 12 detailed guides:

-
    -
  1. Authentication - JWT token-based authentication and session management
  2. -
  3. Authorization - Cedar policy engine and RBAC access control
  4. -
  5. Multi-Factor Authentication - TOTP and WebAuthn/FIDO2 implementation
  6. -
  7. Audit Logging - Comprehensive audit trails and compliance reporting
  8. -
  9. Key Management Service - Encryption key management and rotation
  10. -
  11. Secrets Management - SecretumVault and SOPS/Age integration
  12. -
  13. Encryption - At-rest and in-transit data protection
  14. -
  15. Secure Communication - TLS/mTLS and network security
  16. -
  17. Certificate Management - PKI and certificate lifecycle
  18. -
  19. Compliance - SOC2, GDPR, HIPAA frameworks
  20. -
  21. Security Testing - Test suite and vulnerability scanning
  22. -
  23. Break-Glass Procedures - Emergency access and recovery
  24. -
-

Security Metrics

-

The security system tracks key metrics for monitoring and reporting:

-
    -
  • Authentication Success Rate: Percentage of successful login attempts
  • -
  • MFA Adoption Rate: Percentage of users with MFA enabled
  • -
  • Policy Violations: Count of authorization denials
  • -
  • Audit Event Rate: Events logged per second
  • -
  • Secret Rotation Compliance: Percentage of secrets rotated within policy
  • -
  • Certificate Expiration: Days until certificate expiration
  • -
  • Compliance Score: Overall compliance posture percentage
  • -
  • Security Test Pass Rate: Percentage of security tests passing
  • -
-

Best Practices

-

Follow these security best practices:

-
    -
  1. Enable MFA for all users: Require second factor for all accounts
  2. -
  3. Rotate secrets regularly: Automate secret rotation every 90 days
  4. -
  5. Monitor audit logs: Review security events daily
  6. -
  7. Test security controls: Run security test suite before deployments
  8. -
  9. Keep certificates current: Automate certificate renewal 30 days before expiration
  10. -
  11. Review policies regularly: Audit Cedar policies quarterly
  12. -
  13. Limit break-glass access: Require multi-party approval for emergency access
  14. -
  15. Encrypt all data: Enable encryption at rest and in transit
  16. -
  17. Follow least privilege: Grant minimal required permissions
  18. -
  19. Validate compliance: Run compliance checks before production deployments
  20. -
-

Getting Help

-

For security issues and questions:

-
    -
  • Security Documentation: Complete guides in this security section
  • -
  • CLI Help: provisioning security help
  • -
  • Security Validation: provisioning security validate
  • -
  • Audit Query: provisioning security audit query
  • -
  • Compliance Check: provisioning security compliance check
  • -
-

Security Updates

-

The security system is continuously updated to address emerging threats and vulnerabilities. Subscribe to security advisories and apply updates promptly.

-
-

Next Steps:

- -

Authentication

-

JWT token-based authentication with session management, login flows, and multi-provider support.

-

Overview

-

The authentication system verifies user identity through JWT (JSON Web Token) tokens with RS256 -signatures and Argon2id password hashing. It provides secure session management, token refresh -capabilities, and support for multiple authentication providers.

-

Architecture

-

Authentication Flow

-
┌──────────┐                ┌──────────────┐                ┌────────────┐
-│  Client  │                │  Auth Service│                │  Database  │
-└────┬─────┘                └──────┬───────┘                └─────┬──────┘
-     │                             │                              │
-     │  POST /auth/login           │                              │
-     │  {username, password}       │                              │
-     │────────────────────────────>│                              │
-     │                             │                              │
-     │                             │  Find user by username       │
-     │                             │─────────────────────────────>│
-     │                             │<─────────────────────────────│
-     │                             │  User record                 │
-     │                             │                              │
-     │                             │  Verify password (Argon2id)  │
-     │                             │                              │
-     │                             │  Create session              │
-     │                             │─────────────────────────────>│
-     │                             │<─────────────────────────────│
-     │                             │                              │
-     │                             │  Generate JWT token pair     │
-     │                             │                              │
-     │  {access_token, refresh}    │                              │
-     │<────────────────────────────│                              │
-     │                             │                              │
-
-

Components

-
- - - - - -
ComponentPurposeTechnology
AuthServiceCore authentication logicRust service in control-center
JwtServiceToken generation and verificationRS256 algorithm with jsonwebtoken crate
SessionManagerSession lifecycle managementDatabase-backed session storage
PasswordHasherPassword hashing and verificationArgon2id with configurable parameters
UserServiceUser account managementCRUD operations with role assignment
-
-

JWT Token Structure

-

Access Token

-

Short-lived token for API authentication (default: 15 minutes).

-
{
-  "header": {
-    "alg": "RS256",
-    "typ": "JWT"
-  },
-  "payload": {
-    "sub": "550e8400-e29b-41d4-a716-446655440000",
-    "email": "[user@example.com](mailto:user@example.com)",
-    "username": "alice",
-    "roles": ["user", "developer"],
-    "session_id": "sess_abc123",
-    "mfa_verified": true,
-    "permissions_hash": "sha256:abc123...",
-    "iat": 1704067200,
-    "exp": 1704068100,
-    "iss": "provisioning-platform",
-    "aud": "api.provisioning.example.com"
-  }
-}
-
-

Refresh Token

-

Long-lived token for obtaining new access tokens (default: 7 days).

-
{
-  "header": {
-    "alg": "RS256",
-    "typ": "JWT"
-  },
-  "payload": {
-    "sub": "550e8400-e29b-41d4-a716-446655440000",
-    "session_id": "sess_abc123",
-    "token_type": "refresh",
-    "iat": 1704067200,
-    "exp": 1704672000,
-    "iss": "provisioning-platform"
-  }
-}
-
-

Password Security

-

Argon2id Configuration

-

Password hashing uses Argon2id with security-hardened parameters:

-
// Default Argon2id parameters
-argon2::Params {
-    m_cost: 65536,      // 64 MB memory
-    t_cost: 3,          // 3 iterations
-    p_cost: 4,          // 4 parallelism
-    output_len: 32      // 32 byte hash
-}
-

Password Requirements

-

Default password policy enforces:

-
    -
  • Minimum 12 characters
  • -
  • At least one uppercase letter
  • -
  • At least one lowercase letter
  • -
  • At least one digit
  • -
  • At least one special character
  • -
  • Not in common password list
  • -
  • Not similar to username or email
  • -
-

Session Management

-

Session Lifecycle

-
    -
  1. Creation: New session created on successful login
  2. -
  3. Active: Session tracked with last activity timestamp
  4. -
  5. Refresh: Session extended on token refresh
  6. -
  7. Expiration: Session expires after inactivity timeout
  8. -
  9. Revocation: Manual logout or security event terminates session
  10. -
-

Session Storage

-

Sessions stored in database with:

-
pub struct Session {
-    pub session_id: Uuid,
-    pub user_id: Uuid,
-    pub created_at: DateTime<Utc>,
-    pub expires_at: DateTime<Utc>,
-    pub last_activity: DateTime<Utc>,
-    pub ip_address: Option<String>,
-    pub user_agent: Option<String>,
-    pub is_active: bool,
-}
-

Session Tracking

-

Track multiple concurrent sessions per user:

-
# List active sessions for user
-provisioning security sessions list --user alice
-
-# Revoke specific session
-provisioning security sessions revoke --session-id sess_abc123
-
-# Revoke all sessions except current
-provisioning security sessions revoke-all --except-current
-
-

Login Flows

-

Standard Login

-

Basic username/password authentication:

-
# CLI login
-provisioning auth login --username alice --password <password>
-
-# API login
-curl -X POST  [https://api.provisioning.example.com/auth/login](https://api.provisioning.example.com/auth/login) \
-  -H "Content-Type: application/json" \
-  -d '{
-    "username_or_email": "alice",
-    "password": "SecurePassword123!",
-    "client_info": {
-      "ip_address": "192.168.1.100",
-      "user_agent": "provisioning-cli/1.0"
-    }
-  }'
-
-

Response:

-
{
-  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
-  "refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
-  "token_type": "Bearer",
-  "expires_in": 900,
-  "user": {
-    "user_id": "550e8400-e29b-41d4-a716-446655440000",
-    "username": "alice",
-    "email": "[alice@example.com](mailto:alice@example.com)",
-    "roles": ["user", "developer"]
-  }
-}
-
-

MFA Login

-

Two-phase authentication with MFA:

-
# Phase 1: Initial authentication
-provisioning auth login --username alice --password <password>
-
-# Response indicates MFA required
-# {
-#   "mfa_required": true,
-#   "mfa_token": "temp_token_abc123",
-#   "available_methods": ["totp", "webauthn"]
-# }
-
-# Phase 2: MFA verification
-provisioning auth mfa-verify --mfa-token temp_token_abc123 --code 123456
-
-

SSO Login

-

Single Sign-On with external providers:

-
# Initiate SSO flow
-provisioning auth sso --provider okta
-
-# Or with SAML
-provisioning auth sso --provider azure-ad --protocol saml
-
-

Token Refresh

-

Automatic Refresh

-

Client libraries automatically refresh tokens before expiration:

-
// Automatic token refresh in Rust client
-let client = ProvisioningClient::new()
-    .with_auto_refresh(true)
-    .build()?;
-
-// Tokens refreshed transparently
-client.server().list().await?;
-

Manual Refresh

-

Explicit token refresh when needed:

-
# CLI token refresh
-provisioning auth refresh
-
-# API token refresh
-curl -X POST  [https://api.provisioning.example.com/auth/refresh](https://api.provisioning.example.com/auth/refresh) \
-  -H "Content-Type: application/json" \
-  -d '{
-    "refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
-  }'
-
-

Response:

-
{
-  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
-  "token_type": "Bearer",
-  "expires_in": 900
-}
-
-

Multi-Provider Authentication

-

Supported Providers

-
- - - - - -
ProviderTypeConfiguration
LocalUsername/passwordBuilt-in user database
LDAPDirectory serviceActive Directory, OpenLDAP
SAMLSSOOkta, Azure AD, OneLogin
OIDCOAuth2/OpenIDGoogle, GitHub, Auth0
mTLSCertificateClient certificate authentication
-
-

Provider Configuration

-
[auth.providers.ldap]
-enabled = true
-server = "ldap://ldap.example.com"
-base_dn = "dc=example,dc=com"
-bind_dn = "cn=admin,dc=example,dc=com"
-user_filter = "(uid={username})"
-
-[auth.providers.saml]
-enabled = true
-entity_id = " [https://provisioning.example.com"](https://provisioning.example.com")
-sso_url = " [https://okta.example.com/sso/saml"](https://okta.example.com/sso/saml")
-certificate_path = "/etc/provisioning/saml-cert.pem"
-
-[auth.providers.oidc]
-enabled = true
-issuer = " [https://accounts.google.com"](https://accounts.google.com")
-client_id = "client_id_here"
-client_secret = "client_secret_here"
-redirect_uri = " [https://provisioning.example.com/auth/callback"](https://provisioning.example.com/auth/callback")
-
-

Token Validation

-

JWT Verification

-

All API requests validate JWT tokens:

-
// Middleware validates JWT on every request
-pub async fn jwt_auth_middleware(
-    headers: HeaderMap,
-    State(jwt_service): State<Arc<JwtService>>,
-    mut request: Request,
-    next: Next,
-) -> Result<Response, AuthError> {
-    // Extract token from Authorization header
-    let token = extract_bearer_token(&headers)?;
-
-    // Verify signature and claims
-    let claims = jwt_service.verify_access_token(&token)?;
-
-    // Check expiration
-    if claims.exp < Utc::now().timestamp() {
-        return Err(AuthError::TokenExpired);
-    }
-
-    // Inject user context into request
-    request.extensions_mut().insert(claims);
-
-    Ok(next.run(request).await)
-}
-

Token Revocation

-

Revoke tokens on security events:

-
# Revoke all tokens for user
-provisioning security tokens revoke-user --user alice
-
-# Revoke specific token
-provisioning security tokens revoke --token-id token_abc123
-
-# Check token status
-provisioning security tokens status --token eyJhbGci...
-
-

Security Hardening

-

Configuration

-

Secure authentication settings:

-
[security.auth]
-# JWT settings
-jwt_algorithm = "RS256"
-jwt_issuer = "provisioning-platform"
-access_token_ttl = 900           # 15 minutes
-refresh_token_ttl = 604800       # 7 days
-token_leeway = 30                # 30 seconds clock skew
-
-# Password policy
-password_min_length = 12
-password_require_uppercase = true
-password_require_lowercase = true
-password_require_digit = true
-password_require_special = true
-password_check_common = true
-
-# Session settings
-session_timeout = 1800           # 30 minutes inactivity
-max_sessions_per_user = 5
-remember_me_duration = 2592000   # 30 days
-
-# Security controls
-enforce_mfa = true
-allow_password_reset = true
-lockout_after_attempts = 5
-lockout_duration = 900           # 15 minutes
-
-

Best Practices

-
    -
  1. Use strong passwords: Enforce password policy with minimum 12 characters
  2. -
  3. Enable MFA: Require second factor for all users
  4. -
  5. Rotate keys regularly: Update JWT signing keys every 90 days
  6. -
  7. Monitor failed attempts: Alert on suspicious login patterns
  8. -
  9. Limit session duration: Use short access token TTL with refresh tokens
  10. -
  11. Secure token storage: Store tokens securely, never in local storage
  12. -
  13. Validate on every request: Always verify JWT signature and expiration
  14. -
  15. Use HTTPS only: Never transmit tokens over unencrypted connections
  16. -
-

CLI Integration

-

Login and Session Management

-
# Login with credentials
-provisioning auth login --username alice
-
-# Login with MFA
-provisioning auth login --username alice --mfa
-
-# Check authentication status
-provisioning auth status
-
-# Logout (revoke session)
-provisioning auth logout
-
-# List active sessions
-provisioning security sessions list
-
-# Refresh token
-provisioning auth refresh
-
-

Token Management

-
# Show current token
-provisioning auth token show
-
-# Validate token
-provisioning auth token validate
-
-# Decode token (without verification)
-provisioning auth token decode
-
-# Revoke token
-provisioning auth token revoke
-
-

API Reference

-

Endpoints

-
- - - - - - - - -
EndpointMethodPurpose
/auth/loginPOSTAuthenticate with credentials
/auth/refreshPOSTRefresh access token
/auth/logoutPOSTRevoke session and tokens
/auth/verifyPOSTVerify MFA code
/auth/sessionsGETList active sessions
/auth/sessions/:idDELETERevoke specific session
/auth/password-resetPOSTInitiate password reset
/auth/password-changePOSTChange password
-
-

Troubleshooting

-

Common Issues

-

Token expired errors:

-
# Refresh token
-provisioning auth refresh
-
-# Or re-login
-provisioning auth login
-
-

Invalid signature:

-
# Check JWT configuration
-provisioning config get security.auth.jwt_algorithm
-
-# Verify public key is correct
-provisioning security keys verify
-
-

MFA verification failures:

-
# Check time sync (TOTP requires accurate time)
-ntpdate -q pool.ntp.org
-
-# Re-sync MFA device
-provisioning auth mfa-setup --resync
-
-

Session not found:

-
# Clear local session and re-login
-provisioning auth logout
-provisioning auth login
-
-

Monitoring

-

Metrics

-

Track authentication metrics:

-
    -
  • Login success rate
  • -
  • Failed login attempts per user
  • -
  • Average session duration
  • -
  • Token refresh rate
  • -
  • MFA verification success rate
  • -
  • Active sessions count
  • -
-

Alerts

-

Configure alerts for security events:

-
    -
  • Multiple failed login attempts
  • -
  • Login from new location
  • -
  • Unusual authentication patterns
  • -
  • Session hijacking attempts
  • -
  • Token tampering detected
  • -
-
-

Next Steps:

- -

Authorization

-

Multi-Factor Authentication

-

Audit Logging

-

KMS Guide

-

Secrets Management

-

SecretumVault Integration Guide

-

SecretumVault is a post-quantum cryptography (PQC) secure vault system integrated with -Provisioning’s vault-service. It provides quantum-resistant encryption for sensitive credentials -and infrastructure secrets.

-

Overview

-

SecretumVault combines:

-
    -
  • Post-Quantum Cryptography: Algorithms resistant to quantum computer attacks
  • -
  • Hardware Acceleration: Optional FPGA acceleration for performance
  • -
  • Distributed Architecture: Multi-node secure storage
  • -
  • Compliance: FIPS 140-3 ready, NIST standards
  • -
-

Architecture

-

Integration Points

-
Provisioning
-    ├─ CLI (Nushell)
-    │   └─ nu_plugin_secretumvault
-    │
-    ├─ vault-service (Rust)
-    │   ├─ secretumvault backend
-    │   ├─ rustyvault compatibility
-    │   └─ SOPS + Age integration
-    │
-    └─ Control Center
-        └─ Secret management UI
-
-

Cryptographic Stack

-
User Secret
-    ↓
-KDF (Key Derivation Function)
-    ├─ Argon2id (password-based)
-    └─ HKDF (key-based)
-    ↓
-PQC Encryption Layer
-    ├─ CRYSTALS-Kyber (key encapsulation)
-    ├─ Falcon (signature)
-    ├─ SPHINCS+ (backup signature)
-    └─ Hybrid: PQC + Classical (AES-256)
-    ↓
-Authenticated Encryption
-    ├─ ChaCha20-Poly1305
-    └─ AES-256-GCM
-    ↓
-Secure Storage
-    ├─ Local vault
-    ├─ SurrealDB
-    └─ Hardware module (optional)
-
-

Installation

-

Install SecretumVault

-
# Install via provisioning
-provisioning install secretumvault
-
-# Or manual installation
-cd /Users/Akasha/Development/secretumvault
-cargo install --path .
-
-# Verify installation
-secretumvault --version
-
-

Install Nushell Plugin

-
# Install plugin
-provisioning install nu-plugin-secretumvault
-
-# Reload Nushell
-nu -c "plugin add nu_plugin_secretumvault"
-
-# Verify
-nu -c "secretumvault-plugin version"
-
-

Configuration

-

Environment Setup

-
# Set vault location
-export SECRETUMVAULT_HOME=~/.secretumvault
-
-# Set encryption algorithm
-export SECRETUMVAULT_CIPHER=kyber-aes  # kyber-aes, falcon-aes, hybrid
-
-# Set key derivation
-export SECRETUMVAULT_KDF=argon2id      # argon2id, pbkdf2
-
-# Enable hardware acceleration (optional)
-export SECRETUMVAULT_HW_ACCEL=enabled
-
-

Configuration File

-
# ~/.secretumvault/config.yaml
-vault:
-  storage_backend: surrealdb          # local, surrealdb, redis
-  encryption_cipher: kyber-aes        # kyber-aes, falcon-aes, hybrid
-  key_derivation: argon2id            # argon2id, pbkdf2
-
-  # Argon2id parameters (password strength)
-  kdf:
-    memory: 65536                     # KB
-    iterations: 3
-    parallelism: 4
-
-  # Encryption parameters
-  encryption:
-    key_length: 256                   # bits
-    nonce_length: 12                  # bytes
-    auth_tag_length: 16               # bytes
-
-# Database backend (if using SurrealDB)
-database:
-  url: "surrealdb://localhost:8000"
-  namespace: "provisioning"
-  database: "secrets"
-
-# Hardware acceleration (optional)
-hardware:
-  use_fpga: false
-  fpga_device: "/dev/fpga0"
-
-# Backup configuration
-backup:
-  enabled: true
-  interval: 24                        # hours
-  retention: 30                       # days
-  encrypt_backup: true
-  backup_path: ~/.secretumvault/backups
-
-# Access logging
-audit:
-  enabled: true
-  log_file: ~/.secretumvault/audit.log
-  log_level: info
-  rotate_logs: true
-  retention_days: 365
-
-# Master key management
-master_key:
-  protection: none                    # none, tpm, hsm, hardware-module
-  rotation_enabled: true
-  rotation_interval: 90               # days
-
-

Usage

-

Command Line Interface

-
# Create master key
-secretumvault init
-
-# Add secret
-secretumvault secret add \
-  --name database-password \
-  --value "supersecret" \
-  --metadata "type=database,app=api"
-
-# Retrieve secret
-secretumvault secret get database-password
-
-# List secrets
-secretumvault secret list
-
-# Delete secret
-secretumvault secret delete database-password
-
-# Rotate key
-secretumvault key rotate
-
-# Backup vault
-secretumvault backup create --output vault-backup.enc
-
-# Restore vault
-secretumvault backup restore vault-backup.enc
-
-

Nushell Integration

-
# Load SecretumVault plugin
-plugin add nu_plugin_secretumvault
-
-# Add secret from Nushell
-let password = "mypassword"
-secretumvault-plugin store "app-secret" $password
-
-# Retrieve secret
-let db_pass = (secretumvault-plugin retrieve "database-password")
-
-# List all secrets
-secretumvault-plugin list
-
-# Delete secret
-secretumvault-plugin delete "old-secret"
-
-# Rotate key
-secretumvault-plugin rotate-key
-
-

Provisioning Integration

-
# Configure vault-service to use SecretumVault
-provisioning config set security.vault.backend secretumvault
-
-# Enable in form prefill
-provisioning setup profile --use-secretumvault
-
-# Manage secrets via CLI
-provisioning vault add \
-  --name aws-access-key \
-  --value "AKIAIOSFODNN7EXAMPLE" \
-  --metadata "provider=aws,env=production"
-
-# Use secret in infrastructure
-provisioning ai "Create AWS resources using secret aws-access-key"
-
-

Post-Quantum Cryptography

-

Algorithms Supported

-
- - - - - -
AlgorithmTypeNIST StatusPerformance
CRYSTALS-KyberKEMFinalistFast
FalconSignatureFinalistMedium
SPHINCS+Hash-based SignatureFinalistSlower
AES-256Hybrid (Classical)StandardVery fast
ChaCha20Stream CipherAlternativeFast
-
- -

SecretumVault uses hybrid encryption by default:

-
Secret Input
-    ↓
-Key Material: Classical (AES-256) + PQC (Kyber)
-    ├─ Generate AES key
-    ├─ Generate Kyber keypair
-    └─ Encapsulate using Kyber
-    ↓
-Encrypt with both algorithms
-    ├─ AES-256-GCM encryption
-    └─ Kyber encapsulation (public key cryptography)
-    ↓
-Both keys required to decrypt
-    ├─ If quantum computer breaks Kyber → AES still secure
-    └─ If breakthrough in AES → Kyber still secure
-    ↓
-Encrypted Secret Stored
-
-

Advantages:

-
    -
  • Protection against quantum computers (PQC)
  • -
  • Protection against classical attacks (AES-256)
  • -
  • Compatible with both current and future threats
  • -
  • No single point of failure
  • -
-

Key Rotation Strategy

-
# Manual key rotation
-secretumvault key rotate --algorithm kyber-aes
-
-# Scheduled rotation (every 90 days)
-secretumvault key rotate --schedule 90d
-
-# Emergency rotation
-secretumvault key rotate --emergency --force
-
-

Security Features

-

Authentication

-
# Master key authentication
-secretumvault auth login
-
-# MFA for sensitive operations
-secretumvault auth mfa enable --method totp
-
-# Biometric unlock (supported platforms)
-secretumvault auth enable-biometric
-
-

Access Control

-
# Set vault permissions
-secretumvault acl set database-password \
-  --read "api-service,backup-service" \
-  --write "admin" \
-  --delete "admin"
-
-# View access logs
-secretumvault audit log --secret database-password
-
-

Audit Logging

-

Every operation is logged:

-
# View audit log
-secretumvault audit log --since 24h
-
-# Export audit log
-secretumvault audit export --format json > audit.json
-
-# Monitor real-time
-secretumvault audit monitor
-
-

Sample Log Entry:

-
{
-  "timestamp": "2026-01-16T01:47:00Z",
-  "operation": "secret_retrieve",
-  "secret": "database-password",
-  "user": "api-service",
-  "status": "success",
-  "ip_address": "127.0.0.1",
-  "device_id": "device-123"
-}
-
-

Disaster Recovery

-

Backup Procedures

-
# Create encrypted backup
-secretumvault backup create \
-  --output /secure/vault-backup.enc \
-  --compression gzip
-
-# Verify backup integrity
-secretumvault backup verify /secure/vault-backup.enc
-
-# Restore from backup
-secretumvault backup restore \
-  --input /secure/vault-backup.enc \
-  --verify-checksum
-
-

Recovery Key

-
# Generate recovery key (for emergencies)
-secretumvault recovery-key generate \
-  --threshold 3 \
-  --shares 5
-
-# Share recovery shards
-# Share with 5 trusted people, need 3 to recover
-
-# Recover using shards
-secretumvault recovery-key restore \
-  --shard1 /secure/shard1.key \
-  --shard2 /secure/shard2.key \
-  --shard3 /secure/shard3.key
-
-

Performance

-

Benchmark Results

-
- - - - - -
OperationTimeAlgorithm
Store secret50-100msKyber-AES
Retrieve secret30-50msKyber-AES
Key rotation200-500msKyber-AES
Backup 1000 secrets2-3 secondsKyber-AES
Restore from backup3-5 secondsKyber-AES
-
-

Hardware Acceleration

-

With FPGA acceleration:

-
- - - -
OperationNativeFPGASpeedup
Store secret75ms15ms5x
Key rotation350ms50ms7x
Backup 10002.5s0.4s6x
-
-

Troubleshooting

-

Cannot Initialize Vault

-
# Check permissions
-ls -la ~/.secretumvault
-
-# Clear corrupted state
-rm ~/.secretumvault/state.lock
-
-# Reinitialize
-secretumvault init --force
-
-

Slow Performance

-
# Check algorithm
-secretumvault config get encryption.cipher
-
-# Switch to faster algorithm
-export SECRETUMVAULT_CIPHER=kyber-aes
-
-# Enable hardware acceleration
-export SECRETUMVAULT_HW_ACCEL=enabled
-
-

Master Key Lost

-
# Use recovery key (if available)
-secretumvault recovery-key restore \
-  --shard1 ... --shard2 ... --shard3 ...
-
-# If no recovery key exists, vault is unrecoverable
-# Use recent backup instead
-secretumvault backup restore vault-backup.enc
-
-

Compliance & Standards

-

Certifications

-
    -
  • NIST PQC Standards: CRYSTALS-Kyber, Falcon, SPHINCS+
  • -
  • FIPS 140-3 Ready: Cryptographic module certification path
  • -
  • NIST SP 800-175B: Post-quantum cryptography guidance
  • -
  • EU Cyber Resilience Act: PQC readiness
  • -
-

Export Controls

-

SecretumVault is subject to cryptography export controls in some jurisdictions. Ensure compliance with local regulations.

- - -

Encryption

-

Secure Communication

-

Certificate Management

-

Compliance

-

Security Testing

-

- Provisioning Logo -

-

- Provisioning -

-

Development

-

Comprehensive guides for developers building extensions, custom providers, plugins, and -integrations on the Provisioning platform.

-

Overview

-

Provisioning is designed to be extended and customized for specific infrastructure needs. This section provides everything needed to:

-
    -
  • Build custom cloud providers interfacing with any infrastructure platform via the Provider SDK
  • -
  • Create custom detectors for domain-specific infrastructure analysis and anomaly detection
  • -
  • Develop task services for specialized infrastructure operations beyond built-in services
  • -
  • Write Nushell plugins for high-performance scripting extensions
  • -
  • Integrate external systems via REST APIs and the MCP (Model Context Protocol)
  • -
  • Understand platform internals for daemon architecture, caching, and performance optimization
  • -
-

The platform uses modern Rust with async/await, Nushell for scripting, and -Nickel for configuration - all with production-ready code examples.

-

Development Guides

-

Extension Development

- -

Platform Internals

- -

Integration and APIs

-
    -
  • -

    API Guide - REST API integration with authentication, -pagination, error handling, rate limiting

    -
  • -
  • -

    Build System - Cargo configuration, feature flags, -dependencies, cross-platform compilation

    -
  • -
  • -

    Testing - Unit, integration, property-based testing, -benchmarking, CI/CD patterns

    -
  • -
-

Community

-
    -
  • Contributing - Guidelines, standards, review -process, licensing
  • -
-

Quick Start Paths

-

I want to build a custom provider

-

Start with Custom Provider Development - includes -template, credential patterns, error handling, tests, and publishing workflow.

-

I want to create custom detectors

-

See Custom Detector Development - covers analysis frameworks, state tracking, testing, and marketplace distribution.

-

I want to extend with Nushell

-

Read Plugin Development - FFI bindings, type safety, performance optimization, and integration patterns.

-

I want to understand system performance

-

Study Provisioning Daemon Internals - architecture, caching strategy, connection pooling, metrics collection.

-

I want to integrate external systems

-

Check API Guide - REST endpoints, authentication, webhooks, and integration patterns.

-

Technology Stack

-
    -
  • Language: Rust (async/await with Tokio), Nushell (scripting)
  • -
  • Configuration: Nickel (type-safe) + TOML (generated)
  • -
  • Testing: Unit tests, integration tests, property-based tests
  • -
  • Performance: Prometheus metrics, connection pooling, LRU caching
  • -
  • Security: Post-quantum cryptography, type-safety, secure defaults
  • -
-

Development Environment

-

All development builds with:

-
cargo build --release
-cargo test --all
-cargo clippy -- -D warnings
-
- -
    -
  • For architecture insights → See provisioning/docs/src/architecture/
  • -
  • For API details → See provisioning/docs/src/api-reference/
  • -
  • For examples → See provisioning/docs/src/examples/
  • -
  • For deployment → See provisioning/docs/src/operations/
  • -
-

Extension Development

-

Creating custom extensions to add providers, task services, and clusters to the Provisioning platform.

-

Extension Overview

-

Extensions are modular components that extend platform capabilities:

-
- - - - -
Extension TypePurposeImplementationComplexity
ProvidersCloud infrastructure backendsNushell scripts + Nickel schemasModerate
Task ServicesInfrastructure componentsNushell installation scriptsSimple
ClustersComplete deploymentsNickel schemas + orchestrationModerate
WorkflowsAutomation templatesNickel workflow definitionsSimple
-
-

Extension Structure

-

Standard extension directory layout:

-
provisioning/extensions/<type>/<name>/
-├── nickel/
-│   ├── schema.ncl      # Nickel type definitions
-│   ├── defaults.ncl    # Default configuration
-│   └── validation.ncl  # Validation rules
-├── scripts/
-│   ├── install.nu      # Installation script
-│   ├── uninstall.nu    # Removal script
-│   └── validate.nu     # Validation script
-├── templates/
-│   └── config.template # Configuration templates
-├── tests/
-│   └── test_*.nu       # Test scripts
-├── docs/
-│   └── README.md       # Documentation
-└── metadata.toml       # Extension metadata
-
-

Extension Metadata

-

Every extension requires metadata.toml:

-
# metadata.toml
-[extension]
-name = "my-provider"
-type = "provider"
-version = "1.0.0"
-description = "Custom cloud provider"
-author = "Your Name <[email@example.com](mailto:email@example.com)>"
-license = "MIT"
-
-[dependencies]
-nushell = ">=0.109.0"
-nickel = ">=1.15.1"
-
-[dependencies.extensions]
-# Other extensions this depends on
-base-provider = "1.0.0"
-
-[capabilities]
-create_server = true
-delete_server = true
-create_network = true
-
-[configuration]
-required_fields = ["api_key", "region"]
-optional_fields = ["timeout", "retry_attempts"]
-
-

Creating a Provider Extension

-

Providers implement cloud infrastructure backends.

-

Provider Structure

-
provisioning/extensions/providers/my-provider/
-├── nickel/
-│   ├── schema.ncl
-│   ├── server.ncl
-│   └── network.ncl
-├── scripts/
-│   ├── create_server.nu
-│   ├── delete_server.nu
-│   ├── list_servers.nu
-│   └── validate.nu
-├── templates/
-│   └── server.template
-├── tests/
-│   └── test_provider.nu
-└── metadata.toml
-
-

Provider Schema (Nickel)

-
# nickel/schema.ncl
-{
-  Provider = {
-    name | String,
-    api_key | String,
-    region | String,
-    timeout | default = 30 | Number,
-
-    server_config = {
-      default_plan | default = "medium" | String,
-      allowed_plans | Array String,
-    },
-  },
-
-  Server = {
-    name | String,
-    plan | String,
-    zone | String,
-    hostname | String,
-    tags | default = [] | Array String,
-  },
-}
-
-

Provider Implementation (Nushell)

-
# scripts/create_server.nu
-#!/usr/bin/env nu
-
-# Create server using provider API
-export def main [
-    config: record  # Provider configuration
-    server: record  # Server specification
-] {
-    # Validate configuration
-    validate-config $config
-
-    # Construct API request
-    let request = {
-        name: $server.name
-        plan: $server.plan
-        zone: $server.zone
-    }
-
-    # Call provider API
-    let response = http post $"($config.api_endpoint)/servers" {
-        headers: {
-            Authorization: $"Bearer ($config.api_key)"
-        }
-        body: ($request | to json)
-    }
-
-    # Return server details
-    $response | from json
-}
-
-# Validate provider configuration
-def validate-config [config: record] {
-    if ($config.api_key | is-empty) {
-        error make {msg: "api_key is required"}
-    }
-
-    if ($config.region | is-empty) {
-        error make {msg: "region is required"}
-    }
-}
-
-

Provider Interface Contract

-

All providers must implement:

-
# Required operations
-create_server    # Create new server
-delete_server    # Delete existing server
-get_server       # Get server details
-list_servers     # List all servers
-server_status    # Check server status
-
-# Optional operations
-create_network   # Create network
-delete_network   # Delete network
-attach_storage   # Attach storage volume
-create_snapshot  # Create server snapshot
-
-

Creating a Task Service Extension

-

Task services are installable infrastructure components.

-

Task Service Structure

-
provisioning/extensions/taskservs/my-service/
-├── nickel/
-│   ├── schema.ncl
-│   └── defaults.ncl
-├── scripts/
-│   ├── install.nu
-│   ├── uninstall.nu
-│   ├── health.nu
-│   └── validate.nu
-├── templates/
-│   ├── config.yaml.template
-│   └── systemd.service.template
-├── tests/
-│   └── test_service.nu
-├── docs/
-│   └── README.md
-└── metadata.toml
-
-

Task Service Metadata

-
# metadata.toml
-[extension]
-name = "my-service"
-type = "taskserv"
-version = "2.1.0"
-description = "Custom infrastructure service"
-
-[dependencies.taskservs]
-# Task services this depends on
-containerd = ">=1.7.0"
-kubernetes = ">=1.28.0"
-
-[installation]
-requires_root = true
-platforms = ["linux"]
-architectures = ["x86_64", "aarch64"]
-
-[health_check]
-enabled = true
-endpoint = " [http://localhost:8000/health"](http://localhost:8000/health")
-interval = 30
-timeout = 5
-
-

Task Service Installation Script

-
# scripts/install.nu
-#!/usr/bin/env nu
-
-export def main [
-    config: record  # Service configuration
-    server: record  # Target server details
-] {
-    print "Installing my-service..."
-
-    # Download binaries
-    let version = $config.version? | default "latest"
-    download-binary $version
-
-    # Install systemd service
-    install-systemd-service $config
-
-    # Configure service
-    generate-config $config
-
-    # Start service
-    start-service
-
-    # Verify installation
-    verify-installation
-
-    print "Installation complete"
-}
-
-def download-binary [version: string] {
-    let url = $" [https://github.com/org/my-service/releases/download/($versio](https://github.com/org/my-service/releases/download/($versio)n)/my-service"
-    http get $url | save /usr/local/bin/my-service
-    chmod +x /usr/local/bin/my-service
-}
-
-def install-systemd-service [config: record] {
-    let template = open ../templates/systemd.service.template
-    let rendered = $template | str replace --all "{{VERSION}}" $config.version
-    $rendered | save /etc/systemd/system/my-service.service
-    systemctl daemon-reload
-}
-
-def start-service [] {
-    systemctl enable my-service
-    systemctl start my-service
-}
-
-def verify-installation [] {
-    let status = systemctl is-active my-service
-    if $status != "active" {
-        error make {msg: "Service failed to start"}
-    }
-
-    # Health check
-    sleep 5sec
-    let health = http get  [http://localhost:8000/health](http://localhost:8000/health)
-    if $health.status != "healthy" {
-        error make {msg: "Health check failed"}
-    }
-}
-
-

Creating a Cluster Extension

-

Clusters combine servers and task services into complete deployments.

-

Cluster Schema

-
# nickel/schema.ncl
-{
-  Cluster = {
-    metadata = {
-      name | String,
-      provider | String,
-      environment | default = "production" | String,
-    },
-
-    infrastructure = {
-      servers | Array {
-        name | String,
-        role | | [ "control", "worker", "storage" | ],
-        plan | String,
-      },
-    },
-
-    services = {
-      taskservs | Array String,
-      order | default = [] | Array String,
-    },
-
-    networking = {
-      private_network | default = true | Bool,
-      cidr | default = "10.0.0.0/16" | String,
-    },
-  },
-}
-
-

Cluster Definition Example

-
# clusters/kubernetes-ha.ncl
-{
-  metadata.name = "k8s-ha-cluster",
-  metadata.provider = "upcloud",
-
-  infrastructure.servers = [
-    {name = "control-01", role = "control", plan = "large"},
-    {name = "control-02", role = "control", plan = "large"},
-    {name = "control-03", role = "control", plan = "large"},
-    {name = "worker-01", role = "worker", plan = "xlarge"},
-    {name = "worker-02", role = "worker", plan = "xlarge"},
-  ],
-
-  services.taskservs = ["containerd", "etcd", "kubernetes", "cilium"],
-  services.order = ["containerd", "etcd", "kubernetes", "cilium"],
-
-  networking.private_network = true,
-  networking.cidr = "10.100.0.0/16",
-}
-
-

Extension Testing

-

Test Structure

-
# tests/test_provider.nu
-use std assert
-
-# Test provider configuration validation
-export def test_validate_config [] {
-    let valid_config = {
-        api_key: "test-key"
-        region: "us-east-1"
-    }
-
-    let result = validate-config $valid_config
-    assert equal $result.valid true
-}
-
-# Test server creation
-export def test_create_server [] {
-    let config = load-test-config
-    let server_spec = {
-        name: "test-server"
-        plan: "medium"
-        zone: "us-east-1a"
-    }
-
-    let result = create-server $config $server_spec
-    assert equal $result.status "created"
-}
-
-# Run all tests
-export def main [] {
-    test_validate_config
-    test_create_server
-    print "All tests passed"
-}
-
-

Run tests:

-
# Test extension
-provisioning extension test my-provider
-
-# Test specific component
-nu tests/test_provider.nu
-
-

Extension Packaging

-

OCI Registry Publishing

-

Package and publish extension:

-
# Build extension package
-provisioning extension build my-provider
-
-# Validate package
-provisioning extension validate my-provider-1.0.0.tar.gz
-
-# Publish to registry
-provisioning extension publish my-provider-1.0.0.tar.gz \
-  --registry registry.example.com
-
-

Package structure:

-
my-provider-1.0.0.tar.gz
-├── metadata.toml
-├── nickel/
-├── scripts/
-├── templates/
-├── tests/
-├── docs/
-└── manifest.json
-
-

Extension Installation

-

Install extension from registry:

-
# Install from OCI registry
-provisioning extension install my-provider --version 1.0.0
-
-# Install from local file
-provisioning extension install ./my-provider-1.0.0.tar.gz
-
-# List installed extensions
-provisioning extension list
-
-# Update extension
-provisioning extension update my-provider --version 1.1.0
-
-# Uninstall extension
-provisioning extension uninstall my-provider
-
-

Best Practices

-
    -
  • Follow naming conventions: lowercase with hyphens
  • -
  • Version extensions semantically (semver)
  • -
  • Document all configuration options
  • -
  • Provide comprehensive tests
  • -
  • Include usage examples in docs
  • -
  • Validate input parameters
  • -
  • Handle errors gracefully
  • -
  • Log important operations
  • -
  • Support idempotent operations
  • -
  • Keep dependencies minimal
  • -
- - -

Provider Development

-

Implementing custom cloud provider integrations for the Provisioning platform.

-

Provider Architecture

-

Providers abstract cloud infrastructure APIs through a unified interface, allowing infrastructure definitions to be portable across clouds.

-

Provider Interface

-

All providers must implement these core operations:

-
# Server lifecycle
-create_server     # Provision new server
-delete_server     # Remove server
-get_server        # Fetch server details
-list_servers      # List all servers
-update_server     # Modify server configuration
-server_status     # Get current state
-
-# Network operations (optional)
-create_network    # Create private network
-delete_network    # Remove network
-attach_network    # Attach server to network
-
-# Storage operations (optional)
-attach_volume     # Attach storage volume
-detach_volume     # Detach storage volume
-create_snapshot   # Snapshot server disk
-
-

Provider Template

-

Use the official provider template:

-
# Generate provider scaffolding
-provisioning generate provider --name my-cloud --template standard
-
-# Creates:
-# extensions/providers/my-cloud/
-# ├── nickel/
-# │   ├── schema.ncl
-# │   ├── server.ncl
-# │   └── network.ncl
-# ├── scripts/
-# │   ├── create_server.nu
-# │   ├── delete_server.nu
-# │   └── list_servers.nu
-# └── metadata.toml
-
-

Provider Schema (Nickel)

-

Define provider configuration schema:

-
# nickel/schema.ncl
-{
-  ProviderConfig = {
-    name | String,
-    api_endpoint | String,
-    api_key | String,
-    region | String,
-    timeout | default = 30 | Number,
-    retry_attempts | default = 3 | Number,
-
-    plans = {
-      small  = {cpu = 2, memory = 4096, disk = 25},
-      medium = {cpu = 4, memory = 8192, disk = 50},
-      large  = {cpu = 8, memory = 16384, disk = 100},
-    },
-
-    regions | Array String,
-  },
-
-  ServerSpec = {
-    name | String,
-    plan | String,
-    zone | String,
-    image | default = "ubuntu-24.04" | String,
-    ssh_keys | Array String,
-    user_data | default = "" | String,
-  },
-}
-
-

Implementing Server Creation

-

Create server implementation:

-
# scripts/create_server.nu
-#!/usr/bin/env nu
-
-export def main [
-    config: record,  # Provider configuration
-    spec: record     # Server specification
-]: nothing -> record {
-    # Validate inputs
-    validate-provider-config $config
-    validate-server-spec $spec
-
-    # Map plan to provider-specific values
-    let plan = get-plan-details $config $spec.plan
-
-    # Construct API request
-    let request = {
-        hostname: $spec.name
-        plan: $plan.name
-        zone: $spec.zone
-        storage_devices: [{
-            action: "create"
-            storage: $plan.disk
-            title: "root"
-        }]
-        login: {
-            user: "root"
-            keys: $spec.ssh_keys
-        }
-    }
-
-    # Call provider API with retry logic
-    let server = retry-api-call | { |
-        http post $"($config.api_endpoint)/server" {
-            headers: {Authorization: $"Bearer ($config.api_key)"}
-            body: ($request | to json)
-        } | from json
-    } $config.retry_attempts
-
-    # Wait for server to be ready
-    wait-for-server-ready $config $server.uuid
-
-    # Return server details
-    {
-        id: $server.uuid
-        name: $server.hostname
-        ip_address: $server.ip_addresses.0.address
-        status: "running"
-        provider: $config.name
-    }
-}
-
-def validate-provider-config [config: record] {
-    if ($config.api_key | is-empty) {
-        error make {msg: "API key required"}
-    }
-    if ($config.region | is-empty) {
-        error make {msg: "Region required"}
-    }
-}
-
-def get-plan-details [config: record, plan_name: string]: nothing -> record {
-    $config.plans | get $plan_name
-}
-
-def retry-api-call [operation: closure, max_attempts: int]: nothing -> any {
-    mut attempt = 1
-    mut last_error = null
-
-    while $attempt <= $max_attempts {
-        try {
-            return (do $operation)
-        } catch | { err |
-            $last_error = $err
-            if $attempt < $max_attempts {
-                sleep (1sec * $attempt)  # Exponential backoff
-                $attempt = $attempt + 1
-            }
-        }
-    }
-
-    error make {msg: $"API call failed after ($max_attempts) attempts: ($last_error)"}
-}
-
-def wait-for-server-ready [config: record, server_id: string] {
-    mut ready = false
-    mut attempts = 0
-    let max_wait = 120  # 2 minutes
-
-    while not $ready and $attempts < $max_wait {
-        let status = http get $"($config.api_endpoint)/server/($server_id)" {
-            headers: {Authorization: $"Bearer ($config.api_key)"}
-        } | from json
-
-        if $status.state == "started" {
-            $ready = true
-        } else {
-            sleep 1sec
-            $attempts = $attempts + 1
-        }
-    }
-
-    if not $ready {
-        error make {msg: "Server failed to start within timeout"}
-    }
-}
-
-

Provider Testing

-

Comprehensive provider testing:

-
# tests/test_provider.nu
-use std assert
-
-export def test_create_server [] {
-    # Mock provider config
-    let config = {
-        name: "test-cloud"
-        api_endpoint: " [http://localhost:8080"](http://localhost:8080")
-        api_key: "test-key"
-        region: "test-region"
-        plans: {
-            small: {cpu: 2, memory: 4096, disk: 25}
-        }
-    }
-
-    # Mock server spec
-    let spec = {
-        name: "test-server"
-        plan: "small"
-        zone: "test-zone"
-        ssh_keys: ["ssh-rsa AAAA..."]
-    }
-
-    # Test server creation
-    let server = create-server $config $spec
-
-    assert ($server.id != null)
-    assert ($server.name == "test-server")
-    assert ($server.status == "running")
-}
-
-export def test_list_servers [] {
-    let config = load-test-config
-    let servers = list-servers $config
-
-    assert ($servers | length) > 0
-}
-
-export def main [] {
-    print "Running provider tests..."
-    test_create_server
-    test_list_servers
-    print "All tests passed!"
-}
-
-

Error Handling

-

Robust error handling for provider operations:

-
# Handle API errors gracefully
-def handle-api-error [error: record]: nothing -> record {
-    match $error.status {
-        401 => {error make {msg: "Authentication failed - check API key"}}
-        403 => {error make {msg: "Permission denied - insufficient privileges"}}
-        404 => {error make {msg: "Resource not found"}}
-        429 => {error make {msg: "Rate limit exceeded - retry later"}}
-        500 => {error make {msg: "Provider API error - contact support"}}
-        _   => {error make {msg: $"Unknown error: ($error.message)"}}
-    }
-}
-
-

Provider Best Practices

-
    -
  • Implement idempotent operations where possible
  • -
  • Handle rate limiting with exponential backoff
  • -
  • Validate all inputs before API calls
  • -
  • Log all API requests and responses (without secrets)
  • -
  • Use connection pooling for better performance
  • -
  • Cache provider capabilities and quotas
  • -
  • Implement proper timeout handling
  • -
  • Return consistent error messages
  • -
  • Test against provider sandbox/staging environment
  • -
  • Version provider schemas carefully
  • -
- - -

Plugin Development

-

Developing Nushell plugins for performance-critical operations in the Provisioning platform.

-

Plugin Overview

-

Nushell plugins provide 10-50x performance improvement over HTTP APIs through native Rust implementations.

-

Available Plugins

-
- - - -
PluginPurposePerformance GainLanguage
nu_plugin_authAuthentication and OS keyring5x fasterRust
nu_plugin_kmsKMS encryption operations10x fasterRust
nu_plugin_orchestratorOrchestrator queries30x fasterRust
-
-

Plugin Architecture

-

Plugins communicate with Nushell via MessagePack protocol:

-
Nushell ←→ MessagePack ←→ Plugin Process
-  ↓                           ↓
-Script                    Native Rust
-
-

Creating a Plugin

-

Plugin Template

-

Generate plugin scaffold:

-
# Create new plugin
-cargo new --lib nu_plugin_myfeature
-cd nu_plugin_myfeature
-
-

Add dependencies to Cargo.toml:

-
[package]
-name = "nu_plugin_myfeature"
-version = "0.1.0"
-edition = "2021"
-
-[dependencies]
-nu-plugin = "0.109.0"
-nu-protocol = "0.109.0"
-serde = {version = "1.0", features = ["derive"]}
-
-

Plugin Implementation

-

Implement plugin interface:

-
// src/lib.rs
-use nu_plugin::{EvaluatedCall, LabeledError, Plugin};
-use nu_protocol::{Category, PluginSignature, SyntaxShape, Type, Value};
-
-pub struct MyFeaturePlugin;
-
-impl Plugin for MyFeaturePlugin {
-    fn signature(&self) -> Vec<PluginSignature> {
-        vec![
-            PluginSignature::build("my-feature")
-                .usage("Perform my feature operation")
-                .required("input", SyntaxShape::String, "input value")
-                .input_output_type(Type::String, Type::String)
-                .category(Category::Custom("provisioning".into())),
-        ]
-    }
-
-    fn run(
-        &mut self,
-        name: &str,
-        call: &EvaluatedCall,
-        input: &Value,
-    ) -> Result<Value, LabeledError> {
-        match name {
-            "my-feature" => self.my_feature(call, input),
-            _ => Err(LabeledError {
-                label: "Unknown command".into(),
-                msg: format!("Unknown command: {}", name),
-                span: None,
-            }),
-        }
-    }
-}
-
-impl MyFeaturePlugin {
-    fn my_feature(&self, call: &EvaluatedCall, _input: &Value) -> Result<Value, LabeledError> {
-        let input: String = call.req(0)?;
-
-        // Perform operation
-        let result = perform_operation(&input);
-
-        Ok(Value::string(result, call.head))
-    }
-}
-
-fn perform_operation(input: &str) -> String {
-    // Your implementation here
-    format!("Processed: {}", input)
-}
-
-// Plugin entry point
-fn main() {
-    nu_plugin::serve_plugin(&mut MyFeaturePlugin, nu_plugin::MsgPackSerializer {})
-}
-

Building Plugin

-
# Build release version
-cargo build --release
-
-# Install plugin
-nu -c 'plugin add target/release/nu_plugin_myfeature'
-nu -c 'plugin use myfeature'
-
-# Test plugin
-nu -c 'my-feature "test input"'
-
-

Plugin Performance Optimization

-

Benchmarking

-
use std::time::Instant;
-
-pub fn benchmark_operation() {
-    let start = Instant::now();
-
-    // Operation to benchmark
-    perform_expensive_operation();
-
-    let duration = start.elapsed();
-    eprintln!("Operation took: {:?}", duration);
-}
-

Caching

-

Implement caching for expensive operations:

-
use std::collections::HashMap;
-use std::sync::{Arc, Mutex};
-
-pub struct CachedPlugin {
-    cache: Arc<Mutex<HashMap<String, String>>>,
-}
-
-impl CachedPlugin {
-    fn get_or_compute(&self, key: &str) -> String {
-        let mut cache = self.cache.lock().unwrap();
-
-        if let Some(value) = cache.get(key) {
-            return value.clone();
-        }
-
-        let value = expensive_computation(key);
-        cache.insert(key.to_string(), value.clone());
-        value
-    }
-}
-

Testing Plugins

-

Unit Tests

-
#[cfg(test)]
-mod tests {
-    use super::*;
-    use nu_protocol::{Span, Value};
-
-    #[test]
-    fn test_my_feature() {
-        let plugin = MyFeaturePlugin;
-        let input = Value::string("test", Span::test_data());
-        let result = plugin.my_feature(&mock_call(), &input).unwrap();
-
-        assert_eq!(result.as_string().unwrap(), "Processed: test");
-    }
-
-    fn mock_call() -> EvaluatedCall {
-        // Mock EvaluatedCall for testing
-        todo!()
-    }
-}
-

Integration Tests

-
# tests/test_plugin.nu
-use std assert
-
-def test_plugin_functionality [] {
-    let result = my-feature "test input"
-    assert equal $result "Processed: test input"
-}
-
-def main [] {
-    test_plugin_functionality
-    print "Plugin tests passed"
-}
-
-

Plugin Best Practices

-
    -
  • Keep plugin logic focused and single-purpose
  • -
  • Minimize dependencies to reduce binary size
  • -
  • Use async operations for I/O-bound tasks
  • -
  • Implement proper error handling
  • -
  • Document all plugin commands
  • -
  • Version plugins with semantic versioning
  • -
  • Provide fallback to HTTP API if plugin unavailable
  • -
  • Cache expensive computations
  • -
  • Profile and benchmark performance improvements
  • -
- - -

API Integration Guide

-

Integrate third-party APIs with Provisioning infrastructure.

-

API Client Development

-

Create clients for external APIs:

-
// src/api_client.rs
-use reqwest::Client;
-
-pub struct ApiClient {
-    endpoint: String,
-    api_key: String,
-    client: Client,
-}
-
-impl ApiClient {
-    pub async fn call(&self, path: &str) -> Result<Response> {
-        let url = format!("{}{}", self.endpoint, path);
-        self.client
-            .get(&url)
-            .bearer_auth(&self.api_key)
-            .send()
-            .await
-    }
-}
-

Webhook Integration

-

Handle webhooks from external systems:

-
#[post("/webhooks/{service}")]
-pub async fn handle_webhook(path: web::Path<String>, body: web::Bytes) -> impl Responder {
-    let service = path.into_inner();
-    match service.as_str() {
-        "github" => handle_github_webhook(&body),
-        "stripe" => handle_stripe_webhook(&body),
-        _ => HttpResponse::NotFound().finish(),
-    }
-}
-

Error Handling

-

Robust error handling for API calls with retries:

-
pub async fn call_api_with_retry(
-    client: &ApiClient,
-    path: &str,
-    max_retries: u32,
-) -> Result<Response> {
-    for attempt in 0..max_retries {
-        match client.call(path).await {
-            Ok(response) => return Ok(response),
-            Err(e) if attempt < max_retries - 1 => {
-                let delay = Duration::from_secs(2_u64.pow(attempt));
-                tokio::time::sleep(delay).await;
-            }
-            Err(e) => return Err(e),
-        }
-    }
-    Err(ApiError::MaxRetriesExceeded.into())
-}
- - -

Build System

-

Building, testing, and packaging the Provisioning platform and extensions with Cargo, Just, and Nickel.

-

Build Tools

-
- - - - -
ToolPurposeVersion Required
CargoRust compilation and testingLatest stable
JustTask runner for common operationsLatest
NickelSchema validation and type checking1.15.1+
NushellScript execution and testing0.109.0+
-
-

Building Platform Services

-

Build All Services

-
# Build all Rust services in release mode
-cd provisioning/platform
-cargo build --release --workspace
-
-# Or using just task runner
-just build-platform
-
-

Binary outputs in target/release/:

-
    -
  • provisioning-orchestrator
  • -
  • provisioning-control-center
  • -
  • provisioning-vault-service
  • -
  • provisioning-installer
  • -
-

Build Individual Service

-
# Orchestrator service
-cd provisioning/platform/crates/orchestrator
-cargo build --release
-
-# Control Center service
-cd provisioning/platform/crates/control-center
-cargo build --release
-
-# Development build (faster compilation)
-cargo build
-
-

Testing

-

Run All Tests

-
# Rust unit and integration tests
-cargo test --workspace
-
-# Nushell script tests
-just test-nushell
-
-# Complete test suite
-just test-all
-
-

Test Specific Component

-
# Test orchestrator crate
-cargo test -p provisioning-orchestrator
-
-# Test with output visible
-cargo test -p provisioning-orchestrator -- --nocapture
-
-# Test specific function
-cargo test -p provisioning-orchestrator test_workflow_creation
-
-# Run tests matching pattern
-cargo test workflow
-
-

Security Tests

-
# Run 350+ security test cases
-cargo test -p security --test '*'
-
-# Specific security component
-cargo test -p security authentication
-cargo test -p security authorization
-cargo test -p security kms
-
-

Code Quality

-

Formatting

-
# Format all Rust code
-cargo fmt --all
-
-# Check formatting without modifying
-cargo fmt --all -- --check
-
-# Format Nickel schemas
-nickel fmt provisioning/schemas/**/*.ncl
-
-

Linting

-
# Run Clippy linter
-cargo clippy --all -- -D warnings
-
-# Auto-fix Clippy warnings
-cargo clippy --all --fix
-
-# Clippy with all features enabled
-cargo clippy --all --all-features -- -D warnings
-
-

Nickel Validation

-
# Type check Nickel schemas
-nickel typecheck provisioning/schemas/main.ncl
-
-# Evaluate schema
-nickel eval provisioning/schemas/main.ncl
-
-# Format Nickel files
-nickel fmt provisioning/schemas/**/*.ncl
-
-

Continuous Integration

-

The platform uses automated CI workflows for quality assurance.

-

GitHub Actions Pipeline

-

Key CI jobs:

-
1. Rust Build and Test
-   - cargo build --release --workspace
-   - cargo test --workspace
-   - cargo clippy --all -- -D warnings
-
-2. Nushell Validation
-   - nu --check core/cli/provisioning
-   - Run Nushell test suite
-
-3. Nickel Schema Validation
-   - nickel typecheck schemas/main.ncl
-   - Validate all schema files
-
-4. Security Tests
-   - Run 350+ security test cases
-   - Vulnerability scanning
-
-5. Documentation Build
-   - mdbook build docs
-   - Markdown linting
-
-

Packaging and Distribution

-

Create Release Package

-
# Build optimized binaries
-cargo build --release --workspace
-
-# Strip debug symbols (reduce binary size)
-strip target/release/provisioning-orchestrator
-strip target/release/provisioning-control-center
-
-# Create distribution archive
-just package
-
-

Package Structure

-
provisioning-5.0.0-linux-x86_64.tar.gz
-├── bin/
-│   ├── provisioning                    # Main CLI
-│   ├── provisioning-orchestrator       # Orchestrator service
-│   ├── provisioning-control-center     # Control Center
-│   ├── provisioning-vault-service      # Vault service
-│   └── provisioning-installer          # Platform installer
-├── lib/
-│   └── nulib/                          # Nushell libraries
-├── schemas/                            # Nickel schemas
-├── config/
-│   └── config.defaults.toml            # Default configuration
-├── systemd/
-│   └── *.service                       # Systemd unit files
-└── README.md
-
-

Cross-Platform Builds

-

Supported Targets

-
# Linux x86_64 (primary platform)
-cargo build --release --target x86_64-unknown-linux-gnu
-
-# Linux ARM64 (Raspberry Pi, cloud ARM instances)
-cargo build --release --target aarch64-unknown-linux-gnu
-
-# macOS x86_64
-cargo build --release --target x86_64-apple-darwin
-
-# macOS ARM64 (Apple Silicon)
-cargo build --release --target aarch64-apple-darwin
-
-

Cross-Compilation Setup

-
# Add target architectures
-rustup target add x86_64-unknown-linux-gnu
-rustup target add aarch64-unknown-linux-gnu
-
-# Install cross-compilation tool
-cargo install cross
-
-# Cross-compile with Docker
-cross build --release --target aarch64-unknown-linux-gnu
-
-

Just Task Runner

-

Common build tasks in justfile:

-
# Build all components
-build-all: build-platform build-plugins
-
-# Build platform services
-build-platform:
-    cd platform && cargo build --release --workspace
-
-# Run all tests
-test: test-rust test-nushell test-integration
-
-# Test Rust code
-test-rust:
-    cargo test --workspace
-
-# Test Nushell scripts
-test-nushell:
-    nu scripts/test/test_all.nu
-
-# Format all code
-fmt:
-    cargo fmt --all
-    nickel fmt schemas/**/*.ncl
-
-# Lint all code
-lint:
-    cargo clippy --all -- -D warnings
-    nickel typecheck schemas/main.ncl
-
-# Create release package
-package:
-    ./scripts/package.nu
-
-# Clean build artifacts
-clean:
-    cargo clean
-    rm -rf target/
-
-

Usage examples:

-
just build-all     # Build everything
-just test          # Run all tests
-just fmt           # Format code
-just lint          # Run linters
-just package       # Create distribution
-just clean         # Remove artifacts
-
-

Performance Optimization

-

Release Builds

-
# Cargo.toml
-[profile.release]
-opt-level = 3              # Maximum optimization
-lto = "fat"                # Link-time optimization
-codegen-units = 1          # Better optimization, slower compile
-strip = true               # Strip debug symbols
-panic = "abort"            # Smaller binary size
-
-

Build Time Optimization

-
# Cargo.toml
-[profile.dev]
-opt-level = 1              # Basic optimization
-incremental = true         # Faster recompilation
-
-

Speed up compilation:

-
# Use faster linker (Linux)
-sudo apt install lld
-export RUSTFLAGS="-C link-arg=-fuse-ld=lld"
-
-# Parallel compilation
-cargo build -j 8
-
-# Use cargo-watch for auto-rebuild
-cargo install cargo-watch
-cargo watch -x build
-
-

Development Workflow

- -
# 1. Start development
-just clean
-just build-all
-
-# 2. Make changes to code
-
-# 3. Test changes quickly
-cargo check                # Fast syntax check
-cargo test <specific-test> # Test specific functionality
-
-# 4. Full validation before commit
-just fmt
-just lint
-just test
-
-# 5. Create package for testing
-just package
-
-

Hot Reload Development

-
# Auto-rebuild on file changes
-cargo watch -x build
-
-# Auto-test on changes
-cargo watch -x test
-
-# Run service with auto-reload
-cargo watch -x 'run --bin provisioning-orchestrator'
-
-

Debugging Builds

-

Debug Information

-
# Build with full debug info
-cargo build
-
-# Build with debug info in release mode
-cargo build --release --profile release-with-debug
-
-# Run with backtraces
-RUST_BACKTRACE=1 cargo run
-RUST_BACKTRACE=full cargo run
-
-

Build Verbosity

-
# Verbose build output
-cargo build -vv
-
-# Show build commands
-cargo build -vvv
-
-# Show timing information
-cargo build --timings
-
-

Dependency Tree

-
# View dependency tree
-cargo tree
-
-# Duplicate dependencies
-cargo tree --duplicates
-
-# Build graph visualization
-cargo depgraph | dot -Tpng > deps.png
-
-

Best Practices

-
    -
  • Always run just test before committing
  • -
  • Use cargo fmt and cargo clippy for code quality
  • -
  • Test on multiple platforms before release
  • -
  • Strip binaries for production distributions
  • -
  • Version binaries with semantic versioning
  • -
  • Cache dependencies in CI/CD
  • -
  • Use release profile for production builds
  • -
  • Document build requirements in README
  • -
  • Automate common tasks with Just
  • -
  • Keep build times reasonable (<5 min)
  • -
-

Troubleshooting

-

Common Build Issues

-

Compilation fails with linker error:

-
# Install build dependencies
-sudo apt install build-essential pkg-config libssl-dev
-
-

Out of memory during build:

-
# Reduce parallel jobs
-cargo build -j 2
-
-# Use more swap space
-sudo fallocate -l 8G /swapfile
-sudo mkswap /swapfile
-sudo swapon /swapfile
-
-

Clippy warnings:

-
# Fix automatically where possible
-cargo clippy --all --fix
-
-# Allow specific lints temporarily
-#[allow(clippy::too_many_arguments)]
-
- -
    -
  • Testing - Testing strategies and procedures
  • -
  • Contributing - Contribution guidelines including build requirements
  • -
-

Testing

-

Comprehensive testing strategies for the Provisioning platform including unit tests, integration tests, and 350+ security tests.

-

Testing Overview

-

The platform maintains extensive test coverage across multiple test types:

-
- - - - -
Test TypeCountCoverage TargetAverage Runtime
Unit Tests200+Core logic 80%+< 5 seconds
Integration Tests100+Component integration 60%+< 30 seconds
Security Tests350+Security components 100%< 60 seconds
End-to-End Tests50+Full workflows< 5 minutes
-
-

Running Tests

-

All Tests

-
# Run complete test suite
-cargo test --workspace
-
-# With output visible
-cargo test --workspace -- --nocapture
-
-# Parallel execution with 8 threads
-cargo test --workspace --jobs 8
-
-# Include ignored tests
-cargo test --workspace -- --ignored
-
-

Test by Category

-
# Unit tests only (--lib)
-cargo test --lib
-
-# Integration tests only (--test)
-cargo test --test '*'
-
-# Documentation tests
-cargo test --doc
-
-# Security test suite
-cargo test -p security --test '*'
-
-

Test Specific Component

-
# Test orchestrator crate
-cargo test -p provisioning-orchestrator
-
-# Test control center
-cargo test -p provisioning-control-center
-
-# Test specific module
-cargo test -p provisioning-orchestrator workflows::
-
-# Test specific function
-cargo test -p provisioning-orchestrator test_workflow_creation
-
-

Unit Testing

-

Unit tests verify individual functions and modules in isolation.

-

Rust Unit Tests

-
// src/workflows.rs
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn test_create_workflow() {
-        let config = WorkflowConfig {
-            name: "test-workflow".into(),
-            tasks: vec![],
-        };
-
-        let workflow = Workflow::new(config);
-
-        assert_eq!(workflow.name(), "test-workflow");
-        assert_eq!(workflow.status(), WorkflowStatus::Pending);
-    }
-
-    #[test]
-    fn test_workflow_execution() {
-        let mut workflow = create_test_workflow();
-
-        let result = workflow.execute();
-
-        assert!(result.is_ok());
-        assert_eq!(workflow.status(), WorkflowStatus::Completed);
-    }
-
-    #[test]
-    #[should_panic(expected = "Invalid workflow")]
-    fn test_invalid_workflow() {
-        Workflow::new(invalid_config());
-    }
-}
-

Nushell Unit Tests

-
# tests/test_provider.nu
-use std assert
-
-export def test_validate_config [] {
-    let config = {api_key: "test-key", region: "us-east-1"}
-    let result = validate-config $config
-    assert equal $result.valid true
-}
-
-export def test_create_server [] {
-    let spec = {name: "test-server", plan: "medium"}
-    let server = create-server test-config $spec
-    assert ($server.id != null)
-}
-
-export def main [] {
-    test_validate_config
-    test_create_server
-    print "All tests passed"
-}
-
-

Run Nushell tests:

-
nu tests/test_provider.nu
-
-

Integration Testing

-

Integration tests verify components work together correctly.

-

Service Integration Tests

-
// tests/orchestrator_integration.rs
-use provisioning_orchestrator::Orchestrator;
-use provisioning_database::Database;
-
-#[tokio::test]
-async fn test_workflow_persistence() {
-    let db = Database::new_test().await;
-    let orchestrator = Orchestrator::new(db.clone());
-
-    let workflow_id = orchestrator.create_workflow(test_config()).await.unwrap();
-
-    // Verify workflow persisted to database
-    let workflow = db.get_workflow(&workflow_id).await.unwrap();
-    assert_eq!(workflow.id, workflow_id);
-}
-
-#[tokio::test]
-async fn test_api_integration() {
-    let app = create_test_app().await;
-
-    let response = app
-        .post("/api/v1/workflows")
-        .json(&test_workflow())
-        .send()
-        .await
-        .unwrap();
-
-    assert_eq!(response.status(), 201);
-}
-

Test Containers

-

Use Docker containers for realistic integration testing:

-
use testcontainers::*;
-
-#[tokio::test]
-async fn test_with_database() {
-    let docker = clients::Cli::default();
-    let postgres = docker.run(images::postgres::Postgres::default());
-
-    let db_url = format!(
-        "postgres://postgres@localhost:{}/test",
-        postgres.get_host_port_ipv4(5432)
-    );
-
-    // Run tests against real database
-    let db = Database::connect(&db_url).await.unwrap();
-    // Test database operations...
-}
-

Security Testing

-

Comprehensive security testing with 350+ test cases covering all security components.

-

Authentication Tests

-
#[tokio::test]
-async fn test_jwt_verification() {
-    let auth = AuthService::new();
-
-    let token = auth.generate_token("user123").unwrap();
-    let claims = auth.verify_token(&token).unwrap();
-
-    assert_eq!(claims.sub, "user123");
-}
-
-#[tokio::test]
-async fn test_invalid_token() {
-    let auth = AuthService::new();
-    let result = auth.verify_token("invalid.token.here");
-    assert!(result.is_err());
-}
-
-#[tokio::test]
-async fn test_token_expiration() {
-    let auth = AuthService::new();
-    let token = create_expired_token();
-    let result = auth.verify_token(&token);
-    assert!(matches!(result, Err(AuthError::TokenExpired)));
-}
-

Authorization Tests

-
#[tokio::test]
-async fn test_rbac_enforcement() {
-    let authz = AuthorizationService::new();
-
-    let decision = authz.authorize(
-        "user:user123",
-        "workflow:create",
-        "resource:my-cluster"
-    ).await;
-
-    assert_eq!(decision, Decision::Allow);
-}
-
-#[tokio::test]
-async fn test_policy_denial() {
-    let authz = AuthorizationService::new();
-
-    let decision = authz.authorize(
-        "user:guest",
-        "server:delete",
-        "resource:prod-server"
-    ).await;
-
-    assert_eq!(decision, Decision::Deny);
-}
-

Encryption Tests

-
#[tokio::test]
-async fn test_kms_encryption() {
-    let kms = KmsService::new();
-
-    let plaintext = b"secret data";
-    let ciphertext = kms.encrypt(plaintext).await.unwrap();
-    let decrypted = kms.decrypt(&ciphertext).await.unwrap();
-
-    assert_eq!(plaintext, decrypted.as_slice());
-}
-
-#[tokio::test]
-async fn test_encryption_performance() {
-    let kms = KmsService::new();
-    let plaintext = vec![0u8; 1024]; // 1KB
-
-    let start = Instant::now();
-    kms.encrypt(&plaintext).await.unwrap();
-    let duration = start.elapsed();
-
-    // KMS encryption should complete in < 10ms
-    assert!(duration < Duration::from_millis(10));
-}
-

End-to-End Testing

-

Complete workflow testing from start to finish.

-

Full Workflow Tests

-
#[tokio::test]
-async fn test_complete_workflow() {
-    let platform = Platform::start_test_instance().await;
-
-    // Create infrastructure
-    let cluster_id = platform
-        .create_cluster(test_cluster_config())
-        .await
-        .unwrap();
-
-    // Wait for completion (5 minute timeout)
-    platform
-        .wait_for_cluster(&cluster_id, Duration::from_secs(300))
-        .await;
-
-    // Verify cluster health
-    let health = platform.check_cluster_health(&cluster_id).await;
-    assert!(health.is_healthy());
-
-    // Cleanup
-    platform.delete_cluster(&cluster_id).await.unwrap();
-}
-

Test Fixtures

-

Shared test data and utilities.

-

Common Test Fixtures

-
// tests/fixtures/mod.rs
-pub fn test_workflow_config() -> WorkflowConfig {
-    WorkflowConfig {
-        name: "test-workflow".into(),
-        tasks: vec![
-            Task::new("task1", TaskType::CreateServer),
-            Task::new("task2", TaskType::InstallService),
-        ],
-    }
-}
-
-pub fn test_server_spec() -> ServerSpec {
-    ServerSpec {
-        name: "test-server".into(),
-        plan: "medium".into(),
-        zone: "us-east-1a".into(),
-        image: "ubuntu-24.04".into(),
-    }
-}
-

Mocking

-

Mock external dependencies for isolated testing.

-

Mock External Services

-
use mockall::*;
-
-#[automock]
-trait CloudProvider {
-    async fn create_server(&self, spec: &ServerSpec) -> Result<Server>;
-}
-
-#[tokio::test]
-async fn test_with_mock_provider() {
-    let mut mock_provider = MockCloudProvider::new();
-
-    mock_provider
-        .expect_create_server()
-        .returning| ( | _ Ok(test_server()));
-
-    let result = mock_provider.create_server(&test_spec()).await;
-    assert!(result.is_ok());
-}
-

Test Coverage

-

Measure and maintain code coverage.

-

Generate Coverage Report

-
# Install tarpaulin
-cargo install cargo-tarpaulin
-
-# Generate HTML coverage report
-cargo tarpaulin --out Html --output-dir coverage
-
-# Generate multiple formats
-cargo tarpaulin --out Html --out Xml --out Json
-
-# View coverage
-open coverage/index.html
-
-

Coverage Goals

-
    -
  • Unit tests: Minimum 80% code coverage
  • -
  • Integration tests: Minimum 60% component coverage
  • -
  • Critical paths: 100% coverage required
  • -
  • Security components: 100% coverage required
  • -
-

Performance Testing

-

Benchmark critical operations.

-

Benchmark Tests

-
use criterion::{black_box, criterion_group, criterion_main, Criterion};
-
-fn benchmark_workflow_creation(c: &mut Criterion) {
-    c.bench_function("create_workflow", | | b {
-        b.iter| ( | {
-            Workflow::new(black_box(test_config()))
-        })
-    });
-}
-
-fn benchmark_database_query(c: &mut Criterion) {
-    c.bench_function("query_workflows", | | b {
-        b.iter| ( | {
-            db.query_workflows(black_box(&filter))
-        })
-    });
-}
-
-criterion_group!(benches, benchmark_workflow_creation, benchmark_database_query);
-criterion_main!(benches);
-

Run benchmarks:

-
cargo bench
-
-

Test Best Practices

-
    -
  • Write tests before or alongside code (TDD approach)
  • -
  • Keep tests focused and isolated
  • -
  • Use descriptive test names that explain what is tested
  • -
  • Clean up test resources (databases, files, containers)
  • -
  • Mock external dependencies to avoid flaky tests
  • -
  • Test both success and error conditions
  • -
  • Maintain shared test fixtures for consistency
  • -
  • Run tests in CI/CD pipeline
  • -
  • Monitor test execution time (fail if too slow)
  • -
  • Refactor tests alongside production code
  • -
-

Continuous Testing

-

Watch Mode

-

Auto-run tests on code changes:

-
# Install cargo-watch
-cargo install cargo-watch
-
-# Watch and run tests
-cargo watch -x test
-
-# Watch specific package
-cargo watch -x 'test -p provisioning-orchestrator'
-
-

Pre-Commit Testing

-

Run tests automatically before commits:

-
# Install pre-commit hooks
-pre-commit install
-
-# Runs on every commit:
-# - cargo test
-# - cargo clippy
-# - cargo fmt --check
-
- - -

Contributing

-

Guidelines for contributing to the Provisioning platform including setup, workflow, and best practices.

-

Getting Started

-

Prerequisites

-

Install required development tools:

-
# Rust toolchain (latest stable)
-curl --proto '=https' --tlsv1.2 -sSf  [https://sh.rustup.rs](https://sh.rustup.rs) | sh
-
-# Nushell shell
-brew install nushell
-
-# Nickel configuration language
-brew install nickel
-
-# Just task runner
-brew install just
-
-# Additional development tools
-cargo install cargo-watch cargo-tarpaulin cargo-audit
-
-

Development Workflow

-

Follow these guidelines for all code changes and ensure adherence to the project’s technical standards.

-
    -
  1. Read applicable language guidelines
  2. -
  3. Create feature branch from main
  4. -
  5. Make changes following project standards
  6. -
  7. Write or update tests
  8. -
  9. Run full test suite and linting
  10. -
  11. Create pull request with clear description
  12. -
-

Code Style Guidelines

-

Rust Code

-

Rust code guidelines:

-
    -
  • Use idiomatic Rust patterns
  • -
  • No unwrap() in production code
  • -
  • Comprehensive error handling with custom error types
  • -
  • Format with cargo fmt
  • -
  • Pass cargo clippy -- -D warnings with zero warnings
  • -
  • Add inline documentation for public APIs
  • -
-

Nushell Scripts

-

Nushell code guidelines:

-
    -
  • Use structured data pipelines
  • -
  • Avoid external command dependencies where possible
  • -
  • Handle errors gracefully with try-catch
  • -
  • Document functions with comments
  • -
  • Use type annotations for clarity
  • -
-

Nickel Schemas

-

Nickel configuration guidelines:

-
    -
  • Define clear type constraints
  • -
  • Use lazy evaluation appropriately
  • -
  • Provide default values where sensible
  • -
  • Document schema fields
  • -
  • Validate schemas with nickel typecheck
  • -
-

Testing Requirements

-

All contributions must include appropriate tests:

-

Required Tests

-
    -
  • Unit tests for all new functions
  • -
  • Integration tests for component interactions
  • -
  • Security tests for security-related changes
  • -
  • Documentation tests for code examples
  • -
-

Running Tests

-
# Run all tests
-just test
-
-# Run specific test suite
-cargo test -p provisioning-orchestrator
-
-# Run with coverage
-cargo tarpaulin --out Html
-
-

Test Coverage Requirements

-
    -
  • Unit tests: Minimum 80% code coverage
  • -
  • Critical paths: 100% coverage
  • -
  • Security components: 100% coverage
  • -
-

Documentation

-

Required Documentation

-

All code changes must include:

-
    -
  • Inline code documentation for public APIs
  • -
  • Updated README if adding new components
  • -
  • Examples showing usage
  • -
  • Migration guide for breaking changes
  • -
-

Documentation Standards

-

Documentation standards:

-
    -
  • Use Markdown for all documentation
  • -
  • Code blocks must specify language
  • -
  • Keep lines ≤150 characters
  • -
  • No bare URLs (use markdown links)
  • -
  • Test all code examples
  • -
-

Commit Message Format

-

Use conventional commit format:

-
<type>(<scope>): <subject>
-
-<body>
-
-<footer>
-
-

Types:

-
    -
  • feat: New feature
  • -
  • fix: Bug fix
  • -
  • docs: Documentation changes
  • -
  • test: Adding or updating tests
  • -
  • refactor: Code refactoring
  • -
  • perf: Performance improvements
  • -
  • chore: Maintenance tasks
  • -
-

Example:

-
feat(orchestrator): add workflow retry mechanism
-
-- Implement exponential backoff strategy
-- Add max retry configuration option
-- Update workflow state tracking
-
-Closes #123
-
-

Pull Request Process

-

Before Creating PR

-
    -
  1. Update your branch with latest main
  2. -
  3. Run full test suite: just test
  4. -
  5. Run linters: just lint
  6. -
  7. Format code: just fmt
  8. -
  9. Build successfully: just build-all
  10. -
-

PR Description Template

-
## Description
-Brief description of changes and motivation
-
-## Type of Change
-- [ ] Bug fix (non-breaking change fixing an issue)
-- [ ] New feature (non-breaking change adding functionality)
-- [ ] Breaking change (fix or feature causing existing functionality to change)
-- [ ] Documentation update
-
-## Testing
-- [ ] Unit tests added or updated
-- [ ] Integration tests pass
-- [ ] Manual testing completed
-- [ ] Test coverage maintained or improved
-
-## Checklist
-- [ ] Code follows project style guidelines
-- [ ] Self-review completed
-- [ ] Documentation updated
-- [ ] No new compiler warnings
-- [ ] Tested on relevant platforms
-
-## Related Issues
-Closes #<issue-number>
-
-

Code Review

-

All PRs require code review before merging. Reviewers check:

-
    -
  • Correctness and quality of implementation
  • -
  • Test coverage and quality
  • -
  • Documentation completeness
  • -
  • Adherence to style guidelines
  • -
  • Security implications
  • -
  • Performance considerations
  • -
  • Breaking changes properly documented
  • -
-

Development Best Practices

-

Code Quality

-
    -
  • Write self-documenting code with clear naming
  • -
  • Keep functions focused and single-purpose
  • -
  • Avoid premature optimization
  • -
  • Use meaningful variable and function names
  • -
  • Comment complex logic, not obvious code
  • -
-

Error Handling

-
    -
  • Use custom error types, not strings
  • -
  • Provide context in error messages
  • -
  • Handle errors at appropriate level
  • -
  • Log errors with sufficient detail
  • -
  • Never ignore errors silently
  • -
-

Performance

-
    -
  • Profile before optimizing
  • -
  • Use appropriate data structures
  • -
  • Minimize allocations in hot paths
  • -
  • Consider async for I/O-bound operations
  • -
  • Benchmark performance-critical code
  • -
-

Security

-
    -
  • Validate all inputs
  • -
  • Never log sensitive data
  • -
  • Use constant-time comparisons for secrets
  • -
  • Follow principle of least privilege
  • -
  • Review security guidelines for security-related changes
  • -
-

Getting Help

-

Need assistance with contributions?

-
    -
  1. Check existing documentation in docs/
  2. -
  3. Search for similar closed issues and PRs
  4. -
  5. Ask questions in GitHub Discussions
  6. -
  7. Reach out to maintainers
  8. -
-

Recognition

-

Contributors are recognized in:

-
    -
  • CONTRIBUTORS.md file
  • -
  • Release notes for significant contributions
  • -
  • Project documentation acknowledgments
  • -
-

Thank you for contributing to the Provisioning platform!

-

- Provisioning Logo -

-

- Provisioning -

-

API Reference

-

Complete API documentation for the Provisioning platform, including REST endpoints, CLI -commands, and library interfaces.

-

Available APIs

-

The Provisioning platform provides multiple API surfaces for different use cases and integration patterns.

-

REST API

-

HTTP-based APIs for external integration and programmatic access.

- -

Command-Line Interface

-

Native CLI for interactive and scripted operations.

- -

Nushell Libraries

-

Internal library APIs for extension development and customization.

- -

API Categories

-

Infrastructure Management

-

Manage cloud resources, servers, and infrastructure components.

-

REST Endpoints:

-
    -
  • Server Management - Create, delete, update, list servers
  • -
  • Provider Integration - Cloud provider operations
  • -
  • Network Configuration - Network, firewall, routing
  • -
-

CLI Commands:

-
    -
  • provisioning server - Server lifecycle operations
  • -
  • provisioning provider - Provider configuration
  • -
  • provisioning infrastructure - Infrastructure queries
  • -
-

Service Orchestration

-

Deploy and manage infrastructure services and clusters.

-

REST Endpoints:

-
    -
  • Task Service Deployment - Install, remove, update services
  • -
  • Cluster Management - Cluster lifecycle operations
  • -
  • Dependency Resolution - Automatic dependency handling
  • -
-

CLI Commands:

-
    -
  • provisioning taskserv - Task service operations
  • -
  • provisioning cluster - Cluster management
  • -
  • provisioning workflow - Workflow execution
  • -
-

Workflow Automation

-

Execute batch operations and complex workflows.

-

REST Endpoints:

-
    -
  • Workflow Submission - Submit and track workflows
  • -
  • Task Status - Real-time task monitoring
  • -
  • Checkpoint Recovery - Resume interrupted workflows
  • -
-

CLI Commands:

-
    -
  • provisioning batch - Batch workflow operations
  • -
  • provisioning workflow - Workflow management
  • -
  • provisioning orchestrator - Orchestrator control
  • -
-

Configuration Management

-

Manage configuration across hierarchical layers.

-

REST Endpoints:

-
    -
  • Configuration Retrieval - Get active configuration
  • -
  • Validation - Validate configuration files
  • -
  • Schema Queries - Query configuration schemas
  • -
-

CLI Commands:

-
    -
  • provisioning config - Configuration operations
  • -
  • provisioning validate - Validation commands
  • -
  • provisioning schema - Schema management
  • -
-

Security & Authentication

-

Manage authentication, authorization, secrets, and encryption.

-

REST Endpoints:

-
    -
  • Authentication - Login, token management, MFA
  • -
  • Authorization - Policy evaluation, permissions
  • -
  • Secrets Management - Secret storage and retrieval
  • -
  • KMS Operations - Key management and encryption
  • -
  • Audit Logging - Security event tracking
  • -
-

CLI Commands:

-
    -
  • provisioning auth - Authentication operations
  • -
  • provisioning vault - Secret management
  • -
  • provisioning kms - Key management
  • -
  • provisioning audit - Audit log queries
  • -
-

Platform Services

-

Control platform components and system health.

-

REST Endpoints:

-
    -
  • Service Health - Health checks and status
  • -
  • Service Control - Start, stop, restart services
  • -
  • Configuration - Service configuration management
  • -
  • Monitoring - Metrics and performance data
  • -
-

CLI Commands:

-
    -
  • provisioning platform - Platform management
  • -
  • provisioning service - Service control
  • -
  • provisioning health - Health monitoring
  • -
-

API Conventions

-

REST API Standards

-

All REST endpoints follow consistent conventions:

-

Authentication:

-
Authorization: Bearer <jwt-token>
-
-

Request Format:

-
Content-Type: application/json
-
-

Response Format:

-
{
-  "status": "succes| s error",
-  "data": { ... },
-  "message": "Human-readable message",
-  "timestamp": "2026-01-16T10:30:00Z"
-}
-
-

Error Responses:

-
{
-  "status": "error",
-  "error": {
-    "code": "ERR_CODE",
-    "message": "Error description",
-    "details": { ... }
-  },
-  "timestamp": "2026-01-16T10:30:00Z"
-}
-
-

CLI Command Patterns

-

All CLI commands follow consistent patterns:

-

Common Flags:

-
    -
  • --yes - Skip confirmation prompts
  • -
  • --check - Dry-run mode, show what would happen
  • -
  • --wait - Wait for operation completion
  • -
  • --format jso| n yam| l table - Output format
  • -
  • --verbose - Detailed output
  • -
  • --quiet - Minimal output
  • -
-

Command Structure:

-
provisioning <domain> <action> <resource> [flags]
-
-

Examples:

-
provisioning server create web-01 --plan medium --yes
-provisioning taskserv install kubernetes --cluster prod
-provisioning workflow submit deploy.ncl --wait
-
-

Library Function Signatures

-

Nushell library functions follow consistent signatures:

-

Parameter Order:

-
    -
  1. Required positional parameters
  2. -
  3. Optional positional parameters
  4. -
  5. Named parameters (flags)
  6. -
-

Return Values:

-
    -
  • Success: Returns data structure (record, table, list)
  • -
  • Error: Throws error with structured message
  • -
-

Example:

-
def create-server [
-  name: string           # Required: server name
-  --plan: string = "medium"  # Optional: server plan
-  --wait                 # Optional: wait flag
-] {
-  # Implementation
-}
-
-

API Versioning

-

The Provisioning platform uses semantic versioning for APIs:

-
    -
  • Major version - Breaking changes to API contracts
  • -
  • Minor version - Backwards-compatible additions
  • -
  • Patch version - Backwards-compatible bug fixes
  • -
-

Current API Version: v1.0.0

-

Version Compatibility:

-
    -
  • REST API includes version in URL: /api/v1/servers
  • -
  • CLI maintains backwards compatibility across minor versions
  • -
  • Libraries use semantic import versioning
  • -
-

Rate Limiting

-

REST API endpoints implement rate limiting to ensure platform stability:

-
    -
  • Default Limit: 100 requests per minute per API key
  • -
  • Burst Limit: 20 requests per second
  • -
  • Headers: Rate limit information in response headers
  • -
-
X-RateLimit-Limit: 100
-X-RateLimit-Remaining: 95
-X-RateLimit-Reset: 1642334400
-
-

Authentication

-

All APIs require authentication except public health endpoints.

-

Supported Methods:

-
    -
  • JWT Tokens - Primary authentication method
  • -
  • API Keys - For service-to-service integration
  • -
  • MFA - Multi-factor authentication for sensitive operations
  • -
-

Token Management:

-
# Login and obtain token
-provisioning auth login --user admin
-
-# Use token in requests
-curl -H "Authorization: Bearer $TOKEN"  [https://api/v1/servers](https://api/v1/servers)
-
-

See Authentication Guide for complete details.

-

API Discovery

-

Discover available APIs programmatically:

-

REST API:

-
# Get API specification (OpenAPI)
-curl  [https://api/v1/openapi.json](https://api/v1/openapi.json)
-
-

CLI:

-
# List all commands
-provisioning help --all
-
-# Get command details
-provisioning server help
-
-

Libraries:

-
# List available modules
-use lib_provisioning *
-$nu.scope.commands | where is_custom
-
-

Next Steps

- - - -

REST API Reference

-

Complete HTTP API documentation for the Provisioning platform covering 83+ endpoints across 9 platform services.

-

Base URL

-
 [https://api.provisioning.local/api/v1](https://api.provisioning.local/api/v1)
-
-

All endpoints are prefixed with /api/v1 for version compatibility.

-

Authentication

-

All API requests require authentication using JWT Bearer tokens:

-
Authorization: Bearer <your-jwt-token>
-
-

Obtain tokens via the Authentication API endpoints.

-

Common Response Format

-

All responses follow a consistent structure:

-

Success Response:

-
{
-  "status": "success",
-  "data": { ... },
-  "message": "Operation completed successfully",
-  "timestamp": "2026-01-16T10:30:00Z"
-}
-
-

Error Response:

-
{
-  "status": "error",
-  "error": {
-    "code": "ERR_CODE",
-    "message": "Human-readable error message",
-    "details": { ... }
-  },
-  "timestamp": "2026-01-16T10:30:00Z"
-}
-
-

HTTP Status Codes

-
- - - - - - - - - - - - -
CodeMeaningUsage
200OKSuccessful GET, PUT, PATCH requests
201CreatedSuccessful POST request creating resource
202AcceptedAsync operation accepted, check status
204No ContentSuccessful DELETE request
400Bad RequestInvalid request parameters
401UnauthorizedMissing or invalid authentication
403ForbiddenValid auth but insufficient permissions
404Not FoundResource does not exist
409ConflictResource conflict (duplicate name, etc.)
429Too Many RequestsRate limit exceeded
500Internal Server ErrorServer error
503Service UnavailableService temporarily unavailable
-
-

API Services

-

The platform exposes 9 distinct services with REST APIs:

-
    -
  1. Orchestrator - Workflow execution and task management
  2. -
  3. Control Center - Platform management and monitoring
  4. -
  5. Extension Registry - Extension distribution
  6. -
  7. Auth Service - Authentication and identity
  8. -
  9. Vault Service - Secrets management
  10. -
  11. KMS Service - Key management and encryption
  12. -
  13. Audit Service - Audit logging and compliance
  14. -
  15. Policy Service - Authorization policies
  16. -
  17. Gateway Service - API gateway and routing
  18. -
-

Orchestrator API

-

Workflow execution, task scheduling, and state management.

-

Base Path: /api/v1/orchestrator

-

Submit Workflow

-

Submit a new workflow for execution.

-

Endpoint: POST /workflows

-

Request:

-
{
-  "name": "deploy-cluster",
-  "type": "cluster",
-  "operations": [
-    {
-      "id": "create-servers",
-      "type": "server",
-      "action": "create",
-      "params": {
-        "infra": "my-cluster.ncl"
-      }
-    },
-    {
-      "id": "install-k8s",
-      "type": "taskserv",
-      "action": "install",
-      "params": {
-        "name": "kubernetes"
-      },
-      "dependencies": ["create-servers"]
-    }
-  ],
-  "priority": "normal",
-  "checkpoint_enabled": true
-}
-
-

Response:

-
{
-  "status": "success",
-  "data": {
-    "workflow_id": "wf-20260116-abc123",
-    "state": "queued",
-    "created_at": "2026-01-16T10:30:00Z"
-  }
-}
-
-

Get Workflow Status

-

Retrieve workflow execution status.

-

Endpoint: GET /workflows/{workflow_id}

-

Response:

-
{
-  "status": "success",
-  "data": {
-    "workflow_id": "wf-20260116-abc123",
-    "name": "deploy-cluster",
-    "state": "running",
-    "progress": {
-      "total_tasks": 2,
-      "completed": 1,
-      "failed": 0,
-      "running": 1
-    },
-    "current_task": {
-      "id": "install-k8s",
-      "state": "running",
-      "started_at": "2026-01-16T10:32:00Z"
-    },
-    "created_at": "2026-01-16T10:30:00Z",
-    "updated_at": "2026-01-16T10:32:15Z"
-  }
-}
-
-

List Workflows

-

List all workflows with optional filtering.

-

Endpoint: GET /workflows

-

Query Parameters:

-
    -
  • state (optional) - Filter by state: queue| d runnin| g complete| d failed
  • -
  • limit (optional) - Maximum results (default: 50, max: 100)
  • -
  • offset (optional) - Pagination offset
  • -
-

Response:

-
{
-  "status": "success",
-  "data": {
-    "workflows": [
-      {
-        "workflow_id": "wf-20260116-abc123",
-        "name": "deploy-cluster",
-        "state": "running",
-        "created_at": "2026-01-16T10:30:00Z"
-      }
-    ],
-    "total": 1,
-    "limit": 50,
-    "offset": 0
-  }
-}
-
-

Cancel Workflow

-

Cancel a running workflow.

-

Endpoint: POST /workflows/{workflow_id}/cancel

-

Response:

-
{
-  "status": "success",
-  "data": {
-    "workflow_id": "wf-20260116-abc123",
-    "state": "cancelled",
-    "cancelled_at": "2026-01-16T10:35:00Z"
-  }
-}
-
-

Get Task Logs

-

Retrieve logs for a specific task in a workflow.

-

Endpoint: GET /workflows/{workflow_id}/tasks/{task_id}/logs

-

Query Parameters:

-
    -
  • lines (optional) - Number of lines (default: 100)
  • -
  • follow (optional) - Stream logs (SSE)
  • -
-

Response:

-
{
-  "status": "success",
-  "data": {
-    "task_id": "install-k8s",
-    "logs": [
-      {
-        "timestamp": "2026-01-16T10:32:00Z",
-        "level": "info",
-        "message": "Starting Kubernetes installation"
-      },
-      {
-        "timestamp": "2026-01-16T10:32:15Z",
-        "level": "info",
-        "message": "Downloading Kubernetes binaries"
-      }
-    ]
-  }
-}
-
-

Resume Workflow

-

Resume a failed workflow from checkpoint.

-

Endpoint: POST /workflows/{workflow_id}/resume

-

Request:

-
{
-  "from_checkpoint": "create-servers",
-  "skip_failed": false
-}
-
-

Response:

-
{
-  "status": "success",
-  "data": {
-    "workflow_id": "wf-20260116-abc123",
-    "state": "running",
-    "resumed_at": "2026-01-16T10:40:00Z"
-  }
-}
-
-

Control Center API

-

Platform management, service control, and monitoring.

-

Base Path: /api/v1/control-center

-

List Services

-

List all platform services and their status.

-

Endpoint: GET /services

-

Response:

-
{
-  "status": "success",
-  "data": {
-    "services": [
-      {
-        "name": "orchestrator",
-        "state": "running",
-        "health": "healthy",
-        "uptime": 86400,
-        "version": "1.0.0"
-      },
-      {
-        "name": "control-center",
-        "state": "running",
-        "health": "healthy",
-        "uptime": 86400,
-        "version": "1.0.0"
-      }
-    ]
-  }
-}
-
-

Get Service Health

-

Check health status of a specific service.

-

Endpoint: GET /services/{service_name}/health

-

Response:

-
{
-  "status": "success",
-  "data": {
-    "service": "orchestrator",
-    "health": "healthy",
-    "checks": {
-      "api": "pass",
-      "database": "pass",
-      "storage": "pass"
-    },
-    "timestamp": "2026-01-16T10:30:00Z"
-  }
-}
-
-

Start Service

-

Start a stopped platform service.

-

Endpoint: POST /services/{service_name}/start

-

Response:

-
{
-  "status": "success",
-  "data": {
-    "service": "orchestrator",
-    "state": "starting",
-    "message": "Service start initiated"
-  }
-}
-
-

Stop Service

-

Gracefully stop a running service.

-

Endpoint: POST /services/{service_name}/stop

-

Request:

-
{
-  "force": false,
-  "timeout": 30
-}
-
-

Response:

-
{
-  "status": "success",
-  "data": {
-    "service": "orchestrator",
-    "state": "stopped",
-    "message": "Service stopped gracefully"
-  }
-}
-
-

Restart Service

-

Restart a platform service.

-

Endpoint: POST /services/{service_name}/restart

-

Response:

-
{
-  "status": "success",
-  "data": {
-    "service": "orchestrator",
-    "state": "restarting",
-    "message": "Service restart initiated"
-  }
-}
-
-

Get Service Configuration

-

Retrieve service configuration.

-

Endpoint: GET /services/{service_name}/config

-

Response:

-
{
-  "status": "success",
-  "data": {
-    "service": "orchestrator",
-    "config": {
-      "port": 8080,
-      "max_workers": 10,
-      "checkpoint_enabled": true
-    }
-  }
-}
-
-

Update Service Configuration

-

Update service configuration (requires restart).

-

Endpoint: PUT /services/{service_name}/config

-

Request:

-
{
-  "config": {
-    "max_workers": 20
-  },
-  "restart": true
-}
-
-

Response:

-
{
-  "status": "success",
-  "data": {
-    "service": "orchestrator",
-    "config_updated": true,
-    "restart_required": true
-  }
-}
-
-

Get Platform Metrics

-

Retrieve platform-wide metrics.

-

Endpoint: GET /metrics

-

Response:

-
{
-  "status": "success",
-  "data": {
-    "platform": {
-      "uptime": 86400,
-      "version": "1.0.0"
-    },
-    "resources": {
-      "cpu_usage": 45.2,
-      "memory_usage": 62.8,
-      "disk_usage": 38.1
-    },
-    "workflows": {
-      "total": 150,
-      "running": 5,
-      "queued": 2,
-      "failed": 3
-    },
-    "timestamp": "2026-01-16T10:30:00Z"
-  }
-}
-
-

Extension Registry API

-

Extension distribution, versioning, and discovery.

-

Base Path: /api/v1/registry

-

List Extensions

-

List available extensions.

-

Endpoint: GET /extensions

-

Query Parameters:

-
    -
  • type (optional) - Filter by type: provide| r taskser| v cluste| r workflow
  • -
  • search (optional) - Search by name or description
  • -
-

Response:

-
{
-  "status": "success",
-  "data": {
-    "extensions": [
-      {
-        "name": "kubernetes",
-        "type": "taskserv",
-        "version": "1.29.0",
-        "description": "Kubernetes orchestration platform",
-        "dependencies": ["containerd", "etcd"]
-      }
-    ],
-    "total": 1
-  }
-}
-
-

Get Extension Details

-

Get detailed information about an extension.

-

Endpoint: GET /extensions/{extension_name}

-

Response:

-
{
-  "status": "success",
-  "data": {
-    "name": "kubernetes",
-    "type": "taskserv",
-    "version": "1.29.0",
-    "description": "Kubernetes orchestration platform",
-    "dependencies": ["containerd", "etcd"],
-    "versions": ["1.29.0", "1.28.5", "1.27.10"],
-    "metadata": {
-      "author": "Provisioning Team",
-      "license": "Apache-2.0",
-      "homepage": " [https://kubernetes.io"](https://kubernetes.io")
-    }
-  }
-}
-
-

Download Extension

-

Download an extension package.

-

Endpoint: GET /extensions/{extension_name}/download

-

Query Parameters:

-
    -
  • version (optional) - Specific version (default: latest)
  • -
-

Response: Binary OCI image blob

-

Publish Extension

-

Publish a new extension or version.

-

Endpoint: POST /extensions

-

Request: Multipart form data with OCI image

-

Response:

-
{
-  "status": "success",
-  "data": {
-    "name": "kubernetes",
-    "version": "1.29.0",
-    "published_at": "2026-01-16T10:30:00Z"
-  }
-}
-
-

Auth Service API

-

Authentication, identity management, and MFA.

-

Base Path: /api/v1/auth

-

Login

-

Authenticate user and obtain JWT token.

-

Endpoint: POST /login

-

Request:

-
{
-  "username": "admin",
-  "password": "secure-password"
-}
-
-

Response:

-
{
-  "status": "success",
-  "data": {
-    "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
-    "refresh_token": "refresh-token-abc123",
-    "expires_in": 3600,
-    "user": {
-      "id": "user-123",
-      "username": "admin",
-      "roles": ["admin"]
-    }
-  }
-}
-
-

MFA Challenge

-

Request MFA challenge for two-factor authentication.

-

Endpoint: POST /mfa/challenge

-

Request:

-
{
-  "username": "admin",
-  "password": "secure-password"
-}
-
-

Response:

-
{
-  "status": "success",
-  "data": {
-    "challenge_id": "challenge-abc123",
-    "methods": ["totp", "webauthn"],
-    "expires_in": 300
-  }
-}
-
-

MFA Verify

-

Verify MFA code and complete authentication.

-

Endpoint: POST /mfa/verify

-

Request:

-
{
-  "challenge_id": "challenge-abc123",
-  "method": "totp",
-  "code": "123456"
-}
-
-

Response:

-
{
-  "status": "success",
-  "data": {
-    "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
-    "refresh_token": "refresh-token-abc123",
-    "expires_in": 3600
-  }
-}
-
-

Refresh Token

-

Obtain new access token using refresh token.

-

Endpoint: POST /refresh

-

Request:

-
{
-  "refresh_token": "refresh-token-abc123"
-}
-
-

Response:

-
{
-  "status": "success",
-  "data": {
-    "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
-    "expires_in": 3600
-  }
-}
-
-

Logout

-

Invalidate current session and tokens.

-

Endpoint: POST /logout

-

Request:

-
{
-  "refresh_token": "refresh-token-abc123"
-}
-
-

Response:

-
{
-  "status": "success",
-  "message": "Logged out successfully"
-}
-
-

Create User

-

Create a new user account (admin only).

-

Endpoint: POST /users

-

Request:

-
{
-  "username": "developer",
-  "email": "[dev@example.com](mailto:dev@example.com)",
-  "password": "secure-password",
-  "roles": ["developer"]
-}
-
-

Response:

-
{
-  "status": "success",
-  "data": {
-    "user_id": "user-456",
-    "username": "developer",
-    "created_at": "2026-01-16T10:30:00Z"
-  }
-}
-
-

List Users

-

List all users (admin only).

-

Endpoint: GET /users

-

Response:

-
{
-  "status": "success",
-  "data": {
-    "users": [
-      {
-        "user_id": "user-123",
-        "username": "admin",
-        "email": "[admin@example.com](mailto:admin@example.com)",
-        "roles": ["admin"],
-        "created_at": "2026-01-01T00:00:00Z"
-      }
-    ],
-    "total": 1
-  }
-}
-
-

Vault Service API

-

Secrets management and dynamic credentials.

-

Base Path: /api/v1/vault

-

Store Secret

-

Store a new secret.

-

Endpoint: POST /secrets

-

Request:

-
{
-  "path": "database/postgres/password",
-  "data": {
-    "username": "dbuser",
-    "password": "db-password"
-  },
-  "metadata": {
-    "description": "PostgreSQL credentials"
-  }
-}
-
-

Response:

-
{
-  "status": "success",
-  "data": {
-    "path": "database/postgres/password",
-    "version": 1,
-    "created_at": "2026-01-16T10:30:00Z"
-  }
-}
-
-

Retrieve Secret

-

Retrieve a stored secret.

-

Endpoint: GET /secrets/{path}

-

Query Parameters:

-
    -
  • version (optional) - Specific version (default: latest)
  • -
-

Response:

-
{
-  "status": "success",
-  "data": {
-    "path": "database/postgres/password",
-    "version": 1,
-    "data": {
-      "username": "dbuser",
-      "password": "db-password"
-    },
-    "metadata": {
-      "description": "PostgreSQL credentials"
-    },
-    "created_at": "2026-01-16T10:30:00Z"
-  }
-}
-
-

List Secrets

-

List all secret paths.

-

Endpoint: GET /secrets

-

Query Parameters:

-
    -
  • prefix (optional) - Filter by path prefix
  • -
-

Response:

-
{
-  "status": "success",
-  "data": {
-    "secrets": [
-      {
-        "path": "database/postgres/password",
-        "versions": 1,
-        "updated_at": "2026-01-16T10:30:00Z"
-      }
-    ],
-    "total": 1
-  }
-}
-
-

Delete Secret

-

Delete a secret (soft delete, preserves versions).

-

Endpoint: DELETE /secrets/{path}

-

Response:

-
{
-  "status": "success",
-  "message": "Secret deleted successfully"
-}
-
-

Generate Dynamic Credentials

-

Generate temporary credentials for supported backends.

-

Endpoint: POST /dynamic/{backend}/generate

-

Request:

-
{
-  "role": "readonly",
-  "ttl": 3600
-}
-
-

Response:

-
{
-  "status": "success",
-  "data": {
-    "credentials": {
-      "username": "v-readonly-abc123",
-      "password": "temporary-password"
-    },
-    "ttl": 3600,
-    "expires_at": "2026-01-16T11:30:00Z"
-  }
-}
-
-

KMS Service API

-

Key management, encryption, and decryption.

-

Base Path: /api/v1/kms

-

Encrypt Data

-

Encrypt data using a managed key.

-

Endpoint: POST /encrypt

-

Request:

-
{
-  "key_id": "master-key-01",
-  "plaintext": "sensitive data",
-  "context": {
-    "purpose": "config-encryption"
-  }
-}
-
-

Response:

-
{
-  "status": "success",
-  "data": {
-    "ciphertext": "AQICAHh...",
-    "key_id": "master-key-01"
-  }
-}
-
-

Decrypt Data

-

Decrypt previously encrypted data.

-

Endpoint: POST /decrypt

-

Request:

-
{
-  "ciphertext": "AQICAHh...",
-  "context": {
-    "purpose": "config-encryption"
-  }
-}
-
-

Response:

-
{
-  "status": "success",
-  "data": {
-    "plaintext": "sensitive data",
-    "key_id": "master-key-01"
-  }
-}
-
-

Create Key

-

Create a new encryption key.

-

Endpoint: POST /keys

-

Request:

-
{
-  "key_id": "app-key-01",
-  "algorithm": "AES-256-GCM",
-  "metadata": {
-    "description": "Application encryption key"
-  }
-}
-
-

Response:

-
{
-  "status": "success",
-  "data": {
-    "key_id": "app-key-01",
-    "algorithm": "AES-256-GCM",
-    "created_at": "2026-01-16T10:30:00Z"
-  }
-}
-
-

List Keys

-

List all encryption keys.

-

Endpoint: GET /keys

-

Response:

-
{
-  "status": "success",
-  "data": {
-    "keys": [
-      {
-        "key_id": "master-key-01",
-        "algorithm": "AES-256-GCM",
-        "state": "enabled",
-        "created_at": "2026-01-01T00:00:00Z"
-      }
-    ],
-    "total": 1
-  }
-}
-
-

Rotate Key

-

Rotate an encryption key.

-

Endpoint: POST /keys/{key_id}/rotate

-

Response:

-
{
-  "status": "success",
-  "data": {
-    "key_id": "master-key-01",
-    "version": 2,
-    "rotated_at": "2026-01-16T10:30:00Z"
-  }
-}
-
-

Audit Service API

-

Audit logging, compliance tracking, and event queries.

-

Base Path: /api/v1/audit

-

Query Audit Logs

-

Query audit events with filtering.

-

Endpoint: GET /logs

-

Query Parameters:

-
    -
  • user (optional) - Filter by user ID
  • -
  • action (optional) - Filter by action type
  • -
  • resource (optional) - Filter by resource type
  • -
  • start_time (optional) - Start timestamp
  • -
  • end_time (optional) - End timestamp
  • -
  • limit (optional) - Maximum results (default: 100)
  • -
-

Response:

-
{
-  "status": "success",
-  "data": {
-    "events": [
-      {
-        "event_id": "evt-abc123",
-        "timestamp": "2026-01-16T10:30:00Z",
-        "user": "admin",
-        "action": "workflow.submit",
-        "resource": "wf-20260116-abc123",
-        "result": "success",
-        "metadata": {
-          "workflow_name": "deploy-cluster"
-        }
-      }
-    ],
-    "total": 1
-  }
-}
-
-

Export Audit Logs

-

Export audit logs in various formats.

-

Endpoint: GET /export

-

Query Parameters:

-
    -
  • format - Export format: jso| n cs| v syslo| g ce| f splunk
  • -
  • start_time - Start timestamp
  • -
  • end_time - End timestamp
  • -
-

Response: File download in requested format

-

Get Compliance Report

-

Generate compliance report for specific period.

-

Endpoint: GET /compliance

-

Query Parameters:

-
    -
  • standard - Compliance standard: gdp| r soc| 2 iso27001
  • -
  • start_time - Report start time
  • -
  • end_time - Report end time
  • -
-

Response:

-
{
-  "status": "success",
-  "data": {
-    "standard": "soc2",
-    "period": {
-      "start": "2026-01-01T00:00:00Z",
-      "end": "2026-01-16T23:59:59Z"
-    },
-    "controls": [
-      {
-        "control_id": "CC6.1",
-        "status": "compliant",
-        "evidence_count": 150
-      }
-    ],
-    "summary": {
-      "total_controls": 10,
-      "compliant": 9,
-      "non_compliant": 1
-    }
-  }
-}
-
-

Policy Service API

-

Authorization policy management (Cedar policies).

-

Base Path: /api/v1/policy

-

Evaluate Policy

-

Evaluate authorization request against policies.

-

Endpoint: POST /evaluate

-

Request:

-
{
-  "principal": "User::\"admin\"",
-  "action": "Action::\"workflow.submit\"",
-  "resource": "Workflow::\"deploy-cluster\"",
-  "context": {
-    "time": "2026-01-16T10:30:00Z"
-  }
-}
-
-

Response:

-
{
-  "status": "success",
-  "data": {
-    "decision": "allow",
-    "policies": ["admin-full-access"],
-    "diagnostics": {
-      "reason": "User has admin role"
-    }
-  }
-}
-
-

Create Policy

-

Create a new authorization policy.

-

Endpoint: POST /policies

-

Request:

-
{
-  "policy_id": "developer-read-only",
-  "content": "permit(principal in Role::\"developer\", action == Action::\"read\", resource);",
-  "description": "Developers have read-only access"
-}
-
-

Response:

-
{
-  "status": "success",
-  "data": {
-    "policy_id": "developer-read-only",
-    "created_at": "2026-01-16T10:30:00Z"
-  }
-}
-
-

List Policies

-

List all authorization policies.

-

Endpoint: GET /policies

-

Response:

-
{
-  "status": "success",
-  "data": {
-    "policies": [
-      {
-        "policy_id": "admin-full-access",
-        "description": "Admins have full access",
-        "created_at": "2026-01-01T00:00:00Z"
-      }
-    ],
-    "total": 1
-  }
-}
-
-

Update Policy

-

Update an existing policy (hot reload).

-

Endpoint: PUT /policies/{policy_id}

-

Request:

-
{
-  "content": "permit(principal in Role::\"developer\", action == Action::\"read\", resource);"
-}
-
-

Response:

-
{
-  "status": "success",
-  "data": {
-    "policy_id": "developer-read-only",
-    "updated_at": "2026-01-16T10:30:00Z",
-    "reloaded": true
-  }
-}
-
-

Delete Policy

-

Delete an authorization policy.

-

Endpoint: DELETE /policies/{policy_id}

-

Response:

-
{
-  "status": "success",
-  "message": "Policy deleted successfully"
-}
-
-

Gateway Service API

-

API gateway, routing, and rate limiting.

-

Base Path: /api/v1/gateway

-

Get Route Configuration

-

Retrieve current routing configuration.

-

Endpoint: GET /routes

-

Response:

-
{
-  "status": "success",
-  "data": {
-    "routes": [
-      {
-        "path": "/api/v1/orchestrator/*",
-        "target": " [http://orchestrator:8080",](http://orchestrator:8080",)
-        "methods": ["GET", "POST", "PUT", "DELETE"],
-        "auth_required": true
-      }
-    ]
-  }
-}
-
-

Update Routes

-

Update gateway routing (hot reload).

-

Endpoint: PUT /routes

-

Request:

-
{
-  "routes": [
-    {
-      "path": "/api/v1/custom/*",
-      "target": " [http://custom-service:9000",](http://custom-service:9000",)
-      "methods": ["GET", "POST"],
-      "auth_required": true
-    }
-  ]
-}
-
-

Response:

-
{
-  "status": "success",
-  "message": "Routes updated successfully"
-}
-
-

Get Rate Limits

-

Retrieve rate limiting configuration.

-

Endpoint: GET /rate-limits

-

Response:

-
{
-  "status": "success",
-  "data": {
-    "global": {
-      "requests_per_minute": 100,
-      "burst": 20
-    },
-    "per_user": {
-      "requests_per_minute": 60,
-      "burst": 10
-    }
-  }
-}
-
-

Error Codes

-

Common error codes returned by the API:

-
- - - - - - - - - - - -
CodeDescription
ERR_AUTH_INVALIDInvalid authentication credentials
ERR_AUTH_EXPIREDToken expired
ERR_AUTH_MFA_REQUIREDMFA verification required
ERR_FORBIDDENInsufficient permissions
ERR_NOT_FOUNDResource not found
ERR_CONFLICTResource conflict
ERR_VALIDATIONInvalid request parameters
ERR_RATE_LIMITRate limit exceeded
ERR_WORKFLOW_FAILEDWorkflow execution failed
ERR_SERVICE_UNAVAILABLEService temporarily unavailable
ERR_INTERNALInternal server error
-
-

Rate Limiting Headers

-

All responses include rate limiting headers:

-
X-RateLimit-Limit: 100
-X-RateLimit-Remaining: 95
-X-RateLimit-Reset: 1642334400
-X-RateLimit-Retry-After: 60
-
-

Pagination

-

List endpoints support pagination using offset-based pagination:

-

Request:

-
GET /api/v1/workflows?limit=50&offset=100
-
-

Response includes:

-
{
-  "data": { ... },
-  "total": 500,
-  "limit": 50,
-  "offset": 100,
-  "has_more": true
-}
-
-

Webhooks

-

Platform supports webhook notifications for async operations:

-

Webhook Payload:

-
{
-  "event": "workflow.completed",
-  "timestamp": "2026-01-16T10:30:00Z",
-  "data": {
-    "workflow_id": "wf-20260116-abc123",
-    "state": "completed"
-  },
-  "signature": "sha256=abc123..."
-}
-
-

Configure webhooks via Control Center API.

- - -

CLI Commands Reference

-

Complete command-line interface documentation for the Provisioning platform covering 111+ commands across 11 domain modules.

-

Command Structure

-

All commands follow the pattern:

-
provisioning <domain> <action> [resource] [flags]
-
-

Common Flags (available on most commands):

-
    -
  • --yes - Skip confirmation prompts (auto-yes)
  • -
  • --check - Dry-run mode, show what would happen without executing
  • -
  • --wait - Wait for async operations to complete
  • -
  • --format <jso| n yam| l table> - Output format (default: table)
  • -
  • --verbose - Detailed output with debug information
  • -
  • --quiet - Minimal output, errors only
  • -
  • --help - Show command help
  • -
-

Quick Reference

-

Shortcuts - Single-letter aliases for common domains:

-
provisioning s = provisioning server
-provisioning t = provisioning taskserv
-provisioning c = provisioning cluster
-provisioning w = provisioning workspace
-provisioning cfg = provisioning config
-provisioning b = provisioning batch
-
-

Help Navigation - Bi-directional help system:

-
provisioning help server = provisioning server help
-provisioning help ws = provisioning workspace help
-
-

Domain Modules

-

The CLI is organized into 11 domain modules:

-
    -
  1. Infrastructure - Server, provider, network management
  2. -
  3. Orchestration - Workflow, batch, task execution
  4. -
  5. Configuration - Config validation and management
  6. -
  7. Workspace - Multi-workspace operations
  8. -
  9. Development - Extensions and customization
  10. -
  11. Utilities - Tools and helpers
  12. -
  13. Generation - Schema and config generation
  14. -
  15. Authentication - Auth, MFA, users
  16. -
  17. Security - Vault, KMS, audit, policies
  18. -
  19. Platform - Service control and monitoring
  20. -
  21. Guides - Interactive documentation
  22. -
-

Infrastructure Commands

-

Manage cloud infrastructure, servers, and resources.

-

Server Commands

-

provisioning server create [NAME]

-

Create a new server or servers from infrastructure configuration.

-

Flags:

-
    -
  • --infra <file> - Nickel infrastructure file
  • -
  • --plan <size> - Server plan (small/medium/large/xlarge)
  • -
  • --provider <name> - Cloud provider (upcloud/aws/local)
  • -
  • --zone <name> - Availability zone
  • -
  • --ssh-key <path> - SSH public key path
  • -
  • --tags <key=value> - Server tags (repeatable)
  • -
  • --yes - Skip confirmation
  • -
  • --check - Dry-run mode
  • -
  • --wait - Wait for server creation
  • -
-

Examples:

-
# Create server from infrastructure file
-provisioning server create --infra my-cluster.ncl --yes --wait
-
-# Create single server interactively
-provisioning server create web-01 --plan medium --provider upcloud
-
-# Check what would be created (dry-run)
-provisioning server create --infra cluster.ncl --check
-
-

provisioning server delete [NAM| E ID]

-

Delete servers.

-

Flags:

-
    -
  • --all - Delete all servers in current infrastructure
  • -
  • --force - Force deletion without cleanup
  • -
  • --yes - Skip confirmation
  • -
-

Examples:

-
# Delete specific server
-provisioning server delete web-01 --yes
-
-# Delete all servers
-provisioning server delete --all --yes
-
-

provisioning server list

-

List all servers in the current workspace.

-

Flags:

-
    -
  • --provider <name> - Filter by provider
  • -
  • --state <state> - Filter by state (running/stopped/error)
  • -
  • --format <format> - Output format
  • -
-

Examples:

-
# List all servers
-provisioning server list
-
-# List only running servers
-provisioning server list --state running --format json
-
-

provisioning server status [NAM| E ID]

-

Get detailed server status.

-

Examples:

-
provisioning server status web-01
-provisioning server status --all
-
-

provisioning server ssh [NAM| E ID]

-

SSH into a server.

-

Examples:

-
provisioning server ssh web-01
-provisioning server ssh web-01 -- "systemctl status kubelet"
-
-

Provider Commands

-

provisioning provider list

-

List available cloud providers.

-

provisioning provider validate <NAME>

-

Validate provider configuration and credentials.

-

Examples:

-
provisioning provider validate upcloud
-provisioning provider validate aws
-
-

provisioning provider zones <NAME>

-

List available zones for a provider.

-

Examples:

-
provisioning provider zones upcloud
-provisioning provider zones aws --region us-east-1
-
-

Orchestration Commands

-

Execute workflows, batch operations, and manage tasks.

-

Workflow Commands

-

provisioning workflow submit <FILE>

-

Submit a workflow for execution.

-

Flags:

-
    -
  • --priority <level> - Priority (low/normal/high/critical)
  • -
  • --checkpoint - Enable checkpoint recovery
  • -
  • --wait - Wait for completion
  • -
-

Examples:

-
# Submit workflow and wait
-provisioning workflow submit deploy.ncl --wait
-
-# Submit with high priority
-provisioning workflow submit urgent.ncl --priority high
-
-

provisioning workflow status <ID>

-

Get workflow execution status.

-

Examples:

-
provisioning workflow status wf-20260116-abc123
-
-

provisioning workflow list

-

List workflows.

-

Flags:

-
    -
  • --state <state> - Filter by state (queued/running/completed/failed)
  • -
  • --limit <num> - Maximum results
  • -
-

Examples:

-
# List running workflows
-provisioning workflow list --state running
-
-# List failed workflows
-provisioning workflow list --state failed --format json
-
-

provisioning workflow cancel <ID>

-

Cancel a running workflow.

-

Examples:

-
provisioning workflow cancel wf-20260116-abc123 --yes
-
-

provisioning workflow resume <ID>

-

Resume a failed workflow from checkpoint.

-

Flags:

-
    -
  • --from <checkpoint> - Resume from specific checkpoint
  • -
  • --skip-failed - Skip failed tasks
  • -
-

Examples:

-
# Resume from last checkpoint
-provisioning workflow resume wf-20260116-abc123
-
-# Resume from specific checkpoint
-provisioning workflow resume wf-20260116-abc123 --from create-servers
-
-

provisioning workflow logs <ID>

-

View workflow logs.

-

Flags:

-
    -
  • --task <id> - Show logs for specific task
  • -
  • --follow - Stream logs in real-time
  • -
  • --lines <num> - Number of lines (default: 100)
  • -
-

Examples:

-
# View all workflow logs
-provisioning workflow logs wf-20260116-abc123
-
-# Follow logs in real-time
-provisioning workflow logs wf-20260116-abc123 --follow
-
-# View specific task logs
-provisioning workflow logs wf-20260116-abc123 --task install-k8s
-
-

Batch Commands

-

provisioning batch submit <FILE>

-

Submit a batch workflow with multiple operations.

-

Flags:

-
    -
  • --parallel <num> - Maximum parallel operations
  • -
  • --wait - Wait for completion
  • -
-

Examples:

-
# Submit batch workflow
-provisioning batch submit multi-region.ncl --parallel 3 --wait
-
-

provisioning batch status <ID>

-

Get batch workflow status with progress.

-

provisioning batch monitor <ID>

-

Monitor batch execution in real-time.

-

Configuration Commands

-

Validate and manage configuration.

-

provisioning config validate

-

Validate current configuration.

-

Flags:

-
    -
  • --infra <file> - Specific infrastructure file
  • -
  • --all - Validate all configuration files
  • -
-

Examples:

-
# Validate workspace configuration
-provisioning config validate
-
-# Validate specific infrastructure
-provisioning config validate --infra cluster.ncl
-
-

provisioning config show

-

Display effective configuration.

-

Flags:

-
    -
  • --key <path> - Show specific config value
  • -
  • --format <format> - Output format
  • -
-

Examples:

-
# Show all configuration
-provisioning config show
-
-# Show specific value
-provisioning config show --key paths.base
-
-# Export as JSON
-provisioning config show --format json > config.json
-
-

provisioning config reload

-

Reload configuration from files.

-

provisioning config diff

-

Show configuration differences between environments.

-

Flags:

-
    -
  • --from <env> - Source environment
  • -
  • --to <env> - Target environment
  • -
-

Workspace Commands

-

Manage isolated workspaces.

-

provisioning workspace init <NAME>

-

Initialize a new workspace.

-

Flags:

-
    -
  • --template <name> - Workspace template
  • -
  • --path <path> - Custom workspace path
  • -
-

Examples:

-
# Create workspace from default template
-provisioning workspace init my-project
-
-# Create from template
-provisioning workspace init prod --template production
-
-

provisioning workspace switch <NAME>

-

Switch to a different workspace.

-

Examples:

-
provisioning workspace switch production
-provisioning workspace switch dev
-
-

provisioning workspace list

-

List all workspaces.

-

Flags:

-
    -
  • --format <format> - Output format
  • -
-

Examples:

-
provisioning workspace list
-provisioning workspace list --format json
-
-

provisioning workspace current

-

Show current active workspace.

-

provisioning workspace delete <NAME>

-

Delete a workspace.

-

Flags:

-
    -
  • --force - Force deletion without cleanup
  • -
  • --yes - Skip confirmation
  • -
-

Development Commands

-

Develop custom extensions.

-

provisioning extension create <TYPE> <NAME>

-

Create a new extension.

-

Types: provider, taskserv, cluster, workflow

-

Flags:

-
    -
  • --template <name> - Extension template
  • -
-

Examples:

-
# Create new task service
-provisioning extension create taskserv my-service
-
-# Create new provider
-provisioning extension create provider my-cloud --template basic
-
-

provisioning extension validate <PATH>

-

Validate extension structure and configuration.

-

provisioning extension package <PATH>

-

Package extension for distribution (OCI format).

-

Flags:

-
    -
  • --version <version> - Extension version
  • -
  • --output <path> - Output file path
  • -
-

Examples:

-
provisioning extension package ./my-service --version 1.0.0
-
-

provisioning extension install <NAM| E PATH>

-

Install an extension from registry or file.

-

Examples:

-
# Install from registry
-provisioning extension install kubernetes
-
-# Install from local file
-provisioning extension install ./my-service.tar.gz
-
-

provisioning extension list

-

List installed extensions.

-

Flags:

-
    -
  • --type <type> - Filter by type
  • -
  • --available - Show available (not installed)
  • -
-

Utility Commands

-

Helper commands and tools.

-

provisioning version

-

Show platform version information.

-

Flags:

-
    -
  • --check - Check for updates
  • -
-

Examples:

-
provisioning version
-provisioning version --check
-
-

provisioning health

-

Check platform health.

-

Flags:

-
    -
  • --service <name> - Check specific service
  • -
-

Examples:

-
# Check all services
-provisioning health
-
-# Check specific service
-provisioning health --service orchestrator
-
-

provisioning diagnostics

-

Run platform diagnostics.

-

Flags:

-
    -
  • --output <path> - Save diagnostic report
  • -
-

Examples:

-
provisioning diagnostics --output diagnostics.json
-
-

provisioning setup versions

-

Generate versions file from Nickel schemas.

-

Examples:

-
# Generate /provisioning/core/versions file
-provisioning setup versions
-
-# Use in shell scripts
-source /provisioning/core/versions
-echo "Nushell version: $NU_VERSION"
-
-

Generation Commands

-

Generate schemas, configurations, and infrastructure code.

-

provisioning generate config <TYPE>

-

Generate configuration templates.

-

Types: workspace, infrastructure, provider

-

Flags:

-
    -
  • --output <path> - Output file path
  • -
  • --format <format> - Output format (nickel/yaml/toml)
  • -
-

Examples:

-
# Generate workspace config
-provisioning generate config workspace --output config.ncl
-
-# Generate infrastructure template
-provisioning generate config infrastructure --format nickel
-
-

provisioning generate schema <NAME>

-

Generate Nickel schema from existing configuration.

-

provisioning generate docs

-

Generate documentation from schemas.

-

Authentication Commands

-

Manage authentication and user accounts.

-

provisioning auth login

-

Authenticate to the platform.

-

Flags:

-
    -
  • --user <username> - Username
  • -
  • --password <password> - Password (prompt if not provided)
  • -
  • --mfa <code> - MFA code
  • -
-

Examples:

-
# Interactive login
-provisioning auth login --user admin
-
-# Login with MFA
-provisioning auth login --user admin --mfa 123456
-
-

provisioning auth logout

-

Logout and invalidate tokens.

-

provisioning auth token

-

Display or refresh authentication token.

-

Flags:

-
    -
  • --refresh - Refresh the token
  • -
-

provisioning auth user create <USERNAME>

-

Create a new user (admin only).

-

Flags:

-
    -
  • --email <email> - User email
  • -
  • --roles <roles> - Comma-separated roles
  • -
-

Examples:

-
provisioning auth user create developer --email [dev@example.com](mailto:dev@example.com) --roles developer,operator
-
-

provisioning auth user list

-

List all users (admin only).

-

provisioning auth user delete <USERNAME>

-

Delete a user (admin only).

-

Security Commands

-

Manage secrets, encryption, audit logs, and policies.

-

Vault Commands

-

provisioning vault store <PATH>

-

Store a secret.

-

Flags:

-
    -
  • --value <value> - Secret value
  • -
  • --file <path> - Read value from file
  • -
-

Examples:

-
# Store secret interactively
-provisioning vault store database/postgres/password
-
-# Store from value
-provisioning vault store api/key --value "secret-value"
-
-# Store from file
-provisioning vault store ssh/key --file ~/.ssh/id_rsa
-
-

provisioning vault get <PATH>

-

Retrieve a secret.

-

Flags:

-
    -
  • --version <num> - Specific version
  • -
  • --output <path> - Save to file
  • -
-

Examples:

-
# Get latest secret
-provisioning vault get database/postgres/password
-
-# Get specific version
-provisioning vault get database/postgres/password --version 2
-
-

provisioning vault list

-

List all secret paths.

-

Flags:

-
    -
  • --prefix <prefix> - Filter by path prefix
  • -
-

provisioning vault delete <PATH>

-

Delete a secret.

-

KMS Commands

-

provisioning kms encrypt <FILE>

-

Encrypt a file or data.

-

Flags:

-
    -
  • --key <id> - Key ID
  • -
  • --output <path> - Output file
  • -
-

Examples:

-
# Encrypt file
-provisioning kms encrypt config.yaml --key master-key --output config.enc
-
-# Encrypt string
-echo "sensitive data" | provisioning kms encrypt --key master-key
-
-

provisioning kms decrypt <FILE>

-

Decrypt encrypted data.

-

Flags:

-
    -
  • --output <path> - Output file
  • -
-

provisioning kms create-key <ID>

-

Create a new encryption key.

-

Flags:

-
    -
  • --algorithm <algo> - Algorithm (default: AES-256-GCM)
  • -
-

provisioning kms list-keys

-

List all encryption keys.

-

provisioning kms rotate-key <ID>

-

Rotate an encryption key.

-

Audit Commands

-

provisioning audit query

-

Query audit logs.

-

Flags:

-
    -
  • --user <user> - Filter by user
  • -
  • --action <action> - Filter by action
  • -
  • --resource <resource> - Filter by resource
  • -
  • --start <time> - Start time
  • -
  • --end <time> - End time
  • -
  • --limit <num> - Maximum results
  • -
-

Examples:

-
# Query recent audit logs
-provisioning audit query --limit 100
-
-# Query specific user actions
-provisioning audit query --user admin --action workflow.submit
-
-# Query time range
-provisioning audit query --start "2026-01-15" --end "2026-01-16"
-
-

provisioning audit export

-

Export audit logs.

-

Flags:

-
    -
  • --format <format> - Export format (json/csv/syslog/cef/splunk)
  • -
  • --start <time> - Start time
  • -
  • --end <time> - End time
  • -
  • --output <path> - Output file
  • -
-

Examples:

-
# Export as JSON
-provisioning audit export --format json --output audit.json
-
-# Export last 7 days as CSV
-provisioning audit export --format csv --start "7 days ago" --output audit.csv
-
-

provisioning audit compliance

-

Generate compliance report.

-

Flags:

-
    -
  • --standard <standard> - Compliance standard (gdpr/soc2/iso27001)
  • -
  • --start <time> - Report start time
  • -
  • --end <time> - Report end time
  • -
-

Policy Commands

-

provisioning policy create <ID>

-

Create an authorization policy.

-

Flags:

-
    -
  • --content <cedar> - Cedar policy content
  • -
  • --file <path> - Load from file
  • -
  • --description <text> - Policy description
  • -
-

Examples:

-
# Create from file
-provisioning policy create developer-read --file policies/read-only.cedar
-
-# Create inline
-provisioning policy create admin-full --content "permit(principal in Role::\"admin\", action, resource);"
-
-

provisioning policy list

-

List all authorization policies.

-

provisioning policy evaluate

-

Evaluate a policy decision.

-

Flags:

-
    -
  • --principal <entity> - Principal entity
  • -
  • --action <action> - Action
  • -
  • --resource <resource> - Resource
  • -
-

Examples:

-
provisioning policy evaluate \
-  --principal "User::\"admin\"" \
-  --action "Action::\"workflow.submit\"" \
-  --resource "Workflow::\"deploy\""
-
-

provisioning policy update <ID>

-

Update an existing policy (hot reload).

-

provisioning policy delete <ID>

-

Delete an authorization policy.

-

Platform Commands

-

Control platform services.

-

provisioning platform service list

-

List all platform services and status.

-

provisioning platform service start <NAME>

-

Start a platform service.

-

Examples:

-
provisioning platform service start orchestrator
-
-

provisioning platform service stop <NAME>

-

Stop a platform service.

-

Flags:

-
    -
  • --force - Force stop without graceful shutdown
  • -
  • --timeout <seconds> - Graceful shutdown timeout
  • -
-

provisioning platform service restart <NAME>

-

Restart a platform service.

-

provisioning platform service health <NAME>

-

Check service health.

-

provisioning platform metrics

-

Display platform-wide metrics.

-

Flags:

-
    -
  • --watch - Continuously update metrics
  • -
-

Guides Commands

-

Access interactive guides and documentation.

-

provisioning guide from-scratch

-

Complete walkthrough from installation to first deployment.

-

provisioning guide update

-

Guide for updating the platform.

-

provisioning guide customize

-

Guide for customizing extensions.

-

provisioning sc

-

Quick reference shortcut guide (fastest).

-

provisioning help [COMMAND]

-

Display help for any command.

-

Examples:

-
# General help
-provisioning help
-
-# Command-specific help
-provisioning help server create
-provisioning server create --help  # Same result
-
-

Task Service Commands

-

provisioning taskserv install <NAME>

-

Install a task service on servers.

-

Flags:

-
    -
  • --cluster <name> - Target cluster
  • -
  • --version <version> - Specific version
  • -
  • --servers <names> - Target servers (comma-separated)
  • -
  • --wait - Wait for installation
  • -
  • --yes - Skip confirmation
  • -
-

Examples:

-
# Install Kubernetes on cluster
-provisioning taskserv install kubernetes --cluster prod --wait
-
-# Install specific version
-provisioning taskserv install kubernetes --version 1.29.0
-
-# Install on specific servers
-provisioning taskserv install containerd --servers web-01,web-02
-
-

provisioning taskserv remove <NAME>

-

Remove a task service.

-

Flags:

-
    -
  • --cluster <name> - Target cluster
  • -
  • --purge - Remove all data
  • -
  • --yes - Skip confirmation
  • -
-

provisioning taskserv list

-

List installed task services.

-

Flags:

-
    -
  • --available - Show available (not installed) services
  • -
-

provisioning taskserv status <NAME>

-

Get task service status.

-

Examples:

-
provisioning taskserv status kubernetes
-
-

Cluster Commands

-

provisioning cluster create <NAME>

-

Create a complete cluster from configuration.

-

Flags:

-
    -
  • --infra <file> - Nickel infrastructure file
  • -
  • --type <type> - Cluster type (kubernetes/etcd/postgres)
  • -
  • --wait - Wait for creation
  • -
  • --yes - Skip confirmation
  • -
  • --check - Dry-run mode
  • -
-

Examples:

-
# Create Kubernetes cluster
-provisioning cluster create prod-k8s --infra k8s-cluster.ncl --wait
-
-# Check what would be created
-provisioning cluster create staging --infra staging.ncl --check
-
-

provisioning cluster delete <NAME>

-

Delete a cluster and all resources.

-

Flags:

-
    -
  • --keep-data - Preserve data volumes
  • -
  • --yes - Skip confirmation
  • -
-

provisioning cluster list

-

List all clusters.

-

provisioning cluster status <NAME>

-

Get detailed cluster status.

-

Examples:

-
provisioning cluster status prod-k8s
-
-

provisioning cluster scale <NAME>

-

Scale cluster nodes.

-

Flags:

-
    -
  • --workers <num> - Number of worker nodes
  • -
  • --control-plane <num> - Number of control plane nodes
  • -
-

Examples:

-
# Scale workers to 5 nodes
-provisioning cluster scale prod-k8s --workers 5
-
-

Test Commands

-

provisioning test quick <TASKSERV>

-

Quick test of a task service in container.

-

Examples:

-
provisioning test quick kubernetes
-provisioning test quick postgres
-
-

provisioning test topology load <NAME>

-

Load a test topology template.

-

provisioning test env create

-

Create a test environment.

-

Flags:

-
    -
  • --topology <name> - Topology template
  • -
  • --services <names> - Services to install
  • -
-

provisioning test env list

-

List active test environments.

-

provisioning test env cleanup <ID>

-

Cleanup a test environment.

-

Environment Variables

-

The CLI respects these environment variables:

-
    -
  • PROVISIONING_WORKSPACE - Override active workspace
  • -
  • PROVISIONING_CONFIG - Custom config file path
  • -
  • PROVISIONING_LOG_LEVEL - Log level (debug/info/warn/error)
  • -
  • PROVISIONING_API_URL - API endpoint URL
  • -
  • PROVISIONING_TOKEN - Auth token (overrides login)
  • -
-

Exit Codes

-
- - - - - - - - - -
CodeMeaning
0Success
1General error
2Invalid usage
3Configuration error
4Authentication error
5Permission denied
6Resource not found
7Operation failed
8Timeout
-
-

Shell Completion

-

Generate shell completion scripts:

-
# Bash
-provisioning completion bash > /etc/bash_completion.d/provisioning
-
-# Zsh
-provisioning completion zsh > ~/.zsh/completion/_provisioning
-
-# Fish
-provisioning completion fish > ~/.config/fish/completions/provisioning.fish
-
- - -

Nushell Libraries

-

Orchestrator API

-

Control Center API

-

Examples

-

- Provisioning Logo -

-

- Provisioning -

-

Architecture

-

Deep dive into Provisioning platform architecture, design principles, and -architectural decisions that shape the system.

-

Overview

-

The Provisioning platform uses modular, microservice-based architecture for -enterprise infrastructure as code across multiple clouds. This section -documents foundational architectural decisions and system design that enable:

-
    -
  • Multi-cloud orchestration across AWS, UpCloud, Hetzner, Kubernetes, and on-premise systems
  • -
  • Workspace-first organization with complete infrastructure isolation and multi-tenancy support
  • -
  • Type-safe configuration using Nickel language as source of truth
  • -
  • Autonomous operations through intelligent detectors and automated incident response
  • -
  • Post-quantum security with hybrid encryption protecting against future threats
  • -
-

Architecture Documentation

-

System Understanding

-

- System Architecture Overview with 12 Microservices -

-
    -
  • -

    System Overview - Platform architecture with 12 -microservices, 80+ CLI commands, multi-tenancy model, cloud integration

    -
  • -
  • -

    Design Principles - Configuration-driven design, -workspace isolation, type-safety mandates, autonomous operations, security-first

    -
  • -
  • -

    Component Architecture - 12 microservices: -Orchestrator, Control-Center, Vault-Service, Extension-Registry, AI-Service, -Detector, RAG, MCP-Server, KMS, Platform-Config, Service-Clients

    -
  • -
  • -

    Integration Patterns - REST APIs, async -message queues, event-driven workflows, service discovery, state management

    -
  • -
-

- Microservices Communication Patterns REST Async Events -

-

Architectural Decisions

-
    -
  • Architecture Decision Records (ADRs) - 10 decisions: -modular CLI, workspace-first design, Nickel type-safety, microservice -distribution, communication, post-quantum cryptography, encryption, -observability, SLO management, incident automation
  • -
-

Key Architectural Patterns

-

Modular Design (ADR-001)

-
    -
  • Decentralized CLI command registration reducing code by 84%
  • -
  • Dynamic command discovery and 80+ keyboard shortcuts
  • -
  • Extensible architecture supporting custom commands
  • -
-

Workspace-First Organization (ADR-002)

-
    -
  • Workspaces as primary organizational unit grouping infrastructure, configs, and state
  • -
  • Complete isolation for multi-tenancy and team collaboration
  • -
  • Local schema and extension customization per workspace
  • -
-

Type-Safe Configuration (ADR-003)

-
    -
  • Nickel language as source of truth for all infrastructure definitions
  • -
  • Mandatory schema validation at parse time (not runtime)
  • -
  • Complete migration from KCL with backward compatibility
  • -
-

Distributed Microservices (ADR-004)

-
    -
  • 12 specialized microservices handling specific domains
  • -
  • Independent scaling and deployment per service
  • -
  • Service communication via REST + async queues
  • -
-

Security Architecture (ADR-006 & ADR-007)

-
    -
  • Post-quantum cryptography with CRYSTALS-Kyber hybrid encryption
  • -
  • Multi-layer encryption: at-rest (KMS), in-transit (TLS 1.3), field-level, end-to-end
  • -
  • Centralized secrets management via SecretumVault
  • -
-

Observability & Resilience (ADR-008, ADR-009, ADR-010)

-
    -
  • Unified observability: Prometheus metrics, ELK logging, Jaeger tracing
  • -
  • SLO-driven operations with error budget enforcement
  • -
  • Autonomous incident detection and self-healing
  • -
- -
    -
  • For implementation details → See provisioning/docs/src/features/
  • -
  • For API documentation → See provisioning/docs/src/api-reference/
  • -
  • For deployment guides → See provisioning/docs/src/operations/
  • -
  • For security details → See provisioning/docs/src/security/
  • -
  • For development → See provisioning/docs/src/development/
  • -
-

System Overview

-

Complete architecture of the Provisioning Infrastructure Automation Platform.

-

Architecture Layers

-

Provisioning uses a 5-layer modular architecture:

-
┌─────────────────────────────────────────────────────────────┐
-│ User Interface Layer                                        │
-│ • CLI (provisioning command)  • Web Control Center (UI)     │
-│ • REST API  • MCP Server (AI) • Batch Scheduler             │
-└──────────────────────────┬──────────────────────────────────┘
-                           ↓
-┌─────────────────────────────────────────────────────────────┐
-│ Core Engine Layer (provisioning/core/)                      │
-│ • 211-line CLI dispatcher (84% code reduction)              │
-│ • 476+ configuration accessors (hierarchical)               │
-│ • Provider abstraction (multi-cloud support)                │
-│ • Workspace management system                               │
-│ • Infrastructure validation (54+ Nushell libraries)         │
-│ • Secrets management (SOPS + Age integration)               │
-└──────────────────────────┬──────────────────────────────────┘
-                           ↓
-┌─────────────────────────────────────────────────────────────┐
-│ Orchestration Layer (provisioning/platform/)                │
-│ • Hybrid Orchestrator (Rust + Nushell)                      │
-│ • Workflow execution with checkpoints                       │
-│ • Dependency resolver & task scheduler                      │
-│ • File-based persistence                                    │
-│ • REST API endpoints (83+)                                  │
-│ • State management (SurrealDB)                              │
-└──────────────────────────┬──────────────────────────────────┘
-                           ↓
-┌─────────────────────────────────────────────────────────────┐
-│ Extension Layer (provisioning/extensions/)                  │
-│ • Cloud Providers (UpCloud, AWS, Hetzner, Local)            │
-│ • Task Services (50+ services in 18 categories)             │
-│ • Clusters (9 pre-built cluster templates)                  │
-│ • Batch Workflows (automation templates)                    │
-│ • Nushell Plugins (10-50x performance gains)                │
-└──────────────────────────┬──────────────────────────────────┘
-                           ↓
-┌─────────────────────────────────────────────────────────────┐
-│ Infrastructure Layer                                        │
-│ • Cloud Resources (servers, networks, storage)              │
-│ • Running Services (Kubernetes, databases, etc.)            │
-│ • State Persistence (SurrealDB, file storage)               │
-│ • Monitoring & Logging (Prometheus, Loki)                   │
-└─────────────────────────────────────────────────────────────┘
-
-

Core System Components

-

1. CLI Layer (provisioning/core/cli/)

-

Entry Point: provisioning/core/cli/provisioning

-
    -
  • Bash wrapper (210 lines) - Minimal bootstrap
  • -
  • Routes commands to Nushell dispatcher
  • -
  • Loads environment and validates workspace
  • -
  • Handles error reporting
  • -
-

Key Features:

-
    -
  • Single entry point
  • -
  • Pluggable architecture
  • -
  • Support for 111+ commands
  • -
  • 80+ shortcuts for productivity
  • -
-

2. Core Engine (provisioning/core/nulib/)

-

Structure: 54 Nushell libraries organized by function

-

Main Components:

-

Configuration Management (lib_provisioning/config/)

-
    -
  • Hierarchical loading: 5-layer precedence system
  • -
  • 476+ accessors: Type-safe configuration access
  • -
  • Variable interpolation: Template expansion
  • -
  • TOML merging: Environment-specific overrides
  • -
  • Validation: Schema enforcement
  • -
-

Provider Abstraction (lib_provisioning/providers/)

-
    -
  • Multi-cloud support: UpCloud, AWS, Hetzner, Local
  • -
  • Unified interface: Single API for all providers
  • -
  • Dynamic loading: Load providers on-demand
  • -
  • Credential management: Encrypted credential handling
  • -
  • State tracking: Provider-specific state persistence
  • -
-

Workspace Management (lib_provisioning/workspace/)

-
    -
  • Workspace registry: Track all workspaces
  • -
  • Switching: Atomic workspace transitions
  • -
  • Isolation: Independent state per workspace
  • -
  • Configuration loading: Workspace-specific overrides
  • -
  • Extensions: Inherit from platform extensions
  • -
-

Infrastructure Validation (lib_provisioning/infra_validator/)

-
    -
  • Schema validation: Nickel contract checking
  • -
  • Constraint enforcement: Business rule validation
  • -
  • Dependency analysis: Infrastructure dependency graph
  • -
  • Type checking: Static type validation
  • -
  • Error reporting: Detailed error messages with suggestions
  • -
-

Secrets Management (lib_provisioning/secrets/)

-
    -
  • SOPS integration: Mozilla SOPS for encryption
  • -
  • Age encryption: Modern symmetric encryption
  • -
  • KMS backends: Cosmian, AWS KMS, local
  • -
  • Credential injection: Runtime variable substitution
  • -
  • Audit logging: Track secret access
  • -
-

Command Utilities (lib_provisioning/cmd/)

-
    -
  • SSH operations: Remote command execution
  • -
  • Batch operations: Parallel command execution
  • -
  • Error handling: Structured error reporting
  • -
  • Logging: Comprehensive operation logging
  • -
  • Retry logic: Automatic retry with backoff
  • -
-

3. Orchestration Engine (provisioning/platform/)

-

Technology: Rust + Nushell hybrid

-

12 Microservices (Rust crates):

-
- - - - - - - - - - - - -
ServicePurposeKey Features
orchestratorWorkflow executionScheduler, file persistence, REST API
control-centerAPI gateway + authRBAC, Cedar policies, audit logging
control-center-uiWeb dashboardInfrastructure view, config management
mcp-serverAI integrationModel Context Protocol, auto-completion
vault-serviceSecrets storageEncryption, KMS, credential injection
extension-registryOCI registryExtension distribution, versioning
ai-serviceLLM featuresPrompt optimization, context awareness
detectorAnomaly detectionHealth monitoring, pattern recognition
ragKnowledge retrievalDocument embedding, semantic search
provisioning-daemonBackground serviceEvent monitoring, task scheduling
platform-configConfig managementSchema validation, environment handling
service-clientsAPI clientsSDK for platform services, cloud APIs
-
-

Detailed Services:

-

Orchestrator (crates/orchestrator/)

-
    -
  • High-performance scheduler: Rust core
  • -
  • File-based persistence: Durable queue
  • -
  • Workflow execution: Dependency-aware scheduling
  • -
  • Checkpoint recovery: Resume from failures
  • -
  • Parallel execution: Multi-task handling
  • -
  • State management: Track job status
  • -
  • REST API: 9 core endpoints
  • -
  • Port: 9090 (health check endpoint)
  • -
-

Control Center (crates/control-center/)

-
    -
  • Authorization engine: Cedar policy enforcement
  • -
  • RBAC system: Role-based access control
  • -
  • Audit logging: Complete audit trail
  • -
  • API gateway: REST API for all operations
  • -
  • System configuration: Central configuration management
  • -
  • Health monitoring: Real-time system status
  • -
-

Control Center UI (crates/control-center-ui/)

-
    -
  • Web dashboard: Real-time infrastructure view
  • -
  • Workflow visualization: Batch job monitoring
  • -
  • Configuration management: Web-based configuration
  • -
  • Resource explorer: Browse infrastructure
  • -
  • Audit viewer: Security audit trail
  • -
-

MCP Server (crates/mcp-server/)

-
    -
  • AI integration: Model Context Protocol support
  • -
  • Natural language: Parse infrastructure requests
  • -
  • Auto-completion: Intelligent configuration suggestions
  • -
  • 7 settings tools: Configuration management via LLM
  • -
  • Context-aware: Understand workspace context
  • -
-

Vault Service (crates/vault-service/)

-
    -
  • Secrets backend: Encrypted credential storage
  • -
  • KMS integration: Key Management System support
  • -
  • SOPS + Age: SOPS encryption backend
  • -
  • Credential injection: Secure credential delivery
  • -
  • Audit logging: Secret access tracking
  • -
-

Extension Registry (crates/extension-registry/)

-
    -
  • OCI distribution: Container image distribution
  • -
  • Extension packaging: Provider/taskserv distribution
  • -
  • Version management: Semantic versioning
  • -
  • Registry API: Content addressable storage
  • -
-

AI Service (crates/ai-service/)

-
    -
  • LLM integration: Large Language Model support
  • -
  • Prompt optimization: Infrastructure request parsing
  • -
  • Context awareness: Workspace context enrichment
  • -
  • Response generation: Configuration suggestions
  • -
-

Detector (crates/detector/)

-
    -
  • Anomaly detection: System health monitoring
  • -
  • Pattern recognition: Infrastructure issue identification
  • -
  • Alert generation: Alerting system integration
  • -
  • Real-time monitoring: Continuous surveillance
  • -
-

Platform Config (crates/platform-config/)

-
    -
  • Configuration management: Centralized config loading
  • -
  • Schema validation: Configuration validation
  • -
  • Environment handling: Multi-environment support
  • -
  • Default settings: System-wide defaults
  • -
-

Provisioning Daemon (crates/provisioning-daemon/)

-
    -
  • Background service: Continuous operation
  • -
  • Event monitoring: System event handling
  • -
  • Task scheduling: Background job execution
  • -
  • State synchronization: Infrastructure state sync
  • -
-

RAG Service (crates/rag/)

-
    -
  • Retrieval Augmented Generation: Knowledge base integration
  • -
  • Document embedding: Semantic search
  • -
  • Context retrieval: Intelligent response context
  • -
  • Knowledge synthesis: Answer generation
  • -
-

Service Clients (crates/service-clients/)

-
    -
  • API clients: Client SDK for platform services
  • -
  • Cloud providers: Multi-cloud provider SDKs
  • -
  • Request handling: HTTP/RPC client utilities
  • -
  • Connection pooling: Efficient resource management
  • -
-

4. Extensions (provisioning/extensions/)

-

Modular infrastructure components:

-

Providers (5 cloud providers)

-
    -
  • UpCloud - Primary European cloud
  • -
  • AWS - Amazon Web Services
  • -
  • Hetzner - Baremetal & cloud servers
  • -
  • Local - Development environment
  • -
  • Demo - Testing & mocking
  • -
-

Each provider includes:

-
    -
  • Nickel schemas for configuration
  • -
  • API client implementation
  • -
  • Server creation/deletion logic
  • -
  • Network management
  • -
  • State tracking
  • -
-

Task Services (50+ services in 18 categories)

-
- - - - - - - - - -
CategoryServicesPurpose
Container Runtimecontainerd, crio, podman, crun, youki, runcContainer execution
Kuberneteskubernetes, etcd, coredns, cilium, flannel, calicoOrchestration
Storagerook-ceph, local-storage, mayastor, external-nfsData persistence
Databasespostgres, redis, mysql, mongodbData management
Networkingip-aliases, proxy, resolv, kmsNetwork services
Securitywebhook, kms, oras, radicleSecurity services
Observabilityprometheus, grafana, loki, jaegerMonitoring & logging
Developmentgitea, coder, desktop, buildkitDeveloper tools
Hypervisorkvm, qemu, libvirtVirtualization
-
-

Clusters (9 pre-built templates)

-
    -
  • web - Web service cluster (nginx + postgres)
  • -
  • oci-reg - Container registry
  • -
  • git - Git hosting (Gitea)
  • -
  • buildkit - Build infrastructure
  • -
  • k8s-ha - HA Kubernetes (3 control planes)
  • -
  • postgresql - HA PostgreSQL cluster
  • -
  • cicd-argocd - GitOps CI/CD
  • -
  • cicd-tekton - Tekton pipelines
  • -
-

5. Infrastructure Layer

-

What Provisioning Manages:

-
    -
  • Cloud Resources: VMs, networks, storage
  • -
  • Services: Kubernetes, databases, monitoring
  • -
  • Applications: Web services, APIs, tools
  • -
  • State: Configuration, data, logs
  • -
  • Monitoring: Metrics, traces, logs
  • -
-

Configuration System

-

Hierarchical 5-Layer System:

-
Precedence (High → Low):
-
-1. Runtime Arguments   (CLI flags: --provider upcloud)
-   ↓
-2. Environment Variables (PROVISIONING_PROVIDER=aws)
-   ↓
-3. Workspace Config    (~workspace/config/provisioning.yaml)
-   ↓
-4. Environment Defaults (workspace/config/prod-defaults.toml)
-   ↓
-5. System Defaults     (~/.config/provisioning/ + platform defaults)
-
-

Configuration Languages:

-
- - - - -
FormatPurposeValidationEditability
NickelInfrastructure source✅ Type-safe, contractsDirect
TOMLSettings, defaultsSchema validationDirect
YAMLUser config, metadataSchema validationDirect
JSONExported configsSchema validationGenerated
-
-

Key Features:

-
    -
  • Lazy evaluation
  • -
  • Recursive merging
  • -
  • Variable interpolation
  • -
  • Constraint checking
  • -
  • Automatic validation
  • -
-

State Management

-

SurrealDB Graph Database:

-

Stores complex infrastructure relationships:

-
Nodes:
-- Servers (compute)
-- Networks (connectivity)
-- Storage (persistence)
-- Services (software)
-- Workflows (automation)
-
-Edges:
-- Server → Network (connected)
-- Server → Storage (mounted)
-- Service → Server (running on)
-- Workflow → Dependency (depends on)
-
-

File-Based Persistence:

-

For orchestrator queue and checkpoints:

-
~/.provisioning/
-├── state/              # Infrastructure state
-├── checkpoints/        # Workflow checkpoints
-├── queue/              # Orchestrator queue
-└── logs/               # Operational logs
-
-

Security Architecture

-

4-Layer Security Model:

-
- - - - -
LayerComponentsFeatures
AuthenticationJWT, sessions, MFA2FA, TOTP, WebAuthn
AuthorizationCedar policies, RBACFine-grained permissions
EncryptionAES-256-GCM, TLSAt-rest & in-transit
AuditLogging, compliance7-year retention
-
-

Security Services:

-
    -
  • JWT token validation
  • -
  • Argon2id password hashing
  • -
  • Multi-factor authentication
  • -
  • Cedar policy enforcement
  • -
  • Encrypted credential storage
  • -
  • KMS integration (5 backends)
  • -
  • Audit logging (5 export formats)
  • -
  • Compliance checking (SOC2, GDPR, HIPAA)
  • -
-

Performance Characteristics

-

Modular CLI (84% code reduction):

-
    -
  • Main CLI: 211 lines (vs. 1,329 before)
  • -
  • Command discovery: O(1) dispatcher
  • -
  • Lazy loading: Commands loaded on-demand
  • -
  • Caching: Configuration cached after first load
  • -
-

Orchestrator Performance:

-
    -
  • Dependency resolution: O(n log n) topological sort
  • -
  • Parallel execution: Configurable task limit
  • -
  • Checkpoint recovery: Resume from failure point
  • -
  • Memory efficient: File-based queue
  • -
-

Provider Operations:

-
    -
  • Batch creation: Parallel server provisioning
  • -
  • Bulk operations: Multi-resource transactions
  • -
  • State tracking: Efficient state queries
  • -
  • Rollback: Atomic operation reversal
  • -
-

Nushell Plugins (10-50x speedup):

-
    -
  • Compiled Rust extensions
  • -
  • Direct native code execution
  • -
  • Zero-copy data passing
  • -
  • Async I/O support
  • -
-

Deployment Modes

-

Three Operational Modes:

-
- - - -
ModeInteractionConfigurationRollbackUse Case
Interactive TUIRatatui UIManual inputAutomaticDevelopment
Headless CLICommand-lineScript-drivenManualAutomation
Unattended CI/CDNon-interactiveConfiguration fileAutomaticCI/CD pipelines
-
-

Technology Stack

-
- - - - - - - -
ComponentTechnologyWhy
IaC LanguageNickelType-safe, lazy evaluation, contracts
ScriptingNushell 0.109+Structured data pipelines
PerformanceRustZero-cost abstractions, memory safety
StateSurrealDBGraph database for relationships
EncryptionSOPS + AgeIndustry-standard encryption
SecurityCedar + JWTPolicy enforcement + tokens
OrchestrationCustomSpecialized for infrastructure workflows
-
-

File Organization

-
provisioning/
-├── core/                       # CLI engine (Nushell)
-│   ├── cli/provisioning       # Main entry point
-│   ├── nulib/                 # 54 core libraries
-│   ├── plugins/               # Nushell plugins (Rust)
-│   └── scripts/               # Utility scripts
-│
-├── platform/                   # Microservices (Rust)
-│   ├── crates/                # 12 microservices
-│   │   ├── orchestrator/      # Workflow scheduler
-│   │   ├── control-center/    # API gateway + auth
-│   │   ├── control-center-ui/ # Web dashboard
-│   │   ├── mcp-server/        # AI integration
-│   │   ├── vault-service/     # Secrets backend
-│   │   ├── extension-registry/ # OCI registry
-│   │   ├── ai-service/        # LLM features
-│   │   ├── detector/          # Anomaly detection
-│   │   ├── rag/               # Knowledge retrieval
-│   │   ├── provisioning-daemon/ # Background service
-│   │   ├── platform-config/   # Config management
-│   │   └── service-clients/   # API clients
-│   └── Cargo.toml             # Rust workspace
-│
-├── extensions/                # Extensible components
-│   ├── providers/             # Cloud providers (5)
-│   ├── taskservs/             # Task services (50+)
-│   ├── clusters/              # Cluster templates (9)
-│   └── workflows/             # Automation templates
-│
-├── schemas/                   # Nickel schemas
-│   ├── main.ncl              # Entry point
-│   ├── config/               # Configuration schemas
-│   ├── infrastructure/       # Infrastructure schemas
-│   ├── operations/           # Operational schemas
-│   └── [other schemas]       # Additional schemas
-│
-├── config/                    # System configuration
-│   └── config.defaults.toml  # Default settings
-│
-├── bootstrap/                 # Installation
-│   ├── install.sh            # Bash bootstrap
-│   └── install.nu            # Nushell installer
-│
-├── docs/                      # Product documentation
-│   └── src/                  # mdBook source
-│
-└── README.md                  # Project overview
-
-

Component Interaction

-

Typical Workflow:

-
User Input
-   ↓
-CLI Dispatcher (provisioning/core/cli/provisioning)
-   ↓
-Nushell Handler (provisioning/core/nulib/commands/)
-   ↓
-Configuration Loading (lib_provisioning/config/)
-   ↓
-Provider Selection (lib_provisioning/providers/)
-   ↓
-Validation (lib_provisioning/infra_validator/)
-   ↓
-Orchestrator Queue (provisioning/platform/orchestrator/)
-   ↓
-Task Execution (provider + task service)
-   ↓
-State Update (SurrealDB / file storage)
-   ↓
-Audit Logging (security system)
-   ↓
-User Feedback
-
-

Scalability

-

Provisioning scales from:

-
    -
  • Solo: 2 CPU cores, 4GB RAM (single instance)
  • -
  • MultiUser: 4-8 CPU cores, 8GB RAM (small team)
  • -
  • CICD: 8+ CPU cores, 16GB RAM (enterprise)
  • -
  • Enterprise: Multi-node Kubernetes (unlimited)
  • -
-

Bottlenecks & Solutions:

-
- - - - -
ComponentBottleneckSolution
OrchestratorTask queuePartition by workspace
StateSurrealDBHorizontal scaling
ProvidersAPI rate limitsExponential backoff
StorageDisk I/OSSD + caching
-
-

Integration Points

-

Provisioning integrates with:

-
    -
  • Kubernetes API - Cluster management
  • -
  • Cloud Provider APIs - Resource provisioning
  • -
  • SOPS + Age - Secrets encryption
  • -
  • Prometheus - Metrics collection
  • -
  • Cedar - Policy enforcement
  • -
  • SurrealDB - State persistence
  • -
  • MCP - AI integration
  • -
  • KMS - Key management (Cosmian, AWS, local)
  • -
-

Reliability Features

-

Fault Tolerance:

-
    -
  • Checkpoint recovery - Resume from failure
  • -
  • Automatic rollback - Revert failed operations
  • -
  • Retry logic - Exponential backoff
  • -
  • Health checks - Continuous monitoring
  • -
  • Backup & restore - Data protection
  • -
-

High Availability:

-
    -
  • Multi-node orchestrator
  • -
  • Database replication
  • -
  • Service redundancy
  • -
  • Load balancing
  • -
  • Failover automation
  • -
- - -

Design Principles

-

Core principles guiding Provisioning architecture and development.

-

1. Workspace-First Design

-

Principle: Workspaces are the default organizational unit for ALL infrastructure work.

-

Why:

-
    -
  • Explicit project isolation
  • -
  • Prevent accidental cross-project modifications
  • -
  • Independent credential management
  • -
  • Clear configuration boundaries
  • -
  • Team collaboration enablement
  • -
-

Application:

-
    -
  • Every workspace has independent state
  • -
  • Workspace switching is atomic
  • -
  • Configuration per workspace
  • -
  • Extensions inherited from platform
  • -
-

Code Example:

-
# Workspace-enforced workflow
-provisioning workspace init my-project
-provisioning workspace switch my-project
-
-# This command requires active workspace
-provisioning server create --name web-01
-
-

Impact: All commands validate active workspace before execution.

-
-

2. Type-Safety Mandatory

-

Principle: ALL configurations MUST be type-safe. Validation is NEVER optional.

-

Why:

-
    -
  • Catch errors at configuration time
  • -
  • Prevent runtime failures
  • -
  • Enable IDE support (LSP)
  • -
  • Enforce consistency
  • -
  • Reduce deployment risk
  • -
-

Application:

-
    -
  • Nickel is source of truth (NOT TOML)
  • -
  • Type contracts on ALL schemas
  • -
  • Gradual typing not allowed
  • -
  • Validation in ALL profiles (dev, prod, cicd)
  • -
  • Static analysis before deployment
  • -
-

Code Example:

-
# Type-safe infrastructure definition
-{
-  name : String = "server-01"
-  plan : | [ 'small, 'medium, 'large | ] = 'medium
-  zone : String = "de-fra1"
-  backup_enabled : Bool = false
-} | ServerContract
-
-

Impact: Type errors caught before infrastructure changes.

-
-

3. Configuration-Driven, Never Hardcoded

-

Principle: Configuration is the source of truth. Hardcoded values are forbidden.

-

Why:

-
    -
  • Enable environment-specific behavior
  • -
  • Support multiple deployment modes
  • -
  • Allow runtime reconfiguration
  • -
  • Audit configuration changes
  • -
  • Team collaboration
  • -
-

Application:

-
    -
  • 5-layer configuration hierarchy
  • -
  • 476+ configuration accessors
  • -
  • Variable interpolation
  • -
  • Environment-specific overrides
  • -
  • Schema validation
  • -
-

Code Example:

-
# Configuration drives behavior
-provisioning server create --plan $(config.server.default_plan)
-
-# Environment-specific configs
-PROVISIONING_ENV=prod provisioning server create
-
-

Forbidden:

-
# ❌ WRONG - Hardcoded values
-let server_plan = "medium"
-
-# ✅ RIGHT - Configuration-driven
-let server_plan = (config.server.plan)
-
-

Impact: Single codebase supports all environments.

-
-

4. Multi-Cloud Abstraction

-

Principle: Provider-agnostic interfaces enable multi-cloud deployments.

-

Why:

-
    -
  • Avoid vendor lock-in
  • -
  • Reuse infrastructure code
  • -
  • Support multiple cloud strategies
  • -
  • Easy provider switching
  • -
-

Application:

-
    -
  • Unified provider interface
  • -
  • Abstract resource definitions
  • -
  • Provider-specific implementation
  • -
  • Automatic provider selection
  • -
-

Code Example:

-
# Provider-agnostic configuration
-{
-  servers = [
-    {
-      name = "web-01"
-      plan = "medium"      # Abstract plan size
-      provider = "upcloud" # Swappable provider
-    }
-  ]
-}
-
-

Impact: Same Nickel schema deploys to UpCloud, AWS, or Hetzner.

-
-

5. Modular, Extensible Architecture

-

Principle: Components are loosely coupled, independently deployable.

-

Why:

-
    -
  • Easy to add features
  • -
  • Support custom extensions
  • -
  • Avoid monolithic growth
  • -
  • Enable community contributions
  • -
  • Flexible deployment options
  • -
-

Application:

-
    -
  • 54 core Nushell libraries
  • -
  • 111+ CLI commands in 7 domains
  • -
  • 50+ task services
  • -
  • 5 cloud providers
  • -
  • 9 cluster templates
  • -
  • Pluggable provider interface
  • -
-

Impact: Add features without modifying core system.

-
-

6. Hybrid Rust + Nushell

-

Principle: Rust for performance-critical components, Nushell for orchestration.

-

Why:

-
    -
  • Rust: Type safety, zero-cost abstractions, performance
  • -
  • Nushell: Structured data, productivity, easy automation
  • -
  • Hybrid: Best of both worlds
  • -
-

Application:

-
    -
  • Core CLI: Bash wrapper → Nushell dispatcher
  • -
  • Orchestrator: Rust scheduler + Nushell task execution
  • -
  • Libraries: Nushell for business logic
  • -
  • Performance: Rust plugins for 10-50x speedup
  • -
-

Impact: Fast, type-safe, productive infrastructure automation.

-
-

7. State Management via Graph Database

-

Principle: Infrastructure relationships tracked via SurrealDB graph.

-

Why:

-
    -
  • Model complex infrastructure relationships
  • -
  • Query relationships efficiently
  • -
  • Track dependencies
  • -
  • Support rollback via state history
  • -
  • Audit trail
  • -
-

Application:

-
    -
  • SurrealDB for relationship queries
  • -
  • File-based persistence for queue
  • -
  • Event-driven state updates
  • -
  • Checkpoint-based recovery
  • -
-

Example Relationships:

-
Server → Network (connected to)
-Server → Storage (mounts)
-Cluster → Service (runs)
-Workflow → Dependency (depends on)
-
-

Impact: Complex infrastructure relationships handled gracefully.

-
-

8. Security-First Design

-

Principle: Security is built-in, not bolted-on.

-

Why:

-
    -
  • Enterprise compliance
  • -
  • Data protection
  • -
  • Access control
  • -
  • Audit trails
  • -
  • Threat detection
  • -
-

Application:

-
    -
  • 4-layer security model (auth, authz, encryption, audit)
  • -
  • JWT authentication
  • -
  • Cedar policy enforcement
  • -
  • AES-256-GCM encryption
  • -
  • 7-year audit retention
  • -
  • MFA support (TOTP, WebAuthn)
  • -
-

Impact: Enterprise-grade security by default.

-
-

9. Progressive Disclosure

-

Principle: Simple for common cases, powerful for advanced use cases.

-

Why:

-
    -
  • Low barrier to entry
  • -
  • Professional productivity
  • -
  • Advanced features available
  • -
  • Avoid overwhelming users
  • -
  • Gradual learning curve
  • -
-

Application:

-
    -
  • Simple: Interactive TUI installer
  • -
  • Productive: CLI with 80+ shortcuts
  • -
  • Powerful: Batch workflows, policies
  • -
  • Advanced: Custom extensions, hooks
  • -
-

Impact: All skill levels supported.

-
-

10. Fail-Fast, Recover Gracefully

-

Principle: Detect issues early, provide recovery mechanisms.

-

Why:

-
    -
  • Prevent invalid deployments
  • -
  • Enable safe recovery
  • -
  • Minimize blast radius
  • -
  • Audit failures for learning
  • -
-

Application:

-
    -
  • Validation before execution
  • -
  • Checkpoint-based recovery
  • -
  • Automatic rollback on failure
  • -
  • Detailed error messages
  • -
  • Retry with exponential backoff
  • -
-

Code Example:

-
# Validate before deployment
-provisioning validate config --strict
-
-# Dry-run to check impact
-provisioning --check server create
-
-# Safe rollback on failure
-provisioning workflow rollback --to-checkpoint
-
-

Impact: Safe infrastructure changes with confidence.

-
-

11. Observable & Auditable

-

Principle: All operations traceable, all changes auditable.

-

Why:

-
    -
  • Compliance & regulation
  • -
  • Troubleshooting
  • -
  • Security investigation
  • -
  • Team accountability
  • -
  • Historical analysis
  • -
-

Application:

-
    -
  • Comprehensive audit logging
  • -
  • 5 export formats (JSON, YAML, CSV, syslog, CloudWatch)
  • -
  • Structured log entries
  • -
  • Operation tracing
  • -
  • Resource change tracking
  • -
-

Impact: Complete visibility into infrastructure changes.

-
-

12. No Shortcuts on Reliability

-

Principle: Reliability features are standard, not optional.

-

Why:

-
    -
  • Production requirements
  • -
  • Minimize downtime
  • -
  • Data protection
  • -
  • Business continuity
  • -
  • Trust & confidence
  • -
-

Application:

-
    -
  • Checkpoint recovery
  • -
  • Automatic rollback
  • -
  • Health monitoring
  • -
  • Backup & restore
  • -
  • Multi-node deployment
  • -
  • Service redundancy
  • -
-

Impact: Enterprise-grade reliability standard.

-
-

Architectural Decision Records (ADRs)

-

Key decisions documenting rationale:

-
- - - - - - -
ADRDecisionRationale
ADR-011Nickel MigrationType-safety over KCL flexibility
ADR-010Config Strategy5-layer hierarchy over flat config
ADR-009SurrealDBGraph relationships over relational
ADR-008Modular CLI80+ shortcuts over verbose commands
ADR-007Workspace-FirstIsolation over global state
ADR-006Hybrid ArchitectureRust + Nushell for best of both
-
-
-

Design Trade-offs

-
- - - - - - -
DecisionGainCost
Type-SafetyFewer errorsLearning curve
Config HierarchyFlexibilityComplexity
Workspace IsolationSafetyDuplication
Modular CLIDiscoverabilityNo single command
SurrealDBRelationshipsResource overhead
Validation StrictSafetyFast iteration friction
-
-
- - -

Component Architecture

-

Detailed architecture of each major Provisioning component.

-

Core Components Map

-
User Interface
-  ├─ CLI (Nushell dispatcher)
-  ├─ Web Dashboard (Control Center UI)
-  ├─ REST API (Control Center)
-  └─ MCP Server (AI Integration)
-       ↓
-Core Engine (54 Nushell libraries)
-  ├─ Configuration Management
-  ├─ Provider Abstraction
-  ├─ Workspace Management
-  ├─ Infrastructure Validation
-  ├─ Secrets Management
-  └─ Command Utilities
-       ↓
-Platform Services (12 Rust microservices)
-  ├─ Orchestrator (Workflow execution)
-  ├─ Control Center (API + Auth)
-  ├─ Control Center UI (Web dashboard)
-  ├─ MCP Server (AI integration)
-  ├─ Vault Service (Secrets backend)
-  ├─ Extension Registry (OCI distribution)
-  ├─ AI Service (LLM features)
-  ├─ Detector (Anomaly detection)
-  ├─ RAG (Knowledge retrieval)
-  ├─ Provisioning Daemon (Background service)
-  ├─ Platform Config (Configuration management)
-  └─ Service Clients (API clients)
-       ↓
-Extensions (Modular infrastructure)
-  ├─ Providers (5 cloud providers)
-  ├─ Task Services (50+ services)
-  ├─ Clusters (9 templates)
-  └─ Workflows (Automation)
-       ↓
-Infrastructure (Running resources)
-  ├─ Cloud Compute
-  ├─ Networks & Storage
-  ├─ Services
-  └─ Monitoring
-
-

1. CLI Layer

-

Location: provisioning/core/cli/

-

Main Entry Point (provisioning)

-

Bash wrapper that:

-
    -
  1. Detects Nushell installation
  2. -
  3. Loads environment variables
  4. -
  5. Validates workspace requirement
  6. -
  7. Routes command to dispatcher
  8. -
  9. Handles error reporting
  10. -
-

Command Dispatcher

-

Location: provisioning/core/nulib/main_provisioning/dispatcher.nu

-

Supports:

-
    -
  • 111+ commands across 7 domains
  • -
  • 80+ shortcuts for productivity
  • -
  • Bi-directional help (help workspace / workspace help)
  • -
  • Dynamic loading of command modules
  • -
-

2. Core Engine Components

-

Configuration Management

-

Location: provisioning/core/nulib/lib_provisioning/config/

-

Key Features:

-
    -
  • Load merged configuration from 5 layers
  • -
  • 476+ accessors for config values
  • -
  • Variable interpolation & TOML merging
  • -
  • Schema validation
  • -
  • Configuration caching
  • -
-

Provider Abstraction

-

Location: provisioning/core/nulib/lib_provisioning/providers/

-

Supported Providers (5):

-
    -
  • UpCloud - Primary European cloud
  • -
  • AWS - Amazon Web Services
  • -
  • Hetzner - Baremetal & cloud
  • -
  • Local - Development environment
  • -
  • Demo - Testing & mocking
  • -
-

Features:

-
    -
  • Unified cloud provider interface
  • -
  • Dynamic provider loading
  • -
  • Credential management
  • -
  • Provider state tracking
  • -
-

Workspace Management

-

Location: provisioning/core/nulib/lib_provisioning/workspace/

-

Responsibilities:

-
    -
  • Workspace registry tracking
  • -
  • Atomic workspace switching
  • -
  • Configuration isolation
  • -
  • Extension inheritance
  • -
  • State management
  • -
-

Workspace Registry:

-
workspaces:
-  active: "my-project"
-  registry:
-    my-project:
-      path: ~/.provisioning/workspaces/workspace_my_project
-      created: 2026-01-16T10:30:00Z
-      template: default
-
-

Infrastructure Validation

-

Location: provisioning/core/nulib/lib_provisioning/infra_validator/

-

Validation Stages:

-
    -
  1. Syntax check - Valid Nickel syntax
  2. -
  3. Type check - Type correctness
  4. -
  5. Schema check - Matches expected schema
  6. -
  7. Constraint check - Business rule validation
  8. -
  9. Dependency check - Infrastructure dependencies
  10. -
  11. Security check - Security policies
  12. -
-

Secrets Management

-

Location: provisioning/core/nulib/lib_provisioning/secrets/

-

Backends:

-
    -
  • SOPS + Age (default)
  • -
  • Cosmian KMS (enterprise)
  • -
  • AWS KMS (AWS)
  • -
  • Local KMS (development)
  • -
-

3. Platform Services

-

Orchestrator

-

Location: provisioning/platform/crates/orchestrator/

-

Technology: Rust + Nushell

-

Key Features:

-
    -
  • High-performance workflow execution
  • -
  • File-based persistence
  • -
  • Checkpoint recovery
  • -
  • Parallel execution with dependencies
  • -
  • REST API (83+ endpoints)
  • -
  • Priority-based task scheduling
  • -
-

State Persistence:

-
~/.provisioning/
-├── queue/           # Task queue
-├── checkpoints/     # Workflow checkpoints
-└── state/           # Infrastructure state
-
-

Control Center

-

Location: provisioning/platform/crates/control-center/

-

Technology: Rust (Axum)

-

Features:

-
    -
  • JWT authentication
  • -
  • Cedar policy authorization
  • -
  • RBAC system
  • -
  • Audit logging
  • -
  • REST API for all operations
  • -
-

Authorization Model:

-
    -
  • User roles (admin, user, viewer)
  • -
  • Fine-grained permissions
  • -
  • Cedar policy enforcement
  • -
  • Attribute-based access control
  • -
-

Control Center UI

-

Location: provisioning/platform/crates/control-center-ui/

-

Features:

-
    -
  • Real-time infrastructure view
  • -
  • Workflow visualization
  • -
  • Configuration management
  • -
  • Resource monitoring
  • -
  • Audit log viewer
  • -
-

MCP Server

-

Location: provisioning/platform/crates/mcp-server/

-

Technology: Rust

-

Features:

-
    -
  • AI-powered assistance via MCP
  • -
  • Natural language command parsing
  • -
  • Auto-completion of configurations
  • -
  • 7 configuration tools for LLM
  • -
  • Context-aware recommendations
  • -
-

Vault Service

-

Location: provisioning/platform/crates/vault-service/

-

Features:

-
    -
  • Encrypted credential storage
  • -
  • KMS integration (5 backends)
  • -
  • SOPS + Age encryption
  • -
  • Secure credential injection
  • -
  • Audit logging for secret access
  • -
-

Extension Registry

-

Location: provisioning/platform/crates/extension-registry/

-

Features:

-
    -
  • OCI-compliant distribution
  • -
  • Provider/taskserv packaging
  • -
  • Semantic version management
  • -
  • Content addressable storage
  • -
  • Registry API endpoints
  • -
-

AI Service

-

Location: provisioning/platform/crates/ai-service/

-

Features:

-
    -
  • LLM integration platform
  • -
  • Infrastructure request parsing
  • -
  • Workspace context enrichment
  • -
  • Configuration suggestion generation
  • -
  • Multi-provider LLM support
  • -
-

Detector

-

Location: provisioning/platform/crates/detector/

-

Features:

-
    -
  • System health monitoring
  • -
  • Anomaly pattern detection
  • -
  • Infrastructure issue identification
  • -
  • Real-time surveillance
  • -
  • Alerting system integration
  • -
-

RAG Service

-

Location: provisioning/platform/crates/rag/

-

Features:

-
    -
  • Retrieval Augmented Generation
  • -
  • Document semantic embedding
  • -
  • Knowledge base integration
  • -
  • Context-aware answer generation
  • -
  • Multi-source knowledge synthesis
  • -
-

Provisioning Daemon

-

Location: provisioning/platform/crates/provisioning-daemon/

-

Features:

-
    -
  • Background service operation
  • -
  • System event monitoring
  • -
  • Background job execution
  • -
  • Infrastructure state synchronization
  • -
  • Event-driven architecture
  • -
-

Platform Config

-

Location: provisioning/platform/crates/platform-config/

-

Features:

-
    -
  • Centralized configuration loading
  • -
  • Schema-based validation
  • -
  • Multi-environment support
  • -
  • System-wide default settings
  • -
  • Configuration hot-reload support
  • -
-

Service Clients

-

Location: provisioning/platform/crates/service-clients/

-

Features:

-
    -
  • Platform service client SDKs
  • -
  • Cloud provider API clients
  • -
  • HTTP/RPC request handling
  • -
  • Connection pooling and management
  • -
  • Retry logic and error handling
  • -
-

4. Extension Components

-

Providers

-

Location: provisioning/extensions/providers/

-

Structure:

-
providers/
-├── upcloud/        # UpCloud provider
-├── aws/            # AWS provider
-├── hetzner/        # Hetzner provider
-├── local/          # Local dev provider
-├── demo/           # Demo/test provider
-└── prov_lib/       # Shared utilities
-
-

Provider Interface:

-
    -
  • Create/delete resources
  • -
  • List resources
  • -
  • Query resource status
  • -
  • Network/storage management
  • -
  • Credential validation
  • -
-

Task Services

-

Location: provisioning/extensions/taskservs/

-

50+ Services in 18 categories:

-
    -
  • Container runtimes (containerd, podman, crio)
  • -
  • Kubernetes (etcd, coredns, cilium, calico)
  • -
  • Storage (rook-ceph, mayastor, nfs)
  • -
  • Databases (postgres, redis, mongodb)
  • -
  • Networking (ip-aliases, proxy, kms)
  • -
  • Security (webhook, kms, oras)
  • -
  • Observability (prometheus, grafana, loki)
  • -
  • Development (gitea, coder, buildkit)
  • -
  • Hypervisor (kvm, qemu, libvirt)
  • -
-

Clusters

-

Location: provisioning/extensions/clusters/

-

9 Pre-built Templates:

-
    -
  • web - Web service cluster
  • -
  • oci-reg - Container registry
  • -
  • git - Git hosting (Gitea)
  • -
  • buildkit - Build infrastructure
  • -
  • k8s-ha - HA Kubernetes
  • -
  • postgresql - HA PostgreSQL
  • -
  • cicd-argocd - GitOps CI/CD
  • -
  • cicd-tekton - Tekton pipelines
  • -
-

5. Configuration Layer

-

Nickel Schemas

-

Location: provisioning/schemas/

-

Structure (27 directories):

-
schemas/
-├── main.ncl             # Entry point
-├── lib/                 # Utilities
-├── config/              # Settings
-├── infrastructure/      # Servers, networks
-├── operations/          # Workflows
-├── deployment/          # Kubernetes
-├── services/            # Service defs
-└── versions.ncl         # Tool versions
-
-

3-File Pattern:

-
    -
  1. contracts.ncl - Type definitions
  2. -
  3. defaults.ncl - Default values
  4. -
  5. main.ncl - Entry point + makers
  6. -
-

Component Dependencies

-
CLI
-  ├─ Configuration
-  ├─ Workspace
-  ├─ Validation
-  ├─ Secrets
-  └─ Providers
-
-Providers
-  └─ Orchestrator
-
-Orchestrator
-  ├─ Task Services
-  ├─ Control Center
-  └─ State Manager
-
-Control Center
-  ├─ Authorization
-  ├─ Audit Logging
-  └─ State Manager
-
-

Communication Patterns

-

Synchronous (Request-Response)

-
CLI → Orchestrator → Provider → Cloud API
-
-

Asynchronous (Queue)

-
CLI → Orchestrator (queue) → [Background execution]
-
-

Event-Driven

-
Provider Event → Orchestrator → State Update
-                            → Control Center
-                            → Monitoring
-
- - -

Integration Patterns

-

Design patterns for extending and integrating with Provisioning.

-

1. Provider Integration Pattern

-

Pattern: Add a new cloud provider to Provisioning.

-

2. Task Service Integration Pattern

-

Pattern: Add infrastructure component.

-

3. Cluster Template Pattern

-

Pattern: Create pre-configured cluster template.

-

4. Batch Workflow Pattern

-

Pattern: Create automation workflow for complex operations.

-

5. Custom Extension Pattern

-

Pattern: Create custom Nushell library.

-

6. Authorization Policy Pattern

-

Pattern: Define fine-grained access control via Cedar.

-

7. Webhook Integration

-

Pattern: Trigger Provisioning from external systems.

-

8. Monitoring Integration

-

Pattern: Export metrics and logs to monitoring systems.

-

9. CI/CD Integration

-

Pattern: Use Provisioning in automated pipelines.

-

10. MCP Tool Integration

-

Pattern: Add AI-powered tool via MCP.

-

Integration Scenarios

-

Multi-Cloud Deployment

-

Deploy across UpCloud, AWS, and Hetzner in single workflow.

-

GitOps Workflow

-

Git changes trigger infrastructure updates via webhooks.

-

Self-Service Deployment

-

Non-technical users request infrastructure via natural language.

-

Best Practices

-
    -
  1. Use type-safe Nickel schemas
  2. -
  3. Implement proper error handling
  4. -
  5. Log all operations for audit trails
  6. -
  7. Test extensions before production
  8. -
  9. Document configuration & usage
  10. -
  11. Version extensions independently
  12. -
  13. Support backward compatibility
  14. -
  15. Validate inputs & encrypt credentials
  16. -
- - -

Architecture Decision Records

-

This section contains Architecture Decision Records (ADRs) documenting key architectural decisions and their rationale for the Provisioning platform.

-

ADR Index

-

Core Architecture Decisions

- -

Security and Cryptography

- -

Operations and Observability

- -

Decision Format

-

Each ADR follows this structure:

-
    -
  • Status: Accepted, Proposed, Deprecated, Superseded
  • -
  • Context: Problem statement and constraints
  • -
  • Decision: The chosen approach
  • -
  • Consequences: Benefits and trade-offs
  • -
  • Alternatives: Other options considered
  • -
  • References: Related ADRs and external docs
  • -
-

Rationale for ADRs

-

ADRs document the “why” behind architectural choices:

-
    -
  1. Modular CLI - Scales command set without monolithic registration
  2. -
  3. Workspace-First - Isolates infrastructure and supports multi-tenancy
  4. -
  5. Nickel Source of Truth - Ensures type-safe configuration and prevents runtime errors
  6. -
  7. Microservice Distribution - Enables independent scaling and deployment
  8. -
  9. Communication Protocol - Balances synchronous needs with async event processing
  10. -
  11. Post-Quantum Crypto - Protects against future quantum computing threats
  12. -
  13. Multi-Layer Encryption - Defense in depth against data breaches
  14. -
  15. Observability - Enables rapid troubleshooting and performance analysis
  16. -
  17. SLO Management - Aligns infrastructure quality with business objectives
  18. -
  19. Incident Automation - Reduces MTTR and improves system resilience
  20. -
-

Cross-References

-

These ADRs interact with:

-
    -
  • Platform Documentation - See provisioning/docs/src/architecture/
  • -
  • Features - See provisioning/docs/src/features/ for implementation details
  • -
  • Development Guides - See provisioning/docs/src/development/ for extending systems
  • -
  • Security Documentation - See provisioning/docs/src/security/ for compliance details
  • -
  • Operations Guides - See provisioning/docs/src/operations/ for deployment procedures
  • -
-

Examples

-

Real-world infrastructure as code examples demonstrating Provisioning across -multi-cloud, Kubernetes, security, and operational scenarios.

-

Overview

-

This section contains production-ready examples showing how to:

-
    -
  • Deploy infrastructure from basic single-cloud to complex multi-cloud environments
  • -
  • Orchestrate Kubernetes clusters with Provisioning automation
  • -
  • Implement security patterns including encryption, secrets management, and compliance
  • -
  • Build custom workflows for specialized infrastructure operations
  • -
  • Handle disaster recovery with backup strategies and failover procedures
  • -
  • Optimize costs through resource analysis and right-sizing
  • -
  • Migrate legacy systems from traditional infrastructure to cloud-native architectures
  • -
  • Test infrastructure as code with validation, policy checks, and integration tests
  • -
-

All examples use Nickel for type-safe configuration and are designed as learning resources and templates for your own deployments.

-

Quick Start Examples

-

Basic Infrastructure Setup

-
    -
  • -

    Basic Setup - Single-cloud with networking, -compute, storage - perfect starting point

    -
  • -
  • -

    E-Commerce Platform - Multi-tier -application across AWS and UpCloud with load balancing, databases

    -
  • -
-

Multi-Cloud Deployments

- -

Operational Examples

- -

Advanced Patterns

- -

Security and Compliance

- -

Cloud Provider Specific

- -

Configuration and Migration

- -

Example Organization

-

Each example follows this structure:

-
example-name.md
-├── Overview - What this example demonstrates
-├── Prerequisites - Required setup
-├── Architecture Diagram - Visual representation
-├── Nickel Configuration - Complete, runnable configuration
-├── Deployment Steps - Command-by-command instructions
-├── Verification - How to validate deployment
-├── Troubleshooting - Common issues and solutions
-└── Next Steps - How to extend or customize
-
-

Learning Paths

-

I’m new to Provisioning

-
    -
  1. Start with Basic Setup
  2. -
  3. Read Real-World Scenario
  4. -
  5. Try Kubernetes Deployment
  6. -
-

I need multi-cloud infrastructure

-
    -
  1. Review Multi-Cloud Deployment
  2. -
  3. Study Hybrid Cloud Setup
  4. -
  5. Implement Advanced Networking
  6. -
-

I need to migrate existing infrastructure

-
    -
  1. Start with Legacy System Migration
  2. -
  3. Add Terraform Migration if applicable
  4. -
  5. Set up GitOps Deployment
  6. -
-

I need enterprise features

-
    -
  1. Implement Compliance and Audit
  2. -
  3. Set up Disaster Recovery
  4. -
  5. Deploy Cost Governance
  6. -
  7. Configure Secrets Rotation
  8. -
-

Copy and Customize

-

All examples are self-contained and can be:

-
    -
  1. Copied into your workspace and adapted
  2. -
  3. Extended with additional resources and customizations
  4. -
  5. Tested using Provisioning’s validation framework
  6. -
  7. Deployed directly via provisioning apply
  8. -
-

Use them as templates, learning resources, or reference implementations for your own infrastructure.

- -
    -
  • Configuration Guide → See provisioning/docs/src/infrastructure/nickel-guide.md
  • -
  • API Reference → See provisioning/docs/src/api-reference/
  • -
  • Development → See provisioning/docs/src/development/
  • -
  • Operations → See provisioning/docs/src/operations/
  • -
-

Basic Setup

-

Simple infrastructure setup examples for getting started with the Provisioning platform.

-

Single Server Deployment

-

Deploy a simple web server with UpCloud:

-
# workspace/infra/web-server.ncl
-{
-  servers = [
-    {
-      name = "web-01",
-      provider = 'upcloud,
-      plan = 'medium,
-      zone = "fi-hel1",
-      storage = [
-        {size_gb = 50, type = 'ssd}
-      ]
-    }
-  ]
-}
-
-

Deploy:

-
provisioning workspace create basic-web
-cd basic-web
-cp ../examples/web-server.ncl infra/
-
-provisioning deploy --workspace basic-web --yes
-
-

Three-Tier Application

-

Web frontend, application backend, database:

-
{
-  servers = [
-    {name = "web-01", provider = 'upcloud, plan = 'small, zone = "fi-hel1"},
-    {name = "app-01", provider = 'upcloud, plan = 'medium, zone = "fi-hel1"},
-    {name = "db-01", provider = 'upcloud, plan = 'large, zone = "fi-hel1",
-     storage = [{size_gb = 100, type = 'ssd}]},
-  ],
-
-  task_services = [
-    {name = "nginx", target = "web-01"},
-    {name = "nodejs", target = "app-01"},
-    {name = "postgresql", target = "db-01"},
-  ]
-}
-
-

Development Environment

-

Local development stack with Docker:

-
{
-  servers = [
-    {name = "dev-local", provider = 'local, plan = 'medium}
-  ],
-
-  task_services = [
-    {name = "docker"},
-    {name = "postgresql"},
-    {name = "redis"},
-  ]
-}
-
-

References

- -

Multi-Cloud Examples

-

Deploy infrastructure across multiple cloud providers for redundancy and geographic distribution.

-

Primary-Backup Configuration

-

UpCloud primary in Europe, AWS backup in US:

-
{
-  servers = [
-    # Primary (UpCloud EU)
-    {name = "web-eu", provider = 'upcloud, zone = "fi-hel1", plan = 'medium},
-    {name = "db-eu", provider = 'upcloud, zone = "fi-hel1", plan = 'large},
-
-    # Backup (AWS US)
-    {name = "web-us", provider = 'aws, zone = "us-east-1a", plan = 't3.medium},
-    {name = "db-us", provider = 'aws, zone = "us-east-1a", plan = 'm5.large},
-  ],
-
-  replication = {
-    enabled = true,
-    pairs = [
-      {primary = "db-eu", standby = "db-us", mode = 'async}
-    ]
-  }
-}
-
-

Geographic Distribution

-

Deploy to multiple regions for low latency:

-
{
-  servers = [
-    {name = "web-eu", provider = 'upcloud, zone = "fi-hel1"},
-    {name = "web-us", provider = 'aws, zone = "us-west-2a"},
-    {name = "web-asia", provider = 'aws, zone = "ap-southeast-1a"},
-  ],
-
-  load_balancing = {
-    global = true,
-    geo_routing = true
-  }
-}
-
-

References

- -

Kubernetes Deployment Examples

-

Deploy production-ready Kubernetes clusters with the Provisioning platform.

-

Basic Kubernetes Cluster

-

3-node cluster with Cilium CNI:

-
{
-  task_services = [
-    {
-      name = "kubernetes",
-      config = {
-        control_plane = {nodes = 3, plan = 'medium},
-        workers = [{name = "default", nodes = 3, plan = 'large}],
-        networking = {
-          cni = 'cilium,
-          pod_cidr = "10.42.0.0/16",
-          service_cidr = "10.43.0.0/16"
-        }
-      }
-    }
-  ]
-}
-
-

Production Cluster with Storage

-

Kubernetes with Rook-Ceph storage:

-
{
-  task_services = [
-    {
-      name = "kubernetes",
-      config = {
-        control_plane = {nodes = 3, plan = 'medium},
-        workers = [
-          {name = "general", nodes = 5, plan = 'large},
-          {name = "storage", nodes = 3, plan = 'xlarge,
-           storage = [{size_gb = 500, type = 'ssd}]}
-        ],
-        networking = {cni = 'cilium}
-      }
-    },
-    {
-      name = "rook-ceph",
-      config = {
-        storage_nodes = ["storage-0", "storage-1", "storage-2"],
-        osd_per_device = 1
-      }
-    }
-  ]
-}
-
-

References

- -

Custom Workflow Examples

-

Build complex deployment workflows with dependency management and parallel execution.

-

Multi-Stage Deployment

-
{
-  workflows = [{
-    name = "app-deployment",
-    steps = [
-      {name = "provision-infrastructure", type = 'provision},
-      {name = "install-kubernetes", type = 'task, depends_on = ["provision-infrastructure"]},
-      {name = "deploy-application", type = 'task, depends_on = ["install-kubernetes"]},
-      {name = "configure-monitoring", type = 'task, depends_on = ["deploy-application"]}
-    ]
-  }]
-}
-
-

Parallel Regional Deployment

-
{
-  workflows = [{
-    name = "global-rollout",
-    steps = [
-      {name = "deploy-eu", type = 'task},
-      {name = "deploy-us", type = 'task},
-      {name = "deploy-asia", type = 'task},
-      {name = "configure-dns", type = 'configure,
-       depends_on = ["deploy-eu", "deploy-us", "deploy-asia"]}
-    ]
-  }]
-}
-
-

References

- -

Security Configuration Examples

-

Security configuration examples for authentication, encryption, and secrets management.

-

Complete Security Configuration

-
{
-  security = {
-    authentication = {
-      enabled = true,
-      jwt_algorithm = "RS256",
-      mfa_required = true
-    },
-
-    secrets = {
-      backend = "secretumvault",
-      url = " [https://vault.example.com",](https://vault.example.com",)
-      auto_rotate = true,
-      rotation_days = 90
-    },
-
-    encryption = {
-      at_rest = true,
-      algorithm = "AES-256-GCM",
-      kms_backend = "secretumvault"
-    },
-
-    audit = {
-      enabled = true,
-      retention_days = 2555,
-      export_format = "json"
-    }
-  }
-}
-
-

SecretumVault Integration

-
# Configure SecretumVault
-provisioning config set security.secrets.backend secretumvault
-provisioning config set security.secrets.url  [http://localhost:8200](http://localhost:8200)
-
-# Store secrets
-provisioning vault put database/password --value="secret123"
-
-# Retrieve secrets
-provisioning vault get database/password
-
-

Encrypted Infrastructure Configuration

-
{
-  providers.upcloud = {
-    username = "admin",
-    password = std.secret "UPCLOUD_PASSWORD"  # Encrypted
-  },
-
-  databases = [{
-    name = "production-db",
-    password = std.secret "DB_PASSWORD"  # Encrypted
-  }]
-}
-
-

References

- -

Troubleshooting

-

Systematic problem-solving guides and debugging procedures for diagnosing and resolving issues with the Provisioning platform.

-

Overview

-

This section helps you:

-
    -
  • Solve common issues - Database connection errors, authentication failures, deployment failures
  • -
  • Debug problems - Diagnostic tools, log analysis, tracing execution paths
  • -
  • Analyze logs - Log aggregation, filtering, searching, pattern recognition
  • -
  • Understand errors - Error message interpretation and root cause analysis
  • -
  • Get support - Knowledge base, community resources, professional support
  • -
-

Organized by problem type and component for quick navigation.

-

Troubleshooting Guides

-

Quick Problem Solving

-
    -
  • -

    Common Issues - Authentication failures, -deployment errors, configuration, resource limits, network problems

    -
  • -
  • -

    Debug Guide - Debug logging, verbose output, trace -execution, collect diagnostics, analyze stack traces

    -
  • -
  • -

    Logs Analysis - Find logs, search techniques, -log patterns, interpreting errors, diagnostics

    -
  • -
-

Component-Specific Troubleshooting

-

Each microservice and component has its own troubleshooting section:

-
    -
  • Orchestrator Issues - Workflow failures, scheduling problems, state inconsistencies
  • -
  • Control Center Issues - API errors, permission problems, configuration issues
  • -
  • Vault Service Issues - Secret access failures, key rotation problems, authentication errors
  • -
  • Detector Issues - Analysis failures, false positives, configuration problems
  • -
  • Extension Registry Issues - Provider loading, dependency resolution, versioning conflicts
  • -
-

Infrastructure and Configuration

-
    -
  • Configuration Problems - Nickel syntax errors, schema validation failures, type mismatches
  • -
  • Provider Issues - Authentication failures, API limits, resource creation failures
  • -
  • Task Service Failures - Service-specific errors, timeout issues, state management problems
  • -
  • Network Problems - Connectivity issues, DNS resolution, firewall rules, certificate problems
  • -
-

Problem Diagnosis Flowchart

-
Issue Occurs
-    ↓
-Is it an authentication issue? → See [Common Issues](./common-issues.md) - Authentication
-    ↓ No
-Is it a deployment failure? → See [Common Issues](./common-issues.md) - Deployment
-    ↓ No
-Is it a configuration error? → See [Debug Guide](./debug-guide.md) - Configuration
-    ↓ No
-Enable debug logging → See [Debug Guide](./debug-guide.md)
-    ↓
-Collect logs and traces → See [Logs Analysis](./logs-analysis.md)
-    ↓
-Analyze patterns → Identify root cause
-    ↓
-Apply fix or escalate
-
-

Quick Reference: Common Problems

-
- - - - - - - - -
ProblemSolutionGuide
“Authentication failed”Check credentials, enable MFACommon Issues
“Permission denied”Verify RBAC policies, check Cedar rulesCommon Issues
“Deployment failed”Check logs, verify resources, test connectivityDebug Guide
“Configuration invalid”Validate Nickel schema, check typesCommon Issues
“Provider unavailable”Check API keys, verify connectivityCommon Issues
“Resource creation failed”Check resource limits, verify accountDebug Guide
“Timeout”Increase timeouts, check performanceDebug Guide
“Database error”Check connections, verify schemaCommon Issues
-
-

Debugging Workflow

-
    -
  1. Reproduce - Can you consistently reproduce the issue?
  2. -
  3. Enable Debug Logging - Set RUST_LOG=debug and PROVISIONING_LOG_LEVEL=debug
  4. -
  5. Collect Evidence - Logs, configuration, error messages, stack traces
  6. -
  7. Analyze Patterns - Look for errors, warnings, unusual timing
  8. -
  9. Identify Cause - Root cause analysis
  10. -
  11. Test Fix - Verify the fix resolves the issue
  12. -
  13. Prevent Recurrence - Update documentation, add tests
  14. -
-

Enable Diagnostic Logging

-
# Set log level to debug
-export RUST_LOG=debug
-export PROVISIONING_LOG_LEVEL=debug
-
-# Collect logs to file
-provisioning config set logging.file /var/log/provisioning.log
-provisioning config set logging.level debug
-
-# Enable verbose output
-provisioning --verbose <command>
-
-# Run with tracing
-RUST_BACKTRACE=1 provisioning <command>
-
-

Common Error Codes

-
- - - - - - - -
CodeMeaningAction
401UnauthorizedCheck authentication credentials
403ForbiddenCheck authorization policies
404Not FoundVerify resource exists
409ConflictResolve state conflicts
422InvalidVerify configuration schema
500Internal ErrorCheck server logs
503Service UnavailableWait for service to recover
-
-

Escalation Paths

-

Community Support

-
    -
  1. Check Common Issues
  2. -
  3. Search community forums
  4. -
  5. Ask on GitHub discussions
  6. -
-

Professional Support

-
    -
  1. Open a support ticket
  2. -
  3. Provide: logs, configuration, reproduction steps
  4. -
  5. Wait for response
  6. -
-

Emergency Issues (Security, Data Loss)

-
    -
  1. Contact security team immediately
  2. -
  3. Provide all evidence
  4. -
  5. Document timeline
  6. -
-

Support Resources

-
    -
  • Documentation → Complete guides in provisioning/docs/src/
  • -
  • GitHub Issues → Community issues and discussions
  • -
  • Slack Community → Real-time community support
  • -
  • Email Supportprofessional@provisioning.io
  • -
  • Chat Support → Available during business hours
  • -
- -
    -
  • Operations Guide → See provisioning/docs/src/operations/
  • -
  • Architecture → See provisioning/docs/src/architecture/
  • -
  • Features → See provisioning/docs/src/features/
  • -
  • Development → See provisioning/docs/src/development/
  • -
  • Examples → See provisioning/docs/src/examples/
  • -
-

Common Issues

-

Debug Guide

-

Logs Analysis

-

Getting Help

-

AI & Machine Learning

-

Provisioning includes comprehensive AI capabilities for infrastructure automation via natural -language, intelligent configuration suggestions, and anomaly detection.

-

Overview

-

The AI system consists of three integrated components:

-
    -
  1. TypeDialog AI Backends - Interactive form intelligence and agent automation
  2. -
  3. AI Service Microservice - Central AI processing and coordination
  4. -
  5. Core AI Libraries - Nushell query processing and LLM integration
  6. -
-

Key Capabilities

-

Natural Language Infrastructure

-

Request infrastructure changes in plain English:

-
# Natural language request
-provisioning ai "Create 3 web servers with load balancing and auto-scaling"
-
-# Returns:
-# - Parsed infrastructure requirements
-# - Generated Nickel configuration
-# - Deployment confirmation
-
-

Intelligent Configuration

-

AI suggests optimal configurations based on context:

-
    -
  • Database selection and tuning
  • -
  • Network topology recommendations
  • -
  • Security policy generation
  • -
  • Resource allocation optimization
  • -
-

Anomaly Detection

-

Continuous monitoring and intelligent alerting:

-
    -
  • Infrastructure health anomalies
  • -
  • Performance pattern detection
  • -
  • Security issue identification
  • -
  • Predictive alerting
  • -
-

Components at a Glance

-
- - - - - - -
ComponentPurposeTechnology
typedialog-aiForm intelligence & suggestionsHTTP server, SurrealDB
typedialog-agAI agents & workflow automationType-safe agents, Nickel transpilation
ai-serviceCentral AI microserviceRust, LLM integration
ragKnowledge base retrievalSemantic search, embeddings
mcp-serverModel Context ProtocolAI tool interface
detectorAnomaly detection systemPattern recognition
-
-

Quick Start

-

Enable AI Features

-
# Install AI tools
-provisioning install ai-tools
-
-# Configure AI service
-provisioning ai configure --provider openai --model gpt-4
-
-# Test AI capabilities
-provisioning ai test
-
-

Use Natural Language

-
# Simple request
-provisioning ai "Create a Kubernetes cluster"
-
-# Complex request with options
-provisioning ai "Deploy PostgreSQL HA cluster with replication in AWS, backup to S3"
-
-# Get help on AI features
-provisioning help ai
-
-

Architecture

-

The AI system follows a layered architecture:

-
┌─────────────────────────────────┐
-│  User Interface Layer            │
-│  • Natural language input        │
-│  • TypeDialog AI forms           │
-│  • Chat interface                │
-└────────────┬────────────────────┘
-             ↓
-┌─────────────────────────────────┐
-│  AI Orchestration Layer          │
-│  • AI Service (Rust)             │
-│  • Query processing (Nushell)    │
-│  • Intent recognition            │
-└────────────┬────────────────────┘
-             ↓
-┌─────────────────────────────────┐
-│  Knowledge & Processing Layer    │
-│  • RAG (Retrieval)               │
-│  • LLM Integration               │
-│  • MCP Server                    │
-│  • Detector (anomalies)          │
-└────────────┬────────────────────┘
-             ↓
-┌─────────────────────────────────┐
-│  Infrastructure Layer            │
-│  • Nickel configuration          │
-│  • Deployment execution          │
-│  • Monitoring & feedback         │
-└─────────────────────────────────┘
-
-

Topics

- -

Configuration

-

Environment Variables

-
# LLM Provider
-export PROVISIONING_AI_PROVIDER=openai        # openai, anthropic, local
-export PROVISIONING_AI_MODEL=gpt-4            # Model identifier
-export PROVISIONING_AI_API_KEY=sk-...         # API key
-
-# AI Service
-export PROVISIONING_AI_SERVICE_PORT=9091      # AI service port
-export PROVISIONING_AI_ENABLE_ANOMALY=true    # Enable detector
-export PROVISIONING_AI_RAG_THRESHOLD=0.75     # Similarity threshold
-
-

Configuration File

-
# ~/.config/provisioning/ai.yaml
-ai:
-  enabled: true
-  provider: openai
-  model: gpt-4
-  api_key: ${PROVISIONING_AI_API_KEY}
-
-  service:
-    port: 9091
-    timeout: 30
-    max_retries: 3
-
-  typedialog:
-    ai_enabled: true
-    ag_enabled: true
-    suggestions: true
-
-  rag:
-    enabled: true
-    similarity_threshold: 0.75
-    max_results: 5
-
-  detector:
-    enabled: true
-    update_interval: 60
-    alert_threshold: 0.8
-
-

Use Cases

-

1. Infrastructure from Description

-

Describe infrastructure in natural language, get Nickel configuration:

-
provisioning ai deploy "
-  Create a production Kubernetes cluster with:
-  - 3 control planes
-  - 5 worker nodes
-  - HA PostgreSQL (3 nodes)
-  - Prometheus monitoring
-  - Encrypted networking
-"
-
-

2. Configuration Assistance

-

Get AI suggestions while filling out forms:

-
provisioning setup profile
-# TypeDialog shows suggestions based on context
-# Database recommendations based on workload
-# Security settings optimized for environment
-
-

3. Troubleshooting

-

AI analyzes logs and suggests fixes:

-
provisioning ai troubleshoot --service orchestrator
-
-# Output:
-# Issue detected: High memory usage
-# Likely cause: Task queue backlog
-# Suggestion: Scale orchestrator replicas to 3
-# Command: provisioning orchestrator scale --replicas 3
-
-

4. Anomaly Detection

-

Continuous monitoring with intelligent alerts:

-
provisioning ai anomalies --since 1h
-
-# Output:
-# ⚠️  Unusual pattern detected
-# Time: 2026-01-16T01:47:00Z
-# Service: control-center
-# Metric: API response time
-# Baseline: 45ms → Current: 320ms (+611%)
-# Likelihood: Query performance regression
-
-

Limitations

-
    -
  • LLM Dependency: Requires external LLM provider (OpenAI, Anthropic, etc.)
  • -
  • Network Required: Cloud-based LLM providers need internet connectivity
  • -
  • Context Window: Large infrastructures may exceed LLM context limits
  • -
  • Cost: API calls incur per-token charges
  • -
  • Latency: Natural language processing adds response latency (2-5 seconds)
  • -
-

Configuration Files

-

Key files for AI configuration:

-
- - - - - - -
FilePurpose
.typedialog/ai.dbAI SurrealDB database (typedialog-ai)
.typedialog/agent-*.yamlAI agent definitions (typedialog-ag)
~/.config/provisioning/ai.yamlUser AI settings
provisioning/core/versions.nclTypeDialog versions
core/nulib/lib_provisioning/ai/Core AI libraries
platform/crates/ai-service/AI service crate
-
-

Performance

-

Typical Latencies

-
- - - - -
OperationLatency
Simple request parsing100-200ms
LLM inference2-5 seconds
Configuration generation500ms-1s
Anomaly detection50-100ms
-
-

Scalability

-
    -
  • Concurrent requests: 100+ (load balanced)
  • -
  • Query processing: 10,000+ queries/second
  • -
  • RAG similarity search: <50ms for 1M documents
  • -
  • Anomaly detection: Real-time on 1000+ metrics
  • -
-

Security

-

API Keys

-
    -
  • Stored encrypted in vault-service
  • -
  • Never logged or persisted in plain text
  • -
  • Rotated automatically (configurable)
  • -
  • Audit trail for all API usage
  • -
-

Data Privacy

-
    -
  • Natural language queries not stored by default
  • -
  • LLM provider agreements (OpenAI terms, etc.)
  • -
  • Local-only RAG option available
  • -
  • GDPR compliance support
  • -
- - -

AI Architecture

-

Complete system architecture of Provisioning’s AI capabilities, from user interface through infrastructure generation.

-

System Overview

-
┌──────────────────────────────────────────────────┐
-│  User Interface Layer                            │
-│  • CLI (natural language)                        │
-│  • TypeDialog AI forms                           │
-│  • Interactive wizards                           │
-│  • Web dashboard                                 │
-└────────────────────┬─────────────────────────────┘
-                     ↓
-┌──────────────────────────────────────────────────┐
-│  Request Processing Layer                        │
-│  • Intent recognition                            │
-│  • Entity extraction                             │
-│  • Context parsing                               │
-│  • Request validation                            │
-└────────────────────┬─────────────────────────────┘
-                     ↓
-┌──────────────────────────────────────────────────┐
-│  Knowledge & Retrieval Layer (RAG)              │
-│  • Document embedding                            │
-│  • Vector similarity search                      │
-│  • Keyword matching (BM25)                       │
-│  • Hybrid ranking                                │
-└────────────────────┬─────────────────────────────┘
-                     ↓
-┌──────────────────────────────────────────────────┐
-│  LLM Integration Layer                           │
-│  • MCP tool registration                         │
-│  • Context augmentation                          │
-│  • Prompt engineering                            │
-│  • LLM API calls (OpenAI, Anthropic, etc.)      │
-└────────────────────┬─────────────────────────────┘
-                     ↓
-┌──────────────────────────────────────────────────┐
-│  Configuration Generation Layer                  │
-│  • Nickel code generation                        │
-│  • Schema validation                             │
-│  • Constraint checking                           │
-│  • Cost estimation                               │
-└────────────────────┬─────────────────────────────┘
-                     ↓
-┌──────────────────────────────────────────────────┐
-│  Execution & Feedback Layer                      │
-│  • DAG planning                                  │
-│  • Dry-run simulation                            │
-│  • Deployment execution                          │
-│  • Performance monitoring                        │
-└──────────────────────────────────────────────────┘
-
-

Component Architecture

-

1. User Interface Layer

-

Entry Points:

-
Natural Language Input
-    ├─ CLI: provisioning ai "create kubernetes cluster"
-    ├─ Interactive: provisioning ai interactive
-    ├─ Forms: TypeDialog AI-enhanced forms
-    └─ Web Dashboard: /ai/infrastructure-builder
-
-

Processing:

-
    -
  • Tokenization and normalization
  • -
  • Command pattern matching
  • -
  • Ambiguity resolution
  • -
  • Confidence scoring
  • -
-

2. Intent Recognition

-
User Request
-    ↓
-Intent Classification
-    ├─ Create infrastructure (60%)
-    ├─ Modify configuration (25%)
-    ├─ Query knowledge (10%)
-    └─ Troubleshoot issue (5%)
-    ↓
-Entity Extraction
-    ├─ Resource type (server, database, cluster)
-    ├─ Cloud provider (AWS, UpCloud, Hetzner)
-    ├─ Count/Scale (3 nodes, 10GB)
-    ├─ Requirements (HA, encrypted, monitoring)
-    └─ Constraints (budget, region, environment)
-    ↓
-Request Structure
-
-

3. RAG Knowledge Retrieval

-

Embedding Process:

-
Query: "Create 3 web servers with load balancer"
-    ↓
-Embed Query → Vector [0.234, 0.567, 0.891, ...]
-    ↓
-Search Relevant Documents
-    ├─ Vector similarity (semantic)
-    ├─ BM25 keyword matching (syntactic)
-    └─ Hybrid ranking
-    ↓
-Top Results:
-    1. "Web Server HA Patterns" (0.94 similarity)
-    2. "Load Balancing Best Practices" (0.87)
-    3. "Auto-Scaling Configuration" (0.76)
-    ↓
-Extract Context & Augment Prompt
-
-

Knowledge Organization:

-
knowledge/
-├── infrastructure/           (450 docs)
-│   ├── kubernetes/
-│   ├── databases/
-│   ├── networking/
-│   └── web-services/
-├── best-practices/          (300 docs)
-│   ├── high-availability/
-│   ├── disaster-recovery/
-│   └── performance/
-├── providers/               (250 docs)
-│   ├── aws/
-│   ├── upcloud/
-│   └── hetzner/
-└── security/                (200 docs)
-    ├── encryption/
-    ├── authentication/
-    └── compliance/
-
-

4. LLM Integration (MCP)

-

Tool Registration:

-
LLM (GPT-4, Claude 3)
-    ↓
-MCP Server (provisioning-mcp)
-    ↓
-Available Tools:
-    ├─ create_infrastructure
-    ├─ analyze_configuration
-    ├─ generate_policies
-    ├─ estimate_costs
-    ├─ check_compatibility
-    ├─ validate_nickel
-    ├─ query_knowledge_base
-    └─ get_recommendations
-    ↓
-Tool Execution
-
-

Prompt Engineering Pipeline:

-
Base Prompt Template
-    ↓
-Add Context (RAG results)
-    ↓
-Add Constraints
-    ├─ Budget limit
-    ├─ Region restrictions
-    ├─ Compliance requirements
-    └─ Performance targets
-    ↓
-Add Examples
-    ├─ Successful deployments
-    ├─ Error patterns
-    └─ Best practices
-    ↓
-Enhanced Prompt
-    ↓
-LLM Inference
-
-

5. Configuration Generation

-

Nickel Code Generation:

-
LLM Output (structured)
-    ↓
-Nickel Template Filling
-    ├─ Server definitions
-    ├─ Network configuration
-    ├─ Storage setup
-    └─ Monitoring config
-    ↓
-Generated Nickel File
-    ↓
-Syntax Validation
-    ↓
-Schema Validation (Type Checking)
-    ↓
-Constraint Verification
-    ├─ Resource limits
-    ├─ Budget constraints
-    ├─ Compliance policies
-    └─ Provider capabilities
-    ↓
-Cost Estimation
-    ↓
-Final Configuration
-
-

6. Execution & Feedback

-

Deployment Planning:

-
Configuration
-    ↓
-DAG Generation (Directed Acyclic Graph)
-    ├─ Task decomposition
-    ├─ Dependency analysis
-    ├─ Parallelization
-    └─ Scheduling
-    ↓
-Dry-Run Simulation
-    ├─ Check resources available
-    ├─ Validate API access
-    ├─ Estimate time
-    └─ Identify risks
-    ↓
-Execution with Checkpoints
-    ├─ Create resources
-    ├─ Monitor progress
-    ├─ Collect metrics
-    └─ Save checkpoints
-    ↓
-Post-Deployment
-    ├─ Verify functionality
-    ├─ Run health checks
-    ├─ Collect performance data
-    └─ Store feedback for future improvements
-
-

Data Flow Examples

-

Example 1: Simple Request

-
User: "Create 3 web servers with load balancer"
-    ↓
-Intent: Create Infrastructure
-Entities: type=server, count=3, load_balancer=true
-    ↓
-RAG Retrieval: "Web Server Patterns", "Load Balancing"
-    ↓
-LLM Prompt:
-"Generate Nickel config for 3 web servers with load balancer.
-Context: [web server best practices from knowledge base]
-Constraints: High availability, auto-scaling enabled"
-    ↓
-Generated Nickel:
-{
-  servers = [
-    {name = "web-01", cpu = 4, memory = 8},
-    {name = "web-02", cpu = 4, memory = 8},
-    {name = "web-03", cpu = 4, memory = 8}
-  ]
-  load_balancer = {
-    type = "application"
-    health_check = "/health"
-  }
-}
-    ↓
-Configuration Generated & Validated ✓
-    ↓
-User Approval
-    ↓
-Deployment
-
-

Example 2: Complex Multi-Cloud Request

-
User: "Deploy Kubernetes to AWS, UpCloud, and Hetzner with replication"
-    ↓
-Intent: Multi-Cloud Infrastructure
-Entities: type=kubernetes, providers=[aws, upcloud, hetzner], replicas=3
-    ↓
-RAG Retrieval:
-    - "Multi-Cloud Kubernetes Patterns"
-    - "Inter-Region Replication"
-    - "AWS Kubernetes Setup"
-    - "UpCloud Kubernetes Setup"
-    - "Hetzner Kubernetes Setup"
-    ↓
-LLM Processes:
-    1. Analyze multi-cloud topology
-    2. Identify networking requirements
-    3. Plan data replication strategy
-    4. Consider regional compliance
-    ↓
-Generated Nickel:
-    - Infrastructure definitions for each provider
-    - Inter-region networking configuration
-    - Replication topology
-    - Failover policies
-    ↓
-Cost Breakdown:
-    AWS: $2,500/month
-    UpCloud: $1,800/month
-    Hetzner: $1,500/month
-    Total: $5,800/month
-    ↓
-Compliance Check: EU GDPR ✓, US HIPAA ✓
-    ↓
-Ready for Deployment
-
-

Key Technologies

-

LLM Providers

-

Supported external LLM providers:

-
- - - -
ProviderModelsLatencyCost
OpenAIGPT-4, GPT-3.52-3s$0.05-0.15/1K tokens
AnthropicClaude 3 Opus2-4s$0.03-0.015/1K tokens
Local (Ollama)Llama 2, Mistral5-10sFree
-
-

Vector Databases

-
    -
  • SurrealDB (default): Embedded vector database with HNSW indexing
  • -
  • Pinecone: Cloud vector database (optional)
  • -
  • Milvus: Open-source vector database (optional)
  • -
-

Embedding Models

-
    -
  • text-embedding-3-small (OpenAI): 1,536 dimensions
  • -
  • text-embedding-3-large (OpenAI): 3,072 dimensions
  • -
  • all-MiniLM-L6-v2 (local): 384 dimensions
  • -
-

Performance Characteristics

-

Latency Breakdown

-

For a typical infrastructure creation request:

-
- - - - - - -
StageLatencyDetails
Intent Recognition50-100msLocal NLP
RAG Retrieval50-100msVector search
LLM Inference2-5sExternal API
Nickel Generation100-200msTemplate filling
Validation200-500msType checking
Total2.5-6 secondsEnd-to-end
-
-

Concurrency

-
    -
  • Concurrent Requests: 100+ (with load balancing)
  • -
  • RAG QPS: 50+ searches/second
  • -
  • LLM Throughput: 10+ concurrent requests per API key
  • -
  • Memory: 500MB-2GB (depends on cache size)
  • -
-

Security Architecture

-

Data Protection

-
User Input
-    ↓
-Input Sanitization
-    ├─ Remove PII
-    ├─ Validate constraints
-    └─ Check permissions
-    ↓
-Processing (encrypted in transit)
-    ├─ TLS 1.3 to LLM provider
-    ├─ Secrets stored in vault-service
-    └─ Credentials never logged
-    ↓
-Generated Configuration
-    ├─ Encrypted at rest (AES-256)
-    ├─ Signed for integrity
-    └─ Audit trail maintained
-    ↓
-Output
-
-

Access Control

-
    -
  • API key validation
  • -
  • RBAC permission checking
  • -
  • Rate limiting per user/key
  • -
  • Audit logging of all operations
  • -
-

Extensibility

-

Custom Tools

-

Register custom tools with MCP:

-
// Custom tool example
-register_tool("custom-validator", | confi| g {
-    validate_custom_requirements(&config)
-});
-

Custom RAG Documents

-

Add domain-specific knowledge:

-
provisioning ai knowledge import \
-  --source ./custom-docs \
-  --category infrastructure
-
-

Fine-tuning (Future)

-
    -
  • Support for fine-tuned LLM models
  • -
  • Custom prompt templates
  • -
  • Organization-specific knowledge bases
  • -
- - -

TypeDialog AI & AG Integration

-

TypeDialog provides two AI-powered tools for Provisioning: typedialog-ai (configuration assistant) and typedialog-ag (agent automation).

-

TypeDialog Components

-

typedialog-ai v0.1.0

-

AI Assistant - HTTP server backend for intelligent form suggestions and infrastructure recommendations.

-

Purpose: Enhance interactive forms with AI-powered suggestions and natural language parsing.

-

Architecture:

-
TypeDialog Form
-    ↓
-typedialog-ai HTTP Server
-    ↓
-SurrealDB Backend
-    ↓
-LLM Provider (OpenAI, Anthropic, etc.)
-    ↓
-Suggestions → Deployed Config
-
-

Key Features:

-
    -
  • Form Intelligence: Context-aware field suggestions
  • -
  • Database Recommendations: Suggest database type/configuration based on workload
  • -
  • Network Optimization: Generate optimal network topology
  • -
  • Security Policies: AI-generated Cedar policies
  • -
  • Cost Estimation: Predict infrastructure costs
  • -
-

Installation:

-
# Via provisioning script
-provisioning install ai-tools
-
-# Manual installation
-wget  [https://github.com/typedialog/typedialog-ai/releases/download/v0.1.0/typedialog-ai-<os>-<arch>](https://github.com/typedialog/typedialog-ai/releases/download/v0.1.0/typedialog-ai-<os>-<arch>)
-chmod +x typedialog-ai
-mv typedialog-ai ~/.local/bin/
-
-

Usage:

-
# Start AI server
-typedialog ai serve --db-path ~/.typedialog/ai.db --port 9000
-
-# Test connection
-curl  [http://localhost:9000/health](http://localhost:9000/health)
-
-# Get suggestion for database
-curl -X POST  [http://localhost:9000/suggest/database](http://localhost:9000/suggest/database) \
-  -H "Content-Type: application/json" \
-  -d '{"workload": "transactional", "size": "1TB", "replicas": 3}'
-
-# Response:
-# {"suggestion": "PostgreSQL 15 with pgvector", "confidence": 0.92}
-
-

Configuration:

-
# ~/.typedialog/ai-config.yaml
-typedialog-ai:
-  port: 9000
-  db_path: ~/.typedialog/ai.db
-  loglevel: info
-
-  llm:
-    provider: openai              # or: anthropic, local
-    model: gpt-4
-    api_key: ${OPENAI_API_KEY}
-    temperature: 0.7
-
-  features:
-    form_suggestions: true
-    database_recommendations: true
-    network_optimization: true
-    security_policy_generation: true
-    cost_estimation: true
-
-  cache:
-    enabled: true
-    ttl: 3600
-
-

Database Schema:

-
-- SurrealDB schema for AI suggestions
-DEFINE TABLE ai_suggestions SCHEMAFULL
-DEFINE FIELD timestamp ON ai_suggestions TYPE datetime DEFAULT now();
-DEFINE FIELD context ON ai_suggestions TYPE object;
-DEFINE FIELD suggestion ON ai_suggestions TYPE string;
-DEFINE FIELD confidence ON ai_suggestions TYPE float;
-DEFINE FIELD accepted ON ai_suggestions TYPE bool;
-
-DEFINE TABLE ai_models SCHEMAFULL
-DEFINE FIELD name ON ai_models TYPE string;
-DEFINE FIELD version ON ai_models TYPE string;
-DEFINE FIELD provider ON ai_models TYPE string;
-
-

Endpoints:

-
- - - - - - - -
EndpointMethodPurpose
/healthGETHealth check
/suggest/databasePOSTDatabase recommendations
/suggest/networkPOSTNetwork topology
/suggest/securityPOSTSecurity policies
/estimate/costPOSTCost estimation
/parse/natural-languagePOSTParse natural language
/feedbackPOSTStore suggestion feedback
-
-

typedialog-ag v0.1.0

-

AI Agents - Type-safe agents for automation workflows and Nickel transpilation.

-

Purpose: Define complex automation workflows using type-safe agent descriptions, then transpile to executable Nickel.

-

Architecture:

-
Agent Definition (.agent.yaml)
-    ↓
-typedialog-ag Type Checker
-    ↓
-Agent Execution Plan
-    ↓
-Nickel Transpilation
-    ↓
-Provisioning Execution
-
-

Key Features:

-
    -
  • Type-Safe Agents: Strongly-typed agent definitions
  • -
  • Workflow Automation: Chain multiple infrastructure tasks
  • -
  • Nickel Transpilation: Generate Nickel IaC automatically
  • -
  • Agent Orchestration: Parallel and sequential execution
  • -
  • Rollback Support: Automatic rollback on failure
  • -
-

Installation:

-
# Via provisioning script
-provisioning install ai-tools
-
-# Manual installation
-wget  [https://github.com/typedialog/typedialog-ag/releases/download/v0.1.0/typedialog-ag-<os>-<arch>](https://github.com/typedialog/typedialog-ag/releases/download/v0.1.0/typedialog-ag-<os>-<arch>)
-chmod +x typedialog-ag
-mv typedialog-ag ~/.local/bin/
-
-

Agent Definition Syntax:

-
# provisioning/workflows/deploy-k8s.agent.yaml
-version: "1.0"
-agent: deploy-k8s
-description: "Deploy HA Kubernetes cluster with observability stack"
-
-types:
-  CloudProvider:
-    enum: ["aws", "upcloud", "hetzner"]
-  NodeConfig:
-    cpu: int           # 2..64
-    memory: int        # 4..256 (GB)
-    disk: int          # 10..1000 (GB)
-
-input:
-  provider: CloudProvider
-  name: string         # cluster name
-  nodes: int           # 3..100
-  node_config: NodeConfig
-  enable_monitoring: bool = true
-  enable_backup: bool = true
-
-workflow:
-  - name: validate
-    task: validate_cluster_config
-    args:
-      provider: $input.provider
-      nodes: $input.nodes
-      node_config: $input.node_config
-
-  - name: create_network
-    task: create_vpc
-    depends_on: [validate]
-    args:
-      provider: $input.provider
-      cidr: "10.0.0.0/16"
-
-  - name: create_nodes
-    task: create_nodes
-    depends_on: [create_network]
-    parallel: true
-    args:
-      provider: $input.provider
-      count: $input.nodes
-      config: $input.node_config
-
-  - name: install_kubernetes
-    task: install_kubernetes
-    depends_on: [create_nodes]
-    args:
-      nodes: $create_nodes.output.node_ids
-      version: "1.28.0"
-
-  - name: add_monitoring
-    task: deploy_observability_stack
-    depends_on: [install_kubernetes]
-    when: $input.enable_monitoring
-    args:
-      cluster_name: $input.name
-      storage_class: "ebs"
-
-  - name: setup_backup
-    task: configure_backup
-    depends_on: [install_kubernetes]
-    when: $input.enable_backup
-    args:
-      cluster_name: $input.name
-      backup_interval: "daily"
-
-output:
-  cluster_name: string
-  cluster_id: string
-  kubeconfig_path: string
-  monitoring_url: string
-
-

Usage:

-
# Type-check agent
-typedialog ag check deploy-k8s.agent.yaml
-
-# Run agent interactively
-typedialog ag run deploy-k8s.agent.yaml \
-  --provider upcloud \
-  --name production-k8s \
-  --nodes 5 \
-  --node-config '{"cpu": 8, "memory": 32, "disk": 100}'
-
-# Transpile to Nickel
-typedialog ag transpile deploy-k8s.agent.yaml > deploy-k8s.ncl
-
-# Execute generated Nickel
-provisioning apply deploy-k8s.ncl
-
-

Generated Nickel Output (example):

-
{
-  metadata = {
-    agent = "deploy-k8s"
-    version = "1.0"
-    generated_at = "2026-01-16T01:47:00Z"
-  }
-
-  resources = {
-    network = {
-      provider = "upcloud"
-      vpc = { cidr = "10.0.0.0/16" }
-    }
-
-    compute = {
-      provider = "upcloud"
-      nodes = [
-        { count = 5, cpu = 8, memory = 32, disk = 100 }
-      ]
-    }
-
-    kubernetes = {
-      version = "1.28.0"
-      high_availability = true
-      monitoring = {
-        enabled = true
-        stack = "prometheus-grafana"
-      }
-      backup = {
-        enabled = true
-        interval = "daily"
-      }
-    }
-  }
-}
-
-

Agent Features:

-
- - - - - - -
FeaturePurpose
DependenciesDeclare task ordering (depends_on)
ParallelismRun independent tasks in parallel
ConditionalsExecute tasks based on input conditions
Type SafetyStrong typing on inputs and outputs
RollbackAutomatic rollback on failure
LoggingFull execution trace for debugging
-
-

Integration with Provisioning

-

Using typedialog-ai in Forms

-
# .typedialog/provisioning/form.toml
-[[elements]]
-name = "database_type"
-prompt = "form-database_type-prompt"
-type = "select"
-options = ["postgres", "mysql", "mongodb"]
-
-# Enable AI suggestions
-[elements.ai_suggestions]
-enabled = true
-context = "workload"
-provider = "typedialog-ai"
-endpoint = " [http://localhost:9000/suggest/database"](http://localhost:9000/suggest/database")
-
-

Using typedialog-ag in Workflows

-
# Define agent-based workflow
-provisioning workflow define \
-  --agent deploy-k8s.agent.yaml \
-  --name k8s-deployment \
-  --auto-execute
-
-# Run workflow
-provisioning workflow run k8s-deployment \
-  --provider upcloud \
-  --nodes 5
-
-

Performance

-

typedialog-ai

-
    -
  • Suggestion latency: 500ms-2s per suggestion
  • -
  • Database queries: <100ms (cached)
  • -
  • Concurrent users: 50+
  • -
  • SurrealDB storage: <1GB for 10K suggestions
  • -
-

typedialog-ag

-
    -
  • Type checking: <100ms per agent
  • -
  • Transpilation: <500ms to Nickel
  • -
  • Parallel task execution: O(1) overhead
  • -
  • Agent memory: <50MB per agent
  • -
-

Configuration

-

Enable AI in Provisioning

-
# provisioning/config/config.defaults.toml
-[ai]
-enabled = true
-typedialog_ai = true
-typedialog_ag = true
-
-[ai.typedialog]
-ai_server_url = " [http://localhost:9000"](http://localhost:9000")
-ag_executable = "typedialog-ag"
-
-[ai.form_suggestions]
-enabled = true
-providers = ["database", "network", "security"]
-confidence_threshold = 0.75
-
- - -

AI Service Crate

-

The AI Service crate (provisioning/platform/crates/ai-service/) is the central AI processing -microservice for Provisioning. It coordinates LLM integration, knowledge retrieval, and -infrastructure recommendation generation.

-

Architecture

-

Core Modules

-

The AI Service is organized into specialized modules:

-
- - - - - - - -
ModulePurpose
config.rsConfiguration management and AI service settings
service.rsMain service logic and request handling
mcp.rsModel Context Protocol integration for LLM tools
knowledge.rsKnowledge base management and retrieval
dag.rsDirected Acyclic Graph for workflow orchestration
handlers.rsHTTP endpoint handlers
tool_integration.rsTool registration and execution
-
-

Request Flow

-
User Request (natural language)
-    ↓
-Handlers (HTTP endpoint)
-    ↓
-Intent Recognition (config.rs)
-    ↓
-Knowledge Retrieval (knowledge.rs)
-    ↓
-MCP Tool Selection (mcp.rs)
-    ↓
-LLM Processing (external provider)
-    ↓
-DAG Execution Planning (dag.rs)
-    ↓
-Infrastructure Generation
-    ↓
-Response to User
-
-

Configuration

-

Environment Variables

-
# LLM Configuration
-export PROVISIONING_AI_PROVIDER=openai
-export PROVISIONING_AI_MODEL=gpt-4
-export PROVISIONING_AI_API_KEY=sk-...
-
-# Service Configuration
-export PROVISIONING_AI_PORT=9091
-export PROVISIONING_AI_LOG_LEVEL=info
-export PROVISIONING_AI_TIMEOUT=30
-
-# Knowledge Base
-export PROVISIONING_AI_KNOWLEDGE_PATH=~/.provisioning/knowledge
-export PROVISIONING_AI_CACHE_TTL=3600
-
-# RAG Configuration
-export PROVISIONING_AI_RAG_ENABLED=true
-export PROVISIONING_AI_RAG_SIMILARITY_THRESHOLD=0.75
-
-

Configuration File

-
# provisioning/config/ai-service.toml
-[ai_service]
-port = 9091
-timeout = 30
-max_concurrent_requests = 100
-
-[llm]
-provider = "openai"                 # openai, anthropic, local
-model = "gpt-4"
-api_key = "${PROVISIONING_AI_API_KEY}"
-temperature = 0.7
-max_tokens = 2000
-
-[knowledge]
-enabled = true
-path = "~/.provisioning/knowledge"
-cache_ttl = 3600
-update_interval = 3600
-
-[rag]
-enabled = true
-similarity_threshold = 0.75
-max_results = 5
-embedding_model = "text-embedding-3-small"
-
-[dag]
-max_parallel_tasks = 10
-timeout_per_task = 60
-enable_rollback = true
-
-[security]
-validate_inputs = true
-rate_limit = 1000                   # requests/minute
-audit_logging = true
-
-

HTTP API

-

Endpoints

-

Create Infrastructure Request

-
POST /v1/infrastructure/create
-Content-Type: application/json
-
-{
-  "request": "Create 3 web servers with load balancing",
-  "context": {
-    "workspace": "production",
-    "provider": "upcloud",
-    "environment": "prod"
-  },
-  "options": {
-    "auto_apply": false,
-    "return_nickel": true,
-    "validate": true
-  }
-}
-
-

Response:

-
{
-  "request_id": "req-12345",
-  "status": "success",
-  "infrastructure": {
-    "servers": [
-      {"name": "web-01", "cpu": 4, "memory": 8},
-      {"name": "web-02", "cpu": 4, "memory": 8},
-      {"name": "web-03", "cpu": 4, "memory": 8}
-    ],
-    "load_balancer": {"name": "lb-01", "type": "round-robin"}
-  },
-  "nickel_config": "{ servers = [...] }",
-  "confidence": 0.92,
-  "notes": ["All servers in same availability zone", "Load balancer configured for health checks"]
-}
-
-

Analyze Configuration

-
POST /v1/configuration/analyze
-Content-Type: application/json
-
-{
-  "configuration": "{ name = \"server-01\", cpu = 2, memory = 4 }",
-  "context": {"provider": "upcloud", "environment": "prod"}
-}
-
-

Response:

-
{
-  "analysis": {
-    "resources": {
-      "cpu_score": "low",
-      "memory_score": "minimal",
-      "recommendation": "Increase to cpu=4, memory=8 for production"
-    },
-    "security": {
-      "findings": ["No backup configured", "No monitoring"],
-      "recommendations": ["Enable automated backups", "Deploy monitoring agent"]
-    },
-    "cost": {
-      "estimated_monthly": "$45",
-      "optimization_potential": "20% cost reduction possible"
-    }
-  }
-}
-
-

Generate Policies

-
POST /v1/policies/generate
-Content-Type: application/json
-
-{
-  "requirements": "Allow developers to create servers but not delete, admins full access",
-  "format": "cedar"
-}
-
-

Response:

-
{
-  "policies": [
-    {
-      "effect": "permit",
-      "principal": {"role": "developer"},
-      "action": "CreateServer",
-      "resource": "Server::*"
-    },
-    {
-      "effect": "permit",
-      "principal": {"role": "admin"},
-      "action": ["CreateServer", "DeleteServer", "ModifyServer"],
-      "resource": "Server::*"
-    }
-  ],
-  "format": "cedar",
-  "validation": "valid"
-}
-
-

Get Suggestions

-
GET /v1/suggestions?context=database&workload=transactional&scale=large
-
-

Response:

-
{
-  "suggestions": [
-    {
-      "type": "database",
-      "recommendation": "PostgreSQL 15 with pgvector",
-      "rationale": "Optimal for transactional workload with vector support",
-      "confidence": 0.95,
-      "config": {
-        "engine": "postgres",
-        "version": "15",
-        "extensions": ["pgvector"],
-        "replicas": 3,
-        "backup": "daily"
-      }
-    }
-  ]
-}
-
-

Get Health Status

-
GET /v1/health
-
-

Response:

-
{
-  "status": "healthy",
-  "version": "0.1.0",
-  "llm": {
-    "provider": "openai",
-    "model": "gpt-4",
-    "available": true
-  },
-  "knowledge": {
-    "documents": 1250,
-    "last_update": "2026-01-16T01:00:00Z"
-  },
-  "rag": {
-    "enabled": true,
-    "embeddings": 1250,
-    "search_latency_ms": 45
-  },
-  "uptime_seconds": 86400
-}
-
-

MCP Tool Integration

-

Available Tools

-

The AI Service registers tools with the MCP server for LLM access:

-
// Tools available to LLM
-tools = [
-  "create_infrastructure",
-  "analyze_configuration",
-  "generate_policies",
-  "get_recommendations",
-  "query_knowledge_base",
-  "estimate_costs",
-  "check_compatibility",
-  "validate_nickel"
-]
-

Tool Definitions

-
{
-  "name": "create_infrastructure",
-  "description": "Create infrastructure from natural language description",
-  "parameters": {
-    "type": "object",
-    "properties": {
-      "request": {"type": "string"},
-      "provider": {"type": "string"},
-      "context": {"type": "object"}
-    },
-    "required": ["request"]
-  }
-}
-
-

Knowledge Base

-

Structure

-
knowledge/
-├── infrastructure/         # Infrastructure patterns
-│   ├── kubernetes/
-│   ├── databases/
-│   ├── networking/
-│   └── security/
-├── patterns/               # Design patterns
-│   ├── high-availability/
-│   ├── disaster-recovery/
-│   └── performance/
-├── providers/              # Provider-specific docs
-│   ├── aws/
-│   ├── upcloud/
-│   └── hetzner/
-└── best-practices/         # Best practices
-    ├── security/
-    ├── operations/
-    └── cost-optimization/
-
-

Updating Knowledge

-
# Add new knowledge document
-curl -X POST  [http://localhost:9091/v1/knowledge/add](http://localhost:9091/v1/knowledge/add) \
-  -H "Content-Type: application/json" \
-  -d '{
-    "category": "kubernetes",
-    "title": "HA Kubernetes Setup",
-    "content": "..."
-  }'
-
-# Update embeddings
-curl -X POST  [http://localhost:9091/v1/knowledge/reindex](http://localhost:9091/v1/knowledge/reindex)
-
-# Get knowledge status
-curl  [http://localhost:9091/v1/knowledge/status](http://localhost:9091/v1/knowledge/status)
-
-

DAG Execution

-

Workflow Planning

-

The AI Service uses DAGs to plan complex infrastructure deployments:

-
Validate Config
-    ├→ Create Network
-    │   └→ Create Nodes
-    │       └→ Install Kubernetes
-    │           ├→ Add Monitoring (optional)
-    │           └→ Setup Backup (optional)
-    │
-    └→ Verify Compatibility
-        └→ Estimate Costs
-
-

Task Execution

-
# Execute DAG workflow
-curl -X POST  [http://localhost:9091/v1/workflow/execute](http://localhost:9091/v1/workflow/execute) \
-  -H "Content-Type: application/json" \
-  -d '{
-    "dag": {
-      "tasks": [
-        {"name": "validate", "action": "validate_config"},
-        {"name": "network", "action": "create_network", "depends_on": ["validate"]},
-        {"name": "nodes", "action": "create_nodes", "depends_on": ["network"]}
-      ]
-    }
-  }'
-
-

Performance Characteristics

-

Latency

-
- - - - - - -
OperationLatency
Intent recognition50-100ms
Knowledge retrieval100-200ms
LLM inference2-5 seconds
Nickel generation500ms-1s
DAG planning100-500ms
Policy generation1-2 seconds
-
-

Throughput

-
    -
  • Concurrent requests: 100+
  • -
  • QPS: 50+ requests/second
  • -
  • Knowledge search: <50ms for 1000+ documents
  • -
-

Resource Usage

-
    -
  • Memory: 500MB-2GB (with cache)
  • -
  • CPU: 1-4 cores
  • -
  • Storage: 10GB-50GB (knowledge base)
  • -
  • Network: 10Mbps-100Mbps (LLM requests)
  • -
-

Monitoring & Observability

-

Metrics

-
# Prometheus metrics exposed at /metrics
-provisioning_ai_requests_total{endpoint="/v1/infrastructure/create"}
-provisioning_ai_request_duration_seconds{endpoint="/v1/infrastructure/create"}
-provisioning_ai_llm_tokens{provider="openai", model="gpt-4"}
-provisioning_ai_knowledge_documents_total
-provisioning_ai_cache_hit_ratio
-
-

Logging

-
# View AI Service logs
-provisioning logs service ai-service --tail 100
-
-# Debug mode
-PROVISIONING_AI_LOG_LEVEL=debug provisioning service start ai-service
-
-

Troubleshooting

-

LLM Connection Issues

-
# Test LLM connection
-curl -X POST  [http://localhost:9091/v1/health](http://localhost:9091/v1/health)
-
-# Check configuration
-provisioning config get ai.llm
-
-# View logs
-provisioning logs service ai-service --filter "llm| \ openai"
-
-

Slow Knowledge Retrieval

-
# Check knowledge base status
-curl  [http://localhost:9091/v1/knowledge/status](http://localhost:9091/v1/knowledge/status)
-
-# Reindex embeddings
-curl -X POST  [http://localhost:9091/v1/knowledge/reindex](http://localhost:9091/v1/knowledge/reindex)
-
-# Monitor RAG performance
-curl  [http://localhost:9091/v1/rag/benchmark](http://localhost:9091/v1/rag/benchmark)
-
- - -

RAG & Knowledge Base

-

The RAG (Retrieval Augmented Generation) system enhances AI-generated infrastructure with -domain-specific knowledge. It retrieves relevant documentation, best practices, and patterns to -inform infrastructure recommendations.

-

Architecture

-

Components

-
User Query
-    ↓
-Query Embedder (text-embedding-3-small)
-    ↓
-Vector Similarity Search (SurrealDB)
-    ↓
-Knowledge Retrieval (semantic matching)
-    ↓
-Context Augmentation
-    ↓
-LLM Processing (with knowledge context)
-    ↓
-Infrastructure Recommendation
-
-

Knowledge Flow

-
Documentation Input
-    ↓
-Document Chunking (512 tokens)
-    ↓
-Semantic Embedding
-    ↓
-Vector Storage (SurrealDB)
-    ↓
-Similarity Indexing
-    ↓
-Query Time Retrieval
-
-

Knowledge Base Organization

-

Document Categories

-
- - - - - - -
CategoryPurposeExamples
InfrastructureIaC patterns and templatesKubernetes, databases, networking
Best PracticesOperational guidelinesHA patterns, disaster recovery
Provider GuidesCloud provider documentationAWS, UpCloud, Hetzner specifics
PerformanceOptimization guidelinesResource sizing, caching strategies
SecuritySecurity hardening guidesEncryption, authentication, compliance
TroubleshootingCommon issues and solutionsPerformance, deployment, debugging
-
-

Document Structure

-
id: "doc-k8s-ha-001"
-category: "infrastructure"
-subcategory: "kubernetes"
-title: "High Availability Kubernetes Cluster Setup"
-tags: ["kubernetes", "high-availability", "production"]
-created: "2026-01-10T00:00:00Z"
-updated: "2026-01-16T00:00:00Z"
-
-content: |
-  # High Availability Kubernetes Cluster
-
-  For production Kubernetes deployments, ensure:
-  - Minimum 3 control planes
-  - Distributed across availability zones
-  - etcd with persistent storage
-  - CNI plugin with network policies
-
-embedding: [0.123, 0.456]
-metadata:
-  provider: ["aws", "upcloud", "hetzner"]
-  environment: ["production"]
-  cost_profile: "medium"
-
-

RAG Retrieval Process

- -

When processing a user query, the system:

-
    -
  1. Embed Query: Convert natural language to vector
  2. -
  3. Search Index: Find similar documents (cosine similarity > threshold)
  4. -
  5. Rank Results: Score by relevance
  6. -
  7. Extract Context: Select top N chunks
  8. -
  9. Augment Prompt: Add context to LLM request
  10. -
-

Example:

-
User Query: "Create a Kubernetes cluster in AWS with auto-scaling"
-
-Vector Embedding: [0.234, 0.567, 0.891]
-
-Top Matches:
-1. "HA Kubernetes Setup" (similarity: 0.94)
-2. "AWS Auto-Scaling Patterns" (similarity: 0.87)
-3. "Kubernetes Security Hardening" (similarity: 0.76)
-
-Retrieved Context:
-- Minimum 3 control planes for HA
-- Use AWS ASGs with cluster autoscaler
-- Enable Pod Disruption Budgets
-- Configure network policies
-
-LLM Prompt with Context:
-"Create a Kubernetes cluster with the following context:
-[...retrieved knowledge...]
-User request: Create a Kubernetes cluster in AWS with auto-scaling"
-
-

Configuration

-
[rag]
-enabled = true
-similarity_threshold = 0.75
-max_results = 5
-chunk_size = 512
-chunk_overlap = 50
-
-[embeddings]
-model = "text-embedding-3-small"
-provider = "openai"
-cache_embeddings = true
-
-[vector_store]
-backend = "surrealdb"
-index_type = "hnsw"
-ef_construction = 400
-ef_search = 200
-
-[retrieval]
-bm25_weight = 0.3
-semantic_weight = 0.7
-date_boost = 0.1
-
-

Managing Knowledge

-

Adding Documents

-

Via API:

-
curl -X POST  [http://localhost:9091/v1/knowledge/add](http://localhost:9091/v1/knowledge/add) \
-  -H "Content-Type: application/json" \
-  -d '{
-    "category": "infrastructure",
-    "title": "PostgreSQL HA Setup",
-    "content": "For production PostgreSQL: 3+ replicas, streaming replication",
-    "tags": ["database", "postgresql", "ha"],
-    "metadata": {
-      "provider": ["aws", "upcloud"],
-      "environment": ["production"]
-    }
-  }'
-
-

Batch Import:

-
# Import from markdown files
-provisioning ai knowledge import \
-  --source ./docs/knowledge \
-  --category infrastructure \
-  --auto-tag
-
-# Import from existing documentation
-provisioning ai knowledge import \
-  --source provisioning/docs/src \
-  --recursive
-
-

Organizing Knowledge

-
# List knowledge documents
-provisioning ai knowledge list --category infrastructure
-
-# Search knowledge base
-provisioning ai knowledge search "kubernetes high availability"
-
-# View document
-provisioning ai knowledge view doc-k8s-ha-001
-
-# Update document
-provisioning ai knowledge update doc-k8s-ha-001 \
-  --content "Updated content..." \
-  --tags "kubernetes,ha,production,v1.28"
-
-# Delete document
-provisioning ai knowledge delete doc-k8s-ha-001
-
-

Reindexing

-
# Reindex all documents
-provisioning ai knowledge reindex --all
-
-# Reindex specific category
-provisioning ai knowledge reindex --category infrastructure
-
-# Check indexing status
-provisioning ai knowledge index-status
-
-# Rebuild vector index
-provisioning ai knowledge rebuild-vectors --model text-embedding-3-small
-
-

Knowledge Query API

-

Search Endpoint

-
POST /v1/knowledge/search
-Content-Type: application/json
-
-{
-  "query": "kubernetes cluster setup",
-  "category": "infrastructure",
-  "tags": ["kubernetes"],
-  "limit": 5,
-  "similarity_threshold": 0.75,
-  "metadata_filter": {
-    "provider": ["aws", "upcloud"],
-    "environment": ["production"]
-  }
-}
-
-

Response:

-
{
-  "results": [
-    {
-      "id": "doc-k8s-ha-001",
-      "title": "High Availability Kubernetes Cluster",
-      "category": "infrastructure",
-      "similarity": 0.94,
-      "excerpt": "For production Kubernetes deployments, ensure minimum 3 control planes",
-      "tags": ["kubernetes", "ha", "production"],
-      "metadata": {
-        "provider": ["aws", "upcloud", "hetzner"],
-        "environment": ["production"]
-      }
-    }
-  ],
-  "search_time_ms": 45,
-  "total_matches": 12
-}
-
-

Knowledge Quality

-

Maintenance

-
# Check knowledge quality
-provisioning ai knowledge quality-report
-
-# Remove duplicate documents
-provisioning ai knowledge deduplicate
-
-# Fix broken references
-provisioning ai knowledge validate-refs
-
-# Update outdated docs
-provisioning ai knowledge mark-outdated \
-  --category infrastructure \
-  --older-than 180d
-
-

Metrics

-
# Knowledge base statistics
-curl  [http://localhost:9091/v1/knowledge/stats](http://localhost:9091/v1/knowledge/stats)
-
-

Response:

-
{
-  "total_documents": 1250,
-  "total_chunks": 8432,
-  "categories": {
-    "infrastructure": 450,
-    "security": 200,
-    "best_practices": 300
-  },
-  "embedding_coverage": 0.98,
-  "indexed_chunks": 8256,
-  "vector_index_size_mb": 245,
-  "last_reindex": "2026-01-15T23:00:00Z"
-}
-
- -

RAG uses hybrid search combining semantic and keyword matching:

-
BM25 Score (Keyword Match): 0.7
-Semantic Score (Vector Similarity): 0.92
-
-Hybrid Score = (0.3 × 0.7) + (0.7 × 0.92)
-             = 0.21 + 0.644
-             = 0.854
-
-Relevance: High ✓
-
-

Configuration

-
[hybrid_search]
-bm25_weight = 0.3
-semantic_weight = 0.7
-
-

Performance

-

Retrieval Latency

-
- - - - - -
OperationLatency
Embed query (512 tokens)100-200ms
Vector similarity search20-50ms
BM25 keyword search10-30ms
Hybrid ranking5-10ms
Total retrieval50-100ms
-
-

Vector Index Size

-
    -
  • Documents: 1000 → 8GB storage
  • -
  • Documents: 10000 → 80GB storage
  • -
  • Search latency: Consistent <50ms regardless of size (with HNSW indexing)
  • -
-

Security & Privacy

-

Access Control

-
# Restrict knowledge access
-provisioning ai knowledge acl set doc-k8s-ha-001 \
-  --read "admin,developer" \
-  --write "admin"
-
-# Audit knowledge access
-provisioning ai knowledge audit --document doc-k8s-ha-001
-
-

Data Protection

-
    -
  • Sensitive Info: Automatically redacted from queries (API keys, passwords)
  • -
  • Document Encryption: Optional at-rest encryption
  • -
  • Query Logging: Audit trail for compliance
  • -
-
[security]
-redact_patterns = ["password", "api_key", "secret"]
-encrypt_documents = true
-audit_queries = true
-
- - -

Natural Language Infrastructure

-

Use natural language to describe infrastructure requirements and get automatically generated Nickel configurations and deployment plans.

-

Overview

-

Natural Language Infrastructure (NLI) allows requesting infrastructure changes in plain English:

-
# Instead of writing complex Nickel...
-provisioning ai "Deploy a 3-node HA PostgreSQL cluster with automatic backups in AWS"
-
-# Or interactively...
-provisioning ai interactive
-
-# Interactive mode guides you through requirements
-
-

How It Works

-

Request Processing Pipeline

-
User Natural Language Input
-    ↓
-Intent Recognition
-    ├─ Extract resource type (server, database, cluster)
-    ├─ Identify constraints (HA, region, size)
-    └─ Detect options (monitoring, backup, encryption)
-    ↓
-RAG Knowledge Retrieval
-    ├─ Find similar deployments
-    ├─ Retrieve best practices
-    └─ Get provider-specific guidance
-    ↓
-LLM Inference (GPT-4, Claude 3)
-    ├─ Generate Nickel schema
-    ├─ Calculate resource requirements
-    └─ Create deployment plan
-    ↓
-Configuration Validation
-    ├─ Type checking via Nickel compiler
-    ├─ Schema validation
-    └─ Constraint verification
-    ↓
-Infrastructure Deployment
-    ├─ Dry-run simulation
-    ├─ Cost estimation
-    └─ User confirmation
-    ↓
-Execution & Monitoring
-
-

Command Usage

-

Simple Requests

-
# Web servers with load balancing
-provisioning ai "Create 3 web servers with load balancer"
-
-# Database setup
-provisioning ai "Deploy PostgreSQL with 2 replicas and daily backups"
-
-# Kubernetes cluster
-provisioning ai "Create production Kubernetes cluster with Prometheus monitoring"
-
-

Complex Requests

-
# Multi-cloud deployment
-provisioning ai "
-  Deploy:
-  - 3 HA Kubernetes clusters (AWS, UpCloud, Hetzner)
-  - PostgreSQL 15 with synchronous replication
-  - Redis cluster for caching
-  - ELK stack for logging
-  - Prometheus for monitoring
-  Constraints:
-  - Cross-region high availability
-  - Encrypted inter-region communication
-  - Auto-scaling based on CPU (70%)
-"
-
-# Disaster recovery setup
-provisioning ai "
-  Set up disaster recovery for production environment:
-  - Active-passive failover to secondary region
-  - Daily automated backups (30-day retention)
-  - Monthly DR tests with automated reports
-  - RTO: 4 hours, RPO: 1 hour
-  - Test failover every week
-"
-
-

Interactive Mode

-
# Start interactive mode
-provisioning ai interactive
-
-# System asks clarifying questions:
-# Q: What type of infrastructure? (server, database, cluster, other)
-# Q: Which cloud provider? (aws, upcloud, hetzner, local)
-# Q: Production or development?
-# Q: High availability required?
-# Q: Expected load? (small, medium, large, enterprise)
-# Q: Monitoring and logging?
-# Q: Backup strategy?
-
-# Shows generated configuration for approval
-
-

Example: Web Application Deployment

-

Request

-
provisioning ai "
-  Deploy a production web application:
-  - Frontend: 3 nginx servers with auto-scaling
-  - API: 5 FastAPI instances behind load balancer
-  - Database: HA PostgreSQL with read replicas
-  - Cache: Redis cluster
-  - Monitoring: Prometheus and Grafana
-  - Logs: Elasticsearch + Kibana
-  Environment: AWS
-  Region: us-east-1 (primary), eu-west-1 (DR)
-  Budget: $5000/month max
-"
-
-

Generated Configuration

-

The system generates:

-

1. Nickel Infrastructure Definition:

-
{
-  metadata = {
-    generated_by = "provisioning-ai"
-    timestamp = "2026-01-16T01:47:00Z"
-    confidence = 0.94
-  }
-
-  infrastructure = {
-    frontend = {
-      servers = 3
-      cpu = 4
-      memory = 8
-      type = "t3.large"
-      auto_scaling = {
-        min = 3
-        max = 10
-        target_cpu = 70
-      }
-    }
-
-    api = {
-      servers = 5
-      cpu = 8
-      memory = 16
-      type = "t3.xlarge"
-      load_balancer = {
-        type = "application"
-        health_check = "/health"
-      }
-    }
-
-    database = {
-      type = "postgresql"
-      version = "15"
-      replicas = 2
-      backup = {
-        enabled = true
-        frequency = "daily"
-        retention_days = 30
-      }
-    }
-
-    cache = {
-      type = "redis"
-      nodes = 3
-      cluster_mode = true
-      replication = true
-    }
-
-    monitoring = {
-      prometheus = true
-      grafana = true
-      retention_days = 30
-    }
-
-    logging = {
-      elasticsearch = true
-      kibana = true
-      retention_days = 30
-    }
-  }
-
-  provider = "aws"
-  region_primary = "us-east-1"
-  region_dr = "eu-west-1"
-
-  cost_estimate = {
-    monthly = "$4850"
-    breakdown = {
-      compute = "$2500"
-      database = "$1200"
-      cache = "$600"
-      monitoring = "$400"
-      networking = "$150"
-    }
-  }
-}
-
-

2. Deployment Plan:

-
Deployment Plan: Web Application (Production)
-
-Phase 1: Network & Storage (2-3 hours)
-  - Create VPCs in us-east-1 and eu-west-1
-  - Set up inter-region VPN
-  - Create EBS volumes for database
-  - Create EFS for shared storage
-
-Phase 2: Compute Instances (4-5 hours)
-  - Launch 3 frontend servers
-  - Launch 5 API servers
-  - Create load balancers
-  - Set up auto-scaling groups
-
-Phase 3: Databases (3-4 hours)
-  - Create PostgreSQL primary
-  - Create read replicas
-  - Configure replication
-  - Run initial backup
-
-Phase 4: Cache & Services (2-3 hours)
-  - Create Redis cluster
-  - Deploy Prometheus
-  - Deploy Grafana
-  - Deploy Elasticsearch/Kibana
-
-Phase 5: Configuration (2-3 hours)
-  - Configure health checks
-  - Set up monitoring alerts
-  - Configure log shipping
-  - Deploy TLS certificates
-
-Total Estimated Time: 13-18 hours
-
-

3. Cost Breakdown:

-
Monthly Cost Estimate: $4,850
-
-Compute               $2,500  (EC2 instances)
-Database              $1,200  (RDS PostgreSQL)
-Cache                 $600    (ElastiCache Redis)
-Monitoring            $400    (CloudWatch + Grafana)
-Networking            $150    (NAT Gateway, VPN)
-
-

4. Risk Assessment:

-
Warnings:
-- Budget limit reached at $4,850 (max: $5,000)
-- Cross-region networking latency: 80-100ms
-- Database failover time: 1-2 minutes
-
-Recommendations:
-- Implement connection pooling in API
-- Use read replicas for analytics queries
-- Consider spot instances for non-critical services (30% cost savings)
-
-

Output Formats

-

Get Deployment Script

-
# Get Bash deployment script
-provisioning ai "..." --output bash > deploy.sh
-
-# Get Nushell script
-provisioning ai "..." --output nushell > deploy.nu
-
-# Get Terraform
-provisioning ai "..." --output terraform > main.tf
-
-# Get Nickel (default)
-provisioning ai "..." --output nickel > infrastructure.ncl
-
-

Save for Later

-
# Save configuration for review
-provisioning ai "..." --save deployment-plan --review
-
-# Deploy from saved plan
-provisioning apply deployment-plan
-
-# Compare with current state
-provisioning diff deployment-plan
-
-

Configuration

-

LLM Provider Selection

-
# Use OpenAI (default)
-export PROVISIONING_AI_PROVIDER=openai
-export PROVISIONING_AI_MODEL=gpt-4
-
-# Use Anthropic
-export PROVISIONING_AI_PROVIDER=anthropic
-export PROVISIONING_AI_MODEL=claude-3-opus
-
-# Use local model
-export PROVISIONING_AI_PROVIDER=local
-export PROVISIONING_AI_MODEL=llama2:70b
-
-

Response Options

-
# ~/.config/provisioning/ai.yaml
-natural_language:
-  output_format: nickel              # nickel, terraform, bash, nushell
-  include_cost_estimate: true
-  include_risk_assessment: true
-  include_deployment_plan: true
-  auto_review: false                 # Require approval before deploy
-  dry_run: true                       # Simulate before execution
-  confidence_threshold: 0.85          # Reject low-confidence results
-
-  style:
-    verbosity: detailed
-    include_alternatives: true
-    explain_reasoning: true
-
-

Advanced Features

-

Conditional Infrastructure

-
provisioning ai "
-  Deploy web cluster:
-  - If environment is production: HA setup with 5 nodes
-  - If environment is staging: Standard setup with 2 nodes
-  - If environment is dev: Single node with development tools
-"
-
-

Cost-Optimized Variants

-
# Generate cost-optimized alternative
-provisioning ai "..." --optimize-for cost
-
-# Generate performance-optimized alternative
-provisioning ai "..." --optimize-for performance
-
-# Generate high-availability alternative
-provisioning ai "..." --optimize-for availability
-
-

Template-Based Generation

-
# Use existing templates as base
-provisioning ai "..." --template kubernetes-ha
-
-# List available templates
-provisioning ai templates list
-
-

Safety & Validation

-

Review Before Deploy

-
# Generate and review (no auto-execute)
-provisioning ai "..." --review
-
-# Review generated Nickel
-cat deployment-plan.ncl
-
-# Validate configuration
-provisioning validate deployment-plan.ncl
-
-# Dry-run to see what changes
-provisioning apply --dry-run deployment-plan.ncl
-
-# Apply after approval
-provisioning apply deployment-plan.ncl
-
-

Rollback Support

-
# Create deployment with automatic rollback
-provisioning ai "..." --with-rollback
-
-# Manual rollback if issues
-provisioning workflow rollback --to-checkpoint
-
-# View deployment history
-provisioning history list --type infrastructure
-
-

Limitations

-
    -
  • Context Window: Very large infrastructure descriptions may exceed LLM limits
  • -
  • Ambiguity: Unclear requirements may produce suboptimal configurations
  • -
  • Provider Specifics: Some provider-specific features may require manual adjustment
  • -
  • Cost: API calls incur per-token charges
  • -
  • Latency: Processing takes 2-10 seconds depending on complexity
  • -
- - - -
- - -
-
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - diff --git a/docs/book/resources/logo-text.svg b/docs/book/resources/logo-text.svg deleted file mode 100644 index bef17d6..0000000 --- a/docs/book/resources/logo-text.svg +++ /dev/null @@ -1,149 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/book/resources/provisioning_logo.svg b/docs/book/resources/provisioning_logo.svg deleted file mode 100644 index 024a7df..0000000 --- a/docs/book/resources/provisioning_logo.svg +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/book/searcher.js b/docs/book/searcher.js deleted file mode 100644 index fc65604..0000000 --- a/docs/book/searcher.js +++ /dev/null @@ -1,529 +0,0 @@ -'use strict'; - -/* global Mark, elasticlunr, path_to_root */ - -window.search = window.search || {}; -(function search() { - // Search functionality - // - // You can use !hasFocus() to prevent keyhandling in your key - // event handlers while the user is typing their search. - - if (!Mark || !elasticlunr) { - return; - } - - // eslint-disable-next-line max-len - // IE 11 Compatibility from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith - if (!String.prototype.startsWith) { - String.prototype.startsWith = function(search, pos) { - return this.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search; - }; - } - - const search_wrap = document.getElementById('search-wrapper'), - searchbar = document.getElementById('searchbar'), - searchresults = document.getElementById('searchresults'), - searchresults_outer = document.getElementById('searchresults-outer'), - searchresults_header = document.getElementById('searchresults-header'), - searchicon = document.getElementById('search-toggle'), - content = document.getElementById('content'), - - // SVG text elements don't render if inside a tag. - mark_exclude = ['text'], - marker = new Mark(content), - URL_SEARCH_PARAM = 'search', - URL_MARK_PARAM = 'highlight'; - - let current_searchterm = '', - doc_urls = [], - search_options = { - bool: 'AND', - expand: true, - fields: { - title: {boost: 1}, - body: {boost: 1}, - breadcrumbs: {boost: 0}, - }, - }, - searchindex = null, - results_options = { - teaser_word_count: 30, - limit_results: 30, - }, - teaser_count = 0; - - function hasFocus() { - return searchbar === document.activeElement; - } - - function removeChildren(elem) { - while (elem.firstChild) { - elem.removeChild(elem.firstChild); - } - } - - // Helper to parse a url into its building blocks. - function parseURL(url) { - const a = document.createElement('a'); - a.href = url; - return { - source: url, - protocol: a.protocol.replace(':', ''), - host: a.hostname, - port: a.port, - params: (function() { - const ret = {}; - const seg = a.search.replace(/^\?/, '').split('&'); - for (const part of seg) { - if (!part) { - continue; - } - const s = part.split('='); - ret[s[0]] = s[1]; - } - return ret; - })(), - file: (a.pathname.match(/\/([^/?#]+)$/i) || ['', ''])[1], - hash: a.hash.replace('#', ''), - path: a.pathname.replace(/^([^/])/, '/$1'), - }; - } - - // Helper to recreate a url string from its building blocks. - function renderURL(urlobject) { - let url = urlobject.protocol + '://' + urlobject.host; - if (urlobject.port !== '') { - url += ':' + urlobject.port; - } - url += urlobject.path; - let joiner = '?'; - for (const prop in urlobject.params) { - if (Object.prototype.hasOwnProperty.call(urlobject.params, prop)) { - url += joiner + prop + '=' + urlobject.params[prop]; - joiner = '&'; - } - } - if (urlobject.hash !== '') { - url += '#' + urlobject.hash; - } - return url; - } - - // Helper to escape html special chars for displaying the teasers - const escapeHTML = (function() { - const MAP = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - '\'': ''', - }; - const repl = function(c) { - return MAP[c]; - }; - return function(s) { - return s.replace(/[&<>'"]/g, repl); - }; - })(); - - function formatSearchMetric(count, searchterm) { - if (count === 1) { - return count + ' search result for \'' + searchterm + '\':'; - } else if (count === 0) { - return 'No search results for \'' + searchterm + '\'.'; - } else { - return count + ' search results for \'' + searchterm + '\':'; - } - } - - function formatSearchResult(result, searchterms) { - const teaser = makeTeaser(escapeHTML(result.doc.body), searchterms); - teaser_count++; - - // The ?URL_MARK_PARAM= parameter belongs inbetween the page and the #heading-anchor - const url = doc_urls[result.ref].split('#'); - if (url.length === 1) { // no anchor found - url.push(''); - } - - // encodeURIComponent escapes all chars that could allow an XSS except - // for '. Due to that we also manually replace ' with its url-encoded - // representation (%27). - const encoded_search = encodeURIComponent(searchterms.join(' ')).replace(/'/g, '%27'); - - return '' - + result.doc.breadcrumbs + '' + '' + teaser + ''; - } - - function makeTeaser(body, searchterms) { - // The strategy is as follows: - // First, assign a value to each word in the document: - // Words that correspond to search terms (stemmer aware): 40 - // Normal words: 2 - // First word in a sentence: 8 - // Then use a sliding window with a constant number of words and count the - // sum of the values of the words within the window. Then use the window that got the - // maximum sum. If there are multiple maximas, then get the last one. - // Enclose the terms in . - const stemmed_searchterms = searchterms.map(function(w) { - return elasticlunr.stemmer(w.toLowerCase()); - }); - const searchterm_weight = 40; - const weighted = []; // contains elements of ["word", weight, index_in_document] - // split in sentences, then words - const sentences = body.toLowerCase().split('. '); - let index = 0; - let value = 0; - let searchterm_found = false; - for (const sentenceindex in sentences) { - const words = sentences[sentenceindex].split(' '); - value = 8; - for (const wordindex in words) { - const word = words[wordindex]; - if (word.length > 0) { - for (const searchtermindex in stemmed_searchterms) { - if (elasticlunr.stemmer(word).startsWith( - stemmed_searchterms[searchtermindex]) - ) { - value = searchterm_weight; - searchterm_found = true; - } - } - weighted.push([word, value, index]); - value = 2; - } - index += word.length; - index += 1; // ' ' or '.' if last word in sentence - } - index += 1; // because we split at a two-char boundary '. ' - } - - if (weighted.length === 0) { - return body; - } - - const window_weight = []; - const window_size = Math.min(weighted.length, results_options.teaser_word_count); - - let cur_sum = 0; - for (let wordindex = 0; wordindex < window_size; wordindex++) { - cur_sum += weighted[wordindex][1]; - } - window_weight.push(cur_sum); - for (let wordindex = 0; wordindex < weighted.length - window_size; wordindex++) { - cur_sum -= weighted[wordindex][1]; - cur_sum += weighted[wordindex + window_size][1]; - window_weight.push(cur_sum); - } - - let max_sum_window_index = 0; - if (searchterm_found) { - let max_sum = 0; - // backwards - for (let i = window_weight.length - 1; i >= 0; i--) { - if (window_weight[i] > max_sum) { - max_sum = window_weight[i]; - max_sum_window_index = i; - } - } - } else { - max_sum_window_index = 0; - } - - // add around searchterms - const teaser_split = []; - index = weighted[max_sum_window_index][2]; - for (let i = max_sum_window_index; i < max_sum_window_index + window_size; i++) { - const word = weighted[i]; - if (index < word[2]) { - // missing text from index to start of `word` - teaser_split.push(body.substring(index, word[2])); - index = word[2]; - } - if (word[1] === searchterm_weight) { - teaser_split.push(''); - } - index = word[2] + word[0].length; - teaser_split.push(body.substring(word[2], index)); - if (word[1] === searchterm_weight) { - teaser_split.push(''); - } - } - - return teaser_split.join(''); - } - - function init(config) { - results_options = config.results_options; - search_options = config.search_options; - doc_urls = config.doc_urls; - searchindex = elasticlunr.Index.load(config.index); - - // Set up events - searchicon.addEventListener('click', () => { - searchIconClickHandler(); - }, false); - searchbar.addEventListener('keyup', () => { - searchbarKeyUpHandler(); - }, false); - document.addEventListener('keydown', e => { - globalKeyHandler(e); - }, false); - // If the user uses the browser buttons, do the same as if a reload happened - window.onpopstate = () => { - doSearchOrMarkFromUrl(); - }; - // Suppress "submit" events so the page doesn't reload when the user presses Enter - document.addEventListener('submit', e => { - e.preventDefault(); - }, false); - - // If reloaded, do the search or mark again, depending on the current url parameters - doSearchOrMarkFromUrl(); - - // Exported functions - config.hasFocus = hasFocus; - } - - function unfocusSearchbar() { - // hacky, but just focusing a div only works once - const tmp = document.createElement('input'); - tmp.setAttribute('style', 'position: absolute; opacity: 0;'); - searchicon.appendChild(tmp); - tmp.focus(); - tmp.remove(); - } - - // On reload or browser history backwards/forwards events, parse the url and do search or mark - function doSearchOrMarkFromUrl() { - // Check current URL for search request - const url = parseURL(window.location.href); - if (Object.prototype.hasOwnProperty.call(url.params, URL_SEARCH_PARAM) - && url.params[URL_SEARCH_PARAM] !== '') { - showSearch(true); - searchbar.value = decodeURIComponent( - (url.params[URL_SEARCH_PARAM] + '').replace(/\+/g, '%20')); - searchbarKeyUpHandler(); // -> doSearch() - } else { - showSearch(false); - } - - if (Object.prototype.hasOwnProperty.call(url.params, URL_MARK_PARAM)) { - const words = decodeURIComponent(url.params[URL_MARK_PARAM]).split(' '); - marker.mark(words, { - exclude: mark_exclude, - }); - - const markers = document.querySelectorAll('mark'); - const hide = () => { - for (let i = 0; i < markers.length; i++) { - markers[i].classList.add('fade-out'); - window.setTimeout(() => { - marker.unmark(); - }, 300); - } - }; - - for (let i = 0; i < markers.length; i++) { - markers[i].addEventListener('click', hide); - } - } - } - - // Eventhandler for keyevents on `document` - function globalKeyHandler(e) { - if (e.altKey || - e.ctrlKey || - e.metaKey || - e.shiftKey || - e.target.type === 'textarea' || - e.target.type === 'text' || - !hasFocus() && /^(?:input|select|textarea)$/i.test(e.target.nodeName) - ) { - return; - } - - if (e.key === 'Escape') { - e.preventDefault(); - searchbar.classList.remove('active'); - setSearchUrlParameters('', - searchbar.value.trim() !== '' ? 'push' : 'replace'); - if (hasFocus()) { - unfocusSearchbar(); - } - showSearch(false); - marker.unmark(); - } else if (!hasFocus() && (e.key === 's' || e.key === '/')) { - e.preventDefault(); - showSearch(true); - window.scrollTo(0, 0); - searchbar.select(); - } else if (hasFocus() && (e.key === 'ArrowDown' - || e.key === 'Enter')) { - e.preventDefault(); - const first = searchresults.firstElementChild; - if (first !== null) { - unfocusSearchbar(); - first.classList.add('focus'); - if (e.key === 'Enter') { - window.location.assign(first.querySelector('a')); - } - } - } else if (!hasFocus() && (e.key === 'ArrowDown' - || e.key === 'ArrowUp' - || e.key === 'Enter')) { - // not `:focus` because browser does annoying scrolling - const focused = searchresults.querySelector('li.focus'); - if (!focused) { - return; - } - e.preventDefault(); - if (e.key === 'ArrowDown') { - const next = focused.nextElementSibling; - if (next) { - focused.classList.remove('focus'); - next.classList.add('focus'); - } - } else if (e.key === 'ArrowUp') { - focused.classList.remove('focus'); - const prev = focused.previousElementSibling; - if (prev) { - prev.classList.add('focus'); - } else { - searchbar.select(); - } - } else { // Enter - window.location.assign(focused.querySelector('a')); - } - } - } - - function showSearch(yes) { - if (yes) { - search_wrap.classList.remove('hidden'); - searchicon.setAttribute('aria-expanded', 'true'); - } else { - search_wrap.classList.add('hidden'); - searchicon.setAttribute('aria-expanded', 'false'); - const results = searchresults.children; - for (let i = 0; i < results.length; i++) { - results[i].classList.remove('focus'); - } - } - } - - function showResults(yes) { - if (yes) { - searchresults_outer.classList.remove('hidden'); - } else { - searchresults_outer.classList.add('hidden'); - } - } - - // Eventhandler for search icon - function searchIconClickHandler() { - if (search_wrap.classList.contains('hidden')) { - showSearch(true); - window.scrollTo(0, 0); - searchbar.select(); - } else { - showSearch(false); - } - } - - // Eventhandler for keyevents while the searchbar is focused - function searchbarKeyUpHandler() { - const searchterm = searchbar.value.trim(); - if (searchterm !== '') { - searchbar.classList.add('active'); - doSearch(searchterm); - } else { - searchbar.classList.remove('active'); - showResults(false); - removeChildren(searchresults); - } - - setSearchUrlParameters(searchterm, 'push_if_new_search_else_replace'); - - // Remove marks - marker.unmark(); - } - - // Update current url with ?URL_SEARCH_PARAM= parameter, remove ?URL_MARK_PARAM and - // `#heading-anchor`. `action` can be one of "push", "replace", - // "push_if_new_search_else_replace" and replaces or pushes a new browser history item. - // "push_if_new_search_else_replace" pushes if there is no `?URL_SEARCH_PARAM=abc` yet. - function setSearchUrlParameters(searchterm, action) { - const url = parseURL(window.location.href); - const first_search = !Object.prototype.hasOwnProperty.call(url.params, URL_SEARCH_PARAM); - - if (searchterm !== '' || action === 'push_if_new_search_else_replace') { - url.params[URL_SEARCH_PARAM] = searchterm; - delete url.params[URL_MARK_PARAM]; - url.hash = ''; - } else { - delete url.params[URL_MARK_PARAM]; - delete url.params[URL_SEARCH_PARAM]; - } - // A new search will also add a new history item, so the user can go back - // to the page prior to searching. A updated search term will only replace - // the url. - if (action === 'push' || action === 'push_if_new_search_else_replace' && first_search ) { - history.pushState({}, document.title, renderURL(url)); - } else if (action === 'replace' || - action === 'push_if_new_search_else_replace' && - !first_search - ) { - history.replaceState({}, document.title, renderURL(url)); - } - } - - function doSearch(searchterm) { - // Don't search the same twice - if (current_searchterm === searchterm) { - return; - } else { - current_searchterm = searchterm; - } - - if (searchindex === null) { - return; - } - - // Do the actual search - const results = searchindex.search(searchterm, search_options); - const resultcount = Math.min(results.length, results_options.limit_results); - - // Display search metrics - searchresults_header.innerText = formatSearchMetric(resultcount, searchterm); - - // Clear and insert results - const searchterms = searchterm.split(' '); - removeChildren(searchresults); - for (let i = 0; i < resultcount ; i++) { - const resultElem = document.createElement('li'); - resultElem.innerHTML = formatSearchResult(results[i], searchterms); - searchresults.appendChild(resultElem); - } - - // Display results - showResults(true); - } - - function loadScript(url, id) { - const script = document.createElement('script'); - script.src = url; - script.id = id; - script.onload = () => init(window.search); - script.onerror = error => { - console.error(`Failed to load \`${url}\`: ${error}`); - }; - document.head.append(script); - } - - loadScript(path_to_root + 'searchindex.js', 'search-index'); - -})(window.search); diff --git a/docs/book/searchindex.js b/docs/book/searchindex.js deleted file mode 100644 index 61c96cd..0000000 --- a/docs/book/searchindex.js +++ /dev/null @@ -1 +0,0 @@ -window.search = JSON.parse('{"doc_urls":["index.html#provisioning-platform-documentation","index.html#what-is-provisioning","index.html#key-features","index.html#getting-started","index.html#documentation-structure","index.html#core-technologies","index.html#workspace-first-approach","index.html#support-and-community","index.html#license","getting-started/index.html#getting-started","getting-started/index.html#overview","getting-started/index.html#quick-start-guides","getting-started/index.html#starting-from-scratch","getting-started/index.html#what-youll-learn","getting-started/index.html#prerequisites-checklist","getting-started/index.html#5-minute-quick-start","getting-started/index.html#installation-methods","getting-started/index.html#option-1-binary-recommended","getting-started/index.html#option-2-container","getting-started/index.html#option-3-build-from-source","getting-started/index.html#next-steps-after-installation","getting-started/index.html#common-questions","getting-started/index.html#architecture-overview","getting-started/index.html#whats-next","getting-started/index.html#getting-help","getting-started/index.html#related-documentation","getting-started/prerequisites.html#prerequisites","getting-started/prerequisites.html#required-software","getting-started/prerequisites.html#nushell-01091","getting-started/prerequisites.html#nickel-1151","getting-started/prerequisites.html#sops-3102","getting-started/prerequisites.html#age-121","getting-started/prerequisites.html#k9s-0506","getting-started/prerequisites.html#optional-software","getting-started/prerequisites.html#mdbook","getting-started/prerequisites.html#docker-or-podman","getting-started/prerequisites.html#cargo-rust","getting-started/prerequisites.html#git","getting-started/prerequisites.html#system-requirements","getting-started/prerequisites.html#minimum-hardware","getting-started/prerequisites.html#supported-operating-systems","getting-started/prerequisites.html#network-requirements","getting-started/prerequisites.html#cloud-provider-access","getting-started/prerequisites.html#permission-requirements","getting-started/prerequisites.html#user-permissions","getting-started/prerequisites.html#file-system-permissions","getting-started/prerequisites.html#verification-checklist","getting-started/prerequisites.html#next-steps","getting-started/installation.html#installation","getting-started/installation.html#prerequisites","getting-started/installation.html#installation-steps","getting-started/installation.html#step-1-clone-the-repository","getting-started/installation.html#step-2-add-cli-to-path","getting-started/installation.html#step-3-verify-installation","getting-started/installation.html#step-4-initialize-configuration","getting-started/installation.html#step-5-configure-cloud-provider-credentials","getting-started/installation.html#step-6-encrypt-secrets-recommended","getting-started/installation.html#step-7-validate-configuration","getting-started/installation.html#optional-install-platform-services","getting-started/installation.html#orchestrator-service-rust","getting-started/installation.html#control-center-web-ui","getting-started/installation.html#native-plugins-performance","getting-started/installation.html#workspace-initialization","getting-started/installation.html#troubleshooting","getting-started/installation.html#common-issues","getting-started/installation.html#verification","getting-started/installation.html#next-steps","getting-started/quick-start.html#quick-start","getting-started/quick-start.html#prerequisites","getting-started/quick-start.html#5-minute-deployment","getting-started/quick-start.html#step-1-create-workspace-30-seconds","getting-started/quick-start.html#step-2-define-infrastructure-1-minute","getting-started/quick-start.html#step-3-validate-configuration-30-seconds","getting-started/quick-start.html#step-4-create-infrastructure-2-minutes","getting-started/quick-start.html#step-5-install-task-service-1-minute","getting-started/quick-start.html#step-6-verify-deployment-30-seconds","getting-started/quick-start.html#what-youve-accomplished","getting-started/quick-start.html#common-workflows","getting-started/quick-start.html#list-resources","getting-started/quick-start.html#modify-infrastructure","getting-started/quick-start.html#cleanup","getting-started/quick-start.html#next-steps","getting-started/quick-start.html#deploy-kubernetes","getting-started/quick-start.html#multi-cloud-deployment","getting-started/quick-start.html#use-interactive-guides","getting-started/quick-start.html#troubleshooting-quick-issues","getting-started/quick-start.html#server-creation-fails","getting-started/quick-start.html#task-service-installation-fails","getting-started/quick-start.html#configuration-validation-errors","getting-started/quick-start.html#reference","getting-started/quick-start.html#essential-commands","getting-started/quick-start.html#quick-reference","getting-started/quick-start.html#further-reading","getting-started/first-deployment.html#first-deployment","getting-started/first-deployment.html#overview","getting-started/first-deployment.html#deployment-architecture","getting-started/first-deployment.html#prerequisites","getting-started/first-deployment.html#part-1-workspace-setup","getting-started/first-deployment.html#create-workspace","getting-started/first-deployment.html#configure-workspace","getting-started/first-deployment.html#part-2-infrastructure-definition","getting-started/first-deployment.html#define-nickel-schema","getting-started/first-deployment.html#validate-schema","getting-started/first-deployment.html#part-3-preview-and-validation","getting-started/first-deployment.html#preview-infrastructure","getting-started/first-deployment.html#dependency-graph","getting-started/first-deployment.html#part-4-server-provisioning","getting-started/first-deployment.html#create-servers","getting-started/first-deployment.html#verify-server-access","getting-started/first-deployment.html#part-5-service-installation","getting-started/first-deployment.html#install-task-services","getting-started/first-deployment.html#verify-kubernetes-cluster","getting-started/first-deployment.html#part-6-deployment-verification","getting-started/first-deployment.html#health-checks","getting-started/first-deployment.html#test-application-deployment","getting-started/first-deployment.html#network-policy-test","getting-started/first-deployment.html#part-7-state-management","getting-started/first-deployment.html#view-state","getting-started/first-deployment.html#configuration-backup","getting-started/first-deployment.html#what-youve-learned","getting-started/first-deployment.html#next-steps","getting-started/verification.html#verification","getting-started/verification.html#installation-verification","getting-started/verification.html#cli-and-core-tools","getting-started/verification.html#configuration-validation","getting-started/verification.html#provider-connectivity","getting-started/verification.html#workspace-verification","getting-started/verification.html#workspace-structure","getting-started/verification.html#workspace-configuration","getting-started/verification.html#infrastructure-verification","getting-started/verification.html#server-health","getting-started/verification.html#task-service-health","getting-started/verification.html#cluster-health","getting-started/verification.html#platform-services-verification","getting-started/verification.html#orchestrator-service","getting-started/verification.html#control-center","getting-started/verification.html#native-plugins","getting-started/verification.html#security-verification","getting-started/verification.html#secrets-management","getting-started/verification.html#ssh-keys","getting-started/verification.html#encrypted-configuration","getting-started/verification.html#troubleshooting-common-issues","getting-started/verification.html#cli-not-found","getting-started/verification.html#provider-authentication-fails","getting-started/verification.html#nickel-schema-errors","getting-started/verification.html#server-ssh-fails","getting-started/verification.html#task-service-installation-fails","getting-started/verification.html#health-check-checklist","getting-started/verification.html#performance-verification","getting-started/verification.html#response-times","getting-started/verification.html#resource-usage","getting-started/verification.html#next-steps","setup/index.html#setup--configuration","setup/index.html#overview","setup/index.html#quick-setup","setup/index.html#setup-process-explained","setup/index.html#setup-configuration-guides","setup/index.html#starting-fresh","setup/index.html#setup-profiles","setup/index.html#developer-profile","setup/index.html#production-profile","setup/index.html#custom-profile","setup/index.html#directory-structure-created","setup/index.html#quick-setup-verification","setup/index.html#environment-specific-setup","setup/index.html#for-single-workspace-simple","setup/index.html#for-multiple-workspaces-team","setup/index.html#for-multi-cloud-enterprise","setup/index.html#configuration-hierarchy","setup/index.html#common-setup-tasks","setup/index.html#add-a-cloud-provider","setup/index.html#configure-secrets-storage","setup/index.html#enable-audit-logging","setup/index.html#set-up-multi-tenancy","setup/index.html#setup-validation","setup/index.html#troubleshooting-setup","setup/index.html#next-steps-after-setup","setup/index.html#related-documentation","setup/initial-setup.html#initial-setup","setup/initial-setup.html#overview","setup/initial-setup.html#prerequisites","setup/initial-setup.html#setup-profiles","setup/initial-setup.html#1-developer-profile","setup/initial-setup.html#2-production-profile","setup/initial-setup.html#3-cicd-profile","setup/initial-setup.html#configuration-detection","setup/initial-setup.html#setup-steps","setup/initial-setup.html#step-1-validate-environment","setup/initial-setup.html#step-2-initialize-configuration","setup/initial-setup.html#step-3-configure-providers","setup/initial-setup.html#step-4-configure-security","setup/initial-setup.html#step-5-verify-installation","setup/initial-setup.html#user-configuration","setup/initial-setup.html#environment-variables","setup/initial-setup.html#troubleshooting","setup/initial-setup.html#missing-dependencies","setup/initial-setup.html#permission-errors","setup/initial-setup.html#provider-connection-failed","setup/initial-setup.html#next-steps","setup/workspace-setup.html#workspace-setup","setup/workspace-setup.html#overview","setup/workspace-setup.html#workspace-structure","setup/workspace-setup.html#creating-a-workspace","setup/workspace-setup.html#method-1-from-built-in-template","setup/workspace-setup.html#method-2-from-git-repository","setup/workspace-setup.html#available-templates","setup/workspace-setup.html#switching-workspaces","setup/workspace-setup.html#list-all-workspaces","setup/workspace-setup.html#switch-to-a-workspace","setup/workspace-setup.html#workspace-registry","setup/workspace-setup.html#configuring-workspace","setup/workspace-setup.html#workspace-definition-workspacencl","setup/workspace-setup.html#environment-specific-configuration","setup/workspace-setup.html#workspace-metadata-provisioningyaml","setup/workspace-setup.html#initializing-infrastructure","setup/workspace-setup.html#step-1-create-infrastructure-definition","setup/workspace-setup.html#step-2-validate-configuration","setup/workspace-setup.html#step-3-export-configuration","setup/workspace-setup.html#workspace-security","setup/workspace-setup.html#securing-credentials","setup/workspace-setup.html#git-workflow","setup/workspace-setup.html#multi-workspace-strategies","setup/workspace-setup.html#strategy-1-separate-workspaces-per-environment","setup/workspace-setup.html#strategy-2-single-workspace-multiple-environments","setup/workspace-setup.html#strategy-3-hybrid-approach","setup/workspace-setup.html#workspace-validation","setup/workspace-setup.html#troubleshooting","setup/workspace-setup.html#workspace-not-found","setup/workspace-setup.html#permission-errors","setup/workspace-setup.html#configuration-validation-errors","setup/workspace-setup.html#next-steps","setup/configuration.html#configuration-management","setup/configuration.html#overview","setup/configuration.html#configuration-hierarchy","setup/configuration.html#configuration-sources","setup/configuration.html#1-system-defaults","setup/configuration.html#2-user-configuration","setup/configuration.html#3-workspace-configuration","setup/configuration.html#4-environment-defaults","setup/configuration.html#5-runtime-arguments","setup/configuration.html#provider-configuration","setup/configuration.html#supported-providers","setup/configuration.html#configuring-upcloud","setup/configuration.html#configuring-aws","setup/configuration.html#configuring-hetzner","setup/configuration.html#testing-provider-connectivity","setup/configuration.html#global-configuration-accessors","setup/configuration.html#credential-management","setup/configuration.html#encrypted-credentials","setup/configuration.html#using-environment-variables","setup/configuration.html#kms-integration","setup/configuration.html#configuration-validation","setup/configuration.html#validate-configuration","setup/configuration.html#validate-infrastructure","setup/configuration.html#configuration-merging","setup/configuration.html#working-with-configurations","setup/configuration.html#export-configuration","setup/configuration.html#import-configuration","setup/configuration.html#reset-configuration","setup/configuration.html#environment-variables","setup/configuration.html#best-practices","setup/configuration.html#1-secure-credentials","setup/configuration.html#2-environment-specific-configuration","setup/configuration.html#3-configuration-documentation","setup/configuration.html#4-regular-validation","setup/configuration.html#troubleshooting","setup/configuration.html#configuration-not-loading","setup/configuration.html#provider-connection-failed","setup/configuration.html#environment-variable-conflicts","setup/configuration.html#next-steps","guides/index.html#user-guides","guides/index.html#overview","guides/index.html#getting-started","guides/index.html#im-completely-new-to-provisioning","guides/index.html#i-want-to-organize-infrastructure","guides/index.html#core-workflow-guides","guides/index.html#advanced-operational-guides","guides/index.html#enterprise-features","guides/index.html#quick-navigation","guides/index.html#i-need-to","guides/index.html#guide-structure","guides/index.html#learning-paths","guides/index.html#path-1-im-new-to-provisioning-day-1","guides/index.html#path-2-i-need-production-ready-setup-week-1","guides/index.html#path-3-im-migrating-from-legacy-month-long-project","guides/index.html#path-4-im-building-a-platform-team-project","guides/index.html#related-documentation","guides/from-scratch.html#from-scratch-guide","guides/from-scratch.html#overview","guides/from-scratch.html#phase-1-installation","guides/from-scratch.html#system-prerequisites","guides/from-scratch.html#install-required-tools","guides/from-scratch.html#install-provisioning-platform","guides/from-scratch.html#platform-health-check","guides/from-scratch.html#phase-2-initial-configuration","guides/from-scratch.html#generate-user-configuration","guides/from-scratch.html#configure-encryption","guides/from-scratch.html#provider-credentials","guides/from-scratch.html#validate-configuration","guides/from-scratch.html#phase-3-create-first-workspace","guides/from-scratch.html#initialize-workspace","guides/from-scratch.html#configure-workspace","guides/from-scratch.html#phase-4-define-infrastructure","guides/from-scratch.html#simple-server-configuration","guides/from-scratch.html#validate-infrastructure-schema","guides/from-scratch.html#deploy-infrastructure","guides/from-scratch.html#install-task-service","guides/from-scratch.html#verify-deployment","guides/from-scratch.html#phase-5-kubernetes-cluster-deployment","guides/from-scratch.html#define-kubernetes-infrastructure","guides/from-scratch.html#validate-kubernetes-configuration","guides/from-scratch.html#deploy-kubernetes-cluster","guides/from-scratch.html#access-kubernetes-cluster","guides/from-scratch.html#phase-6-security-configuration","guides/from-scratch.html#enable-audit-logging","guides/from-scratch.html#configure-sops-for-secrets","guides/from-scratch.html#enable-mfa-optional","guides/from-scratch.html#configure-rbac","guides/from-scratch.html#phase-7-multi-cloud-deployment","guides/from-scratch.html#define-multi-cloud-infrastructure","guides/from-scratch.html#deploy-multi-cloud-infrastructure","guides/from-scratch.html#phase-8-monitoring-and-maintenance","guides/from-scratch.html#platform-health-monitoring","guides/from-scratch.html#infrastructure-monitoring","guides/from-scratch.html#backup-configuration","guides/from-scratch.html#phase-9-advanced-workflows","guides/from-scratch.html#custom-workflow-creation","guides/from-scratch.html#execute-custom-workflow","guides/from-scratch.html#troubleshooting","guides/from-scratch.html#common-issues","guides/from-scratch.html#next-steps","guides/from-scratch.html#production-deployment","guides/from-scratch.html#advanced-features","guides/from-scratch.html#learning-resources","guides/from-scratch.html#summary","guides/workspace-management.html#workspace-management","guides/multi-cloud-deployment.html#multi-cloud-deployment","guides/multi-cloud-deployment.html#overview","guides/multi-cloud-deployment.html#multi-cloud-strategies","guides/multi-cloud-deployment.html#strategy-1-primary-backup-architecture","guides/multi-cloud-deployment.html#strategy-2-active-active-architecture","guides/multi-cloud-deployment.html#strategy-3-specialized-workload-distribution","guides/multi-cloud-deployment.html#strategy-4-compliance-driven-architecture","guides/multi-cloud-deployment.html#infrastructure-definition","guides/multi-cloud-deployment.html#multi-provider-server-configuration","guides/multi-cloud-deployment.html#batch-workflow-for-multi-cloud","guides/multi-cloud-deployment.html#deployment-patterns","guides/multi-cloud-deployment.html#pattern-1-sequential-deployment","guides/multi-cloud-deployment.html#pattern-2-parallel-deployment","guides/multi-cloud-deployment.html#pattern-3-blue-green-multi-cloud","guides/multi-cloud-deployment.html#network-configuration","guides/multi-cloud-deployment.html#cross-provider-vpn-mesh","guides/multi-cloud-deployment.html#global-dns-configuration","guides/multi-cloud-deployment.html#data-replication","guides/multi-cloud-deployment.html#database-replication-across-providers","guides/multi-cloud-deployment.html#object-storage-sync","guides/multi-cloud-deployment.html#kubernetes-multi-cloud","guides/multi-cloud-deployment.html#cluster-federation","guides/multi-cloud-deployment.html#multi-cluster-deployments","guides/multi-cloud-deployment.html#cost-optimization","guides/multi-cloud-deployment.html#provider-selection-by-workload","guides/multi-cloud-deployment.html#reserved-instance-strategy","guides/multi-cloud-deployment.html#monitoring-multi-cloud","guides/multi-cloud-deployment.html#centralized-monitoring","guides/multi-cloud-deployment.html#disaster-recovery","guides/multi-cloud-deployment.html#cross-provider-failover","guides/multi-cloud-deployment.html#best-practices","guides/multi-cloud-deployment.html#configuration-management","guides/multi-cloud-deployment.html#security","guides/multi-cloud-deployment.html#deployment","guides/multi-cloud-deployment.html#monitoring","guides/multi-cloud-deployment.html#cost-management","guides/multi-cloud-deployment.html#troubleshooting","guides/multi-cloud-deployment.html#provider-connectivity-issues","guides/multi-cloud-deployment.html#cross-provider-communication-failures","guides/multi-cloud-deployment.html#data-replication-lag","guides/multi-cloud-deployment.html#see-also","guides/custom-extensions.html#custom-extensions","guides/custom-extensions.html#overview","guides/custom-extensions.html#extension-types","guides/custom-extensions.html#providers","guides/custom-extensions.html#task-services","guides/custom-extensions.html#clusters","guides/custom-extensions.html#creating-a-custom-provider","guides/custom-extensions.html#directory-structure","guides/custom-extensions.html#provider-schema-providerncl","guides/custom-extensions.html#server-operations-resourcesservernu","guides/custom-extensions.html#creating-a-custom-task-service","guides/custom-extensions.html#directory-structure-1","guides/custom-extensions.html#service-schema-servicencl","guides/custom-extensions.html#installation-script-installnu","guides/custom-extensions.html#health-check-health-checknu","guides/custom-extensions.html#creating-a-custom-cluster","guides/custom-extensions.html#directory-structure-2","guides/custom-extensions.html#cluster-schema-clusterncl","guides/custom-extensions.html#testing-extensions","guides/custom-extensions.html#local-testing","guides/custom-extensions.html#integration-testing","guides/custom-extensions.html#extension-best-practices","guides/custom-extensions.html#publishing-extensions","guides/custom-extensions.html#extension-registry","guides/custom-extensions.html#private-registry","guides/custom-extensions.html#examples","guides/custom-extensions.html#custom-database-provider","guides/custom-extensions.html#monitoring-stack-service","guides/custom-extensions.html#troubleshooting","guides/custom-extensions.html#extension-not-loading","guides/custom-extensions.html#deployment-failures","guides/custom-extensions.html#references","guides/disaster-recovery.html#disaster-recovery","guides/disaster-recovery.html#overview","guides/disaster-recovery.html#recovery-objectives","guides/disaster-recovery.html#rto-recovery-time-objective","guides/disaster-recovery.html#rpo-recovery-point-objective","guides/disaster-recovery.html#backup-strategy","guides/disaster-recovery.html#automated-backups","guides/disaster-recovery.html#backup-types","guides/disaster-recovery.html#data-replication","guides/disaster-recovery.html#cross-region-replication","guides/disaster-recovery.html#database-replication","guides/disaster-recovery.html#disaster-scenarios","guides/disaster-recovery.html#complete-region-failure","guides/disaster-recovery.html#data-corruption","guides/disaster-recovery.html#platform-service-failure","guides/disaster-recovery.html#failover-procedures","guides/disaster-recovery.html#automated-failover","guides/disaster-recovery.html#manual-failover","guides/disaster-recovery.html#recovery-procedures","guides/disaster-recovery.html#workspace-recovery","guides/disaster-recovery.html#infrastructure-recovery","guides/disaster-recovery.html#platform-recovery","guides/disaster-recovery.html#dr-testing","guides/disaster-recovery.html#test-schedule","guides/disaster-recovery.html#backup-restore-test","guides/disaster-recovery.html#failover-drill","guides/disaster-recovery.html#monitoring-and-alerts","guides/disaster-recovery.html#backup-monitoring","guides/disaster-recovery.html#replication-monitoring","guides/disaster-recovery.html#best-practices","guides/disaster-recovery.html#references","infrastructure/index.html#infrastructure-as-code","infrastructure/index.html#overview","infrastructure/index.html#infrastructure-configuration-guides","infrastructure/index.html#core-configuration","infrastructure/index.html#resources-and-operations","infrastructure/index.html#advanced-topics","infrastructure/index.html#nickel-as-source-of-truth","infrastructure/index.html#configuration-hierarchy","infrastructure/index.html#quick-start-paths","infrastructure/index.html#im-new-to-nickel","infrastructure/index.html#i-need-to-define-infrastructure","infrastructure/index.html#i-want-to-use-awsupcloudhetzner","infrastructure/index.html#i-need-databases-monitoring-logging","infrastructure/index.html#i-want-to-deploy-web-applications","infrastructure/index.html#i-need-multi-cloud-workflows","infrastructure/index.html#i-need-multi-tenant-setup","infrastructure/index.html#example-nickel-configuration","infrastructure/index.html#schema-contracts","infrastructure/index.html#validation-and-testing","infrastructure/index.html#related-documentation","infrastructure/nickel-guide.html#nickel-guide","infrastructure/nickel-guide.html#critical-principle-nickel-is-source-of-truth","infrastructure/nickel-guide.html#why-nickel","infrastructure/nickel-guide.html#installation","infrastructure/nickel-guide.html#core-concepts","infrastructure/nickel-guide.html#records-and-fields","infrastructure/nickel-guide.html#type-annotations","infrastructure/nickel-guide.html#record-merging","infrastructure/nickel-guide.html#contracts-schema-validation","infrastructure/nickel-guide.html#three-file-pattern-provisioning-standard","infrastructure/nickel-guide.html#1-contractsncl---type-definitions","infrastructure/nickel-guide.html#2-defaultsncl---default-values","infrastructure/nickel-guide.html#3-mainncl---entry-point","infrastructure/nickel-guide.html#usage-example","infrastructure/nickel-guide.html#hybrid-interface-pattern","infrastructure/nickel-guide.html#record-merging-strategies","infrastructure/nickel-guide.html#priority-merging-default","infrastructure/nickel-guide.html#recursive-merging","infrastructure/nickel-guide.html#lazy-evaluation","infrastructure/nickel-guide.html#schema-organization","infrastructure/nickel-guide.html#type-system","infrastructure/nickel-guide.html#primitive-types","infrastructure/nickel-guide.html#array-types","infrastructure/nickel-guide.html#enum-types","infrastructure/nickel-guide.html#optional-fields","infrastructure/nickel-guide.html#default-values","infrastructure/nickel-guide.html#validation-patterns","infrastructure/nickel-guide.html#runtime-validation","infrastructure/nickel-guide.html#contract-based-validation","infrastructure/nickel-guide.html#real-world-examples","infrastructure/nickel-guide.html#simple-server-configuration","infrastructure/nickel-guide.html#kubernetes-cluster-configuration","infrastructure/nickel-guide.html#multi-provider-batch-workflow","infrastructure/nickel-guide.html#validation-workflow","infrastructure/nickel-guide.html#type-check-schema","infrastructure/nickel-guide.html#platform-validation","infrastructure/nickel-guide.html#ide-integration","infrastructure/nickel-guide.html#language-server-nickel-lang-lsp","infrastructure/nickel-guide.html#vs-code-configuration","infrastructure/nickel-guide.html#common-patterns","infrastructure/nickel-guide.html#environment-specific-configuration","infrastructure/nickel-guide.html#configuration-composition","infrastructure/nickel-guide.html#migration-from-toml","infrastructure/nickel-guide.html#best-practices","infrastructure/nickel-guide.html#debugging","infrastructure/nickel-guide.html#type-errors","infrastructure/nickel-guide.html#schema-inspection","infrastructure/nickel-guide.html#format-code","infrastructure/nickel-guide.html#next-steps","infrastructure/configuration-system.html#configuration-system","infrastructure/configuration-system.html#configuration-hierarchy","infrastructure/configuration-system.html#configuration-files","infrastructure/configuration-system.html#system-defaults","infrastructure/configuration-system.html#user-configuration","infrastructure/configuration-system.html#workspace-configuration","infrastructure/configuration-system.html#environment-variables","infrastructure/configuration-system.html#configuration-accessors","infrastructure/configuration-system.html#profiles","infrastructure/configuration-system.html#inheritance-and-overrides","infrastructure/configuration-system.html#secrets-management","infrastructure/configuration-system.html#configuration-validation","infrastructure/configuration-system.html#best-practices","infrastructure/configuration-system.html#troubleshooting","infrastructure/configuration-system.html#configuration-not-loading","infrastructure/configuration-system.html#schema-validation-failures","infrastructure/configuration-system.html#environment-variable-issues","infrastructure/configuration-system.html#references","infrastructure/schemas-reference.html#schemas-reference","infrastructure/schemas-reference.html#schema-organization","infrastructure/schemas-reference.html#core-contracts","infrastructure/schemas-reference.html#server-contract","infrastructure/schemas-reference.html#network-contract","infrastructure/schemas-reference.html#storage-contract","infrastructure/schemas-reference.html#workspace-schema","infrastructure/schemas-reference.html#provider-schemas","infrastructure/schemas-reference.html#upcloud-provider","infrastructure/schemas-reference.html#aws-provider","infrastructure/schemas-reference.html#service-schemas","infrastructure/schemas-reference.html#kubernetes-schema","infrastructure/schemas-reference.html#validation-functions","infrastructure/schemas-reference.html#merging-and-composition","infrastructure/schemas-reference.html#contract-enforcement","infrastructure/schemas-reference.html#best-practices","infrastructure/schemas-reference.html#references","infrastructure/providers.html#providers","infrastructure/providers.html#available-providers","infrastructure/providers.html#upcloud-provider","infrastructure/providers.html#aws-provider","infrastructure/providers.html#local-provider","infrastructure/providers.html#multi-cloud-deployments","infrastructure/providers.html#provider-abstraction","infrastructure/providers.html#best-practices","infrastructure/providers.html#references","infrastructure/task-services.html#task-services","infrastructure/task-services.html#categories","infrastructure/task-services.html#kubernetes--container-orchestration","infrastructure/task-services.html#databases","infrastructure/task-services.html#storage","infrastructure/task-services.html#monitoring--observability","infrastructure/task-services.html#networking","infrastructure/task-services.html#security","infrastructure/task-services.html#task-service-definition","infrastructure/task-services.html#using-task-services","infrastructure/task-services.html#installation","infrastructure/task-services.html#cli-commands","infrastructure/task-services.html#custom-task-services","infrastructure/task-services.html#task-service-lifecycle","infrastructure/task-services.html#dependencies","infrastructure/task-services.html#health-checks","infrastructure/task-services.html#best-practices","infrastructure/task-services.html#references","infrastructure/clusters.html#clusters","infrastructure/clusters.html#available-clusters","infrastructure/clusters.html#web-cluster","infrastructure/clusters.html#oci-registry-cluster","infrastructure/clusters.html#kubernetes-cluster","infrastructure/clusters.html#cluster-deployment","infrastructure/clusters.html#cli-commands","infrastructure/clusters.html#deployment-lifecycle","infrastructure/clusters.html#cluster-orchestration","infrastructure/clusters.html#custom-cluster-definitions","infrastructure/clusters.html#cluster-management","infrastructure/clusters.html#scaling","infrastructure/clusters.html#updates","infrastructure/clusters.html#backup-and-recovery","infrastructure/clusters.html#monitoring","infrastructure/clusters.html#best-practices","infrastructure/clusters.html#references","infrastructure/batch-workflows.html#batch-workflows","infrastructure/batch-workflows.html#overview","infrastructure/batch-workflows.html#workflow-definition","infrastructure/batch-workflows.html#dependency-resolution","infrastructure/batch-workflows.html#step-types","infrastructure/batch-workflows.html#provision-steps","infrastructure/batch-workflows.html#task-steps","infrastructure/batch-workflows.html#configure-steps","infrastructure/batch-workflows.html#validate-steps","infrastructure/batch-workflows.html#execution-control","infrastructure/batch-workflows.html#parallel-execution","infrastructure/batch-workflows.html#conditional-execution","infrastructure/batch-workflows.html#retry-logic","infrastructure/batch-workflows.html#checkpoint-and-recovery","infrastructure/batch-workflows.html#checkpointing","infrastructure/batch-workflows.html#recovery","infrastructure/batch-workflows.html#rollback","infrastructure/batch-workflows.html#automatic-rollback","infrastructure/batch-workflows.html#manual-rollback","infrastructure/batch-workflows.html#workflow-management","infrastructure/batch-workflows.html#cli-commands","infrastructure/batch-workflows.html#workflow-state","infrastructure/batch-workflows.html#advanced-features","infrastructure/batch-workflows.html#dynamic-workflows","infrastructure/batch-workflows.html#workflow-templates","infrastructure/batch-workflows.html#notifications","infrastructure/batch-workflows.html#best-practices","infrastructure/batch-workflows.html#troubleshooting","infrastructure/batch-workflows.html#workflow-stuck","infrastructure/batch-workflows.html#step-failures","infrastructure/batch-workflows.html#references","infrastructure/version-management.html#version-management","infrastructure/version-management.html#overview","infrastructure/version-management.html#version-constraints","infrastructure/version-management.html#constraint-operators","infrastructure/version-management.html#version-locking","infrastructure/version-management.html#version-updates","infrastructure/version-management.html#check-for-updates","infrastructure/version-management.html#update-strategies","infrastructure/version-management.html#performing-updates","infrastructure/version-management.html#compatibility-validation","infrastructure/version-management.html#version-resolution","infrastructure/version-management.html#pinning-versions","infrastructure/version-management.html#version-rollback","infrastructure/version-management.html#best-practices","infrastructure/version-management.html#version-metadata","infrastructure/version-management.html#integration-with-cicd","infrastructure/version-management.html#troubleshooting","infrastructure/version-management.html#version-conflicts","infrastructure/version-management.html#update-failures","infrastructure/version-management.html#references","features/index.html#platform-features","features/index.html#overview","features/index.html#feature-guides","features/index.html#organization-and-management","features/index.html#workflow-and-operations","features/index.html#developer-and-automation-features","features/index.html#platform-capabilities","features/index.html#feature-categories","features/index.html#quick-navigation","features/index.html#i-want-to-organize-my-infrastructure","features/index.html#i-want-faster-command-execution","features/index.html#i-want-to-automate-deployment","features/index.html#i-need-to-ensure-security","features/index.html#i-want-to-validate-configurations","features/index.html#i-need-to-extend-capabilities","features/index.html#i-need-to-find-infrastructure-issues","features/index.html#integration-with-platform","features/index.html#related-documentation","features/workspace-management.html#workspace-management","features/workspace-management.html#overview","features/workspace-management.html#why-workspace-first","features/workspace-management.html#workspace-structure","features/workspace-management.html#configuration-hierarchy","features/workspace-management.html#core-commands","features/workspace-management.html#creating-workspaces","features/workspace-management.html#listing-workspaces","features/workspace-management.html#switching-workspaces","features/workspace-management.html#deleting-workspaces","features/workspace-management.html#workspace-registry","features/workspace-management.html#workspace-enforcement","features/workspace-management.html#workspace-templates","features/workspace-management.html#available-templates","features/workspace-management.html#using-templates","features/workspace-management.html#multi-environment-workflows","features/workspace-management.html#strategy-1-separate-workspaces-per-environment","features/workspace-management.html#strategy-2-single-workspace-multiple-environments","features/workspace-management.html#strategy-3-hybrid-approach","features/workspace-management.html#best-practices","features/workspace-management.html#naming-conventions","features/workspace-management.html#configuration-management","features/workspace-management.html#environment-separation","features/workspace-management.html#team-collaboration","features/workspace-management.html#troubleshooting","features/workspace-management.html#no-active-workspace-error","features/workspace-management.html#workspace-not-found","features/workspace-management.html#workspace-path-doesnt-exist","features/workspace-management.html#integration-with-other-features","features/workspace-management.html#batch-workflows","features/workspace-management.html#test-environments","features/workspace-management.html#version-management","features/workspace-management.html#see-also","features/cli-architecture.html#cli-architecture","features/cli-architecture.html#overview","features/cli-architecture.html#key-metrics","features/cli-architecture.html#domain-architecture","features/cli-architecture.html#1-infrastructure-domain","features/cli-architecture.html#2-orchestration-domain","features/cli-architecture.html#3-development-domain","features/cli-architecture.html#4-workspace-domain","features/cli-architecture.html#5-configuration-domain","features/cli-architecture.html#6-utilities-domain","features/cli-architecture.html#7-generation-domain","features/cli-architecture.html#command-shortcuts","features/cli-architecture.html#infrastructure-shortcuts","features/cli-architecture.html#orchestration-shortcuts","features/cli-architecture.html#development-shortcuts","features/cli-architecture.html#configuration-shortcuts","features/cli-architecture.html#utility-shortcuts","features/cli-architecture.html#quick-reference-shortcuts","features/cli-architecture.html#bi-directional-help-system","features/cli-architecture.html#centralized-flag-handling","features/cli-architecture.html#global-flags","features/cli-architecture.html#command-specific-flags","features/cli-architecture.html#command-discovery","features/cli-architecture.html#categorized-help","features/cli-architecture.html#quick-reference","features/cli-architecture.html#interactive-guides","features/cli-architecture.html#command-routing","features/cli-architecture.html#command-implementation-pattern","features/cli-architecture.html#modular-structure","features/cli-architecture.html#internationalization","features/cli-architecture.html#extension-points","features/cli-architecture.html#adding-new-commands","features/cli-architecture.html#adding-new-domains","features/cli-architecture.html#command-aliases","features/cli-architecture.html#best-practices","features/cli-architecture.html#using-shortcuts-effectively","features/cli-architecture.html#dry-run-before-execution","features/cli-architecture.html#using-output-formats","features/cli-architecture.html#performance-optimizations","features/cli-architecture.html#lazy-loading","features/cli-architecture.html#command-caching","features/cli-architecture.html#parallel-execution","features/cli-architecture.html#troubleshooting","features/cli-architecture.html#command-not-found","features/cli-architecture.html#missing-workspace","features/cli-architecture.html#permission-denied","features/cli-architecture.html#see-also","features/configuration-system.html#configuration-system","features/batch-workflows.html#batch-workflows","features/orchestrator.html#orchestrator","features/interactive-guides.html#interactive-guides","features/test-environment.html#test-environment","features/installer.html#platform-installer","features/security-system.html#security-system","features/version-management.html#version-management","features/plugins.html#nushell-plugins","features/plugins.html#overview","features/plugins.html#performance-benefits","features/plugins.html#installation","features/plugins.html#plugin-management","features/plugins.html#core-plugins-priority","features/plugins.html#1-nu_plugin_tera","features/plugins.html#2-nu_plugin_nickel","features/plugins.html#3-nu_plugin_fluent","features/plugins.html#4-nu_plugin_secretumvault","features/plugins.html#performance-plugins","features/plugins.html#5-nu_plugin_orchestrator","features/plugins.html#6-nu_plugin_kms","features/plugins.html#7-nu_plugin_auth","features/plugins.html#utility-plugins","features/plugins.html#8-nu_plugin_hashes","features/plugins.html#9-nu_plugin_highlight","features/plugins.html#10-nu_plugin_image","features/plugins.html#11-nu_plugin_clipboard","features/plugins.html#12-nu_plugin_desktop_notifications","features/plugins.html#13-nu_plugin_qr_maker","features/plugins.html#14-nu_plugin_port_extension","features/plugins.html#legacysecondary-plugins","features/plugins.html#15-nu_plugin_kcl","features/plugins.html#16-api_nu_plugin_kcl","features/plugins.html#17-_nu_plugin_inquire-historical","features/plugins.html#plugin-installation--management","features/plugins.html#installation-methods","features/plugins.html#configuration","features/plugins.html#best-practices","features/plugins.html#use-plugins-when","features/plugins.html#fallback-to-http-api-when","features/plugins.html#troubleshooting","features/plugins.html#plugin-not-loading","features/plugins.html#performance-issues","features/plugins.html#related-documentation","features/multilingual-support.html#multilingual-support","features/multilingual-support.html#supported-languages","features/multilingual-support.html#using-different-languages","features/multilingual-support.html#setting-language-via-environment-variable","features/multilingual-support.html#locale-resolution","features/multilingual-support.html#translation-system-architecture","features/multilingual-support.html#mozilla-fluent-format","features/multilingual-support.html#file-organization","features/multilingual-support.html#help-system-translations","features/multilingual-support.html#categories-covered","features/multilingual-support.html#example-help-output-in-spanish","features/multilingual-support.html#form-translations-typedialog-integration","features/multilingual-support.html#setup-form","features/multilingual-support.html#translated-form-fields","features/multilingual-support.html#supported-forms","features/multilingual-support.html#fallback-chain-configuration","features/multilingual-support.html#adding-new-languages","features/multilingual-support.html#1-add-locale-configuration","features/multilingual-support.html#2-create-locale-directory","features/multilingual-support.html#3-create-translation-files","features/multilingual-support.html#4-translate-strings","features/multilingual-support.html#5-validate-translation","features/multilingual-support.html#6-update-documentation","features/multilingual-support.html#validation--quality-standards","features/multilingual-support.html#translation-quality-rules","features/multilingual-support.html#testing-localization","features/multilingual-support.html#implementation-details","features/multilingual-support.html#typedialog-integration","features/multilingual-support.html#help-system-integration","features/multilingual-support.html#maintenance","features/multilingual-support.html#adding-new-translations","features/multilingual-support.html#updating-existing-translations","features/multilingual-support.html#current-translation-status","features/multilingual-support.html#string-count","features/multilingual-support.html#features-enabled","features/multilingual-support.html#related-documentation","operations/index.html#operations","operations/index.html#overview","operations/index.html#operational-guides","operations/index.html#deployment-and-management","operations/index.html#monitoring-and-observability","operations/index.html#resilience-and-recovery","operations/index.html#troubleshooting","operations/index.html#operational-workflows","operations/index.html#im-deploying-to-production","operations/index.html#i-need-to-monitor-infrastructure","operations/index.html#im-experiencing-an-incident","operations/index.html#i-need-to-backup-and-recover","operations/index.html#i-need-to-optimize-performance","operations/index.html#i-need-help-troubleshooting","operations/index.html#deployment-architecture","operations/index.html#slo-targets","operations/index.html#monitoring-stack","operations/index.html#operational-commands","operations/index.html#related-documentation","operations/deployment-modes.html#deployment-modes","operations/deployment-modes.html#overview","operations/deployment-modes.html#interactive-tui-mode","operations/deployment-modes.html#when-to-use","operations/deployment-modes.html#features","operations/deployment-modes.html#starting-interactive-mode","operations/deployment-modes.html#navigation","operations/deployment-modes.html#headless-cli-mode","operations/deployment-modes.html#when-to-use-1","operations/deployment-modes.html#features-1","operations/deployment-modes.html#command-syntax","operations/deployment-modes.html#example-deployments","operations/deployment-modes.html#unattended-mode","operations/deployment-modes.html#when-to-use-2","operations/deployment-modes.html#requirements","operations/deployment-modes.html#command-syntax-1","operations/deployment-modes.html#example-cicd-integrations","operations/deployment-modes.html#resource-requirements-by-mode","operations/deployment-modes.html#solo-mode","operations/deployment-modes.html#multiuser-mode","operations/deployment-modes.html#cicd-mode","operations/deployment-modes.html#enterprise-mode","operations/deployment-modes.html#choosing-the-right-mode","operations/deployment-modes.html#best-practices","operations/deployment-modes.html#interactive-tui-mode-1","operations/deployment-modes.html#headless-cli-mode-1","operations/deployment-modes.html#unattended-mode-1","operations/deployment-modes.html#related-documentation","operations/service-management.html#service-management","operations/service-management.html#platform-services-overview","operations/service-management.html#service-lifecycle-management","operations/service-management.html#starting-services","operations/service-management.html#stopping-services","operations/service-management.html#restarting-services","operations/service-management.html#checking-service-status","operations/service-management.html#service-configuration","operations/service-management.html#configuration-files","operations/service-management.html#orchestrator-configuration","operations/service-management.html#control-center-configuration","operations/service-management.html#vault-service-configuration","operations/service-management.html#service-dependencies","operations/service-management.html#service-health-monitoring","operations/service-management.html#health-check-endpoints","operations/service-management.html#automated-health-monitoring","operations/service-management.html#log-management","operations/service-management.html#log-locations","operations/service-management.html#log-rotation","operations/service-management.html#log-levels","operations/service-management.html#performance-tuning","operations/service-management.html#orchestrator-performance","operations/service-management.html#database-connection-pooling","operations/service-management.html#memory-limits","operations/service-management.html#service-updates-and-upgrades","operations/service-management.html#zero-downtime-upgrades","operations/service-management.html#version-management","operations/service-management.html#rollback-procedure","operations/service-management.html#security-hardening","operations/service-management.html#service-isolation","operations/service-management.html#network-security","operations/service-management.html#troubleshooting-services","operations/service-management.html#service-wont-start","operations/service-management.html#high-resource-usage","operations/service-management.html#service-crashes","operations/service-management.html#service-metrics","operations/service-management.html#prometheus-integration","operations/service-management.html#grafana-dashboards","operations/service-management.html#best-practices","operations/service-management.html#service-management-1","operations/service-management.html#configuration-management","operations/service-management.html#monitoring-and-alerting","operations/service-management.html#related-documentation","operations/monitoring.html#monitoring","operations/monitoring.html#monitoring-stack-overview","operations/monitoring.html#quick-start","operations/monitoring.html#prometheus-configuration","operations/monitoring.html#service-discovery","operations/monitoring.html#retention-configuration","operations/monitoring.html#key-metrics","operations/monitoring.html#platform-metrics","operations/monitoring.html#system-metrics","operations/monitoring.html#grafana-dashboards","operations/monitoring.html#pre-built-dashboards","operations/monitoring.html#custom-dashboard-creation","operations/monitoring.html#alerting","operations/monitoring.html#alert-rules","operations/monitoring.html#alertmanager-configuration","operations/monitoring.html#log-aggregation-with-loki","operations/monitoring.html#loki-configuration","operations/monitoring.html#promtail-for-log-shipping","operations/monitoring.html#tracing-with-tempo","operations/monitoring.html#distributed-tracing","operations/monitoring.html#performance-monitoring","operations/monitoring.html#query-performance","operations/monitoring.html#resource-monitoring","operations/monitoring.html#custom-metrics","operations/monitoring.html#adding-custom-metrics","operations/monitoring.html#monitoring-best-practices","operations/monitoring.html#related-documentation","operations/backup-recovery.html#backup--recovery","operations/backup-recovery.html#overview","operations/backup-recovery.html#backup-components","operations/backup-recovery.html#critical-data","operations/backup-recovery.html#backup-strategies","operations/backup-recovery.html#full-backup","operations/backup-recovery.html#incremental-backup","operations/backup-recovery.html#continuous-backup","operations/backup-recovery.html#backup-commands","operations/backup-recovery.html#create-backup","operations/backup-recovery.html#list-backups","operations/backup-recovery.html#restore-backup","operations/backup-recovery.html#verify-backup","operations/backup-recovery.html#automated-backup-scheduling","operations/backup-recovery.html#cron-based-backups","operations/backup-recovery.html#systemd-timer-based-backups","operations/backup-recovery.html#backup-destinations","operations/backup-recovery.html#local-filesystem","operations/backup-recovery.html#remote-storage","operations/backup-recovery.html#off-site-backup","operations/backup-recovery.html#database-backup","operations/backup-recovery.html#surrealdb-backup","operations/backup-recovery.html#automated-database-backups","operations/backup-recovery.html#disaster-recovery","operations/backup-recovery.html#recovery-procedures","operations/backup-recovery.html#recovery-time-objectives","operations/backup-recovery.html#point-in-time-recovery","operations/backup-recovery.html#backup-encryption","operations/backup-recovery.html#sops-encryption","operations/backup-recovery.html#age-encryption","operations/backup-recovery.html#backup-retention","operations/backup-recovery.html#retention-policies","operations/backup-recovery.html#backup-monitoring","operations/backup-recovery.html#backup-alerts","operations/backup-recovery.html#backup-metrics","operations/backup-recovery.html#testing-recovery-procedures","operations/backup-recovery.html#regular-dr-drills","operations/backup-recovery.html#best-practices","operations/backup-recovery.html#related-documentation","operations/upgrade.html#upgrading-provisioning","operations/upgrade.html#overview","operations/upgrade.html#before-upgrading","operations/upgrade.html#check-current-version","operations/upgrade.html#backup-configuration","operations/upgrade.html#check-changelog","operations/upgrade.html#verify-system-health","operations/upgrade.html#upgrade-methods","operations/upgrade.html#method-1-in-place-upgrade","operations/upgrade.html#method-2-side-by-side-upgrade","operations/upgrade.html#upgrade-process","operations/upgrade.html#step-1-pre-upgrade-checks","operations/upgrade.html#step-2-backup-data","operations/upgrade.html#step-3-download-new-version","operations/upgrade.html#step-4-run-migration-scripts","operations/upgrade.html#step-5-perform-upgrade","operations/upgrade.html#step-6-verify-upgrade","operations/upgrade.html#breaking-changes","operations/upgrade.html#common-migration-scenarios","operations/upgrade.html#scenario-1-configuration-format-change","operations/upgrade.html#scenario-2-schema-updates","operations/upgrade.html#scenario-3-provider-api-changes","operations/upgrade.html#rollback-procedure","operations/upgrade.html#automatic-rollback","operations/upgrade.html#manual-rollback","operations/upgrade.html#batch-workflow-handling","operations/upgrade.html#troubleshooting-upgrades","operations/upgrade.html#upgrade-hangs","operations/upgrade.html#migration-failure","operations/upgrade.html#service-wont-start","operations/upgrade.html#upgrade-scheduling","operations/upgrade.html#schedule-automated-upgrade","operations/upgrade.html#unattended-upgrade","operations/upgrade.html#version-management","operations/upgrade.html#version-constraints","operations/upgrade.html#vendor-versions","operations/upgrade.html#best-practices","operations/upgrade.html#1-plan-upgrades","operations/upgrade.html#2-backup-everything","operations/upgrade.html#3-test-before-upgrading","operations/upgrade.html#4-monitor-after-upgrade","operations/upgrade.html#5-document-changes","operations/upgrade.html#upgrade-policies","operations/upgrade.html#automatic-updates","operations/upgrade.html#update-channels","operations/upgrade.html#related-documentation","operations/troubleshooting.html#troubleshooting","operations/troubleshooting.html#quick-diagnosis","operations/troubleshooting.html#common-issues","operations/troubleshooting.html#services-wont-start","operations/troubleshooting.html#database-connection-failures","operations/troubleshooting.html#high-resource-usage","operations/troubleshooting.html#workflow-failures","operations/troubleshooting.html#network-connectivity-issues","operations/troubleshooting.html#authentication-failures","operations/troubleshooting.html#debugging-workflows","operations/troubleshooting.html#enable-debug-logging","operations/troubleshooting.html#workflow-state-inspection","operations/troubleshooting.html#manual-workflow-retry","operations/troubleshooting.html#performance-troubleshooting","operations/troubleshooting.html#slow-workflow-execution","operations/troubleshooting.html#database-performance-issues","operations/troubleshooting.html#log-analysis","operations/troubleshooting.html#centralized-log-viewing","operations/troubleshooting.html#structured-log-queries","operations/troubleshooting.html#log-correlation","operations/troubleshooting.html#advanced-debugging","operations/troubleshooting.html#enable-rust-backtrace","operations/troubleshooting.html#core-dump-analysis","operations/troubleshooting.html#network-traffic-analysis","operations/troubleshooting.html#getting-help","operations/troubleshooting.html#collect-diagnostic-information","operations/troubleshooting.html#support-channels","operations/troubleshooting.html#preventive-measures","operations/troubleshooting.html#related-documentation","operations/platform-health.html#platform-health","operations/platform-health.html#health-check-overview","operations/platform-health.html#quick-health-check","operations/platform-health.html#service-health-endpoints","operations/platform-health.html#orchestrator-health","operations/platform-health.html#control-center-health","operations/platform-health.html#vault-service-health","operations/platform-health.html#system-health-checks","operations/platform-health.html#comprehensive-health-check","operations/platform-health.html#health-check-components","operations/platform-health.html#database-health","operations/platform-health.html#filesystem-health","operations/platform-health.html#network-health","operations/platform-health.html#resource-monitoring","operations/platform-health.html#cpu-health","operations/platform-health.html#memory-health","operations/platform-health.html#disk-health","operations/platform-health.html#automated-health-monitoring","operations/platform-health.html#health-check-service","operations/platform-health.html#systemd-health-monitoring","operations/platform-health.html#health-dashboards","operations/platform-health.html#grafana-health-dashboard","operations/platform-health.html#cli-health-dashboard","operations/platform-health.html#health-alerts","operations/platform-health.html#prometheus-alert-rules","operations/platform-health.html#health-check-notifications","operations/platform-health.html#dependency-health","operations/platform-health.html#external-service-health","operations/platform-health.html#third-party-service-monitoring","operations/platform-health.html#health-metrics","operations/platform-health.html#service-metrics","operations/platform-health.html#resource-metrics","operations/platform-health.html#performance-metrics","operations/platform-health.html#health-best-practices","operations/platform-health.html#troubleshooting-unhealthy-state","operations/platform-health.html#related-documentation","security/index.html#security-system","security/index.html#overview","security/index.html#security-architecture","security/index.html#security-layers","security/index.html#layer-1-identity-and-access","security/index.html#layer-2-data-protection","security/index.html#layer-3-network-security","security/index.html#layer-4-compliance-and-monitoring","security/index.html#performance-characteristics","security/index.html#security-standards","security/index.html#component-integration","security/index.html#security-configuration","security/index.html#quick-start","security/index.html#documentation-structure","security/index.html#security-metrics","security/index.html#best-practices","security/index.html#getting-help","security/index.html#security-updates","security/authentication.html#authentication","security/authentication.html#overview","security/authentication.html#architecture","security/authentication.html#authentication-flow","security/authentication.html#components","security/authentication.html#jwt-token-structure","security/authentication.html#access-token","security/authentication.html#refresh-token","security/authentication.html#password-security","security/authentication.html#argon2id-configuration","security/authentication.html#password-requirements","security/authentication.html#session-management","security/authentication.html#session-lifecycle","security/authentication.html#session-storage","security/authentication.html#session-tracking","security/authentication.html#login-flows","security/authentication.html#standard-login","security/authentication.html#mfa-login","security/authentication.html#sso-login","security/authentication.html#token-refresh","security/authentication.html#automatic-refresh","security/authentication.html#manual-refresh","security/authentication.html#multi-provider-authentication","security/authentication.html#supported-providers","security/authentication.html#provider-configuration","security/authentication.html#token-validation","security/authentication.html#jwt-verification","security/authentication.html#token-revocation","security/authentication.html#security-hardening","security/authentication.html#configuration","security/authentication.html#best-practices","security/authentication.html#cli-integration","security/authentication.html#login-and-session-management","security/authentication.html#token-management","security/authentication.html#api-reference","security/authentication.html#endpoints","security/authentication.html#troubleshooting","security/authentication.html#common-issues","security/authentication.html#monitoring","security/authentication.html#metrics","security/authentication.html#alerts","security/authorization.html#authorization","security/mfa.html#multi-factor-authentication","security/audit-logging.html#audit-logging","security/kms-guide.html#kms-guide","security/secrets-management.html#secrets-management","security/secretumvault-guide.html#secretumvault-integration-guide","security/secretumvault-guide.html#overview","security/secretumvault-guide.html#architecture","security/secretumvault-guide.html#integration-points","security/secretumvault-guide.html#cryptographic-stack","security/secretumvault-guide.html#installation","security/secretumvault-guide.html#install-secretumvault","security/secretumvault-guide.html#install-nushell-plugin","security/secretumvault-guide.html#configuration","security/secretumvault-guide.html#environment-setup","security/secretumvault-guide.html#configuration-file","security/secretumvault-guide.html#usage","security/secretumvault-guide.html#command-line-interface","security/secretumvault-guide.html#nushell-integration","security/secretumvault-guide.html#provisioning-integration","security/secretumvault-guide.html#post-quantum-cryptography","security/secretumvault-guide.html#algorithms-supported","security/secretumvault-guide.html#hybrid-mode-recommended","security/secretumvault-guide.html#key-rotation-strategy","security/secretumvault-guide.html#security-features","security/secretumvault-guide.html#authentication","security/secretumvault-guide.html#access-control","security/secretumvault-guide.html#audit-logging","security/secretumvault-guide.html#disaster-recovery","security/secretumvault-guide.html#backup-procedures","security/secretumvault-guide.html#recovery-key","security/secretumvault-guide.html#performance","security/secretumvault-guide.html#benchmark-results","security/secretumvault-guide.html#hardware-acceleration","security/secretumvault-guide.html#troubleshooting","security/secretumvault-guide.html#cannot-initialize-vault","security/secretumvault-guide.html#slow-performance","security/secretumvault-guide.html#master-key-lost","security/secretumvault-guide.html#compliance--standards","security/secretumvault-guide.html#certifications","security/secretumvault-guide.html#export-controls","security/secretumvault-guide.html#related-documentation","security/encryption.html#encryption","security/secure-communication.html#secure-communication","security/certificate-management.html#certificate-management","security/compliance.html#compliance","security/security-testing.html#security-testing","development/index.html#development","development/index.html#overview","development/index.html#development-guides","development/index.html#extension-development","development/index.html#platform-internals","development/index.html#integration-and-apis","development/index.html#community","development/index.html#quick-start-paths","development/index.html#i-want-to-build-a-custom-provider","development/index.html#i-want-to-create-custom-detectors","development/index.html#i-want-to-extend-with-nushell","development/index.html#i-want-to-understand-system-performance","development/index.html#i-want-to-integrate-external-systems","development/index.html#technology-stack","development/index.html#development-environment","development/index.html#navigation","development/extension-development.html#extension-development","development/extension-development.html#extension-overview","development/extension-development.html#extension-structure","development/extension-development.html#extension-metadata","development/extension-development.html#creating-a-provider-extension","development/extension-development.html#provider-structure","development/extension-development.html#provider-schema-nickel","development/extension-development.html#provider-implementation-nushell","development/extension-development.html#provider-interface-contract","development/extension-development.html#creating-a-task-service-extension","development/extension-development.html#task-service-structure","development/extension-development.html#task-service-metadata","development/extension-development.html#task-service-installation-script","development/extension-development.html#creating-a-cluster-extension","development/extension-development.html#cluster-schema","development/extension-development.html#cluster-definition-example","development/extension-development.html#extension-testing","development/extension-development.html#test-structure","development/extension-development.html#extension-packaging","development/extension-development.html#oci-registry-publishing","development/extension-development.html#extension-installation","development/extension-development.html#best-practices","development/extension-development.html#related-documentation","development/provider-development.html#provider-development","development/provider-development.html#provider-architecture","development/provider-development.html#provider-interface","development/provider-development.html#provider-template","development/provider-development.html#provider-schema-nickel","development/provider-development.html#implementing-server-creation","development/provider-development.html#provider-testing","development/provider-development.html#error-handling","development/provider-development.html#provider-best-practices","development/provider-development.html#related-documentation","development/plugin-development.html#plugin-development","development/plugin-development.html#plugin-overview","development/plugin-development.html#available-plugins","development/plugin-development.html#plugin-architecture","development/plugin-development.html#creating-a-plugin","development/plugin-development.html#plugin-template","development/plugin-development.html#plugin-implementation","development/plugin-development.html#building-plugin","development/plugin-development.html#plugin-performance-optimization","development/plugin-development.html#benchmarking","development/plugin-development.html#caching","development/plugin-development.html#testing-plugins","development/plugin-development.html#unit-tests","development/plugin-development.html#integration-tests","development/plugin-development.html#plugin-best-practices","development/plugin-development.html#related-documentation","development/api-guide.html#api-integration-guide","development/api-guide.html#api-client-development","development/api-guide.html#webhook-integration","development/api-guide.html#error-handling","development/api-guide.html#related-documentation","development/build-system.html#build-system","development/build-system.html#build-tools","development/build-system.html#building-platform-services","development/build-system.html#build-all-services","development/build-system.html#build-individual-service","development/build-system.html#testing","development/build-system.html#run-all-tests","development/build-system.html#test-specific-component","development/build-system.html#security-tests","development/build-system.html#code-quality","development/build-system.html#formatting","development/build-system.html#linting","development/build-system.html#nickel-validation","development/build-system.html#continuous-integration","development/build-system.html#github-actions-pipeline","development/build-system.html#packaging-and-distribution","development/build-system.html#create-release-package","development/build-system.html#package-structure","development/build-system.html#cross-platform-builds","development/build-system.html#supported-targets","development/build-system.html#cross-compilation-setup","development/build-system.html#just-task-runner","development/build-system.html#performance-optimization","development/build-system.html#release-builds","development/build-system.html#build-time-optimization","development/build-system.html#development-workflow","development/build-system.html#recommended-workflow","development/build-system.html#hot-reload-development","development/build-system.html#debugging-builds","development/build-system.html#debug-information","development/build-system.html#build-verbosity","development/build-system.html#dependency-tree","development/build-system.html#best-practices","development/build-system.html#troubleshooting","development/build-system.html#common-build-issues","development/build-system.html#related-documentation","development/testing.html#testing","development/testing.html#testing-overview","development/testing.html#running-tests","development/testing.html#all-tests","development/testing.html#test-by-category","development/testing.html#test-specific-component","development/testing.html#unit-testing","development/testing.html#rust-unit-tests","development/testing.html#nushell-unit-tests","development/testing.html#integration-testing","development/testing.html#service-integration-tests","development/testing.html#test-containers","development/testing.html#security-testing","development/testing.html#authentication-tests","development/testing.html#authorization-tests","development/testing.html#encryption-tests","development/testing.html#end-to-end-testing","development/testing.html#full-workflow-tests","development/testing.html#test-fixtures","development/testing.html#common-test-fixtures","development/testing.html#mocking","development/testing.html#mock-external-services","development/testing.html#test-coverage","development/testing.html#generate-coverage-report","development/testing.html#coverage-goals","development/testing.html#performance-testing","development/testing.html#benchmark-tests","development/testing.html#test-best-practices","development/testing.html#continuous-testing","development/testing.html#watch-mode","development/testing.html#pre-commit-testing","development/testing.html#related-documentation","development/contributing.html#contributing","development/contributing.html#getting-started","development/contributing.html#prerequisites","development/contributing.html#development-workflow","development/contributing.html#code-style-guidelines","development/contributing.html#rust-code","development/contributing.html#nushell-scripts","development/contributing.html#nickel-schemas","development/contributing.html#testing-requirements","development/contributing.html#required-tests","development/contributing.html#running-tests","development/contributing.html#test-coverage-requirements","development/contributing.html#documentation","development/contributing.html#required-documentation","development/contributing.html#documentation-standards","development/contributing.html#commit-message-format","development/contributing.html#pull-request-process","development/contributing.html#before-creating-pr","development/contributing.html#pr-description-template","development/contributing.html#code-review","development/contributing.html#development-best-practices","development/contributing.html#code-quality","development/contributing.html#error-handling","development/contributing.html#performance","development/contributing.html#security","development/contributing.html#getting-help","development/contributing.html#recognition","api-reference/index.html#api-reference","api-reference/index.html#available-apis","api-reference/index.html#rest-api","api-reference/index.html#command-line-interface","api-reference/index.html#nushell-libraries","api-reference/index.html#api-categories","api-reference/index.html#infrastructure-management","api-reference/index.html#service-orchestration","api-reference/index.html#workflow-automation","api-reference/index.html#configuration-management","api-reference/index.html#security--authentication","api-reference/index.html#platform-services","api-reference/index.html#api-conventions","api-reference/index.html#rest-api-standards","api-reference/index.html#cli-command-patterns","api-reference/index.html#library-function-signatures","api-reference/index.html#api-versioning","api-reference/index.html#rate-limiting","api-reference/index.html#authentication","api-reference/index.html#api-discovery","api-reference/index.html#next-steps","api-reference/index.html#related-documentation","api-reference/rest-api.html#rest-api-reference","api-reference/rest-api.html#base-url","api-reference/rest-api.html#authentication","api-reference/rest-api.html#common-response-format","api-reference/rest-api.html#http-status-codes","api-reference/rest-api.html#api-services","api-reference/rest-api.html#orchestrator-api","api-reference/rest-api.html#submit-workflow","api-reference/rest-api.html#get-workflow-status","api-reference/rest-api.html#list-workflows","api-reference/rest-api.html#cancel-workflow","api-reference/rest-api.html#get-task-logs","api-reference/rest-api.html#resume-workflow","api-reference/rest-api.html#control-center-api","api-reference/rest-api.html#list-services","api-reference/rest-api.html#get-service-health","api-reference/rest-api.html#start-service","api-reference/rest-api.html#stop-service","api-reference/rest-api.html#restart-service","api-reference/rest-api.html#get-service-configuration","api-reference/rest-api.html#update-service-configuration","api-reference/rest-api.html#get-platform-metrics","api-reference/rest-api.html#extension-registry-api","api-reference/rest-api.html#list-extensions","api-reference/rest-api.html#get-extension-details","api-reference/rest-api.html#download-extension","api-reference/rest-api.html#publish-extension","api-reference/rest-api.html#auth-service-api","api-reference/rest-api.html#login","api-reference/rest-api.html#mfa-challenge","api-reference/rest-api.html#mfa-verify","api-reference/rest-api.html#refresh-token","api-reference/rest-api.html#logout","api-reference/rest-api.html#create-user","api-reference/rest-api.html#list-users","api-reference/rest-api.html#vault-service-api","api-reference/rest-api.html#store-secret","api-reference/rest-api.html#retrieve-secret","api-reference/rest-api.html#list-secrets","api-reference/rest-api.html#delete-secret","api-reference/rest-api.html#generate-dynamic-credentials","api-reference/rest-api.html#kms-service-api","api-reference/rest-api.html#encrypt-data","api-reference/rest-api.html#decrypt-data","api-reference/rest-api.html#create-key","api-reference/rest-api.html#list-keys","api-reference/rest-api.html#rotate-key","api-reference/rest-api.html#audit-service-api","api-reference/rest-api.html#query-audit-logs","api-reference/rest-api.html#export-audit-logs","api-reference/rest-api.html#get-compliance-report","api-reference/rest-api.html#policy-service-api","api-reference/rest-api.html#evaluate-policy","api-reference/rest-api.html#create-policy","api-reference/rest-api.html#list-policies","api-reference/rest-api.html#update-policy","api-reference/rest-api.html#delete-policy","api-reference/rest-api.html#gateway-service-api","api-reference/rest-api.html#get-route-configuration","api-reference/rest-api.html#update-routes","api-reference/rest-api.html#get-rate-limits","api-reference/rest-api.html#error-codes","api-reference/rest-api.html#rate-limiting-headers","api-reference/rest-api.html#pagination","api-reference/rest-api.html#webhooks","api-reference/rest-api.html#related-documentation","api-reference/cli-commands.html#cli-commands-reference","api-reference/cli-commands.html#command-structure","api-reference/cli-commands.html#quick-reference","api-reference/cli-commands.html#domain-modules","api-reference/cli-commands.html#infrastructure-commands","api-reference/cli-commands.html#server-commands","api-reference/cli-commands.html#provider-commands","api-reference/cli-commands.html#orchestration-commands","api-reference/cli-commands.html#workflow-commands","api-reference/cli-commands.html#batch-commands","api-reference/cli-commands.html#configuration-commands","api-reference/cli-commands.html#workspace-commands","api-reference/cli-commands.html#development-commands","api-reference/cli-commands.html#utility-commands","api-reference/cli-commands.html#generation-commands","api-reference/cli-commands.html#authentication-commands","api-reference/cli-commands.html#security-commands","api-reference/cli-commands.html#vault-commands","api-reference/cli-commands.html#kms-commands","api-reference/cli-commands.html#audit-commands","api-reference/cli-commands.html#policy-commands","api-reference/cli-commands.html#platform-commands","api-reference/cli-commands.html#guides-commands","api-reference/cli-commands.html#task-service-commands","api-reference/cli-commands.html#cluster-commands","api-reference/cli-commands.html#test-commands","api-reference/cli-commands.html#environment-variables","api-reference/cli-commands.html#exit-codes","api-reference/cli-commands.html#shell-completion","api-reference/cli-commands.html#related-documentation","api-reference/nushell-libraries.html#nushell-libraries","api-reference/orchestrator-api.html#orchestrator-api","api-reference/control-center-api.html#control-center-api","api-reference/examples.html#examples","architecture/index.html#architecture","architecture/index.html#overview","architecture/index.html#architecture-documentation","architecture/index.html#system-understanding","architecture/index.html#architectural-decisions","architecture/index.html#key-architectural-patterns","architecture/index.html#modular-design-adr-001","architecture/index.html#workspace-first-organization-adr-002","architecture/index.html#type-safe-configuration-adr-003","architecture/index.html#distributed-microservices-adr-004","architecture/index.html#security-architecture-adr-006--adr-007","architecture/index.html#observability--resilience-adr-008-adr-009-adr-010","architecture/index.html#navigation","architecture/system-overview.html#system-overview","architecture/system-overview.html#architecture-layers","architecture/system-overview.html#core-system-components","architecture/system-overview.html#1-cli-layer-provisioningcorecli","architecture/system-overview.html#2-core-engine-provisioningcorenulib","architecture/system-overview.html#3-orchestration-engine-provisioningplatform","architecture/system-overview.html#4-extensions-provisioningextensions","architecture/system-overview.html#5-infrastructure-layer","architecture/system-overview.html#configuration-system","architecture/system-overview.html#state-management","architecture/system-overview.html#security-architecture","architecture/system-overview.html#performance-characteristics","architecture/system-overview.html#deployment-modes","architecture/system-overview.html#technology-stack","architecture/system-overview.html#file-organization","architecture/system-overview.html#component-interaction","architecture/system-overview.html#scalability","architecture/system-overview.html#integration-points","architecture/system-overview.html#reliability-features","architecture/system-overview.html#related-documentation","architecture/design-principles.html#design-principles","architecture/design-principles.html#1-workspace-first-design","architecture/design-principles.html#2-type-safety-mandatory","architecture/design-principles.html#3-configuration-driven-never-hardcoded","architecture/design-principles.html#4-multi-cloud-abstraction","architecture/design-principles.html#5-modular-extensible-architecture","architecture/design-principles.html#6-hybrid-rust--nushell","architecture/design-principles.html#7-state-management-via-graph-database","architecture/design-principles.html#8-security-first-design","architecture/design-principles.html#9-progressive-disclosure","architecture/design-principles.html#10-fail-fast-recover-gracefully","architecture/design-principles.html#11-observable--auditable","architecture/design-principles.html#12-no-shortcuts-on-reliability","architecture/design-principles.html#architectural-decision-records-adrs","architecture/design-principles.html#design-trade-offs","architecture/design-principles.html#related-documentation","architecture/component-architecture.html#component-architecture","architecture/component-architecture.html#core-components-map","architecture/component-architecture.html#1-cli-layer","architecture/component-architecture.html#main-entry-point-provisioning","architecture/component-architecture.html#command-dispatcher","architecture/component-architecture.html#2-core-engine-components","architecture/component-architecture.html#configuration-management","architecture/component-architecture.html#provider-abstraction","architecture/component-architecture.html#workspace-management","architecture/component-architecture.html#infrastructure-validation","architecture/component-architecture.html#secrets-management","architecture/component-architecture.html#3-platform-services","architecture/component-architecture.html#orchestrator","architecture/component-architecture.html#control-center","architecture/component-architecture.html#control-center-ui","architecture/component-architecture.html#mcp-server","architecture/component-architecture.html#vault-service","architecture/component-architecture.html#extension-registry","architecture/component-architecture.html#ai-service","architecture/component-architecture.html#detector","architecture/component-architecture.html#rag-service","architecture/component-architecture.html#provisioning-daemon","architecture/component-architecture.html#platform-config","architecture/component-architecture.html#service-clients","architecture/component-architecture.html#4-extension-components","architecture/component-architecture.html#providers","architecture/component-architecture.html#task-services","architecture/component-architecture.html#clusters","architecture/component-architecture.html#5-configuration-layer","architecture/component-architecture.html#nickel-schemas","architecture/component-architecture.html#component-dependencies","architecture/component-architecture.html#communication-patterns","architecture/component-architecture.html#synchronous-request-response","architecture/component-architecture.html#asynchronous-queue","architecture/component-architecture.html#event-driven","architecture/component-architecture.html#related-documentation","architecture/integration-patterns.html#integration-patterns","architecture/integration-patterns.html#1-provider-integration-pattern","architecture/integration-patterns.html#2-task-service-integration-pattern","architecture/integration-patterns.html#3-cluster-template-pattern","architecture/integration-patterns.html#4-batch-workflow-pattern","architecture/integration-patterns.html#5-custom-extension-pattern","architecture/integration-patterns.html#6-authorization-policy-pattern","architecture/integration-patterns.html#7-webhook-integration","architecture/integration-patterns.html#8-monitoring-integration","architecture/integration-patterns.html#9-cicd-integration","architecture/integration-patterns.html#10-mcp-tool-integration","architecture/integration-patterns.html#integration-scenarios","architecture/integration-patterns.html#multi-cloud-deployment","architecture/integration-patterns.html#gitops-workflow","architecture/integration-patterns.html#self-service-deployment","architecture/integration-patterns.html#best-practices","architecture/integration-patterns.html#related-documentation","architecture/adr/index.html#architecture-decision-records","architecture/adr/index.html#adr-index","architecture/adr/index.html#core-architecture-decisions","architecture/adr/index.html#security-and-cryptography","architecture/adr/index.html#operations-and-observability","architecture/adr/index.html#decision-format","architecture/adr/index.html#rationale-for-adrs","architecture/adr/index.html#cross-references","examples/index.html#examples","examples/index.html#overview","examples/index.html#quick-start-examples","examples/index.html#basic-infrastructure-setup","examples/index.html#multi-cloud-deployments","examples/index.html#operational-examples","examples/index.html#advanced-patterns","examples/index.html#security-and-compliance","examples/index.html#cloud-provider-specific","examples/index.html#configuration-and-migration","examples/index.html#example-organization","examples/index.html#learning-paths","examples/index.html#im-new-to-provisioning","examples/index.html#i-need-multi-cloud-infrastructure","examples/index.html#i-need-to-migrate-existing-infrastructure","examples/index.html#i-need-enterprise-features","examples/index.html#copy-and-customize","examples/index.html#related-documentation","examples/basic-setup.html#basic-setup","examples/basic-setup.html#single-server-deployment","examples/basic-setup.html#three-tier-application","examples/basic-setup.html#development-environment","examples/basic-setup.html#references","examples/multi-cloud.html#multi-cloud-examples","examples/multi-cloud.html#primary-backup-configuration","examples/multi-cloud.html#geographic-distribution","examples/multi-cloud.html#references","examples/kubernetes-deployment.html#kubernetes-deployment-examples","examples/kubernetes-deployment.html#basic-kubernetes-cluster","examples/kubernetes-deployment.html#production-cluster-with-storage","examples/kubernetes-deployment.html#references","examples/custom-workflows.html#custom-workflow-examples","examples/custom-workflows.html#multi-stage-deployment","examples/custom-workflows.html#parallel-regional-deployment","examples/custom-workflows.html#references","examples/security-examples.html#security-configuration-examples","examples/security-examples.html#complete-security-configuration","examples/security-examples.html#secretumvault-integration","examples/security-examples.html#encrypted-infrastructure-configuration","examples/security-examples.html#references","troubleshooting/index.html#troubleshooting","troubleshooting/index.html#overview","troubleshooting/index.html#troubleshooting-guides","troubleshooting/index.html#quick-problem-solving","troubleshooting/index.html#component-specific-troubleshooting","troubleshooting/index.html#infrastructure-and-configuration","troubleshooting/index.html#problem-diagnosis-flowchart","troubleshooting/index.html#quick-reference-common-problems","troubleshooting/index.html#debugging-workflow","troubleshooting/index.html#enable-diagnostic-logging","troubleshooting/index.html#common-error-codes","troubleshooting/index.html#escalation-paths","troubleshooting/index.html#community-support","troubleshooting/index.html#professional-support","troubleshooting/index.html#emergency-issues-security-data-loss","troubleshooting/index.html#support-resources","troubleshooting/index.html#related-documentation","troubleshooting/common-issues.html#common-issues","troubleshooting/debug-guide.html#debug-guide","troubleshooting/logs-analysis.html#logs-analysis","troubleshooting/getting-help.html#getting-help","ai/index.html#ai--machine-learning","ai/index.html#overview","ai/index.html#key-capabilities","ai/index.html#natural-language-infrastructure","ai/index.html#intelligent-configuration","ai/index.html#anomaly-detection","ai/index.html#components-at-a-glance","ai/index.html#quick-start","ai/index.html#enable-ai-features","ai/index.html#use-natural-language","ai/index.html#architecture","ai/index.html#topics","ai/index.html#configuration","ai/index.html#environment-variables","ai/index.html#configuration-file","ai/index.html#use-cases","ai/index.html#1-infrastructure-from-description","ai/index.html#2-configuration-assistance","ai/index.html#3-troubleshooting","ai/index.html#4-anomaly-detection","ai/index.html#limitations","ai/index.html#configuration-files","ai/index.html#performance","ai/index.html#typical-latencies","ai/index.html#scalability","ai/index.html#security","ai/index.html#api-keys","ai/index.html#data-privacy","ai/index.html#related-documentation","ai/ai-architecture.html#ai-architecture","ai/ai-architecture.html#system-overview","ai/ai-architecture.html#component-architecture","ai/ai-architecture.html#1-user-interface-layer","ai/ai-architecture.html#2-intent-recognition","ai/ai-architecture.html#3-rag-knowledge-retrieval","ai/ai-architecture.html#4-llm-integration-mcp","ai/ai-architecture.html#5-configuration-generation","ai/ai-architecture.html#6-execution--feedback","ai/ai-architecture.html#data-flow-examples","ai/ai-architecture.html#example-1-simple-request","ai/ai-architecture.html#example-2-complex-multi-cloud-request","ai/ai-architecture.html#key-technologies","ai/ai-architecture.html#llm-providers","ai/ai-architecture.html#vector-databases","ai/ai-architecture.html#embedding-models","ai/ai-architecture.html#performance-characteristics","ai/ai-architecture.html#latency-breakdown","ai/ai-architecture.html#concurrency","ai/ai-architecture.html#security-architecture","ai/ai-architecture.html#data-protection","ai/ai-architecture.html#access-control","ai/ai-architecture.html#extensibility","ai/ai-architecture.html#custom-tools","ai/ai-architecture.html#custom-rag-documents","ai/ai-architecture.html#fine-tuning-future","ai/ai-architecture.html#related-documentation","ai/typedialog-integration.html#typedialog-ai--ag-integration","ai/typedialog-integration.html#typedialog-components","ai/typedialog-integration.html#typedialog-ai-v010","ai/typedialog-integration.html#typedialog-ag-v010","ai/typedialog-integration.html#integration-with-provisioning","ai/typedialog-integration.html#using-typedialog-ai-in-forms","ai/typedialog-integration.html#using-typedialog-ag-in-workflows","ai/typedialog-integration.html#performance","ai/typedialog-integration.html#typedialog-ai","ai/typedialog-integration.html#typedialog-ag","ai/typedialog-integration.html#configuration","ai/typedialog-integration.html#enable-ai-in-provisioning","ai/typedialog-integration.html#related-documentation","ai/ai-service-crate.html#ai-service-crate","ai/ai-service-crate.html#architecture","ai/ai-service-crate.html#core-modules","ai/ai-service-crate.html#request-flow","ai/ai-service-crate.html#configuration","ai/ai-service-crate.html#environment-variables","ai/ai-service-crate.html#configuration-file","ai/ai-service-crate.html#http-api","ai/ai-service-crate.html#endpoints","ai/ai-service-crate.html#mcp-tool-integration","ai/ai-service-crate.html#available-tools","ai/ai-service-crate.html#tool-definitions","ai/ai-service-crate.html#knowledge-base","ai/ai-service-crate.html#structure","ai/ai-service-crate.html#updating-knowledge","ai/ai-service-crate.html#dag-execution","ai/ai-service-crate.html#workflow-planning","ai/ai-service-crate.html#task-execution","ai/ai-service-crate.html#performance-characteristics","ai/ai-service-crate.html#latency","ai/ai-service-crate.html#throughput","ai/ai-service-crate.html#resource-usage","ai/ai-service-crate.html#monitoring--observability","ai/ai-service-crate.html#metrics","ai/ai-service-crate.html#logging","ai/ai-service-crate.html#troubleshooting","ai/ai-service-crate.html#llm-connection-issues","ai/ai-service-crate.html#slow-knowledge-retrieval","ai/ai-service-crate.html#related-documentation","ai/rag-and-knowledge.html#rag--knowledge-base","ai/rag-and-knowledge.html#architecture","ai/rag-and-knowledge.html#components","ai/rag-and-knowledge.html#knowledge-flow","ai/rag-and-knowledge.html#knowledge-base-organization","ai/rag-and-knowledge.html#document-categories","ai/rag-and-knowledge.html#document-structure","ai/rag-and-knowledge.html#rag-retrieval-process","ai/rag-and-knowledge.html#similarity-search","ai/rag-and-knowledge.html#configuration","ai/rag-and-knowledge.html#managing-knowledge","ai/rag-and-knowledge.html#adding-documents","ai/rag-and-knowledge.html#organizing-knowledge","ai/rag-and-knowledge.html#reindexing","ai/rag-and-knowledge.html#knowledge-query-api","ai/rag-and-knowledge.html#search-endpoint","ai/rag-and-knowledge.html#knowledge-quality","ai/rag-and-knowledge.html#maintenance","ai/rag-and-knowledge.html#metrics","ai/rag-and-knowledge.html#hybrid-search","ai/rag-and-knowledge.html#configuration-1","ai/rag-and-knowledge.html#performance","ai/rag-and-knowledge.html#retrieval-latency","ai/rag-and-knowledge.html#vector-index-size","ai/rag-and-knowledge.html#security--privacy","ai/rag-and-knowledge.html#access-control","ai/rag-and-knowledge.html#data-protection","ai/rag-and-knowledge.html#related-documentation","ai/natural-language-infrastructure.html#natural-language-infrastructure","ai/natural-language-infrastructure.html#overview","ai/natural-language-infrastructure.html#how-it-works","ai/natural-language-infrastructure.html#request-processing-pipeline","ai/natural-language-infrastructure.html#command-usage","ai/natural-language-infrastructure.html#simple-requests","ai/natural-language-infrastructure.html#complex-requests","ai/natural-language-infrastructure.html#interactive-mode","ai/natural-language-infrastructure.html#example-web-application-deployment","ai/natural-language-infrastructure.html#request","ai/natural-language-infrastructure.html#generated-configuration","ai/natural-language-infrastructure.html#output-formats","ai/natural-language-infrastructure.html#get-deployment-script","ai/natural-language-infrastructure.html#save-for-later","ai/natural-language-infrastructure.html#configuration","ai/natural-language-infrastructure.html#llm-provider-selection","ai/natural-language-infrastructure.html#response-options","ai/natural-language-infrastructure.html#advanced-features","ai/natural-language-infrastructure.html#conditional-infrastructure","ai/natural-language-infrastructure.html#cost-optimized-variants","ai/natural-language-infrastructure.html#template-based-generation","ai/natural-language-infrastructure.html#safety--validation","ai/natural-language-infrastructure.html#review-before-deploy","ai/natural-language-infrastructure.html#rollback-support","ai/natural-language-infrastructure.html#limitations","ai/natural-language-infrastructure.html#related-documentation"],"index":{"documentStore":{"docInfo":{"0":{"body":14,"breadcrumbs":4,"title":3},"1":{"body":22,"breadcrumbs":2,"title":1},"10":{"body":43,"breadcrumbs":3,"title":1},"100":{"body":0,"breadcrumbs":6,"title":4},"1000":{"body":23,"breadcrumbs":3,"title":2},"1001":{"body":18,"breadcrumbs":3,"title":2},"1002":{"body":23,"breadcrumbs":4,"title":3},"1003":{"body":0,"breadcrumbs":3,"title":2},"1004":{"body":26,"breadcrumbs":4,"title":3},"1005":{"body":30,"breadcrumbs":3,"title":2},"1006":{"body":0,"breadcrumbs":3,"title":2},"1007":{"body":31,"breadcrumbs":3,"title":2},"1008":{"body":16,"breadcrumbs":3,"title":2},"1009":{"body":0,"breadcrumbs":3,"title":2},"101":{"body":130,"breadcrumbs":5,"title":3},"1010":{"body":12,"breadcrumbs":4,"title":3},"1011":{"body":14,"breadcrumbs":4,"title":3},"1012":{"body":11,"breadcrumbs":5,"title":4},"1013":{"body":17,"breadcrumbs":4,"title":3},"1014":{"body":13,"breadcrumbs":4,"title":3},"1015":{"body":0,"breadcrumbs":3,"title":2},"1016":{"body":13,"breadcrumbs":3,"title":2},"1017":{"body":22,"breadcrumbs":3,"title":2},"1018":{"body":13,"breadcrumbs":3,"title":2},"1019":{"body":8,"breadcrumbs":2,"title":1},"102":{"body":38,"breadcrumbs":4,"title":2},"1020":{"body":22,"breadcrumbs":3,"title":2},"1021":{"body":0,"breadcrumbs":3,"title":2},"1022":{"body":100,"breadcrumbs":4,"title":3},"1023":{"body":50,"breadcrumbs":4,"title":3},"1024":{"body":59,"breadcrumbs":4,"title":3},"1025":{"body":91,"breadcrumbs":3,"title":2},"1026":{"body":55,"breadcrumbs":4,"title":3},"1027":{"body":54,"breadcrumbs":3,"title":2},"1028":{"body":0,"breadcrumbs":3,"title":2},"1029":{"body":21,"breadcrumbs":4,"title":3},"103":{"body":0,"breadcrumbs":6,"title":4},"1030":{"body":28,"breadcrumbs":4,"title":3},"1031":{"body":30,"breadcrumbs":4,"title":3},"1032":{"body":0,"breadcrumbs":3,"title":2},"1033":{"body":37,"breadcrumbs":4,"title":3},"1034":{"body":41,"breadcrumbs":4,"title":3},"1035":{"body":0,"breadcrumbs":3,"title":2},"1036":{"body":24,"breadcrumbs":4,"title":3},"1037":{"body":26,"breadcrumbs":4,"title":3},"1038":{"body":17,"breadcrumbs":3,"title":2},"1039":{"body":0,"breadcrumbs":3,"title":2},"104":{"body":101,"breadcrumbs":4,"title":2},"1040":{"body":15,"breadcrumbs":4,"title":3},"1041":{"body":30,"breadcrumbs":4,"title":3},"1042":{"body":18,"breadcrumbs":4,"title":3},"1043":{"body":0,"breadcrumbs":3,"title":2},"1044":{"body":32,"breadcrumbs":4,"title":3},"1045":{"body":22,"breadcrumbs":3,"title":2},"1046":{"body":35,"breadcrumbs":3,"title":2},"1047":{"body":15,"breadcrumbs":3,"title":2},"1048":{"body":9,"breadcrumbs":4,"title":2},"1049":{"body":37,"breadcrumbs":5,"title":3},"105":{"body":25,"breadcrumbs":4,"title":2},"1050":{"body":37,"breadcrumbs":5,"title":3},"1051":{"body":7,"breadcrumbs":5,"title":3},"1052":{"body":43,"breadcrumbs":4,"title":2},"1053":{"body":22,"breadcrumbs":5,"title":3},"1054":{"body":18,"breadcrumbs":5,"title":3},"1055":{"body":0,"breadcrumbs":5,"title":3},"1056":{"body":24,"breadcrumbs":5,"title":3},"1057":{"body":41,"breadcrumbs":5,"title":3},"1058":{"body":54,"breadcrumbs":4,"title":2},"1059":{"body":45,"breadcrumbs":4,"title":2},"106":{"body":0,"breadcrumbs":6,"title":4},"1060":{"body":42,"breadcrumbs":4,"title":2},"1061":{"body":0,"breadcrumbs":4,"title":2},"1062":{"body":36,"breadcrumbs":4,"title":2},"1063":{"body":41,"breadcrumbs":4,"title":2},"1064":{"body":13,"breadcrumbs":4,"title":2},"1065":{"body":0,"breadcrumbs":5,"title":3},"1066":{"body":32,"breadcrumbs":5,"title":3},"1067":{"body":25,"breadcrumbs":5,"title":3},"1068":{"body":0,"breadcrumbs":4,"title":2},"1069":{"body":33,"breadcrumbs":5,"title":3},"107":{"body":53,"breadcrumbs":4,"title":2},"1070":{"body":20,"breadcrumbs":5,"title":3},"1071":{"body":0,"breadcrumbs":4,"title":2},"1072":{"body":39,"breadcrumbs":5,"title":3},"1073":{"body":27,"breadcrumbs":5,"title":3},"1074":{"body":0,"breadcrumbs":4,"title":2},"1075":{"body":36,"breadcrumbs":5,"title":3},"1076":{"body":24,"breadcrumbs":6,"title":4},"1077":{"body":5,"breadcrumbs":4,"title":2},"1078":{"body":6,"breadcrumbs":4,"title":2},"1079":{"body":8,"breadcrumbs":4,"title":2},"108":{"body":15,"breadcrumbs":5,"title":3},"1080":{"body":8,"breadcrumbs":4,"title":2},"1081":{"body":37,"breadcrumbs":5,"title":3},"1082":{"body":53,"breadcrumbs":5,"title":3},"1083":{"body":14,"breadcrumbs":4,"title":2},"1084":{"body":12,"breadcrumbs":4,"title":2},"1085":{"body":23,"breadcrumbs":3,"title":1},"1086":{"body":130,"breadcrumbs":4,"title":2},"1087":{"body":0,"breadcrumbs":4,"title":2},"1088":{"body":24,"breadcrumbs":6,"title":4},"1089":{"body":27,"breadcrumbs":6,"title":4},"109":{"body":0,"breadcrumbs":6,"title":4},"1090":{"body":22,"breadcrumbs":6,"title":4},"1091":{"body":23,"breadcrumbs":6,"title":4},"1092":{"body":38,"breadcrumbs":4,"title":2},"1093":{"body":51,"breadcrumbs":4,"title":2},"1094":{"body":36,"breadcrumbs":4,"title":2},"1095":{"body":63,"breadcrumbs":4,"title":2},"1096":{"body":65,"breadcrumbs":4,"title":2},"1097":{"body":77,"breadcrumbs":4,"title":2},"1098":{"body":61,"breadcrumbs":4,"title":2},"1099":{"body":82,"breadcrumbs":4,"title":2},"11":{"body":0,"breadcrumbs":5,"title":3},"110":{"body":87,"breadcrumbs":5,"title":3},"1100":{"body":31,"breadcrumbs":4,"title":2},"1101":{"body":36,"breadcrumbs":4,"title":2},"1102":{"body":11,"breadcrumbs":2,"title":1},"1103":{"body":27,"breadcrumbs":2,"title":1},"1104":{"body":0,"breadcrumbs":2,"title":1},"1105":{"body":24,"breadcrumbs":3,"title":2},"1106":{"body":42,"breadcrumbs":2,"title":1},"1107":{"body":0,"breadcrumbs":4,"title":3},"1108":{"body":42,"breadcrumbs":3,"title":2},"1109":{"body":33,"breadcrumbs":3,"title":2},"111":{"body":87,"breadcrumbs":5,"title":3},"1110":{"body":0,"breadcrumbs":3,"title":2},"1111":{"body":29,"breadcrumbs":3,"title":2},"1112":{"body":24,"breadcrumbs":3,"title":2},"1113":{"body":0,"breadcrumbs":3,"title":2},"1114":{"body":29,"breadcrumbs":3,"title":2},"1115":{"body":30,"breadcrumbs":3,"title":2},"1116":{"body":36,"breadcrumbs":3,"title":2},"1117":{"body":0,"breadcrumbs":3,"title":2},"1118":{"body":55,"breadcrumbs":3,"title":2},"1119":{"body":39,"breadcrumbs":3,"title":2},"112":{"body":0,"breadcrumbs":6,"title":4},"1120":{"body":21,"breadcrumbs":3,"title":2},"1121":{"body":0,"breadcrumbs":3,"title":2},"1122":{"body":20,"breadcrumbs":3,"title":2},"1123":{"body":30,"breadcrumbs":3,"title":2},"1124":{"body":0,"breadcrumbs":4,"title":3},"1125":{"body":30,"breadcrumbs":3,"title":2},"1126":{"body":31,"breadcrumbs":3,"title":2},"1127":{"body":0,"breadcrumbs":3,"title":2},"1128":{"body":47,"breadcrumbs":3,"title":2},"1129":{"body":33,"breadcrumbs":3,"title":2},"113":{"body":25,"breadcrumbs":4,"title":2},"1130":{"body":0,"breadcrumbs":3,"title":2},"1131":{"body":64,"breadcrumbs":2,"title":1},"1132":{"body":65,"breadcrumbs":3,"title":2},"1133":{"body":0,"breadcrumbs":3,"title":2},"1134":{"body":39,"breadcrumbs":4,"title":3},"1135":{"body":27,"breadcrumbs":3,"title":2},"1136":{"body":0,"breadcrumbs":3,"title":2},"1137":{"body":42,"breadcrumbs":2,"title":1},"1138":{"body":0,"breadcrumbs":2,"title":1},"1139":{"body":64,"breadcrumbs":3,"title":2},"114":{"body":81,"breadcrumbs":5,"title":3},"1140":{"body":0,"breadcrumbs":2,"title":1},"1141":{"body":24,"breadcrumbs":2,"title":1},"1142":{"body":36,"breadcrumbs":2,"title":1},"1143":{"body":0,"breadcrumbs":2,"title":1},"1144":{"body":0,"breadcrumbs":6,"title":3},"1145":{"body":0,"breadcrumbs":4,"title":2},"1146":{"body":0,"breadcrumbs":4,"title":2},"1147":{"body":0,"breadcrumbs":4,"title":2},"1148":{"body":20,"breadcrumbs":5,"title":3},"1149":{"body":29,"breadcrumbs":3,"title":1},"115":{"body":13,"breadcrumbs":5,"title":3},"1150":{"body":0,"breadcrumbs":3,"title":1},"1151":{"body":19,"breadcrumbs":4,"title":2},"1152":{"body":44,"breadcrumbs":4,"title":2},"1153":{"body":0,"breadcrumbs":3,"title":1},"1154":{"body":17,"breadcrumbs":4,"title":2},"1155":{"body":20,"breadcrumbs":5,"title":3},"1156":{"body":0,"breadcrumbs":3,"title":1},"1157":{"body":29,"breadcrumbs":4,"title":2},"1158":{"body":106,"breadcrumbs":4,"title":2},"1159":{"body":0,"breadcrumbs":3,"title":1},"116":{"body":0,"breadcrumbs":6,"title":4},"1160":{"body":55,"breadcrumbs":5,"title":3},"1161":{"body":43,"breadcrumbs":4,"title":2},"1162":{"body":46,"breadcrumbs":4,"title":2},"1163":{"body":0,"breadcrumbs":5,"title":3},"1164":{"body":32,"breadcrumbs":4,"title":2},"1165":{"body":74,"breadcrumbs":5,"title":3},"1166":{"body":25,"breadcrumbs":5,"title":3},"1167":{"body":0,"breadcrumbs":4,"title":2},"1168":{"body":23,"breadcrumbs":3,"title":1},"1169":{"body":25,"breadcrumbs":4,"title":2},"117":{"body":24,"breadcrumbs":4,"title":2},"1170":{"body":46,"breadcrumbs":4,"title":2},"1171":{"body":0,"breadcrumbs":4,"title":2},"1172":{"body":29,"breadcrumbs":4,"title":2},"1173":{"body":35,"breadcrumbs":4,"title":2},"1174":{"body":0,"breadcrumbs":3,"title":1},"1175":{"body":36,"breadcrumbs":4,"title":2},"1176":{"body":21,"breadcrumbs":4,"title":2},"1177":{"body":0,"breadcrumbs":3,"title":1},"1178":{"body":14,"breadcrumbs":4,"title":2},"1179":{"body":16,"breadcrumbs":4,"title":2},"118":{"body":22,"breadcrumbs":4,"title":2},"1180":{"body":25,"breadcrumbs":5,"title":3},"1181":{"body":0,"breadcrumbs":4,"title":2},"1182":{"body":29,"breadcrumbs":3,"title":1},"1183":{"body":10,"breadcrumbs":4,"title":2},"1184":{"body":21,"breadcrumbs":4,"title":2},"1185":{"body":0,"breadcrumbs":2,"title":1},"1186":{"body":0,"breadcrumbs":4,"title":2},"1187":{"body":0,"breadcrumbs":4,"title":2},"1188":{"body":0,"breadcrumbs":2,"title":1},"1189":{"body":0,"breadcrumbs":4,"title":2},"119":{"body":37,"breadcrumbs":4,"title":2},"1190":{"body":11,"breadcrumbs":3,"title":1},"1191":{"body":77,"breadcrumbs":3,"title":1},"1192":{"body":0,"breadcrumbs":4,"title":2},"1193":{"body":50,"breadcrumbs":4,"title":2},"1194":{"body":12,"breadcrumbs":4,"title":2},"1195":{"body":30,"breadcrumbs":4,"title":2},"1196":{"body":6,"breadcrumbs":3,"title":1},"1197":{"body":0,"breadcrumbs":5,"title":3},"1198":{"body":13,"breadcrumbs":6,"title":4},"1199":{"body":12,"breadcrumbs":6,"title":4},"12":{"body":65,"breadcrumbs":4,"title":2},"120":{"body":19,"breadcrumbs":4,"title":2},"1200":{"body":11,"breadcrumbs":5,"title":3},"1201":{"body":11,"breadcrumbs":6,"title":4},"1202":{"body":9,"breadcrumbs":6,"title":4},"1203":{"body":35,"breadcrumbs":4,"title":2},"1204":{"body":11,"breadcrumbs":4,"title":2},"1205":{"body":15,"breadcrumbs":3,"title":1},"1206":{"body":10,"breadcrumbs":4,"title":2},"1207":{"body":42,"breadcrumbs":4,"title":2},"1208":{"body":40,"breadcrumbs":4,"title":2},"1209":{"body":45,"breadcrumbs":4,"title":2},"121":{"body":6,"breadcrumbs":2,"title":1},"1210":{"body":5,"breadcrumbs":5,"title":3},"1211":{"body":16,"breadcrumbs":4,"title":2},"1212":{"body":33,"breadcrumbs":5,"title":3},"1213":{"body":75,"breadcrumbs":5,"title":3},"1214":{"body":38,"breadcrumbs":5,"title":3},"1215":{"body":5,"breadcrumbs":6,"title":4},"1216":{"body":18,"breadcrumbs":5,"title":3},"1217":{"body":37,"breadcrumbs":5,"title":3},"1218":{"body":130,"breadcrumbs":6,"title":4},"1219":{"body":7,"breadcrumbs":5,"title":3},"122":{"body":0,"breadcrumbs":3,"title":2},"1220":{"body":39,"breadcrumbs":4,"title":2},"1221":{"body":58,"breadcrumbs":5,"title":3},"1222":{"body":0,"breadcrumbs":4,"title":2},"1223":{"body":77,"breadcrumbs":4,"title":2},"1224":{"body":0,"breadcrumbs":4,"title":2},"1225":{"body":37,"breadcrumbs":5,"title":3},"1226":{"body":40,"breadcrumbs":4,"title":2},"1227":{"body":34,"breadcrumbs":4,"title":2},"1228":{"body":15,"breadcrumbs":4,"title":2},"1229":{"body":7,"breadcrumbs":4,"title":2},"123":{"body":29,"breadcrumbs":4,"title":3},"1230":{"body":13,"breadcrumbs":4,"title":2},"1231":{"body":56,"breadcrumbs":4,"title":2},"1232":{"body":26,"breadcrumbs":4,"title":2},"1233":{"body":65,"breadcrumbs":5,"title":3},"1234":{"body":225,"breadcrumbs":5,"title":3},"1235":{"body":94,"breadcrumbs":4,"title":2},"1236":{"body":67,"breadcrumbs":4,"title":2},"1237":{"body":46,"breadcrumbs":5,"title":3},"1238":{"body":12,"breadcrumbs":4,"title":2},"1239":{"body":8,"breadcrumbs":4,"title":2},"124":{"body":28,"breadcrumbs":3,"title":2},"1240":{"body":14,"breadcrumbs":4,"title":2},"1241":{"body":25,"breadcrumbs":4,"title":2},"1242":{"body":13,"breadcrumbs":4,"title":2},"1243":{"body":0,"breadcrumbs":4,"title":2},"1244":{"body":34,"breadcrumbs":4,"title":2},"1245":{"body":99,"breadcrumbs":4,"title":2},"1246":{"body":25,"breadcrumbs":4,"title":2},"1247":{"body":0,"breadcrumbs":5,"title":3},"1248":{"body":15,"breadcrumbs":3,"title":1},"1249":{"body":34,"breadcrumbs":3,"title":1},"125":{"body":23,"breadcrumbs":3,"title":2},"1250":{"body":0,"breadcrumbs":4,"title":2},"1251":{"body":29,"breadcrumbs":4,"title":2},"1252":{"body":23,"breadcrumbs":4,"title":2},"1253":{"body":41,"breadcrumbs":5,"title":3},"1254":{"body":12,"breadcrumbs":4,"title":2},"1255":{"body":6,"breadcrumbs":5,"title":3},"1256":{"body":34,"breadcrumbs":5,"title":3},"1257":{"body":24,"breadcrumbs":4,"title":2},"1258":{"body":35,"breadcrumbs":4,"title":2},"1259":{"body":5,"breadcrumbs":4,"title":2},"126":{"body":0,"breadcrumbs":3,"title":2},"1260":{"body":8,"breadcrumbs":4,"title":2},"1261":{"body":26,"breadcrumbs":4,"title":2},"1262":{"body":0,"breadcrumbs":5,"title":3},"1263":{"body":29,"breadcrumbs":4,"title":2},"1264":{"body":22,"breadcrumbs":5,"title":3},"1265":{"body":0,"breadcrumbs":3,"title":1},"1266":{"body":16,"breadcrumbs":4,"title":2},"1267":{"body":33,"breadcrumbs":5,"title":3},"1268":{"body":28,"breadcrumbs":4,"title":2},"1269":{"body":0,"breadcrumbs":4,"title":2},"127":{"body":35,"breadcrumbs":3,"title":2},"1270":{"body":18,"breadcrumbs":3,"title":1},"1271":{"body":22,"breadcrumbs":3,"title":1},"1272":{"body":18,"breadcrumbs":4,"title":2},"1273":{"body":7,"breadcrumbs":4,"title":2},"1274":{"body":56,"breadcrumbs":5,"title":3},"1275":{"body":0,"breadcrumbs":4,"title":2},"1276":{"body":24,"breadcrumbs":5,"title":3},"1277":{"body":43,"breadcrumbs":4,"title":2},"1278":{"body":0,"breadcrumbs":5,"title":3},"1279":{"body":47,"breadcrumbs":4,"title":2},"128":{"body":15,"breadcrumbs":3,"title":2},"1280":{"body":35,"breadcrumbs":5,"title":3},"1281":{"body":98,"breadcrumbs":4,"title":2},"1282":{"body":0,"breadcrumbs":4,"title":2},"1283":{"body":29,"breadcrumbs":4,"title":2},"1284":{"body":48,"breadcrumbs":5,"title":3},"1285":{"body":0,"breadcrumbs":4,"title":2},"1286":{"body":38,"breadcrumbs":4,"title":2},"1287":{"body":26,"breadcrumbs":5,"title":3},"1288":{"body":0,"breadcrumbs":4,"title":2},"1289":{"body":25,"breadcrumbs":4,"title":2},"129":{"body":0,"breadcrumbs":3,"title":2},"1290":{"body":18,"breadcrumbs":4,"title":2},"1291":{"body":18,"breadcrumbs":4,"title":2},"1292":{"body":46,"breadcrumbs":4,"title":2},"1293":{"body":0,"breadcrumbs":3,"title":1},"1294":{"body":55,"breadcrumbs":5,"title":3},"1295":{"body":10,"breadcrumbs":4,"title":2},"1296":{"body":13,"breadcrumbs":2,"title":1},"1297":{"body":47,"breadcrumbs":3,"title":2},"1298":{"body":0,"breadcrumbs":3,"title":2},"1299":{"body":29,"breadcrumbs":2,"title":1},"13":{"body":30,"breadcrumbs":4,"title":2},"130":{"body":22,"breadcrumbs":3,"title":2},"1300":{"body":25,"breadcrumbs":3,"title":2},"1301":{"body":35,"breadcrumbs":4,"title":3},"1302":{"body":7,"breadcrumbs":3,"title":2},"1303":{"body":41,"breadcrumbs":4,"title":3},"1304":{"body":53,"breadcrumbs":4,"title":3},"1305":{"body":7,"breadcrumbs":3,"title":2},"1306":{"body":38,"breadcrumbs":4,"title":3},"1307":{"body":30,"breadcrumbs":3,"title":2},"1308":{"body":9,"breadcrumbs":3,"title":2},"1309":{"body":33,"breadcrumbs":3,"title":2},"131":{"body":23,"breadcrumbs":4,"title":3},"1310":{"body":30,"breadcrumbs":3,"title":2},"1311":{"body":36,"breadcrumbs":3,"title":2},"1312":{"body":5,"breadcrumbs":4,"title":3},"1313":{"body":30,"breadcrumbs":4,"title":3},"1314":{"body":4,"breadcrumbs":3,"title":2},"1315":{"body":31,"breadcrumbs":4,"title":3},"1316":{"body":5,"breadcrumbs":2,"title":1},"1317":{"body":26,"breadcrumbs":4,"title":3},"1318":{"body":4,"breadcrumbs":3,"title":2},"1319":{"body":32,"breadcrumbs":4,"title":3},"132":{"body":29,"breadcrumbs":3,"title":2},"1320":{"body":22,"breadcrumbs":3,"title":2},"1321":{"body":3,"breadcrumbs":3,"title":2},"1322":{"body":29,"breadcrumbs":3,"title":2},"1323":{"body":55,"breadcrumbs":4,"title":3},"1324":{"body":0,"breadcrumbs":3,"title":2},"1325":{"body":29,"breadcrumbs":3,"title":2},"1326":{"body":21,"breadcrumbs":4,"title":3},"1327":{"body":14,"breadcrumbs":3,"title":2},"1328":{"body":9,"breadcrumbs":2,"title":1},"1329":{"body":0,"breadcrumbs":3,"title":2},"133":{"body":0,"breadcrumbs":4,"title":3},"1330":{"body":41,"breadcrumbs":2,"title":1},"1331":{"body":35,"breadcrumbs":3,"title":2},"1332":{"body":0,"breadcrumbs":4,"title":3},"1333":{"body":31,"breadcrumbs":3,"title":2},"1334":{"body":24,"breadcrumbs":3,"title":2},"1335":{"body":22,"breadcrumbs":3,"title":2},"1336":{"body":4,"breadcrumbs":3,"title":2},"1337":{"body":17,"breadcrumbs":3,"title":2},"1338":{"body":18,"breadcrumbs":3,"title":2},"1339":{"body":14,"breadcrumbs":4,"title":3},"134":{"body":25,"breadcrumbs":3,"title":2},"1340":{"body":0,"breadcrumbs":2,"title":1},"1341":{"body":20,"breadcrumbs":3,"title":2},"1342":{"body":21,"breadcrumbs":3,"title":2},"1343":{"body":52,"breadcrumbs":4,"title":3},"1344":{"body":0,"breadcrumbs":4,"title":3},"1345":{"body":18,"breadcrumbs":4,"title":3},"1346":{"body":68,"breadcrumbs":4,"title":3},"1347":{"body":27,"breadcrumbs":3,"title":2},"1348":{"body":0,"breadcrumbs":4,"title":3},"1349":{"body":24,"breadcrumbs":3,"title":2},"135":{"body":15,"breadcrumbs":3,"title":2},"1350":{"body":21,"breadcrumbs":3,"title":2},"1351":{"body":20,"breadcrumbs":2,"title":1},"1352":{"body":20,"breadcrumbs":2,"title":1},"1353":{"body":19,"breadcrumbs":3,"title":2},"1354":{"body":15,"breadcrumbs":2,"title":1},"1355":{"body":12,"breadcrumbs":4,"title":2},"1356":{"body":11,"breadcrumbs":4,"title":2},"1357":{"body":28,"breadcrumbs":4,"title":2},"1358":{"body":19,"breadcrumbs":5,"title":3},"1359":{"body":12,"breadcrumbs":4,"title":2},"136":{"body":21,"breadcrumbs":3,"title":2},"1360":{"body":0,"breadcrumbs":4,"title":2},"1361":{"body":40,"breadcrumbs":4,"title":2},"1362":{"body":39,"breadcrumbs":4,"title":2},"1363":{"body":38,"breadcrumbs":4,"title":2},"1364":{"body":33,"breadcrumbs":4,"title":2},"1365":{"body":50,"breadcrumbs":4,"title":2},"1366":{"body":40,"breadcrumbs":4,"title":2},"1367":{"body":0,"breadcrumbs":4,"title":2},"1368":{"body":45,"breadcrumbs":5,"title":3},"1369":{"body":62,"breadcrumbs":5,"title":3},"137":{"body":0,"breadcrumbs":3,"title":2},"1370":{"body":51,"breadcrumbs":5,"title":3},"1371":{"body":46,"breadcrumbs":4,"title":2},"1372":{"body":42,"breadcrumbs":4,"title":2},"1373":{"body":49,"breadcrumbs":3,"title":1},"1374":{"body":29,"breadcrumbs":4,"title":2},"1375":{"body":23,"breadcrumbs":4,"title":2},"1376":{"body":14,"breadcrumbs":4,"title":2},"1377":{"body":12,"breadcrumbs":5,"title":3},"1378":{"body":6,"breadcrumbs":4,"title":2},"1379":{"body":18,"breadcrumbs":3,"title":1},"138":{"body":25,"breadcrumbs":3,"title":2},"1380":{"body":34,"breadcrumbs":5,"title":3},"1381":{"body":74,"breadcrumbs":5,"title":3},"1382":{"body":48,"breadcrumbs":4,"title":2},"1383":{"body":9,"breadcrumbs":4,"title":2},"1384":{"body":55,"breadcrumbs":4,"title":2},"1385":{"body":46,"breadcrumbs":4,"title":2},"1386":{"body":55,"breadcrumbs":4,"title":2},"1387":{"body":20,"breadcrumbs":4,"title":2},"1388":{"body":48,"breadcrumbs":4,"title":2},"1389":{"body":27,"breadcrumbs":4,"title":2},"139":{"body":20,"breadcrumbs":3,"title":2},"1390":{"body":9,"breadcrumbs":5,"title":3},"1391":{"body":32,"breadcrumbs":4,"title":2},"1392":{"body":26,"breadcrumbs":4,"title":2},"1393":{"body":19,"breadcrumbs":4,"title":2},"1394":{"body":24,"breadcrumbs":4,"title":2},"1395":{"body":18,"breadcrumbs":4,"title":2},"1396":{"body":18,"breadcrumbs":4,"title":2},"1397":{"body":24,"breadcrumbs":5,"title":3},"1398":{"body":35,"breadcrumbs":4,"title":2},"1399":{"body":7,"breadcrumbs":5,"title":3},"14":{"body":39,"breadcrumbs":4,"title":2},"140":{"body":11,"breadcrumbs":3,"title":2},"1400":{"body":43,"breadcrumbs":4,"title":2},"1401":{"body":35,"breadcrumbs":4,"title":2},"1402":{"body":18,"breadcrumbs":4,"title":2},"1403":{"body":25,"breadcrumbs":4,"title":2},"1404":{"body":7,"breadcrumbs":5,"title":3},"1405":{"body":34,"breadcrumbs":3,"title":1},"1406":{"body":27,"breadcrumbs":4,"title":2},"1407":{"body":28,"breadcrumbs":4,"title":2},"1408":{"body":23,"breadcrumbs":4,"title":2},"1409":{"body":19,"breadcrumbs":3,"title":1},"141":{"body":0,"breadcrumbs":4,"title":3},"1410":{"body":31,"breadcrumbs":4,"title":2},"1411":{"body":25,"breadcrumbs":4,"title":2},"1412":{"body":7,"breadcrumbs":5,"title":3},"1413":{"body":31,"breadcrumbs":4,"title":2},"1414":{"body":35,"breadcrumbs":4,"title":2},"1415":{"body":27,"breadcrumbs":4,"title":2},"1416":{"body":16,"breadcrumbs":4,"title":2},"1417":{"body":31,"breadcrumbs":5,"title":3},"1418":{"body":7,"breadcrumbs":5,"title":3},"1419":{"body":30,"breadcrumbs":4,"title":2},"142":{"body":18,"breadcrumbs":3,"title":2},"1420":{"body":25,"breadcrumbs":4,"title":2},"1421":{"body":37,"breadcrumbs":4,"title":2},"1422":{"body":26,"breadcrumbs":4,"title":2},"1423":{"body":20,"breadcrumbs":4,"title":2},"1424":{"body":9,"breadcrumbs":5,"title":3},"1425":{"body":65,"breadcrumbs":5,"title":3},"1426":{"body":32,"breadcrumbs":5,"title":3},"1427":{"body":54,"breadcrumbs":4,"title":2},"1428":{"body":8,"breadcrumbs":5,"title":3},"1429":{"body":36,"breadcrumbs":4,"title":2},"143":{"body":31,"breadcrumbs":4,"title":3},"1430":{"body":32,"breadcrumbs":4,"title":2},"1431":{"body":24,"breadcrumbs":4,"title":2},"1432":{"body":28,"breadcrumbs":4,"title":2},"1433":{"body":13,"breadcrumbs":4,"title":2},"1434":{"body":8,"breadcrumbs":5,"title":3},"1435":{"body":21,"breadcrumbs":4,"title":2},"1436":{"body":27,"breadcrumbs":4,"title":2},"1437":{"body":21,"breadcrumbs":4,"title":2},"1438":{"body":47,"breadcrumbs":4,"title":2},"1439":{"body":21,"breadcrumbs":5,"title":3},"144":{"body":21,"breadcrumbs":4,"title":3},"1440":{"body":21,"breadcrumbs":3,"title":1},"1441":{"body":29,"breadcrumbs":3,"title":1},"1442":{"body":30,"breadcrumbs":4,"title":2},"1443":{"body":13,"breadcrumbs":5,"title":3},"1444":{"body":54,"breadcrumbs":4,"title":2},"1445":{"body":48,"breadcrumbs":4,"title":2},"1446":{"body":49,"breadcrumbs":4,"title":2},"1447":{"body":5,"breadcrumbs":4,"title":2},"1448":{"body":202,"breadcrumbs":4,"title":2},"1449":{"body":44,"breadcrumbs":4,"title":2},"145":{"body":22,"breadcrumbs":4,"title":3},"1450":{"body":6,"breadcrumbs":4,"title":2},"1451":{"body":198,"breadcrumbs":4,"title":2},"1452":{"body":47,"breadcrumbs":4,"title":2},"1453":{"body":93,"breadcrumbs":4,"title":2},"1454":{"body":94,"breadcrumbs":4,"title":2},"1455":{"body":114,"breadcrumbs":4,"title":2},"1456":{"body":82,"breadcrumbs":4,"title":2},"1457":{"body":61,"breadcrumbs":4,"title":2},"1458":{"body":100,"breadcrumbs":4,"title":2},"1459":{"body":6,"breadcrumbs":4,"title":2},"146":{"body":29,"breadcrumbs":5,"title":4},"1460":{"body":86,"breadcrumbs":4,"title":2},"1461":{"body":83,"breadcrumbs":4,"title":2},"1462":{"body":138,"breadcrumbs":4,"title":2},"1463":{"body":93,"breadcrumbs":4,"title":2},"1464":{"body":73,"breadcrumbs":4,"title":2},"1465":{"body":55,"breadcrumbs":4,"title":2},"1466":{"body":103,"breadcrumbs":5,"title":3},"1467":{"body":117,"breadcrumbs":4,"title":2},"1468":{"body":59,"breadcrumbs":4,"title":2},"1469":{"body":26,"breadcrumbs":4,"title":2},"147":{"body":81,"breadcrumbs":4,"title":3},"1470":{"body":27,"breadcrumbs":4,"title":2},"1471":{"body":19,"breadcrumbs":4,"title":2},"1472":{"body":25,"breadcrumbs":4,"title":2},"1473":{"body":0,"breadcrumbs":4,"title":2},"1474":{"body":0,"breadcrumbs":4,"title":2},"1475":{"body":0,"breadcrumbs":6,"title":3},"1476":{"body":0,"breadcrumbs":2,"title":1},"1477":{"body":11,"breadcrumbs":3,"title":1},"1478":{"body":63,"breadcrumbs":3,"title":1},"1479":{"body":0,"breadcrumbs":4,"title":2},"148":{"body":0,"breadcrumbs":3,"title":2},"1480":{"body":64,"breadcrumbs":4,"title":2},"1481":{"body":26,"breadcrumbs":4,"title":2},"1482":{"body":0,"breadcrumbs":5,"title":3},"1483":{"body":18,"breadcrumbs":6,"title":4},"1484":{"body":20,"breadcrumbs":7,"title":5},"1485":{"body":17,"breadcrumbs":7,"title":5},"1486":{"body":17,"breadcrumbs":6,"title":4},"1487":{"body":24,"breadcrumbs":8,"title":6},"1488":{"body":19,"breadcrumbs":10,"title":8},"1489":{"body":20,"breadcrumbs":3,"title":1},"149":{"body":34,"breadcrumbs":3,"title":2},"1490":{"body":6,"breadcrumbs":4,"title":2},"1491":{"body":132,"breadcrumbs":4,"title":2},"1492":{"body":0,"breadcrumbs":5,"title":3},"1493":{"body":33,"breadcrumbs":6,"title":4},"1494":{"body":176,"breadcrumbs":6,"title":4},"1495":{"body":444,"breadcrumbs":6,"title":4},"1496":{"body":160,"breadcrumbs":5,"title":3},"1497":{"body":24,"breadcrumbs":5,"title":3},"1498":{"body":77,"breadcrumbs":4,"title":2},"1499":{"body":50,"breadcrumbs":4,"title":2},"15":{"body":75,"breadcrumbs":6,"title":4},"150":{"body":17,"breadcrumbs":3,"title":2},"1500":{"body":65,"breadcrumbs":4,"title":2},"1501":{"body":90,"breadcrumbs":4,"title":2},"1502":{"body":34,"breadcrumbs":4,"title":2},"1503":{"body":45,"breadcrumbs":4,"title":2},"1504":{"body":135,"breadcrumbs":4,"title":2},"1505":{"body":37,"breadcrumbs":4,"title":2},"1506":{"body":56,"breadcrumbs":3,"title":1},"1507":{"body":33,"breadcrumbs":4,"title":2},"1508":{"body":36,"breadcrumbs":4,"title":2},"1509":{"body":6,"breadcrumbs":4,"title":2},"151":{"body":18,"breadcrumbs":3,"title":2},"1510":{"body":6,"breadcrumbs":4,"title":2},"1511":{"body":67,"breadcrumbs":6,"title":4},"1512":{"body":73,"breadcrumbs":6,"title":4},"1513":{"body":71,"breadcrumbs":7,"title":5},"1514":{"body":60,"breadcrumbs":6,"title":4},"1515":{"body":50,"breadcrumbs":6,"title":4},"1516":{"body":54,"breadcrumbs":6,"title":4},"1517":{"body":58,"breadcrumbs":8,"title":6},"1518":{"body":45,"breadcrumbs":6,"title":4},"1519":{"body":43,"breadcrumbs":5,"title":3},"152":{"body":7,"breadcrumbs":4,"title":2},"1520":{"body":64,"breadcrumbs":7,"title":5},"1521":{"body":39,"breadcrumbs":5,"title":3},"1522":{"body":34,"breadcrumbs":5,"title":3},"1523":{"body":58,"breadcrumbs":6,"title":4},"1524":{"body":32,"breadcrumbs":5,"title":3},"1525":{"body":6,"breadcrumbs":4,"title":2},"1526":{"body":6,"breadcrumbs":4,"title":2},"1527":{"body":111,"breadcrumbs":5,"title":3},"1528":{"body":2,"breadcrumbs":5,"title":3},"1529":{"body":17,"breadcrumbs":6,"title":4},"153":{"body":44,"breadcrumbs":3,"title":1},"1530":{"body":21,"breadcrumbs":4,"title":2},"1531":{"body":0,"breadcrumbs":6,"title":4},"1532":{"body":21,"breadcrumbs":4,"title":2},"1533":{"body":35,"breadcrumbs":4,"title":2},"1534":{"body":30,"breadcrumbs":4,"title":2},"1535":{"body":31,"breadcrumbs":4,"title":2},"1536":{"body":15,"breadcrumbs":4,"title":2},"1537":{"body":0,"breadcrumbs":5,"title":3},"1538":{"body":39,"breadcrumbs":3,"title":1},"1539":{"body":36,"breadcrumbs":4,"title":2},"154":{"body":53,"breadcrumbs":4,"title":2},"1540":{"body":18,"breadcrumbs":5,"title":3},"1541":{"body":25,"breadcrumbs":4,"title":2},"1542":{"body":21,"breadcrumbs":4,"title":2},"1543":{"body":18,"breadcrumbs":4,"title":2},"1544":{"body":20,"breadcrumbs":4,"title":2},"1545":{"body":18,"breadcrumbs":3,"title":1},"1546":{"body":20,"breadcrumbs":4,"title":2},"1547":{"body":19,"breadcrumbs":4,"title":2},"1548":{"body":21,"breadcrumbs":4,"title":2},"1549":{"body":22,"breadcrumbs":4,"title":2},"155":{"body":58,"breadcrumbs":5,"title":3},"1550":{"body":0,"breadcrumbs":5,"title":3},"1551":{"body":36,"breadcrumbs":3,"title":1},"1552":{"body":46,"breadcrumbs":4,"title":2},"1553":{"body":36,"breadcrumbs":3,"title":1},"1554":{"body":0,"breadcrumbs":5,"title":3},"1555":{"body":39,"breadcrumbs":4,"title":2},"1556":{"body":22,"breadcrumbs":4,"title":2},"1557":{"body":0,"breadcrumbs":4,"title":2},"1558":{"body":5,"breadcrumbs":5,"title":3},"1559":{"body":5,"breadcrumbs":4,"title":2},"156":{"body":0,"breadcrumbs":5,"title":3},"1560":{"body":8,"breadcrumbs":4,"title":2},"1561":{"body":6,"breadcrumbs":4,"title":2},"1562":{"body":5,"breadcrumbs":4,"title":2},"1563":{"body":6,"breadcrumbs":6,"title":4},"1564":{"body":4,"breadcrumbs":7,"title":5},"1565":{"body":6,"breadcrumbs":6,"title":4},"1566":{"body":6,"breadcrumbs":6,"title":4},"1567":{"body":5,"breadcrumbs":6,"title":4},"1568":{"body":8,"breadcrumbs":6,"title":4},"1569":{"body":5,"breadcrumbs":5,"title":3},"157":{"body":37,"breadcrumbs":4,"title":2},"1570":{"body":6,"breadcrumbs":5,"title":3},"1571":{"body":5,"breadcrumbs":5,"title":3},"1572":{"body":7,"breadcrumbs":6,"title":4},"1573":{"body":0,"breadcrumbs":4,"title":2},"1574":{"body":6,"breadcrumbs":5,"title":3},"1575":{"body":7,"breadcrumbs":4,"title":2},"1576":{"body":8,"breadcrumbs":5,"title":3},"1577":{"body":30,"breadcrumbs":4,"title":2},"1578":{"body":6,"breadcrumbs":4,"title":2},"1579":{"body":13,"breadcrumbs":4,"title":3},"158":{"body":7,"breadcrumbs":4,"title":2},"1580":{"body":0,"breadcrumbs":3,"title":2},"1581":{"body":63,"breadcrumbs":4,"title":3},"1582":{"body":28,"breadcrumbs":3,"title":2},"1583":{"body":37,"breadcrumbs":3,"title":2},"1584":{"body":28,"breadcrumbs":3,"title":2},"1585":{"body":81,"breadcrumbs":3,"title":2},"1586":{"body":29,"breadcrumbs":3,"title":2},"1587":{"body":13,"breadcrumbs":3,"title":1},"1588":{"body":75,"breadcrumbs":3,"title":1},"1589":{"body":0,"breadcrumbs":5,"title":3},"159":{"body":10,"breadcrumbs":4,"title":2},"1590":{"body":21,"breadcrumbs":5,"title":3},"1591":{"body":37,"breadcrumbs":5,"title":3},"1592":{"body":35,"breadcrumbs":4,"title":2},"1593":{"body":43,"breadcrumbs":4,"title":2},"1594":{"body":31,"breadcrumbs":4,"title":2},"1595":{"body":40,"breadcrumbs":5,"title":3},"1596":{"body":24,"breadcrumbs":4,"title":2},"1597":{"body":37,"breadcrumbs":4,"title":2},"1598":{"body":0,"breadcrumbs":4,"title":2},"1599":{"body":10,"breadcrumbs":5,"title":3},"16":{"body":0,"breadcrumbs":4,"title":2},"160":{"body":9,"breadcrumbs":4,"title":2},"1600":{"body":11,"breadcrumbs":6,"title":4},"1601":{"body":12,"breadcrumbs":6,"title":4},"1602":{"body":13,"breadcrumbs":5,"title":3},"1603":{"body":27,"breadcrumbs":4,"title":2},"1604":{"body":16,"breadcrumbs":4,"title":2},"1605":{"body":8,"breadcrumbs":4,"title":2},"1606":{"body":42,"breadcrumbs":5,"title":3},"1607":{"body":57,"breadcrumbs":5,"title":3},"1608":{"body":19,"breadcrumbs":4,"title":2},"1609":{"body":4,"breadcrumbs":3,"title":1},"161":{"body":7,"breadcrumbs":4,"title":2},"1610":{"body":8,"breadcrumbs":5,"title":3},"1611":{"body":60,"breadcrumbs":5,"title":3},"1612":{"body":35,"breadcrumbs":4,"title":2},"1613":{"body":5,"breadcrumbs":3,"title":1},"1614":{"body":7,"breadcrumbs":5,"title":3},"1615":{"body":28,"breadcrumbs":5,"title":3},"1616":{"body":47,"breadcrumbs":5,"title":3},"1617":{"body":3,"breadcrumbs":3,"title":1},"1618":{"body":8,"breadcrumbs":5,"title":3},"1619":{"body":34,"breadcrumbs":5,"title":3},"162":{"body":34,"breadcrumbs":5,"title":3},"1620":{"body":30,"breadcrumbs":5,"title":3},"1621":{"body":4,"breadcrumbs":3,"title":1},"1622":{"body":7,"breadcrumbs":5,"title":3},"1623":{"body":33,"breadcrumbs":5,"title":3},"1624":{"body":24,"breadcrumbs":4,"title":2},"1625":{"body":15,"breadcrumbs":5,"title":3},"1626":{"body":5,"breadcrumbs":3,"title":1},"1627":{"body":11,"breadcrumbs":3,"title":1},"1628":{"body":50,"breadcrumbs":3,"title":1},"1629":{"body":0,"breadcrumbs":4,"title":2},"163":{"body":31,"breadcrumbs":5,"title":3},"1630":{"body":35,"breadcrumbs":5,"title":3},"1631":{"body":50,"breadcrumbs":5,"title":3},"1632":{"body":40,"breadcrumbs":4,"title":2},"1633":{"body":45,"breadcrumbs":5,"title":3},"1634":{"body":74,"breadcrumbs":6,"title":4},"1635":{"body":42,"breadcrumbs":4,"title":2},"1636":{"body":32,"breadcrumbs":5,"title":3},"1637":{"body":40,"breadcrumbs":5,"title":3},"1638":{"body":0,"breadcrumbs":4,"title":2},"1639":{"body":9,"breadcrumbs":4,"title":2},"164":{"body":0,"breadcrumbs":5,"title":3},"1640":{"body":10,"breadcrumbs":4,"title":2},"1641":{"body":8,"breadcrumbs":7,"title":5},"1642":{"body":24,"breadcrumbs":4,"title":2},"1643":{"body":16,"breadcrumbs":4,"title":2},"1644":{"body":0,"breadcrumbs":4,"title":2},"1645":{"body":0,"breadcrumbs":4,"title":2},"1646":{"body":0,"breadcrumbs":4,"title":2},"1647":{"body":0,"breadcrumbs":4,"title":2},"1648":{"body":15,"breadcrumbs":5,"title":3},"1649":{"body":29,"breadcrumbs":3,"title":1},"165":{"body":9,"breadcrumbs":5,"title":3},"1650":{"body":0,"breadcrumbs":4,"title":2},"1651":{"body":27,"breadcrumbs":5,"title":3},"1652":{"body":18,"breadcrumbs":4,"title":2},"1653":{"body":15,"breadcrumbs":4,"title":2},"1654":{"body":51,"breadcrumbs":4,"title":2},"1655":{"body":0,"breadcrumbs":4,"title":2},"1656":{"body":24,"breadcrumbs":5,"title":3},"1657":{"body":26,"breadcrumbs":5,"title":3},"1658":{"body":46,"breadcrumbs":3,"title":1},"1659":{"body":27,"breadcrumbs":3,"title":1},"166":{"body":16,"breadcrumbs":5,"title":3},"1660":{"body":0,"breadcrumbs":3,"title":1},"1661":{"body":31,"breadcrumbs":4,"title":2},"1662":{"body":39,"breadcrumbs":4,"title":2},"1663":{"body":0,"breadcrumbs":4,"title":2},"1664":{"body":27,"breadcrumbs":5,"title":3},"1665":{"body":21,"breadcrumbs":5,"title":3},"1666":{"body":31,"breadcrumbs":4,"title":2},"1667":{"body":32,"breadcrumbs":5,"title":3},"1668":{"body":43,"breadcrumbs":3,"title":1},"1669":{"body":35,"breadcrumbs":4,"title":2},"167":{"body":21,"breadcrumbs":5,"title":3},"1670":{"body":0,"breadcrumbs":3,"title":1},"1671":{"body":20,"breadcrumbs":4,"title":2},"1672":{"body":21,"breadcrumbs":3,"title":1},"1673":{"body":0,"breadcrumbs":3,"title":1},"1674":{"body":16,"breadcrumbs":4,"title":2},"1675":{"body":18,"breadcrumbs":4,"title":2},"1676":{"body":19,"breadcrumbs":4,"title":2},"1677":{"body":11,"breadcrumbs":4,"title":2},"1678":{"body":78,"breadcrumbs":4,"title":2},"1679":{"body":0,"breadcrumbs":4,"title":2},"168":{"body":27,"breadcrumbs":4,"title":2},"1680":{"body":34,"breadcrumbs":6,"title":4},"1681":{"body":42,"breadcrumbs":5,"title":3},"1682":{"body":83,"breadcrumbs":6,"title":4},"1683":{"body":55,"breadcrumbs":6,"title":4},"1684":{"body":40,"breadcrumbs":5,"title":3},"1685":{"body":51,"breadcrumbs":5,"title":3},"1686":{"body":0,"breadcrumbs":5,"title":3},"1687":{"body":79,"breadcrumbs":6,"title":4},"1688":{"body":86,"breadcrumbs":8,"title":6},"1689":{"body":0,"breadcrumbs":4,"title":2},"169":{"body":0,"breadcrumbs":5,"title":3},"1690":{"body":35,"breadcrumbs":4,"title":2},"1691":{"body":18,"breadcrumbs":4,"title":2},"1692":{"body":20,"breadcrumbs":4,"title":2},"1693":{"body":0,"breadcrumbs":4,"title":2},"1694":{"body":42,"breadcrumbs":4,"title":2},"1695":{"body":23,"breadcrumbs":3,"title":1},"1696":{"body":0,"breadcrumbs":4,"title":2},"1697":{"body":36,"breadcrumbs":4,"title":2},"1698":{"body":13,"breadcrumbs":4,"title":2},"1699":{"body":0,"breadcrumbs":3,"title":1},"17":{"body":17,"breadcrumbs":6,"title":4},"170":{"body":10,"breadcrumbs":5,"title":3},"1700":{"body":12,"breadcrumbs":4,"title":2},"1701":{"body":13,"breadcrumbs":5,"title":3},"1702":{"body":12,"breadcrumbs":5,"title":3},"1703":{"body":22,"breadcrumbs":4,"title":2},"1704":{"body":15,"breadcrumbs":6,"title":4},"1705":{"body":0,"breadcrumbs":4,"title":2},"1706":{"body":274,"breadcrumbs":5,"title":3},"1707":{"body":363,"breadcrumbs":5,"title":3},"1708":{"body":0,"breadcrumbs":4,"title":2},"1709":{"body":26,"breadcrumbs":6,"title":4},"171":{"body":7,"breadcrumbs":5,"title":3},"1710":{"body":26,"breadcrumbs":6,"title":4},"1711":{"body":0,"breadcrumbs":3,"title":1},"1712":{"body":18,"breadcrumbs":4,"title":2},"1713":{"body":18,"breadcrumbs":4,"title":2},"1714":{"body":0,"breadcrumbs":3,"title":1},"1715":{"body":23,"breadcrumbs":5,"title":3},"1716":{"body":14,"breadcrumbs":4,"title":2},"1717":{"body":18,"breadcrumbs":6,"title":3},"1718":{"body":0,"breadcrumbs":4,"title":1},"1719":{"body":45,"breadcrumbs":5,"title":2},"172":{"body":7,"breadcrumbs":5,"title":3},"1720":{"body":29,"breadcrumbs":5,"title":2},"1721":{"body":0,"breadcrumbs":4,"title":1},"1722":{"body":29,"breadcrumbs":5,"title":2},"1723":{"body":60,"breadcrumbs":5,"title":2},"1724":{"body":0,"breadcrumbs":5,"title":2},"1725":{"body":236,"breadcrumbs":4,"title":1},"1726":{"body":0,"breadcrumbs":6,"title":3},"1727":{"body":20,"breadcrumbs":5,"title":2},"1728":{"body":23,"breadcrumbs":5,"title":2},"1729":{"body":0,"breadcrumbs":5,"title":2},"173":{"body":21,"breadcrumbs":6,"title":4},"1730":{"body":31,"breadcrumbs":4,"title":1},"1731":{"body":28,"breadcrumbs":5,"title":2},"1732":{"body":0,"breadcrumbs":5,"title":2},"1733":{"body":26,"breadcrumbs":5,"title":2},"1734":{"body":29,"breadcrumbs":5,"title":2},"1735":{"body":0,"breadcrumbs":5,"title":2},"1736":{"body":28,"breadcrumbs":4,"title":1},"1737":{"body":11,"breadcrumbs":4,"title":1},"1738":{"body":18,"breadcrumbs":5,"title":2},"1739":{"body":0,"breadcrumbs":5,"title":2},"174":{"body":45,"breadcrumbs":4,"title":2},"1740":{"body":11,"breadcrumbs":4,"title":1},"1741":{"body":19,"breadcrumbs":4,"title":1},"1742":{"body":0,"breadcrumbs":4,"title":1},"1743":{"body":22,"breadcrumbs":6,"title":3},"1744":{"body":15,"breadcrumbs":6,"title":3},"1745":{"body":16,"breadcrumbs":5,"title":2},"1746":{"body":21,"breadcrumbs":6,"title":3},"1747":{"body":0,"breadcrumbs":4,"title":1},"1748":{"body":24,"breadcrumbs":4,"title":1},"1749":{"body":16,"breadcrumbs":5,"title":2},"175":{"body":31,"breadcrumbs":4,"title":2},"1750":{"body":0,"breadcrumbs":6,"title":3},"1751":{"body":48,"breadcrumbs":5,"title":2},"1752":{"body":63,"breadcrumbs":5,"title":2},"1753":{"body":0,"breadcrumbs":6,"title":3},"1754":{"body":106,"breadcrumbs":5,"title":2},"1755":{"body":37,"breadcrumbs":4,"title":1},"1756":{"body":0,"breadcrumbs":5,"title":2},"1757":{"body":59,"breadcrumbs":5,"title":2},"1758":{"body":54,"breadcrumbs":5,"title":2},"1759":{"body":36,"breadcrumbs":4,"title":1},"176":{"body":26,"breadcrumbs":5,"title":3},"1760":{"body":0,"breadcrumbs":6,"title":3},"1761":{"body":63,"breadcrumbs":5,"title":2},"1762":{"body":0,"breadcrumbs":5,"title":2},"1763":{"body":35,"breadcrumbs":4,"title":1},"1764":{"body":26,"breadcrumbs":4,"title":1},"1765":{"body":29,"breadcrumbs":5,"title":2},"1766":{"body":5,"breadcrumbs":4,"title":1},"1767":{"body":0,"breadcrumbs":4,"title":1},"1768":{"body":26,"breadcrumbs":5,"title":2},"1769":{"body":16,"breadcrumbs":6,"title":3},"177":{"body":15,"breadcrumbs":4,"title":2},"1770":{"body":0,"breadcrumbs":5,"title":2},"1771":{"body":28,"breadcrumbs":5,"title":2},"1772":{"body":27,"breadcrumbs":5,"title":2},"1773":{"body":18,"breadcrumbs":5,"title":2},"1774":{"body":12,"breadcrumbs":6,"title":3},"1775":{"body":34,"breadcrumbs":4,"title":1},"1776":{"body":0,"breadcrumbs":4,"title":1},"1777":{"body":71,"breadcrumbs":6,"title":3},"1778":{"body":0,"breadcrumbs":5,"title":2},"1779":{"body":32,"breadcrumbs":5,"title":2},"178":{"body":3,"breadcrumbs":4,"title":2},"1780":{"body":75,"breadcrumbs":5,"title":2},"1781":{"body":47,"breadcrumbs":5,"title":2},"1782":{"body":0,"breadcrumbs":7,"title":4},"1783":{"body":46,"breadcrumbs":4,"title":1},"1784":{"body":292,"breadcrumbs":5,"title":2},"1785":{"body":0,"breadcrumbs":5,"title":2},"1786":{"body":28,"breadcrumbs":5,"title":2},"1787":{"body":23,"breadcrumbs":5,"title":2},"1788":{"body":0,"breadcrumbs":4,"title":1},"1789":{"body":23,"breadcrumbs":6,"title":3},"179":{"body":17,"breadcrumbs":3,"title":1},"1790":{"body":38,"breadcrumbs":5,"title":2},"1791":{"body":0,"breadcrumbs":5,"title":2},"1792":{"body":23,"breadcrumbs":5,"title":2},"1793":{"body":24,"breadcrumbs":6,"title":3},"1794":{"body":16,"breadcrumbs":6,"title":3},"1795":{"body":0,"breadcrumbs":5,"title":2},"1796":{"body":35,"breadcrumbs":6,"title":3},"1797":{"body":22,"breadcrumbs":5,"title":2},"1798":{"body":38,"breadcrumbs":4,"title":1},"1799":{"body":21,"breadcrumbs":5,"title":2},"18":{"body":5,"breadcrumbs":5,"title":3},"180":{"body":35,"breadcrumbs":3,"title":1},"181":{"body":7,"breadcrumbs":4,"title":2},"182":{"body":27,"breadcrumbs":5,"title":3},"183":{"body":21,"breadcrumbs":5,"title":3},"184":{"body":22,"breadcrumbs":5,"title":3},"185":{"body":71,"breadcrumbs":4,"title":2},"186":{"body":0,"breadcrumbs":4,"title":2},"187":{"body":15,"breadcrumbs":6,"title":4},"188":{"body":14,"breadcrumbs":6,"title":4},"189":{"body":28,"breadcrumbs":6,"title":4},"19":{"body":13,"breadcrumbs":6,"title":4},"190":{"body":18,"breadcrumbs":6,"title":4},"191":{"body":12,"breadcrumbs":6,"title":4},"192":{"body":71,"breadcrumbs":4,"title":2},"193":{"body":25,"breadcrumbs":4,"title":2},"194":{"body":0,"breadcrumbs":3,"title":1},"195":{"body":14,"breadcrumbs":4,"title":2},"196":{"body":9,"breadcrumbs":4,"title":2},"197":{"body":12,"breadcrumbs":5,"title":3},"198":{"body":9,"breadcrumbs":4,"title":2},"199":{"body":5,"breadcrumbs":4,"title":2},"2":{"body":59,"breadcrumbs":3,"title":2},"20":{"body":27,"breadcrumbs":5,"title":3},"200":{"body":16,"breadcrumbs":3,"title":1},"201":{"body":86,"breadcrumbs":4,"title":2},"202":{"body":0,"breadcrumbs":4,"title":2},"203":{"body":26,"breadcrumbs":6,"title":4},"204":{"body":17,"breadcrumbs":6,"title":4},"205":{"body":70,"breadcrumbs":4,"title":2},"206":{"body":0,"breadcrumbs":4,"title":2},"207":{"body":29,"breadcrumbs":4,"title":2},"208":{"body":40,"breadcrumbs":4,"title":2},"209":{"body":23,"breadcrumbs":4,"title":2},"21":{"body":51,"breadcrumbs":4,"title":2},"210":{"body":0,"breadcrumbs":4,"title":2},"211":{"body":56,"breadcrumbs":5,"title":3},"212":{"body":43,"breadcrumbs":5,"title":3},"213":{"body":55,"breadcrumbs":5,"title":3},"214":{"body":0,"breadcrumbs":4,"title":2},"215":{"body":26,"breadcrumbs":7,"title":5},"216":{"body":20,"breadcrumbs":6,"title":4},"217":{"body":18,"breadcrumbs":6,"title":4},"218":{"body":0,"breadcrumbs":4,"title":2},"219":{"body":23,"breadcrumbs":4,"title":2},"22":{"body":24,"breadcrumbs":4,"title":2},"220":{"body":39,"breadcrumbs":4,"title":2},"221":{"body":0,"breadcrumbs":5,"title":3},"222":{"body":45,"breadcrumbs":8,"title":6},"223":{"body":35,"breadcrumbs":8,"title":6},"224":{"body":39,"breadcrumbs":6,"title":4},"225":{"body":24,"breadcrumbs":4,"title":2},"226":{"body":0,"breadcrumbs":3,"title":1},"227":{"body":14,"breadcrumbs":4,"title":2},"228":{"body":9,"breadcrumbs":4,"title":2},"229":{"body":20,"breadcrumbs":5,"title":3},"23":{"body":22,"breadcrumbs":4,"title":2},"230":{"body":7,"breadcrumbs":4,"title":2},"231":{"body":6,"breadcrumbs":4,"title":2},"232":{"body":17,"breadcrumbs":3,"title":1},"233":{"body":33,"breadcrumbs":4,"title":2},"234":{"body":0,"breadcrumbs":4,"title":2},"235":{"body":44,"breadcrumbs":5,"title":3},"236":{"body":36,"breadcrumbs":5,"title":3},"237":{"body":23,"breadcrumbs":5,"title":3},"238":{"body":39,"breadcrumbs":5,"title":3},"239":{"body":32,"breadcrumbs":5,"title":3},"24":{"body":17,"breadcrumbs":4,"title":2},"240":{"body":0,"breadcrumbs":4,"title":2},"241":{"body":24,"breadcrumbs":4,"title":2},"242":{"body":41,"breadcrumbs":4,"title":2},"243":{"body":26,"breadcrumbs":4,"title":2},"244":{"body":13,"breadcrumbs":4,"title":2},"245":{"body":20,"breadcrumbs":5,"title":3},"246":{"body":32,"breadcrumbs":5,"title":3},"247":{"body":0,"breadcrumbs":4,"title":2},"248":{"body":34,"breadcrumbs":4,"title":2},"249":{"body":22,"breadcrumbs":5,"title":3},"25":{"body":18,"breadcrumbs":4,"title":2},"250":{"body":26,"breadcrumbs":4,"title":2},"251":{"body":0,"breadcrumbs":4,"title":2},"252":{"body":25,"breadcrumbs":4,"title":2},"253":{"body":19,"breadcrumbs":4,"title":2},"254":{"body":28,"breadcrumbs":4,"title":2},"255":{"body":0,"breadcrumbs":4,"title":2},"256":{"body":24,"breadcrumbs":4,"title":2},"257":{"body":14,"breadcrumbs":4,"title":2},"258":{"body":19,"breadcrumbs":4,"title":2},"259":{"body":41,"breadcrumbs":4,"title":2},"26":{"body":9,"breadcrumbs":2,"title":1},"260":{"body":0,"breadcrumbs":4,"title":2},"261":{"body":29,"breadcrumbs":5,"title":3},"262":{"body":20,"breadcrumbs":6,"title":4},"263":{"body":21,"breadcrumbs":5,"title":3},"264":{"body":21,"breadcrumbs":5,"title":3},"265":{"body":0,"breadcrumbs":3,"title":1},"266":{"body":17,"breadcrumbs":4,"title":2},"267":{"body":20,"breadcrumbs":5,"title":3},"268":{"body":20,"breadcrumbs":5,"title":3},"269":{"body":7,"breadcrumbs":4,"title":2},"27":{"body":0,"breadcrumbs":3,"title":2},"270":{"body":13,"breadcrumbs":4,"title":2},"271":{"body":56,"breadcrumbs":3,"title":1},"272":{"body":0,"breadcrumbs":4,"title":2},"273":{"body":11,"breadcrumbs":6,"title":4},"274":{"body":11,"breadcrumbs":5,"title":3},"275":{"body":40,"breadcrumbs":5,"title":3},"276":{"body":44,"breadcrumbs":5,"title":3},"277":{"body":31,"breadcrumbs":4,"title":2},"278":{"body":0,"breadcrumbs":4,"title":2},"279":{"body":60,"breadcrumbs":3,"title":1},"28":{"body":33,"breadcrumbs":3,"title":2},"280":{"body":41,"breadcrumbs":4,"title":2},"281":{"body":0,"breadcrumbs":4,"title":2},"282":{"body":12,"breadcrumbs":9,"title":7},"283":{"body":19,"breadcrumbs":10,"title":8},"284":{"body":24,"breadcrumbs":10,"title":8},"285":{"body":23,"breadcrumbs":9,"title":7},"286":{"body":17,"breadcrumbs":4,"title":2},"287":{"body":20,"breadcrumbs":4,"title":2},"288":{"body":49,"breadcrumbs":3,"title":1},"289":{"body":0,"breadcrumbs":5,"title":3},"29":{"body":40,"breadcrumbs":3,"title":2},"290":{"body":27,"breadcrumbs":4,"title":2},"291":{"body":75,"breadcrumbs":5,"title":3},"292":{"body":75,"breadcrumbs":5,"title":3},"293":{"body":28,"breadcrumbs":5,"title":3},"294":{"body":0,"breadcrumbs":6,"title":4},"295":{"body":36,"breadcrumbs":5,"title":3},"296":{"body":35,"breadcrumbs":4,"title":2},"297":{"body":100,"breadcrumbs":4,"title":2},"298":{"body":23,"breadcrumbs":4,"title":2},"299":{"body":0,"breadcrumbs":7,"title":5},"3":{"body":20,"breadcrumbs":3,"title":2},"30":{"body":36,"breadcrumbs":3,"title":2},"300":{"body":57,"breadcrumbs":4,"title":2},"301":{"body":36,"breadcrumbs":4,"title":2},"302":{"body":0,"breadcrumbs":6,"title":4},"303":{"body":41,"breadcrumbs":5,"title":3},"304":{"body":65,"breadcrumbs":5,"title":3},"305":{"body":47,"breadcrumbs":4,"title":2},"306":{"body":42,"breadcrumbs":5,"title":3},"307":{"body":30,"breadcrumbs":4,"title":2},"308":{"body":0,"breadcrumbs":7,"title":5},"309":{"body":73,"breadcrumbs":5,"title":3},"31":{"body":45,"breadcrumbs":3,"title":2},"310":{"body":24,"breadcrumbs":5,"title":3},"311":{"body":85,"breadcrumbs":5,"title":3},"312":{"body":52,"breadcrumbs":5,"title":3},"313":{"body":0,"breadcrumbs":6,"title":4},"314":{"body":26,"breadcrumbs":5,"title":3},"315":{"body":37,"breadcrumbs":5,"title":3},"316":{"body":16,"breadcrumbs":5,"title":3},"317":{"body":30,"breadcrumbs":4,"title":2},"318":{"body":0,"breadcrumbs":7,"title":5},"319":{"body":75,"breadcrumbs":6,"title":4},"32":{"body":31,"breadcrumbs":3,"title":2},"320":{"body":21,"breadcrumbs":6,"title":4},"321":{"body":0,"breadcrumbs":6,"title":4},"322":{"body":25,"breadcrumbs":5,"title":3},"323":{"body":26,"breadcrumbs":4,"title":2},"324":{"body":22,"breadcrumbs":4,"title":2},"325":{"body":0,"breadcrumbs":6,"title":4},"326":{"body":67,"breadcrumbs":5,"title":3},"327":{"body":20,"breadcrumbs":5,"title":3},"328":{"body":0,"breadcrumbs":3,"title":1},"329":{"body":85,"breadcrumbs":4,"title":2},"33":{"body":0,"breadcrumbs":3,"title":2},"330":{"body":0,"breadcrumbs":4,"title":2},"331":{"body":13,"breadcrumbs":4,"title":2},"332":{"body":11,"breadcrumbs":4,"title":2},"333":{"body":20,"breadcrumbs":4,"title":2},"334":{"body":40,"breadcrumbs":3,"title":1},"335":{"body":0,"breadcrumbs":4,"title":2},"336":{"body":23,"breadcrumbs":6,"title":3},"337":{"body":41,"breadcrumbs":4,"title":1},"338":{"body":0,"breadcrumbs":6,"title":3},"339":{"body":56,"breadcrumbs":8,"title":5},"34":{"body":12,"breadcrumbs":2,"title":1},"340":{"body":51,"breadcrumbs":8,"title":5},"341":{"body":53,"breadcrumbs":8,"title":5},"342":{"body":55,"breadcrumbs":8,"title":5},"343":{"body":0,"breadcrumbs":5,"title":2},"344":{"body":124,"breadcrumbs":7,"title":4},"345":{"body":114,"breadcrumbs":7,"title":4},"346":{"body":0,"breadcrumbs":5,"title":2},"347":{"body":58,"breadcrumbs":7,"title":4},"348":{"body":51,"breadcrumbs":7,"title":4},"349":{"body":93,"breadcrumbs":9,"title":6},"35":{"body":23,"breadcrumbs":3,"title":2},"350":{"body":0,"breadcrumbs":5,"title":2},"351":{"body":58,"breadcrumbs":7,"title":4},"352":{"body":69,"breadcrumbs":6,"title":3},"353":{"body":0,"breadcrumbs":5,"title":2},"354":{"body":60,"breadcrumbs":6,"title":3},"355":{"body":46,"breadcrumbs":6,"title":3},"356":{"body":0,"breadcrumbs":6,"title":3},"357":{"body":59,"breadcrumbs":5,"title":2},"358":{"body":98,"breadcrumbs":6,"title":3},"359":{"body":0,"breadcrumbs":5,"title":2},"36":{"body":19,"breadcrumbs":3,"title":2},"360":{"body":63,"breadcrumbs":6,"title":3},"361":{"body":40,"breadcrumbs":6,"title":3},"362":{"body":0,"breadcrumbs":6,"title":3},"363":{"body":62,"breadcrumbs":5,"title":2},"364":{"body":0,"breadcrumbs":5,"title":2},"365":{"body":48,"breadcrumbs":6,"title":3},"366":{"body":0,"breadcrumbs":5,"title":2},"367":{"body":22,"breadcrumbs":5,"title":2},"368":{"body":23,"breadcrumbs":4,"title":1},"369":{"body":24,"breadcrumbs":4,"title":1},"37":{"body":24,"breadcrumbs":2,"title":1},"370":{"body":19,"breadcrumbs":4,"title":1},"371":{"body":23,"breadcrumbs":5,"title":2},"372":{"body":0,"breadcrumbs":4,"title":1},"373":{"body":28,"breadcrumbs":6,"title":3},"374":{"body":37,"breadcrumbs":7,"title":4},"375":{"body":32,"breadcrumbs":6,"title":3},"376":{"body":17,"breadcrumbs":4,"title":1},"377":{"body":12,"breadcrumbs":4,"title":2},"378":{"body":22,"breadcrumbs":3,"title":1},"379":{"body":0,"breadcrumbs":4,"title":2},"38":{"body":0,"breadcrumbs":3,"title":2},"380":{"body":14,"breadcrumbs":3,"title":1},"381":{"body":11,"breadcrumbs":4,"title":2},"382":{"body":12,"breadcrumbs":3,"title":1},"383":{"body":0,"breadcrumbs":5,"title":3},"384":{"body":16,"breadcrumbs":4,"title":2},"385":{"body":28,"breadcrumbs":5,"title":3},"386":{"body":55,"breadcrumbs":5,"title":3},"387":{"body":0,"breadcrumbs":6,"title":4},"388":{"body":16,"breadcrumbs":4,"title":2},"389":{"body":25,"breadcrumbs":5,"title":3},"39":{"body":41,"breadcrumbs":3,"title":2},"390":{"body":46,"breadcrumbs":5,"title":3},"391":{"body":30,"breadcrumbs":6,"title":4},"392":{"body":0,"breadcrumbs":5,"title":3},"393":{"body":9,"breadcrumbs":4,"title":2},"394":{"body":37,"breadcrumbs":5,"title":3},"395":{"body":0,"breadcrumbs":4,"title":2},"396":{"body":25,"breadcrumbs":4,"title":2},"397":{"body":23,"breadcrumbs":4,"title":2},"398":{"body":35,"breadcrumbs":5,"title":3},"399":{"body":0,"breadcrumbs":4,"title":2},"4":{"body":55,"breadcrumbs":3,"title":2},"40":{"body":32,"breadcrumbs":4,"title":3},"400":{"body":17,"breadcrumbs":4,"title":2},"401":{"body":18,"breadcrumbs":4,"title":2},"402":{"body":0,"breadcrumbs":3,"title":1},"403":{"body":15,"breadcrumbs":5,"title":3},"404":{"body":17,"breadcrumbs":5,"title":3},"405":{"body":0,"breadcrumbs":3,"title":1},"406":{"body":15,"breadcrumbs":4,"title":2},"407":{"body":16,"breadcrumbs":4,"title":2},"408":{"body":13,"breadcrumbs":3,"title":1},"409":{"body":8,"breadcrumbs":4,"title":2},"41":{"body":33,"breadcrumbs":3,"title":2},"410":{"body":20,"breadcrumbs":3,"title":1},"411":{"body":0,"breadcrumbs":4,"title":2},"412":{"body":16,"breadcrumbs":6,"title":4},"413":{"body":21,"breadcrumbs":6,"title":4},"414":{"body":0,"breadcrumbs":4,"title":2},"415":{"body":34,"breadcrumbs":4,"title":2},"416":{"body":58,"breadcrumbs":4,"title":2},"417":{"body":0,"breadcrumbs":4,"title":2},"418":{"body":23,"breadcrumbs":5,"title":3},"419":{"body":20,"breadcrumbs":4,"title":2},"42":{"body":41,"breadcrumbs":4,"title":3},"420":{"body":0,"breadcrumbs":4,"title":2},"421":{"body":51,"breadcrumbs":5,"title":3},"422":{"body":48,"breadcrumbs":4,"title":2},"423":{"body":45,"breadcrumbs":5,"title":3},"424":{"body":0,"breadcrumbs":4,"title":2},"425":{"body":23,"breadcrumbs":4,"title":2},"426":{"body":28,"breadcrumbs":4,"title":2},"427":{"body":0,"breadcrumbs":4,"title":2},"428":{"body":27,"breadcrumbs":4,"title":2},"429":{"body":26,"breadcrumbs":4,"title":2},"43":{"body":0,"breadcrumbs":3,"title":2},"430":{"body":23,"breadcrumbs":4,"title":2},"431":{"body":0,"breadcrumbs":4,"title":2},"432":{"body":12,"breadcrumbs":4,"title":2},"433":{"body":34,"breadcrumbs":5,"title":3},"434":{"body":42,"breadcrumbs":4,"title":2},"435":{"body":0,"breadcrumbs":4,"title":2},"436":{"body":27,"breadcrumbs":4,"title":2},"437":{"body":20,"breadcrumbs":4,"title":2},"438":{"body":41,"breadcrumbs":4,"title":2},"439":{"body":11,"breadcrumbs":3,"title":1},"44":{"body":31,"breadcrumbs":3,"title":2},"440":{"body":13,"breadcrumbs":4,"title":2},"441":{"body":87,"breadcrumbs":3,"title":1},"442":{"body":0,"breadcrumbs":5,"title":3},"443":{"body":34,"breadcrumbs":4,"title":2},"444":{"body":50,"breadcrumbs":4,"title":2},"445":{"body":31,"breadcrumbs":4,"title":2},"446":{"body":61,"breadcrumbs":5,"title":3},"447":{"body":32,"breadcrumbs":4,"title":2},"448":{"body":0,"breadcrumbs":5,"title":3},"449":{"body":11,"breadcrumbs":5,"title":3},"45":{"body":20,"breadcrumbs":4,"title":3},"450":{"body":7,"breadcrumbs":5,"title":3},"451":{"body":9,"breadcrumbs":5,"title":3},"452":{"body":8,"breadcrumbs":6,"title":4},"453":{"body":13,"breadcrumbs":6,"title":4},"454":{"body":7,"breadcrumbs":6,"title":4},"455":{"body":8,"breadcrumbs":6,"title":4},"456":{"body":49,"breadcrumbs":5,"title":3},"457":{"body":25,"breadcrumbs":4,"title":2},"458":{"body":28,"breadcrumbs":4,"title":2},"459":{"body":25,"breadcrumbs":4,"title":2},"46":{"body":70,"breadcrumbs":3,"title":2},"460":{"body":9,"breadcrumbs":4,"title":2},"461":{"body":33,"breadcrumbs":7,"title":5},"462":{"body":41,"breadcrumbs":3,"title":1},"463":{"body":17,"breadcrumbs":3,"title":1},"464":{"body":0,"breadcrumbs":4,"title":2},"465":{"body":12,"breadcrumbs":4,"title":2},"466":{"body":16,"breadcrumbs":4,"title":2},"467":{"body":29,"breadcrumbs":4,"title":2},"468":{"body":24,"breadcrumbs":5,"title":3},"469":{"body":7,"breadcrumbs":7,"title":5},"47":{"body":15,"breadcrumbs":3,"title":2},"470":{"body":39,"breadcrumbs":6,"title":4},"471":{"body":23,"breadcrumbs":6,"title":4},"472":{"body":43,"breadcrumbs":6,"title":4},"473":{"body":27,"breadcrumbs":4,"title":2},"474":{"body":27,"breadcrumbs":5,"title":3},"475":{"body":0,"breadcrumbs":5,"title":3},"476":{"body":17,"breadcrumbs":5,"title":3},"477":{"body":23,"breadcrumbs":4,"title":2},"478":{"body":21,"breadcrumbs":4,"title":2},"479":{"body":41,"breadcrumbs":4,"title":2},"48":{"body":6,"breadcrumbs":2,"title":1},"480":{"body":0,"breadcrumbs":4,"title":2},"481":{"body":9,"breadcrumbs":4,"title":2},"482":{"body":12,"breadcrumbs":4,"title":2},"483":{"body":10,"breadcrumbs":4,"title":2},"484":{"body":6,"breadcrumbs":4,"title":2},"485":{"body":5,"breadcrumbs":4,"title":2},"486":{"body":0,"breadcrumbs":4,"title":2},"487":{"body":19,"breadcrumbs":4,"title":2},"488":{"body":7,"breadcrumbs":5,"title":3},"489":{"body":0,"breadcrumbs":5,"title":3},"49":{"body":5,"breadcrumbs":2,"title":1},"490":{"body":28,"breadcrumbs":5,"title":3},"491":{"body":74,"breadcrumbs":5,"title":3},"492":{"body":37,"breadcrumbs":6,"title":4},"493":{"body":0,"breadcrumbs":4,"title":2},"494":{"body":27,"breadcrumbs":5,"title":3},"495":{"body":15,"breadcrumbs":4,"title":2},"496":{"body":0,"breadcrumbs":4,"title":2},"497":{"body":32,"breadcrumbs":7,"title":5},"498":{"body":8,"breadcrumbs":5,"title":3},"499":{"body":0,"breadcrumbs":4,"title":2},"5":{"body":19,"breadcrumbs":3,"title":2},"50":{"body":0,"breadcrumbs":3,"title":2},"500":{"body":19,"breadcrumbs":5,"title":3},"501":{"body":21,"breadcrumbs":4,"title":2},"502":{"body":25,"breadcrumbs":4,"title":2},"503":{"body":54,"breadcrumbs":4,"title":2},"504":{"body":0,"breadcrumbs":3,"title":1},"505":{"body":9,"breadcrumbs":4,"title":2},"506":{"body":15,"breadcrumbs":4,"title":2},"507":{"body":15,"breadcrumbs":4,"title":2},"508":{"body":19,"breadcrumbs":4,"title":2},"509":{"body":14,"breadcrumbs":4,"title":2},"51":{"body":13,"breadcrumbs":5,"title":4},"510":{"body":44,"breadcrumbs":4,"title":2},"511":{"body":0,"breadcrumbs":4,"title":2},"512":{"body":15,"breadcrumbs":4,"title":2},"513":{"body":17,"breadcrumbs":4,"title":2},"514":{"body":25,"breadcrumbs":4,"title":2},"515":{"body":18,"breadcrumbs":4,"title":2},"516":{"body":32,"breadcrumbs":4,"title":2},"517":{"body":23,"breadcrumbs":3,"title":1},"518":{"body":17,"breadcrumbs":4,"title":2},"519":{"body":28,"breadcrumbs":4,"title":2},"52":{"body":51,"breadcrumbs":6,"title":5},"520":{"body":28,"breadcrumbs":4,"title":2},"521":{"body":48,"breadcrumbs":4,"title":2},"522":{"body":0,"breadcrumbs":3,"title":1},"523":{"body":17,"breadcrumbs":4,"title":2},"524":{"body":11,"breadcrumbs":5,"title":3},"525":{"body":18,"breadcrumbs":5,"title":3},"526":{"body":12,"breadcrumbs":3,"title":1},"527":{"body":15,"breadcrumbs":4,"title":2},"528":{"body":72,"breadcrumbs":4,"title":2},"529":{"body":0,"breadcrumbs":4,"title":2},"53":{"body":26,"breadcrumbs":5,"title":4},"530":{"body":57,"breadcrumbs":4,"title":2},"531":{"body":30,"breadcrumbs":4,"title":2},"532":{"body":29,"breadcrumbs":4,"title":2},"533":{"body":50,"breadcrumbs":4,"title":2},"534":{"body":0,"breadcrumbs":4,"title":2},"535":{"body":36,"breadcrumbs":4,"title":2},"536":{"body":31,"breadcrumbs":4,"title":2},"537":{"body":0,"breadcrumbs":4,"title":2},"538":{"body":62,"breadcrumbs":4,"title":2},"539":{"body":37,"breadcrumbs":4,"title":2},"54":{"body":23,"breadcrumbs":5,"title":4},"540":{"body":21,"breadcrumbs":4,"title":2},"541":{"body":22,"breadcrumbs":4,"title":2},"542":{"body":50,"breadcrumbs":4,"title":2},"543":{"body":13,"breadcrumbs":3,"title":1},"544":{"body":15,"breadcrumbs":2,"title":1},"545":{"body":0,"breadcrumbs":3,"title":2},"546":{"body":48,"breadcrumbs":3,"title":2},"547":{"body":27,"breadcrumbs":3,"title":2},"548":{"body":17,"breadcrumbs":3,"title":2},"549":{"body":26,"breadcrumbs":4,"title":3},"55":{"body":44,"breadcrumbs":7,"title":6},"550":{"body":54,"breadcrumbs":3,"title":2},"551":{"body":36,"breadcrumbs":3,"title":2},"552":{"body":13,"breadcrumbs":2,"title":1},"553":{"body":17,"breadcrumbs":4,"title":2},"554":{"body":0,"breadcrumbs":3,"title":1},"555":{"body":45,"breadcrumbs":5,"title":3},"556":{"body":32,"breadcrumbs":3,"title":1},"557":{"body":26,"breadcrumbs":3,"title":1},"558":{"body":27,"breadcrumbs":4,"title":2},"559":{"body":30,"breadcrumbs":3,"title":1},"56":{"body":63,"breadcrumbs":6,"title":5},"560":{"body":21,"breadcrumbs":3,"title":1},"561":{"body":20,"breadcrumbs":5,"title":3},"562":{"body":0,"breadcrumbs":5,"title":3},"563":{"body":31,"breadcrumbs":3,"title":1},"564":{"body":37,"breadcrumbs":4,"title":2},"565":{"body":64,"breadcrumbs":5,"title":3},"566":{"body":21,"breadcrumbs":5,"title":3},"567":{"body":15,"breadcrumbs":3,"title":1},"568":{"body":30,"breadcrumbs":4,"title":2},"569":{"body":35,"breadcrumbs":4,"title":2},"57":{"body":16,"breadcrumbs":5,"title":4},"570":{"body":11,"breadcrumbs":3,"title":1},"571":{"body":13,"breadcrumbs":2,"title":1},"572":{"body":0,"breadcrumbs":3,"title":2},"573":{"body":56,"breadcrumbs":3,"title":2},"574":{"body":44,"breadcrumbs":4,"title":3},"575":{"body":71,"breadcrumbs":3,"title":2},"576":{"body":0,"breadcrumbs":3,"title":2},"577":{"body":47,"breadcrumbs":3,"title":2},"578":{"body":26,"breadcrumbs":3,"title":2},"579":{"body":23,"breadcrumbs":3,"title":2},"58":{"body":8,"breadcrumbs":5,"title":4},"580":{"body":46,"breadcrumbs":4,"title":3},"581":{"body":0,"breadcrumbs":3,"title":2},"582":{"body":27,"breadcrumbs":2,"title":1},"583":{"body":27,"breadcrumbs":2,"title":1},"584":{"body":27,"breadcrumbs":3,"title":2},"585":{"body":37,"breadcrumbs":2,"title":1},"586":{"body":39,"breadcrumbs":3,"title":2},"587":{"body":12,"breadcrumbs":2,"title":1},"588":{"body":16,"breadcrumbs":4,"title":2},"589":{"body":20,"breadcrumbs":3,"title":1},"59":{"body":12,"breadcrumbs":4,"title":3},"590":{"body":85,"breadcrumbs":4,"title":2},"591":{"body":26,"breadcrumbs":4,"title":2},"592":{"body":0,"breadcrumbs":4,"title":2},"593":{"body":14,"breadcrumbs":4,"title":2},"594":{"body":12,"breadcrumbs":4,"title":2},"595":{"body":12,"breadcrumbs":4,"title":2},"596":{"body":23,"breadcrumbs":4,"title":2},"597":{"body":0,"breadcrumbs":4,"title":2},"598":{"body":31,"breadcrumbs":4,"title":2},"599":{"body":15,"breadcrumbs":4,"title":2},"6":{"body":29,"breadcrumbs":4,"title":3},"60":{"body":16,"breadcrumbs":5,"title":4},"600":{"body":18,"breadcrumbs":4,"title":2},"601":{"body":0,"breadcrumbs":4,"title":2},"602":{"body":17,"breadcrumbs":3,"title":1},"603":{"body":28,"breadcrumbs":3,"title":1},"604":{"body":0,"breadcrumbs":3,"title":1},"605":{"body":15,"breadcrumbs":4,"title":2},"606":{"body":19,"breadcrumbs":4,"title":2},"607":{"body":0,"breadcrumbs":4,"title":2},"608":{"body":44,"breadcrumbs":4,"title":2},"609":{"body":21,"breadcrumbs":4,"title":2},"61":{"body":52,"breadcrumbs":4,"title":3},"610":{"body":0,"breadcrumbs":4,"title":2},"611":{"body":24,"breadcrumbs":4,"title":2},"612":{"body":38,"breadcrumbs":4,"title":2},"613":{"body":22,"breadcrumbs":3,"title":1},"614":{"body":40,"breadcrumbs":4,"title":2},"615":{"body":0,"breadcrumbs":3,"title":1},"616":{"body":26,"breadcrumbs":4,"title":2},"617":{"body":31,"breadcrumbs":4,"title":2},"618":{"body":11,"breadcrumbs":3,"title":1},"619":{"body":13,"breadcrumbs":4,"title":2},"62":{"body":37,"breadcrumbs":3,"title":2},"620":{"body":19,"breadcrumbs":3,"title":1},"621":{"body":32,"breadcrumbs":4,"title":2},"622":{"body":40,"breadcrumbs":4,"title":2},"623":{"body":41,"breadcrumbs":4,"title":2},"624":{"body":0,"breadcrumbs":4,"title":2},"625":{"body":34,"breadcrumbs":4,"title":2},"626":{"body":21,"breadcrumbs":4,"title":2},"627":{"body":32,"breadcrumbs":4,"title":2},"628":{"body":34,"breadcrumbs":4,"title":2},"629":{"body":39,"breadcrumbs":4,"title":2},"63":{"body":0,"breadcrumbs":2,"title":1},"630":{"body":13,"breadcrumbs":4,"title":2},"631":{"body":25,"breadcrumbs":4,"title":2},"632":{"body":38,"breadcrumbs":4,"title":2},"633":{"body":26,"breadcrumbs":4,"title":2},"634":{"body":22,"breadcrumbs":4,"title":2},"635":{"body":0,"breadcrumbs":3,"title":1},"636":{"body":12,"breadcrumbs":4,"title":2},"637":{"body":19,"breadcrumbs":4,"title":2},"638":{"body":12,"breadcrumbs":3,"title":1},"639":{"body":13,"breadcrumbs":4,"title":2},"64":{"body":84,"breadcrumbs":3,"title":2},"640":{"body":131,"breadcrumbs":3,"title":1},"641":{"body":0,"breadcrumbs":4,"title":2},"642":{"body":32,"breadcrumbs":4,"title":2},"643":{"body":37,"breadcrumbs":4,"title":2},"644":{"body":30,"breadcrumbs":5,"title":3},"645":{"body":56,"breadcrumbs":4,"title":2},"646":{"body":76,"breadcrumbs":4,"title":2},"647":{"body":0,"breadcrumbs":4,"title":2},"648":{"body":8,"breadcrumbs":5,"title":3},"649":{"body":11,"breadcrumbs":6,"title":4},"65":{"body":28,"breadcrumbs":2,"title":1},"650":{"body":10,"breadcrumbs":5,"title":3},"651":{"body":9,"breadcrumbs":5,"title":3},"652":{"body":9,"breadcrumbs":5,"title":3},"653":{"body":9,"breadcrumbs":5,"title":3},"654":{"body":9,"breadcrumbs":6,"title":4},"655":{"body":28,"breadcrumbs":4,"title":2},"656":{"body":25,"breadcrumbs":4,"title":2},"657":{"body":30,"breadcrumbs":4,"title":2},"658":{"body":60,"breadcrumbs":3,"title":1},"659":{"body":35,"breadcrumbs":4,"title":2},"66":{"body":18,"breadcrumbs":3,"title":2},"660":{"body":88,"breadcrumbs":4,"title":2},"661":{"body":40,"breadcrumbs":4,"title":2},"662":{"body":0,"breadcrumbs":4,"title":2},"663":{"body":26,"breadcrumbs":4,"title":2},"664":{"body":43,"breadcrumbs":4,"title":2},"665":{"body":44,"breadcrumbs":4,"title":2},"666":{"body":48,"breadcrumbs":4,"title":2},"667":{"body":52,"breadcrumbs":4,"title":2},"668":{"body":76,"breadcrumbs":4,"title":2},"669":{"body":9,"breadcrumbs":4,"title":2},"67":{"body":8,"breadcrumbs":4,"title":2},"670":{"body":53,"breadcrumbs":4,"title":2},"671":{"body":41,"breadcrumbs":4,"title":2},"672":{"body":5,"breadcrumbs":5,"title":3},"673":{"body":55,"breadcrumbs":8,"title":6},"674":{"body":37,"breadcrumbs":8,"title":6},"675":{"body":39,"breadcrumbs":6,"title":4},"676":{"body":0,"breadcrumbs":4,"title":2},"677":{"body":13,"breadcrumbs":4,"title":2},"678":{"body":32,"breadcrumbs":4,"title":2},"679":{"body":30,"breadcrumbs":4,"title":2},"68":{"body":12,"breadcrumbs":3,"title":1},"680":{"body":33,"breadcrumbs":4,"title":2},"681":{"body":0,"breadcrumbs":3,"title":1},"682":{"body":22,"breadcrumbs":5,"title":3},"683":{"body":19,"breadcrumbs":4,"title":2},"684":{"body":20,"breadcrumbs":6,"title":4},"685":{"body":0,"breadcrumbs":4,"title":2},"686":{"body":28,"breadcrumbs":4,"title":2},"687":{"body":18,"breadcrumbs":4,"title":2},"688":{"body":19,"breadcrumbs":4,"title":2},"689":{"body":23,"breadcrumbs":3,"title":1},"69":{"body":0,"breadcrumbs":5,"title":3},"690":{"body":30,"breadcrumbs":4,"title":2},"691":{"body":25,"breadcrumbs":3,"title":1},"692":{"body":34,"breadcrumbs":4,"title":2},"693":{"body":6,"breadcrumbs":4,"title":2},"694":{"body":59,"breadcrumbs":5,"title":3},"695":{"body":51,"breadcrumbs":5,"title":3},"696":{"body":54,"breadcrumbs":5,"title":3},"697":{"body":37,"breadcrumbs":5,"title":3},"698":{"body":53,"breadcrumbs":5,"title":3},"699":{"body":52,"breadcrumbs":5,"title":3},"7":{"body":13,"breadcrumbs":3,"title":2},"70":{"body":27,"breadcrumbs":8,"title":6},"700":{"body":41,"breadcrumbs":5,"title":3},"701":{"body":6,"breadcrumbs":4,"title":2},"702":{"body":26,"breadcrumbs":4,"title":2},"703":{"body":21,"breadcrumbs":4,"title":2},"704":{"body":27,"breadcrumbs":4,"title":2},"705":{"body":31,"breadcrumbs":4,"title":2},"706":{"body":17,"breadcrumbs":4,"title":2},"707":{"body":15,"breadcrumbs":5,"title":3},"708":{"body":41,"breadcrumbs":6,"title":4},"709":{"body":5,"breadcrumbs":5,"title":3},"71":{"body":50,"breadcrumbs":8,"title":6},"710":{"body":66,"breadcrumbs":4,"title":2},"711":{"body":43,"breadcrumbs":5,"title":3},"712":{"body":0,"breadcrumbs":4,"title":2},"713":{"body":70,"breadcrumbs":4,"title":2},"714":{"body":10,"breadcrumbs":4,"title":2},"715":{"body":20,"breadcrumbs":4,"title":2},"716":{"body":90,"breadcrumbs":4,"title":2},"717":{"body":97,"breadcrumbs":5,"title":3},"718":{"body":73,"breadcrumbs":4,"title":2},"719":{"body":56,"breadcrumbs":3,"title":1},"72":{"body":52,"breadcrumbs":8,"title":6},"720":{"body":6,"breadcrumbs":4,"title":2},"721":{"body":39,"breadcrumbs":5,"title":3},"722":{"body":26,"breadcrumbs":5,"title":3},"723":{"body":45,"breadcrumbs":4,"title":2},"724":{"body":0,"breadcrumbs":4,"title":2},"725":{"body":52,"breadcrumbs":5,"title":3},"726":{"body":28,"breadcrumbs":6,"title":4},"727":{"body":27,"breadcrumbs":5,"title":3},"728":{"body":6,"breadcrumbs":4,"title":2},"729":{"body":18,"breadcrumbs":4,"title":2},"73":{"body":41,"breadcrumbs":8,"title":6},"730":{"body":24,"breadcrumbs":4,"title":2},"731":{"body":19,"breadcrumbs":4,"title":2},"732":{"body":0,"breadcrumbs":3,"title":1},"733":{"body":12,"breadcrumbs":4,"title":2},"734":{"body":20,"breadcrumbs":4,"title":2},"735":{"body":16,"breadcrumbs":4,"title":2},"736":{"body":19,"breadcrumbs":3,"title":1},"737":{"body":0,"breadcrumbs":4,"title":2},"738":{"body":0,"breadcrumbs":4,"title":2},"739":{"body":0,"breadcrumbs":2,"title":1},"74":{"body":37,"breadcrumbs":9,"title":7},"740":{"body":0,"breadcrumbs":4,"title":2},"741":{"body":0,"breadcrumbs":4,"title":2},"742":{"body":0,"breadcrumbs":4,"title":2},"743":{"body":0,"breadcrumbs":4,"title":2},"744":{"body":0,"breadcrumbs":4,"title":2},"745":{"body":27,"breadcrumbs":4,"title":2},"746":{"body":0,"breadcrumbs":3,"title":1},"747":{"body":41,"breadcrumbs":4,"title":2},"748":{"body":21,"breadcrumbs":3,"title":1},"749":{"body":31,"breadcrumbs":4,"title":2},"75":{"body":21,"breadcrumbs":8,"title":6},"750":{"body":0,"breadcrumbs":5,"title":3},"751":{"body":103,"breadcrumbs":4,"title":2},"752":{"body":89,"breadcrumbs":4,"title":2},"753":{"body":128,"breadcrumbs":4,"title":2},"754":{"body":107,"breadcrumbs":4,"title":2},"755":{"body":0,"breadcrumbs":4,"title":2},"756":{"body":72,"breadcrumbs":4,"title":2},"757":{"body":86,"breadcrumbs":4,"title":2},"758":{"body":92,"breadcrumbs":4,"title":2},"759":{"body":0,"breadcrumbs":4,"title":2},"76":{"body":27,"breadcrumbs":4,"title":2},"760":{"body":29,"breadcrumbs":4,"title":2},"761":{"body":33,"breadcrumbs":4,"title":2},"762":{"body":37,"breadcrumbs":4,"title":2},"763":{"body":30,"breadcrumbs":4,"title":2},"764":{"body":37,"breadcrumbs":4,"title":2},"765":{"body":29,"breadcrumbs":4,"title":2},"766":{"body":26,"breadcrumbs":4,"title":2},"767":{"body":0,"breadcrumbs":4,"title":2},"768":{"body":26,"breadcrumbs":4,"title":2},"769":{"body":13,"breadcrumbs":4,"title":2},"77":{"body":0,"breadcrumbs":4,"title":2},"770":{"body":11,"breadcrumbs":5,"title":3},"771":{"body":0,"breadcrumbs":5,"title":3},"772":{"body":60,"breadcrumbs":4,"title":2},"773":{"body":48,"breadcrumbs":3,"title":1},"774":{"body":0,"breadcrumbs":4,"title":2},"775":{"body":17,"breadcrumbs":4,"title":2},"776":{"body":28,"breadcrumbs":5,"title":3},"777":{"body":0,"breadcrumbs":3,"title":1},"778":{"body":19,"breadcrumbs":4,"title":2},"779":{"body":18,"breadcrumbs":4,"title":2},"78":{"body":17,"breadcrumbs":4,"title":2},"780":{"body":15,"breadcrumbs":4,"title":2},"781":{"body":18,"breadcrumbs":4,"title":2},"782":{"body":44,"breadcrumbs":4,"title":2},"783":{"body":0,"breadcrumbs":5,"title":3},"784":{"body":29,"breadcrumbs":7,"title":5},"785":{"body":39,"breadcrumbs":4,"title":2},"786":{"body":0,"breadcrumbs":5,"title":3},"787":{"body":65,"breadcrumbs":5,"title":3},"788":{"body":54,"breadcrumbs":4,"title":2},"789":{"body":8,"breadcrumbs":5,"title":3},"79":{"body":22,"breadcrumbs":4,"title":2},"790":{"body":50,"breadcrumbs":4,"title":2},"791":{"body":76,"breadcrumbs":6,"title":4},"792":{"body":6,"breadcrumbs":6,"title":4},"793":{"body":29,"breadcrumbs":4,"title":2},"794":{"body":49,"breadcrumbs":5,"title":3},"795":{"body":36,"breadcrumbs":4,"title":2},"796":{"body":59,"breadcrumbs":5,"title":3},"797":{"body":0,"breadcrumbs":5,"title":3},"798":{"body":63,"breadcrumbs":6,"title":4},"799":{"body":4,"breadcrumbs":6,"title":4},"8":{"body":5,"breadcrumbs":2,"title":1},"80":{"body":25,"breadcrumbs":3,"title":1},"800":{"body":14,"breadcrumbs":6,"title":4},"801":{"body":59,"breadcrumbs":5,"title":3},"802":{"body":31,"breadcrumbs":5,"title":3},"803":{"body":5,"breadcrumbs":5,"title":3},"804":{"body":0,"breadcrumbs":5,"title":3},"805":{"body":79,"breadcrumbs":5,"title":3},"806":{"body":35,"breadcrumbs":4,"title":2},"807":{"body":0,"breadcrumbs":4,"title":2},"808":{"body":65,"breadcrumbs":4,"title":2},"809":{"body":24,"breadcrumbs":5,"title":3},"81":{"body":0,"breadcrumbs":4,"title":2},"810":{"body":0,"breadcrumbs":3,"title":1},"811":{"body":35,"breadcrumbs":5,"title":3},"812":{"body":24,"breadcrumbs":5,"title":3},"813":{"body":8,"breadcrumbs":5,"title":3},"814":{"body":18,"breadcrumbs":4,"title":2},"815":{"body":43,"breadcrumbs":4,"title":2},"816":{"body":20,"breadcrumbs":4,"title":2},"817":{"body":11,"breadcrumbs":3,"title":1},"818":{"body":63,"breadcrumbs":3,"title":1},"819":{"body":0,"breadcrumbs":4,"title":2},"82":{"body":55,"breadcrumbs":4,"title":2},"820":{"body":38,"breadcrumbs":4,"title":2},"821":{"body":35,"breadcrumbs":4,"title":2},"822":{"body":43,"breadcrumbs":4,"title":2},"823":{"body":25,"breadcrumbs":3,"title":1},"824":{"body":0,"breadcrumbs":4,"title":2},"825":{"body":7,"breadcrumbs":5,"title":3},"826":{"body":10,"breadcrumbs":5,"title":3},"827":{"body":7,"breadcrumbs":5,"title":3},"828":{"body":8,"breadcrumbs":5,"title":3},"829":{"body":5,"breadcrumbs":5,"title":3},"83":{"body":37,"breadcrumbs":5,"title":3},"830":{"body":6,"breadcrumbs":5,"title":3},"831":{"body":11,"breadcrumbs":4,"title":2},"832":{"body":33,"breadcrumbs":4,"title":2},"833":{"body":34,"breadcrumbs":4,"title":2},"834":{"body":42,"breadcrumbs":4,"title":2},"835":{"body":15,"breadcrumbs":4,"title":2},"836":{"body":21,"breadcrumbs":4,"title":2},"837":{"body":51,"breadcrumbs":3,"title":1},"838":{"body":8,"breadcrumbs":5,"title":3},"839":{"body":16,"breadcrumbs":3,"title":1},"84":{"body":21,"breadcrumbs":5,"title":3},"840":{"body":48,"breadcrumbs":3,"title":1},"841":{"body":12,"breadcrumbs":5,"title":3},"842":{"body":18,"breadcrumbs":3,"title":1},"843":{"body":8,"breadcrumbs":5,"title":3},"844":{"body":18,"breadcrumbs":3,"title":1},"845":{"body":21,"breadcrumbs":3,"title":1},"846":{"body":26,"breadcrumbs":4,"title":2},"847":{"body":37,"breadcrumbs":4,"title":2},"848":{"body":7,"breadcrumbs":4,"title":2},"849":{"body":18,"breadcrumbs":3,"title":1},"85":{"body":0,"breadcrumbs":5,"title":3},"850":{"body":19,"breadcrumbs":3,"title":1},"851":{"body":6,"breadcrumbs":4,"title":2},"852":{"body":57,"breadcrumbs":5,"title":3},"853":{"body":0,"breadcrumbs":5,"title":3},"854":{"body":14,"breadcrumbs":4,"title":2},"855":{"body":14,"breadcrumbs":4,"title":2},"856":{"body":14,"breadcrumbs":4,"title":2},"857":{"body":14,"breadcrumbs":4,"title":2},"858":{"body":52,"breadcrumbs":5,"title":3},"859":{"body":0,"breadcrumbs":4,"title":2},"86":{"body":20,"breadcrumbs":5,"title":3},"860":{"body":11,"breadcrumbs":5,"title":3},"861":{"body":20,"breadcrumbs":5,"title":3},"862":{"body":28,"breadcrumbs":4,"title":2},"863":{"body":14,"breadcrumbs":4,"title":2},"864":{"body":10,"breadcrumbs":4,"title":2},"865":{"body":93,"breadcrumbs":5,"title":3},"866":{"body":0,"breadcrumbs":5,"title":3},"867":{"body":63,"breadcrumbs":4,"title":2},"868":{"body":27,"breadcrumbs":4,"title":2},"869":{"body":18,"breadcrumbs":4,"title":2},"87":{"body":25,"breadcrumbs":6,"title":4},"870":{"body":24,"breadcrumbs":5,"title":3},"871":{"body":0,"breadcrumbs":4,"title":2},"872":{"body":15,"breadcrumbs":4,"title":2},"873":{"body":27,"breadcrumbs":4,"title":2},"874":{"body":19,"breadcrumbs":5,"title":3},"875":{"body":14,"breadcrumbs":5,"title":3},"876":{"body":51,"breadcrumbs":4,"title":2},"877":{"body":0,"breadcrumbs":5,"title":3},"878":{"body":23,"breadcrumbs":5,"title":3},"879":{"body":33,"breadcrumbs":5,"title":3},"88":{"body":20,"breadcrumbs":5,"title":3},"880":{"body":0,"breadcrumbs":4,"title":2},"881":{"body":51,"breadcrumbs":4,"title":2},"882":{"body":25,"breadcrumbs":4,"title":2},"883":{"body":28,"breadcrumbs":4,"title":2},"884":{"body":0,"breadcrumbs":4,"title":2},"885":{"body":23,"breadcrumbs":4,"title":2},"886":{"body":9,"breadcrumbs":5,"title":3},"887":{"body":8,"breadcrumbs":4,"title":2},"888":{"body":0,"breadcrumbs":5,"title":3},"889":{"body":36,"breadcrumbs":5,"title":3},"89":{"body":0,"breadcrumbs":3,"title":1},"890":{"body":15,"breadcrumbs":4,"title":2},"891":{"body":29,"breadcrumbs":4,"title":2},"892":{"body":0,"breadcrumbs":4,"title":2},"893":{"body":35,"breadcrumbs":4,"title":2},"894":{"body":23,"breadcrumbs":4,"title":2},"895":{"body":0,"breadcrumbs":4,"title":2},"896":{"body":39,"breadcrumbs":5,"title":3},"897":{"body":42,"breadcrumbs":5,"title":3},"898":{"body":22,"breadcrumbs":4,"title":2},"899":{"body":0,"breadcrumbs":4,"title":2},"9":{"body":12,"breadcrumbs":4,"title":2},"90":{"body":64,"breadcrumbs":4,"title":2},"900":{"body":18,"breadcrumbs":4,"title":2},"901":{"body":11,"breadcrumbs":4,"title":2},"902":{"body":0,"breadcrumbs":4,"title":2},"903":{"body":23,"breadcrumbs":4,"title":2},"904":{"body":19,"breadcrumbs":4,"title":2},"905":{"body":20,"breadcrumbs":4,"title":2},"906":{"body":16,"breadcrumbs":4,"title":2},"907":{"body":10,"breadcrumbs":2,"title":1},"908":{"body":36,"breadcrumbs":4,"title":3},"909":{"body":32,"breadcrumbs":3,"title":2},"91":{"body":5,"breadcrumbs":4,"title":2},"910":{"body":0,"breadcrumbs":3,"title":2},"911":{"body":40,"breadcrumbs":3,"title":2},"912":{"body":13,"breadcrumbs":3,"title":2},"913":{"body":0,"breadcrumbs":3,"title":2},"914":{"body":70,"breadcrumbs":3,"title":2},"915":{"body":30,"breadcrumbs":3,"title":2},"916":{"body":0,"breadcrumbs":3,"title":2},"917":{"body":60,"breadcrumbs":4,"title":3},"918":{"body":35,"breadcrumbs":4,"title":3},"919":{"body":0,"breadcrumbs":2,"title":1},"92":{"body":18,"breadcrumbs":4,"title":2},"920":{"body":109,"breadcrumbs":3,"title":2},"921":{"body":81,"breadcrumbs":3,"title":2},"922":{"body":0,"breadcrumbs":4,"title":3},"923":{"body":49,"breadcrumbs":3,"title":2},"924":{"body":44,"breadcrumbs":4,"title":3},"925":{"body":0,"breadcrumbs":3,"title":2},"926":{"body":44,"breadcrumbs":3,"title":2},"927":{"body":0,"breadcrumbs":3,"title":2},"928":{"body":14,"breadcrumbs":3,"title":2},"929":{"body":19,"breadcrumbs":3,"title":2},"93":{"body":8,"breadcrumbs":4,"title":2},"930":{"body":0,"breadcrumbs":3,"title":2},"931":{"body":58,"breadcrumbs":4,"title":3},"932":{"body":45,"breadcrumbs":4,"title":3},"933":{"body":11,"breadcrumbs":3,"title":2},"934":{"body":8,"breadcrumbs":4,"title":2},"935":{"body":23,"breadcrumbs":3,"title":1},"936":{"body":0,"breadcrumbs":4,"title":2},"937":{"body":47,"breadcrumbs":4,"title":2},"938":{"body":0,"breadcrumbs":4,"title":2},"939":{"body":52,"breadcrumbs":4,"title":2},"94":{"body":24,"breadcrumbs":3,"title":1},"940":{"body":33,"breadcrumbs":4,"title":2},"941":{"body":24,"breadcrumbs":4,"title":2},"942":{"body":0,"breadcrumbs":4,"title":2},"943":{"body":42,"breadcrumbs":4,"title":2},"944":{"body":39,"breadcrumbs":4,"title":2},"945":{"body":43,"breadcrumbs":4,"title":2},"946":{"body":20,"breadcrumbs":4,"title":2},"947":{"body":0,"breadcrumbs":5,"title":3},"948":{"body":58,"breadcrumbs":5,"title":3},"949":{"body":39,"breadcrumbs":6,"title":4},"95":{"body":26,"breadcrumbs":4,"title":2},"950":{"body":0,"breadcrumbs":4,"title":2},"951":{"body":8,"breadcrumbs":4,"title":2},"952":{"body":43,"breadcrumbs":4,"title":2},"953":{"body":16,"breadcrumbs":4,"title":2},"954":{"body":0,"breadcrumbs":4,"title":2},"955":{"body":33,"breadcrumbs":4,"title":2},"956":{"body":20,"breadcrumbs":5,"title":3},"957":{"body":0,"breadcrumbs":4,"title":2},"958":{"body":65,"breadcrumbs":4,"title":2},"959":{"body":40,"breadcrumbs":5,"title":3},"96":{"body":14,"breadcrumbs":3,"title":1},"960":{"body":36,"breadcrumbs":5,"title":3},"961":{"body":0,"breadcrumbs":4,"title":2},"962":{"body":28,"breadcrumbs":4,"title":2},"963":{"body":31,"breadcrumbs":4,"title":2},"964":{"body":0,"breadcrumbs":4,"title":2},"965":{"body":46,"breadcrumbs":4,"title":2},"966":{"body":0,"breadcrumbs":4,"title":2},"967":{"body":26,"breadcrumbs":4,"title":2},"968":{"body":18,"breadcrumbs":4,"title":2},"969":{"body":0,"breadcrumbs":5,"title":3},"97":{"body":0,"breadcrumbs":6,"title":4},"970":{"body":57,"breadcrumbs":5,"title":3},"971":{"body":59,"breadcrumbs":4,"title":2},"972":{"body":11,"breadcrumbs":4,"title":2},"973":{"body":9,"breadcrumbs":3,"title":2},"974":{"body":26,"breadcrumbs":2,"title":1},"975":{"body":0,"breadcrumbs":3,"title":2},"976":{"body":14,"breadcrumbs":4,"title":3},"977":{"body":17,"breadcrumbs":3,"title":2},"978":{"body":18,"breadcrumbs":3,"title":2},"979":{"body":22,"breadcrumbs":4,"title":3},"98":{"body":32,"breadcrumbs":4,"title":2},"980":{"body":0,"breadcrumbs":3,"title":2},"981":{"body":50,"breadcrumbs":5,"title":4},"982":{"body":61,"breadcrumbs":6,"title":5},"983":{"body":0,"breadcrumbs":3,"title":2},"984":{"body":28,"breadcrumbs":6,"title":5},"985":{"body":27,"breadcrumbs":5,"title":4},"986":{"body":27,"breadcrumbs":6,"title":5},"987":{"body":26,"breadcrumbs":6,"title":5},"988":{"body":25,"breadcrumbs":5,"title":4},"989":{"body":27,"breadcrumbs":5,"title":4},"99":{"body":35,"breadcrumbs":4,"title":2},"990":{"body":31,"breadcrumbs":3,"title":2},"991":{"body":0,"breadcrumbs":4,"title":3},"992":{"body":31,"breadcrumbs":6,"title":5},"993":{"body":29,"breadcrumbs":5,"title":4},"994":{"body":34,"breadcrumbs":6,"title":5},"995":{"body":0,"breadcrumbs":3,"title":2},"996":{"body":23,"breadcrumbs":3,"title":2},"997":{"body":34,"breadcrumbs":3,"title":2},"998":{"body":32,"breadcrumbs":4,"title":3},"999":{"body":0,"breadcrumbs":3,"title":2}},"docs":{"0":{"body":"Welcome to the Provisioning Platform documentation. This is an enterprise-grade Infrastructure as Code (IaC) platform built with Rust, Nushell, and Nickel.","breadcrumbs":"Introduction » Provisioning Platform Documentation","id":"0","title":"Provisioning Platform Documentation"},"1":{"body":"Provisioning is a comprehensive infrastructure automation platform that manages complete infrastructure lifecycles across multiple cloud providers. The platform emphasizes type-safety, configuration-driven design, and workspace-first organization.","breadcrumbs":"Introduction » What is Provisioning","id":"1","title":"What is Provisioning"},"10":{"body":"Getting started with Provisioning involves: Verifying prerequisites - System requirements, tools, cloud accounts Installing platform - Binary or container installation Initial configuration - Environment setup, credentials, workspaces First deployment - Deploy actual infrastructure in 5 minutes Verification - Validate everything is working correctly By the end of this section, you\'ll have a running Provisioning installation and have deployed your first infrastructure.","breadcrumbs":"Getting Started » Overview","id":"10","title":"Overview"},"100":{"body":"","breadcrumbs":"First Deployment » Part 2: Infrastructure Definition","id":"100","title":"Part 2: Infrastructure Definition"},"1000":{"body":"# Check logs\\ntail -f ~/.provisioning/logs/upgrade.log # Monitor process\\nprovisioning upgrade --monitor # Stop upgrade gracefully\\nprovisioning upgrade --stop --graceful # Force stop\\nprovisioning upgrade --stop --force","breadcrumbs":"Upgrade » Upgrade Hangs","id":"1000","title":"Upgrade Hangs"},"1001":{"body":"# Check migration logs\\nprovisioning upgrade --migration-logs # Rollback to previous version\\nprovisioning upgrade --rollback # Restore from backup\\nprovisioning backup restore","breadcrumbs":"Upgrade » Migration Failure","id":"1001","title":"Migration Failure"},"1002":{"body":"# Check service logs\\nprovisioning platform logs # Verify configuration\\nprovisioning validate config --strict # Restore configuration from backup\\nprovisioning config restore # Restart services\\nprovisioning orchestrator start","breadcrumbs":"Upgrade » Service Won\'t Start","id":"1002","title":"Service Won\'t Start"},"1003":{"body":"","breadcrumbs":"Upgrade » Upgrade Scheduling","id":"1003","title":"Upgrade Scheduling"},"1004":{"body":"# Schedule upgrade for specific time\\nprovisioning upgrade --schedule \\"2026-01-20T02:00:00\\" # Schedule for next maintenance window\\nprovisioning upgrade --schedule-next-maintenance # Cancel scheduled upgrade\\nprovisioning upgrade --cancel-scheduled","breadcrumbs":"Upgrade » Schedule Automated Upgrade","id":"1004","title":"Schedule Automated Upgrade"},"1005":{"body":"For CI/CD environments: # Non-interactive upgrade\\nprovisioning upgrade --yes --no-confirm # Upgrade with timeout\\nprovisioning upgrade --timeout 3600 # Skip backup\\nprovisioning upgrade --skip-backup # Continue even if health checks fail\\nprovisioning upgrade --force-upgrade","breadcrumbs":"Upgrade » Unattended Upgrade","id":"1005","title":"Unattended Upgrade"},"1006":{"body":"","breadcrumbs":"Upgrade » Version Management","id":"1006","title":"Version Management"},"1007":{"body":"Pin versions for workspace reproducibility: # workspace/versions.ncl\\n{ provisioning = \\"5.0.0\\" nushell = \\"0.109.0\\" nickel = \\"1.15.1\\" sops = \\"3.10.2\\" age = \\"1.2.1\\"\\n} Enforce version constraints: # Check version compliance\\nprovisioning version --check-constraints # Enforce constraint\\nprovisioning version --strict-mode","breadcrumbs":"Upgrade » Version Constraints","id":"1007","title":"Version Constraints"},"1008":{"body":"Pin provider and task service versions: # workspace/infra/versions.ncl\\n{ providers = { upcloud = \\"2.0.0\\" aws = \\"5.0.0\\" } taskservs = { kubernetes = \\"1.28.0\\" postgres = \\"14.0\\" }\\n}","breadcrumbs":"Upgrade » Vendor Versions","id":"1008","title":"Vendor Versions"},"1009":{"body":"","breadcrumbs":"Upgrade » Best Practices","id":"1009","title":"Best Practices"},"101":{"body":"Create infrastructure definition with type-safe Nickel: # Create Kubernetes cluster schema\\ncat > infra/k8s-cluster.ncl <<\'EOF\'\\n{ metadata = { name = \\"k8s-prod\\" provider = \\"upcloud\\" environment = \\"production\\" version = \\"1.0.0\\" } infrastructure = { servers = [ { name = \\"k8s-control-01\\" plan = \\"medium\\" # 4 CPU, 8 GB RAM role = \\"control\\" zone = \\"de-fra1\\" disk_size_gb = 50 backup_enabled = true } { name = \\"k8s-worker-01\\" plan = \\"large\\" # 8 CPU, 16 GB RAM role = \\"worker\\" zone = \\"de-fra1\\" disk_size_gb = 100 backup_enabled = true } { name = \\"k8s-worker-02\\" plan = \\"large\\" role = \\"worker\\" zone = \\"de-fra1\\" disk_size_gb = 100 backup_enabled = true } ] } services = { taskservs = [ \\"containerd\\" # Container runtime (dependency) \\"etcd\\" # Key-value store (dependency) \\"kubernetes\\" # Core orchestration \\"cilium\\" # CNI networking \\"rook-ceph\\" # Persistent storage ] } kubernetes = { version = \\"1.28.0\\" pod_cidr = \\"10.244.0.0/16\\" service_cidr = \\"10.96.0.0/12\\" container_runtime = \\"containerd\\" cri_socket = \\"/run/containerd/containerd.sock\\" } networking = { cni = \\"cilium\\" enable_network_policy = true enable_encryption = true } storage = { provider = \\"rook-ceph\\" replicas = 3 storage_class = \\"ceph-rbd\\" }\\n}\\nEOF","breadcrumbs":"First Deployment » Define Nickel Schema","id":"101","title":"Define Nickel Schema"},"1010":{"body":"Schedule during maintenance windows Test in staging first Communicate with team Have rollback plan ready","breadcrumbs":"Upgrade » 1. Plan Upgrades","id":"1010","title":"1. Plan Upgrades"},"1011":{"body":"# Complete backup before upgrade\\nprovisioning workspace backup --compress\\nprovisioning config backup\\nprovisioning state backup","breadcrumbs":"Upgrade » 2. Backup Everything","id":"1011","title":"2. Backup Everything"},"1012":{"body":"# Use side-by-side upgrade to test\\nprovisioning upgrade --staging\\nprovisioning test suite","breadcrumbs":"Upgrade » 3. Test Before Upgrading","id":"1012","title":"3. Test Before Upgrading"},"1013":{"body":"# Watch orchestrator\\nprovisioning orchestrator status --watch # Monitor platform health\\nprovisioning platform monitor # Check logs\\ntail -f ~/.provisioning/logs/provisioning.log","breadcrumbs":"Upgrade » 4. Monitor After Upgrade","id":"1013","title":"4. Monitor After Upgrade"},"1014":{"body":"# Record what changed\\nprovisioning upgrade --changelog > UPGRADE.md # Update team documentation\\n# Update runbooks\\n# Update dashboards","breadcrumbs":"Upgrade » 5. Document Changes","id":"1014","title":"5. Document Changes"},"1015":{"body":"","breadcrumbs":"Upgrade » Upgrade Policies","id":"1015","title":"Upgrade Policies"},"1016":{"body":"Enable automatic updates: # ~/.config/provisioning/user_config.yaml\\nupgrade: auto_update: true check_interval: \\"daily\\" update_channel: \\"stable\\" auto_backup: true","breadcrumbs":"Upgrade » Automatic Updates","id":"1016","title":"Automatic Updates"},"1017":{"body":"Choose update channel: # Stable releases (recommended)\\nprovisioning upgrade --channel stable # Beta releases\\nprovisioning upgrade --channel beta # Development (nightly)\\nprovisioning upgrade --channel development","breadcrumbs":"Upgrade » Update Channels","id":"1017","title":"Update Channels"},"1018":{"body":"Initial Setup - First-time configuration Platform Health - System monitoring Backup & Recovery - Data protection","breadcrumbs":"Upgrade » Related Documentation","id":"1018","title":"Related Documentation"},"1019":{"body":"Common issues, debugging procedures, and resolution strategies for the Provisioning platform.","breadcrumbs":"Troubleshooting » Troubleshooting","id":"1019","title":"Troubleshooting"},"102":{"body":"# Type-check Nickel schema\\nnickel typecheck infra/k8s-cluster.ncl # Validate against provisioning contracts\\nprovisioning validate config --infra k8s-cluster Expected output: Schema validation: PASSED - Syntax: Valid Nickel - Type safety: All contracts satisfied - Dependencies: Resolved (5 taskservs) - Provider: upcloud (credentials found)","breadcrumbs":"First Deployment » Validate Schema","id":"102","title":"Validate Schema"},"1020":{"body":"Run platform diagnostics: # Comprehensive health check\\nprovisioning diagnose # Check specific component\\nprovisioning diagnose --component orchestrator # Generate diagnostic report\\nprovisioning diagnose --report /tmp/diagnostics.txt","breadcrumbs":"Troubleshooting » Quick Diagnosis","id":"1020","title":"Quick Diagnosis"},"1021":{"body":"","breadcrumbs":"Troubleshooting » Common Issues","id":"1021","title":"Common Issues"},"1022":{"body":"Symptom : Service fails to start or crashes immediately Diagnosis : # Check service status\\nsystemctl status provisioning-orchestrator # View recent logs\\njournalctl -u provisioning-orchestrator -n 100 --no-pager # Check configuration\\nprovisioning validate config Common Causes : Port already in use # Find process using port\\nlsof -i :8080 # Kill conflicting process or change port in config Configuration error # Validate configuration\\nprovisioning validate config --strict # Check for syntax errors\\nnickel typecheck /etc/provisioning/config.ncl Missing dependencies # Check binary dependencies\\nldd /usr/local/bin/provisioning-orchestrator # Install missing libraries\\nsudo apt install Permission issues # Fix ownership\\nsudo chown -R provisioning:provisioning /var/lib/provisioning\\nsudo chown -R provisioning:provisioning /etc/provisioning # Fix permissions\\nsudo chmod 750 /var/lib/provisioning\\nsudo chmod 640 /etc/provisioning/*.toml","breadcrumbs":"Troubleshooting » Services Won\'t Start","id":"1022","title":"Services Won\'t Start"},"1023":{"body":"Symptom : Services can\'t connect to SurrealDB Diagnosis : # Check database status\\nsystemctl status surrealdb # Test database connectivity\\ncurl [http://localhost:8000/health](http://localhost:8000/health) # Check database logs\\njournalctl -u surrealdb -n 50 Resolution : # Restart database\\nsudo systemctl restart surrealdb # Verify connection string in config\\nprovisioning config get database.url # Test manual connection\\nsurreal sql --conn [http://localhost:8000](http://localhost:8000) --user root --pass root","breadcrumbs":"Troubleshooting » Database Connection Failures","id":"1023","title":"Database Connection Failures"},"1024":{"body":"Symptom : Service consuming excessive CPU or memory Diagnosis : # Monitor resource usage\\ntop -p $(pgrep provisioning-orchestrator) # Detailed metrics\\nprovisioning platform metrics --service orchestrator # Check for resource leaks Resolution : # Adjust worker threads\\nprovisioning config set execution.worker_threads 4 # Reduce parallel tasks\\nprovisioning config set execution.max_parallel_tasks 50 # Increase memory limit\\nsudo systemctl set-property provisioning-orchestrator MemoryMax=8G # Restart service\\nsudo systemctl restart provisioning-orchestrator","breadcrumbs":"Troubleshooting » High Resource Usage","id":"1024","title":"High Resource Usage"},"1025":{"body":"Symptom : Workflows fail or hang Diagnosis : # List failed workflows\\nprovisioning workflow list --status failed # View workflow details\\nprovisioning workflow show # Check workflow logs\\nprovisioning workflow logs # Inspect checkpoint state\\nprovisioning workflow checkpoints Common Issues : Provider API errors # Check provider credentials\\nprovisioning provider validate upcloud # Test provider connectivity\\nprovisioning provider test upcloud Dependency resolution failures # Validate infrastructure schema\\nprovisioning validate infra my-cluster.ncl # Check task service dependencies\\nprovisioning taskserv deps kubernetes Timeout issues # Increase timeout\\nprovisioning config set workflows.task_timeout 600 # Enable detailed logging\\nprovisioning config set logging.level debug","breadcrumbs":"Troubleshooting » Workflow Failures","id":"1025","title":"Workflow Failures"},"1026":{"body":"Symptom : Can\'t reach external services or cloud providers Diagnosis : # Test network connectivity\\nping -c 3 upcloud.com # Check DNS resolution\\nnslookup api.upcloud.com # Test HTTPS connectivity\\ncurl -v [https://api.upcloud.com](https://api.upcloud.com) # Check proxy settings\\nenv | grep -i proxy Resolution : # Configure proxy if needed\\nexport HTTPS_PROXY= [http://proxy.example.com:8080](http://proxy.example.com:8080)\\nprovisioning config set network.proxy [http://proxy.example.com:8080](http://proxy.example.com:8080) # Verify firewall rules\\nsudo ufw status # Check routing\\nip route show","breadcrumbs":"Troubleshooting » Network Connectivity Issues","id":"1026","title":"Network Connectivity Issues"},"1027":{"body":"Symptom : API requests fail with 401 Unauthorized Diagnosis : # Check JWT token\\nprovisioning auth status # Verify user credentials\\nprovisioning auth whoami # Check authentication logs\\njournalctl -u provisioning-control-center | grep \\"auth\\" Resolution : # Refresh authentication token\\nprovisioning auth login --username admin # Reset user password\\nprovisioning auth reset-password --username admin # Verify MFA configuration\\nprovisioning auth mfa status","breadcrumbs":"Troubleshooting » Authentication Failures","id":"1027","title":"Authentication Failures"},"1028":{"body":"","breadcrumbs":"Troubleshooting » Debugging Workflows","id":"1028","title":"Debugging Workflows"},"1029":{"body":"# Enable debug mode\\nexport PROVISIONING_LOG_LEVEL=debug\\nprovisioning workflow create my-cluster --debug # Or in configuration\\nprovisioning config set logging.level debug\\nsudo systemctl restart provisioning-orchestrator","breadcrumbs":"Troubleshooting » Enable Debug Logging","id":"1029","title":"Enable Debug Logging"},"103":{"body":"","breadcrumbs":"First Deployment » Part 3: Preview and Validation","id":"103","title":"Part 3: Preview and Validation"},"1030":{"body":"# View workflow state\\nprovisioning workflow state # Export workflow state to JSON\\nprovisioning workflow state --format json > workflow-state.json # Inspect checkpoints\\nprovisioning workflow checkpoints ","breadcrumbs":"Troubleshooting » Workflow State Inspection","id":"1030","title":"Workflow State Inspection"},"1031":{"body":"# Retry failed workflow from last checkpoint\\nprovisioning workflow retry # Retry from specific checkpoint\\nprovisioning workflow retry --from-checkpoint 3 # Force retry (skip validation)\\nprovisioning workflow retry --force","breadcrumbs":"Troubleshooting » Manual Workflow Retry","id":"1031","title":"Manual Workflow Retry"},"1032":{"body":"","breadcrumbs":"Troubleshooting » Performance Troubleshooting","id":"1032","title":"Performance Troubleshooting"},"1033":{"body":"Diagnosis : # Profile workflow execution\\nprovisioning workflow profile # Identify bottlenecks\\nprovisioning workflow analyze Optimization : # Increase parallelism\\nprovisioning config set execution.max_parallel_tasks 200 # Optimize database queries\\nprovisioning database analyze # Add caching\\nprovisioning config set cache.enabled true","breadcrumbs":"Troubleshooting » Slow Workflow Execution","id":"1033","title":"Slow Workflow Execution"},"1034":{"body":"Diagnosis : # Check database metrics\\ncurl [http://localhost:8000/metrics](http://localhost:8000/metrics) # Identify slow queries\\nprovisioning database slow-queries # Check connection pool\\nprovisioning database pool-status Optimization : # Increase connection pool\\nprovisioning config set database.max_connections 200 # Add indexes\\nprovisioning database create-indexes # Optimize vacuum settings\\nprovisioning database vacuum","breadcrumbs":"Troubleshooting » Database Performance Issues","id":"1034","title":"Database Performance Issues"},"1035":{"body":"","breadcrumbs":"Troubleshooting » Log Analysis","id":"1035","title":"Log Analysis"},"1036":{"body":"# View all platform logs\\njournalctl -u provisioning-* -f # Filter by severity\\njournalctl -u provisioning-* -p err # Export logs for analysis\\njournalctl -u provisioning-* --since \\"1 hour ago\\" > /tmp/logs.txt","breadcrumbs":"Troubleshooting » Centralized Log Viewing","id":"1036","title":"Centralized Log Viewing"},"1037":{"body":"Using Loki with LogQL: # Find errors in orchestrator\\n{job=\\"provisioning-orchestrator\\"} | = \\"ERROR\\" # Workflow failures\\n{job=\\"provisioning-orchestrator\\"} | json | status=\\"failed\\" # API request latency over 1s\\n{job=\\"provisioning-control-center\\"} | json | duration > 1","breadcrumbs":"Troubleshooting » Structured Log Queries","id":"1037","title":"Structured Log Queries"},"1038":{"body":"# Correlate logs by request ID\\njournalctl -u provisioning-* | grep \\"request_id=abc123\\" # Trace workflow execution\\nprovisioning workflow trace ","breadcrumbs":"Troubleshooting » Log Correlation","id":"1038","title":"Log Correlation"},"1039":{"body":"","breadcrumbs":"Troubleshooting » Advanced Debugging","id":"1039","title":"Advanced Debugging"},"104":{"body":"# Dry-run to see what will be created\\nprovisioning server create --check --infra k8s-cluster Output shows: Infrastructure Plan: k8s-prod\\nProvider: upcloud\\nRegion: de-fra1 Servers to create: 3 - k8s-control-01 (medium, 4 CPU, 8 GB RAM, 50 GB disk) - k8s-worker-01 (large, 8 CPU, 16 GB RAM, 100 GB disk) - k8s-worker-02 (large, 8 CPU, 16 GB RAM, 100 GB disk) Task services: 5 (with dependencies resolved) 1. containerd (dependency for kubernetes) 2. etcd (dependency for kubernetes) 3. kubernetes 4. cilium (requires kubernetes) 5. rook-ceph (requires kubernetes) Estimated monthly cost: $xxx.xx\\nEstimated deployment time: 15-20 minutes WARNING: Production deployment - ensure backup enabled","breadcrumbs":"First Deployment » Preview Infrastructure","id":"104","title":"Preview Infrastructure"},"1040":{"body":"# Enable backtrace for Rust services\\nexport RUST_BACKTRACE=1\\nsudo systemctl restart provisioning-orchestrator # Full backtrace\\nexport RUST_BACKTRACE=full","breadcrumbs":"Troubleshooting » Enable Rust Backtrace","id":"1040","title":"Enable Rust Backtrace"},"1041":{"body":"# Enable core dumps\\nsudo sysctl -w kernel.core_pattern=/var/crash/core.%e.%p\\nulimit -c unlimited # Analyze core dump\\nsudo coredumpctl list\\nsudo coredumpctl debug # In gdb:\\n(gdb) bt\\n(gdb) info threads\\n(gdb) thread apply all bt","breadcrumbs":"Troubleshooting » Core Dump Analysis","id":"1041","title":"Core Dump Analysis"},"1042":{"body":"# Capture API traffic\\nsudo tcpdump -i any -w /tmp/api-traffic.pcap port 8080 # Analyze with tshark\\ntshark -r /tmp/api-traffic.pcap -Y \\"http\\"","breadcrumbs":"Troubleshooting » Network Traffic Analysis","id":"1042","title":"Network Traffic Analysis"},"1043":{"body":"","breadcrumbs":"Troubleshooting » Getting Help","id":"1043","title":"Getting Help"},"1044":{"body":"# Generate comprehensive diagnostic report\\nprovisioning diagnose --full --output /tmp/diagnostics.tar.gz # Report includes:\\n# - Service status\\n# - Configuration files\\n# - Recent logs (last 1000 lines per service)\\n# - Resource usage metrics\\n# - Database status\\n# - Network connectivity tests\\n# - Workflow states","breadcrumbs":"Troubleshooting » Collect Diagnostic Information","id":"1044","title":"Collect Diagnostic Information"},"1045":{"body":"Check documentation: provisioning help Search logs: journalctl -u provisioning-* Review monitoring dashboards: http://localhost:3000 Run diagnostics: provisioning diagnose Contact support with diagnostic report","breadcrumbs":"Troubleshooting » Support Channels","id":"1045","title":"Support Channels"},"1046":{"body":"Enable comprehensive monitoring and alerting Implement regular health checks Maintain up-to-date documentation Test disaster recovery procedures monthly Keep platform and dependencies updated Review logs regularly for warning signs Monitor resource utilization trends Validate configuration changes before applying","breadcrumbs":"Troubleshooting » Preventive Measures","id":"1046","title":"Preventive Measures"},"1047":{"body":"Service Management - Service lifecycle Monitoring - Observability setup Platform Health - Health checks Backup & Recovery - Recovery procedures","breadcrumbs":"Troubleshooting » Related Documentation","id":"1047","title":"Related Documentation"},"1048":{"body":"Health monitoring, status checks, and system integrity validation for the Provisioning platform.","breadcrumbs":"Platform Health » Platform Health","id":"1048","title":"Platform Health"},"1049":{"body":"The platform provides multiple levels of health monitoring: Level Scope Frequency Response Time Service Health Individual service status Every 10s < 100ms System Health Overall platform status Every 30s < 500ms Infrastructure Health Managed resources Every 60s < 2s Dependency Health External services Every 60s < 1s","breadcrumbs":"Platform Health » Health Check Overview","id":"1049","title":"Health Check Overview"},"105":{"body":"# Visualize dependency resolution\\nprovisioning taskserv dependencies kubernetes --graph Shows: kubernetes\\n├── containerd (required)\\n├── etcd (required)\\n└── cni (cilium) (soft dependency) cilium\\n└── kubernetes (required) rook-ceph\\n└── kubernetes (required)","breadcrumbs":"First Deployment » Dependency Graph","id":"105","title":"Dependency Graph"},"1050":{"body":"# Check overall platform health\\nprovisioning health # Output:\\n# ✓ Orchestrator: healthy (uptime: 5d 3h)\\n# ✓ Control Center: healthy\\n# ✓ Vault Service: healthy\\n# ✓ Database: healthy (connections: 45/100)\\n# ✓ Network: healthy\\n# ✗ MCP Server: degraded (high latency) # Exit code: 0 = healthy, 1 = degraded, 2 = unhealthy","breadcrumbs":"Platform Health » Quick Health Check","id":"1050","title":"Quick Health Check"},"1051":{"body":"All services expose /health endpoints returning standardized responses.","breadcrumbs":"Platform Health » Service Health Endpoints","id":"1051","title":"Service Health Endpoints"},"1052":{"body":"curl [http://localhost:8080/health](http://localhost:8080/health) { \\"status\\": \\"healthy\\", \\"version\\": \\"5.0.0\\", \\"uptime_seconds\\": 432000, \\"checks\\": { \\"database\\": \\"healthy\\", \\"file_system\\": \\"healthy\\", \\"memory\\": \\"healthy\\" }, \\"metrics\\": { \\"active_workflows\\": 12, \\"queued_tasks\\": 45, \\"completed_tasks\\": 9876, \\"worker_threads\\": 8 }, \\"timestamp\\": \\"2026-01-16T10:30:00Z\\"\\n} Health status values: healthy - Service operating normally degraded - Service functional with reduced capacity unhealthy - Service not functioning","breadcrumbs":"Platform Health » Orchestrator Health","id":"1052","title":"Orchestrator Health"},"1053":{"body":"curl [http://localhost:8081/health](http://localhost:8081/health) { \\"status\\": \\"healthy\\", \\"version\\": \\"5.0.0\\", \\"checks\\": { \\"database\\": \\"healthy\\", \\"orchestrator\\": \\"healthy\\", \\"vault\\": \\"healthy\\", \\"auth\\": \\"healthy\\" }, \\"metrics\\": { \\"active_sessions\\": 23, \\"api_requests_per_second\\": 156, \\"p95_latency_ms\\": 45 }\\n}","breadcrumbs":"Platform Health » Control Center Health","id":"1053","title":"Control Center Health"},"1054":{"body":"curl [http://localhost:8085/health](http://localhost:8085/health) { \\"status\\": \\"healthy\\", \\"checks\\": { \\"kms_backend\\": \\"healthy\\", \\"encryption\\": \\"healthy\\", \\"key_rotation\\": \\"healthy\\" }, \\"metrics\\": { \\"active_secrets\\": 234, \\"encryption_ops_per_second\\": 50, \\"kms_latency_ms\\": 3 }\\n}","breadcrumbs":"Platform Health » Vault Service Health","id":"1054","title":"Vault Service Health"},"1055":{"body":"","breadcrumbs":"Platform Health » System Health Checks","id":"1055","title":"System Health Checks"},"1056":{"body":"# Run all health checks\\nprovisioning health check --all # Check specific components\\nprovisioning health check --components orchestrator,database,network # Output detailed report\\nprovisioning health check --detailed --output /tmp/health-report.json","breadcrumbs":"Platform Health » Comprehensive Health Check","id":"1056","title":"Comprehensive Health Check"},"1057":{"body":"Platform health checking verifies: Service Availability - All services responding Database Connectivity - SurrealDB reachable and responsive Filesystem Health - Disk space and I/O performance Network Connectivity - Internal and external connectivity Resource Utilization - CPU, memory, disk within limits Dependency Status - External services available Security Status - Authentication and encryption functional","breadcrumbs":"Platform Health » Health Check Components","id":"1057","title":"Health Check Components"},"1058":{"body":"# Check database health\\nprovisioning health database # Output:\\n# ✓ Connection: healthy (latency: 2ms)\\n# ✓ Disk usage: 45% (22GB / 50GB)\\n# ✓ Active connections: 45 / 100\\n# ✓ Query performance: healthy (avg: 15ms)\\n# ✗ Replication: warning (lag: 5s) Detailed database metrics: # Connection pool status\\nprovisioning database pool-status # Slow query analysis\\nprovisioning database slow-queries --threshold 1000ms # Storage usage\\nprovisioning database storage-stats","breadcrumbs":"Platform Health » Database Health","id":"1058","title":"Database Health"},"1059":{"body":"# Check disk space and I/O\\nprovisioning health filesystem # Output:\\n# ✓ Root filesystem: 65% used (325GB / 500GB)\\n# ✓ Data filesystem: 45% used (225GB / 500GB)\\n# ✓ I/O latency: healthy (avg: 5ms)\\n# ✗ Inodes: warning (85% used) Check specific paths: # Check data directory\\ndf -h /var/lib/provisioning # Check I/O performance\\niostat -x 1 5","breadcrumbs":"Platform Health » Filesystem Health","id":"1059","title":"Filesystem Health"},"106":{"body":"","breadcrumbs":"First Deployment » Part 4: Server Provisioning","id":"106","title":"Part 4: Server Provisioning"},"1060":{"body":"# Check network connectivity\\nprovisioning health network # Test external connectivity\\nprovisioning health network --external # Test provider connectivity\\nprovisioning health network --provider upcloud Network health checks: Internal service-to-service connectivity DNS resolution External API reachability (cloud providers) Network latency and packet loss Firewall rules validation","breadcrumbs":"Platform Health » Network Health","id":"1060","title":"Network Health"},"1061":{"body":"","breadcrumbs":"Platform Health » Resource Monitoring","id":"1061","title":"Resource Monitoring"},"1062":{"body":"# Check CPU utilization\\nprovisioning health cpu # Per-service CPU usage\\nprovisioning platform metrics --metric cpu_usage # Alert if CPU > 90% for 5 minutes Monitor CPU load: # System load average\\nuptime # Per-process CPU\\ntop -b -n 1 | grep provisioning","breadcrumbs":"Platform Health » CPU Health","id":"1062","title":"CPU Health"},"1063":{"body":"# Check memory utilization\\nprovisioning health memory # Memory breakdown by service\\nprovisioning platform metrics --metric memory_usage # Detect memory leaks\\nprovisioning health memory --leak-detection Memory metrics: # Available memory\\nfree -h # Per-service memory\\nps aux | grep provisioning | awk \'{sum+=$6} END {print sum/1024 \\" MB\\"}\'","breadcrumbs":"Platform Health » Memory Health","id":"1063","title":"Memory Health"},"1064":{"body":"# Check disk health\\nprovisioning health disk # SMART status (if available)\\nsudo smartctl -H /dev/sda","breadcrumbs":"Platform Health » Disk Health","id":"1064","title":"Disk Health"},"1065":{"body":"","breadcrumbs":"Platform Health » Automated Health Monitoring","id":"1065","title":"Automated Health Monitoring"},"1066":{"body":"Enable continuous health monitoring: # Start health monitor\\nprovisioning health monitor --interval 30 # Monitor with alerts\\nprovisioning health monitor --interval 30 --alert-email [ops@example.com](mailto:ops@example.com) # Monitor specific components\\nprovisioning health monitor --components orchestrator,database --interval 10","breadcrumbs":"Platform Health » Health Check Service","id":"1066","title":"Health Check Service"},"1067":{"body":"Systemd watchdog for automatic restart on failure: # /etc/systemd/system/provisioning-orchestrator.service\\n[Service]\\nType=notify\\nWatchdogSec=30\\nRestart=on-failure\\nRestartSec=10\\nStartLimitIntervalSec=300\\nStartLimitBurst=5 Service sends periodic health status: // Rust service code\\nsd_notify::notify(true, &[NotifyState::Watchdog])?;","breadcrumbs":"Platform Health » Systemd Health Monitoring","id":"1067","title":"Systemd Health Monitoring"},"1068":{"body":"","breadcrumbs":"Platform Health » Health Dashboards","id":"1068","title":"Health Dashboards"},"1069":{"body":"Import platform health dashboard: provisioning monitoring install-dashboard --name platform-health Dashboard panels: Service status indicators Resource utilization gauges Error rate graphs Latency histograms Workflow success rate Database connection pool Access: http://localhost:3000/d/platform-health","breadcrumbs":"Platform Health » Grafana Health Dashboard","id":"1069","title":"Grafana Health Dashboard"},"107":{"body":"# Create all servers in parallel\\nprovisioning server create --infra k8s-cluster --yes Progress tracking: Creating 3 servers... k8s-control-01: [████████████████████████] 100% k8s-worker-01: [████████████████████████] 100% k8s-worker-02: [████████████████████████] 100% Servers created: 3/3\\nSSH configured: 3/3\\nNetwork ready: 3/3 Servers available: k8s-control-01: 94.237.x.x (running) k8s-worker-01: 94.237.x.x (running) k8s-worker-02: 94.237.x.x (running)","breadcrumbs":"First Deployment » Create Servers","id":"107","title":"Create Servers"},"1070":{"body":"Real-time health monitoring in terminal: # Interactive health dashboard\\nprovisioning health dashboard # Auto-refresh every 5 seconds\\nprovisioning health dashboard --refresh 5","breadcrumbs":"Platform Health » CLI Health Dashboard","id":"1070","title":"CLI Health Dashboard"},"1071":{"body":"","breadcrumbs":"Platform Health » Health Alerts","id":"1071","title":"Health Alerts"},"1072":{"body":"# Platform health alerts\\ngroups: - name: platform_health rules: - alert: ServiceUnhealthy expr: up{job=~\\"provisioning-.*\\"} == 0 for: 1m labels: severity: critical annotations: summary: \\"Service is unhealthy\\" - alert: HighMemoryUsage expr: process_resident_memory_bytes > 4e9 for: 5m labels: severity: warning - alert: DatabaseConnectionPoolExhausted expr: database_connection_pool_active / database_connection_pool_max > 0.9 for: 2m labels: severity: critical","breadcrumbs":"Platform Health » Prometheus Alert Rules","id":"1072","title":"Prometheus Alert Rules"},"1073":{"body":"Configure health check notifications: # /etc/provisioning/health.toml\\n[notifications]\\nenabled = true [notifications.email]\\nenabled = true\\nsmtp_server = \\"smtp.example.com\\"\\nfrom = \\"[health@provisioning.example.com](mailto:health@provisioning.example.com)\\"\\nto = [\\"[ops@example.com](mailto:ops@example.com)\\"] [notifications.slack]\\nenabled = true\\nwebhook_url = \\" [https://hooks.slack.com/services/...\\"](https://hooks.slack.com/services/...\\")\\nchannel = \\"#provisioning-health\\" [notifications.pagerduty]\\nenabled = true\\nservice_key = \\"...\\"","breadcrumbs":"Platform Health » Health Check Notifications","id":"1073","title":"Health Check Notifications"},"1074":{"body":"","breadcrumbs":"Platform Health » Dependency Health","id":"1074","title":"Dependency Health"},"1075":{"body":"Check health of dependencies: # Check cloud provider API\\nprovisioning health dependency upcloud # Check vault service\\nprovisioning health dependency vault # Check all dependencies\\nprovisioning health dependency --all Dependency health includes: API reachability Authentication validity API quota/rate limits Service degradation status","breadcrumbs":"Platform Health » External Service Health","id":"1075","title":"External Service Health"},"1076":{"body":"Monitor integrated services: # Kubernetes cluster health (if managing K8s)\\nprovisioning health kubernetes # Database replication health\\nprovisioning health database --replication # Secret store health\\nprovisioning health secrets","breadcrumbs":"Platform Health » Third-party Service Monitoring","id":"1076","title":"Third-party Service Monitoring"},"1077":{"body":"Key metrics tracked for health monitoring:","breadcrumbs":"Platform Health » Health Metrics","id":"1077","title":"Health Metrics"},"1078":{"body":"provisioning_service_up{service=\\"orchestrator\\"} 1\\nprovisioning_service_health_status{service=\\"orchestrator\\"} 1\\nprovisioning_service_uptime_seconds{service=\\"orchestrator\\"} 432000","breadcrumbs":"Platform Health » Service Metrics","id":"1078","title":"Service Metrics"},"1079":{"body":"provisioning_cpu_usage_percent 45\\nprovisioning_memory_usage_bytes 2.5e9\\nprovisioning_disk_usage_percent{mount=\\"/var/lib/provisioning\\"} 45\\nprovisioning_network_errors_total 0","breadcrumbs":"Platform Health » Resource Metrics","id":"1079","title":"Resource Metrics"},"108":{"body":"# Test SSH connectivity\\nprovisioning server ssh k8s-control-01 -- uname -a # Check all servers\\nprovisioning server list","breadcrumbs":"First Deployment » Verify Server Access","id":"108","title":"Verify Server Access"},"1080":{"body":"provisioning_api_latency_p50_ms 25\\nprovisioning_api_latency_p95_ms 85\\nprovisioning_api_latency_p99_ms 150\\nprovisioning_workflow_duration_seconds 45","breadcrumbs":"Platform Health » Performance Metrics","id":"1080","title":"Performance Metrics"},"1081":{"body":"Monitor all critical services continuously Set appropriate alert thresholds Test alert notifications regularly Maintain health check runbooks Review health metrics weekly Establish health baselines Automate remediation where possible Document health status definitions Integrate health checks with CI/CD Monitor upstream dependencies","breadcrumbs":"Platform Health » Health Best Practices","id":"1081","title":"Health Best Practices"},"1082":{"body":"When health check fails: # 1. Identify unhealthy component\\nprovisioning health check --detailed # 2. View component logs\\njournalctl -u provisioning- -n 100 # 3. Check resource availability\\nprovisioning health resources # 4. Restart unhealthy service\\nsudo systemctl restart provisioning- # 5. Verify recovery\\nprovisioning health check # 6. Review recent changes\\ngit log --since=\\"1 day ago\\" -- /etc/provisioning/","breadcrumbs":"Platform Health » Troubleshooting Unhealthy State","id":"1082","title":"Troubleshooting Unhealthy State"},"1083":{"body":"Service Management - Service lifecycle Monitoring - Comprehensive monitoring Troubleshooting - Issue resolution Deployment Modes - Installation modes","breadcrumbs":"Platform Health » Related Documentation","id":"1083","title":"Related Documentation"},"1084":{"body":"Enterprise-grade security infrastructure with 12 integrated components providing authentication, authorization, encryption, and compliance.","breadcrumbs":"Security Overview » Security System","id":"1084","title":"Security System"},"1085":{"body":"The Provisioning platform security system delivers comprehensive protection across all layers of the infrastructure automation platform. Built for enterprise deployments, it provides defense-in-depth through multiple security controls working together.","breadcrumbs":"Security Overview » Overview","id":"1085","title":"Overview"},"1086":{"body":"The security system is organized into 12 core components: Component Purpose Key Features Authentication User identity verification JWT tokens, session management, multi-provider auth Authorization Access control enforcement Cedar policy engine, RBAC, fine-grained permissions MFA Multi-factor authentication TOTP, WebAuthn/FIDO2, backup codes Audit Logging Comprehensive audit trails 7-year retention, 5 export formats, compliance reporting KMS Key management 5 KMS backends, envelope encryption, key rotation Secrets Management Secure secret storage SecretumVault integration, SOPS/Age, dynamic secrets Encryption Data protection At-rest and in-transit encryption, AES-256-GCM Secure Communication Network security TLS/mTLS, certificate management, secure channels Certificate Management PKI operations CA management, certificate issuance, rotation Compliance Regulatory adherence SOC2, GDPR, HIPAA, policy enforcement Security Testing Validation framework 350+ tests, vulnerability scanning, penetration testing Break-Glass Emergency access Multi-party approval, audit trails, time-limited access","breadcrumbs":"Security Overview » Security Architecture","id":"1086","title":"Security Architecture"},"1087":{"body":"","breadcrumbs":"Security Overview » Security Layers","id":"1087","title":"Security Layers"},"1088":{"body":"Authentication : Verify user identity with JWT tokens and Argon2id password hashing Authorization : Enforce access control with Cedar policies and RBAC MFA : Add second factor with TOTP or FIDO2 hardware keys","breadcrumbs":"Security Overview » Layer 1: Identity and Access","id":"1088","title":"Layer 1: Identity and Access"},"1089":{"body":"Encryption : Protect data at rest with AES-256-GCM and in transit with TLS 1.3 Secrets Management : Store secrets securely in SecretumVault with automatic rotation KMS : Manage encryption keys with envelope encryption across 5 backend options","breadcrumbs":"Security Overview » Layer 2: Data Protection","id":"1089","title":"Layer 2: Data Protection"},"109":{"body":"","breadcrumbs":"First Deployment » Part 5: Service Installation","id":"109","title":"Part 5: Service Installation"},"1090":{"body":"Secure Communication : Enforce TLS/mTLS for all service-to-service communication Certificate Management : Automate certificate lifecycle with cert-manager integration Network Policies : Control traffic flow with Kubernetes NetworkPolicies","breadcrumbs":"Security Overview » Layer 3: Network Security","id":"1090","title":"Layer 3: Network Security"},"1091":{"body":"Audit Logging : Record all security events with 7-year retention Compliance : Validate against SOC2, GDPR, and HIPAA frameworks Security Testing : Continuous validation with automated security test suite","breadcrumbs":"Security Overview » Layer 4: Compliance and Monitoring","id":"1091","title":"Layer 4: Compliance and Monitoring"},"1092":{"body":"Authentication Overhead : Less than 20ms per request with JWT verification Authorization Decision : Less than 10ms with Cedar policy evaluation Encryption Operations : Less than 5ms with KMS-backed envelope encryption Audit Logging : Asynchronous with zero blocking on critical path MFA Verification : Less than 100ms for TOTP, less than 500ms for WebAuthn","breadcrumbs":"Security Overview » Performance Characteristics","id":"1092","title":"Performance Characteristics"},"1093":{"body":"The security system adheres to industry standards and best practices: OWASP Top 10 : Protection against common web vulnerabilities NIST Cybersecurity Framework : Aligned with identify, protect, detect, respond, recover Zero Trust Architecture : Never trust, always verify principle Defense in Depth : Multiple layers of security controls Least Privilege : Minimal access rights for users and services Secure by Default : Security controls enabled out of the box","breadcrumbs":"Security Overview » Security Standards","id":"1093","title":"Security Standards"},"1094":{"body":"All security components work together as a cohesive system: ┌─────────────────────────────────────────────────────────────┐\\n│ User Request │\\n└──────────────────────┬──────────────────────────────────────┘ │ ▼\\n┌─────────────────────────────────────────────────────────────┐\\n│ Authentication (JWT + Session) │\\n│ ↓ │\\n│ Authorization (Cedar Policies) │\\n│ ↓ │\\n│ MFA Verification (if required) │\\n└──────────────────────┬──────────────────────────────────────┘ │ ▼\\n┌─────────────────────────────────────────────────────────────┐\\n│ Audit Logging (Record all actions) │\\n└──────────────────────┬──────────────────────────────────────┘ │ ▼\\n┌─────────────────────────────────────────────────────────────┐\\n│ Secure Communication (TLS/mTLS) │\\n│ ↓ │\\n│ Data Access (Encrypted with KMS) │\\n│ ↓ │\\n│ Secrets Retrieved (SecretumVault) │\\n└──────────────────────┬──────────────────────────────────────┘ │ ▼\\n┌─────────────────────────────────────────────────────────────┐\\n│ Compliance Validation (SOC2/GDPR checks) │\\n└──────────────────────┬──────────────────────────────────────┘ │ ▼\\n┌─────────────────────────────────────────────────────────────┐\\n│ Response │\\n└─────────────────────────────────────────────────────────────┘","breadcrumbs":"Security Overview » Component Integration","id":"1094","title":"Component Integration"},"1095":{"body":"Security settings are managed through hierarchical configuration: # Security defaults in config/security.toml\\n[security]\\nauth_enabled = true\\nmfa_required = true\\naudit_enabled = true\\nencryption_at_rest = true\\ntls_min_version = \\"1.3\\" [security.jwt]\\nalgorithm = \\"RS256\\"\\naccess_token_ttl = 900 # 15 minutes\\nrefresh_token_ttl = 604800 # 7 days [security.mfa]\\ntotp_enabled = true\\nwebauthn_enabled = true\\nbackup_codes_count = 10 [security.kms]\\nbackend = \\"secretumvault\\"\\nenvelope_encryption = true\\nkey_rotation_days = 90 [security.audit]\\nretention_days = 2555 # 7 years\\nexport_formats = [\\"json\\", \\"csv\\", \\"parquet\\", \\"sqlite\\", \\"syslog\\"] [security.compliance]\\nframeworks = [\\"soc2\\", \\"gdpr\\", \\"hipaa\\"]\\npolicy_enforcement = \\"strict\\"","breadcrumbs":"Security Overview » Security Configuration","id":"1095","title":"Security Configuration"},"1096":{"body":"Enable security system for your deployment: # Enable all security features\\nprovisioning config set security.enabled true # Configure authentication\\nprovisioning config set security.auth.jwt_algorithm RS256\\nprovisioning config set security.auth.mfa_required true # Set up SecretumVault integration\\nprovisioning config set security.secrets.backend secretumvault\\nprovisioning config set security.secrets.url [http://localhost:8200](http://localhost:8200) # Enable audit logging\\nprovisioning config set security.audit.enabled true\\nprovisioning config set security.audit.retention_days 2555 # Configure compliance framework\\nprovisioning config set security.compliance.frameworks soc2,gdpr # Verify security configuration\\nprovisioning security validate","breadcrumbs":"Security Overview » Quick Start","id":"1096","title":"Quick Start"},"1097":{"body":"This security documentation is organized into 12 detailed guides: Authentication - JWT token-based authentication and session management Authorization - Cedar policy engine and RBAC access control Multi-Factor Authentication - TOTP and WebAuthn/FIDO2 implementation Audit Logging - Comprehensive audit trails and compliance reporting Key Management Service - Encryption key management and rotation Secrets Management - SecretumVault and SOPS/Age integration Encryption - At-rest and in-transit data protection Secure Communication - TLS/mTLS and network security Certificate Management - PKI and certificate lifecycle Compliance - SOC2, GDPR, HIPAA frameworks Security Testing - Test suite and vulnerability scanning Break-Glass Procedures - Emergency access and recovery","breadcrumbs":"Security Overview » Documentation Structure","id":"1097","title":"Documentation Structure"},"1098":{"body":"The security system tracks key metrics for monitoring and reporting: Authentication Success Rate : Percentage of successful login attempts MFA Adoption Rate : Percentage of users with MFA enabled Policy Violations : Count of authorization denials Audit Event Rate : Events logged per second Secret Rotation Compliance : Percentage of secrets rotated within policy Certificate Expiration : Days until certificate expiration Compliance Score : Overall compliance posture percentage Security Test Pass Rate : Percentage of security tests passing","breadcrumbs":"Security Overview » Security Metrics","id":"1098","title":"Security Metrics"},"1099":{"body":"Follow these security best practices: Enable MFA for all users : Require second factor for all accounts Rotate secrets regularly : Automate secret rotation every 90 days Monitor audit logs : Review security events daily Test security controls : Run security test suite before deployments Keep certificates current : Automate certificate renewal 30 days before expiration Review policies regularly : Audit Cedar policies quarterly Limit break-glass access : Require multi-party approval for emergency access Encrypt all data : Enable encryption at rest and in transit Follow least privilege : Grant minimal required permissions Validate compliance : Run compliance checks before production deployments","breadcrumbs":"Security Overview » Best Practices","id":"1099","title":"Best Practices"},"11":{"body":"","breadcrumbs":"Getting Started » Quick Start Guides","id":"11","title":"Quick Start Guides"},"110":{"body":"# Install all task services (automatic dependency resolution)\\nprovisioning taskserv create kubernetes --infra k8s-cluster Installation flow (automatic): Resolving dependencies... containerd → etcd → kubernetes → cilium, rook-ceph Installing task services: 5 [1/5] Installing containerd... k8s-control-01: [████████████████████████] 100% k8s-worker-01: [████████████████████████] 100% k8s-worker-02: [████████████████████████] 100% [2/5] Installing etcd... k8s-control-01: [████████████████████████] 100% [3/5] Installing kubernetes... Control plane init: [████████████████████████] 100% Worker join: [████████████████████████] 100% Cluster ready: [████████████████████████] 100% [4/5] Installing cilium... CNI deployment: [████████████████████████] 100% Network policies: [████████████████████████] 100% [5/5] Installing rook-ceph... Operator: [████████████████████████] 100% Cluster: [████████████████████████] 100% Storage class: [████████████████████████] 100% All task services installed successfully","breadcrumbs":"First Deployment » Install Task Services","id":"110","title":"Install Task Services"},"1100":{"body":"For security issues and questions: Security Documentation : Complete guides in this security section CLI Help : provisioning security help Security Validation : provisioning security validate Audit Query : provisioning security audit query Compliance Check : provisioning security compliance check","breadcrumbs":"Security Overview » Getting Help","id":"1100","title":"Getting Help"},"1101":{"body":"The security system is continuously updated to address emerging threats and vulnerabilities. Subscribe to security advisories and apply updates promptly. Next Steps : Read Authentication Guide to set up user authentication Configure Authorization with Cedar policies Enable MFA for all user accounts Set up Audit Logging for compliance","breadcrumbs":"Security Overview » Security Updates","id":"1101","title":"Security Updates"},"1102":{"body":"JWT token-based authentication with session management, login flows, and multi-provider support.","breadcrumbs":"Authentication » Authentication","id":"1102","title":"Authentication"},"1103":{"body":"The authentication system verifies user identity through JWT (JSON Web Token) tokens with RS256 signatures and Argon2id password hashing. It provides secure session management, token refresh capabilities, and support for multiple authentication providers.","breadcrumbs":"Authentication » Overview","id":"1103","title":"Overview"},"1104":{"body":"","breadcrumbs":"Authentication » Architecture","id":"1104","title":"Architecture"},"1105":{"body":"┌──────────┐ ┌──────────────┐ ┌────────────┐\\n│ Client │ │ Auth Service│ │ Database │\\n└────┬─────┘ └──────┬───────┘ └─────┬──────┘ │ │ │ │ POST /auth/login │ │ │ {username, password} │ │ │────────────────────────────>│ │ │ │ │ │ │ Find user by username │ │ │─────────────────────────────>│ │ │<─────────────────────────────│ │ │ User record │ │ │ │ │ │ Verify password (Argon2id) │ │ │ │ │ │ Create session │ │ │─────────────────────────────>│ │ │<─────────────────────────────│ │ │ │ │ │ Generate JWT token pair │ │ │ │ │ {access_token, refresh} │ │ │<────────────────────────────│ │ │ │ │","breadcrumbs":"Authentication » Authentication Flow","id":"1105","title":"Authentication Flow"},"1106":{"body":"Component Purpose Technology AuthService Core authentication logic Rust service in control-center JwtService Token generation and verification RS256 algorithm with jsonwebtoken crate SessionManager Session lifecycle management Database-backed session storage PasswordHasher Password hashing and verification Argon2id with configurable parameters UserService User account management CRUD operations with role assignment","breadcrumbs":"Authentication » Components","id":"1106","title":"Components"},"1107":{"body":"","breadcrumbs":"Authentication » JWT Token Structure","id":"1107","title":"JWT Token Structure"},"1108":{"body":"Short-lived token for API authentication (default: 15 minutes). { \\"header\\": { \\"alg\\": \\"RS256\\", \\"typ\\": \\"JWT\\" }, \\"payload\\": { \\"sub\\": \\"550e8400-e29b-41d4-a716-446655440000\\", \\"email\\": \\"[user@example.com](mailto:user@example.com)\\", \\"username\\": \\"alice\\", \\"roles\\": [\\"user\\", \\"developer\\"], \\"session_id\\": \\"sess_abc123\\", \\"mfa_verified\\": true, \\"permissions_hash\\": \\"sha256:abc123...\\", \\"iat\\": 1704067200, \\"exp\\": 1704068100, \\"iss\\": \\"provisioning-platform\\", \\"aud\\": \\"api.provisioning.example.com\\" }\\n}","breadcrumbs":"Authentication » Access Token","id":"1108","title":"Access Token"},"1109":{"body":"Long-lived token for obtaining new access tokens (default: 7 days). { \\"header\\": { \\"alg\\": \\"RS256\\", \\"typ\\": \\"JWT\\" }, \\"payload\\": { \\"sub\\": \\"550e8400-e29b-41d4-a716-446655440000\\", \\"session_id\\": \\"sess_abc123\\", \\"token_type\\": \\"refresh\\", \\"iat\\": 1704067200, \\"exp\\": 1704672000, \\"iss\\": \\"provisioning-platform\\" }\\n}","breadcrumbs":"Authentication » Refresh Token","id":"1109","title":"Refresh Token"},"111":{"body":"# SSH to control plane\\nprovisioning server ssh k8s-control-01 # Check cluster status\\nkubectl get nodes\\nkubectl get pods --all-namespaces\\nkubectl get storageclass Expected output: NAME STATUS ROLES AGE VERSION\\nk8s-control-01 Ready control-plane 5m v1.28.0\\nk8s-worker-01 Ready 4m v1.28.0\\nk8s-worker-02 Ready 4m v1.28.0 NAMESPACE NAME READY STATUS\\nkube-system cilium-xxxxx 1/1 Running\\nkube-system cilium-operator-xxxxx 1/1 Running\\nkube-system etcd-k8s-control-01 1/1 Running\\nrook-ceph rook-ceph-operator-xxxxx 1/1 Running NAME PROVISIONER\\nceph-rbd rook-ceph.rbd.csi.ceph.com","breadcrumbs":"First Deployment » Verify Kubernetes Cluster","id":"111","title":"Verify Kubernetes Cluster"},"1110":{"body":"","breadcrumbs":"Authentication » Password Security","id":"1110","title":"Password Security"},"1111":{"body":"Password hashing uses Argon2id with security-hardened parameters: // Default Argon2id parameters\\nargon2::Params { m_cost: 65536, // 64 MB memory t_cost: 3, // 3 iterations p_cost: 4, // 4 parallelism output_len: 32 // 32 byte hash\\n}","breadcrumbs":"Authentication » Argon2id Configuration","id":"1111","title":"Argon2id Configuration"},"1112":{"body":"Default password policy enforces: Minimum 12 characters At least one uppercase letter At least one lowercase letter At least one digit At least one special character Not in common password list Not similar to username or email","breadcrumbs":"Authentication » Password Requirements","id":"1112","title":"Password Requirements"},"1113":{"body":"","breadcrumbs":"Authentication » Session Management","id":"1113","title":"Session Management"},"1114":{"body":"Creation : New session created on successful login Active : Session tracked with last activity timestamp Refresh : Session extended on token refresh Expiration : Session expires after inactivity timeout Revocation : Manual logout or security event terminates session","breadcrumbs":"Authentication » Session Lifecycle","id":"1114","title":"Session Lifecycle"},"1115":{"body":"Sessions stored in database with: pub struct Session { pub session_id: Uuid, pub user_id: Uuid, pub created_at: DateTime, pub expires_at: DateTime, pub last_activity: DateTime, pub ip_address: Option, pub user_agent: Option, pub is_active: bool,\\n}","breadcrumbs":"Authentication » Session Storage","id":"1115","title":"Session Storage"},"1116":{"body":"Track multiple concurrent sessions per user: # List active sessions for user\\nprovisioning security sessions list --user alice # Revoke specific session\\nprovisioning security sessions revoke --session-id sess_abc123 # Revoke all sessions except current\\nprovisioning security sessions revoke-all --except-current","breadcrumbs":"Authentication » Session Tracking","id":"1116","title":"Session Tracking"},"1117":{"body":"","breadcrumbs":"Authentication » Login Flows","id":"1117","title":"Login Flows"},"1118":{"body":"Basic username/password authentication: # CLI login\\nprovisioning auth login --username alice --password # API login\\ncurl -X POST [https://api.provisioning.example.com/auth/login](https://api.provisioning.example.com/auth/login) \\\\ -H \\"Content-Type: application/json\\" \\\\ -d \'{ \\"username_or_email\\": \\"alice\\", \\"password\\": \\"SecurePassword123!\\", \\"client_info\\": { \\"ip_address\\": \\"192.168.1.100\\", \\"user_agent\\": \\"provisioning-cli/1.0\\" } }\' Response: { \\"access_token\\": \\"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...\\", \\"refresh_token\\": \\"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...\\", \\"token_type\\": \\"Bearer\\", \\"expires_in\\": 900, \\"user\\": { \\"user_id\\": \\"550e8400-e29b-41d4-a716-446655440000\\", \\"username\\": \\"alice\\", \\"email\\": \\"[alice@example.com](mailto:alice@example.com)\\", \\"roles\\": [\\"user\\", \\"developer\\"] }\\n}","breadcrumbs":"Authentication » Standard Login","id":"1118","title":"Standard Login"},"1119":{"body":"Two-phase authentication with MFA: # Phase 1: Initial authentication\\nprovisioning auth login --username alice --password # Response indicates MFA required\\n# {\\n# \\"mfa_required\\": true,\\n# \\"mfa_token\\": \\"temp_token_abc123\\",\\n# \\"available_methods\\": [\\"totp\\", \\"webauthn\\"]\\n# } # Phase 2: MFA verification\\nprovisioning auth mfa-verify --mfa-token temp_token_abc123 --code 123456","breadcrumbs":"Authentication » MFA Login","id":"1119","title":"MFA Login"},"112":{"body":"","breadcrumbs":"First Deployment » Part 6: Deployment Verification","id":"112","title":"Part 6: Deployment Verification"},"1120":{"body":"Single Sign-On with external providers: # Initiate SSO flow\\nprovisioning auth sso --provider okta # Or with SAML\\nprovisioning auth sso --provider azure-ad --protocol saml","breadcrumbs":"Authentication » SSO Login","id":"1120","title":"SSO Login"},"1121":{"body":"","breadcrumbs":"Authentication » Token Refresh","id":"1121","title":"Token Refresh"},"1122":{"body":"Client libraries automatically refresh tokens before expiration: // Automatic token refresh in Rust client\\nlet client = ProvisioningClient::new() .with_auto_refresh(true) .build()?; // Tokens refreshed transparently\\nclient.server().list().await?;","breadcrumbs":"Authentication » Automatic Refresh","id":"1122","title":"Automatic Refresh"},"1123":{"body":"Explicit token refresh when needed: # CLI token refresh\\nprovisioning auth refresh # API token refresh\\ncurl -X POST [https://api.provisioning.example.com/auth/refresh](https://api.provisioning.example.com/auth/refresh) \\\\ -H \\"Content-Type: application/json\\" \\\\ -d \'{ \\"refresh_token\\": \\"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...\\" }\' Response: { \\"access_token\\": \\"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...\\", \\"token_type\\": \\"Bearer\\", \\"expires_in\\": 900\\n}","breadcrumbs":"Authentication » Manual Refresh","id":"1123","title":"Manual Refresh"},"1124":{"body":"","breadcrumbs":"Authentication » Multi-Provider Authentication","id":"1124","title":"Multi-Provider Authentication"},"1125":{"body":"Provider Type Configuration Local Username/password Built-in user database LDAP Directory service Active Directory, OpenLDAP SAML SSO Okta, Azure AD, OneLogin OIDC OAuth2/OpenID Google, GitHub, Auth0 mTLS Certificate Client certificate authentication","breadcrumbs":"Authentication » Supported Providers","id":"1125","title":"Supported Providers"},"1126":{"body":"[auth.providers.ldap]\\nenabled = true\\nserver = \\"ldap://ldap.example.com\\"\\nbase_dn = \\"dc=example,dc=com\\"\\nbind_dn = \\"cn=admin,dc=example,dc=com\\"\\nuser_filter = \\"(uid={username})\\" [auth.providers.saml]\\nenabled = true\\nentity_id = \\" [https://provisioning.example.com\\"](https://provisioning.example.com\\")\\nsso_url = \\" [https://okta.example.com/sso/saml\\"](https://okta.example.com/sso/saml\\")\\ncertificate_path = \\"/etc/provisioning/saml-cert.pem\\" [auth.providers.oidc]\\nenabled = true\\nissuer = \\" [https://accounts.google.com\\"](https://accounts.google.com\\")\\nclient_id = \\"client_id_here\\"\\nclient_secret = \\"client_secret_here\\"\\nredirect_uri = \\" [https://provisioning.example.com/auth/callback\\"](https://provisioning.example.com/auth/callback\\")","breadcrumbs":"Authentication » Provider Configuration","id":"1126","title":"Provider Configuration"},"1127":{"body":"","breadcrumbs":"Authentication » Token Validation","id":"1127","title":"Token Validation"},"1128":{"body":"All API requests validate JWT tokens: // Middleware validates JWT on every request\\npub async fn jwt_auth_middleware( headers: HeaderMap, State(jwt_service): State>, mut request: Request, next: Next,\\n) -> Result { // Extract token from Authorization header let token = extract_bearer_token(&headers)?; // Verify signature and claims let claims = jwt_service.verify_access_token(&token)?; // Check expiration if claims.exp < Utc::now().timestamp() { return Err(AuthError::TokenExpired); } // Inject user context into request request.extensions_mut().insert(claims); Ok(next.run(request).await)\\n}","breadcrumbs":"Authentication » JWT Verification","id":"1128","title":"JWT Verification"},"1129":{"body":"Revoke tokens on security events: # Revoke all tokens for user\\nprovisioning security tokens revoke-user --user alice # Revoke specific token\\nprovisioning security tokens revoke --token-id token_abc123 # Check token status\\nprovisioning security tokens status --token eyJhbGci...","breadcrumbs":"Authentication » Token Revocation","id":"1129","title":"Token Revocation"},"113":{"body":"# Platform-level health check\\nprovisioning cluster status k8s-cluster # Individual service health\\nprovisioning taskserv status kubernetes\\nprovisioning taskserv status cilium\\nprovisioning taskserv status rook-ceph","breadcrumbs":"First Deployment » Health Checks","id":"113","title":"Health Checks"},"1130":{"body":"","breadcrumbs":"Authentication » Security Hardening","id":"1130","title":"Security Hardening"},"1131":{"body":"Secure authentication settings: [security.auth]\\n# JWT settings\\njwt_algorithm = \\"RS256\\"\\njwt_issuer = \\"provisioning-platform\\"\\naccess_token_ttl = 900 # 15 minutes\\nrefresh_token_ttl = 604800 # 7 days\\ntoken_leeway = 30 # 30 seconds clock skew # Password policy\\npassword_min_length = 12\\npassword_require_uppercase = true\\npassword_require_lowercase = true\\npassword_require_digit = true\\npassword_require_special = true\\npassword_check_common = true # Session settings\\nsession_timeout = 1800 # 30 minutes inactivity\\nmax_sessions_per_user = 5\\nremember_me_duration = 2592000 # 30 days # Security controls\\nenforce_mfa = true\\nallow_password_reset = true\\nlockout_after_attempts = 5\\nlockout_duration = 900 # 15 minutes","breadcrumbs":"Authentication » Configuration","id":"1131","title":"Configuration"},"1132":{"body":"Use strong passwords : Enforce password policy with minimum 12 characters Enable MFA : Require second factor for all users Rotate keys regularly : Update JWT signing keys every 90 days Monitor failed attempts : Alert on suspicious login patterns Limit session duration : Use short access token TTL with refresh tokens Secure token storage : Store tokens securely, never in local storage Validate on every request : Always verify JWT signature and expiration Use HTTPS only : Never transmit tokens over unencrypted connections","breadcrumbs":"Authentication » Best Practices","id":"1132","title":"Best Practices"},"1133":{"body":"","breadcrumbs":"Authentication » CLI Integration","id":"1133","title":"CLI Integration"},"1134":{"body":"# Login with credentials\\nprovisioning auth login --username alice # Login with MFA\\nprovisioning auth login --username alice --mfa # Check authentication status\\nprovisioning auth status # Logout (revoke session)\\nprovisioning auth logout # List active sessions\\nprovisioning security sessions list # Refresh token\\nprovisioning auth refresh","breadcrumbs":"Authentication » Login and Session Management","id":"1134","title":"Login and Session Management"},"1135":{"body":"# Show current token\\nprovisioning auth token show # Validate token\\nprovisioning auth token validate # Decode token (without verification)\\nprovisioning auth token decode # Revoke token\\nprovisioning auth token revoke","breadcrumbs":"Authentication » Token Management","id":"1135","title":"Token Management"},"1136":{"body":"","breadcrumbs":"Authentication » API Reference","id":"1136","title":"API Reference"},"1137":{"body":"Endpoint Method Purpose /auth/login POST Authenticate with credentials /auth/refresh POST Refresh access token /auth/logout POST Revoke session and tokens /auth/verify POST Verify MFA code /auth/sessions GET List active sessions /auth/sessions/:id DELETE Revoke specific session /auth/password-reset POST Initiate password reset /auth/password-change POST Change password","breadcrumbs":"Authentication » Endpoints","id":"1137","title":"Endpoints"},"1138":{"body":"","breadcrumbs":"Authentication » Troubleshooting","id":"1138","title":"Troubleshooting"},"1139":{"body":"Token expired errors : # Refresh token\\nprovisioning auth refresh # Or re-login\\nprovisioning auth login Invalid signature : # Check JWT configuration\\nprovisioning config get security.auth.jwt_algorithm # Verify public key is correct\\nprovisioning security keys verify MFA verification failures : # Check time sync (TOTP requires accurate time)\\nntpdate -q pool.ntp.org # Re-sync MFA device\\nprovisioning auth mfa-setup --resync Session not found : # Clear local session and re-login\\nprovisioning auth logout\\nprovisioning auth login","breadcrumbs":"Authentication » Common Issues","id":"1139","title":"Common Issues"},"114":{"body":"# Deploy test application on K8s cluster\\ncat < -- curl [http://test-nginx](http://test-nginx)","breadcrumbs":"First Deployment » Network Policy Test","id":"115","title":"Network Policy Test"},"1150":{"body":"","breadcrumbs":"SecretumVault Guide » Architecture","id":"1150","title":"Architecture"},"1151":{"body":"Provisioning ├─ CLI (Nushell) │ └─ nu_plugin_secretumvault │ ├─ vault-service (Rust) │ ├─ secretumvault backend │ ├─ rustyvault compatibility │ └─ SOPS + Age integration │ └─ Control Center └─ Secret management UI","breadcrumbs":"SecretumVault Guide » Integration Points","id":"1151","title":"Integration Points"},"1152":{"body":"User Secret ↓\\nKDF (Key Derivation Function) ├─ Argon2id (password-based) └─ HKDF (key-based) ↓\\nPQC Encryption Layer ├─ CRYSTALS-Kyber (key encapsulation) ├─ Falcon (signature) ├─ SPHINCS+ (backup signature) └─ Hybrid: PQC + Classical (AES-256) ↓\\nAuthenticated Encryption ├─ ChaCha20-Poly1305 └─ AES-256-GCM ↓\\nSecure Storage ├─ Local vault ├─ SurrealDB └─ Hardware module (optional)","breadcrumbs":"SecretumVault Guide » Cryptographic Stack","id":"1152","title":"Cryptographic Stack"},"1153":{"body":"","breadcrumbs":"SecretumVault Guide » Installation","id":"1153","title":"Installation"},"1154":{"body":"# Install via provisioning\\nprovisioning install secretumvault # Or manual installation\\ncd /Users/Akasha/Development/secretumvault\\ncargo install --path . # Verify installation\\nsecretumvault --version","breadcrumbs":"SecretumVault Guide » Install SecretumVault","id":"1154","title":"Install SecretumVault"},"1155":{"body":"# Install plugin\\nprovisioning install nu-plugin-secretumvault # Reload Nushell\\nnu -c \\"plugin add nu_plugin_secretumvault\\" # Verify\\nnu -c \\"secretumvault-plugin version\\"","breadcrumbs":"SecretumVault Guide » Install Nushell Plugin","id":"1155","title":"Install Nushell Plugin"},"1156":{"body":"","breadcrumbs":"SecretumVault Guide » Configuration","id":"1156","title":"Configuration"},"1157":{"body":"# Set vault location\\nexport SECRETUMVAULT_HOME=~/.secretumvault # Set encryption algorithm\\nexport SECRETUMVAULT_CIPHER=kyber-aes # kyber-aes, falcon-aes, hybrid # Set key derivation\\nexport SECRETUMVAULT_KDF=argon2id # argon2id, pbkdf2 # Enable hardware acceleration (optional)\\nexport SECRETUMVAULT_HW_ACCEL=enabled","breadcrumbs":"SecretumVault Guide » Environment Setup","id":"1157","title":"Environment Setup"},"1158":{"body":"# ~/.secretumvault/config.yaml\\nvault: storage_backend: surrealdb # local, surrealdb, redis encryption_cipher: kyber-aes # kyber-aes, falcon-aes, hybrid key_derivation: argon2id # argon2id, pbkdf2 # Argon2id parameters (password strength) kdf: memory: 65536 # KB iterations: 3 parallelism: 4 # Encryption parameters encryption: key_length: 256 # bits nonce_length: 12 # bytes auth_tag_length: 16 # bytes # Database backend (if using SurrealDB)\\ndatabase: url: \\"surrealdb://localhost:8000\\" namespace: \\"provisioning\\" database: \\"secrets\\" # Hardware acceleration (optional)\\nhardware: use_fpga: false fpga_device: \\"/dev/fpga0\\" # Backup configuration\\nbackup: enabled: true interval: 24 # hours retention: 30 # days encrypt_backup: true backup_path: ~/.secretumvault/backups # Access logging\\naudit: enabled: true log_file: ~/.secretumvault/audit.log log_level: info rotate_logs: true retention_days: 365 # Master key management\\nmaster_key: protection: none # none, tpm, hsm, hardware-module rotation_enabled: true rotation_interval: 90 # days","breadcrumbs":"SecretumVault Guide » Configuration File","id":"1158","title":"Configuration File"},"1159":{"body":"","breadcrumbs":"SecretumVault Guide » Usage","id":"1159","title":"Usage"},"116":{"body":"","breadcrumbs":"First Deployment » Part 7: State Management","id":"116","title":"Part 7: State Management"},"1160":{"body":"# Create master key\\nsecretumvault init # Add secret\\nsecretumvault secret add \\\\ --name database-password \\\\ --value \\"supersecret\\" \\\\ --metadata \\"type=database,app=api\\" # Retrieve secret\\nsecretumvault secret get database-password # List secrets\\nsecretumvault secret list # Delete secret\\nsecretumvault secret delete database-password # Rotate key\\nsecretumvault key rotate # Backup vault\\nsecretumvault backup create --output vault-backup.enc # Restore vault\\nsecretumvault backup restore vault-backup.enc","breadcrumbs":"SecretumVault Guide » Command Line Interface","id":"1160","title":"Command Line Interface"},"1161":{"body":"# Load SecretumVault plugin\\nplugin add nu_plugin_secretumvault # Add secret from Nushell\\nlet password = \\"mypassword\\"\\nsecretumvault-plugin store \\"app-secret\\" $password # Retrieve secret\\nlet db_pass = (secretumvault-plugin retrieve \\"database-password\\") # List all secrets\\nsecretumvault-plugin list # Delete secret\\nsecretumvault-plugin delete \\"old-secret\\" # Rotate key\\nsecretumvault-plugin rotate-key","breadcrumbs":"SecretumVault Guide » Nushell Integration","id":"1161","title":"Nushell Integration"},"1162":{"body":"# Configure vault-service to use SecretumVault\\nprovisioning config set security.vault.backend secretumvault # Enable in form prefill\\nprovisioning setup profile --use-secretumvault # Manage secrets via CLI\\nprovisioning vault add \\\\ --name aws-access-key \\\\ --value \\"AKIAIOSFODNN7EXAMPLE\\" \\\\ --metadata \\"provider=aws,env=production\\" # Use secret in infrastructure\\nprovisioning ai \\"Create AWS resources using secret aws-access-key\\"","breadcrumbs":"SecretumVault Guide » Provisioning Integration","id":"1162","title":"Provisioning Integration"},"1163":{"body":"","breadcrumbs":"SecretumVault Guide » Post-Quantum Cryptography","id":"1163","title":"Post-Quantum Cryptography"},"1164":{"body":"Algorithm Type NIST Status Performance CRYSTALS-Kyber KEM Finalist Fast Falcon Signature Finalist Medium SPHINCS+ Hash-based Signature Finalist Slower AES-256 Hybrid (Classical) Standard Very fast ChaCha20 Stream Cipher Alternative Fast","breadcrumbs":"SecretumVault Guide » Algorithms Supported","id":"1164","title":"Algorithms Supported"},"1165":{"body":"SecretumVault uses hybrid encryption by default: Secret Input ↓\\nKey Material: Classical (AES-256) + PQC (Kyber) ├─ Generate AES key ├─ Generate Kyber keypair └─ Encapsulate using Kyber ↓\\nEncrypt with both algorithms ├─ AES-256-GCM encryption └─ Kyber encapsulation (public key cryptography) ↓\\nBoth keys required to decrypt ├─ If quantum computer breaks Kyber → AES still secure └─ If breakthrough in AES → Kyber still secure ↓\\nEncrypted Secret Stored Advantages : Protection against quantum computers (PQC) Protection against classical attacks (AES-256) Compatible with both current and future threats No single point of failure","breadcrumbs":"SecretumVault Guide » Hybrid Mode (Recommended)","id":"1165","title":"Hybrid Mode (Recommended)"},"1166":{"body":"# Manual key rotation\\nsecretumvault key rotate --algorithm kyber-aes # Scheduled rotation (every 90 days)\\nsecretumvault key rotate --schedule 90d # Emergency rotation\\nsecretumvault key rotate --emergency --force","breadcrumbs":"SecretumVault Guide » Key Rotation Strategy","id":"1166","title":"Key Rotation Strategy"},"1167":{"body":"","breadcrumbs":"SecretumVault Guide » Security Features","id":"1167","title":"Security Features"},"1168":{"body":"# Master key authentication\\nsecretumvault auth login # MFA for sensitive operations\\nsecretumvault auth mfa enable --method totp # Biometric unlock (supported platforms)\\nsecretumvault auth enable-biometric","breadcrumbs":"SecretumVault Guide » Authentication","id":"1168","title":"Authentication"},"1169":{"body":"# Set vault permissions\\nsecretumvault acl set database-password \\\\ --read \\"api-service,backup-service\\" \\\\ --write \\"admin\\" \\\\ --delete \\"admin\\" # View access logs\\nsecretumvault audit log --secret database-password","breadcrumbs":"SecretumVault Guide » Access Control","id":"1169","title":"Access Control"},"117":{"body":"# Show current workspace state\\nprovisioning workspace info # List all resources\\nprovisioning server list\\nprovisioning taskserv list # Export state for backup\\nprovisioning workspace export > k8s-cluster-state.json","breadcrumbs":"First Deployment » View State","id":"117","title":"View State"},"1170":{"body":"Every operation is logged: # View audit log\\nsecretumvault audit log --since 24h # Export audit log\\nsecretumvault audit export --format json > audit.json # Monitor real-time\\nsecretumvault audit monitor Sample Log Entry : { \\"timestamp\\": \\"2026-01-16T01:47:00Z\\", \\"operation\\": \\"secret_retrieve\\", \\"secret\\": \\"database-password\\", \\"user\\": \\"api-service\\", \\"status\\": \\"success\\", \\"ip_address\\": \\"127.0.0.1\\", \\"device_id\\": \\"device-123\\"\\n}","breadcrumbs":"SecretumVault Guide » Audit Logging","id":"1170","title":"Audit Logging"},"1171":{"body":"","breadcrumbs":"SecretumVault Guide » Disaster Recovery","id":"1171","title":"Disaster Recovery"},"1172":{"body":"# Create encrypted backup\\nsecretumvault backup create \\\\ --output /secure/vault-backup.enc \\\\ --compression gzip # Verify backup integrity\\nsecretumvault backup verify /secure/vault-backup.enc # Restore from backup\\nsecretumvault backup restore \\\\ --input /secure/vault-backup.enc \\\\ --verify-checksum","breadcrumbs":"SecretumVault Guide » Backup Procedures","id":"1172","title":"Backup Procedures"},"1173":{"body":"# Generate recovery key (for emergencies)\\nsecretumvault recovery-key generate \\\\ --threshold 3 \\\\ --shares 5 # Share recovery shards\\n# Share with 5 trusted people, need 3 to recover # Recover using shards\\nsecretumvault recovery-key restore \\\\ --shard1 /secure/shard1.key \\\\ --shard2 /secure/shard2.key \\\\ --shard3 /secure/shard3.key","breadcrumbs":"SecretumVault Guide » Recovery Key","id":"1173","title":"Recovery Key"},"1174":{"body":"","breadcrumbs":"SecretumVault Guide » Performance","id":"1174","title":"Performance"},"1175":{"body":"Operation Time Algorithm Store secret 50-100ms Kyber-AES Retrieve secret 30-50ms Kyber-AES Key rotation 200-500ms Kyber-AES Backup 1000 secrets 2-3 seconds Kyber-AES Restore from backup 3-5 seconds Kyber-AES","breadcrumbs":"SecretumVault Guide » Benchmark Results","id":"1175","title":"Benchmark Results"},"1176":{"body":"With FPGA acceleration: Operation Native FPGA Speedup Store secret 75ms 15ms 5x Key rotation 350ms 50ms 7x Backup 1000 2.5s 0.4s 6x","breadcrumbs":"SecretumVault Guide » Hardware Acceleration","id":"1176","title":"Hardware Acceleration"},"1177":{"body":"","breadcrumbs":"SecretumVault Guide » Troubleshooting","id":"1177","title":"Troubleshooting"},"1178":{"body":"# Check permissions\\nls -la ~/.secretumvault # Clear corrupted state\\nrm ~/.secretumvault/state.lock # Reinitialize\\nsecretumvault init --force","breadcrumbs":"SecretumVault Guide » Cannot Initialize Vault","id":"1178","title":"Cannot Initialize Vault"},"1179":{"body":"# Check algorithm\\nsecretumvault config get encryption.cipher # Switch to faster algorithm\\nexport SECRETUMVAULT_CIPHER=kyber-aes # Enable hardware acceleration\\nexport SECRETUMVAULT_HW_ACCEL=enabled","breadcrumbs":"SecretumVault Guide » Slow Performance","id":"1179","title":"Slow Performance"},"118":{"body":"# Backup workspace configuration\\ntar -czf k8s-cluster-backup.tar.gz infra/ config/ runtime/ # Store securely (encrypted)\\nsops -e k8s-cluster-backup.tar.gz > k8s-cluster-backup.tar.gz.enc","breadcrumbs":"First Deployment » Configuration Backup","id":"118","title":"Configuration Backup"},"1180":{"body":"# Use recovery key (if available)\\nsecretumvault recovery-key restore \\\\ --shard1 ... --shard2 ... --shard3 ... # If no recovery key exists, vault is unrecoverable\\n# Use recent backup instead\\nsecretumvault backup restore vault-backup.enc","breadcrumbs":"SecretumVault Guide » Master Key Lost","id":"1180","title":"Master Key Lost"},"1181":{"body":"","breadcrumbs":"SecretumVault Guide » Compliance & Standards","id":"1181","title":"Compliance & Standards"},"1182":{"body":"✅ NIST PQC Standards : CRYSTALS-Kyber, Falcon, SPHINCS+ ✅ FIPS 140-3 Ready : Cryptographic module certification path ✅ NIST SP 800-175B : Post-quantum cryptography guidance ✅ EU Cyber Resilience Act : PQC readiness","breadcrumbs":"SecretumVault Guide » Certifications","id":"1182","title":"Certifications"},"1183":{"body":"SecretumVault is subject to cryptography export controls in some jurisdictions. Ensure compliance with local regulations.","breadcrumbs":"SecretumVault Guide » Export Controls","id":"1183","title":"Export Controls"},"1184":{"body":"Security Overview - Security architecture Encryption Guide - Encryption strategies Secrets Management - Secret handling Vault Service - Microservice architecture KMS Guide - Key management system","breadcrumbs":"SecretumVault Guide » Related Documentation","id":"1184","title":"Related Documentation"},"1185":{"body":"","breadcrumbs":"Encryption » Encryption","id":"1185","title":"Encryption"},"1186":{"body":"","breadcrumbs":"Secure Communication » Secure Communication","id":"1186","title":"Secure Communication"},"1187":{"body":"","breadcrumbs":"Certificate Management » Certificate Management","id":"1187","title":"Certificate Management"},"1188":{"body":"","breadcrumbs":"Compliance » Compliance","id":"1188","title":"Compliance"},"1189":{"body":"","breadcrumbs":"Security Testing » Security Testing","id":"1189","title":"Security Testing"},"119":{"body":"This deployment demonstrated: Workspace creation and configuration Nickel schema structure for infrastructure-as-code Type-safe configuration validation Automatic dependency resolution Multi-server provisioning Task service installation with health checks Kubernetes cluster deployment Storage and networking configuration Verification and testing workflows State management and backup","breadcrumbs":"First Deployment » What You\'ve Learned","id":"119","title":"What You\'ve Learned"},"1190":{"body":"Comprehensive guides for developers building extensions, custom providers, plugins, and integrations on the Provisioning platform.","breadcrumbs":"Development Overview » Development","id":"1190","title":"Development"},"1191":{"body":"Provisioning is designed to be extended and customized for specific infrastructure needs. This section provides everything needed to: Build custom cloud providers interfacing with any infrastructure platform via the Provider SDK Create custom detectors for domain-specific infrastructure analysis and anomaly detection Develop task services for specialized infrastructure operations beyond built-in services Write Nushell plugins for high-performance scripting extensions Integrate external systems via REST APIs and the MCP (Model Context Protocol) Understand platform internals for daemon architecture, caching, and performance optimization The platform uses modern Rust with async/await, Nushell for scripting, and Nickel for configuration - all with production-ready code examples.","breadcrumbs":"Development Overview » Overview","id":"1191","title":"Overview"},"1192":{"body":"","breadcrumbs":"Development Overview » Development Guides","id":"1192","title":"Development Guides"},"1193":{"body":"Extension Development - Framework for extensions (providers, task services, plugins, clusters) with type-safety Custom Provider Development - Build cloud providers with async Rust, credentials, state, error recovery, testing Custom Task Services - Specialized service development for infrastructure operations Custom Detector Development - Cost, compliance, performance, security risk detection Plugin Development - Nushell plugins for high-performance scripting with FFI bindings","breadcrumbs":"Development Overview » Extension Development","id":"1193","title":"Extension Development"},"1194":{"body":"Provisioning Daemon Internals - TCP server, connection pooling, caching, metrics, shutdown, 50x speedup","breadcrumbs":"Development Overview » Platform Internals","id":"1194","title":"Platform Internals"},"1195":{"body":"API Guide - REST API integration with authentication, pagination, error handling, rate limiting Build System - Cargo configuration, feature flags, dependencies, cross-platform compilation Testing - Unit, integration, property-based testing, benchmarking, CI/CD patterns","breadcrumbs":"Development Overview » Integration and APIs","id":"1195","title":"Integration and APIs"},"1196":{"body":"Contributing - Guidelines, standards, review process, licensing","breadcrumbs":"Development Overview » Community","id":"1196","title":"Community"},"1197":{"body":"","breadcrumbs":"Development Overview » Quick Start Paths","id":"1197","title":"Quick Start Paths"},"1198":{"body":"Start with Custom Provider Development - includes template, credential patterns, error handling, tests, and publishing workflow.","breadcrumbs":"Development Overview » I want to build a custom provider","id":"1198","title":"I want to build a custom provider"},"1199":{"body":"See Custom Detector Development - covers analysis frameworks, state tracking, testing, and marketplace distribution.","breadcrumbs":"Development Overview » I want to create custom detectors","id":"1199","title":"I want to create custom detectors"},"12":{"body":"Prerequisites - System requirements (Nushell 0.109.1+, Docker/Podman optional), cloud account setup, tool installation. Installation - Step-by-step installation: binary download, container, or source build with platform verification. Quick Start - 5-minute guide: install → configure → deploy infrastructure (requires 5 minutes and your AWS/UpCloud credentials). First Deployment - Deploy your first infrastructure: create workspace, configure provider, deploy resources, verify success. Verification - Validate installation: check system health, test CLI commands, verify cloud integration, confirm resource creation.","breadcrumbs":"Getting Started » Starting from Scratch","id":"12","title":"Starting from Scratch"},"120":{"body":"Verification - Comprehensive platform health checks Workspace Management - Advanced workspace patterns Batch Workflows - Multi-cloud orchestration Security System - Secure your infrastructure","breadcrumbs":"First Deployment » Next Steps","id":"120","title":"Next Steps"},"1200":{"body":"Read Plugin Development - FFI bindings, type safety, performance optimization, and integration patterns.","breadcrumbs":"Development Overview » I want to extend with Nushell","id":"1200","title":"I want to extend with Nushell"},"1201":{"body":"Study Provisioning Daemon Internals - architecture, caching strategy, connection pooling, metrics collection.","breadcrumbs":"Development Overview » I want to understand system performance","id":"1201","title":"I want to understand system performance"},"1202":{"body":"Check API Guide - REST endpoints, authentication, webhooks, and integration patterns.","breadcrumbs":"Development Overview » I want to integrate external systems","id":"1202","title":"I want to integrate external systems"},"1203":{"body":"Language : Rust (async/await with Tokio), Nushell (scripting) Configuration : Nickel (type-safe) + TOML (generated) Testing : Unit tests, integration tests, property-based tests Performance : Prometheus metrics, connection pooling, LRU caching Security : Post-quantum cryptography, type-safety, secure defaults","breadcrumbs":"Development Overview » Technology Stack","id":"1203","title":"Technology Stack"},"1204":{"body":"All development builds with: cargo build --release\\ncargo test --all\\ncargo clippy -- -D warnings","breadcrumbs":"Development Overview » Development Environment","id":"1204","title":"Development Environment"},"1205":{"body":"For architecture insights → See provisioning/docs/src/architecture/ For API details → See provisioning/docs/src/api-reference/ For examples → See provisioning/docs/src/examples/ For deployment → See provisioning/docs/src/operations/","breadcrumbs":"Development Overview » Navigation","id":"1205","title":"Navigation"},"1206":{"body":"Creating custom extensions to add providers, task services, and clusters to the Provisioning platform.","breadcrumbs":"Extension Development » Extension Development","id":"1206","title":"Extension Development"},"1207":{"body":"Extensions are modular components that extend platform capabilities: Extension Type Purpose Implementation Complexity Providers Cloud infrastructure backends Nushell scripts + Nickel schemas Moderate Task Services Infrastructure components Nushell installation scripts Simple Clusters Complete deployments Nickel schemas + orchestration Moderate Workflows Automation templates Nickel workflow definitions Simple","breadcrumbs":"Extension Development » Extension Overview","id":"1207","title":"Extension Overview"},"1208":{"body":"Standard extension directory layout: provisioning/extensions///\\n├── nickel/\\n│ ├── schema.ncl # Nickel type definitions\\n│ ├── defaults.ncl # Default configuration\\n│ └── validation.ncl # Validation rules\\n├── scripts/\\n│ ├── install.nu # Installation script\\n│ ├── uninstall.nu # Removal script\\n│ └── validate.nu # Validation script\\n├── templates/\\n│ └── config.template # Configuration templates\\n├── tests/\\n│ └── test_*.nu # Test scripts\\n├── docs/\\n│ └── README.md # Documentation\\n└── metadata.toml # Extension metadata","breadcrumbs":"Extension Development » Extension Structure","id":"1208","title":"Extension Structure"},"1209":{"body":"Every extension requires metadata.toml: # metadata.toml\\n[extension]\\nname = \\"my-provider\\"\\ntype = \\"provider\\"\\nversion = \\"1.0.0\\"\\ndescription = \\"Custom cloud provider\\"\\nauthor = \\"Your Name <[email@example.com](mailto:email@example.com)>\\"\\nlicense = \\"MIT\\" [dependencies]\\nnushell = \\">=0.109.0\\"\\nnickel = \\">=1.15.1\\" [dependencies.extensions]\\n# Other extensions this depends on\\nbase-provider = \\"1.0.0\\" [capabilities]\\ncreate_server = true\\ndelete_server = true\\ncreate_network = true [configuration]\\nrequired_fields = [\\"api_key\\", \\"region\\"]\\noptional_fields = [\\"timeout\\", \\"retry_attempts\\"]","breadcrumbs":"Extension Development » Extension Metadata","id":"1209","title":"Extension Metadata"},"121":{"body":"Validate the Provisioning platform installation and infrastructure health.","breadcrumbs":"Verification » Verification","id":"121","title":"Verification"},"1210":{"body":"Providers implement cloud infrastructure backends.","breadcrumbs":"Extension Development » Creating a Provider Extension","id":"1210","title":"Creating a Provider Extension"},"1211":{"body":"provisioning/extensions/providers/my-provider/\\n├── nickel/\\n│ ├── schema.ncl\\n│ ├── server.ncl\\n│ └── network.ncl\\n├── scripts/\\n│ ├── create_server.nu\\n│ ├── delete_server.nu\\n│ ├── list_servers.nu\\n│ └── validate.nu\\n├── templates/\\n│ └── server.template\\n├── tests/\\n│ └── test_provider.nu\\n└── metadata.toml","breadcrumbs":"Extension Development » Provider Structure","id":"1211","title":"Provider Structure"},"1212":{"body":"# nickel/schema.ncl\\n{ Provider = { name | String, api_key | String, region | String, timeout | default = 30 | Number, server_config = { default_plan | default = \\"medium\\" | String, allowed_plans | Array String, }, }, Server = { name | String, plan | String, zone | String, hostname | String, tags | default = [] | Array String, },\\n}","breadcrumbs":"Extension Development » Provider Schema (Nickel)","id":"1212","title":"Provider Schema (Nickel)"},"1213":{"body":"# scripts/create_server.nu\\n#!/usr/bin/env nu # Create server using provider API\\nexport def main [ config: record # Provider configuration server: record # Server specification\\n] { # Validate configuration validate-config $config # Construct API request let request = { name: $server.name plan: $server.plan zone: $server.zone } # Call provider API let response = http post $\\"($config.api_endpoint)/servers\\" { headers: { Authorization: $\\"Bearer ($config.api_key)\\" } body: ($request | to json) } # Return server details $response | from json\\n} # Validate provider configuration\\ndef validate-config [config: record] { if ($config.api_key | is-empty) { error make {msg: \\"api_key is required\\"} } if ($config.region | is-empty) { error make {msg: \\"region is required\\"} }\\n}","breadcrumbs":"Extension Development » Provider Implementation (Nushell)","id":"1213","title":"Provider Implementation (Nushell)"},"1214":{"body":"All providers must implement: # Required operations\\ncreate_server # Create new server\\ndelete_server # Delete existing server\\nget_server # Get server details\\nlist_servers # List all servers\\nserver_status # Check server status # Optional operations\\ncreate_network # Create network\\ndelete_network # Delete network\\nattach_storage # Attach storage volume\\ncreate_snapshot # Create server snapshot","breadcrumbs":"Extension Development » Provider Interface Contract","id":"1214","title":"Provider Interface Contract"},"1215":{"body":"Task services are installable infrastructure components.","breadcrumbs":"Extension Development » Creating a Task Service Extension","id":"1215","title":"Creating a Task Service Extension"},"1216":{"body":"provisioning/extensions/taskservs/my-service/\\n├── nickel/\\n│ ├── schema.ncl\\n│ └── defaults.ncl\\n├── scripts/\\n│ ├── install.nu\\n│ ├── uninstall.nu\\n│ ├── health.nu\\n│ └── validate.nu\\n├── templates/\\n│ ├── config.yaml.template\\n│ └── systemd.service.template\\n├── tests/\\n│ └── test_service.nu\\n├── docs/\\n│ └── README.md\\n└── metadata.toml","breadcrumbs":"Extension Development » Task Service Structure","id":"1216","title":"Task Service Structure"},"1217":{"body":"# metadata.toml\\n[extension]\\nname = \\"my-service\\"\\ntype = \\"taskserv\\"\\nversion = \\"2.1.0\\"\\ndescription = \\"Custom infrastructure service\\" [dependencies.taskservs]\\n# Task services this depends on\\ncontainerd = \\">=1.7.0\\"\\nkubernetes = \\">=1.28.0\\" [installation]\\nrequires_root = true\\nplatforms = [\\"linux\\"]\\narchitectures = [\\"x86_64\\", \\"aarch64\\"] [health_check]\\nenabled = true\\nendpoint = \\" [http://localhost:8000/health\\"](http://localhost:8000/health\\")\\ninterval = 30\\ntimeout = 5","breadcrumbs":"Extension Development » Task Service Metadata","id":"1217","title":"Task Service Metadata"},"1218":{"body":"# scripts/install.nu\\n#!/usr/bin/env nu export def main [ config: record # Service configuration server: record # Target server details\\n] { print \\"Installing my-service...\\" # Download binaries let version = $config.version? | default \\"latest\\" download-binary $version # Install systemd service install-systemd-service $config # Configure service generate-config $config # Start service start-service # Verify installation verify-installation print \\"Installation complete\\"\\n} def download-binary [version: string] { let url = $\\" [https://github.com/org/my-service/releases/download/($versio](https://github.com/org/my-service/releases/download/($versio)n)/my-service\\" http get $url | save /usr/local/bin/my-service chmod +x /usr/local/bin/my-service\\n} def install-systemd-service [config: record] { let template = open ../templates/systemd.service.template let rendered = $template | str replace --all \\"{{VERSION}}\\" $config.version $rendered | save /etc/systemd/system/my-service.service systemctl daemon-reload\\n} def start-service [] { systemctl enable my-service systemctl start my-service\\n} def verify-installation [] { let status = systemctl is-active my-service if $status != \\"active\\" { error make {msg: \\"Service failed to start\\"} } # Health check sleep 5sec let health = http get [http://localhost:8000/health](http://localhost:8000/health) if $health.status != \\"healthy\\" { error make {msg: \\"Health check failed\\"} }\\n}","breadcrumbs":"Extension Development » Task Service Installation Script","id":"1218","title":"Task Service Installation Script"},"1219":{"body":"Clusters combine servers and task services into complete deployments.","breadcrumbs":"Extension Development » Creating a Cluster Extension","id":"1219","title":"Creating a Cluster Extension"},"122":{"body":"","breadcrumbs":"Verification » Installation Verification","id":"122","title":"Installation Verification"},"1220":{"body":"# nickel/schema.ncl\\n{ Cluster = { metadata = { name | String, provider | String, environment | default = \\"production\\" | String, }, infrastructure = { servers | Array { name | String, role | | [ \\"control\\", \\"worker\\", \\"storage\\" | ], plan | String, }, }, services = { taskservs | Array String, order | default = [] | Array String, }, networking = { private_network | default = true | Bool, cidr | default = \\"10.0.0.0/16\\" | String, }, },\\n}","breadcrumbs":"Extension Development » Cluster Schema","id":"1220","title":"Cluster Schema"},"1221":{"body":"# clusters/kubernetes-ha.ncl\\n{ metadata.name = \\"k8s-ha-cluster\\", metadata.provider = \\"upcloud\\", infrastructure.servers = [ {name = \\"control-01\\", role = \\"control\\", plan = \\"large\\"}, {name = \\"control-02\\", role = \\"control\\", plan = \\"large\\"}, {name = \\"control-03\\", role = \\"control\\", plan = \\"large\\"}, {name = \\"worker-01\\", role = \\"worker\\", plan = \\"xlarge\\"}, {name = \\"worker-02\\", role = \\"worker\\", plan = \\"xlarge\\"}, ], services.taskservs = [\\"containerd\\", \\"etcd\\", \\"kubernetes\\", \\"cilium\\"], services.order = [\\"containerd\\", \\"etcd\\", \\"kubernetes\\", \\"cilium\\"], networking.private_network = true, networking.cidr = \\"10.100.0.0/16\\",\\n}","breadcrumbs":"Extension Development » Cluster Definition Example","id":"1221","title":"Cluster Definition Example"},"1222":{"body":"","breadcrumbs":"Extension Development » Extension Testing","id":"1222","title":"Extension Testing"},"1223":{"body":"# tests/test_provider.nu\\nuse std assert # Test provider configuration validation\\nexport def test_validate_config [] { let valid_config = { api_key: \\"test-key\\" region: \\"us-east-1\\" } let result = validate-config $valid_config assert equal $result.valid true\\n} # Test server creation\\nexport def test_create_server [] { let config = load-test-config let server_spec = { name: \\"test-server\\" plan: \\"medium\\" zone: \\"us-east-1a\\" } let result = create-server $config $server_spec assert equal $result.status \\"created\\"\\n} # Run all tests\\nexport def main [] { test_validate_config test_create_server print \\"All tests passed\\"\\n} Run tests: # Test extension\\nprovisioning extension test my-provider # Test specific component\\nnu tests/test_provider.nu","breadcrumbs":"Extension Development » Test Structure","id":"1223","title":"Test Structure"},"1224":{"body":"","breadcrumbs":"Extension Development » Extension Packaging","id":"1224","title":"Extension Packaging"},"1225":{"body":"Package and publish extension: # Build extension package\\nprovisioning extension build my-provider # Validate package\\nprovisioning extension validate my-provider-1.0.0.tar.gz # Publish to registry\\nprovisioning extension publish my-provider-1.0.0.tar.gz \\\\ --registry registry.example.com Package structure: my-provider-1.0.0.tar.gz\\n├── metadata.toml\\n├── nickel/\\n├── scripts/\\n├── templates/\\n├── tests/\\n├── docs/\\n└── manifest.json","breadcrumbs":"Extension Development » OCI Registry Publishing","id":"1225","title":"OCI Registry Publishing"},"1226":{"body":"Install extension from registry: # Install from OCI registry\\nprovisioning extension install my-provider --version 1.0.0 # Install from local file\\nprovisioning extension install ./my-provider-1.0.0.tar.gz # List installed extensions\\nprovisioning extension list # Update extension\\nprovisioning extension update my-provider --version 1.1.0 # Uninstall extension\\nprovisioning extension uninstall my-provider","breadcrumbs":"Extension Development » Extension Installation","id":"1226","title":"Extension Installation"},"1227":{"body":"Follow naming conventions: lowercase with hyphens Version extensions semantically (semver) Document all configuration options Provide comprehensive tests Include usage examples in docs Validate input parameters Handle errors gracefully Log important operations Support idempotent operations Keep dependencies minimal","breadcrumbs":"Extension Development » Best Practices","id":"1227","title":"Best Practices"},"1228":{"body":"Provider Development - Provider specifics Nickel Guide - Nickel language Build System - Building extensions Testing - Testing strategies","breadcrumbs":"Extension Development » Related Documentation","id":"1228","title":"Related Documentation"},"1229":{"body":"Implementing custom cloud provider integrations for the Provisioning platform.","breadcrumbs":"Provider Development » Provider Development","id":"1229","title":"Provider Development"},"123":{"body":"# Check CLI version\\nprovisioning version # Verify Nushell\\nnu --version # 0.109.1+ # Verify Nickel\\nnickel --version # 1.15.1+ # Check SOPS and Age\\nsops --version # 3.10.2+\\nage --version # 1.2.1+ # Verify K9s\\nk9s version # 0.50.6+","breadcrumbs":"Verification » CLI and Core Tools","id":"123","title":"CLI and Core Tools"},"1230":{"body":"Providers abstract cloud infrastructure APIs through a unified interface, allowing infrastructure definitions to be portable across clouds.","breadcrumbs":"Provider Development » Provider Architecture","id":"1230","title":"Provider Architecture"},"1231":{"body":"All providers must implement these core operations: # Server lifecycle\\ncreate_server # Provision new server\\ndelete_server # Remove server\\nget_server # Fetch server details\\nlist_servers # List all servers\\nupdate_server # Modify server configuration\\nserver_status # Get current state # Network operations (optional)\\ncreate_network # Create private network\\ndelete_network # Remove network\\nattach_network # Attach server to network # Storage operations (optional)\\nattach_volume # Attach storage volume\\ndetach_volume # Detach storage volume\\ncreate_snapshot # Snapshot server disk","breadcrumbs":"Provider Development » Provider Interface","id":"1231","title":"Provider Interface"},"1232":{"body":"Use the official provider template: # Generate provider scaffolding\\nprovisioning generate provider --name my-cloud --template standard # Creates:\\n# extensions/providers/my-cloud/\\n# ├── nickel/\\n# │ ├── schema.ncl\\n# │ ├── server.ncl\\n# │ └── network.ncl\\n# ├── scripts/\\n# │ ├── create_server.nu\\n# │ ├── delete_server.nu\\n# │ └── list_servers.nu\\n# └── metadata.toml","breadcrumbs":"Provider Development » Provider Template","id":"1232","title":"Provider Template"},"1233":{"body":"Define provider configuration schema: # nickel/schema.ncl\\n{ ProviderConfig = { name | String, api_endpoint | String, api_key | String, region | String, timeout | default = 30 | Number, retry_attempts | default = 3 | Number, plans = { small = {cpu = 2, memory = 4096, disk = 25}, medium = {cpu = 4, memory = 8192, disk = 50}, large = {cpu = 8, memory = 16384, disk = 100}, }, regions | Array String, }, ServerSpec = { name | String, plan | String, zone | String, image | default = \\"ubuntu-24.04\\" | String, ssh_keys | Array String, user_data | default = \\"\\" | String, },\\n}","breadcrumbs":"Provider Development » Provider Schema (Nickel)","id":"1233","title":"Provider Schema (Nickel)"},"1234":{"body":"Create server implementation: # scripts/create_server.nu\\n#!/usr/bin/env nu export def main [ config: record, # Provider configuration spec: record # Server specification\\n]: nothing -> record { # Validate inputs validate-provider-config $config validate-server-spec $spec # Map plan to provider-specific values let plan = get-plan-details $config $spec.plan # Construct API request let request = { hostname: $spec.name plan: $plan.name zone: $spec.zone storage_devices: [{ action: \\"create\\" storage: $plan.disk title: \\"root\\" }] login: { user: \\"root\\" keys: $spec.ssh_keys } } # Call provider API with retry logic let server = retry-api-call | { | http post $\\"($config.api_endpoint)/server\\" { headers: {Authorization: $\\"Bearer ($config.api_key)\\"} body: ($request | to json) } | from json } $config.retry_attempts # Wait for server to be ready wait-for-server-ready $config $server.uuid # Return server details { id: $server.uuid name: $server.hostname ip_address: $server.ip_addresses.0.address status: \\"running\\" provider: $config.name }\\n} def validate-provider-config [config: record] { if ($config.api_key | is-empty) { error make {msg: \\"API key required\\"} } if ($config.region | is-empty) { error make {msg: \\"Region required\\"} }\\n} def get-plan-details [config: record, plan_name: string]: nothing -> record { $config.plans | get $plan_name\\n} def retry-api-call [operation: closure, max_attempts: int]: nothing -> any { mut attempt = 1 mut last_error = null while $attempt <= $max_attempts { try { return (do $operation) } catch | { err | $last_error = $err if $attempt < $max_attempts { sleep (1sec * $attempt) # Exponential backoff $attempt = $attempt + 1 } } } error make {msg: $\\"API call failed after ($max_attempts) attempts: ($last_error)\\"}\\n} def wait-for-server-ready [config: record, server_id: string] { mut ready = false mut attempts = 0 let max_wait = 120 # 2 minutes while not $ready and $attempts < $max_wait { let status = http get $\\"($config.api_endpoint)/server/($server_id)\\" { headers: {Authorization: $\\"Bearer ($config.api_key)\\"} } | from json if $status.state == \\"started\\" { $ready = true } else { sleep 1sec $attempts = $attempts + 1 } } if not $ready { error make {msg: \\"Server failed to start within timeout\\"} }\\n}","breadcrumbs":"Provider Development » Implementing Server Creation","id":"1234","title":"Implementing Server Creation"},"1235":{"body":"Comprehensive provider testing: # tests/test_provider.nu\\nuse std assert export def test_create_server [] { # Mock provider config let config = { name: \\"test-cloud\\" api_endpoint: \\" [http://localhost:8080\\"](http://localhost:8080\\") api_key: \\"test-key\\" region: \\"test-region\\" plans: { small: {cpu: 2, memory: 4096, disk: 25} } } # Mock server spec let spec = { name: \\"test-server\\" plan: \\"small\\" zone: \\"test-zone\\" ssh_keys: [\\"ssh-rsa AAAA...\\"] } # Test server creation let server = create-server $config $spec assert ($server.id != null) assert ($server.name == \\"test-server\\") assert ($server.status == \\"running\\")\\n} export def test_list_servers [] { let config = load-test-config let servers = list-servers $config assert ($servers | length) > 0\\n} export def main [] { print \\"Running provider tests...\\" test_create_server test_list_servers print \\"All tests passed!\\"\\n}","breadcrumbs":"Provider Development » Provider Testing","id":"1235","title":"Provider Testing"},"1236":{"body":"Robust error handling for provider operations: # Handle API errors gracefully\\ndef handle-api-error [error: record]: nothing -> record { match $error.status { 401 => {error make {msg: \\"Authentication failed - check API key\\"}} 403 => {error make {msg: \\"Permission denied - insufficient privileges\\"}} 404 => {error make {msg: \\"Resource not found\\"}} 429 => {error make {msg: \\"Rate limit exceeded - retry later\\"}} 500 => {error make {msg: \\"Provider API error - contact support\\"}} _ => {error make {msg: $\\"Unknown error: ($error.message)\\"}} }\\n}","breadcrumbs":"Provider Development » Error Handling","id":"1236","title":"Error Handling"},"1237":{"body":"Implement idempotent operations where possible Handle rate limiting with exponential backoff Validate all inputs before API calls Log all API requests and responses (without secrets) Use connection pooling for better performance Cache provider capabilities and quotas Implement proper timeout handling Return consistent error messages Test against provider sandbox/staging environment Version provider schemas carefully","breadcrumbs":"Provider Development » Provider Best Practices","id":"1237","title":"Provider Best Practices"},"1238":{"body":"Extension Development - Extension basics API Guide - REST API patterns Testing - Testing strategies","breadcrumbs":"Provider Development » Related Documentation","id":"1238","title":"Related Documentation"},"1239":{"body":"Developing Nushell plugins for performance-critical operations in the Provisioning platform.","breadcrumbs":"Plugin Development » Plugin Development","id":"1239","title":"Plugin Development"},"124":{"body":"# Validate all configuration files\\nprovisioning validate config # Check environment\\nprovisioning env # Show all configuration\\nprovisioning allenv Expected output: Configuration validation: PASSED - User config: ~/.config/provisioning/user_config.yaml ✓ - System defaults: provisioning/config/config.defaults.toml ✓ - Provider credentials: configured ✓","breadcrumbs":"Verification » Configuration Validation","id":"124","title":"Configuration Validation"},"1240":{"body":"Nushell plugins provide 10-50x performance improvement over HTTP APIs through native Rust implementations.","breadcrumbs":"Plugin Development » Plugin Overview","id":"1240","title":"Plugin Overview"},"1241":{"body":"Plugin Purpose Performance Gain Language nu_plugin_auth Authentication and OS keyring 5x faster Rust nu_plugin_kms KMS encryption operations 10x faster Rust nu_plugin_orchestrator Orchestrator queries 30x faster Rust","breadcrumbs":"Plugin Development » Available Plugins","id":"1241","title":"Available Plugins"},"1242":{"body":"Plugins communicate with Nushell via MessagePack protocol: Nushell ←→ MessagePack ←→ Plugin Process ↓ ↓\\nScript Native Rust","breadcrumbs":"Plugin Development » Plugin Architecture","id":"1242","title":"Plugin Architecture"},"1243":{"body":"","breadcrumbs":"Plugin Development » Creating a Plugin","id":"1243","title":"Creating a Plugin"},"1244":{"body":"Generate plugin scaffold: # Create new plugin\\ncargo new --lib nu_plugin_myfeature\\ncd nu_plugin_myfeature Add dependencies to Cargo.toml: [package]\\nname = \\"nu_plugin_myfeature\\"\\nversion = \\"0.1.0\\"\\nedition = \\"2021\\" [dependencies]\\nnu-plugin = \\"0.109.0\\"\\nnu-protocol = \\"0.109.0\\"\\nserde = {version = \\"1.0\\", features = [\\"derive\\"]}","breadcrumbs":"Plugin Development » Plugin Template","id":"1244","title":"Plugin Template"},"1245":{"body":"Implement plugin interface: // src/lib.rs\\nuse nu_plugin::{EvaluatedCall, LabeledError, Plugin};\\nuse nu_protocol::{Category, PluginSignature, SyntaxShape, Type, Value}; pub struct MyFeaturePlugin; impl Plugin for MyFeaturePlugin { fn signature(&self) -> Vec { vec![ PluginSignature::build(\\"my-feature\\") .usage(\\"Perform my feature operation\\") .required(\\"input\\", SyntaxShape::String, \\"input value\\") .input_output_type(Type::String, Type::String) .category(Category::Custom(\\"provisioning\\".into())), ] } fn run( &mut self, name: &str, call: &EvaluatedCall, input: &Value, ) -> Result { match name { \\"my-feature\\" => self.my_feature(call, input), _ => Err(LabeledError { label: \\"Unknown command\\".into(), msg: format!(\\"Unknown command: {}\\", name), span: None, }), } }\\n} impl MyFeaturePlugin { fn my_feature(&self, call: &EvaluatedCall, _input: &Value) -> Result { let input: String = call.req(0)?; // Perform operation let result = perform_operation(&input); Ok(Value::string(result, call.head)) }\\n} fn perform_operation(input: &str) -> String { // Your implementation here format!(\\"Processed: {}\\", input)\\n} // Plugin entry point\\nfn main() { nu_plugin::serve_plugin(&mut MyFeaturePlugin, nu_plugin::MsgPackSerializer {})\\n}","breadcrumbs":"Plugin Development » Plugin Implementation","id":"1245","title":"Plugin Implementation"},"1246":{"body":"# Build release version\\ncargo build --release # Install plugin\\nnu -c \'plugin add target/release/nu_plugin_myfeature\'\\nnu -c \'plugin use myfeature\' # Test plugin\\nnu -c \'my-feature \\"test input\\"\'","breadcrumbs":"Plugin Development » Building Plugin","id":"1246","title":"Building Plugin"},"1247":{"body":"","breadcrumbs":"Plugin Development » Plugin Performance Optimization","id":"1247","title":"Plugin Performance Optimization"},"1248":{"body":"use std::time::Instant; pub fn benchmark_operation() { let start = Instant::now(); // Operation to benchmark perform_expensive_operation(); let duration = start.elapsed(); eprintln!(\\"Operation took: {:?}\\", duration);\\n}","breadcrumbs":"Plugin Development » Benchmarking","id":"1248","title":"Benchmarking"},"1249":{"body":"Implement caching for expensive operations: use std::collections::HashMap;\\nuse std::sync::{Arc, Mutex}; pub struct CachedPlugin { cache: Arc>>,\\n} impl CachedPlugin { fn get_or_compute(&self, key: &str) -> String { let mut cache = self.cache.lock().unwrap(); if let Some(value) = cache.get(key) { return value.clone(); } let value = expensive_computation(key); cache.insert(key.to_string(), value.clone()); value }\\n}","breadcrumbs":"Plugin Development » Caching","id":"1249","title":"Caching"},"125":{"body":"# List available providers\\nprovisioning providers # Test provider connection (UpCloud example)\\nprovisioning provider test upcloud # Test provider connection (AWS example)\\nprovisioning provider test aws","breadcrumbs":"Verification » Provider Connectivity","id":"125","title":"Provider Connectivity"},"1250":{"body":"","breadcrumbs":"Plugin Development » Testing Plugins","id":"1250","title":"Testing Plugins"},"1251":{"body":"#[cfg(test)]\\nmod tests { use super::*; use nu_protocol::{Span, Value}; #[test] fn test_my_feature() { let plugin = MyFeaturePlugin; let input = Value::string(\\"test\\", Span::test_data()); let result = plugin.my_feature(&mock_call(), &input).unwrap(); assert_eq!(result.as_string().unwrap(), \\"Processed: test\\"); } fn mock_call() -> EvaluatedCall { // Mock EvaluatedCall for testing todo!() }\\n}","breadcrumbs":"Plugin Development » Unit Tests","id":"1251","title":"Unit Tests"},"1252":{"body":"# tests/test_plugin.nu\\nuse std assert def test_plugin_functionality [] { let result = my-feature \\"test input\\" assert equal $result \\"Processed: test input\\"\\n} def main [] { test_plugin_functionality print \\"Plugin tests passed\\"\\n}","breadcrumbs":"Plugin Development » Integration Tests","id":"1252","title":"Integration Tests"},"1253":{"body":"Keep plugin logic focused and single-purpose Minimize dependencies to reduce binary size Use async operations for I/O-bound tasks Implement proper error handling Document all plugin commands Version plugins with semantic versioning Provide fallback to HTTP API if plugin unavailable Cache expensive computations Profile and benchmark performance improvements","breadcrumbs":"Plugin Development » Plugin Best Practices","id":"1253","title":"Plugin Best Practices"},"1254":{"body":"Build System - Building Rust plugins Extension Development - Extension basics Testing - Testing strategies","breadcrumbs":"Plugin Development » Related Documentation","id":"1254","title":"Related Documentation"},"1255":{"body":"Integrate third-party APIs with Provisioning infrastructure.","breadcrumbs":"API Guide » API Integration Guide","id":"1255","title":"API Integration Guide"},"1256":{"body":"Create clients for external APIs: // src/api_client.rs\\nuse reqwest::Client; pub struct ApiClient { endpoint: String, api_key: String, client: Client,\\n} impl ApiClient { pub async fn call(&self, path: &str) -> Result { let url = format!(\\"{}{}\\", self.endpoint, path); self.client .get(&url) .bearer_auth(&self.api_key) .send() .await }\\n}","breadcrumbs":"API Guide » API Client Development","id":"1256","title":"API Client Development"},"1257":{"body":"Handle webhooks from external systems: #[post(\\"/webhooks/{service}\\")]\\npub async fn handle_webhook(path: web::Path, body: web::Bytes) -> impl Responder { let service = path.into_inner(); match service.as_str() { \\"github\\" => handle_github_webhook(&body), \\"stripe\\" => handle_stripe_webhook(&body), _ => HttpResponse::NotFound().finish(), }\\n}","breadcrumbs":"API Guide » Webhook Integration","id":"1257","title":"Webhook Integration"},"1258":{"body":"Robust error handling for API calls with retries: pub async fn call_api_with_retry( client: &ApiClient, path: &str, max_retries: u32,\\n) -> Result { for attempt in 0..max_retries { match client.call(path).await { Ok(response) => return Ok(response), Err(e) if attempt < max_retries - 1 => { let delay = Duration::from_secs(2_u64.pow(attempt)); tokio::time::sleep(delay).await; } Err(e) => return Err(e), } } Err(ApiError::MaxRetriesExceeded.into())\\n}","breadcrumbs":"API Guide » Error Handling","id":"1258","title":"Error Handling"},"1259":{"body":"Extension Development REST API Reference","breadcrumbs":"API Guide » Related Documentation","id":"1259","title":"Related Documentation"},"126":{"body":"","breadcrumbs":"Verification » Workspace Verification","id":"126","title":"Workspace Verification"},"1260":{"body":"Building, testing, and packaging the Provisioning platform and extensions with Cargo, Just, and Nickel.","breadcrumbs":"Build System » Build System","id":"1260","title":"Build System"},"1261":{"body":"Tool Purpose Version Required Cargo Rust compilation and testing Latest stable Just Task runner for common operations Latest Nickel Schema validation and type checking 1.15.1+ Nushell Script execution and testing 0.109.0+","breadcrumbs":"Build System » Build Tools","id":"1261","title":"Build Tools"},"1262":{"body":"","breadcrumbs":"Build System » Building Platform Services","id":"1262","title":"Building Platform Services"},"1263":{"body":"# Build all Rust services in release mode\\ncd provisioning/platform\\ncargo build --release --workspace # Or using just task runner\\njust build-platform Binary outputs in target/release/: provisioning-orchestrator provisioning-control-center provisioning-vault-service provisioning-installer","breadcrumbs":"Build System » Build All Services","id":"1263","title":"Build All Services"},"1264":{"body":"# Orchestrator service\\ncd provisioning/platform/crates/orchestrator\\ncargo build --release # Control Center service\\ncd provisioning/platform/crates/control-center\\ncargo build --release # Development build (faster compilation)\\ncargo build","breadcrumbs":"Build System » Build Individual Service","id":"1264","title":"Build Individual Service"},"1265":{"body":"","breadcrumbs":"Build System » Testing","id":"1265","title":"Testing"},"1266":{"body":"# Rust unit and integration tests\\ncargo test --workspace # Nushell script tests\\njust test-nushell # Complete test suite\\njust test-all","breadcrumbs":"Build System » Run All Tests","id":"1266","title":"Run All Tests"},"1267":{"body":"# Test orchestrator crate\\ncargo test -p provisioning-orchestrator # Test with output visible\\ncargo test -p provisioning-orchestrator -- --nocapture # Test specific function\\ncargo test -p provisioning-orchestrator test_workflow_creation # Run tests matching pattern\\ncargo test workflow","breadcrumbs":"Build System » Test Specific Component","id":"1267","title":"Test Specific Component"},"1268":{"body":"# Run 350+ security test cases\\ncargo test -p security --test \'*\' # Specific security component\\ncargo test -p security authentication\\ncargo test -p security authorization\\ncargo test -p security kms","breadcrumbs":"Build System » Security Tests","id":"1268","title":"Security Tests"},"1269":{"body":"","breadcrumbs":"Build System » Code Quality","id":"1269","title":"Code Quality"},"127":{"body":"# List workspaces\\nprovisioning workspace list # Show current workspace\\nprovisioning workspace current # Verify workspace structure\\nls -la / Expected structure: workspace-name/\\n├── infra/ # Infrastructure Nickel schemas\\n├── config/ # Workspace configuration\\n├── extensions/ # Custom extensions\\n└── runtime/ # State and logs","breadcrumbs":"Verification » Workspace Structure","id":"127","title":"Workspace Structure"},"1270":{"body":"# Format all Rust code\\ncargo fmt --all # Check formatting without modifying\\ncargo fmt --all -- --check # Format Nickel schemas\\nnickel fmt provisioning/schemas/**/*.ncl","breadcrumbs":"Build System » Formatting","id":"1270","title":"Formatting"},"1271":{"body":"# Run Clippy linter\\ncargo clippy --all -- -D warnings # Auto-fix Clippy warnings\\ncargo clippy --all --fix # Clippy with all features enabled\\ncargo clippy --all --all-features -- -D warnings","breadcrumbs":"Build System » Linting","id":"1271","title":"Linting"},"1272":{"body":"# Type check Nickel schemas\\nnickel typecheck provisioning/schemas/main.ncl # Evaluate schema\\nnickel eval provisioning/schemas/main.ncl # Format Nickel files\\nnickel fmt provisioning/schemas/**/*.ncl","breadcrumbs":"Build System » Nickel Validation","id":"1272","title":"Nickel Validation"},"1273":{"body":"The platform uses automated CI workflows for quality assurance.","breadcrumbs":"Build System » Continuous Integration","id":"1273","title":"Continuous Integration"},"1274":{"body":"Key CI jobs: 1. Rust Build and Test - cargo build --release --workspace - cargo test --workspace - cargo clippy --all -- -D warnings 2. Nushell Validation - nu --check core/cli/provisioning - Run Nushell test suite 3. Nickel Schema Validation - nickel typecheck schemas/main.ncl - Validate all schema files 4. Security Tests - Run 350+ security test cases - Vulnerability scanning 5. Documentation Build - mdbook build docs - Markdown linting","breadcrumbs":"Build System » GitHub Actions Pipeline","id":"1274","title":"GitHub Actions Pipeline"},"1275":{"body":"","breadcrumbs":"Build System » Packaging and Distribution","id":"1275","title":"Packaging and Distribution"},"1276":{"body":"# Build optimized binaries\\ncargo build --release --workspace # Strip debug symbols (reduce binary size)\\nstrip target/release/provisioning-orchestrator\\nstrip target/release/provisioning-control-center # Create distribution archive\\njust package","breadcrumbs":"Build System » Create Release Package","id":"1276","title":"Create Release Package"},"1277":{"body":"provisioning-5.0.0-linux-x86_64.tar.gz\\n├── bin/\\n│ ├── provisioning # Main CLI\\n│ ├── provisioning-orchestrator # Orchestrator service\\n│ ├── provisioning-control-center # Control Center\\n│ ├── provisioning-vault-service # Vault service\\n│ └── provisioning-installer # Platform installer\\n├── lib/\\n│ └── nulib/ # Nushell libraries\\n├── schemas/ # Nickel schemas\\n├── config/\\n│ └── config.defaults.toml # Default configuration\\n├── systemd/\\n│ └── *.service # Systemd unit files\\n└── README.md","breadcrumbs":"Build System » Package Structure","id":"1277","title":"Package Structure"},"1278":{"body":"","breadcrumbs":"Build System » Cross-Platform Builds","id":"1278","title":"Cross-Platform Builds"},"1279":{"body":"# Linux x86_64 (primary platform)\\ncargo build --release --target x86_64-unknown-linux-gnu # Linux ARM64 (Raspberry Pi, cloud ARM instances)\\ncargo build --release --target aarch64-unknown-linux-gnu # macOS x86_64\\ncargo build --release --target x86_64-apple-darwin # macOS ARM64 (Apple Silicon)\\ncargo build --release --target aarch64-apple-darwin","breadcrumbs":"Build System » Supported Targets","id":"1279","title":"Supported Targets"},"128":{"body":"# Show workspace configuration\\nprovisioning config show # Validate workspace-specific config\\nprovisioning validate config --workspace ","breadcrumbs":"Verification » Workspace Configuration","id":"128","title":"Workspace Configuration"},"1280":{"body":"# Add target architectures\\nrustup target add x86_64-unknown-linux-gnu\\nrustup target add aarch64-unknown-linux-gnu # Install cross-compilation tool\\ncargo install cross # Cross-compile with Docker\\ncross build --release --target aarch64-unknown-linux-gnu","breadcrumbs":"Build System » Cross-Compilation Setup","id":"1280","title":"Cross-Compilation Setup"},"1281":{"body":"Common build tasks in justfile: # Build all components\\nbuild-all: build-platform build-plugins # Build platform services\\nbuild-platform: cd platform && cargo build --release --workspace # Run all tests\\ntest: test-rust test-nushell test-integration # Test Rust code\\ntest-rust: cargo test --workspace # Test Nushell scripts\\ntest-nushell: nu scripts/test/test_all.nu # Format all code\\nfmt: cargo fmt --all nickel fmt schemas/**/*.ncl # Lint all code\\nlint: cargo clippy --all -- -D warnings nickel typecheck schemas/main.ncl # Create release package\\npackage: ./scripts/package.nu # Clean build artifacts\\nclean: cargo clean rm -rf target/ Usage examples: just build-all # Build everything\\njust test # Run all tests\\njust fmt # Format code\\njust lint # Run linters\\njust package # Create distribution\\njust clean # Remove artifacts","breadcrumbs":"Build System » Just Task Runner","id":"1281","title":"Just Task Runner"},"1282":{"body":"","breadcrumbs":"Build System » Performance Optimization","id":"1282","title":"Performance Optimization"},"1283":{"body":"# Cargo.toml\\n[profile.release]\\nopt-level = 3 # Maximum optimization\\nlto = \\"fat\\" # Link-time optimization\\ncodegen-units = 1 # Better optimization, slower compile\\nstrip = true # Strip debug symbols\\npanic = \\"abort\\" # Smaller binary size","breadcrumbs":"Build System » Release Builds","id":"1283","title":"Release Builds"},"1284":{"body":"# Cargo.toml\\n[profile.dev]\\nopt-level = 1 # Basic optimization\\nincremental = true # Faster recompilation Speed up compilation: # Use faster linker (Linux)\\nsudo apt install lld\\nexport RUSTFLAGS=\\"-C link-arg=-fuse-ld=lld\\" # Parallel compilation\\ncargo build -j 8 # Use cargo-watch for auto-rebuild\\ncargo install cargo-watch\\ncargo watch -x build","breadcrumbs":"Build System » Build Time Optimization","id":"1284","title":"Build Time Optimization"},"1285":{"body":"","breadcrumbs":"Build System » Development Workflow","id":"1285","title":"Development Workflow"},"1286":{"body":"# 1. Start development\\njust clean\\njust build-all # 2. Make changes to code # 3. Test changes quickly\\ncargo check # Fast syntax check\\ncargo test # Test specific functionality # 4. Full validation before commit\\njust fmt\\njust lint\\njust test # 5. Create package for testing\\njust package","breadcrumbs":"Build System » Recommended Workflow","id":"1286","title":"Recommended Workflow"},"1287":{"body":"# Auto-rebuild on file changes\\ncargo watch -x build # Auto-test on changes\\ncargo watch -x test # Run service with auto-reload\\ncargo watch -x \'run --bin provisioning-orchestrator\'","breadcrumbs":"Build System » Hot Reload Development","id":"1287","title":"Hot Reload Development"},"1288":{"body":"","breadcrumbs":"Build System » Debugging Builds","id":"1288","title":"Debugging Builds"},"1289":{"body":"# Build with full debug info\\ncargo build # Build with debug info in release mode\\ncargo build --release --profile release-with-debug # Run with backtraces\\nRUST_BACKTRACE=1 cargo run\\nRUST_BACKTRACE=full cargo run","breadcrumbs":"Build System » Debug Information","id":"1289","title":"Debug Information"},"129":{"body":"","breadcrumbs":"Verification » Infrastructure Verification","id":"129","title":"Infrastructure Verification"},"1290":{"body":"# Verbose build output\\ncargo build -vv # Show build commands\\ncargo build -vvv # Show timing information\\ncargo build --timings","breadcrumbs":"Build System » Build Verbosity","id":"1290","title":"Build Verbosity"},"1291":{"body":"# View dependency tree\\ncargo tree # Duplicate dependencies\\ncargo tree --duplicates # Build graph visualization\\ncargo depgraph | dot -Tpng > deps.png","breadcrumbs":"Build System » Dependency Tree","id":"1291","title":"Dependency Tree"},"1292":{"body":"Always run just test before committing Use cargo fmt and cargo clippy for code quality Test on multiple platforms before release Strip binaries for production distributions Version binaries with semantic versioning Cache dependencies in CI/CD Use release profile for production builds Document build requirements in README Automate common tasks with Just Keep build times reasonable (<5 min)","breadcrumbs":"Build System » Best Practices","id":"1292","title":"Best Practices"},"1293":{"body":"","breadcrumbs":"Build System » Troubleshooting","id":"1293","title":"Troubleshooting"},"1294":{"body":"Compilation fails with linker error: # Install build dependencies\\nsudo apt install build-essential pkg-config libssl-dev Out of memory during build: # Reduce parallel jobs\\ncargo build -j 2 # Use more swap space\\nsudo fallocate -l 8G /swapfile\\nsudo mkswap /swapfile\\nsudo swapon /swapfile Clippy warnings: # Fix automatically where possible\\ncargo clippy --all --fix # Allow specific lints temporarily\\n#[allow(clippy::too_many_arguments)]","breadcrumbs":"Build System » Common Build Issues","id":"1294","title":"Common Build Issues"},"1295":{"body":"Testing - Testing strategies and procedures Contributing - Contribution guidelines including build requirements","breadcrumbs":"Build System » Related Documentation","id":"1295","title":"Related Documentation"},"1296":{"body":"Comprehensive testing strategies for the Provisioning platform including unit tests, integration tests, and 350+ security tests.","breadcrumbs":"Testing » Testing","id":"1296","title":"Testing"},"1297":{"body":"The platform maintains extensive test coverage across multiple test types: Test Type Count Coverage Target Average Runtime Unit Tests 200+ Core logic 80%+ < 5 seconds Integration Tests 100+ Component integration 60%+ < 30 seconds Security Tests 350+ Security components 100% < 60 seconds End-to-End Tests 50+ Full workflows < 5 minutes","breadcrumbs":"Testing » Testing Overview","id":"1297","title":"Testing Overview"},"1298":{"body":"","breadcrumbs":"Testing » Running Tests","id":"1298","title":"Running Tests"},"1299":{"body":"# Run complete test suite\\ncargo test --workspace # With output visible\\ncargo test --workspace -- --nocapture # Parallel execution with 8 threads\\ncargo test --workspace --jobs 8 # Include ignored tests\\ncargo test --workspace -- --ignored","breadcrumbs":"Testing » All Tests","id":"1299","title":"All Tests"},"13":{"body":"By completing this section, you\'ll know how to: ✅ Install and configure Provisioning ✅ Create your first workspace ✅ Configure cloud providers (AWS, UpCloud, Hetzner, etc.) ✅ Write simple Nickel infrastructure definitions ✅ Deploy infrastructure using Provisioning ✅ Verify and manage deployed resources","breadcrumbs":"Getting Started » What You\'ll Learn","id":"13","title":"What You\'ll Learn"},"130":{"body":"# List all servers\\nprovisioning server list # Check server status\\nprovisioning server status # Test SSH connectivity\\nprovisioning server ssh -- echo \\"Connection successful\\"","breadcrumbs":"Verification » Server Health","id":"130","title":"Server Health"},"1300":{"body":"# Unit tests only (--lib)\\ncargo test --lib # Integration tests only (--test)\\ncargo test --test \'*\' # Documentation tests\\ncargo test --doc # Security test suite\\ncargo test -p security --test \'*\'","breadcrumbs":"Testing » Test by Category","id":"1300","title":"Test by Category"},"1301":{"body":"# Test orchestrator crate\\ncargo test -p provisioning-orchestrator # Test control center\\ncargo test -p provisioning-control-center # Test specific module\\ncargo test -p provisioning-orchestrator workflows:: # Test specific function\\ncargo test -p provisioning-orchestrator test_workflow_creation","breadcrumbs":"Testing » Test Specific Component","id":"1301","title":"Test Specific Component"},"1302":{"body":"Unit tests verify individual functions and modules in isolation.","breadcrumbs":"Testing » Unit Testing","id":"1302","title":"Unit Testing"},"1303":{"body":"// src/workflows.rs\\n#[cfg(test)]\\nmod tests { use super::*; #[test] fn test_create_workflow() { let config = WorkflowConfig { name: \\"test-workflow\\".into(), tasks: vec![], }; let workflow = Workflow::new(config); assert_eq!(workflow.name(), \\"test-workflow\\"); assert_eq!(workflow.status(), WorkflowStatus::Pending); } #[test] fn test_workflow_execution() { let mut workflow = create_test_workflow(); let result = workflow.execute(); assert!(result.is_ok()); assert_eq!(workflow.status(), WorkflowStatus::Completed); } #[test] #[should_panic(expected = \\"Invalid workflow\\")] fn test_invalid_workflow() { Workflow::new(invalid_config()); }\\n}","breadcrumbs":"Testing » Rust Unit Tests","id":"1303","title":"Rust Unit Tests"},"1304":{"body":"# tests/test_provider.nu\\nuse std assert export def test_validate_config [] { let config = {api_key: \\"test-key\\", region: \\"us-east-1\\"} let result = validate-config $config assert equal $result.valid true\\n} export def test_create_server [] { let spec = {name: \\"test-server\\", plan: \\"medium\\"} let server = create-server test-config $spec assert ($server.id != null)\\n} export def main [] { test_validate_config test_create_server print \\"All tests passed\\"\\n} Run Nushell tests: nu tests/test_provider.nu","breadcrumbs":"Testing » Nushell Unit Tests","id":"1304","title":"Nushell Unit Tests"},"1305":{"body":"Integration tests verify components work together correctly.","breadcrumbs":"Testing » Integration Testing","id":"1305","title":"Integration Testing"},"1306":{"body":"// tests/orchestrator_integration.rs\\nuse provisioning_orchestrator::Orchestrator;\\nuse provisioning_database::Database; #[tokio::test]\\nasync fn test_workflow_persistence() { let db = Database::new_test().await; let orchestrator = Orchestrator::new(db.clone()); let workflow_id = orchestrator.create_workflow(test_config()).await.unwrap(); // Verify workflow persisted to database let workflow = db.get_workflow(&workflow_id).await.unwrap(); assert_eq!(workflow.id, workflow_id);\\n} #[tokio::test]\\nasync fn test_api_integration() { let app = create_test_app().await; let response = app .post(\\"/api/v1/workflows\\") .json(&test_workflow()) .send() .await .unwrap(); assert_eq!(response.status(), 201);\\n}","breadcrumbs":"Testing » Service Integration Tests","id":"1306","title":"Service Integration Tests"},"1307":{"body":"Use Docker containers for realistic integration testing: use testcontainers::*; #[tokio::test]\\nasync fn test_with_database() { let docker = clients::Cli::default(); let postgres = docker.run(images::postgres::Postgres::default()); let db_url = format!( \\"postgres://postgres@localhost:{}/test\\", postgres.get_host_port_ipv4(5432) ); // Run tests against real database let db = Database::connect(&db_url).await.unwrap(); // Test database operations...\\n}","breadcrumbs":"Testing » Test Containers","id":"1307","title":"Test Containers"},"1308":{"body":"Comprehensive security testing with 350+ test cases covering all security components.","breadcrumbs":"Testing » Security Testing","id":"1308","title":"Security Testing"},"1309":{"body":"#[tokio::test]\\nasync fn test_jwt_verification() { let auth = AuthService::new(); let token = auth.generate_token(\\"user123\\").unwrap(); let claims = auth.verify_token(&token).unwrap(); assert_eq!(claims.sub, \\"user123\\");\\n} #[tokio::test]\\nasync fn test_invalid_token() { let auth = AuthService::new(); let result = auth.verify_token(\\"invalid.token.here\\"); assert!(result.is_err());\\n} #[tokio::test]\\nasync fn test_token_expiration() { let auth = AuthService::new(); let token = create_expired_token(); let result = auth.verify_token(&token); assert!(matches!(result, Err(AuthError::TokenExpired)));\\n}","breadcrumbs":"Testing » Authentication Tests","id":"1309","title":"Authentication Tests"},"131":{"body":"# List installed task services\\nprovisioning taskserv list # Check service status\\nprovisioning taskserv status # Verify service health\\nprovisioning taskserv health ","breadcrumbs":"Verification » Task Service Health","id":"131","title":"Task Service Health"},"1310":{"body":"#[tokio::test]\\nasync fn test_rbac_enforcement() { let authz = AuthorizationService::new(); let decision = authz.authorize( \\"user:user123\\", \\"workflow:create\\", \\"resource:my-cluster\\" ).await; assert_eq!(decision, Decision::Allow);\\n} #[tokio::test]\\nasync fn test_policy_denial() { let authz = AuthorizationService::new(); let decision = authz.authorize( \\"user:guest\\", \\"server:delete\\", \\"resource:prod-server\\" ).await; assert_eq!(decision, Decision::Deny);\\n}","breadcrumbs":"Testing » Authorization Tests","id":"1310","title":"Authorization Tests"},"1311":{"body":"#[tokio::test]\\nasync fn test_kms_encryption() { let kms = KmsService::new(); let plaintext = b\\"secret data\\"; let ciphertext = kms.encrypt(plaintext).await.unwrap(); let decrypted = kms.decrypt(&ciphertext).await.unwrap(); assert_eq!(plaintext, decrypted.as_slice());\\n} #[tokio::test]\\nasync fn test_encryption_performance() { let kms = KmsService::new(); let plaintext = vec![0u8; 1024]; // 1KB let start = Instant::now(); kms.encrypt(&plaintext).await.unwrap(); let duration = start.elapsed(); // KMS encryption should complete in < 10ms assert!(duration < Duration::from_millis(10));\\n}","breadcrumbs":"Testing » Encryption Tests","id":"1311","title":"Encryption Tests"},"1312":{"body":"Complete workflow testing from start to finish.","breadcrumbs":"Testing » End-to-End Testing","id":"1312","title":"End-to-End Testing"},"1313":{"body":"#[tokio::test]\\nasync fn test_complete_workflow() { let platform = Platform::start_test_instance().await; // Create infrastructure let cluster_id = platform .create_cluster(test_cluster_config()) .await .unwrap(); // Wait for completion (5 minute timeout) platform .wait_for_cluster(&cluster_id, Duration::from_secs(300)) .await; // Verify cluster health let health = platform.check_cluster_health(&cluster_id).await; assert!(health.is_healthy()); // Cleanup platform.delete_cluster(&cluster_id).await.unwrap();\\n}","breadcrumbs":"Testing » Full Workflow Tests","id":"1313","title":"Full Workflow Tests"},"1314":{"body":"Shared test data and utilities.","breadcrumbs":"Testing » Test Fixtures","id":"1314","title":"Test Fixtures"},"1315":{"body":"// tests/fixtures/mod.rs\\npub fn test_workflow_config() -> WorkflowConfig { WorkflowConfig { name: \\"test-workflow\\".into(), tasks: vec![ Task::new(\\"task1\\", TaskType::CreateServer), Task::new(\\"task2\\", TaskType::InstallService), ], }\\n} pub fn test_server_spec() -> ServerSpec { ServerSpec { name: \\"test-server\\".into(), plan: \\"medium\\".into(), zone: \\"us-east-1a\\".into(), image: \\"ubuntu-24.04\\".into(), }\\n}","breadcrumbs":"Testing » Common Test Fixtures","id":"1315","title":"Common Test Fixtures"},"1316":{"body":"Mock external dependencies for isolated testing.","breadcrumbs":"Testing » Mocking","id":"1316","title":"Mocking"},"1317":{"body":"use mockall::*; #[automock]\\ntrait CloudProvider { async fn create_server(&self, spec: &ServerSpec) -> Result;\\n} #[tokio::test]\\nasync fn test_with_mock_provider() { let mut mock_provider = MockCloudProvider::new(); mock_provider .expect_create_server() .returning| ( | _ Ok(test_server())); let result = mock_provider.create_server(&test_spec()).await; assert!(result.is_ok());\\n}","breadcrumbs":"Testing » Mock External Services","id":"1317","title":"Mock External Services"},"1318":{"body":"Measure and maintain code coverage.","breadcrumbs":"Testing » Test Coverage","id":"1318","title":"Test Coverage"},"1319":{"body":"# Install tarpaulin\\ncargo install cargo-tarpaulin # Generate HTML coverage report\\ncargo tarpaulin --out Html --output-dir coverage # Generate multiple formats\\ncargo tarpaulin --out Html --out Xml --out Json # View coverage\\nopen coverage/index.html","breadcrumbs":"Testing » Generate Coverage Report","id":"1319","title":"Generate Coverage Report"},"132":{"body":"For Kubernetes clusters: # SSH to control plane\\nprovisioning server ssh # Check cluster nodes\\nkubectl get nodes # Check system pods\\nkubectl get pods -n kube-system # Check cluster info\\nkubectl cluster-info","breadcrumbs":"Verification » Cluster Health","id":"132","title":"Cluster Health"},"1320":{"body":"Unit tests : Minimum 80% code coverage Integration tests : Minimum 60% component coverage Critical paths : 100% coverage required Security components : 100% coverage required","breadcrumbs":"Testing » Coverage Goals","id":"1320","title":"Coverage Goals"},"1321":{"body":"Benchmark critical operations.","breadcrumbs":"Testing » Performance Testing","id":"1321","title":"Performance Testing"},"1322":{"body":"use criterion::{black_box, criterion_group, criterion_main, Criterion}; fn benchmark_workflow_creation(c: &mut Criterion) { c.bench_function(\\"create_workflow\\", | | b { b.iter| ( | { Workflow::new(black_box(test_config())) }) });\\n} fn benchmark_database_query(c: &mut Criterion) { c.bench_function(\\"query_workflows\\", | | b { b.iter| ( | { db.query_workflows(black_box(&filter)) }) });\\n} criterion_group!(benches, benchmark_workflow_creation, benchmark_database_query);\\ncriterion_main!(benches); Run benchmarks: cargo bench","breadcrumbs":"Testing » Benchmark Tests","id":"1322","title":"Benchmark Tests"},"1323":{"body":"Write tests before or alongside code (TDD approach) Keep tests focused and isolated Use descriptive test names that explain what is tested Clean up test resources (databases, files, containers) Mock external dependencies to avoid flaky tests Test both success and error conditions Maintain shared test fixtures for consistency Run tests in CI/CD pipeline Monitor test execution time (fail if too slow) Refactor tests alongside production code","breadcrumbs":"Testing » Test Best Practices","id":"1323","title":"Test Best Practices"},"1324":{"body":"","breadcrumbs":"Testing » Continuous Testing","id":"1324","title":"Continuous Testing"},"1325":{"body":"Auto-run tests on code changes: # Install cargo-watch\\ncargo install cargo-watch # Watch and run tests\\ncargo watch -x test # Watch specific package\\ncargo watch -x \'test -p provisioning-orchestrator\'","breadcrumbs":"Testing » Watch Mode","id":"1325","title":"Watch Mode"},"1326":{"body":"Run tests automatically before commits: # Install pre-commit hooks\\npre-commit install # Runs on every commit:\\n# - cargo test\\n# - cargo clippy\\n# - cargo fmt --check","breadcrumbs":"Testing » Pre-Commit Testing","id":"1326","title":"Pre-Commit Testing"},"1327":{"body":"Build System - Building and running tests Contributing - Test requirements for contributions API Guide - API testing examples","breadcrumbs":"Testing » Related Documentation","id":"1327","title":"Related Documentation"},"1328":{"body":"Guidelines for contributing to the Provisioning platform including setup, workflow, and best practices.","breadcrumbs":"Contributing » Contributing","id":"1328","title":"Contributing"},"1329":{"body":"","breadcrumbs":"Contributing » Getting Started","id":"1329","title":"Getting Started"},"133":{"body":"","breadcrumbs":"Verification » Platform Services Verification","id":"133","title":"Platform Services Verification"},"1330":{"body":"Install required development tools: # Rust toolchain (latest stable)\\ncurl --proto \'=https\' --tlsv1.2 -sSf [https://sh.rustup.rs](https://sh.rustup.rs) | sh # Nushell shell\\nbrew install nushell # Nickel configuration language\\nbrew install nickel # Just task runner\\nbrew install just # Additional development tools\\ncargo install cargo-watch cargo-tarpaulin cargo-audit","breadcrumbs":"Contributing » Prerequisites","id":"1330","title":"Prerequisites"},"1331":{"body":"Follow these guidelines for all code changes and ensure adherence to the project\'s technical standards. Read applicable language guidelines Create feature branch from main Make changes following project standards Write or update tests Run full test suite and linting Create pull request with clear description","breadcrumbs":"Contributing » Development Workflow","id":"1331","title":"Development Workflow"},"1332":{"body":"","breadcrumbs":"Contributing » Code Style Guidelines","id":"1332","title":"Code Style Guidelines"},"1333":{"body":"Rust code guidelines: Use idiomatic Rust patterns No unwrap() in production code Comprehensive error handling with custom error types Format with cargo fmt Pass cargo clippy -- -D warnings with zero warnings Add inline documentation for public APIs","breadcrumbs":"Contributing » Rust Code","id":"1333","title":"Rust Code"},"1334":{"body":"Nushell code guidelines: Use structured data pipelines Avoid external command dependencies where possible Handle errors gracefully with try-catch Document functions with comments Use type annotations for clarity","breadcrumbs":"Contributing » Nushell Scripts","id":"1334","title":"Nushell Scripts"},"1335":{"body":"Nickel configuration guidelines: Define clear type constraints Use lazy evaluation appropriately Provide default values where sensible Document schema fields Validate schemas with nickel typecheck","breadcrumbs":"Contributing » Nickel Schemas","id":"1335","title":"Nickel Schemas"},"1336":{"body":"All contributions must include appropriate tests:","breadcrumbs":"Contributing » Testing Requirements","id":"1336","title":"Testing Requirements"},"1337":{"body":"Unit tests for all new functions Integration tests for component interactions Security tests for security-related changes Documentation tests for code examples","breadcrumbs":"Contributing » Required Tests","id":"1337","title":"Required Tests"},"1338":{"body":"# Run all tests\\njust test # Run specific test suite\\ncargo test -p provisioning-orchestrator # Run with coverage\\ncargo tarpaulin --out Html","breadcrumbs":"Contributing » Running Tests","id":"1338","title":"Running Tests"},"1339":{"body":"Unit tests: Minimum 80% code coverage Critical paths: 100% coverage Security components: 100% coverage","breadcrumbs":"Contributing » Test Coverage Requirements","id":"1339","title":"Test Coverage Requirements"},"134":{"body":"# Check orchestrator status\\ncurl [http://localhost:5000/health](http://localhost:5000/health) # View orchestrator version\\ncurl [http://localhost:5000/version](http://localhost:5000/version) # List active workflows\\nprovisioning workflow list Expected response: { \\"status\\": \\"healthy\\", \\"version\\": \\"x.x.x\\", \\"uptime\\": \\"2h 15m\\"\\n}","breadcrumbs":"Verification » Orchestrator Service","id":"134","title":"Orchestrator Service"},"1340":{"body":"","breadcrumbs":"Contributing » Documentation","id":"1340","title":"Documentation"},"1341":{"body":"All code changes must include: Inline code documentation for public APIs Updated README if adding new components Examples showing usage Migration guide for breaking changes","breadcrumbs":"Contributing » Required Documentation","id":"1341","title":"Required Documentation"},"1342":{"body":"Documentation standards: Use Markdown for all documentation Code blocks must specify language Keep lines ≤150 characters No bare URLs (use markdown links) Test all code examples","breadcrumbs":"Contributing » Documentation Standards","id":"1342","title":"Documentation Standards"},"1343":{"body":"Use conventional commit format: ():