$schema: 'http://support.riverbed.com/apis/service_def/2.2'
id: 'http://support.riverbed.com/apis/cmc.sectransport/1.0'
provider: 'riverbed'
name: cmc.sectransport
version: "1.0"
title: REST API for secure transport managment


types:
  ###################################################################################
  # Security Group Member
  ###################################################################################
  # Defines a member of a group, typed to facilitate format checking
  serial:
    type: string
    description: Universally unique ID for an appliance

  ipv4address:
    description: IPv4 address (x.y.z.k)
    type: string
    pattern: '^((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))?$'

  stat_block:
    type: object
    description: Representation of a statistics object
    properties:
      bytes_in:
        description: 'Bytes received'
        type: number
        readOnly: true
      bytes_out:
        description: 'Bytes sent'
        type: number
        readOnly: true
      packets_in:
        description: 'Packets received'
        type: number
        readOnly: true
      packets_out:
        description: 'Packets sent'
        type: number
        readOnly: true
    additionalProperties: false


  datapoint:
    type: object
    properties:
      timestamp: {type: timestamp}
      data:
        $ref: '#/types/stat_block'

  controller_info:
    type: object
    description: Controller information
    properties:
      serial:
        $merge:
            source: { $ref: '#/types/serial' }
            with: { description: The controller appliance to send update notifications to }
      public_ip:
        $merge:
            source: { $ref: '#/types/ipv4address' }
            with: { description: The public ip address of the controller }
      port:
        type: integer
        description: Port to go along with the public ip
        minimum: 0
        maximum: 65535
      private_ip:
        $merge:
            source: { $ref: '#/types/ipv4address' }
            with: { description: The private ip addres of the controller }
      is_primary:
        type: boolean
        description: Whether this controller is primary or not
      hostname:
        type: string
        description: Hostname of controller
        readOnly: True
      id:
        type: integer
        description: Appliance Inventory Id associated for this appliance
        readOnly: True

  poller_response:
    type: object
    properties:
      poll_req_id:
        type: integer
        description: Request id registered with poller
      serial:
        type: string
        description: Appliance from which response is received
      poll_time:
        type: timestamp
      resp_data:
        type: string
        description: Response from the polled request

  peer_stats:
    type: object
    properties:
      serial:
        $merge:
            source: { $ref: '#/types/serial' }
            with: { description: Peer(appliance) for which this resource represents the stats }
      stats:
        type: array
        items:
          $ref: '#/types/datapoint'
      rekey_times:
        type: array
        description: List of rekey timestamps
        items:
          type: timestamp

