diff --git a/doc/api_samples/os-aggregates/aggregate-add-host-post-req.json b/doc/api_samples/os-aggregates/aggregate-add-host-post-req.json
new file mode 100644
index 000000000000..cd6fc6e083e6
--- /dev/null
+++ b/doc/api_samples/os-aggregates/aggregate-add-host-post-req.json
@@ -0,0 +1,6 @@
+{
+ "add_host":
+ {
+ "host": "581d29b9e3504d8a895caddb13839b15"
+ }
+}
\ No newline at end of file
diff --git a/doc/api_samples/os-aggregates/aggregate-add-host-post-req.xml b/doc/api_samples/os-aggregates/aggregate-add-host-post-req.xml
new file mode 100644
index 000000000000..5f48f043d2d7
--- /dev/null
+++ b/doc/api_samples/os-aggregates/aggregate-add-host-post-req.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/doc/api_samples/os-aggregates/aggregate-metadata-post-req.json b/doc/api_samples/os-aggregates/aggregate-metadata-post-req.json
new file mode 100644
index 000000000000..7331e06a8c0b
--- /dev/null
+++ b/doc/api_samples/os-aggregates/aggregate-metadata-post-req.json
@@ -0,0 +1,9 @@
+{
+ "set_metadata":
+ {
+ "metadata":
+ {
+ "key": "value"
+ }
+ }
+}
\ No newline at end of file
diff --git a/doc/api_samples/os-aggregates/aggregate-metadata-post-req.xml b/doc/api_samples/os-aggregates/aggregate-metadata-post-req.xml
new file mode 100644
index 000000000000..d9b935fd45f8
--- /dev/null
+++ b/doc/api_samples/os-aggregates/aggregate-metadata-post-req.xml
@@ -0,0 +1,6 @@
+
+
+
+ value
+
+
\ No newline at end of file
diff --git a/doc/api_samples/os-aggregates/aggregate-post-req.json b/doc/api_samples/os-aggregates/aggregate-post-req.json
new file mode 100644
index 000000000000..82272c2936b5
--- /dev/null
+++ b/doc/api_samples/os-aggregates/aggregate-post-req.json
@@ -0,0 +1,7 @@
+{
+ "aggregate":
+ {
+ "name": "name",
+ "availability_zone": "nova"
+ }
+}
\ No newline at end of file
diff --git a/doc/api_samples/os-aggregates/aggregate-post-req.xml b/doc/api_samples/os-aggregates/aggregate-post-req.xml
new file mode 100644
index 000000000000..d25f5f848ca7
--- /dev/null
+++ b/doc/api_samples/os-aggregates/aggregate-post-req.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/doc/api_samples/os-aggregates/aggregate-post-resp.json b/doc/api_samples/os-aggregates/aggregate-post-resp.json
new file mode 100644
index 000000000000..6dd939b365d1
--- /dev/null
+++ b/doc/api_samples/os-aggregates/aggregate-post-resp.json
@@ -0,0 +1,11 @@
+{
+ "aggregate": {
+ "availability_zone": "nova",
+ "created_at": "2012-10-01T18:50:27.781065",
+ "deleted": false,
+ "deleted_at": null,
+ "id": 1,
+ "name": "name",
+ "updated_at": null
+ }
+}
\ No newline at end of file
diff --git a/doc/api_samples/os-aggregates/aggregate-post-resp.xml b/doc/api_samples/os-aggregates/aggregate-post-resp.xml
new file mode 100644
index 000000000000..544271bdc8c0
--- /dev/null
+++ b/doc/api_samples/os-aggregates/aggregate-post-resp.xml
@@ -0,0 +1,10 @@
+
+
+ name
+ nova
+ False
+ 2012-10-01 18:50:35.506667
+ None
+ None
+ 1
+
\ No newline at end of file
diff --git a/doc/api_samples/os-aggregates/aggregate-remove-host-post-req.json b/doc/api_samples/os-aggregates/aggregate-remove-host-post-req.json
new file mode 100644
index 000000000000..e5165cbab1aa
--- /dev/null
+++ b/doc/api_samples/os-aggregates/aggregate-remove-host-post-req.json
@@ -0,0 +1,6 @@
+{
+ "remove_host":
+ {
+ "host": "581d29b9e3504d8a895caddb13839b15"
+ }
+}
\ No newline at end of file
diff --git a/doc/api_samples/os-aggregates/aggregate-remove-host-post-req.xml b/doc/api_samples/os-aggregates/aggregate-remove-host-post-req.xml
new file mode 100644
index 000000000000..87e5d64f9a10
--- /dev/null
+++ b/doc/api_samples/os-aggregates/aggregate-remove-host-post-req.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/doc/api_samples/os-aggregates/aggregate-update-post-req.json b/doc/api_samples/os-aggregates/aggregate-update-post-req.json
new file mode 100644
index 000000000000..0af1a37a4d9c
--- /dev/null
+++ b/doc/api_samples/os-aggregates/aggregate-update-post-req.json
@@ -0,0 +1,7 @@
+{
+ "aggregate":
+ {
+ "name": "newname",
+ "availability_zone": "nova2"
+ }
+}
\ No newline at end of file
diff --git a/doc/api_samples/os-aggregates/aggregate-update-post-req.xml b/doc/api_samples/os-aggregates/aggregate-update-post-req.xml
new file mode 100644
index 000000000000..1eb9c38fdb7c
--- /dev/null
+++ b/doc/api_samples/os-aggregates/aggregate-update-post-req.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/doc/api_samples/os-aggregates/aggregate-update-post-resp.json b/doc/api_samples/os-aggregates/aggregate-update-post-resp.json
new file mode 100644
index 000000000000..81869e730a2d
--- /dev/null
+++ b/doc/api_samples/os-aggregates/aggregate-update-post-resp.json
@@ -0,0 +1,13 @@
+{
+ "aggregate": {
+ "availability_zone": "nova2",
+ "created_at": "2012-10-01T18:50:27.781065",
+ "deleted": false,
+ "deleted_at": null,
+ "hosts": [],
+ "id": 1,
+ "metadata": {},
+ "name": "newname",
+ "updated_at": "2012-10-01T18:50:27.791392"
+ }
+}
\ No newline at end of file
diff --git a/doc/api_samples/os-aggregates/aggregate-update-post-resp.xml b/doc/api_samples/os-aggregates/aggregate-update-post-resp.xml
new file mode 100644
index 000000000000..ad9498aa0b0c
--- /dev/null
+++ b/doc/api_samples/os-aggregates/aggregate-update-post-resp.xml
@@ -0,0 +1,12 @@
+
+
+ newname
+ nova2
+ False
+ 2012-10-01 18:50:35.506667
+ 2012-10-01 18:50:35.517397
+
+ None
+ 1
+
+
\ No newline at end of file
diff --git a/doc/api_samples/os-aggregates/aggregates-add-host-post-resp.json b/doc/api_samples/os-aggregates/aggregates-add-host-post-resp.json
new file mode 100644
index 000000000000..518f4176a9b1
--- /dev/null
+++ b/doc/api_samples/os-aggregates/aggregates-add-host-post-resp.json
@@ -0,0 +1,15 @@
+{
+ "aggregate": {
+ "availability_zone": "nova",
+ "created_at": "2012-10-01T18:50:27.511586",
+ "deleted": false,
+ "deleted_at": null,
+ "hosts": [
+ "581d29b9e3504d8a895caddb13839b15"
+ ],
+ "id": 1,
+ "metadata": {},
+ "name": "name",
+ "updated_at": null
+ }
+}
\ No newline at end of file
diff --git a/doc/api_samples/os-aggregates/aggregates-add-host-post-resp.xml b/doc/api_samples/os-aggregates/aggregates-add-host-post-resp.xml
new file mode 100644
index 000000000000..a4c9de5fd071
--- /dev/null
+++ b/doc/api_samples/os-aggregates/aggregates-add-host-post-resp.xml
@@ -0,0 +1,14 @@
+
+
+ name
+ nova
+ False
+ 2012-10-01 18:50:35.236556
+ None
+
+ 7c9e00dbca5e4fb88538b021c0f933a5
+
+ None
+ 1
+
+
\ No newline at end of file
diff --git a/doc/api_samples/os-aggregates/aggregates-get-resp.json b/doc/api_samples/os-aggregates/aggregates-get-resp.json
new file mode 100644
index 000000000000..cde446e51fb3
--- /dev/null
+++ b/doc/api_samples/os-aggregates/aggregates-get-resp.json
@@ -0,0 +1,13 @@
+{
+ "aggregate": {
+ "availability_zone": "nova",
+ "created_at": "2012-10-01T18:50:27.048605",
+ "deleted": false,
+ "deleted_at": null,
+ "hosts": [],
+ "id": 1,
+ "metadata": {},
+ "name": "name",
+ "updated_at": null
+ }
+}
\ No newline at end of file
diff --git a/doc/api_samples/os-aggregates/aggregates-get-resp.xml b/doc/api_samples/os-aggregates/aggregates-get-resp.xml
new file mode 100644
index 000000000000..be1349bd28d3
--- /dev/null
+++ b/doc/api_samples/os-aggregates/aggregates-get-resp.xml
@@ -0,0 +1,12 @@
+
+
+ name
+ nova
+ False
+ 2012-10-01 18:50:34.764838
+ None
+
+ None
+ 1
+
+
\ No newline at end of file
diff --git a/doc/api_samples/os-aggregates/aggregates-list-get-resp.json b/doc/api_samples/os-aggregates/aggregates-list-get-resp.json
new file mode 100644
index 000000000000..75b412b53870
--- /dev/null
+++ b/doc/api_samples/os-aggregates/aggregates-list-get-resp.json
@@ -0,0 +1,15 @@
+{
+ "aggregates": [
+ {
+ "availability_zone": "nova",
+ "created_at": "2012-10-01T18:50:27.252869",
+ "deleted": false,
+ "deleted_at": null,
+ "hosts": [],
+ "id": 1,
+ "metadata": {},
+ "name": "name",
+ "updated_at": null
+ }
+ ]
+}
\ No newline at end of file
diff --git a/doc/api_samples/os-aggregates/aggregates-list-get-resp.xml b/doc/api_samples/os-aggregates/aggregates-list-get-resp.xml
new file mode 100644
index 000000000000..c5590855b874
--- /dev/null
+++ b/doc/api_samples/os-aggregates/aggregates-list-get-resp.xml
@@ -0,0 +1,14 @@
+
+
+
+ name
+ nova
+ False
+ 2012-10-01 18:50:34.970677
+ None
+
+ None
+ 1
+
+
+
\ No newline at end of file
diff --git a/doc/api_samples/os-aggregates/aggregates-metadata-post-resp.json b/doc/api_samples/os-aggregates/aggregates-metadata-post-resp.json
new file mode 100644
index 000000000000..dc4806a4f71d
--- /dev/null
+++ b/doc/api_samples/os-aggregates/aggregates-metadata-post-resp.json
@@ -0,0 +1,15 @@
+{
+ "aggregate": {
+ "availability_zone": "nova",
+ "created_at": "2012-10-01T18:50:26.604176",
+ "deleted": false,
+ "deleted_at": null,
+ "hosts": [],
+ "id": 1,
+ "metadata": {
+ "key": "value"
+ },
+ "name": "name",
+ "updated_at": null
+ }
+}
\ No newline at end of file
diff --git a/doc/api_samples/os-aggregates/aggregates-metadata-post-resp.xml b/doc/api_samples/os-aggregates/aggregates-metadata-post-resp.xml
new file mode 100644
index 000000000000..7eeefb8b7af8
--- /dev/null
+++ b/doc/api_samples/os-aggregates/aggregates-metadata-post-resp.xml
@@ -0,0 +1,14 @@
+
+
+ name
+ nova
+ False
+ 2012-10-01 18:50:34.313003
+ None
+
+ None
+ 1
+
+ value
+
+
\ No newline at end of file
diff --git a/doc/api_samples/os-aggregates/aggregates-remove-host-post-resp.json b/doc/api_samples/os-aggregates/aggregates-remove-host-post-resp.json
new file mode 100644
index 000000000000..497fcb7fb67e
--- /dev/null
+++ b/doc/api_samples/os-aggregates/aggregates-remove-host-post-resp.json
@@ -0,0 +1,13 @@
+{
+ "aggregate": {
+ "availability_zone": "nova",
+ "created_at": "2012-10-01T18:50:27.511586",
+ "deleted": false,
+ "deleted_at": null,
+ "hosts": [],
+ "id": 1,
+ "metadata": {},
+ "name": "name",
+ "updated_at": null
+ }
+}
\ No newline at end of file
diff --git a/doc/api_samples/os-aggregates/aggregates-remove-host-post-resp.xml b/doc/api_samples/os-aggregates/aggregates-remove-host-post-resp.xml
new file mode 100644
index 000000000000..dc8a55330b32
--- /dev/null
+++ b/doc/api_samples/os-aggregates/aggregates-remove-host-post-resp.xml
@@ -0,0 +1,12 @@
+
+
+ name
+ nova
+ False
+ 2012-10-01 18:50:35.236556
+ None
+
+ None
+ 1
+
+
\ No newline at end of file
diff --git a/doc/api_samples/os-aggregates/server-post-req.json b/doc/api_samples/os-aggregates/server-post-req.json
new file mode 100644
index 000000000000..d88eb4122223
--- /dev/null
+++ b/doc/api_samples/os-aggregates/server-post-req.json
@@ -0,0 +1,16 @@
+{
+ "server" : {
+ "name" : "new-server-test",
+ "imageRef" : "http://openstack.example.com/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b",
+ "flavorRef" : "http://openstack.example.com/openstack/flavors/1",
+ "metadata" : {
+ "My Server Name" : "Apache1"
+ },
+ "personality" : [
+ {
+ "path" : "/etc/banner.txt",
+ "contents" : "ICAgICAgDQoiQSBjbG91ZCBkb2VzIG5vdCBrbm93IHdoeSBpdCBtb3ZlcyBpbiBqdXN0IHN1Y2ggYSBkaXJlY3Rpb24gYW5kIGF0IHN1Y2ggYSBzcGVlZC4uLkl0IGZlZWxzIGFuIGltcHVsc2lvbi4uLnRoaXMgaXMgdGhlIHBsYWNlIHRvIGdvIG5vdy4gQnV0IHRoZSBza3kga25vd3MgdGhlIHJlYXNvbnMgYW5kIHRoZSBwYXR0ZXJucyBiZWhpbmQgYWxsIGNsb3VkcywgYW5kIHlvdSB3aWxsIGtub3csIHRvbywgd2hlbiB5b3UgbGlmdCB5b3Vyc2VsZiBoaWdoIGVub3VnaCB0byBzZWUgYmV5b25kIGhvcml6b25zLiINCg0KLVJpY2hhcmQgQmFjaA=="
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/doc/api_samples/os-aggregates/server-post-resp.json b/doc/api_samples/os-aggregates/server-post-resp.json
new file mode 100644
index 000000000000..0eba66ae6f11
--- /dev/null
+++ b/doc/api_samples/os-aggregates/server-post-resp.json
@@ -0,0 +1,16 @@
+{
+ "server": {
+ "adminPass": "kWaKB9zfiMsq",
+ "id": "d261e7aa-50ea-45bb-827c-61bd94deb012",
+ "links": [
+ {
+ "href": "http://openstack.example.com/v2/openstack/servers/d261e7aa-50ea-45bb-827c-61bd94deb012",
+ "rel": "self"
+ },
+ {
+ "href": "http://openstack.example.com/openstack/servers/d261e7aa-50ea-45bb-827c-61bd94deb012",
+ "rel": "bookmark"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/nova/tests/integrated/api_samples/os-aggregates/aggregate-add-host-post-req.json.tpl b/nova/tests/integrated/api_samples/os-aggregates/aggregate-add-host-post-req.json.tpl
new file mode 100644
index 000000000000..2a84101a16ee
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/aggregate-add-host-post-req.json.tpl
@@ -0,0 +1,6 @@
+{
+ "add_host":
+ {
+ "host": "%(host_name)s"
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-aggregates/aggregate-add-host-post-req.xml.tpl b/nova/tests/integrated/api_samples/os-aggregates/aggregate-add-host-post-req.xml.tpl
new file mode 100644
index 000000000000..4454134efb05
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/aggregate-add-host-post-req.xml.tpl
@@ -0,0 +1,2 @@
+
+
diff --git a/nova/tests/integrated/api_samples/os-aggregates/aggregate-metadata-post-req.json.tpl b/nova/tests/integrated/api_samples/os-aggregates/aggregate-metadata-post-req.json.tpl
new file mode 100644
index 000000000000..63a2921cacc8
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/aggregate-metadata-post-req.json.tpl
@@ -0,0 +1,9 @@
+{
+ "set_metadata":
+ {
+ "metadata":
+ {
+ "key": "value"
+ }
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-aggregates/aggregate-metadata-post-req.xml.tpl b/nova/tests/integrated/api_samples/os-aggregates/aggregate-metadata-post-req.xml.tpl
new file mode 100644
index 000000000000..72b1e742aa7b
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/aggregate-metadata-post-req.xml.tpl
@@ -0,0 +1,6 @@
+
+
+
+ value
+
+
diff --git a/nova/tests/integrated/api_samples/os-aggregates/aggregate-post-req.json.tpl b/nova/tests/integrated/api_samples/os-aggregates/aggregate-post-req.json.tpl
new file mode 100644
index 000000000000..fc806061e88d
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/aggregate-post-req.json.tpl
@@ -0,0 +1,7 @@
+{
+ "aggregate":
+ {
+ "name": "name",
+ "availability_zone": "nova"
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-aggregates/aggregate-post-req.xml.tpl b/nova/tests/integrated/api_samples/os-aggregates/aggregate-post-req.xml.tpl
new file mode 100644
index 000000000000..4931476ae5ab
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/aggregate-post-req.xml.tpl
@@ -0,0 +1,2 @@
+
+
diff --git a/nova/tests/integrated/api_samples/os-aggregates/aggregate-post-resp.json.tpl b/nova/tests/integrated/api_samples/os-aggregates/aggregate-post-resp.json.tpl
new file mode 100644
index 000000000000..c5139950ac45
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/aggregate-post-resp.json.tpl
@@ -0,0 +1,11 @@
+{
+ "aggregate": {
+ "availability_zone": "nova",
+ "created_at": "%(timestamp)s",
+ "deleted": false,
+ "deleted_at": null,
+ "id": %(aggregate_id)s,
+ "name": "name",
+ "updated_at": null
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-aggregates/aggregate-post-resp.xml.tpl b/nova/tests/integrated/api_samples/os-aggregates/aggregate-post-resp.xml.tpl
new file mode 100644
index 000000000000..f8603ac33ff0
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/aggregate-post-resp.xml.tpl
@@ -0,0 +1,10 @@
+
+
+ name
+ nova
+ False
+ %(timestamp)s
+ None
+ None
+ %(aggregate_id)s
+
diff --git a/nova/tests/integrated/api_samples/os-aggregates/aggregate-remove-host-post-req.json.tpl b/nova/tests/integrated/api_samples/os-aggregates/aggregate-remove-host-post-req.json.tpl
new file mode 100644
index 000000000000..66ecf30cd6d5
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/aggregate-remove-host-post-req.json.tpl
@@ -0,0 +1,6 @@
+{
+ "remove_host":
+ {
+ "host": "%(host_name)s"
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-aggregates/aggregate-remove-host-post-req.xml.tpl b/nova/tests/integrated/api_samples/os-aggregates/aggregate-remove-host-post-req.xml.tpl
new file mode 100644
index 000000000000..bc2896835f9f
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/aggregate-remove-host-post-req.xml.tpl
@@ -0,0 +1,2 @@
+
+
diff --git a/nova/tests/integrated/api_samples/os-aggregates/aggregate-update-post-req.json.tpl b/nova/tests/integrated/api_samples/os-aggregates/aggregate-update-post-req.json.tpl
new file mode 100644
index 000000000000..55e4b09346ea
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/aggregate-update-post-req.json.tpl
@@ -0,0 +1,7 @@
+{
+ "aggregate":
+ {
+ "name": "newname",
+ "availability_zone": "nova2"
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-aggregates/aggregate-update-post-req.xml.tpl b/nova/tests/integrated/api_samples/os-aggregates/aggregate-update-post-req.xml.tpl
new file mode 100644
index 000000000000..04ce4fba58e8
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/aggregate-update-post-req.xml.tpl
@@ -0,0 +1,2 @@
+
+
diff --git a/nova/tests/integrated/api_samples/os-aggregates/aggregate-update-post-resp.json.tpl b/nova/tests/integrated/api_samples/os-aggregates/aggregate-update-post-resp.json.tpl
new file mode 100644
index 000000000000..89a48ee570eb
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/aggregate-update-post-resp.json.tpl
@@ -0,0 +1,13 @@
+{
+ "aggregate": {
+ "availability_zone": "nova2",
+ "created_at": "%(timestamp)s",
+ "deleted": false,
+ "deleted_at": null,
+ "hosts": [],
+ "id": 1,
+ "metadata": {},
+ "name": "newname",
+ "updated_at": "%(timestamp)s"
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-aggregates/aggregate-update-post-resp.xml.tpl b/nova/tests/integrated/api_samples/os-aggregates/aggregate-update-post-resp.xml.tpl
new file mode 100644
index 000000000000..3f72a0b43018
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/aggregate-update-post-resp.xml.tpl
@@ -0,0 +1,12 @@
+
+
+ newname
+ nova2
+ False
+ %(timestamp)s
+ %(timestamp)s
+
+ None
+ 1
+
+
diff --git a/nova/tests/integrated/api_samples/os-aggregates/aggregates-add-host-post-resp.json.tpl b/nova/tests/integrated/api_samples/os-aggregates/aggregates-add-host-post-resp.json.tpl
new file mode 100644
index 000000000000..ee0ea6c3d6d7
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/aggregates-add-host-post-resp.json.tpl
@@ -0,0 +1,15 @@
+{
+ "aggregate": {
+ "availability_zone": "nova",
+ "created_at": "%(timestamp)s",
+ "deleted": false,
+ "deleted_at": null,
+ "hosts": [
+ "%(compute_host)s"
+ ],
+ "id": 1,
+ "metadata": {},
+ "name": "name",
+ "updated_at": null
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-aggregates/aggregates-add-host-post-resp.xml.tpl b/nova/tests/integrated/api_samples/os-aggregates/aggregates-add-host-post-resp.xml.tpl
new file mode 100644
index 000000000000..82a0401ad1b8
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/aggregates-add-host-post-resp.xml.tpl
@@ -0,0 +1,14 @@
+
+
+ name
+ nova
+ False
+ %(timestamp)s
+ None
+
+ %(compute_host)s
+
+ None
+ 1
+
+
diff --git a/nova/tests/integrated/api_samples/os-aggregates/aggregates-get-resp.json.tpl b/nova/tests/integrated/api_samples/os-aggregates/aggregates-get-resp.json.tpl
new file mode 100644
index 000000000000..8ce7d9c407cf
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/aggregates-get-resp.json.tpl
@@ -0,0 +1,13 @@
+{
+ "aggregate": {
+ "availability_zone": "nova",
+ "created_at": "%(timestamp)s",
+ "deleted": false,
+ "deleted_at": null,
+ "hosts": [],
+ "id": 1,
+ "metadata": {},
+ "name": "name",
+ "updated_at": null
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-aggregates/aggregates-get-resp.xml.tpl b/nova/tests/integrated/api_samples/os-aggregates/aggregates-get-resp.xml.tpl
new file mode 100644
index 000000000000..56f0dd3e888b
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/aggregates-get-resp.xml.tpl
@@ -0,0 +1,12 @@
+
+
+ name
+ nova
+ False
+ %(timestamp)s
+ None
+
+ None
+ 1
+
+
diff --git a/nova/tests/integrated/api_samples/os-aggregates/aggregates-list-get-resp.json.tpl b/nova/tests/integrated/api_samples/os-aggregates/aggregates-list-get-resp.json.tpl
new file mode 100644
index 000000000000..f373f02f79d4
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/aggregates-list-get-resp.json.tpl
@@ -0,0 +1,15 @@
+{
+ "aggregates": [
+ {
+ "availability_zone": "nova",
+ "created_at": "%(timestamp)s",
+ "deleted": false,
+ "deleted_at": null,
+ "hosts": [],
+ "id": 1,
+ "metadata": {},
+ "name": "name",
+ "updated_at": null
+ }
+ ]
+}
diff --git a/nova/tests/integrated/api_samples/os-aggregates/aggregates-list-get-resp.xml.tpl b/nova/tests/integrated/api_samples/os-aggregates/aggregates-list-get-resp.xml.tpl
new file mode 100644
index 000000000000..417b1016f4ff
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/aggregates-list-get-resp.xml.tpl
@@ -0,0 +1,14 @@
+
+
+
+ name
+ nova
+ False
+ %(timestamp)s
+ None
+
+ None
+ 1
+
+
+
diff --git a/nova/tests/integrated/api_samples/os-aggregates/aggregates-metadata-post-resp.json.tpl b/nova/tests/integrated/api_samples/os-aggregates/aggregates-metadata-post-resp.json.tpl
new file mode 100644
index 000000000000..058a1ecf5364
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/aggregates-metadata-post-resp.json.tpl
@@ -0,0 +1,15 @@
+{
+ "aggregate": {
+ "availability_zone": "nova",
+ "created_at": "%(timestamp)s",
+ "deleted": false,
+ "deleted_at": null,
+ "hosts": [],
+ "id": 1,
+ "metadata": {
+ "key": "value"
+ },
+ "name": "name",
+ "updated_at": null
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-aggregates/aggregates-metadata-post-resp.xml.tpl b/nova/tests/integrated/api_samples/os-aggregates/aggregates-metadata-post-resp.xml.tpl
new file mode 100644
index 000000000000..9bbd1f0bdf07
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/aggregates-metadata-post-resp.xml.tpl
@@ -0,0 +1,14 @@
+
+
+ name
+ nova
+ False
+ %(timestamp)s
+ None
+
+ None
+ 1
+
+ value
+
+
diff --git a/nova/tests/integrated/api_samples/os-aggregates/aggregates-remove-host-post-resp.json.tpl b/nova/tests/integrated/api_samples/os-aggregates/aggregates-remove-host-post-resp.json.tpl
new file mode 100644
index 000000000000..8ce7d9c407cf
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/aggregates-remove-host-post-resp.json.tpl
@@ -0,0 +1,13 @@
+{
+ "aggregate": {
+ "availability_zone": "nova",
+ "created_at": "%(timestamp)s",
+ "deleted": false,
+ "deleted_at": null,
+ "hosts": [],
+ "id": 1,
+ "metadata": {},
+ "name": "name",
+ "updated_at": null
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-aggregates/aggregates-remove-host-post-resp.xml.tpl b/nova/tests/integrated/api_samples/os-aggregates/aggregates-remove-host-post-resp.xml.tpl
new file mode 100644
index 000000000000..56f0dd3e888b
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/aggregates-remove-host-post-resp.xml.tpl
@@ -0,0 +1,12 @@
+
+
+ name
+ nova
+ False
+ %(timestamp)s
+ None
+
+ None
+ 1
+
+
diff --git a/nova/tests/integrated/api_samples/os-aggregates/server-post-req.json.tpl b/nova/tests/integrated/api_samples/os-aggregates/server-post-req.json.tpl
new file mode 100644
index 000000000000..d3916d1aa68a
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/server-post-req.json.tpl
@@ -0,0 +1,16 @@
+{
+ "server" : {
+ "name" : "new-server-test",
+ "imageRef" : "%(host)s/openstack/images/%(image_id)s",
+ "flavorRef" : "%(host)s/openstack/flavors/1",
+ "metadata" : {
+ "My Server Name" : "Apache1"
+ },
+ "personality" : [
+ {
+ "path" : "/etc/banner.txt",
+ "contents" : "ICAgICAgDQoiQSBjbG91ZCBkb2VzIG5vdCBrbm93IHdoeSBpdCBtb3ZlcyBpbiBqdXN0IHN1Y2ggYSBkaXJlY3Rpb24gYW5kIGF0IHN1Y2ggYSBzcGVlZC4uLkl0IGZlZWxzIGFuIGltcHVsc2lvbi4uLnRoaXMgaXMgdGhlIHBsYWNlIHRvIGdvIG5vdy4gQnV0IHRoZSBza3kga25vd3MgdGhlIHJlYXNvbnMgYW5kIHRoZSBwYXR0ZXJucyBiZWhpbmQgYWxsIGNsb3VkcywgYW5kIHlvdSB3aWxsIGtub3csIHRvbywgd2hlbiB5b3UgbGlmdCB5b3Vyc2VsZiBoaWdoIGVub3VnaCB0byBzZWUgYmV5b25kIGhvcml6b25zLiINCg0KLVJpY2hhcmQgQmFjaA=="
+ }
+ ]
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-aggregates/server-post-req.xml.tpl b/nova/tests/integrated/api_samples/os-aggregates/server-post-req.xml.tpl
new file mode 100644
index 000000000000..f92614984242
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/server-post-req.xml.tpl
@@ -0,0 +1,19 @@
+
+
+
+ Apache1
+
+
+
+ ICAgICAgDQoiQSBjbG91ZCBkb2VzIG5vdCBrbm93IHdoeSBp
+ dCBtb3ZlcyBpbiBqdXN0IHN1Y2ggYSBkaXJlY3Rpb24gYW5k
+ IGF0IHN1Y2ggYSBzcGVlZC4uLkl0IGZlZWxzIGFuIGltcHVs
+ c2lvbi4uLnRoaXMgaXMgdGhlIHBsYWNlIHRvIGdvIG5vdy4g
+ QnV0IHRoZSBza3kga25vd3MgdGhlIHJlYXNvbnMgYW5kIHRo
+ ZSBwYXR0ZXJucyBiZWhpbmQgYWxsIGNsb3VkcywgYW5kIHlv
+ dSB3aWxsIGtub3csIHRvbywgd2hlbiB5b3UgbGlmdCB5b3Vy
+ c2VsZiBoaWdoIGVub3VnaCB0byBzZWUgYmV5b25kIGhvcml6
+ b25zLiINCg0KLVJpY2hhcmQgQmFjaA==
+
+
+
diff --git a/nova/tests/integrated/api_samples/os-aggregates/server-post-resp.json.tpl b/nova/tests/integrated/api_samples/os-aggregates/server-post-resp.json.tpl
new file mode 100644
index 000000000000..d5f030c8730b
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/server-post-resp.json.tpl
@@ -0,0 +1,16 @@
+{
+ "server": {
+ "adminPass": "%(password)s",
+ "id": "%(id)s",
+ "links": [
+ {
+ "href": "%(host)s/v2/openstack/servers/%(uuid)s",
+ "rel": "self"
+ },
+ {
+ "href": "%(host)s/openstack/servers/%(uuid)s",
+ "rel": "bookmark"
+ }
+ ]
+ }
+}
diff --git a/nova/tests/integrated/api_samples/os-aggregates/server-post-resp.xml.tpl b/nova/tests/integrated/api_samples/os-aggregates/server-post-resp.xml.tpl
new file mode 100644
index 000000000000..3bb13e69bd6d
--- /dev/null
+++ b/nova/tests/integrated/api_samples/os-aggregates/server-post-resp.xml.tpl
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/nova/tests/integrated/test_api_samples.py b/nova/tests/integrated/test_api_samples.py
index 1599bd9b8ea9..5abcaaff78ca 100644
--- a/nova/tests/integrated/test_api_samples.py
+++ b/nova/tests/integrated/test_api_samples.py
@@ -71,6 +71,8 @@ class ApiSampleTestBase(integrated_helpers._IntegratedTestBase):
if not data:
return {}
if self.ctype == 'json':
+ # NOTE(vish): allow non-quoted replacements to survive json
+ data = re.sub(r'([^"])%\((.+)\)s([^"])', r'\1"%(int:\2)s"\3', data)
return jsonutils.loads(data)
else:
def to_dict(node):
@@ -163,13 +165,22 @@ class ApiSampleTestBase(integrated_helpers._IntegratedTestBase):
# NOTE(vish): escape stuff for regex
for char in '[]<>?':
expected = expected.replace(char, '\\%s' % char)
+ # NOTE(vish): special handling of subs that are not quoted. We are
+ # expecting an int but we had to pass in a string
+ # so the json would parse properly.
+ if expected.startswith("%(int:"):
+ result = str(result)
+ expected = expected.replace('int:', '')
expected = expected % subs
match = re.match(expected, result)
if not match:
raise NoMatch(_('Values do not match:\n'
'%(expected)s\n%(result)s') % locals())
- if match.groups():
- matched_value = match.groups()[0]
+ try:
+ matched_value = match.group('id')
+ except IndexError:
+ if match.groups():
+ matched_value = match.groups()[0]
else:
if isinstance(expected, basestring):
# NOTE(danms): Ignore whitespace in this comparison
@@ -201,13 +212,15 @@ class ApiSampleTestBase(integrated_helpers._IntegratedTestBase):
else:
text = r'[^<]*'
return {
- 'timestamp': '[0-9]{4}-[0,1][0-9]-[0-3][0-9]T'
- '[0-9]{2}:[0-9]{2}:[0-9]{2}'
- '(Z|(\+|-)[0-9]{2}:[0-9]{2})',
+ # NOTE(treinish): Could result in a false positive, but it
+ # shouldn't be an issue for this case.
+ 'timestamp': '\d{4}-[0,1]\d-[0-3]\d[ ,T]'
+ '\d{2}:\d{2}:\d{2}'
+ '(Z|(\+|-)\d{2}:\d{2}|\.\d{6})',
'password': '[0-9a-zA-Z]{1,12}',
'ip': '[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}',
'ip6': '([0-9a-zA-Z]{1,4}:){1,7}:?[0-9a-zA-Z]',
- 'id': '([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}'
+ 'id': '(?P[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}'
'-[0-9a-f]{4}-[0-9a-f]{12})',
'uuid': '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}'
'-[0-9a-f]{4}-[0-9a-f]{12}',
@@ -1060,3 +1073,75 @@ class CloudPipeSampleJsonTest(ApiSampleTestBase):
class CloudPipeSampleXmlTest(CloudPipeSampleJsonTest):
ctype = "xml"
+
+
+class AggregatesSampleJsonTest(ServersSampleBase):
+ extension_name = "nova.api.openstack.compute.contrib" + \
+ ".aggregates.Aggregates"
+
+ def test_aggregate_create(self):
+ subs = {
+ "aggregate_id": '(?P\d+)'
+ }
+ response = self._do_post('os-aggregates', 'aggregate-post-req', subs)
+ self.assertEqual(response.status, 200)
+ subs.update(self._get_regexes())
+ return self._verify_response('aggregate-post-resp', subs, response)
+
+ def test_list_aggregates(self):
+ self.test_aggregate_create()
+ response = self._do_get('os-aggregates')
+ subs = self._get_regexes()
+ return self._verify_response('aggregates-list-get-resp',
+ subs, response)
+
+ def test_aggregate_get(self):
+ agg_id = self.test_aggregate_create()
+ response = self._do_get('os-aggregates/%s' % agg_id)
+ subs = self._get_regexes()
+ return self._verify_response('aggregates-get-resp', subs, response)
+
+ def test_add_metadata(self):
+ agg_id = self.test_aggregate_create()
+ response = self._do_post('os-aggregates/%s/action' % agg_id,
+ 'aggregate-metadata-post-req',
+ {'action': 'set_metadata'})
+ subs = self._get_regexes()
+ return self._verify_response('aggregates-metadata-post-resp',
+ subs, response)
+
+ def test_add_host(self):
+ aggregate_id = self.test_aggregate_create()
+ subs = {
+ "action": "add_host",
+ "host_name": self.compute.host,
+ }
+ response = self._do_post('os-aggregates/%s/action' % aggregate_id,
+ 'aggregate-add-host-post-req', subs)
+ subs.update(self._get_regexes())
+ return self._verify_response('aggregates-add-host-post-resp',
+ subs, response)
+
+ def test_remove_host(self):
+ self.test_add_host()
+ subs = {
+ "action": "add_host",
+ "host_name": self.compute.host,
+ }
+ response = self._do_post('os-aggregates/1/action',
+ 'aggregate-remove-host-post-req', subs)
+ subs.update(self._get_regexes())
+ return self._verify_response('aggregates-remove-host-post-resp',
+ subs, response)
+
+ def test_update_aggregate(self):
+ aggregate_id = self.test_aggregate_create()
+ response = self._do_put('os-aggregates/%s' % aggregate_id,
+ 'aggregate-update-post-req', {})
+ subs = self._get_regexes()
+ return self._verify_response('aggregate-update-post-resp',
+ subs, response)
+
+
+class AggregatesSampleXmlTest(AggregatesSampleJsonTest):
+ ctype = 'xml'