openapi: 3.0.3

info:
  title: StorPool Disaster Recovery as a Service
  description: StorPool Disaster Recovery as a Service
  version: 1.1.0

servers:
  - url: 'http://localhost:8000/v1.1'

paths:
  /locations:
    get:
      summary: Get all locations
      tags:
        - Locations
      responses:
        "200":
          description: Return all locations
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/location"
              example:
                - locationName: Zone-A
                  locationId: bac3d
                - locationName: Zone-B
                  locationId: ab4cd
        "502":
          description: Could not read the locations from the storage system

  /drServiceCreate:
    post:
      summary: Create a service
      tags:
        - Service
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                vmId:
                  $ref: "#/components/schemas/vmId"
                locationId:
                  $ref: "#/components/schemas/locationId"
                drPolicyName:
                  $ref: "#/components/schemas/drPolicyName"
      responses:
        "200":
          description: The DR service has been created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  drId:
                    $ref: "#/components/schemas/drId"
        "400":
          description: An error occurred, check the response message
          content:
            application/json:
              schema:
                type: object
                properties:
                  reason:
                    type: string
                    title: The reason this request was rejected
                    example: The VM already has a DR service
                    # example: No such location

  /drService:
    get:
      summary: Obtain information about a service
      tags:
        - Service
      parameters:
        - name: drId
          in: query
          required: true
          schema:
            $ref: "#/components/schemas/drId"
      responses:
        "200":
          description: Information about the requested DR service has been returned successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/drService"
        "404":
          description: No DR service with the requested drId was found

  /drServiceUpdate:
    post:
      summary: Update a service
      tags:
        - Service
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                drId:
                  $ref: "#/components/schemas/drId"
                vmId:
                  nullable: true
                  allOf:
                  - $ref: "#/components/schemas/vmId"
                locationId:
                  nullable: true
                  allOf:
                  - $ref: "#/components/schemas/locationId"
                drPolicyName:
                  nullable: true
                  allOf:
                  - $ref: "#/components/schemas/drPolicyName"
                drState:
                  nullable: true
                  allOf:
                  - $ref: "#/components/schemas/drState"
      responses:
        "200":
          description: The DR service has been updated successfully
        "404":
          description: No DR service with the requested drId was found

  /drServiceDelete:
    post:
      summary: Delete a service
      tags:
        - Service
      parameters:
        - in: query
          name: drId
          required: true
          schema:
            $ref: "#/components/schemas/drId"
      responses:
        "200":
          description: The DR service and its recovery points have been deleted
            successfully
        "404":
          description: No DR service with the requested drId was found

  /metadata:
    get:
      summary: Get VM metadata for a recovery point
      tags:
        - VM metadata
      parameters:
        - name: recoveryPointId
          in: query
          required: true
          schema:
            $ref: "#/components/schemas/recoveryPointId"
      responses:
        "200":
          description: VM metadata from the requested snapshot has been
            returned successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  vmMetaData:
                    $ref: "#/components/schemas/vmMetaData"
        "404":
          description: No recovery point with the requested recoveryPointId was found

    post:
      summary: Update VM metadata
      tags:
        - VM metadata
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                drId:
                  $ref: "#/components/schemas/drId"
                vmMetaData:
                  $ref: "#/components/schemas/vmMetaData"
      responses:
        "200":
          description: The VM metadata has been updated successfully
        "404":
          description: No DR service with the requested drId was found

  /recoveryPointCreate:
    post:
      summary: Create a recovery point
      tags:
        - Recovery point
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                drId:
                  $ref: "#/components/schemas/drId"
      responses:
        "200":
          description: The recovery point has been created successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/recoveryPoint"
        "404":
          description: No DR service with the requested drId was found
        "409":
          description: Did not find any storage volumes for the VM of the
            DR service

  /recoveryPoint:
    get:
      summary: Obtain information about all recovery points of a DR Service
      tags:
        - Recovery point
      parameters:
        - name: drId
          in: query
          required: true
          schema:
            $ref: "#/components/schemas/drId"
      responses:
        "200":
          description: The list of all recovery points for the DR Service has been returned successfully
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/recoveryPoint"
        "404":
          description: No DR service with the requested drId was found

  /recoveryPointDelete:
    post:
      summary: Delete a recovery point
      tags:
        - Recovery point
      parameters:
        - in: query
          name: recoveryPointId
          required: true
          schema:
            $ref: "#/components/schemas/recoveryPointId"
        - in: query
          name: where
          required: true
          schema:
            $ref: "#/components/schemas/recoveryPointAvailability"
          description: |
            Indicate which copies of the recovery point should be deleted.
            Currently only local deletions are supported.
      responses:
        "200":
          description: The recovery point copy has been deleted successfully
        "404":
          description: No recovery point with the requested recoveryPointId was found

  /drRevert:
    post:
      summary: Revert a VM to a recovery point
      description: |
        Reverts a VM to a recovery point.

        An optional diskmap controls which VM disks are reverted and from
        which recovery-point disks. When diskmap is omitted, each VM disk
        is reverted from the recovery-point disk with the same label.
      tags:
        - Revert
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - vmId
                - recoveryPointId
              properties:
                vmId:
                  $ref: "#/components/schemas/vmId"
                recoveryPointId:
                  $ref: "#/components/schemas/recoveryPointId"
                locationId:
                  nullable: true
                  allOf:
                  - $ref: "#/components/schemas/locationId"
                drPolicyName:
                  nullable: true
                  allOf:
                  - $ref: "#/components/schemas/drPolicyName"
                diskmap:
                  $ref: "#/components/schemas/diskRevertMap"
            example:
              vmId: a90e2dee-fad4-405d-b75e-3ea6561d659a
              recoveryPointId: 44d4e71f-e320-4af8-a198-28a279b5994e
              diskmap:
                "1": "1"
                "2": "3"
                "4": null
      responses:
        "200":
          description: |
            The VM has been reverted to the recovery point successfully.
            If locationId and drPolicyName have been provided, the VM was
            assigned to the drId from the recovery point and the DR service was
            activated successfully.
        "400":
          description: |
            Invalid request, including malformed diskmap (non-object value,
            non-string keys, duplicate revert targets, remapping of
            vm-state, or invalid target disk labels).
        "404":
          description: No recovery point with the requested recoveryPointId was found

  /dreStatus:
    get:
      summary: Get information about all DR services and Virtual Machines
      tags:
        - Status
      responses:
        "200":
          description: Return all DR services and Virtual Machines
          content:
            application/json:
              schema:
                type: object
                properties:
                  services:
                    type: array
                    items:
                      $ref: "#/components/schemas/drService"
                  vms:
                    type: array
                    items:
                      $ref: "#/components/schemas/vmInfo"
        "502":
          description: Could not read the information from the storage system

