gluon/doc/source/devref/gluon_api_spec.rst

22 KiB

Gluon API Specification

Gluon supports the processing of a specification document to define an object-oriented API. The gluon API specification uses YAML syntax to define the structure and relationships of the objects that are manipulated by the API. This specification also includes metadata definitions that can be used for the automatic generation of human readable API documentation.

The specification allows for the definition of two types of objects: base objects and API objects. A base object is an object specification that does not have an API definition field. An object with an API definition field is an API object. A base object is used to define a set of attributes that can be included in other object definitions. Base objects can extend other base objects but not API objects. An API object can only extend base objects. No code is created for base objects. The gluon framework will generate code for API objects.

For each API object, the gluon framework will generate code for database storage and code to support a REST API to manipulate the object. The API endpoints created will support the basic CRUD operations on the object. Each API object will have a corresponding database table. Each API object is required to have a primary key field. The primary key field is used as the identifier in the generated API endpoints. For example, if we define an API object for a Port with a path name of ports the following API URL endpoints will be generated where <port_id> is the primary key.

Operation URL Description
POST /proton/<api_name>/ports Create Port object
PUT /proton/<api_name>/ports/<port_id> Modify Port object
GET /proton/<api_name>/ports Get all Port objects
GET /proton/<api_name>/ports/<port_id> Get one Port object
DELETE /proton/<api_name>/ports/<port_id> Delete a Port object

The content type for all of the operations is application/json.

The API objects can have pointer relationships and parent/child relationships to other API objects. A pointer relationship can be created by defining a field that uses the object name of another object as its type. When this type of relationship is specified, the primary key of the referenced object becomes a foreign key in the object's database table. A parent/child relationship can be created at the API level by specifying the parent object name in an object's API definition (see ApiDef). When a parent/child relationship is specified, a pointer relationship from the child object to the parent object is automatically created using the primary key of the parent.

In addition, different API endpoints are generated to manipulate the child object. For example, assume we define an API object for Port and another API object for Interface where the Interface is a child of the Port. If the path names are ports and interfaces, the following API URL endpoints for the Interface object would be generated.

Operation URL Description
POST /proton/<api_name>/ports/<port_id>/interfaces Create Interface object
PUT /proton/<api_name>/ports/<port_id>/interfaces/<interface_id> Modify Interface object
GET /proton/<api_name>/ports/<port_id>/interfaces Get all Interface objects for Port
GET /proton/<api_name>/ports/<port_id>/interfaces/<interface_id> Get one Interface object
DELETE /proton/<api_name>/ports/<port_id>/interfaces/<interface_id> Delete an Interface object

This document describes the specification for defining an API. Further guidance on how to design an API using the Service Binding Model can be found here.

Schema Definition

The schema exposes two types of fields. Fixed fields, which have a declared name, and Patterned fields, which declare a regex pattern for the field name. Patterned fields can have multiple occurrences as long as each has a unique name. Each field will have a value that is defined as a primitive type or as an JSON object. The JSON objects are very similar to the Schema Object found in Swagger. However, some extensions are added and only a small subset of the properties are supported.

Primitive Data Types

Type Description Associated Properties
integer Integer number
  • format: int32, int64 (default: int32)
  • min: integer
  • max: integer
number Floating point number n/a
string Text String
  • length: integer (default: 255)
  • format: date-time, json, ipv4, ipv6, mac, url, email
boolean Boolean value (true/false) n/a
uuid Text string in UUID format n/a
enum Text string from a list of values
  • values: [string]

File Structure

The API is defined by a single file. The Root Object is defined by the ProtonDef object. See the complete Example at the end of this page for an example of the ProtonDef syntax.

ProtonDef

Fixed Field Type Required Description
file_version string true Proton File Version
imports string false File path to common base object definitions
info InfoDef true Metadata for this API specification that is useful in the generation of human readable API documentation.
objects ObjectsDef true Object definitions for this API

Example

file_version: 1.0
imports: base/base.yaml
info:
  name: net-l3vpn
  version: 1.0
  description "L3VPN API Specification"
  author:
    name: "Gluon Team"
    url: https://wiki.openstack.org/wiki/Gluon
    email: bh526r@att.com
objects:
  Port:
    api:
      name: port
      plural_name: ports
    extends: BasePort
    attributes:
      alarms:
        type: string
        length: 255
        description: "Alarm summary for port"
  ...

The ProtonDef is the root object for the API specification. The file_version is used to identify the format used to create this file. The info field contains the metadata about the API. The objects field contains the base and API object definitions for the API.

InfoDef

Fixed Field Type Required Description
name string true Name of the API
version string true Version of the API
description string false Description of the API
author AuthorDef false Information about API authorship

The InfoDef is where metadata about the API can be specified. At a minimum the name and version of the API must be specified.

Example

name: net-l3vpn
version: 1.0
description "L3VPN API Specification"
author:
  name: "Gluon Team"
  url: https://wiki.openstack.org/wiki/Gluon
  email: bh526r@att.com

AuthorDef

Fixed Field Type Required Description
name string true Name of the author
url string false URL to author website
email string false Email address of author

