provisioning/schemas/providers/backup.ncl

106 lines
4.5 KiB
Text

# Backup provider contract — the interface every backup/restore provider must implement.
# Consumed by op.nu to build and execute archive commands generically.
# Each provider declares its binary, features, environment requirements, and
# the exact subcommands + flags needed for each operation.
let _Features = {
tags | Bool | doc "Supports --tag key=value on snapshot create" | default = true,
ui | Bool | doc "Has built-in web UI (e.g. kopia server start --ui)" | default = false,
verify | Bool | default = true,
mount | Bool | doc "Supports FUSE mount of snapshots" | default = false,
encryption | Bool | doc "Encrypts snapshots end-to-end (non-negotiable for this stack)" | default = true,
compression | Bool | default = false,
dedup | [| 'none, 'per_repo, 'global |] | default = 'per_repo,
streaming | Bool | doc "Supports backup from stdin (pg_dump pipe, etc.)" | default = false,
} in
let _Env = {
required | Array String | doc "Must be set before any operation",
optional | Array String | default = [],
} in
let _Connection = {
required | Bool | doc "Must call connect before backup (kopia=true, restic=false)" | default = false,
status_subcmd | String | optional | doc "Subcommand to check if already connected",
connect_subcmd | String | optional | doc "Subcommand to establish connection to the repo",
state_file | String | optional | doc "Filename stored under ops_dir for per-workspace connection state (e.g. '.kopia-config')",
s3_flags | {
bucket | String | optional,
endpoint | String | optional,
prefix | String | optional,
} | default = {},
} in
let _BackupCmd = {
subcmd | String | doc "Subcommand (may contain spaces, e.g. 'snapshot create')",
repo_flag | String | optional | doc "Flag for repository URL; absent if config-file based",
tag_flag | String | optional | doc "Flag for a single tag entry (repeated per tag)",
snapshot_id_regex | String | doc "Regex with named group 'id' to extract snapshot ID from stdout",
} in
let _RestoreCmd = {
subcmd | String,
repo_flag | String | optional,
target_flag | String | doc "Flag for restore destination; empty string = positional arg",
} in
let _ListCmd = {
subcmd | String,
repo_flag | String | optional,
tag_flag | String | optional,
} in
let _ForgetCmd = {
subcmd | String | doc "Subcommand that removes old snapshots",
repo_flag | String | optional,
tag_flag | String | optional | doc "Scope forget to a specific tag (workspace isolation)",
keep_last_flag | String | optional | doc "Absent when retention is controlled via policy_subcmd",
keep_monthly_flag | String | optional,
keep_yearly_flag | String | optional,
extra_flags | Array String | default = [],
policy_subcmd | String | optional | doc "If set, run policy subcommand before forget (kopia model)",
policy_keep_flags | {
keep_latest | String | default = "--keep-latest",
keep_monthly | String | default = "--keep-monthly",
keep_annual | String | default = "--keep-annual",
} | optional,
} in
let _VerifyCmd = {
subcmd | String,
repo_flag | String | optional,
} in
# EncryptionRequired contract: provider features must include encryption=true.
# A BackupPolicy referencing a provider that does not encrypt fails at
# `nickel export` time, not at runtime — this is how the non-negotiable
# E2E encryption invariant is enforced.
let _EncryptionRequired = std.contract.from_validator (fun value =>
if value.features.encryption == true
then 'Ok
else 'Error {
message = "BackupProvider lacks 'encryption in features (E2E encryption is non-negotiable)",
}
) in
{
BackupProvider = {
name | String | doc "Provider identifier — must match the directory name under extensions/providers/backup/",
binary | String | doc "CLI binary invoked for all operations",
features | _Features | default = {},
env | _Env,
connection | _Connection | default = {},
mount_capable | Bool | doc "Convenience flag mirroring features.mount" | default = false,
streaming_capable | Bool | doc "Convenience flag mirroring features.streaming" | default = false,
commands = {
backup | _BackupCmd,
restore | _RestoreCmd,
list | _ListCmd,
forget | _ForgetCmd,
verify | _VerifyCmd | optional,
},
},
# Apply this contract to provider definitions to enforce E2E encryption.
EncryptionRequired = _EncryptionRequired,
}