You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltacloud.apache.org by lu...@apache.org on 2011/08/06 01:10:32 UTC

svn commit: r1154412 [2/3] - in /incubator/deltacloud/trunk/site: content/api.mdown output/api.html

Modified: incubator/deltacloud/trunk/site/content/api.mdown
URL: http://svn.apache.org/viewvc/incubator/deltacloud/trunk/site/content/api.mdown?rev=1154412&r1=1154411&r2=1154412&view=diff
==============================================================================
--- incubator/deltacloud/trunk/site/content/api.mdown (original)
+++ incubator/deltacloud/trunk/site/content/api.mdown Fri Aug  5 23:10:32 2011
@@ -1,5 +1,5 @@
 ---
-title: Deltacloud - Documentation
+title: Deltacloud - Documentation - REST API and Developer Guide
 area: documentation
 extension: html
 filter:
@@ -7,310 +7,3364 @@ filter:
   - outline
 ---
 
-[basic-relationships]: styles/basic-relationships.png
+# Apache Deltacloud API
 
-# Deltacloud API
+<a name=toc>
 
-<toc numbering="off" toc_style="ul" toc_range='h2-h3' />
+<toc numbering="off" toc_style="ul" toc_range='h2-h4' />
 
-The Deltacloud API is built as a service-based REST API. You do not
-directly link a Deltacloud library into your program to use it.
-Instead, a client speaks the Deltacloud API over HTTP to a server
-which implements the REST interface.
+* * *
 