The AuthorDef allows authorship information about the API to be specified. This information is optional.

Example

name: "Gluon Team"
url: https://wiki.openstack.org/wiki/Gluon
email: bh526r@att.com

ObjectsDef

Pattern Field Type Required Description
[_a-zA-Z][_a-zA-Z0-9]* ObjectDef true Field/Value Object definitions

The ObjectsDef allows one or more objects to be specified for the API. The field name should follow the lexical definitions for a Python identifier.

Example

VpnService:
  api:
    name: vpn
    plural_name: vpns
  extends: BaseService
  attributes:
    ipv4_family:
      type: string
      length: 255
      description: "Comma separated list of route target strings"
    ipv6_family:
      type: string
      length: 255
      description: "Comma separated list of route target strings"
    route_distinguishers:
      type: string
      length: 32
      description: "Route distinguisher for this VPN"

ObjectDef

Fixed Field Type Required Description
api ApiDef false API path information for object
extends string false Name of a base object definition to extend
attributes AttributesDef true Attribute definitions of object
policies PolicyDef false Access rules for this API object

The ObjectDef defines either a base object or an API object. If the api field is present, it is an API object. If the api field is omitted, it is a base object. The extends field (if present) must specify the ObjectDef name of another base object. The policies field is only allowed for an API object. If the policies field is omitted, no access control is applied to the object.

Example

api:
  name: port
  plural_name: ports
extends: BasePort
attributes:
  alarms:
    type: string
    length: 255
    description: "Alarm summary for port"
policies:
  create: "rule:admin_or_network_owner"
  delete: "rule:admin_or_network_owner"
  get: "rule:admin_or_owner"
  get_one: "rule:admin_or_owner"
  update: "rule:admin_or_network_owner"

ApiDef

Fixed Field Type Required Description
name string true Singular path name for the object
plural_name string false Plural path name for the object
parent string false Name of an ObjectDef specification

The ApiDef defines the API path and optionally a parent/child relationship for the object. The parent field (if present) must specify the ObjectDef name of another API object. The name field is used by the generated CLI code to identify the object to be manipulated. The plural_name field is used by the generated API code as part of the path to identify the object to be manipulated. If the plural_name field is omitted, an 's' character is added to the name for the API path during code generation.

Example

name: interface
plural_name: interfaces
parent: Port

PolicyDef

Fixed Field Type Required Description
create string false Rule specifier string
delete string false Rule specifier string
get string false Rule specifier string
get_one string false Rule specifier string
update string false Rule specifier string

The PolicyDef defines the Role-Based Access Control (RBAC) for the object. The access to the object can be controlled for each generated action. The syntax of the rule specifier string is defined in the Openstack Policy document.

Example

create: "rule:admin_or_network_owner"
delete: "rule:admin_or_network_owner"
get: "rule:admin_or_owner"
get_one: "rule:admin_or_owner"
update: "rule:admin_or_network_owner"

AttributesDef

Pattern Field Type Required Description
[_a-zA-Z][_a-zA-Z0-9]* AttributeSchemaDef true Field/Value Attribute definitions

The AttributesDef allows one or more attributes to be specified for the object. The field name should follow the lexical definitions for a Python identifier.

Example

id:
  type: uuid
  required: true
  primary: true
  description: "UUID of Interface instance"

AttributeSchemaDef

Fixed Field Type Required Description
type string true Primitive data type or ObjectDef name
primary boolean false Primary key for object (if true)
description string false Description of the attribute
required boolean false Required flag for object creation (default: false)
length integer false Length if type is string (default: 255)
values [string] false Array of strings (required if type is enum)
format string false Format if type is integer or string
min integer false Min value if type is integer
max integer false Max value if type is integer

Each attribute is defined by an AttributeSchemaDef. The type field is mandatory and can specify a primitive data type or it can be the name of an ObjectDef. The ObjectDef name must be for an API object. One attribute for an object must have the primary field specified. The required field is used to specify if the attribute must be present when creating an object. If the type is enum, the values field must be present and define an array of valid strings for the enumeration.

If the type is integer:

  • The format field can specify if the integer is 32 or 64 bit. Default is int32
  • The min field can specify the valid minimum value
  • The max field can specify the valid maximum value

If the type is string:

  • The format field can specify the formatting that will be validated for the string. The string formatting validations supported are:

    • date-time - Validated according to Date_Time
    • json - Valid JSON string
    • ipv4 - Validated according to IPV4
    • ipv6 - Validated according to IPV6
    • mac - Valid MAC address according to IEEE 802
    • uri - Validated according to URI
    • email - Validated according to EMAIL
  • The length field can specify the size of the string. Default is 255

Example

The following example shows the AttributeSchemaDef definitions for ipaddress, subnet_prefix, status, and profile.

ipaddress:
  type: string
  length: 23
  description: "IP Address of port"
  format: ipv4
subnet_prefix:
  type: integer
  description: "Subnet mask"
  format: int32
  min: 1
  max: 31
status:
  type: enum
  required: true
  description: "Operational status of Port"
  values:
    - 'ACTIVE'
    - 'DOWN'
