provisioning-catalog/providers/prov_lib/nickel/provider_catalog.ncl

62 lines
2.3 KiB
Text
Raw Normal View History

# Provider catalog contract — declarative shape every provider exports via
# its `nickel/catalog.ncl`. Round-trip target: the Rust types in
# `libre-forge-fleet/crates/fleet-protocol/src/provider.rs`
# (BillingPolicy, InstanceType, Supports, Arch, Rounding). Field names and
# allowed string-enum values match Rust's `#[serde(rename_all = "snake_case")]`
# representation so `nickel export --format json` produces JSON the daemon
# can deserialize directly.
#
# Add a new provider:
# 1. Copy `hetzner/nickel/catalog.ncl` to `<new>/nickel/catalog.ncl`.
# 2. Populate `instance_types`, `billing_policy`, `supports` for that cloud.
# 3. Run `nickel export --import-path <prov_root> <new>/nickel/catalog.ncl`
# and verify the JSON deserialises as `ProviderCatalog` in fleet-protocol.
let _Arch = std.contract.from_predicate (fun v =>
std.is_string v && (v == "x86_64" || v == "arm64")
) in
let _Rounding = std.contract.from_predicate (fun v =>
std.is_string v && (v == "ceil_hour" || v == "ceil_minute" || v == "ceil_second" || v == "exact")
) in
let _NonNeg = std.contract.from_predicate (fun v =>
std.is_number v && v >= 0
) in
{
# Cents per hour, sub-cent granularity. 1 EUR = 10_000 Cents.
# See fleet-protocol::provider::Cents (i64).
InstanceType = {
id | String,
arch | _Arch,
cpu | _NonNeg,
ram_gb | _NonNeg,
disk_gb | _NonNeg,
hourly_cents | _NonNeg,
},
BillingPolicy = {
granularity_s | _NonNeg | doc "smallest billable increment in seconds",
minimum_s | _NonNeg | doc "lower bound applied after granularity rounding",
monthly_cap_hours | _NonNeg | doc "hours after which price plateaus inside a calendar month",
rounding | _Rounding,
},
Supports = {
resize | Bool | default = false,
resize_needs_reboot | Bool | default = false,
stop_start_free | Bool | default = false,
spot | Bool | default = false,
sustained_use_discount | Bool | default = false,
},
# Top-level shape every <provider>/nickel/catalog.ncl returns.
ProviderCatalog = {
name | String | doc "stable provider id matching fleet-protocol::Provider::name()",
instance_types | Array InstanceType,
billing_policy | BillingPolicy,
supports | Supports,
},
}