isoloom_spec/syntax.rs
1//! The spec as an author writes it, version 1: one declaration per machine. A machine is `os`
2//! plus a catalogue `service:` or a custom `app:` (or the OS alone); per-target facts live in a
3//! top-level `overrides:`. Parsed once into types that can't hold an invalid state, with every
4//! problem coded and placed ([`Problem`]). The plan lowers it into [`crate::model`], the form
5//! the backends read, once per target.
6
7mod app;
8mod check;
9mod files;
10mod forms;
11mod hardware;
12mod inputs;
13mod machine;
14mod mistake;
15mod names;
16mod old_keys;
17mod os;
18mod overrides;
19mod parse;
20pub mod placeholder;
21mod ports;
22mod problem;
23mod process;
24mod shared;
25mod spans;
26mod step;
27mod warning;
28
29pub use app::{App, ApplianceRecipe, Build, Recipe};
30pub use check::{Unresolved, check, placeholder_problems};
31pub use files::{File, FileSource, Mode};
32pub use forms::{Form, NoForm, container as container_form, reboots, vm as vm_form};
33pub use hardware::{Hardware, Tpm};
34pub use inputs::{Input, Inputs};
35pub use machine::{Kind, Machine, Octets, Services};
36pub use names::{InputName, PortName, ServiceRef, Version};
37pub use os::OsRef;
38pub use overrides::{
39 CloudMachine, CloudOverrides, DockerNetwork, DockerOverrides, EsxiOverrides, ExternalMachine, ExternalNetwork, ExternalOverrides, ExternalVolume,
40 KubernetesOverrides, Overrides, ProviderBoxes, ProxmoxMachine, ProxmoxOverrides, ProxmoxVolume, VagrantBox, VagrantMachine, VagrantOverrides,
41};
42pub use parse::parse;
43pub use ports::{Port, PortProtocol, Publish};
44pub use problem::{Code, FieldPath, Problem, Problems, Span, closest};
45pub use process::{Command, EnvValue, HealthPage, HealthProbe, Healthcheck, PortRef};
46pub use shared::{Group, Shared};
47pub use spans::Spans;
48pub use step::{
49 AbsPath, AptWord, Argv, CommandStep, Copy, FileState, FileStep, Firewall, FirewallPort, GroupName, GroupStep, Guard, HttpsUrl, Invocation, Package,
50 PackageName, PackageVersion, Password, ProjectPath, Repository, RepositoryKey, RepositoryName, Service, Sha256, Step, Template, UnitName, UserName,
51 UserStep,
52};
53pub use warning::Warning;
54
55use indexmap::IndexMap;
56use schemars::JsonSchema;
57
58use crate::model::{Check, CloudServices, Constraints, Controller, EnvironmentDns, Network, Provision, Reach, SecretSource, SharedVolume, Target, Tool};
59
60/// An environment spec, as written. Field order is kept (machines start in the order written).
61#[derive(Debug, Clone, PartialEq, Default, JsonSchema)]
62pub struct Spec {
63 /// The version of the `isoloom.yml` format the file is written in: `1`.
64 pub version: Version,
65 /// The environment's id, in kebab case (`supplier-portal`): it names its containers, VMs,
66 /// networks and cloud resources.
67 pub name: String,
68 /// The environment's networks, by name: each an address block the machines on it share.
69 #[schemars(default)]
70 pub networks: IndexMap<String, Network>,
71 /// Allowed traffic between networks; everything else between networks is blocked.
72 #[schemars(default)]
73 pub reach: Vec<Reach>,
74 /// The environment's names in a private DNS zone: off unless `private: true`.
75 pub dns: Option<EnvironmentDns>,
76 /// Values given at each start (a flag, a launch token): a list of names, or a map of name to
77 /// `{ sensitive, description }`. An input is sensitive unless it says otherwise: it reaches a
78 /// machine as a file (`files: [{ path, input }]`), never as an environment variable.
79 #[schemars(default)]
80 pub inputs: Inputs,
81 /// Secrets, by kebab-case name: the store each value is read from at each start (`env`,
82 /// `file`, `vault`, `sops`). A machine gets one as a file (`files: [{ path, secret }]`).
83 #[schemars(default)]
84 pub secrets: IndexMap<String, SecretSource>,
85 /// Volumes shared between machines, by name: `{ owner, persistent }`.
86 #[schemars(default)]
87 pub volumes: IndexMap<String, SharedVolume>,
88 /// The environment's machines, by name, started in the order written (after their
89 /// `depends_on`).
90 #[schemars(default)]
91 pub machines: IndexMap<String, Machine>,
92 /// Machine fields every machine shares (a machine's own value wins).
93 pub common: Option<Shared>,
94 /// Named sets of machines sharing fields, also Ansible inventory groups and `overrides` keys.
95 #[schemars(default)]
96 pub groups: IndexMap<String, Group>,
97 /// The environment's own Ansible, run from Isoloom's Linux controller once every machine is
98 /// up.
99 #[schemars(default)]
100 pub provision: Vec<Provision>,
101 /// The controller added for `provision:` and playbook checks: `{ resources, keep_running }`.
102 pub controller: Option<Controller>,
103 /// Black-box checks that prove the behaviour on every target.
104 #[schemars(default)]
105 pub checks: Vec<Check>,
106 /// Shown once the environment is up, in Markdown, with `{{ path }}` placeholders:
107 /// `machines.<m>.ports.<name>.port`, `.published`, `.url`, `machines.<m>.addresses.<network>`
108 /// and `cloud.outputs.<name>`, each checked at validation.
109 pub message: Option<String>,
110 /// Per-target facts with no portable meaning, by target (`docker`, `vagrant`, `proxmox`,
111 /// `aws`, ...).
112 #[schemars(default)]
113 pub overrides: Overrides,
114 /// Observers beside the environment, on every network: a toolbox (`shell`), or any container
115 /// image.
116 #[schemars(default)]
117 pub tools: IndexMap<String, Tool>,
118 /// Narrows the targets the machines' forms allow.
119 pub targets: Option<Vec<Target>>,
120 /// What the place it runs in imposes: an HTTP proxy, registry and package mirrors, time
121 /// servers.
122 pub constraints: Option<Constraints>,
123 /// An environment of cloud services rather than machines: a Terraform module applied into
124 /// the user's own cloud account.
125 pub cloud: Option<CloudServices>,
126 /// Base machine name → its clones, for machines that had a `count`. Filled when parsing.
127 #[schemars(skip)]
128 pub clones: IndexMap<String, Vec<String>>,
129 /// Where each field is written, for the problems found after parsing.
130 #[schemars(skip)]
131 pub spans: Spans,
132}