profile:
  type: string
  length: 128
  description: "JSON string for binding profile dictionary"
  format: json

References

Date_Time IPV4 IPV6 URI EMAIL

Complete Example Specification

This section shows the L3VPN API defined using this specification. The base objects that would be defined in base/base.yaml are in the Base Objects section and the API is defined in the API Specification section.

Base Objects

file_version: 1.0
objects:
  BasePort:
    attributes:
      id:
        type: uuid
        primary: true:
        description: "UUID of Port instance"
      name:
        type: string
        length: 64
        description: "Descriptive name for Port"
      tenant_id:
        type: uuid
        required: true
        description: "UUID of Tenant owning this Port"
      mac_address:
        type: string
        length: 17
        required: true
        description: "MAC address for Port"
        validate: mac_address
      admin_state_up:
        type: boolean
        required: true
        description: "Admin state of Port"
      status:
        type: enum
        required: true
        description: "Operational status of Port"
        values:
          - 'ACTIVE'
          - 'DOWN'
      vnic_type:
        type: enum
        required: true
        description: "Port should be attache to this VNIC type"
        values:
           - 'normal'
           - 'virtual'
           - 'direct'
           - 'macvtap'
           - 'sriov'
           - 'whole-dev'
      mtu:
        type: integer
        description: "MTU"
        required: true
      vlan_transparency:
        type: boolean
        description: "Allow VLAN tagged traffic on Port"
        required: true
      profile:
        type: string # JSON Format
        length: 128
        description: "JSON string for binding profile dictionary"
        format: json
      device_id:
        type: uuid
        description: "UUID of bound VM"
      device_owner:
        type: string
        length: 128
        description: "Name of compute or network service (if bound)"
      host_id:
        type: string
        length: 32
        description: "binding:host_id: Name of bound host"
      vif_details:
        type: string # JSON Format
        length: 128
        description: "binding:vif_details: JSON string for VIF details"
        format: json
      vif_type:
        type: string
        length: 32
        description: "binding:vif_type: binding type for VIF"
  BaseInterface:
    attributes:
      id:
        type: uuid
        required: true
        primary: true
        description: "UUID of Interface instance"
      port_id:
        type: uuid
        required: true
        description: "Pointer to Port instance"
      segmentation_type:
        type: enum
        required: true
        description: "Type of segmentation for this interface"
        values:
          - 'none'
          - 'vlan'
          - 'tunnel_vxlan'
          - 'tunnel_gre'
          - 'mpls'
      segmentation_id:
        type: integer
        required: true
        description: "Segmentation identifier"
  BaseService:
    attributes:
      id:
        type: uuid
        required: true
        primary: true
        description: "UUID of Service instance"
      name:
        type: string
        length: 64
        description: "Descriptive name of Service"
      description:
        type: string
        length: 256
        description: "Description of Service"
  BaseServiceBinding:
    attributes:
      interface_id:
        type: uuid
        required: true
        primary: true
        description: "Pointer to Interface instance"
      service_id:
        type: uuid
        required: true
        description: "Pointer to Service instance"

API Specification

file_version: 1.0
imports: base/base.yaml
info:
  name: net-l3vpn
  version: 1.0
  description "L3VPN API Specification"
  author:
    name: "Gluon Team"
    url: https://wiki.openstack.org/wiki/Gluon
    email: bh526r@att.com
objects:
  Port:
    api:
      name: port
      plural_name: ports
    extends: BasePort
    attributes:
      alarms:
        type: string
        length: 255
        description: "Alarm summary for port"
  Interface:
    api:
      name: interface
      plural_name: interfaces
      parent: Port
    extends: BaseInterface
  VpnService:
    api:
      name: vpn
      plural_name: vpns
    extends: BaseService
    attributes:
      ipv4_family:
        type: string
        length: 255
        description: "Comma separated list of route target strings"
      ipv6_family:
        type: string
        length: 255
        description: "Comma separated list of route target strings"
      route_distinguishers:
        type: string
        length: 32
        description: "Route distinguisher for this VPN"
  VpnBinding:
    extends: BaseServiceBinding
    api:
      name: vpnbinding
      plural_name: vpnbindings
    attributes:
      service_id:    # Override from base object for specific Service type
        type: VpnService
        required: true
        primary: true
        description: "Pointer to VpnService instance"
      ipaddress:
        type: string
        length: 23
        description: "IP Address of port"
        format: ipv4
      subnet_prefix:
        type: integer
        description: "Subnet mask"
        format: int32
        min: 1
        max: 31
      gateway:
        type: string
        length: 32
        description: "Default gateway"
        format: ipv4
  VpnAfConfig:
    api:
      name: vpnafconfig
      plural_name: vpnafconfigs
    attributes:
      vrf_rt_value:
        required: True
        type: string
        length: 32
        primary: 'True'
        description: "Route target string"
      vrf_rt_type:
        type: enum
        required: True
        description: "Route target type"
        values:
          - export_extcommunity
          - import_extcommunity
          - both
      import_route_policy:
        type: string
        length: 32
        description: "Route target import policy"
      export_route_policy:
        type: string
        length: 32
        description: "Route target export policy"