bug 932408: python-novaclient miss OSAPI host operations
add client bindings for host-related actions. Change-Id: I98b3c11ec189029bafe73f499070ab132de640af
This commit is contained in:
parent
bca5acddaf
commit
ddc1b2c083
1
AUTHORS
1
AUTHORS
|
@ -3,6 +3,7 @@ Andrey Brindeyev <abrindeyev@griddynamics.com>
|
||||||
Andy Smith <github@anarkystic.com>
|
Andy Smith <github@anarkystic.com>
|
||||||
Anthony Young <sleepsonthefloor@gmail.com>
|
Anthony Young <sleepsonthefloor@gmail.com>
|
||||||
Antony Messerli <amesserl@rackspace.com>
|
Antony Messerli <amesserl@rackspace.com>
|
||||||
|
Armando Migliaccio <Armando.Migliaccio@eu.citrix.com>
|
||||||
Brian Lamar <brian.lamar@rackspace.com>
|
Brian Lamar <brian.lamar@rackspace.com>
|
||||||
Brian Waldon <brian.waldon@rackspace.com>
|
Brian Waldon <brian.waldon@rackspace.com>
|
||||||
Chmouel Boudjnah <chmouel.boudjnah@rackspace.co.uk>
|
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
|
get-vnc-console Get a vnc console for a server
|
||||||
help Display help about this program or one of its
|
help Display help about this program or one of its
|
||||||
subcommands.
|
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
|
image-create Create a new image by taking a snapshot of a running
|
||||||
server.
|
server.
|
||||||
image-delete Delete an image.
|
image-delete Delete an image.
|
||||||
|
|
|
@ -135,9 +135,12 @@ class Manager(utils.HookableMixin):
|
||||||
if hasattr(self, '_uuid_cache'):
|
if hasattr(self, '_uuid_cache'):
|
||||||
self._uuid_cache.write("%s\n" % uuid)
|
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)
|
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):
|
def _create(self, url, body, response_key, return_raw=False, **kwargs):
|
||||||
self.run_hooks('modify_body_for_create', body, **kwargs)
|
self.run_hooks('modify_body_for_create', body, **kwargs)
|
||||||
|
|
|
@ -24,11 +24,22 @@ class Host(base.Resource):
|
||||||
return "<Host: %s>" % self.host
|
return "<Host: %s>" % self.host
|
||||||
|
|
||||||
def _add_details(self, info):
|
def _add_details(self, info):
|
||||||
dico = 'resource' in info and \
|
dico = 'resource' in info and info['resource'] or info
|
||||||
info['resource'] or info
|
|
||||||
for (k, v) in dico.items():
|
for (k, v) in dico.items():
|
||||||
setattr(self, k, v)
|
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):
|
class HostManager(base.ManagerWithFind):
|
||||||
resource_class = Host
|
resource_class = Host
|
||||||
|
@ -39,4 +50,14 @@ class HostManager(base.ManagerWithFind):
|
||||||
|
|
||||||
:param host: destination host name.
|
: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)
|
||||||
|
|
|
@ -1408,6 +1408,36 @@ def do_describe_resource(cs, args):
|
||||||
utils.print_list(result, columns)
|
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):
|
def do_endpoints(cs, args):
|
||||||
"""Discover endpoints that get returned from the authenticate services"""
|
"""Discover endpoints that get returned from the authenticate services"""
|
||||||
catalog = cs.client.service_catalog.catalog
|
catalog = cs.client.service_catalog.catalog
|
||||||
|
|
|
@ -720,3 +720,36 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||||
'cpu': 1, 'memory_mb': 2048, 'disk_gb': 30}},
|
'cpu': 1, 'memory_mb': 2048, 'disk_gb': 30}},
|
||||||
{'resource': {'project': 'admin', 'host': 'dummy',
|
{'resource': {'project': 'admin', 'host': 'dummy',
|
||||||
'cpu': 1, 'memory_mb': 2048, 'disk_gb': 30}}]})
|
'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)
|
||||||
|
|
|
@ -12,3 +12,43 @@ class HostsTest(utils.TestCase):
|
||||||
hs = cs.hosts.get('host')
|
hs = cs.hosts.get('host')
|
||||||
cs.assert_called('GET', '/os-hosts/host')
|
cs.assert_called('GET', '/os-hosts/host')
|
||||||
[self.assertTrue(isinstance(h, hosts.Host)) for h in hs]
|
[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))
|
||||||
|
|
|
@ -385,3 +385,31 @@ class ShellTest(utils.TestCase):
|
||||||
{'os-migrateLive': {'host': 'hostname',
|
{'os-migrateLive': {'host': 'hostname',
|
||||||
'block_migration': True,
|
'block_migration': True,
|
||||||
'disk_over_commit': 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')
|
||||||
|
|
Loading…
Reference in New Issue