provisioning/schemas/lib/contracts.ncl

200 lines
7.7 KiB
Text
Raw Normal View History

# | KCL core lib schema contracts
# | Migrated from: provisioning/kcl/lib.k
# | Pattern: Schema definitions only
let _concerns_lib = import "concerns.ncl" in
{
StorageVol = {
name | String,
size | Number,
total | Number,
type | String,
mount | Bool,
mount_path | String | optional,
fstab | Bool,
},
Storage = {
name | String,
size | Number,
total | Number,
type | String,
mount | Bool,
mount_path | String | optional,
fstab | Bool,
parts,
},
TaskServDependency = {
name | String,
kind | [| 'Requires, 'PrefersBefore, 'ConflictsWith |] | default = 'Requires,
condition | String | default = "",
},
TaskServDef = {
name | String,
install_mode | String | default = "library",
profile | String | default = "default",
target_save_path | String | default = "",
depends_on | Array {
name | String,
kind | [| 'Requires, 'PrefersBefore, 'ConflictsWith |] | default = 'Requires,
condition | String | default = "",
} | default = [],
on_error | [| 'Stop, 'Continue, 'Retry |] | default = 'Stop,
max_retries | Number | default = 0,
params | { .. } | default = {},
..
},
ClusterDef = {
name | String,
profile | String | default = "default",
target_save_path | String | default = "",
},
# Unified component model — deployment mode selector
DeployMode = [| 'taskserv, 'cluster, 'container |],
# Port exposure requirements declared by a component
PortRequirement = {
port | Number,
protocol | String | default = "TCP",
exposure | [| 'public, 'private, 'internal |] | default = 'internal,
},
# What a component needs from the infrastructure
ComponentRequires = {
storage | { size | String, persistent | Bool } | optional,
ports | Array {
port | Number,
protocol | String | default = "TCP",
exposure | [| 'public, 'private, 'internal |] | default = 'internal,
} | default = [],
credentials | Array String | default = [],
},
# What a component exposes to other components
ComponentProvides = {
service | String | optional,
port | Number | optional,
databases | Array String | default = [],
endpoints | Array String | default = [],
},
# Operations supported by a component (maps to CMD_TSK dispatch in scripts)
ComponentOperations = {
install | Bool | default = true,
update | Bool | default = false,
reinstall | Bool | default = false,
delete | Bool | default = false,
backup | Bool | default = false,
restore | Bool | default = false,
health | Bool | default = false,
config | Bool | default = false,
scripts | Bool | default = false,
restart | Bool | default = false,
},
# How to verify a component is live after deployment.
# Orthogonal to mode (provisioning mechanism) — describes runtime observability strategy.
LiveCheckDef = {
# 'k8s_pods — kubectl get pods filtered by namespace+selector (via CP SSH)
# 'k8s_nodes — kubectl get nodes filtered by selector; healthy = all Ready (for worker components)
# 'k8s_api — proxy: apiserver reachable if kubectl returns node list
# 'systemd — systemctl is-active <service> on target servers (skipped in ll fast path)
# 'none — no observable runtime state (one-shot ops, bare binaries)
strategy | [| 'k8s_pods, 'k8s_nodes, 'k8s_api, 'systemd, 'none |] | default = 'none,
# 'cp_only — SSH to control-plane only (kubectl sees all pods/nodes from there)
# 'target — SSH to component.target (typically CP for taskservs with explicit target)
# 'all_servers — check all servers in workspace state (systemd only; skipped in ll)
# 'workers_only — check only worker nodes (k8s_nodes for kubernetes_worker)
scope | [| 'cp_only, 'target, 'all_servers, 'workers_only |] | default = 'cp_only,
namespace | String | default = "", # overrides component.namespace for pod filter
selector | String | default = "", # overrides component.pod_selector; also used as node name filter
service | String | default = "", # systemd unit name
# Aggregation for multi-server checks (all_servers / workers_only scope):
# 'all_must_pass — any failure → degraded (runtimes, DNS)
# 'any_active — at least one live → partial acceptable
# 'majority — >50% live → healthy
aggregate | [| 'all_must_pass, 'any_active, 'majority |] | default = 'all_must_pass,
},
# Unified component definition — extends TaskServDef shape with mode, requires, provides.
# Open record with defaults on new fields: existing taskservs satisfy ComponentDef.
ComponentDef = {
name | String,
mode | [| 'taskserv, 'cluster, 'container |] | default = 'taskserv,
target | String | optional, # server hostname (taskserv mode)
namespace | String | optional, # k8s namespace (cluster mode)
pod_selector | String | optional, # k8s pod name search pattern (overrides component name when k8s release name differs)
live_check | LiveCheckDef | default = { strategy = 'none, scope = 'cp_only, namespace = "", selector = "", service = "", aggregate = 'all_must_pass },
node_selector | { _ | String } | optional, # k8s node affinity (cluster mode)
install_mode | String | default = "library",
profile | String | default = "default",
target_save_path | String | default = "",
depends_on | Array {
name | String,
kind | [| 'Requires, 'PrefersBefore, 'ConflictsWith |] | default = 'Requires,
condition | String | default = "",
} | default = [],
on_error | [| 'Stop, 'Continue, 'Retry |] | default = 'Stop,
max_retries | Number | default = 0,
params | { .. } | default = {},
requires | {
storage | { size | String, persistent | Bool } | optional,
ports | Array {
port | Number,
protocol | String | default = "TCP",
exposure | [| 'public, 'private, 'internal |] | default = 'internal,
} | default = [],
credentials | Array String | default = [],
} | default = {},
provides | {
service | String | optional,
port | Number | optional,
databases | Array String | default = [],
endpoints | Array String | default = [],
} | default = {},
operations | {
install | Bool | default = true,
update | Bool | default = false,
reinstall | Bool | default = false,
delete | Bool | default = false,
backup | Bool | default = false,
restore | Bool | default = false,
health | Bool | default = false,
config | Bool | default = false,
scripts | Bool | default = false,
restart | Bool | default = false,
} | default = {},
# Mandatory declarative surface for service-level concerns. Each entry is a
# ConcernState variant (enabled/disabled/pending/inherited). Components that
# don't implement a concern declare 'pending {reason, backlog_ref} or
# 'disabled {reason} — never omit. CI/ontoref consume this surface to emit
# backlog priorities and architecture documentation.
concerns | _concerns_lib.ServiceConcerns,
..
},
ScaleData = {
def | String,
disabled | Bool,
mode | String,
expire | Dyn | optional,
from | Dyn | optional,
to | Dyn | optional,
},
ScaleResource = {
default,
fallback | Dyn | optional,
up | Dyn | optional,
down | Dyn | optional,
min | Dyn | optional,
max | Dyn | optional,
path | String,
},
}