swagger: '2.0'
info:
  title: fn
  description: The open source serverless platform.
  version: "2.0.0"
# the domain of the service
host: "127.0.0.1:8080"
# array of all schemes that your API supports
schemes:
  - https
  - http
# will be prefixed to all paths
basePath: /v2

consumes:
  - application/json
produces:
  - application/json
paths:
  /apps:
    get:
      operationId: "ListApps"
      summary: "Get A List Of Applications"
      description: "Get a filtered list of Applications in alphabetical order."
      tags:
        - Apps
      parameters:
        - $ref: '#/parameters/cursor'
        - $ref: '#/parameters/perPage'
        - name: name
          in: query
          description: "The Application name to filter by."
          required: false
          type: string
      responses:
        200:
          description: "A list of Applications."
          schema:
            $ref: '#/definitions/AppList'
        default:
          description: "An unexpected error occurred."
          schema:
            $ref: '#/definitions/Error'
    post:
      operationId: "CreateApp"
      summary: "Create A New Application"
      description: "Creates a new Application, returning the complete entity."
      tags:
        - Apps
      parameters:
        - name: body
          in: body
          description: "Application data to insert."
          required: true
          schema:
            $ref: '#/definitions/App'
      responses:
        200:
          description: "Application details and stats."
          schema:
            $ref: '#/definitions/App'
        400:
          description: "Parameters are missing or invalid."
          schema:
            $ref: '#/definitions/Error'
        409:
          description: "Application with name already exists."
          schema:
            $ref: '#/definitions/Error'
        default:
          description: "An unexpected error occurred."
          schema:
            $ref: '#/definitions/Error'

  /apps/{appID}:
    delete:
      operationId: "DeleteApp"
      summary: "Delete An Application"
      description: "Delete the specified Application."
      tags:
        - Apps
      parameters:
         - $ref: '#/parameters/AppID'
      responses:
        204:
          description: "Application successfully deleted."
        404:
          description: "Application does not exist."
          schema:
            $ref: '#/definitions/Error'
        default:
          description: "An unexpected error occurred."
          schema:
            $ref: '#/definitions/Error'
    get:
      operationId: "GetApp"
      summary: "Get Information For An Application"
      description: "Returns more details about an Application, such as statistics."
      tags:
        - Apps
      parameters:
        - $ref: '#/parameters/AppID'
      responses:
        200:
          description: "Application details and stats."
          schema:
            $ref: '#/definitions/App'
        404:
          description: "The Application does not exist."
          schema:
            $ref: '#/definitions/Error'
        default:
          description: "An unexpected error occurred."
          schema:
            $ref: '#/definitions/Error'
    put:
      operationId: "UpdateApp"
      summary: "Update an Application"
      description: "Updates an Application via merging the provided values."
      tags:
        - Apps
      parameters:
        - $ref: '#/parameters/AppID'
        - name: body
          in: body
          description: "Application data to merge with current values."
          required: true
          schema:
            $ref: '#/definitions/App'
      responses:
        200:
          description: "Application details and stats."
          schema:
            $ref: '#/definitions/App'
        400:
          description: "Parameters are missing or invalid."
          schema:
            $ref: '#/definitions/Error'
        404:
          description: "The Application does not exist."
          schema:
            $ref: '#/definitions/Error'
        default:
          description: "An unexpected error occurred."
          schema:
            $ref: '#/definitions/Error'

  /fns:
    get:
      operationId: "ListFns"
      summary: "Get A list Of Functions Within An Application"
      description: "Get a filtered list of Functions for an Application, in alphabetical order."
      tags:
        - Fns
      parameters:
        - $ref: '#/parameters/AppIDQuery'
        - $ref: '#/parameters/cursor'
        - $ref: '#/parameters/perPage'
        - name: name
          in: query
          description: "Function name to filter by"
          required: false
          type: string
      responses:
        200:
          description: "List of Functions."
          schema:
            $ref: '#/definitions/FnList'
        default:
          description: "Error"
          schema:
            $ref: '#/definitions/Error'
    post:
      operationId: "CreateFn"
      summary: "Create A New Function"
      description: "Creates a new Function, returning the complete entity."
      tags:
        - Fns
      parameters:
        - name: body
          in: body
          description: "Function data to insert."
          required: true
          schema:
            $ref: '#/definitions/Fn'
      responses:
        200:
          description: "Function details."
          schema:
            $ref: '#/definitions/Fn'
        409:
          description: "Function with name already exists."
          schema:
             $ref: '#/definitions/Error'
        400:
          description: "Invalid Function."
          schema:
            $ref: '#/definitions/Error'
        default:
          description: "An unexpected error occurred."
          schema:
            $ref: '#/definitions/Error'

  /fns/{fnID}:
    delete:
      operationId: "DeleteFn"
      summary: "Delete A Function"
      description: "Delete the specified Function."
      tags:
        - Fns
      parameters:
        - $ref: '#/parameters/FnID'
      responses:
        204:
          description: "Function successfully deleted."
        404:
          description: "Function does not exist."
          schema:
            $ref: '#/definitions/Error'
        default:
          description: "Error"
          schema:
            $ref: '#/definitions/Error'
    get:
      operationId: "GetFn"
      summary: "Get Definition Of A Function"
      description: "Gets the definition for the Function with the specified ID."
      tags:
        - Fns
      parameters:
        - $ref: '#/parameters/FnID'
      responses:
        200:
          description: "Function definition"
          schema:
            $ref: '#/definitions/Fn'
        404:
          description: "Function does not exist."
          schema:
            $ref: '#/definitions/Error'
        default:
          description: "Error"
          schema:
            $ref: '#/definitions/Error'
    put:
      operationId: "UpdateFn"
      summary: "Update A Function"
      description: "Updates a Function via merging the provided values."
      tags:
        - Fns
      parameters:
        - $ref: '#/parameters/FnID'
        - name: body
          in: body
          description: "Function data to merge with current values."
          required: true
          schema:
            $ref: '#/definitions/Fn'
      responses:
        200:
          description: "Updated Function metadata."
          schema:
            $ref: '#/definitions/Fn'
        400:
          description: "Parameters are missing or invalid."
          schema:
            $ref: '#/definitions/Error'
        404:
          description: "The Function does not exist."
          schema:
            $ref: '#/definitions/Error'
        default:
          description: "An unexpected error occurred."
          schema:
            $ref: '#/definitions/Error'

  /triggers:
    get:
      operationId: "ListTriggers"
      summary: "Get A List Of Triggers Within An Application Or Function"
      description: "This will list all Triggers for a particular Application or Function, returned in name alphabetical order."
      tags:
        - Triggers
      parameters:
        - $ref: '#/parameters/AppIDQuery'
        - $ref: '#/parameters/FnIDQuery'
        - $ref: '#/parameters/cursor'
        - $ref: '#/parameters/perPage'
        - name: name
          in: query
          description: "A Trigger name to filter by."
          required: false
          type: string
      responses:
        200:
          description: "List of Triggers"
          schema:
            $ref: '#/definitions/TriggerList'
        default:
          description: "An unexpected error occurred."
          schema:
            $ref: '#/definitions/Error'
    post:
      operationId: "CreateTrigger"
      summary: "Create A New Trigger."
      description: "Creates a new Trigger, returning the complete entity."
      tags:
        - Triggers
      parameters:
        - name: body
          in: body
          description: "Trigger data to insert."
          required: true
          schema:
            $ref: '#/definitions/Trigger'
      responses:
        200:
          description: "Trigger details."
          schema:
            $ref: '#/definitions/Trigger'
        409:
          description: "Trigger with name already exists."
          schema:
             $ref: '#/definitions/Error'
        400:
          description: "Invalid Trigger."
          schema:
            $ref: '#/definitions/Error'
        default:
          description: "An unexpected error occurred."
          schema:
            $ref: '#/definitions/Error'

  /triggers/{triggerID}:
    delete:
      operationId: "DeleteTrigger"
      summary: "Delete A Trigger"
      description: "Delete the specified Trigger."
      tags:
        - Triggers
      parameters:
        - $ref: '#/parameters/TriggerID'
      responses:
        204:
          description: "Trigger successfully deleted."
        404:
          description: "The Trigger does not exist."
          schema:
            $ref: '#/definitions/Error'
        default:
          description: "An unexpected error occurred."
          schema:
            $ref: '#/definitions/Error'
    get:
      operationId: "GetTrigger"
      summary: "Get Definition Of A Trigger"
      description: "Gets the definition for the Trigger with the specified ID."
      tags:
        - Triggers
      parameters:
        - $ref: '#/parameters/TriggerID'
      responses:
        200:
          description: "Trigger information"
          schema:
            $ref: '#/definitions/Trigger'
        404:
          description: "The Trigger does not exist."
          schema:
            $ref: '#/definitions/Error'
        default:
          description: "An unexpected error occurred."
          schema:
            $ref: '#/definitions/Error'
    put:
      operationId: "UpdateTrigger"
      summary: "Update A Trigger"
      description: "Updates a Trigger by merging the provided values."
      tags:
        - Triggers
      parameters:
        - $ref: '#/parameters/TriggerID'
        - name: body
          in: body
          description: "Trigger data to merge into current value."
          required: true
          schema:
            $ref: '#/definitions/Trigger'
      responses:
        200:
          description: "Updated Triggers metadata."
          schema:
            $ref: '#/definitions/Trigger'
        400:
          description: "Parameters are missing or invalid."
          schema:
            $ref: '#/definitions/Error'
        404:
          description: "The Trigger does not exist."
          schema:
            $ref: '#/definitions/Error'
        default:
          description: "An unexpected error occurred."
          schema:
            $ref: '#/definitions/Error'

  /fns/{fnID}/calls:
    get:
      summary: Get a fns calls.
      description: Get a functions calls, results returned in created_at, descending order (newest first).
      tags:
        - Call
      parameters:
        - $ref: '#/parameters/FnID'
        - $ref: '#/parameters/cursor'
        - $ref: '#/parameters/perPage'
        - name: from_time
          description: Unix timestamp in seconds, of call.created_at to begin the results at, default 0.
          required: false
          type: integer
          in: query
        - name: to_time
          description: Unix timestamp in seconds, of call.created_at to end the results at, defaults to latest.
          required: false
          type: integer
          in: query
      responses:
        200:
          description: "List of Calls"
          schema:
            $ref:  '#/definitions/CallList'
        404:
          description: "Calls not found"
          schema:
            $ref: '#/definitions/Error'
        410:
          description: Server does not support this operation.

  /fns/{fnID}/calls/{callID}:
    get:
      summary: Get call information
      description: Get call information
      tags:
        - Call
      parameters:
        - $ref: '#/parameters/FnID'
        - $ref: '#/parameters/CallID'
      responses:
        200:
          description: Call found.
          schema:
            $ref:  '#/definitions/Call'
        404:
          description: Call not found.
          schema:
            $ref: '#/definitions/Error'
        410:
          description: Server does not support this operation.

  /fns/{fnID}/calls/{callID}/log:
    get:
      operationId: "GetCallLogs"
      summary: "Get logs for a call."
      description: "Get logs for a call."
      tags:
        - Call
        - Log
      parameters:
        - $ref: '#/parameters/FnID'
        - $ref: '#/parameters/CallID'
      responses:
        200:
          description: Log found.
          schema:
            $ref:  '#/definitions/Log'
        404:
          description: Log not found.
          schema:
            $ref: '#/definitions/Error'
        410:
          description: Server does not support this operation.

