swagger: '2.0'
info:
  version: '1'
  title: Device inventory
  description: |
    An API for device attribute management and device grouping. Intended for use by the web GUI.

    Devices can upload vendor-specific attributes (software/hardware info, health checks, metrics, etc.) of various data types to the backend.

    This API enables the user to:
    * list devices with their attributes
    * search devices by attribute value
    * use the results to create and manage device groups for the purpose of deployment scheduling

basePath: '/api/management/v1/inventory'
host: 'docker.mender.io'
schemes:
  - https

paths:
  /devices:
    get:
      operationId: getDevices
      summary: List devices
      description:  |
        Returns a paged collection of devices and their attributes.
        Accepts optional search and sort parameters.

        **Searching**
        Searching by attributes values is accomplished by appending attribute
        name/value pairs to the query string, e.g.:

        ```
        GET /devices?attr_name_1=foo&
                     attr_name_2=100&
                     ...
        ```
      parameters:
        - name: Authorization
          in: header
          required: true
          type: string
          format: Bearer [token]
          description: Contains the JWT token issued by the User Administration and Authentication Service.
        - name: page
          in: query
          description: Starting page.
          required: false
          type: number
          format: integer
          default: 1
        - name: per_page
          in: query
          description: Number of results per page.
          required: false
          type: number
          format: integer
          default: 10
        - name: sort
          in: query
          description: |
            Supports sorting the device list by attribute values.

            The parameter is formatted as a list of attribute names and sort directions, e.g.:

            '?sort=attr1:asc, attr2:desc'

            will sort by 'attr1' ascending, and then by 'attr2' descending. 'desc' is the default
            sort direction, and can be omitted.
          required: false
          type: string
        - name: has_group
          in: query
          description: If present, limits the results only to devices assigned/not assigned to a group.
          required: false
          type: boolean

      responses:
        200:
          description: Successful response.
          headers:
            Link:
              type: string
              description: |
                Standard header, used for page navigation.

                Supported relation types are 'first', 'next' and 'prev'.
          schema:
            title: ListOfDevices
            type: array
            items:
              $ref: '#/definitions/Device'
          examples:
            application/json:
              - id: "291ae0e5956c69c2267489213df4459d19ed48a806603def19d417d004a4b67e"
                attributes:
                  - name: "ip_addr"
                    value: "1.2.3.4"
                    description: "IP address"
                  - name: "mac_addr"
                    value: "00.01:02:03:04:05"
                    description: "MAC address"
                  - name: "ports"
                    value:
                      - "8080"
                      - "8081"
                    description: "Open ports"
                updated_ts: "2016-10-03T16:58:51.639Z"
              - id: "76f40e5956c699e327489213df4459d1923e1a806603def19d417d004a4a3ef"
                attributes:
                  - name: "mac"
                    value: "00:01:02:03:04:05"
                    description: "MAC address"
                updated_ts: "2016-10-04T18:24:21.432Z"
        400:
          description: Missing or malformed request parameters. See error for details.
          schema:
            $ref: '#/definitions/Error'
        500:
          description: Internal error.
          schema:
            $ref: '#/definitions/Error'
  /devices/{id}:
    get:
      operationId: getDevices
      summary: Get a selected device
      description: Returns the details of the selected devices, including its attributes.
      parameters:
        - name: Authorization
          in: header
          required: true
          type: string
          format: Bearer [token]
          description: Contains the JWT token issued by the User Administration and Authentication Service.
        - name: id
          in: path
          description: Device identifier.
          required: true
          type: string
      responses:
        200:
          description: Successful response - the device was found.
          schema:
            $ref: "#/definitions/Device"
          examples:
            application/json:
              id: "291ae0e5956c69c2267489213df4459d19ed48a806603def19d417d004a4b67e"
              attributes:
                - name: "ip_addr"
                  value: "1.2.3.4"
                  description: "IP address"
                - name: "mac_addr"
                  value: "00.01:02:03:04:05"
                  description: "MAC address"
                - name: "ports"
                  value:
                    - "8080"
                    - "8081"
                  description: "Open ports"
              updated_ts: "2016-10-03T16:58:51.639Z"
        404:
          description: The device was not found.
          schema:
            $ref: "#/definitions/Error"
        500:
          description: Internal server error.
          schema:
            $ref: "#/definitions/Error"
    delete:
      operationId: removeDevice
      summary: Remove selected device
      description: Deletes all information concerning the device, including its attributes.
      parameters:
        - name: Authorization
          in: header
          required: true
          type: string
          format: Bearer [token]
          description: Contains the JWT token issued by the User Administration and Authentication Service.
        - name: id
          in: path
          description: Device identifier.
          required: true
          type: string
      responses:
          204:
            description: Device removed
          500:
            description: Internal server error.
            schema:
              $ref: "#/definitions/Error"

  /devices/{id}/group:
    get:
      operationId: getGroup
      summary: Get a selected device's group
      parameters:
        - name: Authorization
          in: header
          required: true
          type: string
          format: Bearer [token]
          description: Contains the JWT token issued by the User Administration and Authentication Service.
        - name: id
          in: path
          description: Device identifier.
          required: true
          type: string
      responses:
        200:
          description: |
            Successful response.

            If the device is not assigned to any group, the 'group' field will be set to 'null'.
          schema:
            $ref: "#/definitions/Group"
          examples:
            application/json:
              group: "testing"
        400:
          description: Missing or malformed request params or body. See the error message for details.
        404:
          description: The device was not found.
          schema:
            $ref: "#/definitions/Error"
        500:
          description: Internal server error.
          schema:
            $ref: "#/definitions/Error"
    put:
      operationId: addGroupDevice
      summary: Add a device to a group
      description: |
        Adds a device to a group.

        Note that a given device can belong to at most one group.
        If a device already belongs to some group, it will be moved
        to the selected one.
      parameters:
        - name: Authorization
          in: header
          required: true
          type: string
          format: Bearer [token]
          description: Contains the JWT token issued by the User Administration and Authentication Service.
        - name: id
          in: path
          description: Device identifier.
          required: true
          type: string
        - name: group
          in: body
          description: Group descriptor.
          required: true
          schema:
            $ref: '#/definitions/Group'
      responses:
        204:
          description: Success - the device was added to the group.
        400:
          description: Missing or malformed request params or body. See the error message for details.
        404:
          description: The device was not found.
          schema:
            $ref: "#/definitions/Error"
        500:
          description: Internal server error.
          schema:
            $ref: "#/definitions/Error"
  /devices/{id}/group/{name}:
    delete:
      operationId: removeGroupDevice
      summary: Remove a device from a group
      description: |
        Removes the device with identifier 'id' from the group 'group'.
      parameters:
        - name: Authorization
          in: header
          required: true
          type: string
          format: Bearer [token]
          description: Contains the JWT token issued by the User Administration and Authentication Service.
        - name: id
          in: path
          description: Device identifier.
          required: true
          type: string
        - name: name
          in: path
          description: Group name.
          required: true
          type: string
      responses:
        204:
          description: The device was successfully removed from the group.
        404:
          description: The device was not found or doesn't belong to the group.
          schema:
            $ref: '#/definitions/Error'
        500:
          description: Internal error.
          schema:
            $ref: '#/definitions/Error'
  /groups:
    get:
      operationId: getGroups
      summary: List groups
      description: Returns a collection of all defined device groups.
      responses:
        200:
          description: Successful response.
          schema:
            type: array
            items:
              title: ListOfGroupNames
              description: Group name
              type: string
          examples:
            application/json:
              - "staging"
              - "testing"
              - "production"
        500:
          description: Internal server error.
          schema:
            $ref: '#/definitions/Error'

  /groups/{name}/devices:
    get:
      operationId: getGroupDevices
      summary: List the devices belonging to a given group
      description: |
        Returns a paged collection of device IDs.
      parameters:
        - name: Authorization
          in: header
          required: true
          type: string
          format: Bearer [token]
          description: Contains the JWT token issued by the User Administration and Authentication Service.
        - name: page
          in: query
          description: Starting page.
          required: false
          type: number
          format: integer
          default: 1
        - name: per_page
          in: query
          description: Number of results per page.
          required: false
          type: number
          format: integer
          default: 10
        - name: name
          in: path
          description: Group name.
          required: true
          type: string
      responses:
        200:
          description: Successful response
          headers:
            Link:
              type: string
              description: Standard header, we support 'first', 'next', and 'prev'.
          schema:
            title: ListOfIDs
            type: array
            items:
              type: string
        400:
          description: Invalid request parameters.
          schema:
            $ref: '#/definitions/Error'
        404:
          description: The group was not found.
          schema:
            $ref: '#/definitions/Error'
        500:
          description: Internal server error.
          schema:
            $ref: '#/definitions/Error'