resources:
  peer_group_stats:
    $merge:
      source: { $ref: '#/types/peer_stats' }
      with:
        required: [ serial ]
        description: Group-level stats for this peer relative to other peers in the group

        links:
          self:
            path: $/appliances/items/{serial}/group_stats
            params:
              group_id: {type: integer}
              start_time: {type: timestamp}
              end_time:  {type: timestamp}
          get:
            method: GET
            description: Get group stats for peer
            response:
              $ref: '#/resources/peer_group_stats'

  all_peer_group_stats:
    type: object
    description: peer_group_stats for all peers belonging to a group
    properties:
      id:
        type: integer
        description: Group Id for which this resource represents the stats
      peer_stats:
        type: array
        items:
          $ref: '#/types/peer_stats'
    links:
      self:
        path: $/groups/items/{id}/all_peer_group_stats
        params:
          start_time: {type: timestamp}
          end_time:  {type: timestamp}
      get:
        method: GET
        description: Get group stats for peers belonging to the group
        response:
          $ref: '#/resources/all_peer_group_stats'

  group_stats:
    type: object
    description: Group-level stats
    properties:
      id:
        type: integer
        description: Group Id for which this resource represents the stats
      stats:
        type: array
        items:
          $ref: '#/types/datapoint'
      rekey_times:
        type: array
        description: List of rekey timestamps
        items:
          type: timestamp
    links:
      self:
        path: $/groups/items/{id}/group_stats
        params:
          start_time: {type: timestamp}
          end_time:  {type: timestamp}
      get:
        method: GET
        description: Get stats for group
        response:
          $ref: '#/resources/group_stats'


  controller_status:
    type: object
    description: Controller connectivity/service status
    properties:
      serial:
        $merge:
            source: { $ref: '#/types/serial' }
            with: { description: serial of the controller for which this resource contains the status }
      status:
        type: string
        enum: ['up', 'down']
        readOnly: True

    links:
      self:
        path: $/controllers/items/{serial}/status
      get:
        method: GET
        description: Get status for this controller
        response:
          $ref: '#/resources/controller_status'


  #############################################################################
  # Appliance information
  #############################################################################
  # Defines an appliance and its relationships in ST
  appliance:
    type: object
    description: Registered appliance
    properties:
      id:
        type: integer
        description: Appliance inventory id

      serial:
        $merge:
            source: { $ref: '#/types/serial' }
            with: { description: Universally Unique Identifier }

      name:
        type: string
        description: The human readable name of the appliance

      group_membership:
        type: array
        description: What security groups this appliance belongs to
        items:
          type: integer
          relations:
            full:
              resource: '#/resources/group'
              vars:
                id: "0"

    links:
      self:
        path: "$/appliances/items/{serial}"

      get:
        method: GET
        description: Get information about the appliance
        response:
          $ref: '#/resources/appliance'


    relations:
      instances:
        resource: '#/resources/appliances'

      group_stats:
        resource: '#/resources/peer_group_stats'
        vars: {serial: "0/serial"}


  ###################################################################################
  # Appliance information
  ###################################################################################
  # When the controller starts up, it needs to get all the info at once with this
  appliances:
    type: array
    description: ST information for all registered appliances on the system
    items:
      $merge:
          source: { $ref: '#/resources/appliance' }
          with:
              relations:
                full:
                  resource: '#/resources/appliance'
                  vars:
                    serial: "0/serial"

    links:
      self:
        path: "$/appliances"

      get:
        method: GET
        description: Get ST information for all registered appliances on the system
        response:
          $ref: '#/resources/appliances'


  ###################################################################################
  # Controller registration
  ###################################################################################
  controller:
    $merge:
      source: { $ref: '#/types/controller_info' }
      with:
        description: Controller information
        required: [ serial, private_ip ]

        links:
          self:
            path: "$/controllers/items/{serial}"

          set:
            method: PUT
            description: Update the controller
            request:
              $ref: '#/resources/controller'
            response:
              $ref: '#/resources/controller'

          delete:
            method: DELETE
            description: Remove a controller

        relations:
          status:
            resource: '#/resources/controller_status'
            vars: {serial: "0/serial"}

  controllers:
    type: array
    description: List of all controllers registered with the CMC
    items:
      $merge:
          source: { $ref: '#/resources/controller' }
          with:
              relations:
                full:
                  resource: '#/resources/controller'
                  vars:
                    serial: "0/serial"

    links:
      self:
        path: "$/controllers"

      get:
        method: GET
        description: Get the list of all controllers registered on the CMC
        response:
          $ref: '#/resources/controllers'

      create:
        method: POST
        description: Create a new controller
        request:
          $ref: '#/resources/controller'
        response:
          $ref: '#/resources/controller'

  primary_controller:
    $merge:
      source: { $ref: '#/types/controller_info' }
      with:
        description: Primary controller for appliances that are part of ST groups

        links:
          self:
            path: "$/controllers/primary"
            params:
              serial: { $ref: '#/types/serial' }

          get:
            method: GET
            description: Get the primary controller based on appliance membership
            response:
              $ref: '#/resources/primary_controller'

  #############################################################################
  # Security Group
  #############################################################################


  # This defines a group for individual queries
  group:
    type: object
    description: A secure transport group
    additionalProperties: True
    required: [ name ]
    properties:
      # This is the unique identifier
      id:
        type: integer
        description: Permanent ID of the group
        readOnly: True

      name:
        type: string
        description: Name of the group
        readOnly: True

      key_auto_expiry:
        type: number
        description: Max time in seconds that a key can be used
        minimum: 31
        maximum: 31557600

      data_rekey_volume:
        # This property needs a better name...
        type: number
        description: Max number of bytes that can be transfered in a security group before rekey
        minimum: 0

      rekey_pktprcnt:
        type: number
        description: Percentage of packets from max, when re-key must be performed
        minimum: 0
        maximum: 100

      rekey_pktcnt:
        type: integer
        description: Cumulative packet counter for a SPI, after which re-key must be performed
        minimum: 0

      headless_timeout:
        type: number
        description: How long in seconds can an appliance run without controller link
        minimum: 31
        maximum: 31557600

      keepalive_interval:
        type: integer
        description: How often should keep alive messages be sent between peers
        minimum: 10
        maximum: 3600

      # Group membership
      members:
        type: array
        description: The members of this security group
        items:
          type: object
          properties:
            serial:
              $ref: '#/types/serial'
            name:
              type: string
          readOnly: true
          relations:
            full:
              resource: '#/resources/appliance'
              vars:
                serial: "0/serial"

    links:
      self:
        path: "$/groups/items/{id}"

      get:
        method: GET
        description: Get information about the group
        response:
          $ref: '#/resources/group'

      set:
        method: PUT
        description: Update a group
        request:
          $ref: '#/resources/group'
        response:
          $ref: '#/resources/group'

    relations:
      instances:
        resource: '#/resources/groups'

      group_stats:
        resource: '#/resources/group_stats'
        vars: {id: "0/id"}


  ###################################################################################
  # Security Group
  ###################################################################################
  # Collection of all group resources
  groups:
    type: array
    description: All of the groups configured in the system
    items:
      $merge:
          source: { $ref: '#/resources/group' }
          with:
              relations:
                full:
                  resource: '#/resources/group'
                  vars:
                    id: "0/id"
    links:
      self:
        path: "$/groups"

      get:
        method: GET
        description: Get all groups on the system
        response:
          $ref: '#/resources/groups'


  ###################################################################################
  # Security Group
  ###################################################################################
  # When the controller starts up, it needs to get all the info at once with this
  configuration:
    type: object
    description: Secure Transport Configuration
    properties:
      groups:
        $merge:
            source: { $ref: '#/resources/groups' }
            with: { description: All the groups configured in the system }
      revision:
        type: string
        description: Revision of this configuration

    links:
      self:
        path: "$/configuration"

      get:
        method: GET
        description: Get secure transport configuration
        response:
          $ref: '#/resources/configuration'

  poller:
    type: object
    description: Temporary callback for stats poll requests
    required: [ poll_req_id, serial, poll_time, resp_data ]

    links:
      self:
        path: "$/poller_callback"

      callback:
        method: POST
        description: Callback to get polled response
        request:
            $ref: '#/types/poller_response'