openapi: "3.0.3"
info:
  title: b'nerd Backup Operator API
  description: |
    Kubernetes custom resources for Restic-based volume backups, restores, and snapshot backups.
    API group: backups.k8s.bnerd.com/v1
  version: "0.9.1"
  contact:
    name: b'nerd
    url: https://bnerd.com
    email: support@bnerd.com

servers:
  - url: "{server}/apis/backups.k8s.bnerd.com/v1"
    description: Kubernetes API server
    variables:
      server:
        default: https://kubernetes.default.svc

tags:
  - name: VolumeBackup
    description: Scheduled PVC backups via CronJobs
  - name: VolumeRestore
    description: One-time restore to new or existing PVC
  - name: VolumeSnapshotBackup
    description: OpenStack Cinder snapshot-based backups
  - name: S3Backup
    description: S3 bucket-to-repository backups

paths:
  /namespaces/{namespace}/volumebackups:
    parameters:
      - $ref: '#/components/parameters/Namespace'
    get:
      tags: [VolumeBackup]
      summary: List VolumeBackups
      operationId: listVolumeBackups
      responses:
        '200':
          description: VolumeBackup list
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VolumeBackupList'
    post:
      tags: [VolumeBackup]
      summary: Create a VolumeBackup
      operationId: createVolumeBackup
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VolumeBackup'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VolumeBackup'

  /namespaces/{namespace}/volumebackups/{name}:
    parameters:
      - $ref: '#/components/parameters/Namespace'
      - $ref: '#/components/parameters/Name'
    get:
      tags: [VolumeBackup]
      summary: Get a VolumeBackup
      operationId: getVolumeBackup
      responses:
        '200':
          description: VolumeBackup
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VolumeBackup'
    put:
      tags: [VolumeBackup]
      summary: Replace a VolumeBackup
      operationId: replaceVolumeBackup
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VolumeBackup'
      responses:
        '200':
          description: Updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VolumeBackup'
    patch:
      tags: [VolumeBackup]
      summary: Patch a VolumeBackup
      operationId: patchVolumeBackup
      requestBody:
        required: true
        content:
          application/merge-patch+json:
            schema:
              $ref: '#/components/schemas/VolumeBackup'
      responses:
        '200':
          description: Patched
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VolumeBackup'
    delete:
      tags: [VolumeBackup]
      summary: Delete a VolumeBackup
      operationId: deleteVolumeBackup
      responses:
        '200':
          description: Deleted

  /namespaces/{namespace}/volumerestores:
    parameters:
      - $ref: '#/components/parameters/Namespace'
    get:
      tags: [VolumeRestore]
      summary: List VolumeRestores
      operationId: listVolumeRestores
      responses:
        '200':
          description: VolumeRestore list
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VolumeRestoreList'
    post:
      tags: [VolumeRestore]
      summary: Create a VolumeRestore
      operationId: createVolumeRestore
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VolumeRestore'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VolumeRestore'

  /namespaces/{namespace}/volumerestores/{name}:
    parameters:
      - $ref: '#/components/parameters/Namespace'
      - $ref: '#/components/parameters/Name'
    get:
      tags: [VolumeRestore]
      summary: Get a VolumeRestore
      operationId: getVolumeRestore
      responses:
        '200':
          description: VolumeRestore
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VolumeRestore'
    put:
      tags: [VolumeRestore]
      summary: Replace a VolumeRestore
      operationId: replaceVolumeRestore
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VolumeRestore'
      responses:
        '200':
          description: Updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VolumeRestore'
    delete:
      tags: [VolumeRestore]
      summary: Delete a VolumeRestore
      operationId: deleteVolumeRestore
      responses:
        '200':
          description: Deleted

  /namespaces/{namespace}/volumesnapshotbackups:
    parameters:
      - $ref: '#/components/parameters/Namespace'
    get:
      tags: [VolumeSnapshotBackup]
      summary: List VolumeSnapshotBackups
      operationId: listVolumeSnapshotBackups
      responses:
        '200':
          description: VolumeSnapshotBackup list
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VolumeSnapshotBackupList'
    post:
      tags: [VolumeSnapshotBackup]
      summary: Create a VolumeSnapshotBackup
      operationId: createVolumeSnapshotBackup
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VolumeSnapshotBackup'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VolumeSnapshotBackup'

  /namespaces/{namespace}/volumesnapshotbackups/{name}:
    parameters:
      - $ref: '#/components/parameters/Namespace'
      - $ref: '#/components/parameters/Name'
    get:
      tags: [VolumeSnapshotBackup]
      summary: Get a VolumeSnapshotBackup
      operationId: getVolumeSnapshotBackup
      responses:
        '200':
          description: VolumeSnapshotBackup
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VolumeSnapshotBackup'
    put:
      tags: [VolumeSnapshotBackup]
      summary: Replace a VolumeSnapshotBackup
      operationId: replaceVolumeSnapshotBackup
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VolumeSnapshotBackup'
      responses:
        '200':
          description: Updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VolumeSnapshotBackup'
    delete:
      tags: [VolumeSnapshotBackup]
      summary: Delete a VolumeSnapshotBackup
      operationId: deleteVolumeSnapshotBackup
      responses:
        '200':
          description: Deleted

  /namespaces/{namespace}/s3backups:
    parameters:
      - $ref: '#/components/parameters/Namespace'
    get:
      tags: [S3Backup]
      summary: List S3Backups
      operationId: listS3Backups
      responses:
        '200':
          description: S3Backup list
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/S3BackupList'
    post:
      tags: [S3Backup]
      summary: Create an S3Backup
      operationId: createS3Backup
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/S3Backup'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/S3Backup'

  /namespaces/{namespace}/s3backups/{name}:
    parameters:
      - $ref: '#/components/parameters/Namespace'
      - $ref: '#/components/parameters/Name'
    get:
      tags: [S3Backup]
      summary: Get an S3Backup
      operationId: getS3Backup
      responses:
        '200':
          description: S3Backup
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/S3Backup'
    put:
      tags: [S3Backup]
      summary: Replace an S3Backup
      operationId: replaceS3Backup
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/S3Backup'
      responses:
        '200':
          description: Updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/S3Backup'
    delete:
      tags: [S3Backup]
      summary: Delete an S3Backup
      operationId: deleteS3Backup
      responses:
        '200':
          description: Deleted