-Since cloud providers use their own APIs instead of the Deltacloud
-API, we provide a translation layer that makes it possible to use
-Deltacloud with these providers.
-
-## REST
-
-The Deltacloud API is a [RESTful API][1], using HATEOAS architectural
-style. The API requires no client-side URL construction. Access is
-based entirely off a single entry-point resource. This allows other
-implementors to structure their URL space however they like.
-
-[1]: http://en.wikipedia.org/wiki/Representational_State_Transfer
-
-Additionally, the Deltacloud API uses _content negotiation_ to
-determine the format of the returned representation. As of the current
-revision, the only required representation is XML. Clients wishing to
-receive XML representations must specify the HTTP `Accept` header as
-`application/xml`.
-
-## Authentication
-
-The Deltacloud API uses HTTP authentication methods for authenticating
-a given client. There is no explicit _login_ action required. If
-authentication is required, an HTTP status of 401 will be returned to
-challenge for credentials.
+## 1. Introduction
+
+Apache Deltacloud is a REST-based (HATEOAS) cloud abstraction API, that enables
+management of resources in different IaaS clouds using a single API. A series of
+ back-end drivers 'speak' each cloud provider's native API and the Deltacloud Core
+ Framework provides the basis for implementing drivers as needed for other/new IaaS
+cloud providers. Apache Deltacloud currently supports many back-end cloud providers,
+ as listed in [Drivers](./drivers.html).
+
+The Apache Deltacloud project empowers its users in avoiding lockin to any single
+cloud provider. Deltacloud provides an API abstraction that can be implemented as a
+ wrapper around a large number of clouds, freeing users of cloud from dealing with the
+particulars of each cloud's API.
+
+* * *
+
+### 1.1 Collections
+
+The following terms represent the abstractions used in the Apache Deltacloud API and
+are introduced here to aid the reader. Each represents an entity in the 'back-end'
+provider cloud such as a running virtual server or a server image. It should be
+noted that not all clouds support all of the following entity collections. Only
+ the appropriate entity collections are exposed for a given back-end driver
+(e.g. the Microsoft Azure driver currently exposes only the 'Buckets' collection).
+
+##### Realms
+
+A distinct organizational unit within the back-end cloud such as a datacenter.
+A realm may but does not necessarily represent the geographical location of the
+compute resources being accessed.
+
+##### Instances
+
+ A realized virtual server, running in a given back-end cloud. These are instantiated
+from server Images.
+
+##### Images
+
+These are templates (virtual machine images) from which Instances are created.
+Each Image defines the root partition and initial storage for the Instance operating system.
+
+##### Instance States
+
+These represent the Instance lifecycle; at any time an Instance will be in one of
+ *start, pending, running, stopped, shutting_down, finished*.
+
+##### Keys
+
+These represent credentials used to access a running Instance. These can be of type
+*key* (e.g., an *RSA* key), or of type *password* (i.e., with *username* and
+*password* attributes).
+
+##### Storage_Volume
+
+This is a virtual storage device that can be attached to an Instance and mounted
+by the OS therein.
+
+##### Storage_Snapshot
+
+These are copies, snapshots of a Storage_Volume at a specified point in time.
+
+##### Bucket
+
+A container for data blobs. The organisational unit of a generic *key* ==> *value*
+ based data store (such as Rackspace CloudFiles or Amazon S3). Individual data
+items, *Blobs*, are exposed as a subcollection under a bucket.
+
+##### Blob
+
+A generic binary data item that exists with a specified bucket (an `object' in
+ Amazon S3 and Rackspace CloudFiles).
+
+##### Address
+
+Represents an IP addresses. Depending on the back-end cloud provider addresses
+can be 'public' in which case they represent a unique, globally routable IP
+address, or 'private' in which case they represent an address routable only
+within a private network.
+
+##### Load Balancer
+
+Allows distribution of ingress network traffic received by a specified IP address
+to a number of instances.
+
+##### Firewalls
+
+Represent sets of rules that govern the accessibility of a running instance over
+the public Internet
+
+<br/>
+[Contents](#toc)
+<br/>
+* * *
+
+### 1.2 Client Requests
+
+In keeping with REST, clients make requests through HTTP, with the usual
+meanings assigned to the standard HTTP verbs GET, POST, PUT, and DELETE.
+
+Beyond the generally accepted REST design principles, Apache Deltacloud
+follows the guidelines discussed in the Fedora Project [Cloud APIs Rest Style Guide](http://fedoraproject.org/wiki/Cloud_APIs_REST_Style_Guide "Fedora Cloud APIs REST Style Guide").
+
+The URL space of the API is structured into collections of resources
+(entities, objects). The top level entities used in the Deltacloud API are:
+Realms, Images, Instance States, Instances, Keys, Storage Volume,
+Storage Snapshots, Blob Storage.
+
+
+<br/>
+[Contents](#toc)
+<br/>
+* * *
+
+### 1.3 Authentication
+
+The Deltacloud API server is stateless, and does not keep any information
+about the current client. In particular, it does not store the credentials for
+the backend cloud it is talking to. Instead, it uses HTTP basic authentication,
+and clients have to send the username/password for the backend cloud on every request.
+
+The specifics of what needs to be sent varies from cloud to cloud; some
+cloud providers employ a username and password for API access, whilst
+others use special-purpose API keys. A list of the credentials that a given
+cloud provider expects for API access is [available here](documentation.html)
+
+<br/>
+[Contents](#toc)
+<br/>
+* * *
+
+### 1.4 Server responses
+
+The server can respond to client requests in a variety of formats. The
+appropriate response format is determined by HTTP content negotiation.
+The primary format is XML, which is the basis for this document. Output is
+also available as JSON and, mostly for testing, as HTML. Clients can also
+explicitly request a specific response format by including the
+'format=' request parameter (e.g., http://deltacloudserver.foo/api?format=xml
+or http://deltacloudserver.foo/api?format=json).
+
+In general and especially for the html inteface, list operations such as
+`GET /api/realms` will only provide a list of the objects of this resource type
+with only brief details; full details can be retrieved by making a request
+`GET /api/realms/:id` to the URL of the individual realm.
+
+<br/>
+[Contents](#toc)
+<br/>
+* * *
+
+### 1.5 API conventions
+
+Any XML element that represents an object, such as an instance has an
+href and a id attribute. The href provides the URL at which object-specific
+actions can be performed (e.g., a GET to the URL will give details
+of the object). The id provides an identifier of the object and this is unique
+within its collection (i.e., unique id for each Instance, Image, Realm etc).
+
+Generally, objects also have a human-readable name; the name is provided in a
+`<name/>` child element of the object’s container tag.
+
+<br/>
+[Contents](#toc)
+<br/>
+* * *
+
+### 1.6 API stability and evolution
+
+Future changes to the API will be made in a manner that allows old clients
+to work against newer versions of the the API server.
+
+The stability guarantees given by the Apache Deltacloud API imply that the
+following changes may happen in newer versions of the API:
+
+  * adding new collections, or supporting new operations on existing collections
+  * adding optional parameters to existing operations
+  * adding additional attributes and elements to the XML/JSON responses
+
+On the other hand, these changes would violate API stability and will therefore
+not be made:
+
+  * removing an operation on a collection
+  * making an optional parameter for an operation mandatory
+  * removing attributes or elements from XML responses
+
+<br/>
+[Contents](#toc)
+<br/>
+* * *
+
+### 1.7 Online documentation
+
+Automatically generated documentation can be accessed on every server running
+the Deltacloud Core API service through the URL `http://localhost:3001/api/docs/`.
+The documentation is both available in HTML and XML, though the XML format is not
+part of this specification, and may change in an incompatible way.
+
+
+<br/>
+[Contents](#toc)
+<br/>
+* * *
+
+## 2. The API entry point
+
+Any part of the official API can be reached through the main entry point,
+by default http://localhost:3001/api. The entry point list the resources
+the server knows about for the current cloud provider; for the Amazon EC2 driver for example, these are:
+
+* Instances
+* Instance states
+* Images
+* Realms
+* Hardware profiles
+* Keys
+* Buckets
+* Storage volumes
+* Storage snapshots
+* Load Balancers
+* Addresses
+* Firewalls
+
+`Example request:`
+
+    GET /api?format=xml HTTP/1.1
+    Authorization: Basic AU1J3UB2121Afd1DdyQWxLaTYTmJMNF4zTXBoRGdhMDh2RUw5ZDAN9zVXVa==
+    User-Agent: curl/7.20.1 (i386-redhat-linux-gnu)
+    Host: localhost:3001
+    Accept: */*
+
+`Server response:`
+
+    HTTP/1.1 200 OK
+    Content-Type: application/xml
+    Content-Length: 1439
+
+    <api driver='ec2' version='0.3.0'>
+      <link href='http://localhost:3001/api/instance_states' rel='instance_states'>
+      </link>
+      <link href='http://localhost:3001/api/drivers' rel='drivers'>
+      </link>
+      <link href='http://localhost:3001/api/addresses' rel='addresses'>
+      </link>
+      <link href='http://localhost:3001/api/hardware_profiles' rel='hardware_profiles'>
+      </link>
+      <link href='http://localhost:3001/api/firewalls' rel='firewalls'>
+      </link>
+      <link href='http://localhost:3001/api/storage_volumes' rel='storage_volumes'>
+      </link>
+      <link href='http://localhost:3001/api/images' rel='images'>
+        <feature name='owner_id'>
+        </feature>
+      </link>
+      <link href='http://localhost:3001/api/realms' rel='realms'>
+      </link>
+      <link href='http://localhost:3001/api/buckets' rel='buckets'>
+        <feature name='bucket_location'>
+        </feature>
+      </link>
+      <link href='http://localhost:3001/api/instances' rel='instances'>
+        <feature name='user_data'>
+        </feature>
+        <feature name='authentication_key'>
+        </feature>
+        <feature name='firewalls'>
+        </feature>
+        <feature name='instance_count'>
+        </feature>
+        <feature name='attach_snapshot'>
+        </feature>
+      </link>
+      <link href='http://localhost:3001/api/storage_snapshots' rel='storage_snapshots'>
+      </link>
+      <link href='http://localhost:3001/api/keys' rel='keys'>
+      </link>
+      <link href='http://localhost:3001/api/load_balancers' rel='load_balancers'>
+      </link>
+    </api>
 
-## Primary Entry Point
 
-Any Deltacloud implementor _must_ provide exactly one well-known URL
-as an entry-point. For example, `http://fancycloudprovider.com/api`.
+Specific implementations for the Apache Deltacloud API may not support all resource
+types defined by this API. For example, a Deltacloud instance pointing at a storage-only
+service will not expose compute resources like instances and hardware profiles.
+
+
+<br/>
+[Contents](#toc)
+<br/>
+* * *
+
+### 2.1 Features
+
+The Apache Deltacloud API defines the standard behavior and semantics
+for each of the resource types as a baseline for any API implementation; it
+is often desirable to enhance standard API behavior with specific features.
+The API also defines all the features that can be supported by an API
+implementation - each of them has a fixed, predefined meaning. As an
+example, the feature user-name indicates that a user-specified name can be
+assigned to an instance when it is created. Features are advertised in the
+top-level entry point as illustrated below:
+
+    <api driver='mock' version='0.3.0'>
+      ...
+      <link href='http://localhost:3001/api/instances' rel='instances'>
+        <feature name='hardware_profiles'></feature>
+        <feature name='user_name'></feature>
+        <feature name='authentication_key'></feature>
+      </link>
+      ...
+    </api>
 
-The result of this entry-point is a set of entry-points into other
-collections, such as _images_, _instances_, _hardware profiles_ and
-_realms_, among others.
+The following describes the features available to each collection in
+the Deltacloud API together with a brief description:
 
-Each collection is defined by a `<link>` tag with an `href` attribute
-which includes the fully-qualified URL to the collection (which _may_
-exist on different servers) and a `rel` attribute to denote which
-collection is being specified.
+    Feature                 Collection   Operation             Description
+    -------                 ----------   ---------             -----------
+    owner_id                Images       GET /api/images       Allows filtering of the
+                                                               image list by owner_id
+    --                      --           --                    --
+    user_name               Instances    POST /api/instances   Accept a user-defined name
+                                                               on instance creation
+    --                      --           --                    --
+    user_data               Instances    POST /api/instances   Provide user-defined data
+                                                               that is accessible by the
+                                                               running instance
+    --                      --           --                    --
+    user_iso                Instances    POST /api/instances   Provide a base64 encoded
+                                                               gzipped ISO file accessible
+                                                               as CD-ROM drive by the
+                                                               running instnace
+    --                      --           --                    --
+    user_files              Instances    POST /api/instances   Accept files that will be
+                                                               placed into the launched
+                                                               instance
+    --                      --           --                    --
+    firewalls               Instances    POST /api/instances   Put the instance into one
+                                                               or more firewalls on launch
+    --                      --           --                    --
+    authentication_key      Instances    POST /api/instances   Provide the authentication
+                                                               key to be used for
+                                                               accessing the instance
+    --                      --           --                    --
+    authentication_password Instances    POST /api/instances   Provide the password to be
+                                                               used to access the running
+                                                               instance
+    --                      --           --                    --
+    instance_count          Instances    POST /api/instances   Specify the number of
+                                                               instances to launch in
+                                                               one operation
+    --                      --           --                    --
+    attach_snapshot         Instances    POST /api/instances   Attach a storage_snapshot
+                                                               to an instance as a
+                                                               storage_volume
+    --                      --           --                    --
+    sandboxing              Instances    POST /api/instances   Launch a instance from
+                                                               a sandbox image
+                                                               (Gogrid specific)
+    --                      --           --                    --
+    bucket_location         Buckets      POST /api/buckets     Specify a location that
+                                                               the bucket should be
+                                                               created in (e.g.
+                                                               specific cloud-provider
+                                                               datacenter)
+
+<br/>
+[Contents](#toc)
+<br/>
+* * *
+
+## 3. Compute Resources
+
+The compute resources are ***instances, instance states, images, realms, hardware profiles,
+firewalls, load balancers, addresses*** and ***keys***.
+
+
+### 3.1 Realms
+
+A ***realm*** represents a boundary containing resources, such as a data
+center. The exact definition of a ***realm*** is left to the cloud provider.
+In some cases, a ***realm*** may represent different datacenters, different continents,
+or different pools of resources within a single datacenter. A cloud provider may
+insist that resources must all exist within a single ***realm*** in order to cooperate.
+For instance, storage volumes may only be allowed to be mounted to instances within
+the same ***realm***. Generally speaking, going from one ***realm*** to another within the same
+cloud may change many aspects of the cloud, such as SLA’s, pricing terms, etc.
+
+#### `GET /api/realms`
+
+List all realms. Can be filtered by adding a request parameter ***architecture***
+to the realms that support a specific ***architecture*** such as ***i386***. The example
+below shows the retrieval of all ***realms*** for the AWS EC2 driver, which correspond
+to EC2 "availability zones":
+
+`Example request:`
+
+    GET /api/realms?format=xml HTTP/1.1
+    Authorization: Basic AU1J3UB2121Afd1DdyQWxLaTYTmJMNF4zTXBoRGdhMDh2RUw5ZDAN9zVXVa==
+    User-Agent: curl/7.20.1 (i386-redhat-linux-gnu)
+    Host: localhost:3001
+    Accept: */*
+
+`Server response:`
+
+    HTTP/1.1 200 OK
+    Content-Type: application/xml
+    Content-Length: 639
+    <?xml version='1.0' encoding='utf-8' ?>
+    <realms>
+      <realm href='http://localhost:3001/api/realms/us-east-1a' id='us-east-1a'>
+        <name>us-east-1a</name>
+        <state>available</state>
+      </realm>
+      <realm href='http://localhost:3001/api/realms/us-east-1b' id='us-east-1b'>
+        <name>us-east-1b</name>
+        <state>available</state>
+      </realm>
+      <realm href='http://localhost:3001/api/realms/us-east-1c' id='us-east-1c'>
+        <name>us-east-1c</name>
+        <state>available</state>
+      </realm>
+      <realm href='http://localhost:3001/api/realms/us-east-1d' id='us-east-1d'>
+        <name>us-east-1d</name>
+        <state>available</state>
+      </realm>
+    </realms>
 
-    <api driver='ec2' version='1.0'>
-      <link href='http://fancycloudprovider.com/api/hardware_profiles' rel='hardware_profiles' />
-      <link href='http://fancycloudprovider.com/api/instance_states' rel='instance_states' />
-      <link href='http://fancycloudprovider.com/api/realms' rel='realms' />
-      <link href='http://fancycloudprovider.com/api/images' rel='images' />
-      <link href='http://fancycloudprovider.com/api/instances' rel='instances' />
-    </api>
+#### `GET /api/realms/:id`
 
-## Resources
+Provide the details of a ***realm***. Currently, these are a ***name***, a  ***state*** and a
+ ***limit** applicable to the current requester. The ***name*** is an arbitrary label
+with no specific meaning in the API. The ***state*** can be either ***AVAILABLE***
+ or ***UNAVAILABLE***. The example below shows the ***realm*** for the Rackspace driver.
+Since Rackspace does not currently have a notion of ***realms*** the Deltacloud
+Rackspace driver provides a single ***realm*** called 'US', signifying that all
+compute resources for that cloud provider are hosted in the United States:
+
+`Example request:`
+
+    GET /api/realms/us?format=xml HTTP/1.1
+    Authorization: Basic AU1J3UB2121Afd1DdyQWxLaTYTmJMNF4zTXBoRGdhMDh2RUw5ZDAN9zVXVa==
+    User-Agent: curl/7.20.1 (i386-redhat-linux-gnu)
+    Host: localhost:3002
+    Accept: */*
+
+`Server response:`
+
+    HTTP/1.1 200 OK
+    Content-Type: application/xml
+    Content-Length: 182
 
-From the primary entry-point, a client may follow the URL provided for
-a collection to retrieve the resources within that collection. The
-collection representation will include the full representations of the
-items within it, along with links to retrieve each item individually.
-
-![Basic relationships][basic-relationships]
-
-### Hardware Profiles
-
-Within a cloud provider a _hardware profile_ represents a
-configuration of resources upon which a machine may be deployed. A
-hardware profile defines aspects such as local disk storage, available
-RAM, and architecture. A future revision of the Deltacloud API will
-include more aspects, including number and speed of CPUs available.
-Each provider is free to define as many (or as few) hardware profiles
-as desired.
+    <?xml version='1.0' encoding='utf-8' ?>
+    <realm href='http://localhost:3001/api/realms/us' id='us'>
+        <name>United States</name>
+        <state>AVAILABLE</state>
+        <limit></limit>
+    </realm>
 
+<br/>
+[Contents](#toc)
+<br/>
+* * *
+
+### 3.2 Hardware Profiles
+
+A ***hardware profile*** describes the sizing of a virtual machine in a cloud and
+prescribes details such as how many virtual CPUs, how much memory or
+how much local storage an instance might have. The attributes of a ***hardware profile***
+consist of a human-readable ***name*** and a list of ***<property/>*** elements.
+Each property defines possible values along a sizing dimension.
+
+Since clouds differ sharply in how virtual machine sizing is represented
+and influenced, hardware profiles provide a generic mechanism to express sizing
+constraints. For each dimension (amount of memory etc.), the hardware
+profile can express one of the following:
+
+1. Size is **fixed** in this dimension, e.g. instances all have 2GB of memory, *or*
+2. Size can be varied freely within some **range**, e.g. instances can have
+   from 1GB to 4GB of memory, *or*
+3. Size can be chosen from a predefined set of values, an **enumeration**,
+   e.g., instances can have 512 MB, 1 GB or 4GB of memory.
+
+When creating a new ***instance***, a client must specify the ***hardware profile***
+on which the ***instance*** is based.
+
+In addition to the sizing constraints, a hardware profile may also indicate the
+parameters (if any) that can be specified by a client in ***instance*** operations.
+These user-defined, variable dimensions are denoted by a *\<param\>* XML tag within
+the given property. For instance, the following extract shows the *memory* dimension
+for a hardware profile that can be specified in the HTTP POST *create* operation of the
+***instances*** collection (i.e., creating a new instance). The given parameter must be
+specified using the name *hwp_memory*, its default value is *10240* but the client may
+specify a value in the range *7680* upto *15360*:
+
+    ...
+    <property kind='range' name='memory' unit='MB' value='10240'>
+        <param href='http://localhost:3003/api/instances' method='post' name='hwp_memory' operation='create' />
+        <range first='7680.0' last='15360' />
+    </property>
+    ...
+
+#### `GET /api/hardware_profiles`
+
+Produce a list if all ***hardware profiles*** availaible with this cloud. The example
+below lists the hardware profiles available in the Amazon EC2 cloud. As EC2 provides
+a set of pre-defined ***hardware profiles***, the properties of each dimension
+(memory,cpu etc) are of type *fixed*:
+
+`Example request:`
+
+    GET /api/hardware_profiles?format=xml HTTP/1.1
+    Authorization: Basic AU1J3UB2121Afd1DdyQWxLaTYTmJMNF4zTXBoRGdhMDh2RUw5ZDAN9zVXVa==
+    User-Agent: curl/7.20.1 (i386-redhat-linux-gnu)
+    Host: localhost:3001
+    Accept: */*
+
+`Server response:`
+
+    HTTP/1.1 200 OK
+    Content-Type: application/xml
+    Content-Length: 3896
+    <?xml version='1.0' encoding='utf-8' ?>
     <hardware_profiles>
-      <hardware_profile href='http://fancycloudprovider.com/api/hardware_profiles/m1-small' id='m1-small'>
-        <property kind='fixed' name='storage' unit='GB' value='160' />
+      <hardware_profile href='http://localhost:3001/api/hardware_profiles/t1.micro' id='t1.micro'>
+        <name>t1.micro</name>
+        <property kind='fixed' name='cpu' unit='count' value='1' />
+        <property kind='fixed' name='memory' unit='MB' value='645.12' />
         <property kind='fixed' name='architecture' unit='label' value='i386' />
+        <property kind='fixed' name='storage' unit='GB' value='160' />
+      </hardware_profile>
+      <hardware_profile href='http://localhost:3001/api/hardware_profiles/m1.small' id='m1.small'>
+        <name>m1.small</name>
         <property kind='fixed' name='cpu' unit='count' value='1' />
         <property kind='fixed' name='memory' unit='MB' value='1740.8' />
+        <property kind='fixed' name='architecture' unit='label' value='i386' />
+        <property kind='fixed' name='storage' unit='GB' value='160' />
       </hardware_profile>
-
-Each `<hardware_profile>` block shall contain an `href` attribute providing a
-URL to manipulate a specific profile, along with property elements for each
-attribute of the hardware.
-
-- **`id`**            is a unique identifier for the profile
-- **`property`**      describes each of the hardware aspects
-
-Properties have the following attributes:
-
-- **`name`**          the type of the property: *e.g.* `memory` or `storage`
-- **`unit`**          the units in which the value is specified: `MB`, `GB`, `count` or `label`
-- **`value`**         the actual value of the property. It depends on the specified unit: `1024`, `2` on `x86_64`
-- **`kind`**          describes the values to chose from.
-  - **`fixed`**         only the value specified in the property is available
-  - **`enum`**          a list of available values is provided
-  - **`range`**         available values are described by a numeric range
-
-When the `kind` is either an `enum` or a `range`, there must be two additional elements specified. One
-that specifies the allowed values and the second with a way of picking a value.
-
-In the non-fixed case, the `value` property attribute specifies the default value.
-
-      <hardware_profile href='http://fancycloudprovider.com/api/hardware_profiles/m1-xlarge' id='m1-xlarge'>
-        <property kind='enum' name='storage' unit='GB' value='1024'>
-          <param href='http://fancycloudprovider.com/api/instances' method='post' name='hwp_storage' operation='create' />
-          <enum>
-            <entry value='1024' />
-            <entry value='2048' />
-            <entry value='4096' />
-          </enum>
-        </property>
-        <property kind='fixed' name='architecture' unit='label' value='x86_64' />
+      <hardware_profile href='http://localhost:3001/api/hardware_profiles/m1.large' id='m1.large'>
+        <name>m1.large</name>
         <property kind='fixed' name='cpu' unit='count' value='4' />
-        <property kind='range' name='memory' unit='MB' value='12288'>
-          <param href='http://fancycloudprovider.com/api/instances' method='post' name='hwp_memory' operation='create' />
-          <range first='12288' last='32768' />
-        </property>
+        <property kind='fixed' name='memory' unit='MB' value='7680.0' />
+        <property kind='fixed' name='architecture' unit='label' value='x86_64' />
+        <property kind='fixed' name='storage' unit='GB' value='850' />
+      </hardware_profile>
+      <hardware_profile href='http://localhost:3001/api/hardware_profiles/m1.xlarge' id='m1.xlarge'>
+        <name>m1.xlarge</name>
+        <property kind='fixed' name='cpu' unit='count' value='8' />
+        <property kind='fixed' name='memory' unit='MB' value='15360' />
+        <property kind='fixed' name='architecture' unit='label' value='x86_64' />
+        <property kind='fixed' name='storage' unit='GB' value='1690' />
+      </hardware_profile>
+      <hardware_profile href='http://localhost:3001/api/hardware_profiles/c1.medium' id='c1.medium'>
+        <name>c1.medium</name>
+        <property kind='fixed' name='cpu' unit='count' value='5' />
+        <property kind='fixed' name='memory' unit='MB' value='1740.8' />
+        <property kind='fixed' name='architecture' unit='label' value='i386' />
+        <property kind='fixed' name='storage' unit='GB' value='350' />
+      </hardware_profile>
+      <hardware_profile href='http://localhost:3001/api/hardware_profiles/c1.xlarge' id='c1.xlarge'>
+        <name>c1.xlarge</name>
+        <property kind='fixed' name='cpu' unit='count' value='20' />
+        <property kind='fixed' name='memory' unit='MB' value='7168' />
+        <property kind='fixed' name='architecture' unit='label' value='x86_64' />
+        <property kind='fixed' name='storage' unit='GB' value='1690' />
+      </hardware_profile>
+      <hardware_profile href='http://localhost:3001/api/hardware_profiles/m2.xlarge' id='m2.xlarge'>
+        <name>m2.xlarge</name>
+        <property kind='fixed' name='cpu' unit='count' value='6.5' />
+        <property kind='fixed' name='memory' unit='MB' value='17510.4' />
+        <property kind='fixed' name='architecture' unit='label' value='x86_64' />
+        <property kind='fixed' name='storage' unit='GB' value='420' />
+      </hardware_profile>
+      <hardware_profile href='http://localhost:3001/api/hardware_profiles/m2.2xlarge' id='m2.2xlarge'>
+        <name>m2.2xlarge</name>
+        <property kind='fixed' name='cpu' unit='count' value='13' />
+        <property kind='fixed' name='memory' unit='MB' value='35020.8' />
+        <property kind='fixed' name='architecture' unit='label' value='x86_64' />
+        <property kind='fixed' name='storage' unit='GB' value='850' />
+      </hardware_profile>
+      <hardware_profile href='http://localhost:3001/api/hardware_profiles/m2.4xlarge' id='m2.4xlarge'>
+        <name>m2.4xlarge</name>
+        <property kind='fixed' name='cpu' unit='count' value='26' />
+        <property kind='fixed' name='memory' unit='MB' value='70041.6' />
+        <property kind='fixed' name='architecture' unit='label' value='x86_64' />
+        <property kind='fixed' name='storage' unit='GB' value='1690' />
       </hardware_profile>
     </hardware_profiles>
 
+#### `GET /api/hardware profiles/:id`
 
-At this time, hardware profile resources are immutable and read-only. In a
-future revision they may be mutable.
-
-### Realms
-
-Within a cloud provider a _realm_ represents a boundary containing
-resources. The exact definition of a realm is left to the cloud
-provider. In some cases, a realm may represent different datacenters,
-different continents, or different pools of resources within a single
-datacenter. A cloud provider may insist that resources must all exist
-within a single realm in order to cooperate. For instance, storage
-volumes may only be allowed to be mounted to instances within the same
-realm.
-
-    <realms>
-      <realm href="http://fancycloudprovider.com/api/realms/us" id='us'>
-        <name>United States</name>
-        <state>AVAILABLE</state>
-        <limit/>
-      </realm>
-      <realm href="http://fancycloudprovider.com/api/realms/eu" id='eu'>
-        <name>Europe</name>
-        <state>AVAILABLE</state>
-        <limit/>
-      </realm>
-    </realms>
-
-Each `<realm>` block shall contain an `href` attribute providing a URL
-to manipulate a specific realm, along with elements for each attribute
-of a realm.
-
-- **`id`**          A unique identifier for the realm
-- **`name`**        A short label
-- **`state`**       Indicator of the current state of a realm
-  - AVAILABLE
-  - UNAVAILABLE
-- **`limit`**       Limits applicable for the _current requester_
-
-### Images
-
-An _image_ is a platonic form of a machine. Images are not directly
-executable, but are a template for creating actual instances of
-machines.
-
-The instances collection will return a set of all images available to
-the current user.
+This call retrieves the details of a specific ***hardware profile***.
+The example below shows a request for the *m1-large* profile of the Deltacloud *mock* driver.
+ This ***hardware profile*** demonstrates the three different types of parameters (i.e.,
+ *fixed*, *range*, *enum*). The example shows that ***instances*** launched with this
+ ***hardware profile*** will have exactly *2* virtual CPUs, memory in the range *7.5* to
+*15GB* and local storage that can either be 850MB or 1GB. The default value for
+each dimension is indicated by the value attribute on the property element:
+
+
+`Example request:`
+
+    GET /api/hardware_profiles/m1-large?format=xml HTTP/1.1
+    Authorization: Basic bW9ja3VzZXI6bW9ja3Bhc3N3b3Jk
+    User-Agent: curl/7.20.1 (i386-redhat-linux-gnu)
+    Host: localhost:3003
+    Accept: */*
+
+`Server response:`
+
+    HTTP/1.1 200 OK
+    Content-Type: application/xml
+    Content-Length: 808
+
+    <?xml version='1.0' encoding='utf-8' ?>
+    <hardware_profile href='http://localhost:3003/api/hardware_profiles/m1-large' id='m1-large'>
+      <name>m1-large</name>
+      <property kind='fixed' name='cpu' unit='count' value='2' />
+      <property kind='range' name='memory' unit='MB' value='10240'>
+        <param href='http://localhost:3003/api/instances' method='post' name='hwp_memory' operation='create' />
+        <range first='7680.0' last='15360' />
+      </property>
+      <property kind='enum' name='storage' unit='GB' value='850'>
+        <param href='http://localhost:3003/api/instances' method='post' name='hwp_storage' operation='create' />
+        <enum>
+          <entry value='850' />
+          <entry value='1024' />
+        </enum>
+      </property>
+      <property kind='fixed' name='architecture' unit='label' value='x86_64' />
+    </hardware_profile>
+
+<br/>
+[Contents](#toc)
+<br/>
+* * *
+
+### 3.3 Images
+
+***Images*** are used to launch ***instances***. Each ***image*** represents
+a virtual machine image in the back-end cloud, containing the root
+partition and initial storage for an instance operating system.
+
+An ***image*** has human-readable *name* and *description*, an *owner_id*
+that identifies the user account to which the ***image*** belongs, as well as
+an *architecture* and a *state*. The *architecture* attribute refers to whether the
+***image*** will create an ***instance*** with *32* or *64* bit processor; the values
+that the Deltacloud server returns for this attribute are thus *i386* and *x86_64* respectively.
+The *state* attribute is as reported by the cloud provider and so will vary between back-end clouds.
+For example AWS EC2 ***image*** state can be one of *AVAILABLE*, *PENDING* or *FAILED*
+whereas Rackspace Cloudservers ***image*** state can be one of *UNKNOWN*, *PREPARING*,
+ *ACTIVE*, *QUEUED* or *FAILED*. Finally, each ***image*** also contains an \<actions\>
+attribute that specifies the URI to which a client may issue a **HTTP POST** for creation of
+an ***instance*** from the given ***image***.
+
+#### `GET /api/images`
+
+Return a list of all ***images*** available in the back-end cloud. By default this call will
+return **all** images that are available to the given user account. Optionally a client
+may restrict the list of ***images*** returned by specifying the **owner_id** or **architecture**
+parameters in the request (**architecture** is one of *x86_64* for 64-bit processors or *i386*
+for 32-bit processors). The example below restricts the image list to **64-bit** architecture images
+belonging to **owner_id 023801271342**:
+
+`Example request:`
+
+    GET /api/images?owner_id=023801271342&architecture=x86_64&format=xml HTTP/1.1
+    Authorization: Basic AU1J3UB2121Afd1DdyQWxLaTYTmJMNF4zTXBoRGdhMDh2RUw5ZDAN9zVXVa==
+    User-Agent: curl/7.20.1 (i386-redhat-linux-gnu)
+    Host: localhost:3001
+    Accept: */*
+
+`Server response:`
+
+    HTTP/1.1 200 OK
+    Content-Type: application/xml
+    Content-Length: 1971
 
+    <?xml version='1.0' encoding='utf-8' ?>
     <images>
-      <image href="http://fancycloudprovider.com/api/images/img1" id='img1'>
-        <owner_id>fedoraproject</owner_id>
-        <name>Fedora 10</name>
-        <description>Fedora 10</description>
+      <image href='http://localhost:3001/api/images/ami-eea35787' id='ami-eea35787'>
+        <name>sles-10-sp3-v1.00.x86_64</name>
+        <owner_id>013907871322</owner_id>
+        <description>SUSE Linux Enterprise Server 10 Service Pack 3 for x86_64 (v1.00)</description>
         <architecture>x86_64</architecture>
+        <state></state>
+        <actions>
+          <link href='http://localhost:3001/api/instances;image_id=ami-eea35787' method='post' rel='create_instance' />
+        </actions>
       </image>
-      <image href="http://fancycloudprovider.com/api/images/img2" id='img2'>
-        <owner_id>fedoraproject</owner_id>
-        <name>Fedora 10</name>
-        <description>Fedora 10</description>
-        <architecture>i386</architecture>
+      <image href='http://localhost:3001/api/images/ami-6e649707' id='ami-6e649707'>
+        <name>sles-11-sp1-hvm-v1.00.x86_64</name>
+        <owner_id>013907871322</owner_id>
+        <description>SUSE Linux Enterprise Server 11 Service Pack 1 for HVM x86_64 (v1.00)</description>
+        <architecture>x86_64</architecture>
+        <state></state>
+        <actions>
+          <link href='http://localhost:3001/api/instances;image_id=ami-6e649707' method='post' rel='create_instance' />
+        </actions>
       </image>
-      <image href="http://fancycloudprovider.com/api/images/img3" id='img3'>
-        <owner_id>ted</owner_id>
-        <name>JBoss</name>
-        <description>JBoss</description>
-        <architecture>i386</architecture>
+      <image href='http://localhost:3001/api/images/ami-e4a7558d' id='ami-e4a7558d'>
+        <name>sles-11-sp1-hvm-v1.01.x86_64</name>
+        <owner_id>013907871322</owner_id>
+        <description>SUSE Linux Enterprise Server 11 Service Pack 1 for HVM x86_64 (v1.01)</description>
+        <architecture>x86_64</architecture>
+        <state></state>
+        <actions>
+          <link href='http://localhost:3001/api/instances;image_id=ami-e4a7558d' method='post' rel='create_instance' />
+        </actions>
+      </image>
+      <image href='http://localhost:3001/api/images/ami-e4a3578d' id='ami-e4a3578d'>
+        <name>sles-11-sp1-v1.00.x86_64</name>
+        <owner_id>013907871322</owner_id>
+        <description>SUSE Linux Enterprise Server 11 Service Pack 1 for x86_64 (v1.00)</description>
+        <architecture>x86_64</architecture>
+        <state></state>
+        <actions>
+          <link href='http://localhost:3001/api/instances;image_id=ami-e4a3578d' method='post' rel='create_instance' />
+        </actions>
       </image>
     </images>
 
-Each `<image>` block _shall_ contain an `href` attribute providing a
-URL to manipulate a specific image, along with elements for each
-attribute of an image. Each element, including those for optional
-attributes must be present. Optional attributes may be specified as a
-element with empty content.
-
-These attributes include
-
-- **`id`**            A unique identifier for the image
-- **`owner_id`**      An opaque identifier which indicates the owner of an image
-- **`name`**          An _optional_ short label describing the image
-- **`description`**   An _optional_ description describing the image more fully
-- **`architecture`**  A description of the machine architecture of the image
-  which may contain values such as:
-  - `i386`
-  - `x86_64`
-
-At this time, image resources are immutable and read-only.  In a future revision
-they will be mutable.
-
-### Instances
-
-An _instance_ is a concrete machine realized from an _image_. The
-images collection may be obtained by following the link from the
-primary entry-point.
+#### `GET /api/images/:id`
 
-    <instances>
-      <instance href="http://fancycloudprovider.com/api/instances/inst1" id='inst1'>
-        <owner_id>larry</owner_id>
-        <name>Production JBoss Instance</name>
-        <image href="http://fancycloudprovider.com/api/images/img3"/>
-        <hardware_profile href="http://fancycloudprovider.com/api/hardware_profiles/m1-small"/>
-        <realm href="http://fancycloudprovider.com/api/realms/us"/>
+Retrieve the description of a specific ***image***.
 
+`Example request:`
+
+    GET /api/images/14?format=xml HTTP/1.1
+    Authorization: Basic AU1J3UB2121Afd1DdyQWxLaTYTmJMNF4zTXBoRGdhMDh2RUw5ZDAN9zVXVa==
+    User-Agent: curl/7.20.1 (i386-redhat-linux-gnu)
+    Host: localhost:3002
+    Accept: */*
+
+`Server response:`
+
+    HTTP/1.1 200 OK
+    Content-Type: application/xml
+    Content-Length: 433
+
+    <?xml version='1.0' encoding='utf-8' ?>
+    <image href='http://localhost:3002/api/images/14' id='14'>
+      <name>Red Hat Enterprise Linux 5.4</name>
+      <owner_id>jsmith</owner_id>
+      <description>Red Hat Enterprise Linux 5.4</description>
+      <architecture>x86_64</architecture>
+      <state>ACTIVE</state>
+      <actions>
+        <link href='http://localhost:3002/api/instances;image_id=14' method='post' rel='create_instance' />
+      </actions>
+    </image>
+
+#### `POST /api/images`
+
+Create a new ***image*** from an existing, running ***instance***. This operation is not
+available in all cloud providers and for some cloud providers this operation is not
+possible for all ***instances***. For example, in the Amazon EC2 cloud, a custom
+***image*** can be created from EBS backed ***instances*** but not from ***root-store***
+instances. The Deltacloud API provides a mechanism with which clients can determine whether
+a given ***instance*** may be saved as a custom ***image***. For those cases where
+***instance*** 'snapshot' is possible, the ***instance*** XML \<actions\> list will
+contain a **create_image** action that defines the URI for a client to use in creating
+the new image. For example:
+
+    ...
+    <actions>
+      <link href='http://localhost:3002/api/instances/20109341/reboot' method='post' rel='reboot' />
+      <link href='http://localhost:3002/api/instances/20109341/stop' method='post' rel='stop' />
+      <link href='http://localhost:3002/api/instances/20109341/run;id=20109341' method='post' rel='run' />
+      <link href='http://localhost:3002/api/images;instance_id=20109341' method='post' rel='create_image' />
+    </actions>
+    ...
+
+To create a new ***image*** the client must specify the *instance_id* of the running instance.
+ Optionally, the client may also provide a *name* and a *description*. The parameters are
+specified as multipart/form-data fields in the client POST. The Deltacloud server will
+respond to a successful operation with **HTTP 201 Created** and provide details of the
+newly created ***image***:
+
+
+
+`Example request:`
+
+    POST /api/images?format=xml HTTP/1.1
+    Authorization: Basic AU1J3UB2121Afd1DdyQWxLaTYTmJMNF4zTXBoRGdhMDh2RUw5ZDAN9zVXVa==
+    User-Agent: curl/7.20.1 (i386-redhat-linux-gnu)
+    Host: localhost:3002
+    Accept: */*
+    Content-Length: 404
+    Expect: 100-continue
+    Content-Type: multipart/form-data; boundary=----------------------------ba9acb193034
+
+    ------------------------------ba9acb193034
+    Content-Disposition: form-data; name="instance_id"
+
+    20109341
+    ------------------------------ba9acb193034
+    Content-Disposition: form-data; name="name"
+
+    customisedserver
+    ------------------------------ba9acb193034
+    Content-Disposition: form-data; name="description"
+
+    jsmith customised web server July 21 2011
+    ------------------------------ba9acb193034--
+
+
+`Server response:`
+
+    HTTP/1.1 201 Created
+    Content-Type: application/xml
+    Content-Length: 427
+
+    <?xml version='1.0' encoding='utf-8' ?>
+    <image href='http://localhost:3002/api/images/12346145' id='12346145'>
+      <name>customisedserver</name>
+      <owner_id>mandreou</owner_id>
+      <description>customisedserver</description>
+      <architecture>x86_64</architecture>
+      <state>QUEUED</state>
+      <actions>
+        <link href='http://localhost:3002/api/instances;image_id=12346145' method='post' rel='create_instance' />
+      </actions>
+    </image>
+
+
+#### `DELETE /api/images/:id`
+
+Deletes the specified ***image*** from the back-end cloud. The Deltacloud server
+will return a **HTTP 204 No Content** after a succesful operation:
+
+`Example request:`
+
+    DELETE /api/images/12346145?format=xml HTTP/1.1
+    Authorization: Basic AU1J3UB2121Afd1DdyQWxLaTYTmJMNF4zTXBoRGdhMDh2RUw5ZDAN9zVXVa==
+    User-Agent: curl/7.20.1 (i386-redhat-linux-gnu)
+    Host: localhost:3002
+    Accept: */*
+
+`Server response:`
+
+    HTTP/1.1 204 No Content
+
+<br/>
+[Contents](#toc)
+<br/>
+* * *
+
+### 3.4 Instance States
+
+Each cloud defines a slightly different lifecycle model for ***instances***. In some
+clouds, ***instances*** start running immediately after creation, in others, they
+enter a pending state and they need to be explicitly started to become
+running.
+
+These differences between clouds are modelled by expressing the lifecycle
+of an instance as a finite state machine and capturing this in a ***instance states***
+entity. The start state of the automaton is start and its final state is
+finished. The API defines the following states for an ***instance***:
+
+#####Instance states and their meanings:
+
+    State             Meaning
+    -----             -------
+    start             Instances are in this state before they are created
+    --
+    pending           Creation of the instance has been requested and is in progress
+    --
+    running           The instance is running
+    --
+    shutting-down     A shutdown has been requested for the instance and is in progress
+    --
+    stopped           The instance is stopped
+    --
+    finished          All resources for this instance have now been freed
+
+
+The actions (state transitions) possible for an ***instance*** are as shown below.
+The precise actions that can be performed on a specific ***instance*** are
+expressed as part of the details for that ***instance***.
+
+#####Instance actions and their meanings:
+
+    Action            Meaning
+    ------            -------
+    start             Start the instance
+    --
+    stop              Stop (and for some providers, Shutdown) the instance
+    --
+    reboot            Reboot the instance
+    --
+    destroy           Stop the instance and completely destroy it
+
+
+#### `GET /api/instance_states`
+
+This call retrieves the ***instance_states*** entity for a back-end cloud. The ***instance_states***
+entity defines the transitions possible between the various states of an ***instance***,
+and these are back-end cloud specific. In effect ***instance_states*** defines the finite state
+machine for ***instances*** from the given cloud.
+
+`Example request:`
+
+    GET /api/instance_states?format=xml HTTP/1.1
+    Authorization: Basic AU1J3UB2121Afd1DdyQWxLaTYTmJMNF4zTXBoRGdhMDh2RUw5ZDAN9zVXVa==
+    User-Agent: curl/7.20.1 (i386-redhat-linux-gnu)
+    Host: localhost:3002
+    Accept: */*
+
+`Server response:`
+
+    HTTP/1.1 200 OK
+    Content-Type: application/xml
+    Content-Length: 583
+
+    <states>
+      <state name='start'>
+        <transition action='create' to='pending'></transition>
+      </state>
+      <state name='pending'>
+        <transition auto='true' to='running'></transition>
+      </state>
+      <state name='running'>
+        <transition action='reboot' to='running'></transition>
+        <transition action='stop' to='shutting_down'></transition>
+      </state>
+      <state name='shutting_down'>
+        <transition auto='true' to='stopped'></transition>
+      </state>
+      <state name='stopped'>
+        <transition auto='true' to='finish'></transition>
+      </state>
+      <state name='finish'>
+      </state>
+    </states>
+
+
+<br/>
+[Contents](#toc)
+<br/>
+* * *
+
+### 3.5 Instances
+
+An ***instance*** represents the focus of all cloud compute activity: a running
+virtual machine. An ***instance*** is created from an ***image***, with a specified
+***hardware profile*** and in a given ***realm***. Each ***instance*** can have a
+number of other attributes, not all of which are exposed for all back-end cloud
+providers. The full list of possible ***instance*** attributes is:
+
+    Attribute           Meaning
+    ---------           -------
+    owner_id            The id of the cloud provider account that launched the instance
+    --
+    image_id            The id of the image from which the instance was launched
+    --
+    name                A human readable name for the instance given at launch time
+    --
+    realm_id            Realm into which the instance was launced
+    --
+    state               Current state of the instance (e.g., 'running')
+    --
+    actions             Actions that a client may effect on the instance, based on current state.
+    --
+    public_addresses    The globally routable IP address of the instance
+    --
+    private_addresses   The private IP address of the instance, routable within its private network
+    --
+    instance_profile    The specific values of memory, cpu, storage
+    --
+    launch_time         Timestamp at which the instance was launched
+    --
+    keyname             Name of authentication Key, if this method is used for authentication (e.g., EC2)
+    --
+    username            The username for authentication when connecting to the instance
+    --
+    password            The password used together with username above.
+    --
+    firewalls           The firewalls that this instance was launched into (EC2 specific)
+    --
+
+#### `GET /api/instances`
+
+Produce a listing of all current ***Instances*** in the given cloud (belonging to
+the specified account). The example shown below displays ***instances*** in the Amazon EC2 cloud:
+
+`Example request:`
+
+    GET /api/instances?format=xml HTTP/1.1
+    Authorization: Basic AU1J3UB2121Afd1DdyQWxLaTYTmJMNF4zTXBoRGdhMDh2RUw5ZDAN9zVXVa==
+    User-Agent: curl/7.20.1 (i386-redhat-linux-gnu)
+    Host: localhost:3001
+    Accept: */*
+
+
+`Client response:`
+
+    HTTP/1.1 200 OK
+    Content-Type: application/xml
+    Content-Length: 2790
+    <?xml version='1.0' encoding='utf-8' ?>
+    <instances>
+      <instance href='http://localhost:3001/api/instances/i-1fbc627e' id='i-1fbc627e'>
+        <name>ami-f51aff9c</name>
+        <owner_id>393485797142</owner_id>
+        <image href='http://localhost:3001/api/images/ami-f51aff9c' id='ami-f51aff9c'></image>
+        <realm href='http://localhost:3001/api/realms/us-east-1c' id='us-east-1c'></realm>
         <state>RUNNING</state>
+        <hardware_profile href='http://localhost:3001/api/hardware_profiles/c1.medium' id='c1.medium'>
+        </hardware_profile>
         <actions>
-          <link rel="reboot" href="http://fancycloudprovider.com/api/instances/inst1/reboot"/>
-          <link rel="stop" href="http://fancycloudprovider.com/api/instances/inst1/stop"/>
+          <link href='http://localhost:3001/api/instances/i-1fbc627e/reboot' method='post' rel='reboot' />
+          <link href='http://localhost:3001/api/instances/i-1fbc627e/stop' method='post' rel='stop' />
+          <link href='http://localhost:3001/api/instances/i-1fbc627e/run;id=i-1fbc627e' method='post' rel='run' />
         </actions>
-        <public_addresses>
-          <address>inst1.larry.fancycloudprovider.com</address>
-        </public_addresses>
-
-        <private_addresses>
-          <address>inst1.larry.internal</address>
-        </private_addresses>
+        <launch_time>2011-07-22T11:29:48.000Z</launch_time>
+        <public_addresses><address>ec2-50-16-183-107.compute-1.amazonaws.com</address></public_addresses>
+        <private_addresses><address>domU-12-31-39-0F-79-D4.compute-1.internal</address></private_addresses>
+        <firewalls>
+          <firewall href='http://localhost:3001/api/firewalls/default' id='default'></firewall>
+        </firewalls>
+        <authentication type='key'>
+          <login>
+            <keyname>eftah</keyname>
+          </login>
+        </authentication>
+      </instance>
+      <instance href='http://localhost:3001/api/instances/i-f3ba6492' id='i-f3ba6492'>
+        <name>ami-2b5fba42</name>
+        <owner_id>393485797142</owner_id>
+        <image href='http://localhost:3001/api/images/ami-2b5fba42' id='ami-2b5fba42'></image>
+        <realm href='http://localhost:3001/api/realms/us-east-1d' id='us-east-1d'></realm>
+        <state>RUNNING</state>
+        <hardware_profile href='http://localhost:3001/api/hardware_profiles/m1.small' id='m1.small'>
+        </hardware_profile>
+        <actions>
+          <link href='http://localhost:3001/api/instances/i-f3ba6492/reboot' method='post' rel='reboot' />
+          <link href='http://localhost:3001/api/instances/i-f3ba6492/stop' method='post' rel='stop' />
+          <link href='http://localhost:3001/api/instances/i-f3ba6492/run;id=i-f3ba6492' method='post' rel='run' />
+        </actions>
+        <launch_time>2011-07-22T11:32:25.000Z</launch_time>
+        <public_addresses><address>ec2-184-73-78-87.compute-1.amazonaws.com</address></public_addresses>
+        <private_addresses><address>ip-10-196-89-221.ec2.internal</address></private_addresses>
+        <firewalls>
+          <firewall href='http://localhost:3001/api/firewalls/default' id='default'></firewall>
+          <firewall href='http://localhost:3001/api/firewalls/test' id='test'></firewall>
+        </firewalls>
+        <authentication type='key'>
+          <login>
+            <keyname>eftah</keyname>
+          </login>
+        </authentication>
       </instance>
     </instances>
 
-Each `<instance>` block shall contain an href attribute providing a
-URL to manipulate a specific instance, along with elements for each
-attribute of an instance. Each element, including those for optional
-attributes must be present. Optional attributes may be specified as a
-element with empty content.
+#### `GET /api/instances/:id`
+
+Get the details for a specific ***Instance***. The example shown below is for an ***instance***
+launched in the Rackspace Cloudservers cloud. As can be seen, the authentication type used is
+**password** but the *username* and *password* attributes are blank. This is because Rackspace
+only reports these values once, during instance creation and not for subsequent requests.
+An example of the response from ***instance*** creation can be found under the
+[POST /api/instances](#create_instance) subsection below, showing how the*username*/*password*
+fields are populated.
+
+`Example request:`
+
+    GET /api/instances/20112212?format=xml HTTP/1.1
+    Authorization: Basic AU1J3UB2121Afd1DdyQWxLaTYTmJMNF4zTXBoRGdhMDh2RUw5ZDAN9zVXVa==
+    User-Agent: curl/7.20.1 (i386-redhat-linux-gnu)
+    Host: localhost:3002
+    Accept: */*
+
+`Server response:`
+<a name=get_instance> .
+    HTTP/1.1 200 OK
+    Content-Type: application/xml
+    Content-Length: 1167
+    <?xml version='1.0' encoding='utf-8' ?>
+    <instance href='http://localhost:3002/api/instances/20112212' id='20112212'>
+      <name>myserver</name>
+      <owner_id>mandreou</owner_id>
+      <image href='http://localhost:3002/api/images/53' id='53'></image>
+      <realm href='http://localhost:3002/api/realms/us' id='us'></realm>
+      <state>RUNNING</state>
+      <hardware_profile href='http://localhost:3002/api/hardware_profiles/1' id='1'>
+      </hardware_profile>
+      <actions>
+        <link href='http://localhost:3002/api/instances/20112212/reboot' method='post' rel='reboot' />
+        <link href='http://localhost:3002/api/instances/20112212/stop' method='post' rel='stop' />
+        <link href='http://localhost:3002/api/instances/20112212/run;id=20112212' method='post' rel='run' />
+        <link href='http://localhost:3002/api/images;instance_id=20112212' method='post' rel='create_image' />
+      </actions>
+      <public_addresses><address>50.57.116.72</address></public_addresses>
+      <private_addresses><address>10.182.143.64</address></private_addresses>
+      <authentication type='password'>
+        <login>
+          <username>root</username>
+          <password></password>
+        </login>
+      </authentication>
+    </instance>
+
+#### `POST /api/instances/:id/:action`
+
+The valid actions for an ***instance*** are specified by the ***instance_states*** entity.
+The set of permissible actions that a client may effect on an ***instance*** at a given time
+depends on the current ***instance state***. These are as reported by the \<actions\> attribute
+in the Deltacloud server response to a [GET /api/instances/:id](#get_instance) call. The first
+example shown below is to **reboot** a currently running instance, followed by a **stop**.
+
+Note that after invoking the **stop** operation, the ***instance*** state may be reported as **RUNNING**
+in the Deltacloud server response. This is because it may take some time for the ***instance*** state
+ to change in the backend cloud provider (and this will vary between providers). Subsequent requests
+ for either the list of ***instances*** or a specific ***instance*** will confirm that the action was
+ effected correctly.
+
+The Deltacloud server also allows a special 'run-on-instance' action for some cloud provider
+***instances***.This enables a client to perform a command on a running ***instance*** over
+**SSH** and the Deltacloud server will return the output of that command to the client.
+ Where available, this is reported as the **run** action in the list of ***instance***
+actions. The command to be executed on the running ***instance*** is specified by the
+**cmd** parameter, whilst authentication is specified either by the **private_key** parameter
+for cloud providers that expect key based authentication for connecting to ***instances***
+or the **password** parameter for those cloud providers that use a **username/password** for
+authentication. The last examples shown below illustrate the 'run-on-instance' feature for
+an Amazon EC2 ***instance*** and a Rackspace Cloudservers ***instance***. The two examples
+differ in how authentication is performed (private RSA Key for EC2 and username/password
+for Rackspace).
+
+`Example request: (reboot)`
+
+    POST /api/instances/i-f3ba6492/reboot?format=xml HTTP/1.1
+    Authorization: Basic AU1J3UB2121Afd1DdyQWxLaTYTmJMNF4zTXBoRGdhMDh2RUw5ZDAN9zVXVa==
+    User-Agent: curl/7.20.1 (i386-redhat-linux-gnu)
+    Host: localhost:3001
+    Accept: */*
+
+`Server response:`
+
+    HTTP/1.1 200 OK
+    Content-Type: application/xml
+    Content-Length: 1322
+
+    <?xml version='1.0' encoding='utf-8' ?>
+    <instance href='http://localhost:3001/api/instances/i-f3ba6492' id='i-f3ba6492'>
+      <name>ami-f51aff9c</name>
+      <owner_id>393485797142</owner_id>
+      <image href='http://localhost:3001/api/images/ami-f51aff9c' id='ami-f51aff9c'></image>
+      <realm href='http://localhost:3001/api/realms/us-east-1c' id='us-east-1c'></realm>
+      <state>RUNNING</state>
+      <hardware_profile href='http://localhost:3001/api/hardware_profiles/c1.medium' id='c1.medium'>
+      </hardware_profile>
+      <actions>
+        <link href='http://localhost:3001/api/instances/i-f3ba6492/reboot' method='post' rel='reboot' />
+        <link href='http://localhost:3001/api/instances/i-f3ba6492/stop' method='post' rel='stop' />
+        <link href='http://localhost:3001/api/instances/i-f3ba6492/run;id=i-f3ba6492' method='post' rel='run' />
+      </actions>
+      <launch_time>2011-07-22T11:29:48.000Z</launch_time>
+      <public_addresses><address>ec2-50-16-183-107.compute-1.amazonaws.com</address></public_addresses>
+      <private_addresses><address>domU-12-31-39-0F-79-D4.compute-1.internal</address></private_addresses>
+      <firewalls>  <firewall href='http://localhost:3001/api/firewalls/default' id='default'></firewall></firewalls>
+      <authentication type='key'>
+        <login>
+          <keyname>eftah</keyname>
+        </login>
+      </authentication>
+    </instance>
+
+`Example request: (stop)`
+
+    POST /api/instances/20112212/stop?format=xml HTTP/1.1
+    Authorization: Basic AU1J3UB2121Afd1DdyQWxLaTYTmJMNF4zTXBoRGdhMDh2RUw5ZDAN9zVXVa==
+    User-Agent: curl/7.20.1 (i386-redhat-linux-gnu)
+    Host: localhost:3002
+    Accept: */*
+
+`Server response:`
+
+    HTTP/1.1 200 OK
+    Content-Type: application/xml
+    Content-Length: 1167
+
+    <?xml version='1.0' encoding='utf-8' ?>
+    <instance href='http://localhost:3002/api/instances/20112212' id='20112212'>
+      <name>myserver</name>
+      <owner_id>mandreou</owner_id>
+      <image href='http://localhost:3002/api/images/53' id='53'></image>
+      <realm href='http://localhost:3002/api/realms/us' id='us'></realm>
+      <state>STOPPED</state>
+      <hardware_profile href='http://localhost:3002/api/hardware_profiles/1' id='1'>
+      </hardware_profile>
+      <actions>
+        <link href='http://localhost:3002/api/instances/20112212/reboot' method='post' rel='reboot' />
+        <link href='http://localhost:3002/api/instances/20112212/stop' method='post' rel='stop' />
+        <link href='http://localhost:3002/api/instances/20112212/run;id=20112212' method='post' rel='run' />
+        <link href='http://localhost:3002/api/images;instance_id=20112212' method='post' rel='create_image' />
+      </actions>
+      <public_addresses><address>50.57.116.72</address></public_addresses>
+      <private_addresses><address>10.182.143.64</address></private_addresses>
+      <authentication type='password'>
+        <login>
+          <username>root</username>
+          <password></password>
+        </login>
+      </authentication>
+    </instance>
+
+`Example request (run-on-instance Amazon EC2):`
+NOTE: run-on-instance requests to EC2 ***instances*** will fail with
+**502 Bad Gateway - Execution Expired** if the ***firewall*** in which the ***instance***
+was launched does not grant **SSH** access (tcp, port 22) to the requesting client's
+IP address. This access may be given using the [firewalls](#firewalls) collection.
+
+    POST /api/instances/i-afde73ce/run?format=xml HTTP/1.1
+    Authorization: Basic AU1J3UB2121Afd1DdyQWxLaTYTmJMNF4zTXBoRGdhMDh2RUw5ZDAN9zVXVa==
+    User-Agent: curl/7.20.1 (i386-redhat-linux-gnu)
+    Host: localhost:3001
+    Content-Length: 1927
+    Content-Type: multipart/form-data; boundary=----------------------------332ed6691ab8
+
+    ------------------------------332ed6691ab8
+    Content-Disposition: form-data; name="cmd"
+
+    uname -a; ls -l
+    ------------------------------332ed6691ab8
+    Content-Disposition: form-data; name="private_key"
+
+    -----BEGIN RSA PRIVATE KEY-----.BTTEpATBAAKDAQEA4t3R/PgUo3KDDuX4
+    vZZpZuXFkAA/5X2lFRY2/xsQqbPz9utPOsUoPf9Aajy+.vGRJrO2KAJ9U/JTNDzr
+    3NPbG3aHYPSnwsSxkFSG4Q6ukqYlxT9TPF/+wvdxfAtp3nYw3ZGuSX/DOtToWtQ8
+    F/+GvHTHKDQSB+TeEs1Sa/PFwxpspB+RqHbqOTWPsFOHL+9sZGTqd6D4B.R6DBNh
+    9Dabu9BVZrl5BTOKlbAgrKnzsGKvaBST/D2.AB/HB9/GOT36OoBmEr1y9gFwu4Xf
+    aKw+AXVf9y9TKxVD3TE5uB.oDZG8s4gr2e691xHG9YGzBBBbNzfFh94b3Td5JBGS
+    zRDTKYBfOgv+Zu5N+WyeaZ0ab50DwK9BXYB5hsRu5zbAqObbTZkwN9qwBOZHzATX
+    wVTZU+eTz.39OZPqu4fQwrBN13lDbUoZxlqT9g2+haQBB9sTDzQEZ08QKBgQDJyw
+    lBBZqQKBgQDz5E2rL59lNS5pBxDO9r6B9rXtBBTZ5tZUWNFRvyNsxY5nJT03.KDw
+    qo2VP5WDZeOhRWEUY96./pWN3hNFDkT44vDpeXQUh3rBHyD5DWvWxAze9Ds+UTO/
+    esuLwP5vXhfoYp6gV9XG.BEBzSVq8kZ2kZtlbWHTR/SGepTkDgYEA9zwHTDhtKR2
+    KS8/BSFZQ884ZqFkbwT9fTW6s0rgUSBDTUDgYEA9W5HXTOEPGFDnqBhKPLN.xD9D
+    vZZpZuXFkAA/5X2lFRY2/xsQqbPz9utPOsUoPf9Aajy+.vGRJrO2KAJ9U/JTNDzr
+    lBBZqQKBgQDz5E2rL59lNS5pBxDO9r6B9rXtBBTZ5tZUWNFRvyNsxY5nJT03.KDw
+    F/+GvHTHKDQSB+TeEs1Sa/PFwxpspB+RqHbqOTWPsFOHL+9sZGTqd6D4B.R6DBNh
+    wVTZU+eTz.39OZPqu4fQwrBN13lDbUoZxlqT9g2+haQBB9sTDzQEZ08QKBgQDJyw
+    lBBZqQKBgQDz5E2rL59lNS5pBxDO9r6B9rXtBBTZ5tZUWNFRvyNsxY5nJT03.KDw
+    DAAeVWKU1OyDXfN4v6Zn1nNrhSkdrd+XV0nTLExsfg==.-----END RSA PRIVAT
+    E KEY-----
+    ------------------------------332ed6691ab8--
+
+`Server response:`
+
+    HTTP/1.1 200 OK
+    Content-Type: application/xml
+    Date: Mon, 25 Jul 2011 12:56:02 GMT
+    Content-Length: 497
+
+    <instance href='http://localhost:3001/api/instances/i-afde73ce' id='i-afde73ce'>
+      <public_address>
+        ec2-50-19-59-126.compute-1.amazonaws.com
+      </public_address>
+      <command>
+        uname -a; ls -l
+      </command>
+      <output>Linux domU-12-31-39-0F-E1-78 2.6.21.7-2.fc8xen #1 SMP Fri Feb 15 12:39:36 EST 2008 i686 i686 i386 GNU/Linux
+      total 140
+      -rw-r--r-- 1 root root 137263 Mar 26  2008 ec2-ami-tools-1.3-19974.noarch.rpm
+      -rw-r--r-- 1 root root      0 Mar 26  2008 firstlogin
+      </output>
+    </instance>
+
+
+`Example request (run-on-instance Rackspace Cloudservers):`
+
+    POST /api/instances/20117112/run?format=xml HTTP/1.1
+    Authorization: Basic AU1J3UB2121Afd1DdyQWxLaTYTmJMNF4zTXBoRGdhMDh2RUw5ZDAN9zVXVa==
+    User-Agent: curl/7.20.1 (i386-redhat-linux-gnu)
+    Host: localhost:3002
+    Accept: */*
+    Content-Length: 275
+    Expect: 100-continue
+    Content-Type: multipart/form-data; boundary=----------------------------9b05ece66f4d
+    ------------------------------9b05ece66f4d
+    Content-Disposition: form-data; name="cmd"
+
+    uname -a; ifconfig; pwd
+    ------------------------------9b05ece66f4d
+    Content-Disposition: form-data; name="password"
+
+    myserverqB2Uwk21I
+    ------------------------------9b05ece66f4d--
+
+`Server response:`
+
+    HTTP/1.1 200 OK
+    Content-Type: application/xml
+    Date: Mon, 25 Jul 2011 13:02:15 GMT
+    Content-Length: 1781
+
+    <instance href='http://localhost:3002/api/instances/20117112' id='20117112'>
+      <public_address>
+        50.57.117.249
+      </public_address>
+      <command>
+        uname -a; ifconfig; pwd
+      </command>
+      <output>Linux myserver 2.6.35.4-rscloud #8 SMP Mon Sep 20 15:54:33 UTC 2010 x86_64 x86_64 x86_64 GNU/Linux
+      eth0      Link encap:Ethernet  HWaddr 40:40:B1:7A:52:7E
+                inet addr:50.57.117.249  Bcast:50.57.117.255  Mask:255.255.255.0
+                inet6 addr: fe80::4240:b1ff:fe7a:527e/64 Scope:Link
+                UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
+                RX packets:54 errors:0 dropped:0 overruns:0 frame:0
+                TX packets:62 errors:0 dropped:0 overruns:0 carrier:0
+                collisions:0 txqueuelen:1000
+                RX bytes:5880 (5.7 KiB)  TX bytes:6331 (6.1 KiB)
+                Interrupt:24
+
+      eth1      Link encap:Ethernet  HWaddr 40:40:8E:4B:52:23
+                inet addr:10.182.131.159  Bcast:10.182.159.255  Mask:255.255.224.0
+                inet6 addr: fe80::4240:8eff:fe4b:5223/64 Scope:Link
+                UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
+                RX packets:3 errors:0 dropped:0 overruns:0 frame:0
+                TX packets:12 errors:0 dropped:0 overruns:0 carrier:0
+                collisions:0 txqueuelen:1000
+                RX bytes:188 (188.0 b)  TX bytes:720 (720.0 b)
+                Interrupt:25
+
+      lo        Link encap:Local Loopback
+                inet addr:127.0.0.1  Mask:255.0.0.0
+                inet6 addr: ::1/128 Scope:Host
+                UP LOOPBACK RUNNING  MTU:16436  Metric:1
+                RX packets:0 errors:0 dropped:0 overruns:0 frame:0
+                TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
+                collisions:0 txqueuelen:0
+                RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)
+
+      /root</output>
+    </instance>
+
+
+<a name=create_instance>.
+#### `POST /api/instances`
+
+Create a new ***instance***. At a minimum clients must specify the ***image*** from
+which the virtual machine ***instance*** is to be created. Optionally a client
+may also specify a ***hardware profile*** and ***realm*** (with default values used
+otherwise). Clients can also provide a *name* for the new *instance* though this is not
+supported by all back-end cloud providers. Whether a given feature is available is advertised
+in the response to the Deltacloud server API entry point.
+The details of the new ***instance*** are returned in response to this operation.
+
+For creation of an ***instance*** in the Amazon EC2 cloud a client can also specify the
+name of the EC2 keypair to be used as well as the firewalls (EC2 security groups) that the
+***instance*** should be launched into. The EC2 keypair is specified with the parameter *keyname*
+while firewalls are specified sequentially as *firewalls1* ... *firewalls2* ... etc. These parameters
+are specified in the first ***instance*** creation example below. Note that the values for
+public and private addresses are blank in the server response, as these have not yet been
+assigned by the cloud provider. Subsequent requests for the ***instance*** details
+will provide these values.
+
+<a name=create_instance_ec2>.
+
+`Client request: (AWS EC2)`
+
+    POST /api/instances?format=xml HTTP/1.1
+    Authorization: Basic AU1J3UB2121Afd1DdyQWxLaTYTmJMNF4zTXBoRGdhMDh2RUw5ZDAN9zVXVa==
+    User-Agent: curl/7.20.1 (i386-redhat-linux-gnu)
+    Host: localhost:3001
+    Accept: */*
+    Content-Length: 676
+    Expect: 100-continue
+    Content-Type: multipart/form-data; boundary=----------------------------cce0758d1679
+
+    ------------------------------cce0758d1679
+    Content-Disposition: form-data; name="keyname"
+
+    eftah
+    ------------------------------cce0758d1679
+    Content-Disposition: form-data; name="image_id"
+
+    ami-f51aff9c
+    ------------------------------cce0758d1679
+    Content-Disposition: form-data; name="realm_id"
+
+    us-east-1c
+    ------------------------------cce0758d1679
+    Content-Disposition: form-data; name="hwp_id"
+
+    c1.medium
+    ------------------------------cce0758d1679
+    Content-Disposition: form-data; name="firewalls1"
+
+    default
+    ------------------------------cce0758d1679
+    Content-Disposition: form-data; name="firewalls2"
+
+    test
+    ------------------------------cce0758d1679--
+
+`Server response:`
+
+    HTTP/1.1 201 Created
+    Content-Type: application/xml
+    Content-Length: 1183
+
+    <?xml version='1.0' encoding='utf-8' ?>
+    <instance href='http://localhost:3001/api/instances/i-cbb861aa' id='i-cbb861aa'>
+      <name>ami-f51aff9c</name>
+      <owner_id>393485797142</owner_id>
+      <image href='http://localhost:3001/api/images/ami-f51aff9c' id='ami-f51aff9c'></image>
+      <realm href='http://localhost:3001/api/realms/us-east-1c' id='us-east-1c'></realm>
+      <state>PENDING</state>
+      <hardware_profile href='http://localhost:3001/api/hardware_profiles/c1.medium' id='c1.medium'>
+      </hardware_profile>
+      <actions>
+        <link href='http://localhost:3001/api/instances/i-cbb861aa/stop' method='post' rel='stop' />
+        <link href='http://localhost:3001/api/instances/i-cbb861aa/run;id=i-cbb861aa' method='post' rel='run' />
+      </actions>
+      <launch_time>2011-07-22T16:09:45.000Z</launch_time>
+      <public_addresses></public_addresses>
+      <private_addresses></private_addresses>
+      <firewalls>
+        <firewall href='http://localhost:3001/api/firewalls/test' id='test'></firewall>
+        <firewall href='http://localhost:3001/api/firewalls/default' id='default'></firewall>
+      </firewalls>
+      <authentication type='key'>
+        <login>
+          <keyname>eftah</keyname>
+        </login>
+      </authentication>
+    </instance>
+
+The second example given below shows creation of an ***instance*** in the Rackspace
+Cloudservers cloud. Here you can see that the client provides the optional *name*
+ parameter and that the created instance uses authentication of type **password**.
+The *username* and *password* are returned with the details of the newly created
+***instance***:
+
+`Example request: (Rackspace Cloudservers)`
+
+    POST /api/instances?format=xml HTTP/1.1
+    Authorization: Basic AU1J3UB2121Afd1DdyQWxLaTYTmJMNF4zTXBoRGdhMDh2RUw5ZDAN9zVXVa==
+    User-Agent: curl/7.20.1 (i386-redhat-linux-gnu)
+    Host: localhost:3002
+    Accept: */*
+    Content-Length: 342
+    Expect: 100-continue
+    Content-Type: multipart/form-data; boundary=----------------------------7424b11a955d
+
+    ------------------------------7424b11a955d
+    Content-Disposition: form-data; name="image_id"
+
+    53
+    ------------------------------7424b11a955d
+    Content-Disposition: form-data; name="hwp_id"
+
+    1
+    ------------------------------7424b11a955d
+    Content-Disposition: form-data; name="name"
+
+    myserver
+    ------------------------------7424b11a955d--
+
+`Server response:`
+
+    HTTP/1.1 201 Created
+    Content-Type: application/xml
+    Content-Length: 883
+
+    <?xml version='1.0' encoding='utf-8' ?>
+    <instance href='http://localhost:3002/api/instances/20112212' id='20112212'>
+      <name>myserver</name>
+      <owner_id>mandreou</owner_id>
+      <image href='http://localhost:3002/api/images/53' id='53'></image>
+      <realm href='http://localhost:3002/api/realms/us' id='us'></realm>
+      <state>PENDING</state>
+      <hardware_profile href='http://localhost:3002/api/hardware_profiles/1' id='1'>
+      </hardware_profile>
+      <actions>
+        <link href='http://localhost:3002/api/instances/20112212/run;id=20112212' method='post' rel='run' />
+      </actions>
+      <public_addresses><address>50.57.116.72</address></public_addresses>
+      <private_addresses><address>10.182.143.64</address></private_addresses>
+      <authentication type='password'>
+        <login>
+          <username>root</username>
+          <password>myserver4OvKh7Ak3</password>
+        </login>
+      </authentication>
+    </instance>
+
+<br/>
+[Contents](#toc)
+<br/>
+* * *
+
+### 3.6 Keys
+
+A ***key*** captures the credentials required to access an ***Instance***. The Deltacloud API supports
+two main types of ***keys***: type **password** which have *username* and *password* attributes, or type
+**key** which have *fingerprint* and *pem* (private key) attributes (public/private keypair).
+The key type is determined by the back-end cloud provider.
+
+Some cloud providers require that the client specify the credentials to be used for connecting to an
+ ***instance*** as a parameter to ***instance*** creation. An example is the Amazon EC2 cloud which uses
+***keys*** of type **key** and where the identifier of the **key** to be used with a given ***instance***
+is supplied in the *keyname* parameter to the [POST /api/instances](#create_instance_ec2) call.
+
+Other cloud providers report the ***instance*** credentials in the response to ***instance***
+creation and make them available for subsequent retrieval. An example is the Gogrid Cloud,
+ which uses ***keys*** of type  **password** (note: the Rackspace cloud also reports credentials
+during ***instance*** creation though it does not provide a mechanism with which to retrieve
+those passwords thereafter).
+
+#### `GET /api/keys`
+
+This gives a listing of all available keys. The example shown below is for ***keys*** from the Amazon
+EC2 cloud, which are of type **key**. Note that the XML response does not contain the private key
+attribute. This is because EC2 only provides the private key once, when the key is created (see
+[key creation](#key_create) for an example):
+
+<a name=get_keys>.
+
+`Example request:`
+
+    GET /api/keys?format=xml HTTP/1.1
+    Authorization: Basic AU1J3UB2121Afd1DdyQWxLaTYTmJMNF4zTXBoRGdhMDh2RUw5ZDAN9zVXVa==
+    User-Agent: curl/7.20.1 (i386-redhat-linux-gnu)
+    Host: localhost:3001
+    Accept: */*
+
+`Server response:`
+
+    HTTP/1.1 200 OK
+    Content-Type: application/xml
+    Date: Tue, 26 Jul 2011 08:09:26 GMT
+    Content-Length: 733
+
+    <?xml version='1.0' encoding='utf-8' ?>
+    <keys>
+      <key href='http://localhost:3001/api/keys/deltacloud_jsmith' id='deltacloud_jsmith' type='key'>
+        <actions>
+          <link href='http://localhost:3001/api/keys/deltacloud_jsmith' method='delete' rel='destroy' />
+        </actions>
+        <fingerprint>38:93:81:11:83:c2:c7:27:e8:79:17:e2:08:c9:13:99:73:90:8e:cc</fingerprint>
+        <state>AVAILABLE</state>
+      </key>
+      <key href='http://localhost:3001/api/keys/the_key' id='the_key' type='key'>
+        <actions>
+          <link href='http://localhost:3001/api/keys/the_key' method='delete' rel='destroy' />
+        </actions>
+        <fingerprint>39:d3:9b:bb:93:92:97:27:e9:7d:b7:e2:09:9d:b3:dd:73:d0:9e:99</fingerprint>
+        <state>AVAILABLE</state>
+      </key>
+    </keys>
+
+
+#### `GET /api/keys/:id`
+
+Get the XML description for a specific key. The example below shows a key of type **password** from the
+Gogrid cloud:
+
+`Example request:`
+
+    GET /api/keys/72398?format=xml HTTP/1.1
+    Authorization: Basic AU1J3UB2121Afd1DdyQWxLaTYTmJMNF4zTXBoRGdhMDh2RUw5ZDAN9zVXVa==
+    User-Agent: curl/7.21.2 (x86_64-apple-darwin10.3.1)
+    Host: localhost:3001
+    Accept: */*
+
+`Server response:`
+
+    HTTP/1.1 200 OK
+    Content-Type: application/xml
+    Date: Tue, 26 Jul 2011 11:13:25 GMT
+    Content-Length: 269
+
+    <?xml version='1.0' encoding='utf-8' ?>
+    <key href='http://localhost:3001/api/keys/72398' id='72398' type='password'>
+        <actions>
+        </actions>
+        <username><![CDATA[26648]]></username>
+        <password><![CDATA[3woc7UWdJsJEcm8@]]></password>
+        <state></state>
+    </key>
+
+#### `POST /api/keys`
+
+Some back-end cloud providers allow a client to create new credentials for
+accessing Instances. The parameters (key attributes) required by this function will depend on the
+ back-end and are specified in the relevant driver. At present only the Amazon EC2 cloud implements a key
+create method and this requires the key *name* to be specified as a parameter. It should be noted that
+the private key attribute of a newly created key is reported only once, in response to the create
+operation as shown in the example below. The client should save the private key for future use with
+ ***instance*** authentication. In all subsequent calls, only the fingerprint attribute is displayed
+ in the Deltacloud server response, as illustrated by the [GET /api/keys](#get_keys) call above.
+
+<a name=key_create>.
+
+`Example request:`
+
+    POST /api/keys?format=xml HTTP/1.1
+    Authorization: Basic AU1J3UB2121Afd1DdyQWxLaTYTmJMNF4zTXBoRGdhMDh2RUw5ZDAN9zVXVa==
+    User-Agent: curl/7.20.1 (i386-redhat-linux-gnu)
+    Host: localhost:3001
+    Accept: */*
+    Content-Length: 153
+    Expect: 100-continue
+    Content-Type: multipart/form-data; boundary=----------------------------92fbd163f915
+
+    ------------------------------92fbd163f915
+    Content-Disposition: form-data; name="name"
+
+    jsmith_new_key
+    ------------------------------92fbd163f915--
+
+`Server response:`
+
+    HTTP/1.1 201 Created
+    Content-Type: application/xml
+    Date: Tue, 26 Jul 2011 10:58:58 GMT
+    Content-Length: 2062
+
+    <?xml version='1.0' encoding='utf-8' ?>
+    <key href='http://localhost:3001/api/keys/jsmith_new_key' id='jsmith_new_key' type='key'>
+      <actions>
+        <link href='http://localhost:3001/api/keys/jsmith_new_key' method='delete' rel='destroy' />
+      </actions>
+      <fingerprint>c6:80:5c:0a:b8:66:0d:58:5a:bf:0f:c2:5d:35:d3:c7:49:f3:5a:5f</fingerprint>
+      <pem>
+        <![CDATA[-----BEGIN RSA PRIVATE KEY-----
+        MIIEpgIBAAKCAQEAsPIzLQEpoLkxd0WESPEWQ4AMn9e0T6jHIMl/a2GUx2TA2Q10n6i5h4VAXXrK
+        m9fNnPJhw1uRbuL7Oz57QSftGUfz05EaLOsvIEq3OXA0HqnFPF7Dd4yvy07KfgNHe2c26NqIqxgw
+        GCy6tfd/9iKQIlFCG8I/M6fgEG/vw30GP5EywYLS0J7lYfNHJAVAznjX0LoOWvT0zYajZ7gWJ30/
+        sQ/IFaKxC3BpT6K2aQP+RgAimALHinFuoT4+07SsrQXEezLemAG/gdbw3+7DL9BGq0CCoY1RxeC7
+        qNh9BJwHtq9QPYg/RKruiYak/TSoB71/VP67lJv0WEkCRJKEFpz5SQIDAQABAoIBAQChVyZcmdvI
+        JjS5aVSWYeWIBMD+GmPZ4q428iPR2LcdHHxPLVqyndkVfeXTlrwZX6umuMd1pw+zyRmEypL+NRaW
+        36mutnbkkEl3K0loASw07V3fjxSx9EDyo1Q1lG3gUpuZtHG7eCGaWWahtxwhZSCBehBKWVLhmefP
+        dRFs8Zn56LhfxByS/HcmHYddq1ggynFgg1DszYKTiJ0k5Zd/w4gh3GXH02S50cNFumJh9tbZNeDz
+        yqa6a12N21loZ/VRRL7lEjpf3K2n0DCQ5pp0I9/FiwuwHMWr6qPSsQt9N/XclNiVg7fz+btNsqVY
+        US1kBkvazoaANmF3VOXT9bmiFnuBAoGBAOkURD2uBe9UUl7xvWON7yS+tBcs1KyYDsTEhsS5dLdk
+        n73/5vyEVzozdywTR7lQWVQhWWwkK/FJd9Xo/VV5bGXl+MK/JxIQHrEhLzO1OeYEBiw2eKhigyDb
+        lm7pk/DuBNqgnA9YVnSvRYjpnvgBeb89CHvdhqn52GcbB2ShXurRAoGBAMJYyqNyl8CiIqesigts
+        tlRk0UmS/LS6I58f7nbcrkgO3ZDsYhXhj9aKSJx56bpWTwoFdl7nTSUwkFgq2ts3g7EPQbYD/5G6
+        kwpq0tvC23zZTfYvjExNVORh9PJBCrBl1tC/5nqYSrHC7H3Ys/SW3DF+0LPTdOtx5FwL5Utr3lT5
+        AoGBAM3Y8EvpHaS5O+ZOaY07FTHGmxa8qTelM6XkS4ICqGovnEUZdM8fskncmit6+6VWqQ38RhWT
+        /Jsk34k0NEkA7BMyf/i/CaqSQgj93co1C+VxOGJj2TwdhOHIDZv2/omSLQdJQYrr4a87/JVmftdZ
+        tkSHiq6afwwvdEfbPzRIsKOBAoGBAK5EjEAP6z+So1yS/J3N95ipZnmA0hUErBhtu5jdvXFj0w22
+        ySUxw5bvHLkjIJA0AF/OEhx7b9OfPm+wzdqwZugH9DZQU4TLNjqrGzRv//xtptjQPg/Vb//yToBE
+        Dl+qkftReEwJ70CCtykJfiQeeofvXRlCzZ6p28kl6Y+9w/mRAoGBANI8AGB1iUDMQDiEfTAuH7jB
+        nZTZUsfAaysoku3gyVmtcu1Zo7T02b8YW3ypuNu664KO7eNik9q68yKa7oDuLVrVj6Sh2DInoeW9
+        vbjp2KcyMVEPHzWh86LV9IY5oHjQxlK/PMhQWMEeysi6j2qFqrx2rqRhG6kZUcFHFoHQpmv2
+        -----END RSA PRIVATE KEY-----]]>
+      </pem>
+      <state>AVAILABLE</state>
+    </key>
+
+
+#### `DELETE /api/keys/:id`
+
+Delete a ***key***, specified by its :id attribute. Note that as with the :create
+operation, this feature is currently only available in the Amazon EC2 driver.
+
+`Example request:`
+
+    DELETE /api/keys/jsmith_new_key?format=xml HTTP/1.1
+    Authorization: Basic AU1J3UB2121Afd1DdyQWxLaTYTmJMNF4zTXBoRGdhMDh2RUw5ZDAN9zVXVa==
+    User-Agent: curl/7.20.1 (i386-redhat-linux-gnu)
+    Host: localhost:3001
+    Accept: */*
+
+`Server response:`
+
+    HTTP/1.1 204 No Content
+    Date: Tue, 26 Jul 2011 10:18:38 GMT
+
+
+<br/>
+[Contents](#toc)
+<br/>
+* * *
+
+<a name=firewalls>.
+### 3.7 Firewalls
+
+Firewalls represent sets of rules that govern the accessibility of a running
+ ***instance*** over the  public Internet. At present only the Amazon EC2 cloud
+supports this collection (Amazon EC2 'Security Groups'). A ***firewall*** has
+a **name** and **description**, an **owner_id** and a set of **rules**. An
+***instance*** is 'launched into' a ***firewall*** where this is supported,
+by specifying the **firewalls1 ... firewallsN** parameters in the
+ [POST /api/instances](#create_instance_ec2) operation.
+
+Each ***firewall rule*** has a number of attributes describing the access granted
+to clients that want to communicate with the ***instance*** over the Internet.
+Each rule has an **allow_protocol** (*tcp*, *udp*  or *icmp*) a **port_from**
+and **port_to** that delimit the port range for access, a **sources** list which
+can contain ***firewalls*** (i.e. allow ***instances*** in another ***firewall***
+to communicate with ***instances*** in the ***firewall*** in which this rule exists),
+or a number of IP addresses in CIDR format, or  a mix of both. Finally each rule
+also specifies a **direction**, indicating whether it applies to ingress
+or egress traffic.
+
+As Amazon EC2 has no notion of a ***firewall rule*** ID, the Deltacloud server constructs one
+for each rule as the concatenation of its attributes. The format used is:
+owner_id~protocol~from_port~to_port~@sources.
+
+As explained above a source can be of type **address** in which case it defines an
+*IP type* (ipv4/ipv6), an *IP address* and *routing prefix* (CIDR netmask). Sources
+of type **group** have a *name* that defines the ***firewall*** to which access
+is being granted and an *owner_id* (identifier of the account that created the
+specified firewall).
+
+An example of a rule id is:
+
+    393485797142~tcp~22~22~@group,393485797142,default,@address,ipv4,10.1.2.3,24
+              {owner_id~protocol~from_port~to_port~@sources}
+
+By creating the rule identifier abstraction, the Deltacloud API supports deletion of
+an entire firewall rule as one operation,
+[DELETE /api/firewalls/:firewall_id/:rule_id](#delete_firewall_rule).
+
+#### `GET /api/firewalls`
+
+Retrieve a list of all ***firewalls***.
+
+`Example request:`
+
+    GET /api/firewalls?format=xml HTTP/1.1
+    Authorization: Basic AU1J3UB2121Afd1DdyQWxLaTYTmJMNF4zTXBoRGdhMDh2RUw5ZDAN9zVXVa==
+    User-Agent: curl/7.20.1 (i386-redhat-linux-gnu)
+    Host: localhost:3001
+    Accept: */*
+
+`Server response:`
+
+    HTTP/1.1 200 OK
+    Content-Type: application/xml
+    Date: Tue, 26 Jul 2011 15:56:04 GMT
+    Content-Length: 1640
+
+    <?xml version='1.0' encoding='utf-8' ?>
+    <firewalls>
+      <firewall href='http://localhost:3001/api/firewalls/default' id='default'>
+        <name><![CDATA[default]]></name>
+        <description><![CDATA[default group]]></description>
+        <owner_id>393485797142</owner_id>
+        <rules>
+          <rule id='393485797142~tcp~22~22~@address,ipv4,87.228.192.251,32'>
+            <allow_protocol>tcp</allow_protocol>
+            <port_from>22</port_from>
+            <port_to>22</port_to>
+            <direction>ingress</direction>
+            <sources>
+              <source address='87.228.192.251' family='ipv4' prefix='32' type='address'></source>
+            </sources>
+          </rule>
+        </rules>
+      </firewall>
+      <firewall href='http://localhost:3001/api/firewalls/test' id='test'>
+        <name><![CDATA[test]]></name>
+        <description><![CDATA[this is just a test]]></description>
+        <owner_id>393485797142</owner_id>
+        <rules>
+          <rule id='393485797142~tcp~22~22~@group,393485797142,default,@address,ipv4,10.1.2.3,24'>
+            <allow_protocol>tcp</allow_protocol>
+            <port_from>22</port_from>
+            <port_to>22</port_to>
+            <direction>ingress</direction>
+            <sources>
+              <source name='default' owner='393485797142' type='group'></source>
+              <source address='10.1.2.3' family='ipv4' prefix='24' type='address'></source>
+            </sources>
+          </rule>
+        </rules>
+      </firewall>
+      <firewall href='http://localhost:3001/api/firewalls/new_firewall' id='new_firewall'>
+        <name><![CDATA[new_firewall]]></name>
+        <description><![CDATA[new_one]]></description>
+        <owner_id>393485797142</owner_id>
+        <rules>
+        </rules>
+      </firewall>
+    </firewalls>
+
+
+#### `GET /api/firewalls/:id`
+
+Retrieve details of a single specified ***firewall***.
+
+`Example request:`
+
+    GET /api/firewalls/test?format=xml HTTP/1.1
+    Authorization: Basic AU1J3UB2121Afd1DdyQWxLaTYTmJMNF4zTXBoRGdhMDh2RUw5ZDAN9zVXVa==
+    User-Agent: curl/7.20.1 (i386-redhat-linux-gnu)
+    Host: localhost:3001
+    Accept: */*
+
+`Server reponse:`
+
+    HTTP/1.1 200 OK
+    Content-Type: application/xml
+    Date: Wed, 27 Jul 2011 08:20:29 GMT
+    Content-Length: 835
+
+    <?xml version='1.0' encoding='utf-8' ?>
+    <firewall href='http://localhost:3001/api/firewalls/test' id='test'>
+      <name><![CDATA[test]]></name>
+      <description><![CDATA[this is just a test]]></description>
+      <owner_id>393485797142</owner_id>
+      <rules>
+        <rule href='http://localhost:3001/api/firewalls/test/393485797142~tcp~22~22~@group,393485797142,default,@address,ipv4,10.1.2.3,24' id='393485797142~tcp~22~22~@group,393485797142,default,@address,ipv4,10.1.2.3,24'>
+          <allow_protocol>tcp</allow_protocol>
+          <port_from>22</port_from>
+          <port_to>22</port_to>
+          <direction>ingress</direction>
+          <sources>
+            <source name='default' owner='393485797142' type='group'></source>
+            <source address='10.1.2.3' family='ipv4' prefix='24' type='address'></source>
+          </sources>
+        </rule>
+      </rules>
+    </firewall>
+
+
+#### `POST /api/firewalls`
+

[... 1572 lines stripped ...]