diff options
author | Armando Migliaccio <armando.migliaccio@eu.citrix.com> | 2012-02-14 22:56:42 +0000 |
---|---|---|
committer | Armando Migliaccio <armando.migliaccio@eu.citrix.com> | 2012-02-17 18:37:10 +0000 |
commit | ddc1b2c083323781334fdca7467b4914e823e0d6 (patch) | |
tree | 31b4ddab0f974a029628fcbb50d4fbb6b0d0391f | |
parent | bca5acddafcf0cc7864022db92ae47ee1c61b29f (diff) | |
download | python-novaclient-ddc1b2c083323781334fdca7467b4914e823e0d6.tar.gz |
bug 932408: python-novaclient miss OSAPI host operations
add client bindings for host-related actions.
Change-Id: I98b3c11ec189029bafe73f499070ab132de640af
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | README.rst | 2 | ||||
-rw-r--r-- | novaclient/base.py | 7 | ||||
-rw-r--r-- | novaclient/v1_1/hosts.py | 27 | ||||
-rw-r--r-- | novaclient/v1_1/shell.py | 30 | ||||
-rw-r--r-- | tests/v1_1/fakes.py | 33 | ||||
-rw-r--r-- | tests/v1_1/test_hosts.py | 40 | ||||
-rw-r--r-- | tests/v1_1/test_shell.py | 28 |
8 files changed, 163 insertions, 5 deletions
@@ -3,6 +3,7 @@ Andrey Brindeyev <abrindeyev@griddynamics.com> Andy Smith <github@anarkystic.com> Anthony Young <sleepsonthefloor@gmail.com> Antony Messerli <amesserl@rackspace.com> +Armando Migliaccio <Armando.Migliaccio@eu.citrix.com> Brian Lamar <brian.lamar@rackspace.com> Brian Waldon <brian.waldon@rackspace.com> Chmouel Boudjnah <chmouel.boudjnah@rackspace.co.uk> @@ -107,6 +107,8 @@ You'll find complete documentation on the shell by running get-vnc-console Get a vnc console for a server help Display help about this program or one of its subcommands. + host-update Update the host status or maintenance mode + host-action Perform a power action on the host image-create Create a new image by taking a snapshot of a running server. image-delete Delete an image. diff --git a/novaclient/base.py b/novaclient/base.py index a24825f7..30ea73ec 100644 --- a/novaclient/base.py +++ b/novaclient/base.py @@ -135,9 +135,12 @@ class Manager(utils.HookableMixin): if hasattr(self, '_uuid_cache'): self._uuid_cache.write("%s\n" % uuid) - def _get(self, url, response_key): + def _get(self, url, response_key=None): resp, body = self.api.client.get(url) - return self.resource_class(self, body[response_key]) + if response_key: + return self.resource_class(self, body[response_key]) + else: + return self.resource_class(self, body) def _create(self, url, body, response_key, return_raw=False, **kwargs): self.run_hooks('modify_body_for_create', body, **kwargs) diff --git a/novaclient/v1_1/hosts.py b/novaclient/v1_1/hosts.py index bb595038..172b08b7 100644 --- a/novaclient/v1_1/hosts.py +++ b/novaclient/v1_1/hosts.py @@ -24,11 +24,22 @@ class Host(base.Resource): return "<Host: %s>" % self.host def _add_details(self, info): - dico = 'resource' in info and \ - info['resource'] or info + dico = 'resource' in info and info['resource'] or info for (k, v) in dico.items(): setattr(self, k, v) + def update(self, values): + return self.manager.update(self.host, values) + + def startup(self): + return self.manager.host_action(self.host, 'startup') + + def shutdown(self): + return self.manager.host_action(self.host, 'shutdown') + + def reboot(self): + return self.manager.host_action(self.host, 'reboot') + class HostManager(base.ManagerWithFind): resource_class = Host @@ -39,4 +50,14 @@ class HostManager(base.ManagerWithFind): :param host: destination host name. """ - return self._list("/os-hosts/%s" % (host), "host") + return self._list("/os-hosts/%s" % host, "host") + + def update(self, host, values): + """Update status or maintenance mode for the host.""" + result = self._update("/os-hosts/%s" % host, values) + return self.resource_class(self, result) + + def host_action(self, host, action): + """Performs an action on a host.""" + url = "/os-hosts/%s/%s" % (host, action) + return self._get(url) diff --git a/novaclient/v1_1/shell.py b/novaclient/v1_1/shell.py index f0dd81be..1e63c3f0 100644 --- a/novaclient/v1_1/shell.py +++ b/novaclient/v1_1/shell.py @@ -1408,6 +1408,36 @@ def do_describe_resource(cs, args): utils.print_list(result, columns) +@utils.arg('host', metavar='<hostname>', help='Name of host.') +@utils.arg('--status', metavar='<status>', default=None, dest='status', + help='Either enable or disable a host.') +@utils.arg('--maintenance', metavar='<maintenance_mode>', default=None, + dest='maintenance', + help='Either put or resume host to/from maintenance.') +def do_host_update(cs, args): + """Update host settings.""" + updates = {} + columns = ["HOST"] + if args.status: + updates['status'] = args.status + columns.append("status") + if args.maintenance: + updates['maintenance_mode'] = args.maintenance + columns.append("maintenance_mode") + result = cs.hosts.update(args.host, updates) + utils.print_list([result], columns) + + +@utils.arg('host', metavar='<hostname>', help='Name of host.') +@utils.arg('--action', metavar='<action>', dest='action', + choices=['startup', 'shutdown', 'reboot'], + help='A power action: startup, reboot, or shutdown.') +def do_host_action(cs, args): + """Perform a power action on a host.""" + result = cs.hosts.host_action(args.host, args.action) + utils.print_list([result], ['HOST', 'power_action']) + + def do_endpoints(cs, args): """Discover endpoints that get returned from the authenticate services""" catalog = cs.client.service_catalog.catalog diff --git a/tests/v1_1/fakes.py b/tests/v1_1/fakes.py index c2880018..e9127157 100644 --- a/tests/v1_1/fakes.py +++ b/tests/v1_1/fakes.py @@ -720,3 +720,36 @@ class FakeHTTPClient(base_client.HTTPClient): 'cpu': 1, 'memory_mb': 2048, 'disk_gb': 30}}, {'resource': {'project': 'admin', 'host': 'dummy', 'cpu': 1, 'memory_mb': 2048, 'disk_gb': 30}}]}) + + def get_os_hosts_sample_host(self, *kw): + return (200, {'host': [{'resource': {'host': 'sample_host'}}], }) + + def put_os_hosts_sample_host_1(self, body, **kw): + return (200, {'host': 'sample-host_1', + 'status': 'enabled'}) + + def put_os_hosts_sample_host_2(self, body, **kw): + return (200, {'host': 'sample-host_2', + 'maintenance_mode': 'on_maintenance'}) + + def put_os_hosts_sample_host_3(self, body, **kw): + return (200, {'host': 'sample-host_3', + 'status': 'enabled', + 'maintenance_mode': 'on_maintenance'}) + + def get_os_hosts_sample_host_startup(self, **kw): + return (200, {'host': 'sample_host', + 'power_action': 'startup'}) + + def get_os_hosts_sample_host_reboot(self, **kw): + return (200, {'host': 'sample_host', + 'power_action': 'reboot'}) + + def get_os_hosts_sample_host_shutdown(self, **kw): + return (200, {'host': 'sample_host', + 'power_action': 'shutdown'}) + + def put_os_hosts_sample_host(self, body, **kw): + result = {'host': 'dummy'} + result.update(body) + return (200, result) diff --git a/tests/v1_1/test_hosts.py b/tests/v1_1/test_hosts.py index 5151c283..a6e8b5c7 100644 --- a/tests/v1_1/test_hosts.py +++ b/tests/v1_1/test_hosts.py @@ -12,3 +12,43 @@ class HostsTest(utils.TestCase): hs = cs.hosts.get('host') cs.assert_called('GET', '/os-hosts/host') [self.assertTrue(isinstance(h, hosts.Host)) for h in hs] + + def test_update_enable(self): + host = cs.hosts.get('sample_host')[0] + values = {"status": "enabled"} + result = host.update(values) + cs.assert_called('PUT', '/os-hosts/sample_host', values) + self.assertTrue(isinstance(result, hosts.Host)) + + def test_update_maintenance(self): + host = cs.hosts.get('sample_host')[0] + values = {"maintenance_mode": "enable"} + result = host.update(values) + cs.assert_called('PUT', '/os-hosts/sample_host', values) + self.assertTrue(isinstance(result, hosts.Host)) + + def test_update_both(self): + host = cs.hosts.get('sample_host')[0] + values = {"status": "enabled", + "maintenance_mode": "enable"} + result = host.update(values) + cs.assert_called('PUT', '/os-hosts/sample_host', values) + self.assertTrue(isinstance(result, hosts.Host)) + + def test_host_startup(self): + host = cs.hosts.get('sample_host')[0] + result = host.startup() + cs.assert_called('GET', '/os-hosts/sample_host/startup') + self.assertTrue(isinstance(result, hosts.Host)) + + def test_host_reboot(self): + host = cs.hosts.get('sample_host')[0] + result = host.reboot() + cs.assert_called('GET', '/os-hosts/sample_host/reboot') + self.assertTrue(isinstance(result, hosts.Host)) + + def test_host_shutdown(self): + host = cs.hosts.get('sample_host')[0] + result = host.shutdown() + cs.assert_called('GET', '/os-hosts/sample_host/shutdown') + self.assertTrue(isinstance(result, hosts.Host)) diff --git a/tests/v1_1/test_shell.py b/tests/v1_1/test_shell.py index 31123414..ed138d98 100644 --- a/tests/v1_1/test_shell.py +++ b/tests/v1_1/test_shell.py @@ -385,3 +385,31 @@ class ShellTest(utils.TestCase): {'os-migrateLive': {'host': 'hostname', 'block_migration': True, 'disk_over_commit': True}}) + + def test_host_update_status(self): + self.run_command('host-update sample-host_1 --status enabled') + body = {'status': 'enabled'} + self.assert_called('PUT', '/os-hosts/sample-host_1', body) + + def test_host_update_maintenance(self): + self.run_command('host-update sample-host_2 --maintenance enable') + body = {'maintenance_mode': 'enable'} + self.assert_called('PUT', '/os-hosts/sample-host_2', body) + + def test_host_update_multiple_settings(self): + self.run_command('host-update sample-host_3 ' + '--status disabled --maintenance enable') + body = {'status': 'disabled', 'maintenance_mode': 'enable'} + self.assert_called('PUT', '/os-hosts/sample-host_3', body) + + def test_host_startup(self): + self.run_command('host-action sample-host --action startup') + self.assert_called('GET', '/os-hosts/sample-host/startup') + + def test_host_shutdown(self): + self.run_command('host-action sample-host --action shutdown') + self.assert_called('GET', '/os-hosts/sample-host/shutdown') + + def test_host_reboot(self): + self.run_command('host-action sample-host --action reboot') + self.assert_called('GET', '/os-hosts/sample-host/reboot') |