components:
  schemas:
    locationName:
      type: string
      title: Location name
      description: |
        Human-readable name for a location.
      example: Zone-A

    locationId:
      type: string
      title: Location identifier
      description: |
        Identifier for a location.
      example: abc4

    location:
      type: object
      title: Location
      properties:
        id:
          $ref: "#/components/schemas/locationId"
        name:
          $ref: "#/components/schemas/locationName"
      example:
        locationName: Zone-A
        locationId: d2ba

    vmId:
      type: string
      title: Virtual Machine identifier
      description: |
        The unique Virtual Machine identifier across all zones.
        It shall not change during the lifetime of the Virtual Machine.
        The DR VM created at the DR site shall have a different identifier.
        A cloned VM shall have a new identifier.
      example: a90e2dee-fad4-405d-b75e-3ea6561d659a

    vmMetaData:
      type: string
      title: Virtual Machine metadata
      description: |
        Metadata for the Virtual Machine. It is not processed by the DR service.

    drId:
      type: string
      title: DR identifier
      description: |
        A unique identifier generated by the DR engine.
        It is preserved across multiple zones, when recovery points are copied
        or sent to a remote zone.
        While an identifier may have only one active VM per zone,
        it can have recovery points of many VMs from different zones.
      example: 42ae6a4c-e421-48b5-8e90-c6e83368037e

    drPolicyName:
      type: string
      pattern: '^[a-zA-z0-9_-]+$'
      title: Policy name
      description: |
        A text identifier of the DR policy.
        Only interpreted by the DR engine when DR is integrated with VolumeCare.
        Note the string pattern, spaces and most special characters are not allowed.
      example: "hourly-zone-b"

    recoveryPointAvailability:
      type: string
      title: Recovery point availability
      description: |
        The availability of the recovery point:

        "local": available only in the VM's local zone

        "remote": available only in the VM's remote zone

        "both": available in both the VM's local and remote
          zones

      example: "local"
      enum:
        - local
        - remote
        - both

    recoveryPointType:
      type: string
      title: Recovery point type
      description: |
        The type of the recovery point by means of creation:

        "scheduled": A recovery point created by the DRE according to the DR Service's policy schedule

        "on-demand": An on-demand recovery point created through the DRE's API

      example: "on-demand"
      enum:
        - scheduled
        - on-demand

    recoveryPointId:
      type: string
      title: Recovery point identifier
      description: A unique recovery point identifier generated by the DR engine.
      example: 44d4e71f-e320-4af8-a198-28a279b5994e

    recoveryPoint:
      type: object
      title: Recovery point created for a DR service
      description: |
        A recovery point to which a VM can be reverted to.
        One recovery point can have copies in multiple zone.
      properties:
        recoveryPointId:
          $ref: "#/components/schemas/recoveryPointId"
        drId:
          $ref: "#/components/schemas/drId"
        vmId:
          $ref: "#/components/schemas/vmId"
        origin:
          $ref: "#/components/schemas/locationId"
        ts:
          type: integer
          description: The timestamp when the snapshots were created
        availability:
          $ref: "#/components/schemas/recoveryPointAvailability"
        syncing:
          type: boolean
          description: Indicates if the recovery point is currently being synced
            with the remote zone.
        type:
          $ref: "#/components/schemas/recoveryPointType"

    drState:
      type: string
      title: DR service state
      description: |
        The current state of the DR service. Can be different in different zones.

        "active": There a is VM defined in this zone, and new recovery points can be
                  created.

        "paused": There is a VM defined in this zone, but creation of new
                  recovery points is temporarily suspended.

        "remote": No VM is defined in this zone. There are only recovery points
                  replicated from a remote VMs. Creation of recovery points in this
                  zone is not possible.
      enum:
        - active
        - paused
        - remote

    drService:
      type: object
      title: DR service
      properties:
        drId:
          $ref: "#/components/schemas/drId"
        state:
          allOf:
            - $ref: "#/components/schemas/drState"
          description: |
            The state of the DR service as seen in the current zone. The same DR
            service may have different states in different zones.
        vmId:
          nullable: true
          allOf:
          - $ref: "#/components/schemas/vmId"
          description: |
            The vmId of the local VM if state is "active" or "paused" and None if
            state is "remote". The vmId will be different in different zones for the
            same drId. In the typical case, the vmId will be defined in only one
            zone.
        locationId:
          nullable: true
          allOf:
          - $ref: "#/components/schemas/locationId"
          description: |
            The remote location if state is "active" or "paused". None if state is
            "remote".
        policy:
          nullable: true
          allOf:
          - $ref: "#/components/schemas/drPolicyName"

    diskRevertMap:
      type: object
      title: Disk revert map
      description: |
        Optional request field. When omitted, each VM disk uses identity mapping.

        Maps VM disk labels to recovery-point disk labels. Disk labels are the
        disk values reported by GET /dreStatus (for example "1",
        "2").

        - Key: disk label on the target VM.
        - Value: disk label in the recovery point to revert from, or null to
          skip reverting that VM disk.
        - A key not present in the map uses identity mapping (VM disk "1"
          reverts from recovery-point disk "1").
        - The vm-state disk cannot be remapped; it is always reverted
          automatically.
      additionalProperties:
        nullable: true
        type: string
      example:
        "1": "1"
        "2": "3"
        "4": null

    vmDiskInfo:
      type: object
      title: Virtual Machine disk
      properties:
        name:
          type: string
          title: The name of the disk in StorPool
          example: volume_name
        disk:
          type: string
          title: Numbering of the disk for the VM
          example: "1"

    vmInfo:
      type: object
      title: Virtual Machine
      properties:
        id:
          $ref: "#/components/schemas/vmId"
        disks:
          type: array
          items:
            $ref: "#/components/schemas/vmDiskInfo"