components:
  parameters:
    Namespace:
      name: namespace
      in: path
      required: true
      schema:
        type: string
    Name:
      name: name
      in: path
      required: true
      schema:
        type: string

  schemas:
    # --- Shared schemas ---

    ObjectMeta:
      type: object
      properties:
        name:
          type: string
        namespace:
          type: string
        labels:
          type: object
          additionalProperties:
            type: string
        annotations:
          type: object
          additionalProperties:
            type: string
        creationTimestamp:
          type: string
          format: date-time

    LocalObjectReference:
      type: object
      required: [name]
      properties:
        name:
          type: string
        namespace:
          type: string

    SecretReference:
      type: object
      required: [name]
      properties:
        name:
          type: string
        namespace:
          type: string

    RepositorySpec:
      type: object
      required: [type, url, secretRef]
      properties:
        type:
          type: string
          enum: [s3, gcs, azure, local, sftp, rest]
          description: Repository backend type
        url:
          type: string
          description: "Repository URL (e.g., s3:bucket/path)"
        secretRef:
          $ref: '#/components/schemas/SecretReference'

    RetentionSpec:
      type: object
      properties:
        keepLast:
          type: integer
          minimum: 1
          description: Keep the N most recent snapshots
        keepDaily:
          type: integer
          minimum: 0
          description: Keep daily snapshots for N days
        keepWeekly:
          type: integer
          minimum: 0
          description: Keep weekly snapshots for N weeks
        keepMonthly:
          type: integer
          minimum: 0
          description: Keep monthly snapshots for N months
        keepYearly:
          type: integer
          minimum: 0
          description: Keep yearly snapshots for N years

    CacheSpec:
      type: object
      properties:
        enabled:
          type: boolean
          default: true
        size:
          type: string
          default: "5Gi"
        storageClass:
          type: string
        accessMode:
          type: string
          default: "ReadWriteOnce"

    ResourceRequirements:
      type: object
      properties:
        requests:
          type: object
          properties:
            memory:
              type: string
              default: "256Mi"
            cpu:
              type: string
              default: "200m"
        limits:
          type: object
          properties:
            memory:
              type: string
              default: "1Gi"
            cpu:
              type: string
              default: "1000m"

    ImageSpec:
      type: object
      properties:
        repository:
          type: string
          default: "registry.bnerd.com/public/restic"
        tag:
          type: string
          default: "0.18.1"
        pullPolicy:
          type: string
          enum: [Always, IfNotPresent, Never]
          default: "Always"

    KubeconfigSpec:
      type: object
      properties:
        inCluster:
          type: boolean
          default: true
        secretRef:
          type: object
          required: [name]
          properties:
            name:
              type: string
            namespace:
              type: string
            key:
              type: string
              default: "kubeconfig"

    CheckSpec:
      type: object
      properties:
        enabled:
          type: boolean
          default: false
        schedule:
          type: string
          default: "0 4 * * *"
        readDataSubset:
          type: string
          default: "10%"
        resources:
          $ref: '#/components/schemas/ResourceRequirements'

    RestoreTestSpec:
      type: object
      properties:
        enabled:
          type: boolean
          default: false
        schedule:
          type: string
          default: "0 5 * * *"
        storage:
          type: object
          properties:
            type:
              type: string
              enum: [emptyDir, pvc]
              default: emptyDir
            size:
              type: string
              default: "5Gi"
            storageClass:
              type: string
        fileCount:
          type: integer
          default: 50
          minimum: 1
          maximum: 500
        verifyChecksums:
          type: boolean
          default: true
        resources:
          $ref: '#/components/schemas/ResourceRequirements'

    WebhookSpec:
      type: object
      properties:
        success:
          type: string
          description: URL to POST on success
        failure:
          type: string
          description: URL to POST on failure

    JobConfigSpec:
      type: object
      properties:
        keepSuccessfulJobs:
          type: integer
          default: 3
          minimum: 0
          maximum: 10
        keepFailedJobs:
          type: integer
          default: 3
          minimum: 0
          maximum: 10

    Toleration:
      type: object
      properties:
        key:
          type: string
        operator:
          type: string
          enum: [Exists, Equal]
        value:
          type: string
        effect:
          type: string
          enum: [NoSchedule, PreferNoSchedule, NoExecute]
        tolerationSeconds:
          type: integer

    Condition:
      type: object
      properties:
        type:
          type: string
        status:
          type: string
        lastTransitionTime:
          type: string
          format: date-time
        reason:
          type: string
        message:
          type: string

    # --- VolumeBackup ---

    VolumeBackup:
      type: object
      properties:
        apiVersion:
          type: string
          example: "backups.k8s.bnerd.com/v1"
        kind:
          type: string
          example: "VolumeBackup"
        metadata:
          $ref: '#/components/schemas/ObjectMeta'
        spec:
          $ref: '#/components/schemas/VolumeBackupSpec'
        status:
          $ref: '#/components/schemas/VolumeBackupStatus'

    VolumeBackupList:
      type: object
      properties:
        apiVersion:
          type: string
        kind:
          type: string
          example: "VolumeBackupList"
        items:
          type: array
          items:
            $ref: '#/components/schemas/VolumeBackup'

    VolumeBackupSpec:
      type: object
      required: [volumeClaimRef, repository]
      properties:
        volumeClaimRef:
          $ref: '#/components/schemas/LocalObjectReference'
        schedule:
          type: string
          default: "0 3 * * *"
          example: "0 3 * * *"
        repository:
          $ref: '#/components/schemas/RepositorySpec'
        paths:
          type: array
          items:
            type: string
          default: ["/"]
        exclude:
          type: array
          items:
            type: string
        host:
          type: string
          description: "Defaults to {namespace}-{volumename}"
        retention:
          $ref: '#/components/schemas/RetentionSpec'
        cache:
          $ref: '#/components/schemas/CacheSpec'
        resources:
          $ref: '#/components/schemas/ResourceRequirements'
        image:
          $ref: '#/components/schemas/ImageSpec'
        kubeconfig:
          $ref: '#/components/schemas/KubeconfigSpec'
        suspended:
          type: boolean
          default: false
        check:
          $ref: '#/components/schemas/CheckSpec'
        restoreTest:
          $ref: '#/components/schemas/RestoreTestSpec'
        webhooks:
          $ref: '#/components/schemas/WebhookSpec'
        nodeSelector:
          type: object
          additionalProperties:
            type: string
        tolerations:
          type: array
          items:
            $ref: '#/components/schemas/Toleration'
        affinity:
          type: object
          description: Kubernetes affinity rules
        jobConfig:
          $ref: '#/components/schemas/JobConfigSpec'

    VolumeBackupStatus:
      type: object
      properties:
        phase:
          type: string
          enum: [Pending, Running, Succeeded, Failed]
        lastBackup:
          type: string
          format: date-time
        lastSnapshot:
          type: string
        message:
          type: string
        volumeSize:
          type: string
        conditions:
          type: array
          items:
            $ref: '#/components/schemas/Condition'

    # --- VolumeRestore ---

    VolumeRestore:
      type: object
      properties:
        apiVersion:
          type: string
          example: "backups.k8s.bnerd.com/v1"
        kind:
          type: string
          example: "VolumeRestore"
        metadata:
          $ref: '#/components/schemas/ObjectMeta'
        spec:
          $ref: '#/components/schemas/VolumeRestoreSpec'
        status:
          $ref: '#/components/schemas/VolumeRestoreStatus'

    VolumeRestoreList:
      type: object
      properties:
        apiVersion:
          type: string
        kind:
          type: string
          example: "VolumeRestoreList"
        items:
          type: array
          items:
            $ref: '#/components/schemas/VolumeRestore'

    VolumeRestoreSpec:
      type: object
      required: [targetPVC]
      properties:
        sourceBackup:
          type: object
          properties:
            volumeBackupRef:
              $ref: '#/components/schemas/LocalObjectReference'
            snapshotId:
              type: string
            snapshotDate:
              type: string
              format: date-time
        sourceRepository:
          type: object
          required: [type, url, secretRef]
          properties:
            type:
              type: string
              enum: [s3, gcs, azure, local, sftp, rest]
            url:
              type: string
            secretRef:
              $ref: '#/components/schemas/SecretReference'
            host:
              type: string
            snapshotId:
              type: string
            snapshotDate:
              type: string
              format: date-time
        targetPVC:
          type: object
          properties:
            createNew:
              type: boolean
              default: true
            name:
              type: string
            storageClass:
              type: string
            size:
              type: string
            accessMode:
              type: string
              default: "ReadWriteOnce"
            annotations:
              type: object
              additionalProperties:
                type: string
            labels:
              type: object
              additionalProperties:
                type: string
        restoreSpec:
          type: object
          properties:
            paths:
              type: array
              items:
                type: string
              default: ["/"]
            exclude:
              type: array
              items:
                type: string
            targetPath:
              type: string
              default: "/"
            overwrite:
              type: string
              enum: [always, if-changed, if-newer, never]
              default: "always"
        jobConfig:
          type: object
          properties:
            retries:
              type: integer
              default: 3
              minimum: 0
              maximum: 10
            backoffLimit:
              type: integer
              default: 6
              minimum: 0
            activeDeadlineSeconds:
              type: integer
              minimum: 1
            keepSuccessfulJobs:
              type: integer
              default: 3
              minimum: 0
              maximum: 10
            keepFailedJobs:
              type: integer
              default: 3
              minimum: 0
              maximum: 10
        resources:
          $ref: '#/components/schemas/ResourceRequirements'
        image:
          $ref: '#/components/schemas/ImageSpec'
        kubeconfig:
          $ref: '#/components/schemas/KubeconfigSpec'
        nodeSelector:
          type: object
          additionalProperties:
            type: string
        tolerations:
          type: array
          items:
            $ref: '#/components/schemas/Toleration'
        affinity:
          type: object

    VolumeRestoreStatus:
      type: object
      properties:
        phase:
          type: string
          enum: [Pending, Running, Succeeded, Failed, Retrying]
        startTime:
          type: string
          format: date-time
        completionTime:
          type: string
          format: date-time
        duration:
          type: string
        message:
          type: string
        progress:
          type: object
          properties:
            filesTotal:
              type: integer
            filesRestored:
              type: integer
            bytesTotal:
              type: integer
              format: int64
            bytesRestored:
              type: integer
              format: int64
            percentComplete:
              type: number
              minimum: 0
              maximum: 100
        sourceInfo:
          type: object
          properties:
            snapshotId:
              type: string
            snapshotDate:
              type: string
              format: date-time
            repository:
              type: string
            host:
              type: string
            paths:
              type: array
              items:
                type: string
        targetInfo:
          type: object
          properties:
            pvcName:
              type: string
            pvcNamespace:
              type: string
            storageClass:
              type: string
            size:
              type: string
            created:
              type: boolean
        jobInfo:
          type: object
          properties:
            currentJob:
              type: string
            attempt:
              type: integer
            totalAttempts:
              type: integer
            jobHistory:
              type: array
              items:
                type: object
                properties:
                  jobName:
                    type: string
                  attempt:
                    type: integer
                  phase:
                    type: string
                  startTime:
                    type: string
                    format: date-time
                  completionTime:
                    type: string
                    format: date-time
                  message:
                    type: string
        conditions:
          type: array
          items:
            $ref: '#/components/schemas/Condition'

    # --- VolumeSnapshotBackup ---

    VolumeSnapshotBackup:
      type: object
      properties:
        apiVersion:
          type: string
          example: "backups.k8s.bnerd.com/v1"
        kind:
          type: string
          example: "VolumeSnapshotBackup"
        metadata:
          $ref: '#/components/schemas/ObjectMeta'
        spec:
          $ref: '#/components/schemas/VolumeSnapshotBackupSpec'
        status:
          $ref: '#/components/schemas/VolumeSnapshotBackupStatus'

    VolumeSnapshotBackupList:
      type: object
      properties:
        apiVersion:
          type: string
        kind:
          type: string
          example: "VolumeSnapshotBackupList"
        items:
          type: array
          items:
            $ref: '#/components/schemas/VolumeSnapshotBackup'

    VolumeSnapshotBackupSpec:
      type: object
      required: [volumeClaimRef, repository]
      properties:
        volumeClaimRef:
          $ref: '#/components/schemas/LocalObjectReference'
        openstack:
          type: object
          properties:
            credentialsSecretRef:
              $ref: '#/components/schemas/SecretReference'
            region:
              type: string
            autoDiscover:
              type: boolean
              default: true
        snapshot:
          type: object
          properties:
            force:
              type: boolean
              default: true
            timeout:
              type: integer
              default: 600
            namePrefix:
              type: string
              default: "backup"
            retention:
              type: object
              properties:
                keepLast:
                  type: integer
                  default: 3
                keepForDays:
                  type: integer
                  default: 7
        temporaryVolume:
          type: object
          properties:
            storageClass:
              type: string
            timeout:
              type: integer
              default: 300
        repository:
          $ref: '#/components/schemas/RepositorySpec'
        host:
          type: string
        paths:
          type: array
          items:
            type: string
          default: ["/"]
        exclude:
          type: array
          items:
            type: string
        retention:
          $ref: '#/components/schemas/RetentionSpec'
        cache:
          type: object
          properties:
            enabled:
              type: boolean
              default: false
            size:
              type: string
              default: "1Gi"
            storageClass:
              type: string
        resources:
          type: object
          properties:
            requests:
              type: object
              properties:
                memory:
                  type: string
                  default: "256Mi"
                cpu:
                  type: string
                  default: "200m"
            limits:
              type: object
              properties:
                memory:
                  type: string
                  default: "2Gi"
                cpu:
                  type: string
                  default: "2000m"
        image:
          type: object
          properties:
            repository:
              type: string
              default: "registry.bnerd.com/public/restic"
            tag:
              type: string
              default: "0.18.1"
            pullPolicy:
              type: string
              default: "IfNotPresent"
        nodeSelector:
          type: object
          additionalProperties:
            type: string
        tolerations:
          type: array
          items:
            $ref: '#/components/schemas/Toleration'
        affinity:
          type: object

    VolumeSnapshotBackupStatus:
      type: object
      properties:
        phase:
          type: string
          enum: [Pending, CreatingSnapshot, CreatingVolume, Backup, Cleanup, Succeeded, Failed]
        message:
          type: string
        currentSnapshot:
          type: object
          properties:
            id:
              type: string
            name:
              type: string
            cinderVolumeId:
              type: string
            status:
              type: string
            createdAt:
              type: string
            sizeGB:
              type: integer
        temporaryVolume:
          type: object
          properties:
            pvcName:
              type: string
            pvName:
              type: string
            cinderVolumeId:
              type: string
            status:
              type: string
        backupJob:
          type: object
          properties:
            name:
              type: string
            status:
              type: string
            startTime:
              type: string
            completionTime:
              type: string
        lastBackup:
          type: object
          properties:
            timestamp:
              type: string
            status:
              type: string
            duration:
              type: string

    # --- S3Backup ---

    S3Backup:
      type: object
      properties:
        apiVersion:
          type: string
          example: "backups.k8s.bnerd.com/v1"
        kind:
          type: string
          example: "S3Backup"
        metadata:
          $ref: '#/components/schemas/ObjectMeta'
        spec:
          $ref: '#/components/schemas/S3BackupSpec'
        status:
          $ref: '#/components/schemas/S3BackupStatus'

    S3BackupList:
      type: object
      properties:
        apiVersion:
          type: string
        kind:
          type: string
          example: "S3BackupList"
        items:
          type: array
          items:
            $ref: '#/components/schemas/S3Backup'

    S3BackupSpec:
      type: object
      required: [source, repository]
      properties:
        source:
          type: object
          required: [endpoint, bucket, secretRef]
          properties:
            endpoint:
              type: string
              description: "S3 endpoint URL"
              example: "https://s3.eu-central-1.amazonaws.com"
            bucket:
              type: string
              description: Source bucket name
            prefix:
              type: string
              description: Only back up objects under this prefix
            region:
              type: string
            usePathStyle:
              type: boolean
              default: true
            noCheckBucket:
              type: boolean
              default: false
            secretRef:
              $ref: '#/components/schemas/SecretReference'
        schedule:
          type: string
          default: "0 3 * * *"
        repository:
          $ref: '#/components/schemas/RepositorySpec'
        host:
          type: string
          description: "Defaults to {namespace}-{bucket}"
        exclude:
          type: array
          items:
            type: string
        retention:
          $ref: '#/components/schemas/RetentionSpec'
        cache:
          $ref: '#/components/schemas/CacheSpec'
        resources:
          $ref: '#/components/schemas/ResourceRequirements'
        image:
          $ref: '#/components/schemas/ImageSpec'
        suspended:
          type: boolean
          default: false
        check:
          $ref: '#/components/schemas/CheckSpec'
        restoreTest:
          $ref: '#/components/schemas/RestoreTestSpec'
        webhooks:
          $ref: '#/components/schemas/WebhookSpec'
        nodeSelector:
          type: object
          additionalProperties:
            type: string
        tolerations:
          type: array
          items:
            $ref: '#/components/schemas/Toleration'
        affinity:
          type: object
        jobConfig:
          $ref: '#/components/schemas/JobConfigSpec'

    S3BackupStatus:
      type: object
      properties:
        phase:
          type: string
          enum: [Pending, Running, Succeeded, Failed]
        lastBackup:
          type: string
          format: date-time
        lastSnapshot:
          type: string
        message:
          type: string
        conditions:
          type: array
          items:
            $ref: '#/components/schemas/Condition'
