# NOTE: Do not upgrade past Swagger 2. zclient does not support OpenAPI 3 unless
# https://github.com/Yelp/bravado/issues/306 is resolved.
swagger: "2.0"
info:
  description: "Pipedream scheduling microservice"
  version: "1.0.0"
  title: "scheduling"
  contact:
    name: "Infra"
    email: "infrateam@zoox.com"
    url: "https://git.zooxlabs.com/zooxco/driving"
# https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md
basePath: "/v1"
paths:
  /pipedef/{name}:
    get:
      summary: "Get a PipeDef by name. NOTE: Deprecated."
      produces:
        - "application/json"
      parameters:
        - in: "path"
          name: "name"
          type: "string"
          required: true
        - in: "query"
          name: "version_num"
          type: "integer"
      responses:
        "200":
          description: "PipeDef"
          schema:
            $ref: "#/definitions/PipeDef"
        "400":
          description: "Bad request."
          schema:
            $ref: "#/definitions/ErrorResponse"
        "404":
          description: "Not found."
          schema:
            $ref: "#/definitions/ErrorResponse"
        "500":
          description: "Internal server error."
          schema:
            $ref: "#/definitions/ErrorResponse"

  /pipeline:
    post:
      summary: "Schedule a pipeline with an optional recurring schedule."
      consumes:
        - "application/json"
      produces:
        - "application/json"
      parameters:
        - $ref: "#/parameters/Authorization"
        - in: "body"
          name: "scheduledPipedef"
          description: "Parameters to schedule pipeline."
          schema:
            $ref: "#/definitions/ScheduledPipeDef"
      responses:
        "201":
          description: "Pipeline created!"
          schema:
            $ref: "#/definitions/PipeIdResponse"
        "400":
          description: "Bad request."
          schema:
            $ref: "#/definitions/ErrorResponse"
        "403":
          description: "Forbidden."
          schema:
            $ref: "#/definitions/ErrorResponse"
        "404":
          description: "Not found."
          schema:
            $ref: "#/definitions/ErrorResponse"
        "500":
          description: "Internal server error."
          schema:
            $ref: "#/definitions/ErrorResponse"

  /pipeline/{pipeId}:
    patch:
      summary: "Cancel a pipeline or stages"
      consumes:
        - "application/json"
      produces:
        - "application/json"
      parameters:
        - in: "path"
          name: "pipeId"
          type: "string"
          required: true
        - in: "body"
          name: "cancelPipeline"
          schema:
            $ref: "#/definitions/CancelPipelineRequest"
      responses:
        "200":
          description: "Success"
          schema:
            $ref: "#/definitions/PipeIdResponse"
        "400":
          description: "Bad request."
          schema:
            $ref: "#/definitions/ErrorResponse"
        "403":
          description: "Forbidden."
          schema:
            $ref: "#/definitions/ErrorResponse"
        "404":
          description: "Not found."
          schema:
            $ref: "#/definitions/ErrorResponse"
        "500":
          description: "Internal server error."
          schema:
            $ref: "#/definitions/ErrorResponse"

  /pipeline/{pipeId}/retry_pipedef:
    get:
      summary: "Get a PipeDef (pipeline definition) to retry this pipeline."
      description: |
        "There are several types of retry PipeDefs that can be returned by this
        endpoint, depending on the parameters provided.

        Retry pipeline:
        * Required params: pipeId
        * In this case, the entire pipeline is retried.

        Retry pipeline failed stages:
        * Required params: pipeId, only_retry_failed_stages
        * Only the minimal set of stages to achieve the intended completed pipeline will be rerun.
        * For parallel tasks within a given stage, only failed tasks will be rerun.
        * Failed pipelines will have their parameters propagated into rerun pipelines accordingly.

        Retry stage:
        * Required params: pipeId, stage_name
        * In this case, the given stage is retried.

        Retry tasks:
        * Required params: pipeId, stage_name, stage_tasks
        * In this case, a just the list of tasks in a given stage are retried.

        It is the responsibility of the client to schedule the pipeline."
      produces:
        - "application/json"
      parameters:
        - in: "path"
          name: "pipeId"
          type: "string"
          required: true
        - in: "query"
          name: "only_retry_failed_stages"
          description: |
            "If this parameter is true, returns a PipeDef that only retries the failed
            jobs in a pipeline.
            NOTE: Only one of only_retry_failed_stages, and stage_name should be provided."
          type: "boolean"
        - in: "query"
          name: "stage_name"
          description: |
            "If this parameter is provided, only this stage will be retried.
            NOTE: Only one of only_retry_failed_stages, and stage_name should be provided."
          type: "string"
        - in: "query"
          name: "stage_tasks"
          description: |
            "A list of task IDs in a stage.
            NOTE: stage_name must be provided if stage_tasks is provided."
          type: "array"
          items:
            type: "integer"
      responses:
        "200":
          description: "PipeDef"
          schema:
            $ref: "#/definitions/PipeDef"
        "400":
          description: "Bad request."
          schema:
            $ref: "#/definitions/ErrorResponse"
        "404":
          description: "Not found."
          schema:
            $ref: "#/definitions/ErrorResponse"
        "500":
          description: "Internal server error."
          schema:
            $ref: "#/definitions/ErrorResponse"

definitions:
  ErrorResponse:
    type: "object"
    properties:
      message:
        type: "string"

  PipeIdResponse:
    type: "object"
    properties:
      pipeId:
        type: "string"
      piperUrl:
        type: "string"

  CancelPipelineRequest:
    type: "object"
    properties:
      operation:
        type: "string"
        enum: ["cancel_pipeline", "cancel_stages", "cancel_task"]
      stages:
        description: "Stage indexes to cancel if the operation is cancel_stages."
        type: "array"
        items:
          type: "integer"
    required:
      - "operation"

  PipeDef:
    type: "object"
    description: |
            "A PipeDef is a definition of the pipeline you want to run on
            pipedream.
            NOTE: This is validated internally by the scheduler.
            See pipedream/proto/job.proto for the definition.
            If the PipeDef is invalid, a 400 response will be returned."

  ScheduledPipeDef:
    type: "object"
    description: "A pipedef and (optional) recurring schedule to be launched as a pipeline."
    properties:
      pipedef:
        $ref: "#/definitions/PipeDef"
      schedule:
        type: "string"
        description: |
          "An optional cron expresion.
          Describes the timetable for a recurring job.
          See https://dkron.io/usage/cron-spec/#cron-expression-format
          for an extensive guide on all possible values for this field."
      context:
        type: "object"
        description: "Additional context for scheduling the pipeline."
    required:
      - "pipedef"

parameters:
  Authorization:
    in: "header"
    name: "Authorization"
    description: |
      "Authorization header should include user or vault token,
      e.g. sudo user=foo,vault wrapped_token=12345."
    type: "string"
    pattern: '^(sudo user=(\S+)|vault wrapped_token=(\S+))(,(sudo user=(\S+)|vault wrapped_token=(\S+)))?$'
