Формат job v1

Актуально для v0.53.0 (pre-GA single-agent). Поля spec.schedules, runtime_hooks, backup.encryption и др. зависят от feature gates агента (docs/reference/feature-gates.md, docs/reference/experimental-features.md). Матрица зрелости провайдеров и подсистем: docs/reference/feature-status-matrix.md. Этот документ не описывает production restore/orchestration и не задаёт контракт центрального control plane.

Поддерживаемая схема

api_version: iobackup.io/v1
kind: BackupJob

В v1 исполняется только BackupJob.

Зарезервированные kind для будущих версий

Структура

Корневые блоки:

Внутри spec:

Детально по каждому полю, с уровнями вложенности и перекрёстными ссылками — в разделе «Справочник полей YAML».

Карта источников (source.type)

Примеры и поля конфигурации описаны ниже по типам и в тематических страницах сайта:

type Страница / раздел
filesystem Filesystem source; раздел ниже.
postgres Раздел ниже.
mysql Раздел ниже.
clickhouse ClickHouse source; ниже.
openldap OpenLDAP source; ниже.
vault Vault source; ниже.
docker_compose Docker Compose source; ниже.

Для postgres и mysql также см. общий паттерн Docker/runner для утилит.

Карта назначений (destination.type)

Конфиг всегда в destination.config:

type Страница
local Local destination.
s3 S3 destination; приёмник потоков и aws/docker см. также streaming и блок ниже.
ssh SSH destination.

Политики, уведомления, поток данных

Справочник полей YAML

Ниже — «человеческое» описание дерева задания. Необязательные поля помечены как опциональные; часть значений подставляется по умолчанию (см. важные defaults). Точное соответствие структуре — пакет internal/job/model.go.

Корень документа

Поле Обязательно Описание
api_version да Должно быть iobackup.io/v1.
kind да Должно быть BackupJob.
metadata да См. ниже.
spec да См. ниже.

metadata

Поле Обязательно Описание
job_id да Стабильный идентификатор job в агенте.
name нет Человекочитаемое имя.
description нет Произвольное описание.
labels нет Карта строк ключ: значение для фильтрации UI/отчётов.

