mirror of
https://github.com/garethgeorge/backrest.git
synced 2026-08-28 11:56:28 +00:00
317 lines
14 KiB
Protocol Buffer
317 lines
14 KiB
Protocol Buffer
syntax = "proto3";
|
|
|
|
package v1;
|
|
|
|
option go_package = "github.com/garethgeorge/backrest/gen/go/v1";
|
|
|
|
import "google/protobuf/empty.proto";
|
|
import "v1/crypto.proto";
|
|
|
|
|
|
// Config is the top level config object for restic UI.
|
|
message Config {
|
|
// modification number, used for read-modify-write consistency in the UI. Incremented on every write.
|
|
int32 modno = 1 [json_name="modno"];
|
|
int32 version = 6 [json_name="version"]; // version of the config file format. Used to determine when to run migrations.
|
|
|
|
// The instance name for the Backrest installation.
|
|
// This identifies backups created by this instance and is displayed in the UI.
|
|
string instance = 2 [json_name="instance"];
|
|
|
|
repeated Repo repos = 3 [json_name="repos"];
|
|
repeated Plan plans = 4 [json_name="plans"];
|
|
Auth auth = 5 [json_name="auth"];
|
|
Multihost multihost = 7 [json_name="sync"];
|
|
}
|
|
|
|
message Multihost {
|
|
PrivateKey identity = 1;
|
|
repeated Peer known_hosts = 2 [json_name="knownHosts"];
|
|
repeated Peer authorized_clients = 3 [json_name="authorizedClients"];
|
|
repeated PairingToken pairing_tokens = 4 [json_name="pairingTokens"]; // active pairing tokens generated by this instance (server-side only)
|
|
|
|
message Peer {
|
|
string instance_id = 1 [json_name="instanceId"]; // a human readable name for the peer, typically the same as its instance ID.
|
|
string keyid = 2 [json_name="keyId"]; // the key ID of the peer. This must match the sha256 of the public key the client provides in handshake.
|
|
reserved 3; // was keyid_verified, removed in favor of pairing tokens
|
|
repeated Permission permissions = 5 [json_name="permissions"]; // permissions granted to this peer.
|
|
|
|
// Known host only fields
|
|
string instance_url = 4 [json_name="instanceUrl"]; // instance URL, required for a known host. Otherwise meaningless.
|
|
string initial_pairing_secret = 6 [json_name="initialPairingSecret"]; // one-time pairing secret sent during first handshake to auto-authorize with the server. Cleared after successful pairing.
|
|
}
|
|
|
|
message PairingToken {
|
|
string secret = 1 [json_name="secret"]; // the one-time secret used to validate the pairing request
|
|
string label = 2 [json_name="label"]; // human-readable label for this token
|
|
int64 created_at_unix = 3 [json_name="createdAtUnix"]; // unix timestamp when the token was created
|
|
int64 expires_at_unix = 4 [json_name="expiresAtUnix"]; // unix timestamp when the token expires
|
|
int32 max_uses = 5 [json_name="maxUses"]; // maximum number of clients that can pair with this token, 0 means unlimited
|
|
int32 uses = 6 [json_name="uses"]; // number of times this token has been used
|
|
repeated Permission permissions = 7 [json_name="permissions"]; // permissions granted to clients that pair with this token
|
|
}
|
|
|
|
message Permission {
|
|
enum Type {
|
|
PERMISSION_UNKNOWN = 0;
|
|
|
|
// Granted on a knownHost (by client → host): the local instance pushes
|
|
// operations for in-scope repos/plans up to that known host, and
|
|
// exposes those resource IDs/GUIDs in the resource list it sends.
|
|
// Granted on an authorizedClient: no effect. The host never pushes
|
|
// operations down to clients.
|
|
PERMISSION_READ_OPERATIONS = 1;
|
|
|
|
// Granted on an authorizedClient (by host → client): in-scope repos/plans
|
|
// are included in the host's RemoteConfig and resource list sent to
|
|
// the client (read-only view of host config).
|
|
// Granted on a knownHost (by client → host): in-scope repos/plans are
|
|
// included in the client's RemoteConfig and resource list sent to the
|
|
// host (read-only view of client config).
|
|
PERMISSION_READ_CONFIG = 2;
|
|
|
|
// Granted on an authorizedClient (by host → client): same view as
|
|
// READ_CONFIG. There is no client→host SetConfig path, so the "write"
|
|
// half is currently a no-op on the host side.
|
|
// Granted on a knownHost (by client → host): everything READ_CONFIG does,
|
|
// plus the client accepts SetConfig from the host for in-scope IDs
|
|
// (create/update/delete plans, create/update/delete repos).
|
|
PERMISSION_READ_WRITE_CONFIG = 3;
|
|
|
|
// Both peers must grant this for shared repos to flow:
|
|
// - Granted on an authorizedClient (by host → client): host pushes
|
|
// in-scope repos marked as 'shared' to that client via SetConfig.
|
|
// A scopeless grant acts as a wildcard (push every shared repo);
|
|
// a scoped grant restricts which shared repos are pushed.
|
|
// - Granted on a knownHost (by client → host): client accepts pushed
|
|
// shared repos that are new or already owned by this host. Always
|
|
// evaluated scope-lessly on the client — scopes are ignored here
|
|
// because the client doesn't pre-know the incoming repo IDs.
|
|
// If either side is missing the grant, no shared repos are transferred.
|
|
PERMISSION_RECEIVE_SHARED_REPOS = 4;
|
|
}
|
|
// Scopes are any of '*', 'repo:<repo_id>' or 'plan:<plan_id>','-repo:<repo_id>','-plan:<plan_id>'.
|
|
// '*' means all repos and plans, 'repo:<repo_id>' means the repo with the given ID, 'plan:<plan_id>' means the plan with the given ID.
|
|
// '!repo:<repo_id>' means all repos except the one with the given ID, '!plan:<plan_id>' means all plans except the one with the given ID.
|
|
Type type = 1;
|
|
repeated string scopes = 2 [json_name="scopes"];
|
|
}
|
|
}
|
|
|
|
message Repo {
|
|
string id = 1 [json_name="id"]; // unique but human readable ID for this repo.
|
|
string uri = 2 [json_name="uri"]; // URI of the repo.
|
|
string guid = 11 [json_name="guid"]; // a globally unique ID for this repo. Should be derived as the 'id' field in `restic cat config --json`.
|
|
string password = 3 [json_name="password"]; // plaintext password
|
|
repeated string env = 4 [json_name="env"]; // extra environment variables to set for restic.
|
|
repeated string flags = 5 [json_name="flags"]; // extra flags set on the restic command.
|
|
PrunePolicy prune_policy = 6 [json_name="prunePolicy"]; // policy for when to run prune.
|
|
CheckPolicy check_policy = 9 [json_name="checkPolicy"]; // policy for when to run check.
|
|
repeated Hook hooks = 7 [json_name="hooks"]; // hooks to run on events for this repo.
|
|
bool auto_unlock = 8 [json_name="autoUnlock"]; // automatically unlock the repo when needed.
|
|
bool auto_initialize = 12 [json_name="autoInitialize"]; // whether the repo should be auto-initialized if not found.
|
|
CommandPrefix command_prefix = 10 [json_name="commandPrefix"]; // modifiers for the restic commands
|
|
bool shared = 13 [json_name="shared"]; // if true, this repo is pushed to all authorized clients with read-config permission
|
|
string origin_instance_id = 14 [json_name="originInstanceId"]; // set when this repo was pushed from a remote instance; marks it as non-editable
|
|
ForgetPolicy forget_policy = 15 [json_name="forgetPolicy"]; // optional repo-level forget policy. If set, overrides per-plan retention policies.
|
|
}
|
|
|
|
message Plan {
|
|
string id = 1 [json_name="id"]; // unique but human readable ID for this plan.
|
|
string repo = 2 [json_name="repo"]; // ID of the repo to use.
|
|
repeated string paths = 4 [json_name="paths"]; // paths to include in the backup.
|
|
repeated string excludes = 5 [json_name="excludes"]; // glob patterns to exclude.
|
|
repeated string iexcludes = 9 [json_name="iexcludes"]; // case insensitive glob patterns to exclude.
|
|
Schedule schedule = 12 [json_name="schedule"]; // schedule for the backup.
|
|
RetentionPolicy retention = 7 [json_name="retention"]; // retention policy for snapshots.
|
|
repeated Hook hooks = 8 [json_name="hooks"]; // hooks to run on events for this plan.
|
|
repeated string backup_flags = 10 [json_name="backup_flags"]; // extra flags to set when running a backup command.
|
|
bool skip_if_unchanged = 13 [json_name="skipIfUnchanged"]; // skip the backup if no changes are detected.
|
|
reserved 3, 6, 11; // deprecated
|
|
}
|
|
|
|
message CommandPrefix {
|
|
enum IONiceLevel {
|
|
IO_DEFAULT = 0;
|
|
IO_BEST_EFFORT_LOW = 1;
|
|
IO_BEST_EFFORT_HIGH = 2;
|
|
IO_IDLE = 3;
|
|
}
|
|
|
|
enum CPUNiceLevel {
|
|
CPU_DEFAULT = 0;
|
|
CPU_HIGH = 1;
|
|
CPU_LOW = 2;
|
|
}
|
|
|
|
IONiceLevel io_nice = 1 [json_name="ioNice"]; // ionice level to set.
|
|
CPUNiceLevel cpu_nice = 2 [json_name="cpuNice"]; // nice level to set.
|
|
}
|
|
|
|
message RetentionPolicy {
|
|
oneof policy {
|
|
int32 policy_keep_last_n = 10 [json_name="policyKeepLastN"];
|
|
TimeBucketedCounts policy_time_bucketed = 11 [json_name="policyTimeBucketed"];
|
|
bool policy_keep_all = 12 [json_name="policyKeepAll"];
|
|
}
|
|
|
|
message TimeBucketedCounts {
|
|
int32 hourly = 1 [json_name="hourly"]; // keep the last n hourly snapshots.
|
|
int32 daily = 2 [json_name="daily"]; // keep the last n daily snapshots.
|
|
int32 weekly = 3 [json_name="weekly"]; // keep the last n weekly snapshots.
|
|
int32 monthly = 4 [json_name="monthly"]; // keep the last n monthly snapshots.
|
|
int32 yearly = 5 [json_name="yearly"]; // keep the last n yearly snapshots.
|
|
int32 keep_last_n = 6 [json_name="keepLastN"]; // keep the last n snapshots regardless of age.
|
|
}
|
|
}
|
|
|
|
message ForgetPolicy {
|
|
Schedule schedule = 1 [json_name="schedule"];
|
|
RetentionPolicy retention = 2 [json_name="retention"];
|
|
}
|
|
|
|
message PrunePolicy {
|
|
Schedule schedule = 2 [json_name="schedule"];
|
|
int64 max_unused_bytes = 3 [json_name="maxUnusedBytes"]; // max unused bytes before running prune.
|
|
double max_unused_percent = 4 [json_name="maxUnusedPercent"]; // max unused percent before running prune.
|
|
}
|
|
|
|
message CheckPolicy {
|
|
Schedule schedule = 1 [json_name="schedule"];
|
|
|
|
oneof mode {
|
|
bool structure_only = 100 [json_name="structureOnly"]; // only check the structure of the repo. No pack data is read.
|
|
double read_data_subset_percent = 101 [json_name="readDataSubsetPercent"]; // check a percentage of pack data.
|
|
}
|
|
}
|
|
|
|
message Schedule {
|
|
oneof schedule {
|
|
bool disabled = 1 [json_name="disabled"]; // disable the schedule.
|
|
string cron = 2 [json_name="cron"]; // cron expression describing the schedule.
|
|
int32 maxFrequencyDays = 3 [json_name="maxFrequencyDays"]; // max frequency of runs in days.
|
|
int32 maxFrequencyHours = 4 [json_name="maxFrequencyHours"]; // max frequency of runs in hours.
|
|
}
|
|
|
|
enum Clock {
|
|
CLOCK_DEFAULT = 0; // same as CLOCK_LOCAL
|
|
CLOCK_LOCAL = 1;
|
|
CLOCK_UTC = 2;
|
|
CLOCK_LAST_RUN_TIME = 3;
|
|
}
|
|
|
|
Clock clock = 5 [json_name="clock"]; // clock to use for scheduling.
|
|
}
|
|
|
|
message Hook {
|
|
enum Condition {
|
|
CONDITION_UNKNOWN = 0;
|
|
CONDITION_ANY_ERROR = 1; // error running any operation.
|
|
CONDITION_SNAPSHOT_START = 2; // backup started.
|
|
CONDITION_SNAPSHOT_END = 3; // backup completed (success or fail).
|
|
CONDITION_SNAPSHOT_ERROR = 4; // snapshot failed.
|
|
CONDITION_SNAPSHOT_WARNING = 5; // snapshot completed with warnings.
|
|
CONDITION_SNAPSHOT_SUCCESS = 6; // snapshot succeeded.
|
|
CONDITION_SNAPSHOT_SKIPPED = 7; // snapshot was skipped e.g. due to no changes.
|
|
|
|
// prune conditions
|
|
CONDITION_PRUNE_START = 100; // prune started.
|
|
CONDITION_PRUNE_ERROR = 101; // prune failed.
|
|
CONDITION_PRUNE_SUCCESS = 102; // prune succeeded.
|
|
|
|
// check conditions
|
|
CONDITION_CHECK_START = 200; // check started.
|
|
CONDITION_CHECK_ERROR = 201; // check failed.
|
|
CONDITION_CHECK_SUCCESS = 202; // check succeeded.
|
|
|
|
// forget conditions
|
|
CONDITION_FORGET_START = 300; // forget started.
|
|
CONDITION_FORGET_ERROR = 301; // forget failed.
|
|
CONDITION_FORGET_SUCCESS = 302; // forget succeeded.
|
|
}
|
|
|
|
enum OnError {
|
|
ON_ERROR_IGNORE = 0;
|
|
ON_ERROR_CANCEL = 1; // cancels the operation and skips subsequent hooks
|
|
ON_ERROR_FATAL = 2; // fails the operation and subsequent hooks.
|
|
ON_ERROR_RETRY_1MINUTE = 100; // retry the operation every minute
|
|
ON_ERROR_RETRY_10MINUTES = 101; // retry the operation every 10 minutes
|
|
ON_ERROR_RETRY_EXPONENTIAL_BACKOFF = 103; // retry the operation with exponential backoff up to 1h max.
|
|
}
|
|
|
|
repeated Condition conditions = 1 [json_name="conditions"];
|
|
OnError on_error = 2 [json_name="onError"];
|
|
|
|
oneof action {
|
|
Command action_command = 100 [json_name="actionCommand"];
|
|
Webhook action_webhook = 101 [json_name="actionWebhook"];
|
|
Discord action_discord = 102 [json_name="actionDiscord"];
|
|
Gotify action_gotify = 103 [json_name="actionGotify"];
|
|
Slack action_slack = 104 [json_name="actionSlack"];
|
|
Shoutrrr action_shoutrrr = 105 [json_name="actionShoutrrr"];
|
|
Healthchecks action_healthchecks = 106 [json_name="actionHealthchecks"];
|
|
Telegram action_telegram = 107 [json_name="actionTelegram"];
|
|
}
|
|
|
|
message Command {
|
|
string command = 1 [json_name="command"];
|
|
}
|
|
|
|
message Webhook {
|
|
string webhook_url = 1 [json_name="webhookUrl"];
|
|
enum Method {
|
|
UNKNOWN = 0;
|
|
GET = 1;
|
|
POST = 2;
|
|
}
|
|
Method method = 2 [json_name="method"];
|
|
string template = 100 [json_name="template"];
|
|
}
|
|
|
|
message Discord {
|
|
string webhook_url = 1 [json_name="webhookUrl"];
|
|
string template = 2 [json_name="template"]; // template for the webhook payload.
|
|
}
|
|
|
|
message Gotify {
|
|
string base_url = 1 [json_name="baseUrl"];
|
|
string token = 3 [json_name="token"];
|
|
string template = 100 [json_name="template"]; // template for the webhook payload.
|
|
string title_template = 101 [json_name="titleTemplate"]; // template for the webhook title.
|
|
int32 priority = 102 [json_name="priority"]; // priority level for the notification (1-10)
|
|
}
|
|
|
|
message Slack {
|
|
string webhook_url = 1 [json_name="webhookUrl"];
|
|
string template = 2 [json_name="template"]; // template for the webhook payload.
|
|
}
|
|
|
|
message Shoutrrr {
|
|
string shoutrrr_url = 1 [json_name="shoutrrrUrl"];
|
|
string template = 2 [json_name="template"];
|
|
}
|
|
|
|
message Healthchecks {
|
|
string webhook_url = 1 [json_name="webhookUrl"];
|
|
string template = 2 [json_name="template"];
|
|
}
|
|
|
|
message Telegram {
|
|
string bot_token = 1 [json_name="botToken"];
|
|
string chat_id = 2 [json_name="chatId"];
|
|
string template = 3 [json_name="template"]; // template for the message text.
|
|
}
|
|
}
|
|
|
|
message Auth {
|
|
bool disabled = 1 [json_name="disabled"]; // disable authentication.
|
|
repeated User users = 2 [json_name="users"]; // users to allow access to the UI.
|
|
}
|
|
|
|
message User {
|
|
string name = 1 [json_name="name"];
|
|
oneof password {
|
|
string password_bcrypt = 2 [json_name="passwordBcrypt"];
|
|
}
|
|
}
|