definitions:
  Attribute:
    description: Attribute descriptor.
    type: object
    required:
      - name
      - value
    properties:
      name:
        type: string
        description: |
            A human readable, unique attribute ID, e.g. 'device_type', 'ip_addr', 'cpu_load', etc.
      description:
        type: string
        description: Attribute description.
      value:
        type: string
        description: |
            The current value of the attribute.

            Attribute type is implicit, inferred from the JSON type.

            Supported types: number, string, array of numbers, array of strings. Mixed arrays are not allowed.
    example:
      application/json:
        name: "cpu_load"
        description: "The current CPU load."
        value: 42
  Device:
    type: object
    properties:
      id:
        type: string
        description: Mender-assigned unique ID.
      updated_ts:
        type: string
        description: Timestamp of the most recent attribute update.
      attributes:
        type: array
        items:
          $ref: '#/definitions/Attribute'
        description: A list of attribute descriptors.
    example:
      application/json:
        id: "291ae0e5956c69c2267489213df4459d19ed48a806603def19d417d004a4b67e"
        attributes:
          - name: "ip_addr"
            value: "1.2.3.4"
            description: "IP address"
          - name: "mac_addr"
            value: "00.01:02:03:04:05"
            description: "MAC address"
          - name: "ports"
            value:
              - "8080"
              - "8081"
            description: "Open ports"
        updated_ts: "2016-10-03T16:58:51.639Z"
  Group:
    description: Device group.
    type: object
    properties:
      group:
        type: string
    required:
      - group
    example:
      application/json:
        group: "staging"
  Error:
    description: Error descriptor.
    type: object
    properties:
      error:
        description: Description of the error.
        type: string
      request_id:
        description: Request ID (same as in X-MEN-RequestID header).
        type: string
    example:
      application/json:
          error: "failed to decode device group data: JSON payload is empty"
          request_id: "f7881e82-0492-49fb-b459-795654e7188a"
