Hello again,
To get the ball rolling I've spent some time over the weekend working on an OCCI Walkthrough (following in the footsteps of Sun's excellent HelloCloud document). It captures the latest thinking and feedback received from many of you over the past few weeks and is intended as a simple (if technical) introduction to new users.
As you can see we are about as close to raw HTTP as we'll ever get, and the use of HTML forms for many operations trivialises implementation on both the server and client side. Shifting further towards a document-based "Resource Oriented Architecture" results in an API that "just makes sense" and is extremely (horizontally) scalable. Multiple representations also allow us to lock down what we need to for interoperability (e.g. the simple OCCI descriptor format) while enabling providers to innovate and differentiate (safely) by supporting various formats (e.g. VMD, VMDK, VMX, OVF, etc.) and features (e.g. auditing, change control, security, etc.).
Anwyay without further ado, current version's copied below and latest version's in the wiki.
Sam
The Open Cloud Computing Interface (OCCI) is an API for managing cloud infrastructure services (also known as Infrastructure as a Service or IaaS) which strictly adheres to REpresentational State Transfer (REST) principles and is closely tied to HyperText Tranfer Protocol (HTTP). For simplicity and scalability reasons it specifically avoids Remote Procedure Call (RPC) style interfaces and can essentially be implemented as a horizontally scalable document repository with which both nodes and clients interact.
This document describes a step-by-step walkthrough of performing various tasks as at the time of writing.
As the resource itself (e.g. a physical machine, storage array or network switch) cannot be transferred over HTTP (at least not yet!) we instead make available one or more representations of that resource. For example, an API modeling a person might return a picture, fingerprints, identity document(s) or even a digitised DNA sequence, but not the person themselves. A circle might be represented by SVG drawing primatives or any three distinct points on the curve. For cloud infrastructure there are many useful representations, and while OCCI standardises a number of them for interoperability purposes, an implementation is free to implement others in order to best serve the specific needs of their users and to differentiate from other offerings. Other examples include:
The client indicates which representation(s) it desires by way of the URL and/or HTTP Accept headers (e.g. HTTP Content Negotiation) and if the server is unable to satisfy the request then it should return HTTP 406 Not Acceptable.
In addition to the protocol itself, OCCI defines a simple key/value based descriptor format for cloud infrastructure resources:
Given the simplicity of the format it is trivial to translate between wire formats including plain text, JSON, XML and others. For example:
compute.cores 2
compute.speed 3200
compute.memory 2048
Each resource is identified by its' dereferenceable URL which is by definition unique, giving information about the origin and type of the resource as well as a local identifier (the combination of which forms a globally unique compound key). The primary drawback is that the more information that goes into the key (and therefore the more transparent it is), the more likely it is to change. For example, if you migrate a resource from one implementation to another then its' identifier will change (though in this instance the source should provide a HTTP 301 Moved Permanently response along with the new location, assuming it is known, or HTTP 410 Gone otherwise).
In order to realise the benefit of transparent, dereferenceable identifiers while still being able to track resources through their entire lifecycle an immutable UUID attribute should be allocated which will remain with the resource throughout its' life. This is particularly important where the same resource (e.g. a network) appears in multiple places.
New implementations should use type 4 (random) UUIDs anyway, as these can be safely allocated by any node without consulting a register/sequence, but where existing identifiers are available they should be used instead (e.g. http://amazon.com/compute/ami-ef48af86).
To create a resource simply POST it to the appropropriate collection (e.g. /compute, /network or /storage) as an HTML form (supported by virtually all user agents) or in another supported format (e.g. OVF):
POST /compute HTTP/1.1
Host: example.com
Content-Length: 35
Content-Type: application/x-www-form-urlencoded
compute.cores=2&compute.memory=2048
If this was successful the server will automatically allocate an identifier and return HTTP 200 OK along with a Location: header pointing at the newly created resource. You may also PUT the resource directly in place if you already know its' identifier or will be generating it on the client side:
PUT /compute/b10fa926-41a6-4125-ae94-bfad2670ca87 HTTP/1.1
Host: example.com
Content-Length: 35
Content-Type: application/occi+text
compute.cores 2
compute.memory 2048
Rather than generating the new resource from scratch you may also be given the option to GET a template and POST or PUT it back (for example, where "small", "medium" and "large" instances or pre-configured appliances are offered).
GET /compute/b10fa926-41a6-4125-ae94-bfad2670ca87 HTTP/1.1
Host: example.com
This will return a HTTP 300 Multiple Choices response containing a list of available representations for the resource as well as a suggestion in the form of a HTTP Location: header of the default rendering, which should be HTML (thereby allowing standard browsers to access the API directly). An arbitrary number of alternatives may also be returned by way of HTTP Link: headers.
If you just need to know what representations are available you should make a HEAD request instead of a GET - this will return the metadata in the headers without the default rendering.
Some requests (such as searches) will need to return a collection of resources. There are two options:
DELETE /compute/b10fa926-41a6-4125-ae94-bfad2670ca87 HTTP/1.1
Host: example.com
Each resource may expose collections for functions such as logging, auditing, change control, documentation and other operations (e.g. http://example.com/compute/123/log/456) in addition to any required by OCCI. As usual CRUD operations map to HTTP verbs (as above) and clients can either PUT entries directly if they know or will generate the identifiers, or POST them to the collection if this will be handled on the server side (using POST Once Exactly (POE) to ensure idempotency).
Requests are used to trigger state changes and other operations such as backups, snapshots, migrations and invasive reconfigurations (such as storage resource resizing). Those that do not complete immediately (returning HTTP 200 OK or similar) must be handled asynchronously (returning HTTP 201 Accepted or similar).
POST /compute/123/requests HTTP/1.1
Host: example.com
Content-Length: 35
Content-Type: application/x-www-form-urlencoded
state=shutdown&type=acpioff
The actual operation may not start immediately (for example, backups which are only handled daily at midnight) and may take some time to complete (for example a secure erase which requires multiple passes over the disk). Clients can poll for status periodically or use server push (or a non-HTTP technology such as XMPP) to monitor for events.