definitions:
  App:
    type: object
    properties:
      id:
        type: string
        description: "App ID"
        readOnly: true
      name:
        type: string
        description: "Name of this app. Must be different than the image name. Can ony contain alphanumeric, -, and _."
        readOnly: true
      config:
        type: object
        description: "Application function configuration, applied to all Functions."
        additionalProperties:
          type: string
      annotations:
        type: object
        description: "Application annotations - this is a map of annotations attached to this app, keys must not exceed 128 bytes and must consist of non-whitespace printable ascii characters, and the seralized representation of individual values must not exeed 512 bytes."
        additionalProperties:
          type: object
      syslog_url:
        type: string
        x-nullable: true
        description: "A comma separated list of syslog urls to send all function logs to. supports tls, udp or tcp. e.g. tls://logs.papertrailapp.com:1"
      created_at:
        type: string
        format: date-time
        description: "Time when app was created. Always in UTC."
        readOnly: true
      updated_at:
        type: string
        format: date-time
        description: "Most recent time that app was updated. Always in UTC."
        readOnly: true

  AppList:
    type: object
    required:
      - items
    properties:
      next_cursor:
        type: string
        description: "Cursor to send with subsequent request to receive the next page, if non-empty."
        readOnly: true
      items:
        type: array
        items:
          $ref: '#/definitions/App'

  Fn:
    type: object
    properties:
      id:
        type: string
        description: "Unique identifier"
        readOnly: true
      name:
        type: string
        description: "Unique name for this function."
      app_id:
        type: string
        description: "App ID."
      image:
        type: string
        description: "Full container image name, e.g. hub.docker.com/fnproject/yo or fnproject/yo (default registry: hub.docker.com)"
      memory:
        type: integer
        format: uint64
        description: "Maximum usable memory given to function (MiB)."
      timeout:
        type: integer
        default: 30
        format: int32
        description: "Timeout for executions of a function. Value in Seconds."
      idle_timeout:
        type: integer
        default: 30
        format: int32
        description: "Hot functions idle timeout before container termination. Value in Seconds."
      config:
        type: object
        description: "Function configuration key values."
        additionalProperties:
          type: string
      annotations:
        type: object
        description: "Func annotations - this is a map of annotations attached to this func, keys must not exceed 128 bytes and must consist of non-whitespace printable ascii characters, and the seralized representation of individual values must not exeed 512 bytes."
        additionalProperties:
          type: object
      created_at:
        type: string
        format: date-time
        description: "Time when function was created. Always in UTC RFC3339."
        readOnly: true
      updated_at:
        type: string
        format: date-time
        description: "Most recent time that function was updated. Always in UTC RFC3339."
        readOnly: true

  FnList:
    type: object
    required:
      - items
    properties:
      next_cursor:
        type: string
        description: "Cursor to send with subsequent request to receive the next page, if non-empty."
        readOnly: true
      items:
        type: array
        items:
          $ref: '#/definitions/Fn'

  Trigger:
    type: object
    properties:
      id:
        type: string
        description: "Unique Trigger identifier."
        readOnly: true
      name:
        type: string
        description: "Unique name for this trigger, used to identify this trigger."
      type:
        type: string
        description: "Class of trigger, e.g. schedule, http, queue"
      source:
        type: string
        description: "URI path for this trigger. e.g. `sayHello`, `say/hello`"
      fn_id:
        type: string
        description: "Opaque, unique Function identifier"
        readOnly: true
      app_id:
        type: string
        description: "Opaque, unique Application identifier"
        readOnly: true
      annotations:
        type: object
        description: "Trigger annotations - this is a map of annotations attached to this trigger, keys must not exceed 128 bytes and must consist of non-whitespace printable ascii characters, and the seralized representation of individual values must not exeed 512 bytes."
        additionalProperties:
          type: object
      created_at:
        type: string
        format: date-time
        description: "Time when trigger was created. Always in UTC."
        readOnly: true
      updated_at:
        type: string
        format: date-time
        description: "Most recent time that trigger was updated. Always in UTC."
        readOnly: true

  TriggerList:
    type: object
    required:
      - items
    properties:
      next_cursor:
        type: string
        description: "Cursor to send with subsequent request to receive the next page, if non-empty."
        readOnly: true
      items:
        type: array
        items:
          $ref: '#/definitions/Trigger'

  Error:
    type: object
    properties:
      message:
        type: string
        readOnly: true
      fields:
        type: string
        readOnly: true

  Log:
    type: object
    properties:
      call_id:
        type: string
        description: Call UUID ID
      log:
        type: string # maybe bytes, long logs wouldn't fit into string type

  Call:
    type: object
    properties:
      id:
        type: string
        description: Call ID.
        readOnly: true
      status:
        type: string
        description: Call execution status.
        readOnly: true
      error:
        type: string
        description: Call execution error, if status is 'error'.
        readOnly: true
      app_id:
        type: string
        description: App ID of fn that executed this call.
        readOnly: true
      fn_id:
        type: string
        description: Fn ID of fn that executed this call.
        readOnly: true
      created_at:
        type: string
        format: date-time
        description: Time when call was submitted. Always in UTC.
        readOnly: true
      started_at:
        type: string
        format: date-time
        description: Time when call started execution. Always in UTC.
        readOnly: true
      completed_at:
        type: string
        format: date-time
        description: Time when call completed, whether it was successul or failed. Always in UTC.
        readOnly: true
      stats:
        type: array
        items:
          $ref: '#/definitions/Stat'
        description: A histogram of stats for a call, each is a snapshot of a calls state at the timestamp.
        readOnly: true

  CallList:
    type: object
    required:
      - items
    properties:
      next_cursor:
        type: string
        description: "Cursor to send with subsequent request to recieve next page, if non-empty."
        readOnly: true
      items:
        type: array
        items:
          $ref: '#/definitions/Call'

  Stat:
    type: object
    properties:
      timestamp:
        type: string
        format: date-time
      metrics:
        type: object
        properties:
          net_rx:
            type: integer
            format: int64
          net_tx:
            type: integer
            format: int64
          mem_limit:
            type: integer
            format: int64
          mem_usage:
            type: integer
            format: int64
          disk_read:
            type: integer
            format: int64
          disk_write:
            type: integer
            format: int64
          cpu_user:
            type: integer
            format: int64
          cpu_total:
            type: integer
            format: int64
          cpu_kernel:
            type: integer
            format: int64

parameters:
  cursor:
    name: cursor
    description: "Cursor from previous response.next_cursor to begin results after, if any."
    required: false
    type: string
    in: query
  perPage:
    name: per_page
    description: "Number of results to return, defaults to 30. Max of 100."
    required: false
    type: integer
    in: query

  AppID:
    name: appID
    in: path
    description: "Opaque, unique Application ID."
    required: true
    type: string
  FnID:
    name: fnID
    in: path
    description: "Opaque, unique Function ID."
    required: true
    type: string
  TriggerID:
    name: triggerID
    in: path
    description: "Opaque, unique Trigger ID."
    required: true
    type: string
  CallID:
    name: callID
    in: path
    description: "Opaque, unique Call ID."
    required: true
    type: string

  FnIDQuery:
    name: fn_id
    in: query
    description: "Function ID."
    required: false
    type: string
  AppIDQuery:
    name: app_id
    in: query
    description: "Application ID."
    required: false
    type: string