Tenant / namespace / project / environment (0.17-fix.80): отдельных полей metadata.namespace в Go-модели пока нет — используйте соглашение по labels (например tenant, project, environment или префикс iobackup.io/*), пока в 0.18+ не появятся first-class поля.

System-managed identity and revisions (0.17-fix.20)

Начиная с 0.17-fix.20 агент хранит отдельную immutable историю версий job (revisions) и использует system-managed identity.

В обычном YAML (job submit/apply, без специальных флагов импорта) нельзя задавать system-managed поля — агент выставляет их сам. Валидация (job.Validate) отклоняет submit, если задано любое из:

Код ошибки: JOB_UID_NOT_ALLOWED_IN_NORMAL_SUBMIT (сообщение агрегирует эти поля).

Не используйте в ручном YAML (агент перезапишет или это приведёт к рассинхрону с API): metadata.latest_job_revision_id, metadata.submitted_hash, metadata.resolved_hash, metadata.matched_previous_job_id, metadata.deleted_at, metadata.delete_reason — они появляются в ответах API и в JSON в bolt.

metadata.job_id — стабильный пользовательский slug (primary key «по id» в API); при rename меняется, цепочка прежних id — в previous_job_ids на стороне агента.

metadata.job_uidнеизменяемый идентификатор цепочки job; сохраняется при rename.

Для просмотра истории версий используйте API/CLI:

Каждый Run сохраняет executed_job_snapshot (sanitized) и executed_job_hash для воспроизводимости.

spec

Поле Обязательно Описание
enabled да true/false — включено ли выполнение.
operation да (частично) По умолчанию подставляется type: backup. Другие типы в v1 не исполняются.
logging нет Logging/export policy hints (0.17-fix.50 foundation): include_source_paths, path_redaction.
data нет Data classification hints (0.17-fix.50 foundation): classification, contains_pii, residency, log_sensitivity.
execution нет Как гоняются tasks: mode (sequential / параллель по настройкам), fail_fast, max_parallel_tasks, timeout, опционально resources.
artifact нет Режим артефакта и staging: см. важные defaults и streaming.
resources нет Job-level resource limits (0.17-fix.30 foundation): max_runtime, max_artifact_size, min_free_space, max_stdout_bytes, max_stderr_bytes. Поля парсятся и отражаются в capabilities/health summary; строгий per-field enforcement (остановка run по каждому лимиту) — неполный / roadmap — опирайтесь на docs/internal/roadmap/status-matrix.md.
concurrency нет Job-level concurrency (0.17-fix.30 foundation): policy (allow|forbid|queue), lock_key, max_parallel_tasks.
conditions нет Reserved before/after run conditions (0.17-fix.30 foundation).
policies нет Job-level: retention, verify, encryption, validation, immutability, при необходимости вложенные resources/concurrency — см. retention, verify, auto-verify и подтаблицу ниже.
defaults нет Значения по умолчанию для tasks: backup, destination (тип + config), вложенные policies.
notifications нет Job-level webhooks: список в webhooks — события, URL, auth, retry; подробно webhooks.
tasks да Массив задач; минимум одна.

spec.operation

Поле Описание
type В v1 фактически только backup (подставляется по умолчанию, если пусто).
strategy В v1 исполняется только full (значение по умолчанию). Значения incremental, differential, synthetic_full и др. — reserved до реализации pipeline; валидация вернёт OPERATION_STRATEGY_UNSUPPORTED, если указать не-full.

spec.repository (опционально, 0.17-fix.40)

Логический блок репозитория (type, engine, repository_id, snapshot_id, parent_snapshot_id, external_ref, chunking). Исполняется связка по умолчанию type: single_artifact + engine: iobackup. Значения вроде external_engine / content_addressed зарезервированы: при попытке исполнить неподдерживаемую комбинацию валидация вернёт стабильный код (см. Go job.Validate / preflight).

spec.requires (reserved)

Поле spec.requires в YAML может встречаться в черновиках спецификации; в текущей Go-модели (internal/job/model.go) нет соответствующего поля — ключ игнорируется при decode или остаётся только в сыром YAML вне runtime. Semantics появятся в будущих версиях.

spec.logging (опционально, 0.17-fix.50)

spec:
  logging:
    include_source_paths: false
    path_redaction: basename # full | basename | hash | none

Defaults: include_source_paths=false, path_redaction=basename.

spec.data (опционально, 0.17-fix.50)

spec:
  data:
    classification: internal # public | internal | confidential | restricted
    contains_pii: false
    residency:
    log_sensitivity: normal # normal | high

Это signal-поля для будущего enforcement (export/support bundle / encryption / approvals).

Agent ExportPolicy.IncludePaths и HTTP API артефактов (не поля BackupJob YAML)

Поле ExportPolicy.IncludePaths относится к конфигурации процесса iobackup-agent, а не к документу BackupJob. В коде это agent.Config.ExportPolicy (internal/agent/config.go, значения по умолчанию — internal/agent.DefaultConfig). Отдельного поля в YAML job для этого нет.

Семантика для публичных ответов HTTP, которые сериализуют storage.BackupManifest в JSON:

IncludePaths Поведение в GET /api/v1/artifacts, GET /api/v1/artifacts/{backup_id}, GET /api/v1/artifacts/{backup_id}/manifest
false (дефолт) Path-like поля (например artifact.path, artifacts[].path, destination/source блоки с ключами вроде path, object_key, url) проходят через слой redaction с PathRedaction: basename: в JSON остаётся хвост пути (имя файла / последний сегмент), без полного абсолютного или каталожного префикса на хосте.
true Те же поля отдаются с полными строками путей/ключей (режим redaction full), если оператор явно принимает такое раскрытие через конфиг агента.

Не затрагивается этим переключателем: запись манифеста в metadata DB, POST …/verify, GET …/download, DELETE … — там по-прежнему используются полные пути из хранилища, иначе невозможно прочитать объект у destination.

Отдельно: iobackupctl metadata export задаёт политику путей своими флагами (--include-paths и т.д.); это не то же самое, что ExportPolicy.IncludePaths, хотя смысл «показывать пути или нет» схож.

См. также docs/internal/roadmap/status-matrix.md (раздел Known gaps / Deferred) и docs/internal/roadmap/roadmap.md (блок про hardening 40/50/60).

spec.execution (опционально)

Поле Описание
mode Например sequential — порядок выполнения tasks.
fail_fast Останавливать ли job при первой ошибке task.
max_parallel_tasks Ограничение параллелизма (если поддерживается конфигурацией).
timeout Строка длительности (например 2h) на уровне job.
resources Зарезервировано под расширения; произвольная карта.

spec.concurrency (опционально, 0.17-fix.30)

spec:
  concurrency:
    policy: forbid
    lock_key: mysql-prod
    max_parallel_tasks: 1

Поддержка:

spec.artifact (опционально)

Поле Описание
mode Например auto, stream, file, directory — влияет на streaming vs staging; см. streaming.
staging.enabled Разрешить ли локальный staging.
staging.path Каталог staging, если задан.
staging.max_size Ограничение размера staging.

spec.policies (опционально)

Блок Описание
retention Параметры политики хранения на уровне job (дни, будни, «последние успешные» и т.д.) — детали retention.
verify after_run, limit_per_task — см. verify и auto-verify.
encryption required (требует backup.encryption.enabled на каждой task), allowed_algorithms — signal; client-side streaming encryption исполняется при features.encryption=true и валидном task.backup.encryption (см. docs/features/encryption/encryption.md).
validation enabled, level — foundation; «строгий» режим до реализации может давать ошибку валидации, если включить unsupported уровень.
immutability enabled, mode, retain_until, legal_hold — reserved / частично парсится; enforcement см. roadmap.
resources / concurrency Дублируют job-level блоки на уровне политик при необходимости (см. internal/job/model.go).

spec.defaults (опционально)

Если в task не указаны backup, destination или policies, агент может подставить значения отсюда:

Поле Описание
backup Карта настроек по умолчанию для task.backup.
destination type + config по умолчанию для task.destination.
policies Политики по умолчанию для tasks.

spec.notifications (опционально)

Поле Описание
webhooks Список конфигураций webhook: name, enabled, events, request (method, url, timeout, headers, auth), retry, payload, policy. См. webhooks.

spec.notifications.webhooks[].payload (0.17-fix.50)

Поле Описание
format Зарезервировано под формат тела (например json).
template Зарезервировано под шаблоны после безопасного механизма trusted templates (roadmap 0.21+); сейчас не выполняется произвольный шаблон из YAML.

Итоговый HTTP body собирается агентом как DTO + опциональные включения из policy, затем redact.RedactAny.

spec.notifications.webhooks[].policy (0.17-fix.50)

policy:
  include_job_snapshot: false
  include_manifest: false
  include_labels: true
  include_paths: false

Payload всегда проходит redaction layer; включение paths управляет только тем, допускаются ли они в payload (и в каком виде).

Элемент spec.tasks[]

Каждая задача описывает один проход «источник → упаковка/чексы → назначение» (и опционально свои политики и уведомления).

Поле Обязательно Описание
task_id да Уникальный id задачи внутри job.
required нет Default true. Если false, failure этой задачи ведёт к partial_success, а не failed (0.17-fix.30).
source да type + config — см. карту источников.
backup нет Формат архива, сжатие, checksum, шифрование — зависят от source/destination.
destination да type + config — см. карту назначений.
resources нет Task-level override resources (0.17-fix.30 foundation).
policies нет Retention/verify на уровне task (перекрывают или дополняют job в зависимости от логики агента).
notifications нет Webhooks только для этой task.
hooks нет Reserved до ~0.21 (safe hooks). Структура парсится, но inline-команды и произвольные пути не исполняются; при features.hooks=false (дефолт) непустые hooks дают HOOKS_UNSUPPORTED. Не используйте hooks в prod, ожидая выполнение — только после feature gate и реализации движка.
timeout нет Таймаут конкретной task.
tags нет Метки для фильтрации/отчётов.

task.backup (опционально)

Поле Описание
format Например tar.gz для filesystem.
compression Например gzip.
checksum Например sha256.
encryption enabled, algorithm (aes-256-gcm), key_ref (env:/file:) для mode: direct (по умолчанию), chunk_max_plaintext, mode (direct|envelope), kek_ref, key_id, key_version для envelope — см. docs/features/encryption/encryption.md. Требует features.encryption; envelope — ещё features.envelope_encryption.

depends_on (reserved)

Поле depends_on для DAG задач в текущей модели не реализовано — не полагайтесь на порядок, отличный от порядка элементов в tasks[] и spec.execution.mode.

source и destination (endpoint)

Оба устроены одинаково:

type: <строка из registry>
config: { ... }   # произвольная структура под выбранный type
# только task.destination (опционально):
write_policy:
  on_conflict: fail   # fail | overwrite | create_new (дефолт: fail)

Для destination блок write_policy задаёт поведение при конфликте ключа/пути для объектов, которыми владеет iobackup: fail (по умолчанию), overwrite, create_new. В манифесте рядом с артефактом может дублироваться семантика в destination.write_policy как JSON-объект (см. docs/reference/manifest-schema.md).

Конкретные ключи config — в разделах по типам и на страницах источников / назначений.

Зарезервировано / не исполняется в v1 (0.17-fix.80)

Тема Поведение
source.type: filesystem_incremental Зарезервировано под будущий incremental pipeline — SOURCE_UNSUPPORTED (см. internal/job/model.go). Пример YAML: examples/future/filesystem-incremental-restic.yaml.
spec.repository с external_engine / content-addressed моделью Зарезервировано — исполняется только single_artifact + iobackup.
spec.operation.type: restore (и kind RestoreJob) Не исполняется в v1 — отдельный roadmap (2.3+).
Hooks / inline templates См. features.hooks и раздел hooks выше; шаблоны payload — 0.21+.
Client-side encryption features.encryption (+ features.envelope_encryption для mode: envelope). Пример: examples/future/encryption.yaml.
Scheduler / central management Нет в single-agent core; поля management/sync сейчас только в capabilities как placeholders (0.17-fix.70).

Важные defaults

Итог: по умолчанию система пытается работать строго потоково, без полного временного локального artifact-файла.

Рекомендации по секретам

Учётные данные не храните в открытом виде в job, который кладёте в Git или передаёте через незащищённые каналы. Используйте один из механизмов из раздела «Учётные данные»:

Детали, список полей по провайдерам и примеры — ниже в том же разделе.

S3-compatible: endpoint и region

Для destination.type: s3 endpoint и region задаются по тем же правилам, что и ключи: ровно один источник на каждую семантику — литерал (endpoint / region) или endpoint_env | endpoint_path | endpoint_vault или region_env | region_path | region_vault. См. Учётные данные и s3-destination.

Пример только с env:

destination:
  type: s3
  config:
    endpoint_env: S3_ENDPOINT
    region_env: S3_REGION
    bucket: iobackup
    access_key_env: S3_ACCESS_KEY
    secret_key_env: S3_SECRET_KEY

Полный обзор S3: s3-destination.

Docker fallback для tool-based provider-ов

Для postgres/mysql source и s3 destination можно явно задать runner в docker-контейнере (runner.mode: docker). Автоматического fallback с хоста в контейнер нет: при runner.mode: local используется бинарник с PATH, при ошибке нужно либо установить утилиту, либо переключить YAML на docker.

Пример (PostgreSQL):

tasks:
  - source:
      type: postgres
      config:
        dump:
          tool: pg_dump
          runner:
            mode: docker
            docker:
              image: postgres:16-alpine
              network: host
              extra_args: []
    destination:
      type: s3
      config:
        upload:
          runner:
            mode: docker
            docker:
              image: amazon/aws-cli:latest
              # или оставьте пустым, тогда используется default: amazon/aws-cli:latest
              extra_args: []

Аналогично для MySQL (mysqldump в образе клиента):

tasks:
  - source:
      type: mysql
      config:
        host: 127.0.0.1
        username: backup
        password_env: MYSQL_BACKUP_PASSWORD
        databases:
          - app
        dump:
          tool: mysqldump
          runner:
            mode: docker
            docker:
              image: mysql:8.0
              network: host
              extra_args: []
    destination:
      type: s3
      config:
        upload:
          runner:
            mode: docker
            docker:
              image: amazon/aws-cli:latest

Режим runner.mode: docker явно задаёт выполнение через контейнер (автоматического переключения с local на docker при отсутствии бинарника нет). В режиме local используется утилита с хоста; если её нет в PATH, run завершится ошибкой — тогда задайте docker или установите клиент на хост.

Поддерживаемые режимы:

Filesystem source (каталоги на хосте агента)

source.type: filesystem упаковывает один или несколько путей в один поток filesystem_backup.tar.gz (gzip+tar):

source:
  type: filesystem
  config:
    paths:
      - /var/lib/app
    include_hidden: false
    exclude:
      - "*.tmp"

Полная спецификация полей, exclude/скрытые файлы/symlinks и pre-flight: filesystem-source.

Учётные данные (*_env, *_path, *_vault)

Общие правила

Для каждого логического параметра (один пароль, один ключ API, один токен и т.д.) в YAML допускается ровно один способ доставить значение:

Суффикс Где живёт значение Как интерпретируется
..._env Процесс iobackup-agent на узле выполнения Строковое значение переменной с именем из поля (как указано в YAML). Пустое значение переменной — ошибка резолва.
..._path Локальный путь на том же узле, что и агент Файл читается целиком; результат обрезается по пробелам и хвостовым \n/\r (секрет может занимать одну строку или несколько — используется весь текст после trim). Пустое содержимое после trim — ошибка. Выставите права файла так, чтобы читать мог только нужный POSIX-пользователь агента.
..._vault Secret в Vault KV версии 2 Обращение к API выполняется клиентом Vault, настроенным на агенте, а не «произвольным» URL из job. Отдельно см. блок про два сценария Vault ниже.

Взаимоисключение: нельзя задать одновременно, например, password_env и password_vault или password_path и password_env для одной и той же роли пароля — валидация / резолвер вернут ошибку (use exactly one of *_env, *_path, or *_vault).

Plaintext в job: технически некоторые поля можно указать литералами (endpoint, region, иногда пароль в типах, где модель это допускает) — это по-прежнему плохая практика для секретов; preflight там, где включено, может предупреждать об открытых ключах. Для ключей и паролей предпочтительны триада или overlay.

Vault на агенте (для всех полей *_vault)

Клиент KV v2 создаётся в процессе агента. Задаётся один набор параметров подключения (адрес обязателен, если вы используете любой *_vault):

Ссылка в job — объект VaultKVRef (в YAML под ключом password_vault, secret_key_vault и т.д.):

password_vault:
  mount: secret       # необязательно; по умолчанию KV mount `secret`
  path: myapp/pg      # logical path внутри движка (без префикса `data/` в YAML)
  field: password     # ключ в данных секрета после чтения KV v2 (строка или нестроковое значение будет приведено к строке)

Разбор значения из Vault: выполняется KVv2(mount).Get(ctx, path); из ответа берётся поле field. Пустая строка в поле — ошибка; если поля нет в данных — ошибка.

Важно — два разных Vault в продукте:

  1. «Vault как клиент учётных данных» — адрес/token из конфига iobackup-agent. Все password_vault, access_key_vault, token_vault при обычном использовании читаются с этого кластера/адреса.
  2. source.type: vault — поле config.address задаёт Vault, из которого делается бэкап KV. Токен к этому адресу — всё так же один из token_env | token_path | token_vault; при token_vault значение токена подтягивается через клиент Vault агента (п. 1 выше). То есть KV ref для пароля Postgres и KV ref для токена в vault-source используют одну и ту же точку конфигурации клиента на агенте, если вы не запускаете отдельные агенты с разными -vault-addr.

Локальный overlay (-job-secrets-file, IOBACKUP_JOB_SECRETS_FILE)

Путь задаётся только на агенте (флаг или env). При submit и при validate агент:

  1. Декодирует тело запроса (YAML/JSON) в BackupJob.
  2. Если файл overlay задан и прочитан — сливает его в уже разобранный job до Validate / ValidateStrict / записи в store (submit).

Поведение merge (упрощённо):

Типичный шаблон: в репозитории — job без секретов; на сервере — файл /etc/iobackup/job-secrets.local.yaml только с нужными фрагментами spec.tasks[].source.config.password_path или password_vault и т.д.

Карта полей по провайдерам

Ниже — поля с суффиксами _env / _path / _vault (семантика везде «ровно один из трёх» там, где строка помечена как обязательная в спецификации провайдера).

Место в job Поля триады
source.type: postgresconfig password_*
source.type: mysqlconfig password_*
source.type: openldapconfig password_* (bind)
source.type: clickhouseconfig password_* опционально (если авторизация не используется — можно не задавать ни одного источника; при наличии — снова ровно один)
source.type: vaultconfig token_* для доступа к address этого source
destination.type: s3config access_key_*, secret_key_*; отдельно по одному источнику на семантику endpoint (endpoint литерал или endpoint_*) и region (region литерал или region_*; если регион нигде не задан — в коде по умолчанию us-east-1).
spec.notifications.webhooks[].request.auth token_* (bearer); password_* (basic); header_value_* (custom header); см. webhooks

Подробнее по S3 см. s3-destination; по vault source — vault-source; webhook auth — webhooks.

Source: PostgreSQL (postgres)

Логический дамп через pg_dump (на хосте или в Docker по dump.runner).

Обязательные поля config: host, username, ровно один из (password_env | password_path | password_vault), непустой список databases.

Поле Описание
host Хост СУБД.
port Порт (если нестандартный).
username Пользователь для дампа.
password_env Переменная окружения с паролем.
password_path Файл с паролем на агенте.
password_vault KV ref для пароля (mount/path/field).
databases Список имён БД для выгрузки.
dump.tool Обычно pg_dump.
dump.format Например custom / plain — в зависимости от версии и сценария.
dump.jobs Параллелизм, если поддерживается выбранным форматом.
dump.clean / if_exists Флаги поведения дампа.
dump.runner mode: local | docker, блок docker (image, network, extra_args).

Пример: postgres.local.yaml · YAML. Перекрёстно: Docker/runner, local destination, s3 destination.

Source: MySQL (mysql)

Логический дамп через mysqldump (на хосте или в Docker).

Обязательные поля config: host, username, один из (password_env | password_path | password_vault), непустой список databases.

Поле Описание
host / port Подключение к серверу.
username Учётка для дампа.
password_env | password_path | password_vault Ровно один источник пароля.
databases Список БД.
dump.tool Обычно mysqldump.
dump.single_transaction Консистентный снимок InnoDB.
dump.routines / triggers / events Включение объектов в дамп.
dump.master_data При необходимости для репликации.
dump.runner Как у PostgreSQL: local vs docker.

Пример: mysql.local.yaml · YAML. Перекрёстно: Docker/runner, назначения — local, s3.

Vault source (KV export)

source.type: vault поддерживает выгрузку секретов из Vault KV (v1/v2):

source:
  type: vault
  config:
    address: http://127.0.0.1:18200
    token_env: VAULT_TOKEN
    mount: iobackup
    kv_version: 2
    include_paths:
      - ""
    timeout: 30s

Минимально обязательные поля:

Подробнее: vault-source.

OpenLDAP source (directory snapshot)

source.type: openldap поддерживает snapshot LDAP directory в JSON:

source:
  type: openldap
  config:
    host: 127.0.0.1
    port: 18389
    bind_dn: cn=admin,dc=example,dc=org
    password_env: OPENLDAP_ADMIN_PASSWORD
    base_dn: dc=example,dc=org
    scope: sub
    filter: (objectClass=*)

Минимально обязательные поля:

Подробнее: openldap-source.

ClickHouse source (HTTP snapshot)

source.type: clickhouse поддерживает snapshot таблиц в JSONL:

source:
  type: clickhouse
  config:
    host: 127.0.0.1
    port: 18123
    username: default
    databases:
      - iobackup

Минимально обязательные поля:

Подробнее: clickhouse-source.

Docker Compose source (project snapshot)

source.type: docker_compose поддерживает snapshot compose-проекта:

source:
  type: docker_compose
  config:
    project_dir: /path/to/compose-project
    compose_files:
      - docker-compose.yml
    include_paths:
      - .env
    snapshot_volumes: true

Минимально обязательные поля:

Подробнее: docker-compose-source.

Auto verify после run

Можно включить автоматический verify после каждого успешного backup-run:

spec:
  policies:
    verify:
      after_run: true
      # опционально, сколько последних successful-артефактов
      # проверять по каждой task (по умолчанию 1)
      limit_per_task: 1

Поддерживаемые уровни:

Детали: verify.