diff --git a/doc/v3/api_samples/os-hosts/host-get-reboot.json b/doc/v3/api_samples/os-hosts/host-get-reboot.json
new file mode 100644
index 0000000000..2167d81d0f
--- /dev/null
+++ b/doc/v3/api_samples/os-hosts/host-get-reboot.json
@@ -0,0 +1,6 @@
+{
+ "host": {
+ "host": "9557750dbc464741a89c907921c1cb31",
+ "power_action": "reboot"
+ }
+}
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-hosts/host-get-reboot.xml b/doc/v3/api_samples/os-hosts/host-get-reboot.xml
new file mode 100644
index 0000000000..8b6534e7ec
--- /dev/null
+++ b/doc/v3/api_samples/os-hosts/host-get-reboot.xml
@@ -0,0 +1,5 @@
+
+
+ 34e0a2409dab4052b17b4172a2a44172
+ reboot
+
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-hosts/host-get-resp.json b/doc/v3/api_samples/os-hosts/host-get-resp.json
new file mode 100644
index 0000000000..fc19d3a170
--- /dev/null
+++ b/doc/v3/api_samples/os-hosts/host-get-resp.json
@@ -0,0 +1,31 @@
+{
+ "host": [
+ {
+ "resource": {
+ "cpu": 1,
+ "disk_gb": 1028,
+ "host": "c1a7de0ac9d94e4baceae031d05caae3",
+ "memory_mb": 8192,
+ "project": "(total)"
+ }
+ },
+ {
+ "resource": {
+ "cpu": 0,
+ "disk_gb": 0,
+ "host": "c1a7de0ac9d94e4baceae031d05caae3",
+ "memory_mb": 512,
+ "project": "(used_now)"
+ }
+ },
+ {
+ "resource": {
+ "cpu": 0,
+ "disk_gb": 0,
+ "host": "c1a7de0ac9d94e4baceae031d05caae3",
+ "memory_mb": 0,
+ "project": "(used_max)"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-hosts/host-get-resp.xml b/doc/v3/api_samples/os-hosts/host-get-resp.xml
new file mode 100644
index 0000000000..cb58012c35
--- /dev/null
+++ b/doc/v3/api_samples/os-hosts/host-get-resp.xml
@@ -0,0 +1,24 @@
+
+
+
+ (total)
+ 8192
+ ee7466478092405c8f8e001b9ca0afb0
+ 1
+ 1028
+
+
+ (used_now)
+ 512
+ ee7466478092405c8f8e001b9ca0afb0
+ 0
+ 0
+
+
+ (used_max)
+ 0
+ ee7466478092405c8f8e001b9ca0afb0
+ 0
+ 0
+
+
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-hosts/host-get-shutdown.json b/doc/v3/api_samples/os-hosts/host-get-shutdown.json
new file mode 100644
index 0000000000..8977ad905c
--- /dev/null
+++ b/doc/v3/api_samples/os-hosts/host-get-shutdown.json
@@ -0,0 +1,6 @@
+{
+ "host": {
+ "host": "77cfa0002e4d45fe97f185968111b27b",
+ "power_action": "shutdown"
+ }
+}
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-hosts/host-get-shutdown.xml b/doc/v3/api_samples/os-hosts/host-get-shutdown.xml
new file mode 100644
index 0000000000..28c5ae6b6d
--- /dev/null
+++ b/doc/v3/api_samples/os-hosts/host-get-shutdown.xml
@@ -0,0 +1,5 @@
+
+
+ 9c1d73144d4d43e28fe32840e35fec91
+ shutdown
+
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-hosts/host-get-startup.json b/doc/v3/api_samples/os-hosts/host-get-startup.json
new file mode 100644
index 0000000000..e61e3b2837
--- /dev/null
+++ b/doc/v3/api_samples/os-hosts/host-get-startup.json
@@ -0,0 +1,6 @@
+{
+ "host": {
+ "host": "4b392b27930343bbaa27fd5d8328a564",
+ "power_action": "startup"
+ }
+}
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-hosts/host-get-startup.xml b/doc/v3/api_samples/os-hosts/host-get-startup.xml
new file mode 100644
index 0000000000..9c97f43ab5
--- /dev/null
+++ b/doc/v3/api_samples/os-hosts/host-get-startup.xml
@@ -0,0 +1,5 @@
+
+
+ f6bf5a52bd0645cdb7e1b28a1d647f3c
+ startup
+
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-hosts/host-put-maintenance-req.json b/doc/v3/api_samples/os-hosts/host-put-maintenance-req.json
new file mode 100644
index 0000000000..309a287f1e
--- /dev/null
+++ b/doc/v3/api_samples/os-hosts/host-put-maintenance-req.json
@@ -0,0 +1,6 @@
+{
+ "host": {
+ "status": "enable",
+ "maintenance_mode": "disable"
+ }
+}
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-hosts/host-put-maintenance-req.xml b/doc/v3/api_samples/os-hosts/host-put-maintenance-req.xml
new file mode 100644
index 0000000000..0a17686178
--- /dev/null
+++ b/doc/v3/api_samples/os-hosts/host-put-maintenance-req.xml
@@ -0,0 +1,5 @@
+
+
+ enable
+ disable
+
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-hosts/host-put-maintenance-resp.json b/doc/v3/api_samples/os-hosts/host-put-maintenance-resp.json
new file mode 100644
index 0000000000..591e13ac69
--- /dev/null
+++ b/doc/v3/api_samples/os-hosts/host-put-maintenance-resp.json
@@ -0,0 +1,7 @@
+{
+ "host": {
+ "host": "65c5d5b7e3bd44308e67fc50f362aee6",
+ "maintenance_mode": "off_maintenance",
+ "status": "enabled"
+ }
+}
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-hosts/host-put-maintenance-resp.xml b/doc/v3/api_samples/os-hosts/host-put-maintenance-resp.xml
new file mode 100644
index 0000000000..8ed40b442e
--- /dev/null
+++ b/doc/v3/api_samples/os-hosts/host-put-maintenance-resp.xml
@@ -0,0 +1,6 @@
+
+
+ enabled
+ off_maintenance
+ 966158fd3a084a7791a11c592d1a5fcb
+
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-hosts/hosts-list-resp.json b/doc/v3/api_samples/os-hosts/hosts-list-resp.json
new file mode 100644
index 0000000000..854ca4a767
--- /dev/null
+++ b/doc/v3/api_samples/os-hosts/hosts-list-resp.json
@@ -0,0 +1,39 @@
+{
+ "hosts": [
+ {
+ "host_name": "b6e4adbc193d428ea923899d07fb001e",
+ "service": "conductor",
+ "zone": "internal"
+ },
+ {
+ "host_name": "09c025b0efc64211bd23fc50fa974cdf",
+ "service": "compute",
+ "zone": "nova"
+ },
+ {
+ "host_name": "a942ebfa00064d9d89a9e5a175cb9ba8",
+ "service": "cert",
+ "zone": "internal"
+ },
+ {
+ "host_name": "e73ec0bd35c64de4a1adfa8b8969a1f6",
+ "service": "consoleauth",
+ "zone": "internal"
+ },
+ {
+ "host_name": "396a8a0a234f476eb05fb9fbc5802ba7",
+ "service": "network",
+ "zone": "internal"
+ },
+ {
+ "host_name": "abffda96592c4eacaf4111c28fddee17",
+ "service": "scheduler",
+ "zone": "internal"
+ },
+ {
+ "host_name": "a8820f04962a4b4ba9fe2e9540c24094",
+ "service": "cells",
+ "zone": "internal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/doc/v3/api_samples/os-hosts/hosts-list-resp.xml b/doc/v3/api_samples/os-hosts/hosts-list-resp.xml
new file mode 100644
index 0000000000..d935cd9799
--- /dev/null
+++ b/doc/v3/api_samples/os-hosts/hosts-list-resp.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/nova/tests/integrated/v3/api_samples/os-hosts/host-get-reboot.json.tpl b/nova/tests/integrated/v3/api_samples/os-hosts/host-get-reboot.json.tpl
new file mode 100644
index 0000000000..ad9551e08f
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-hosts/host-get-reboot.json.tpl
@@ -0,0 +1,6 @@
+{
+ "host": {
+ "host": "%(host_name)s",
+ "power_action": "reboot"
+ }
+}
diff --git a/nova/tests/integrated/v3/api_samples/os-hosts/host-get-reboot.xml.tpl b/nova/tests/integrated/v3/api_samples/os-hosts/host-get-reboot.xml.tpl
new file mode 100644
index 0000000000..75328d88a8
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-hosts/host-get-reboot.xml.tpl
@@ -0,0 +1,5 @@
+
+
+ %(host_name)s
+ reboot
+
diff --git a/nova/tests/integrated/v3/api_samples/os-hosts/host-get-resp.json.tpl b/nova/tests/integrated/v3/api_samples/os-hosts/host-get-resp.json.tpl
new file mode 100644
index 0000000000..efb234b436
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-hosts/host-get-resp.json.tpl
@@ -0,0 +1,31 @@
+{
+ "host": [
+ {
+ "resource": {
+ "cpu": 1,
+ "disk_gb": 1028,
+ "host": "%(host_name)s",
+ "memory_mb": 8192,
+ "project": "(total)"
+ }
+ },
+ {
+ "resource": {
+ "cpu": 0,
+ "disk_gb": 0,
+ "host": "%(host_name)s",
+ "memory_mb": 512,
+ "project": "(used_now)"
+ }
+ },
+ {
+ "resource": {
+ "cpu": 0,
+ "disk_gb": 0,
+ "host": "%(host_name)s",
+ "memory_mb": 0,
+ "project": "(used_max)"
+ }
+ }
+ ]
+}
diff --git a/nova/tests/integrated/v3/api_samples/os-hosts/host-get-resp.xml.tpl b/nova/tests/integrated/v3/api_samples/os-hosts/host-get-resp.xml.tpl
new file mode 100644
index 0000000000..e162734ba3
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-hosts/host-get-resp.xml.tpl
@@ -0,0 +1,24 @@
+
+
+
+ (total)
+ 8192
+ %(host_name)s
+ 1
+ 1028
+
+
+ (used_now)
+ 512
+ %(host_name)s
+ 0
+ 0
+
+
+ (used_max)
+ 0
+ %(host_name)s
+ 0
+ 0
+
+
diff --git a/nova/tests/integrated/v3/api_samples/os-hosts/host-get-shutdown.json.tpl b/nova/tests/integrated/v3/api_samples/os-hosts/host-get-shutdown.json.tpl
new file mode 100644
index 0000000000..3d31950b5e
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-hosts/host-get-shutdown.json.tpl
@@ -0,0 +1,6 @@
+{
+ "host": {
+ "host": "%(host_name)s",
+ "power_action": "shutdown"
+ }
+}
diff --git a/nova/tests/integrated/v3/api_samples/os-hosts/host-get-shutdown.xml.tpl b/nova/tests/integrated/v3/api_samples/os-hosts/host-get-shutdown.xml.tpl
new file mode 100644
index 0000000000..a7b2593a78
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-hosts/host-get-shutdown.xml.tpl
@@ -0,0 +1,5 @@
+
+
+ %(host_name)s
+ shutdown
+
diff --git a/nova/tests/integrated/v3/api_samples/os-hosts/host-get-startup.json.tpl b/nova/tests/integrated/v3/api_samples/os-hosts/host-get-startup.json.tpl
new file mode 100644
index 0000000000..a5640e4f25
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-hosts/host-get-startup.json.tpl
@@ -0,0 +1,6 @@
+{
+ "host": {
+ "host": "%(host_name)s",
+ "power_action": "startup"
+ }
+}
diff --git a/nova/tests/integrated/v3/api_samples/os-hosts/host-get-startup.xml.tpl b/nova/tests/integrated/v3/api_samples/os-hosts/host-get-startup.xml.tpl
new file mode 100644
index 0000000000..3797a7cf47
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-hosts/host-get-startup.xml.tpl
@@ -0,0 +1,5 @@
+
+
+ %(host_name)s
+ startup
+
diff --git a/nova/tests/integrated/v3/api_samples/os-hosts/host-put-maintenance-req.json.tpl b/nova/tests/integrated/v3/api_samples/os-hosts/host-put-maintenance-req.json.tpl
new file mode 100644
index 0000000000..d026fd37cd
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-hosts/host-put-maintenance-req.json.tpl
@@ -0,0 +1,6 @@
+{
+ "host": {
+ "status": "enable",
+ "maintenance_mode": "disable"
+ }
+}
diff --git a/nova/tests/integrated/v3/api_samples/os-hosts/host-put-maintenance-req.xml.tpl b/nova/tests/integrated/v3/api_samples/os-hosts/host-put-maintenance-req.xml.tpl
new file mode 100644
index 0000000000..7e1962a81b
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-hosts/host-put-maintenance-req.xml.tpl
@@ -0,0 +1,5 @@
+
+
+ enable
+ disable
+
diff --git a/nova/tests/integrated/v3/api_samples/os-hosts/host-put-maintenance-resp.json.tpl b/nova/tests/integrated/v3/api_samples/os-hosts/host-put-maintenance-resp.json.tpl
new file mode 100644
index 0000000000..5c8f144a99
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-hosts/host-put-maintenance-resp.json.tpl
@@ -0,0 +1,7 @@
+{
+ "host": {
+ "host": "%(host_name)s",
+ "maintenance_mode": "off_maintenance",
+ "status": "enabled"
+ }
+}
diff --git a/nova/tests/integrated/v3/api_samples/os-hosts/host-put-maintenance-resp.xml.tpl b/nova/tests/integrated/v3/api_samples/os-hosts/host-put-maintenance-resp.xml.tpl
new file mode 100644
index 0000000000..ee311c75cf
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-hosts/host-put-maintenance-resp.xml.tpl
@@ -0,0 +1,6 @@
+
+
+ enabled
+ off_maintenance
+ %(host_name)s
+
diff --git a/nova/tests/integrated/v3/api_samples/os-hosts/hosts-list-resp.json.tpl b/nova/tests/integrated/v3/api_samples/os-hosts/hosts-list-resp.json.tpl
new file mode 100644
index 0000000000..cd5bfdf999
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-hosts/hosts-list-resp.json.tpl
@@ -0,0 +1,39 @@
+{
+ "hosts": [
+ {
+ "host_name": "%(host_name)s",
+ "service": "conductor",
+ "zone": "internal"
+ },
+ {
+ "host_name": "%(host_name)s",
+ "service": "compute",
+ "zone": "nova"
+ },
+ {
+ "host_name": "%(host_name)s",
+ "service": "cert",
+ "zone": "internal"
+ },
+ {
+ "host_name": "%(host_name)s",
+ "service": "consoleauth",
+ "zone": "internal"
+ },
+ {
+ "host_name": "%(host_name)s",
+ "service": "network",
+ "zone": "internal"
+ },
+ {
+ "host_name": "%(host_name)s",
+ "service": "scheduler",
+ "zone": "internal"
+ },
+ {
+ "host_name": "%(host_name)s",
+ "service": "cells",
+ "zone": "internal"
+ }
+ ]
+}
diff --git a/nova/tests/integrated/v3/api_samples/os-hosts/hosts-list-resp.xml.tpl b/nova/tests/integrated/v3/api_samples/os-hosts/hosts-list-resp.xml.tpl
new file mode 100644
index 0000000000..b45394ca75
--- /dev/null
+++ b/nova/tests/integrated/v3/api_samples/os-hosts/hosts-list-resp.xml.tpl
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/nova/tests/integrated/v3/test_hosts.py b/nova/tests/integrated/v3/test_hosts.py
new file mode 100644
index 0000000000..2c1eebe79b
--- /dev/null
+++ b/nova/tests/integrated/v3/test_hosts.py
@@ -0,0 +1,56 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+# Copyright 2012 Nebula, Inc.
+# Copyright 2013 IBM Corp.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from nova.tests.integrated.v3 import api_sample_base
+
+
+class HostsSampleJsonTest(api_sample_base.ApiSampleTestBaseV3):
+ extension_name = "os-hosts"
+
+ def test_host_startup(self):
+ response = self._do_get('os-hosts/%s/startup' % self.compute.host)
+ subs = self._get_regexes()
+ self._verify_response('host-get-startup', subs, response, 200)
+
+ def test_host_reboot(self):
+ response = self._do_get('os-hosts/%s/reboot' % self.compute.host)
+ subs = self._get_regexes()
+ self._verify_response('host-get-reboot', subs, response, 200)
+
+ def test_host_shutdown(self):
+ response = self._do_get('os-hosts/%s/shutdown' % self.compute.host)
+ subs = self._get_regexes()
+ self._verify_response('host-get-shutdown', subs, response, 200)
+
+ def test_host_maintenance(self):
+ response = self._do_put('os-hosts/%s' % self.compute.host,
+ 'host-put-maintenance-req', {})
+ subs = self._get_regexes()
+ self._verify_response('host-put-maintenance-resp', subs, response, 200)
+
+ def test_host_get(self):
+ response = self._do_get('os-hosts/%s' % self.compute.host)
+ subs = self._get_regexes()
+ self._verify_response('host-get-resp', subs, response, 200)
+
+ def test_hosts_list(self):
+ response = self._do_get('os-hosts')
+ subs = self._get_regexes()
+ self._verify_response('hosts-list-resp', subs, response, 200)
+
+
+class HostsSampleXmlTest(HostsSampleJsonTest):
+ ctype = 'xml'