432 lines
15 KiB
ReStructuredText
432 lines
15 KiB
ReStructuredText
==============================
|
|
Port and Service Binding Model
|
|
==============================
|
|
|
|
This document describes a generic modeling paradigm for new service APIs
|
|
(Protons) for OpenStack Gluon.
|
|
|
|
One fundamental driving force behind Gluon is the need for flexibility in
|
|
defining new network service APIs. The modeling paradigm described in the
|
|
following provides **design guidelines** and describes **best practices** for
|
|
creating new network service APIs. It hence supports developers in making the
|
|
best use of the flexibility provided by Gluon.
|
|
|
|
This model is based on the "service binding pattern" described in the NetReady
|
|
requirements document [0]_ and was adapted for Gluon.
|
|
|
|
The modeling tools in Gluon provide building blocks to allow the creation of
|
|
arbitrarily complex networking APIs. However, some constraints are needed to
|
|
enforce model consistency and to ensure interworking with the rest of the
|
|
Openstack system. This document describes the base objects that provide the
|
|
building blocks for defining new API objects and the relationship constraints
|
|
enforced by the system.
|
|
|
|
Objects and Relationships
|
|
-------------------------
|
|
|
|
The fundamental goal of this design paradigm is to clearly separate VM ports
|
|
from services and define how services bind to particular VM ports.
|
|
Specifically, there are four basic entities:
|
|
|
|
i) ports,
|
|
ii) interfaces,
|
|
iii) services, and
|
|
iv) service bindings.
|
|
|
|
|
|
* **Port**
|
|
|
|
A Port object represents a vNIC which is bindable to an OpenStack instance by
|
|
the compute service (Nova). It hence comprises all required information for
|
|
defining the hand-off point between a network and a VM instance. Other
|
|
services may in the future bind to ports (today, this happens within Neutron
|
|
to bind things like routers and DHCP services in the ML2 world).
|
|
|
|
* **Interface**
|
|
|
|
An interface is a logical entity which specifies a traffic segmentation
|
|
mechanism (i.e., VLAN, VxLAN, GRE). Interfaces sit on top of ports and
|
|
services are bound to interfaces instead of ports. Hence, interfaces allow
|
|
for binding multiple (incompatible) services to a single port.
|
|
|
|
When a Port is created, a corresponding default Interface object is
|
|
automatically created for un-segmented traffic. The UUID of this default
|
|
interface will be the same as the UUID of the parent Port. Additional
|
|
Interface objects created for the Port will have unique UUID identifiers.
|
|
|
|
* **Service**
|
|
|
|
A Service object represents a specific networking service, for example a L2
|
|
network, a L3VPN or a service chaining service.
|
|
|
|
* **Service Binding**
|
|
|
|
A Service Binding object binds a networking service to an Interface object.
|
|
It has at least two attributes: a reference to an Interface and a reference
|
|
to a Service. In addition, it can comprise attributes which are specific to a
|
|
Service **and** an Interface.
|
|
|
|
A Service Binding is **not** an extension of an Interface (no inheritance).
|
|
Instead, it is a separate entity. Modeling the binding as a separate entity
|
|
instead of encoding it in the Interface object has the following advantages:
|
|
|
|
i) It allows for dynamically binding and unbinding a Service while keeping
|
|
the VM and its port untouched. This simplifies VM migration across hosts as
|
|
well as the migration of VMs between different network services and backends.
|
|
|
|
ii) This entity allows for encapsulating service specific attributes which
|
|
are specific to an Interface but that are not part of the Interface. For
|
|
example, in a L3 service, the IP address of the interface bound to the
|
|
service can be specified here whereas this is not required for a pure L2
|
|
service.
|
|
|
|
The following diagram shows the relationship between these objects:
|
|
|
|
::
|
|
|
|
|
|
+-----------+
|
|
| |
|
|
| Port |
|
|
| |
|
|
+-----+-----+
|
|
| 1
|
|
|
|
|
|
|
|
|
|
|
| *
|
|
+-----------+ +-----+-----+
|
|
| Service | * 1 | |
|
|
| Binding +-----------+ Interface +
|
|
| | | |
|
|
+-----+-----+ +-----------+
|
|
| 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1
|
|
+-----+-----+
|
|
| |
|
|
| Service |
|
|
| |
|
|
+-----------+
|
|
|
|
|
|
Base Object Definitions
|
|
-----------------------
|
|
|
|
These are the base objects for defining APIs. These objects cannot be used
|
|
directly in an API definition. They must be used as the base object for
|
|
objects of similar type. There is an **"extends"** keyword in the
|
|
YAML model to provide this capability. To have a functional networking API,
|
|
one must extend the ``BasePort``, ``BaseInterface``, ``BaseService`` and
|
|
``BaseServiceBinding`` objects. It is not required that additional attributes
|
|
are defined for the extended objects. See the Interface definition in the
|
|
example_ at the end of this document.
|
|
|
|
In addition, you can also define objects that do not extend any of the base
|
|
objects. The proton server will provide CRUD functions on these objects but it
|
|
will not ensure any model consistency. However, objects that are extensions of
|
|
base objects will be examined to ensure model consistency. For example, the
|
|
proton server will have logic to validate that a Service Binding object
|
|
references only valid Interface and Service objects.
|
|
|
|
**BasePort**
|
|
|
|
The ``BasePort`` object must be extended in an API model. This base object
|
|
contains all of the attributes needed by Nova to bind the Port to a VM. The
|
|
extended object may contain additional attributes needed by the API model
|
|
(but not Nova). Note, the extended object does not have to define additional
|
|
attributes.
|
|
|
|
::
|
|
|
|
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'
|
|
zone:
|
|
type: string
|
|
length: 64
|
|
description: "zone information"
|
|
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"
|
|
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"
|
|
vif_type:
|
|
type: string
|
|
length: 32
|
|
description: "binding:vif_type: Headline binding type for VIF"
|
|
|
|
**BaseInterface**
|
|
|
|
The ``BaseInterface`` object must be extended in an API model. A default
|
|
Interface object will automatically be created for each Port object. Note,
|
|
the extended object does not have to define additional attributes.
|
|
|
|
::
|
|
|
|
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 segmention for this interface"
|
|
values:
|
|
- 'none'
|
|
- 'vlan'
|
|
- 'tunnel_vxlan'
|
|
- 'tunnel_gre'
|
|
- 'mpls'
|
|
- 'other'
|
|
segmentation_id:
|
|
type: integer
|
|
required: true
|
|
description: "Segmentation identifier"
|
|
|
|
**BaseService**
|
|
|
|
The ``BaseService`` object must be extended in an API model. There can be
|
|
multiple Services defined of a given model. However, an Interface can only
|
|
be bound to one Service. Note, the extended object does not have to define
|
|
additional attributes.
|
|
|
|
::
|
|
|
|
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**
|
|
|
|
The ``BaseServiceBinding`` object must be extended in an API model. Additional
|
|
attributes can be added to the extended object that are specific for a Port
|
|
bound to the Service. Note, the extended object does not have to define
|
|
additional attributes.
|
|
|
|
The ``service_id`` attribute can be re-defined in the extended object to specify
|
|
the specific type of Service that can be bound. The system will validate
|
|
that the UUID specified for the ``interface_id`` is a known Interface object. A
|
|
null value is also accepted to effectively "unbind" the interface from the
|
|
service. The system will also validate that the UUID specified for the
|
|
``service_id`` is a known Service object.
|
|
|
|
::
|
|
|
|
BaseServcieBinding:
|
|
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"
|
|
|
|
|
|
Example L3VPN API using proposed model:
|
|
---------------------------------------
|
|
|
|
The following model defines an L3VPN service. The Port and Interface objects
|
|
extend the ``BasePort`` and ``BaseInterface``, respectively. You can extend an object
|
|
without adding attributes. That is done with the Interface object. Even if no
|
|
attributes are added, you are still required to extend these objects for a
|
|
functional API. You must also extend the ``BaseService`` and ``BaseServiceBinding``
|
|
base objects in a similar manner.
|
|
|
|
Note, the VpnAfConfig object does not extend a base class. The
|
|
modeling tools allow for the creation of arbitrary objects as needed by an API
|
|
model. The proton server will not enforce any constraints on the relationships
|
|
between these objects and objects extended from base objects.
|
|
|
|
.. _example:
|
|
|
|
::
|
|
|
|
Port:
|
|
extends: BasePort
|
|
api:
|
|
name: ports
|
|
parent:
|
|
type: root
|
|
attributes:
|
|
alarms:
|
|
type: string
|
|
length: 256
|
|
description: "Alarm summary for port"
|
|
|
|
Interface:
|
|
extends: BaseInterface
|
|
api:
|
|
name: interfaces
|
|
parent:
|
|
type: root
|
|
|
|
VpnService:
|
|
extends: BaseService
|
|
api:
|
|
name: vpns
|
|
parent:
|
|
type: root
|
|
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: vpnbindings
|
|
parent:
|
|
type: root
|
|
attributes:
|
|
service_id: # Override from base object for specific Service type
|
|
type: VpnService
|
|
required: true
|
|
description: "Pointer to VpnService instance"
|
|
ipaddress:
|
|
type: 'string'
|
|
length: 64
|
|
description: "IP Address of port"
|
|
validate: 'ipv4address'
|
|
subnet_prefix:
|
|
type: 'integer'
|
|
description: "Subnet mask"
|
|
values:
|
|
- '1-31'
|
|
gateway:
|
|
type: 'string'
|
|
length: 64
|
|
description: "Default gateway"
|
|
validate: 'ipv4address'
|
|
|
|
VpnAfConfig:
|
|
api:
|
|
name: vpnafconfigs
|
|
parent:
|
|
type: root
|
|
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"
|
|
|
|
|
|
|
|
References
|
|
|
|
.. [0] NetReady - Service Binding model: http://artifacts.opnfv.org/netready/colorado/docs/requirements/index.html#service-binding-design-pattern
|
|
|