QuantumV2APIIntro

= Quantum Developer v2 API Intro =

Note: Please see Quantum/APIv2-specification for the latest Quantum v2.0 specification.

The goal of this document is to quickly get a Quantum developer who is already familiar with how things worked with the v1.0 and v1.1 API up to speed on the v2.0 API. Full API specification (i.e., http://docs.openstack.org/api/openstack-network/1.0/content/index.html) will be coming as well, but this document is an attempt to jumpstart developers who have Folsom-2 work that requires using v2.0 API.

The v2.0 API code is available for review here: https://review.openstack.org/#/c/8039/ And instructions for getting up and running the v2.0 API code are here: RunningQuantumV2Api.

There are still some gaps between the code and the current planned API, but we're looking to close them soon.

You're encouraged to look through the code once you read this overview.

Summary
The v2.0 API represents a combination of the Quantum v1.1 API with some of the most essential IPAM capabilities from the Melange API. These IPAM capabilities focus on being able to associate IP address blocks and other network configuration required by a network device (e.g., default gateway, dns-servers) with a Quantum Network, and then being able to allocate an IP address out of such a block and associate it with a device that is attached to the network via a Quantum Port.

The v2.0 API does this by introducing a new enity, called a Subnet. Subnets can represent either a v4 or v6 address block, and each Quantum Network commonly has one or more subnets. When a port is created on the network, by default it will be allocated an available fixed IP address out of one the designated subnets for each IP version. When the Port is destroyed, the allocated addresses return to the pool of available IPs on the subnet.

Basic high-level flow:


 * Tenant creates a network (e.g., "net1")
 * Tenant associates a subnet with that network (e.g., "10.0.0.0/24") (may be combined with step above)
 * Tenant boots a VM, specifying a single NIC connected to "net1".
 * Nova contacts Quantum and creates a port1 on net1. port1 is assigned IP (e.g., 10.0.0.2).
 * Tenant destroys VM.
 * Nova contacts Quantum and destroys port1. IP (e.g., 10.0.0.2) is returned to pool.

The API supports many more options and some alternative flows (e.g., user requesting an IP), but the above flow is a good place to start.

More advanced capabilities, including Security Groups, L3-forwarding between different Quantum Networks, Floating IPs, etc. will be implemented as API extensions in Folsom.

Entities Details
All entities support the basic CRUD operations with POST/GET/PUT/DELETE operations on an entity + UUID URL (e.g., /v2.0/networks/98bd8391-199f-4440-824d-8659e4906786) as well as search operations with filtering using a GET on the base entity URL (e.g., /v2.0/networks ).

Note: current code uses underscores in attribute names, but may change to camel-case or dashes to be more inline with other openstack apis (Question: is there an openstack API "style guide" anywhere for consistency details like this?).

Network
/v2.0/networks

Subnet
/v2.0/subnets

Port
/v2.0/ports

params="{\"network\": {\"tenant_id\": \"default\", \"name\": \"net1\", \"admin_state_up\": true}}"

Basic JSON example
Create a network, a subnet on that network, and a port on that network. Remember that the port is likely to be created by Nova on behalf of a tenant.

POST /v2.0/networks

Request:

{ "network": { "name" : "net1" "tenant_id": a4fc5328-c270-4891-845a-e61c9153d261 "admin_state_up": true } }

Response:

{  "network": { "status": "ACTIVE", "subnets": [], "name": "net1", "admin_state_up": true, "tenant_id": "a4fc5328-c270-4891-845a-e61c9153d261", "id": "c4863456-2c40-44f2-ab9f-63f978a8a4f3" } }

POST /v2.0/subnets

Request:

{ "subnet": { "network_id": "98bd8391-199f-4440-824d-8659e4906786", "ip_version": 4, "cidr": "10.0.0.0/24", } }

Response:

{ "subnet": { "id": "e76a23fe-b028-47b8-a765-858b65c0f857", "network_id": "98bd8391-199f-4440-824d-8659e4906786", "ip_version": 4, "cidr": "10.0.0.0/24", "gateway_ip": "10.0.0.1", "dns_nameservers": ["8.8.8.8"], "allocation_pools": [ { "start" : "10.0.0.2", "end": "10.0.0.254"}], "host_routes": [], } }

POST /v2.0/ports

{ "port": { "network_id": "98bd8391-199f-4440-824d-8659e4906786", "device_id": "32aeb491-4e78-4c24-8ab8-363daa65aa4d" } }

Response:

{ "port": { "id": "b08a3807-5d3b-4ab8-95ce-3ed5aa28bdf6", "network_id": "98bd8391-199f-4440-824d-8659e4906786", "admin_state_up": True, "status": "ACTIVE", "mac_address": "ca:fe:de:ad:be:ef", "fixed_ips": [ "10.0.0.2" ], "host_routes": [ { "destination": "0.0.0.0/0", "nexthop" : "10.0.0.1" }, { "destination": "10.0.0.0/24", "nexthop": Null }], "device_id": "32aeb491-4e78-4c24-8ab8-363daa65aa4d", } }

Other capabilities

 * supports filtering based on all top level attributes of an API entity. For example, GET /v2.0/networks?name=foobar
 * by default, returns all attributes for any Show or List call. Has mechanism to limit the set of attributes returned (e.g., return just 'id').  Also has "verbose" mechanism to 'explode' UUID references within a returned object.  For example, doing a GET on network, and having a GET on a network return the fully populated data for all associated subnets.

Notable Non-IPAM Changes from v1.1

 * ports are flattened to be a top level resource. Goal was to be able to search over ports without knowing net-id, and have searches return results from multiple networks (e.g., all ports associated with a device)
 * bulk create operations for networks, ports, and subnets (idea is to more efficiently handle creating many items?)
 * tenant-id is not longer represented in the URL. This is more inline with other openstack services.
 * no notion of an attachment and attachment-id. Instead, service integrating with Quantum (e.g., Nova) must be aware of port-ids, and communicate the binding between a port-id and a vswitch/pswitch port to Quantum.  This simplifies the API, and the Nova / Quantum integration.

Open Questions
(not a complete list, please add)


 * Does each subnet + port need a tenant-id, or does it inherit the tenant-id of the network? How does this interact with the Authz need to delegate control of a port?
 * With bulk create, how are errors handled if there is a failure in adding one of the items?
 * How to best represent fixed IPs on a port? How to best view the allocated IPs on a subnet?  Should ports have a reference to the subnet so you can easily get all ports with IPs on the subnet?  Or should subnet have attribute or sub-url for all allocated ports?
 * How about modifying the fixed_ips_v* fields of Port to be addresses + prefix length or, better, (IP address, subnet ID) pairs? In that case, only one fixed_ips field is necessary, since each subnet indicates the IP version, and we can have a list mixing IPv4 and IPv6 addresses: [{"address": "192.168.1.1", "subnet_id": "fabdaafb-a723-4e59-8b0a-3d28239df66a"}, {"address": "fe80::ca2a:14ff:fe43:...", "subnet_id": "..."}].
 * Is there no way of detaching a interface from a port or moving it between networks now? (Or could this still be achieved on the nova side of things?)
 * It would be nice if, as well as the this API documentation, there was a description of how you bind an interface (or tunnel endpoint, or whatever else) to a port. It's nicer to have it written out than having to reason it out of the QuantumManager and friends.
 * How do we specify some kind of limit on the 'list' attributes? I suspect we would not want to allow someone specifying a thousand DNS servers for a subnet.  Should all list attributes have a MAX_LEN specified?
 * Do we need port to have hosts information, the subnet's hosts are not enough?