Remove deprecated os-hosts CLIs and python API bindings

These were all deprecated in the 9.0.0 release in Pike
via change I79091edf5a2569e49e79deba312456fdcdee09e1 and
can now be removed. This will go into the 10.0.0 release.

Change-Id: I85a287ff2666c2dcdcbbc8fd6c2e285176f7a67a
This commit is contained in:
Matt Riedemann 2018-01-11 16:59:20 -05:00
parent 8c73ba4471
commit 1d88717e75
9 changed files with 14 additions and 593 deletions

View File

@ -51,9 +51,6 @@ class SimpleReadOnlyNovaClientTest(base.ClientTestBase):
def test_admin_flavor_list(self):
self.assertIn("Memory_MB", self.nova('flavor-list'))
def test_admin_host_list(self):
self.nova('host-list')
def test_admin_hypervisor_list(self):
self.nova('hypervisor-list')

View File

@ -1,144 +0,0 @@
# 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 novaclient.tests.unit.fixture_data import base
class BaseFixture(base.Fixture):
base_url = 'os-hosts'
def setUp(self):
super(BaseFixture, self).setUp()
get_os_hosts_host = {
'host': [
{'resource': {'project': '(total)', 'host': 'dummy',
'cpu': 16, 'memory_mb': 32234, 'disk_gb': 128}},
{'resource': {'project': '(used_now)', 'host': 'dummy',
'cpu': 1, 'memory_mb': 2075, 'disk_gb': 45}},
{'resource': {'project': '(used_max)', 'host': 'dummy',
'cpu': 1, 'memory_mb': 2048, 'disk_gb': 30}},
{'resource': {'project': 'admin', 'host': 'dummy',
'cpu': 1, 'memory_mb': 2048, 'disk_gb': 30}}
]
}
headers = self.json_headers
self.requests_mock.get(self.url('host'),
json=get_os_hosts_host,
headers=headers)
def get_os_hosts(request, context):
zone = 'nova1'
service = None
if request.query:
try:
zone = request.qs['zone'][0]
except Exception:
pass
try:
service = request.qs['service'][0]
except Exception:
pass
return {
'hosts': [
{
'host_name': 'host1',
'service': service or 'nova-compute',
'zone': zone
},
{
'host_name': 'host1',
'service': service or 'nova-cert',
'zone': zone
}
]
}
self.requests_mock.get(self.url(),
json=get_os_hosts,
headers=headers)
get_os_hosts_sample_host = {
'host': [
{'resource': {'host': 'sample_host'}}
],
}
self.requests_mock.get(self.url('sample_host'),
json=get_os_hosts_sample_host,
headers=headers)
self.requests_mock.put(self.url('sample_host', 1),
json=self.put_host_1(),
headers=headers)
self.requests_mock.put(self.url('sample_host', 2),
json=self.put_host_2(),
headers=headers)
self.requests_mock.put(self.url('sample_host', 3),
json=self.put_host_3(),
headers=headers)
self.requests_mock.get(self.url('sample_host', 'reboot'),
json=self.get_host_reboot(),
headers=headers)
self.requests_mock.get(self.url('sample_host', 'startup'),
json=self.get_host_startup(),
headers=headers)
self.requests_mock.get(self.url('sample_host', 'shutdown'),
json=self.get_host_shutdown(),
headers=headers)
def put_os_hosts_sample_host(request, context):
result = {'host': 'dummy'}
result.update(request.json())
return result
self.requests_mock.put(self.url('sample_host'),
json=put_os_hosts_sample_host,
headers=headers)
class V1(BaseFixture):
def put_host_1(self):
return {'host': 'sample-host_1',
'status': 'enabled'}
def put_host_2(self):
return {'host': 'sample-host_2',
'maintenance_mode': 'on_maintenance'}
def put_host_3(self):
return {'host': 'sample-host_3',
'status': 'enabled',
'maintenance_mode': 'on_maintenance'}
def get_host_reboot(self):
return {'host': 'sample_host',
'power_action': 'reboot'}
def get_host_startup(self):
return {'host': 'sample_host',
'power_action': 'startup'}
def get_host_shutdown(self):
return {'host': 'sample_host',
'power_action': 'shutdown'}

View File

@ -1672,43 +1672,9 @@ class FakeSessionClient(base_client.SessionClient):
'forced_down': False}})
#
# Hosts
# Hypervisors
#
def get_os_hosts(self, **kw):
zone = kw.get('zone', 'nova1')
return (200, {}, {'hosts': [{'host': 'host1',
'service': 'nova-compute',
'zone': zone},
{'host': 'host1',
'service': 'nova-cert',
'zone': zone}]})
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_reboot(self, **kw):
return (200, {}, {'host': 'sample_host',
'power_action': 'reboot'})
def get_os_hosts_sample_host_startup(self, **kw):
return (200, {}, {'host': 'sample_host',
'power_action': 'startup'})
def get_os_hosts_sample_host_shutdown(self, **kw):
return (200, {}, {'host': 'sample_host',
'power_action': 'shutdown'})
def get_os_hypervisors(self, **kw):
return (200, {}, {
"hypervisors": [

View File

@ -1,148 +0,0 @@
#
# 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.
import mock
from novaclient import api_versions
from novaclient import exceptions
from novaclient.tests.unit.fixture_data import client
from novaclient.tests.unit.fixture_data import hosts as data
from novaclient.tests.unit import utils
from novaclient.tests.unit.v2 import fakes
from novaclient.v2 import hosts
class HostsTest(utils.FixturedTestCase):
client_fixture_class = client.V1
data_fixture_class = data.V1
def setUp(self):
super(HostsTest, self).setUp()
self.warning_mock = mock.patch('warnings.warn').start()
self.addCleanup(self.warning_mock.stop)
def test_describe_resource(self):
hs = self.cs.hosts.get('host')
self.warning_mock.assert_called_once()
self.assert_request_id(hs, fakes.FAKE_REQUEST_ID_LIST)
self.assert_called('GET', '/os-hosts/host')
for h in hs:
self.assertIsInstance(h, hosts.Host)
def test_list_host(self):
hs = self.cs.hosts.list()
self.warning_mock.assert_called_once()
self.assert_request_id(hs, fakes.FAKE_REQUEST_ID_LIST)
self.assert_called('GET', '/os-hosts')
for h in hs:
self.assertIsInstance(h, hosts.Host)
self.assertEqual(h.zone, 'nova1')
def test_list_host_with_zone(self):
hs = self.cs.hosts.list('nova')
self.assert_request_id(hs, fakes.FAKE_REQUEST_ID_LIST)
self.assert_called('GET', '/os-hosts?zone=nova')
for h in hs:
self.assertIsInstance(h, hosts.Host)
self.assertEqual(h.zone, 'nova')
def test_update_enable(self):
host = self.cs.hosts.get('sample_host')[0]
values = {"status": "enabled"}
result = host.update(values)
# one warning for the get, one warning for the update
self.assertEqual(2, self.warning_mock.call_count)
self.assert_request_id(result, fakes.FAKE_REQUEST_ID_LIST)
self.assert_called('PUT', '/os-hosts/sample_host', values)
self.assertIsInstance(result, hosts.Host)
def test_update_maintenance(self):
host = self.cs.hosts.get('sample_host')[0]
values = {"maintenance_mode": "enable"}
result = host.update(values)
self.assert_request_id(result, fakes.FAKE_REQUEST_ID_LIST)
self.assert_called('PUT', '/os-hosts/sample_host', values)
self.assertIsInstance(result, hosts.Host)
def test_update_both(self):
host = self.cs.hosts.get('sample_host')[0]
values = {"status": "enabled",
"maintenance_mode": "enable"}
result = host.update(values)
self.assert_request_id(result, fakes.FAKE_REQUEST_ID_LIST)
self.assert_called('PUT', '/os-hosts/sample_host', values)
self.assertIsInstance(result, hosts.Host)
def test_host_startup(self):
host = self.cs.hosts.get('sample_host')[0]
result = host.startup()
# one warning for the get, one warning for the action
self.assertEqual(2, self.warning_mock.call_count)
self.assert_request_id(result, fakes.FAKE_REQUEST_ID_LIST)
self.assert_called(
'GET', '/os-hosts/sample_host/startup')
def test_host_reboot(self):
host = self.cs.hosts.get('sample_host')[0]
result = host.reboot()
# one warning for the get, one warning for the action
self.assertEqual(2, self.warning_mock.call_count)
self.assert_request_id(result, fakes.FAKE_REQUEST_ID_LIST)
self.assert_called(
'GET', '/os-hosts/sample_host/reboot')
def test_host_shutdown(self):
host = self.cs.hosts.get('sample_host')[0]
result = host.shutdown()
# one warning for the get, one warning for the action
self.assertEqual(2, self.warning_mock.call_count)
self.assert_request_id(result, fakes.FAKE_REQUEST_ID_LIST)
self.assert_called(
'GET', '/os-hosts/sample_host/shutdown')
def test_hosts_repr(self):
hs = self.cs.hosts.get('host')
self.assertEqual('<Host: dummy>', repr(hs[0]))
def test_hosts_list_repr(self):
hs = self.cs.hosts.list()
for h in hs:
self.assertEqual('<Host: %s>' % h.host_name, repr(h))
class DeprecatedHostsTestv2_43(utils.FixturedTestCase):
"""Tests the os-hosts API bindings at microversion 2.43 to ensure
they fail with a 404 error.
"""
client_fixture_class = client.V1
def setUp(self):
super(DeprecatedHostsTestv2_43, self).setUp()
self.cs.api_version = api_versions.APIVersion('2.43')
def test_get(self):
self.assertRaises(exceptions.VersionNotFoundForAPIMethod,
self.cs.hosts.get, 'host')
def test_list(self):
self.assertRaises(exceptions.VersionNotFoundForAPIMethod,
self.cs.hosts.list)
def test_update(self):
self.assertRaises(exceptions.VersionNotFoundForAPIMethod,
self.cs.hosts.update, 'host', {"status": "enabled"})
def test_host_action(self):
self.assertRaises(exceptions.VersionNotFoundForAPIMethod,
self.cs.hosts.host_action, 'host', 'reboot')

View File

@ -2454,66 +2454,6 @@ class ShellTest(utils.TestCase):
self.assert_called(
'DELETE', '/os-services/%s' % fakes.FAKE_SERVICE_UUID_1)
def test_host_list(self):
_, err = self.run_command('host-list')
# make sure we said it's deprecated
self.assertIn('WARNING: Command host-list is deprecated', err)
# and replaced with hypervisor-list
self.assertIn('hypervisor-list', err)
self.assert_called('GET', '/os-hosts')
def test_host_list_with_zone(self):
self.run_command('host-list --zone nova')
self.assert_called('GET', '/os-hosts?zone=nova')
def test_host_update_status(self):
_, err = self.run_command('host-update sample-host_1 --status enable')
# make sure we said it's deprecated
self.assertIn('WARNING: Command host-update is deprecated', err)
# and replaced with service-enable
self.assertIn('service-enable', err)
body = {'status': 'enable'}
self.assert_called('PUT', '/os-hosts/sample-host_1', body)
def test_host_update_maintenance(self):
_, err = (
self.run_command('host-update sample-host_2 --maintenance enable'))
# make sure we said it's deprecated
self.assertIn('WARNING: Command host-update is deprecated', err)
# and there is no replacement
self.assertIn('There is no replacement', err)
body = {'maintenance_mode': 'enable'}
self.assert_called('PUT', '/os-hosts/sample-host_2', body)
def test_host_update_multiple_settings(self):
_, err = self.run_command('host-update sample-host_3 '
'--status disable --maintenance enable')
# make sure we said it's deprecated
self.assertIn('WARNING: Command host-update is deprecated', err)
# and replaced with service-disable
self.assertIn('service-disable', err)
body = {'status': 'disable', 'maintenance_mode': 'enable'}
self.assert_called('PUT', '/os-hosts/sample-host_3', body)
def test_host_startup(self):
_, err = self.run_command('host-action sample-host --action startup')
# make sure we said it's deprecated
self.assertIn('WARNING: Command host-action is deprecated', err)
# and there is no replacement
self.assertIn('There is no replacement', err)
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')
def test_host_evacuate_v2_14(self):
self.run_command('host-evacuate hyper --target target_hyper',
api_version='2.14')

View File

@ -26,7 +26,6 @@ from novaclient.v2 import cells
from novaclient.v2 import contrib
from novaclient.v2 import flavor_access
from novaclient.v2 import flavors
from novaclient.v2 import hosts
from novaclient.v2 import hypervisors
from novaclient.v2 import images
from novaclient.v2 import instance_action
@ -156,7 +155,6 @@ class Client(object):
self.virtual_interfaces = \
virtual_interfaces.VirtualInterfaceManager(self)
self.aggregates = aggregates.AggregateManager(self)
self.hosts = hosts.HostManager(self)
self.hypervisors = hypervisors.HypervisorManager(self)
self.hypervisor_stats = hypervisors.HypervisorStatsManager(self)
self.services = services.ServiceManager(self)

View File

@ -1,112 +0,0 @@
# Copyright 2011 OpenStack Foundation
# All Rights Reserved.
#
# 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.
"""
DEPRECATED host interface
"""
import warnings
from novaclient import api_versions
from novaclient import base
from novaclient.i18n import _
HOSTS_DEPRECATION_WARNING = (
_('The os-hosts API is deprecated. This API binding will be removed '
'in the first major release after the Nova server 16.0.0 Pike release.')
)
class Host(base.Resource):
"""DEPRECATED"""
def __repr__(self):
return "<Host: %s>" % self.host
def _add_details(self, info):
dico = 'resource' in info and info['resource'] or info
for (k, v) in dico.items():
setattr(self, k, v)
@api_versions.wraps("2.0", "2.42")
def update(self, values):
return self.manager.update(self.host, values)
@api_versions.wraps("2.0", "2.42")
def startup(self):
return self.manager.host_action(self.host, 'startup')
@api_versions.wraps("2.0", "2.42")
def shutdown(self):
return self.manager.host_action(self.host, 'shutdown')
@api_versions.wraps("2.0", "2.42")
def reboot(self):
return self.manager.host_action(self.host, 'reboot')
@property
def host_name(self):
return self.host
@host_name.setter
def host_name(self, value):
# A host from hosts.list() has the attribute "host_name" instead of
# "host." This sets "host" if that's the case. Even though it doesn't
# exactly mirror the response format, it enables users to work with
# host objects from list and non-list operations interchangeably.
self.host = value
class HostManager(base.ManagerWithFind):
resource_class = Host
@api_versions.wraps("2.0", "2.42")
def get(self, host):
"""
DEPRECATED Describes cpu/memory/hdd info for host.
:param host: destination host name.
"""
warnings.warn(HOSTS_DEPRECATION_WARNING, DeprecationWarning)
return self._list("/os-hosts/%s" % host, "host")
@api_versions.wraps("2.0", "2.42")
def update(self, host, values):
"""DEPRECATED Update status or maintenance mode for the host."""
warnings.warn(HOSTS_DEPRECATION_WARNING, DeprecationWarning)
return self._update("/os-hosts/%s" % host, values)
@api_versions.wraps("2.0", "2.42")
def host_action(self, host, action):
"""
DEPRECATED Perform an action on a host.
:param host: The host to perform an action
:param action: The action to perform
:returns: An instance of novaclient.base.TupleWithMeta
"""
warnings.warn(HOSTS_DEPRECATION_WARNING, DeprecationWarning)
url = '/os-hosts/%s/%s' % (host, action)
resp, body = self.api.client.get(url)
return base.TupleWithMeta((resp, body), resp)
@api_versions.wraps("2.0", "2.42")
def list(self, zone=None):
warnings.warn(HOSTS_DEPRECATION_WARNING, DeprecationWarning)
url = '/os-hosts'
if zone:
url = '/os-hosts?zone=%s' % zone
return self._list(url, "hosts")
list_all = list

View File

@ -49,26 +49,6 @@ from novaclient.v2 import servers
logger = logging.getLogger(__name__)
# NOTE(mriedem): Remove this along with the deprecated commands in the first
# major python-novaclient release AFTER the nova server 16.0.0 Pike release.
def emit_hosts_deprecation_warning(command_name, replacement=None):
if replacement is None:
print(_('WARNING: Command %s is deprecated and will be removed '
'in the first major release after the Nova server 16.0.0 '
'Pike release. There is no replacement or alternative for '
'this command. Specify --os-compute-api-version less than '
'2.43 to continue using this command until it is removed.') %
command_name, file=sys.stderr)
else:
print(_('WARNING: Command %(command)s is deprecated and will be '
'removed in the first major release after the Nova server '
'16.0.0 Pike release. Use %(replacement)s instead. Specify '
'--os-compute-api-version less than 2.43 to continue using '
'this command until it is removed.') %
{'command': command_name, 'replacement': replacement},
file=sys.stderr)
# NOTE(mriedem): Remove this along with the deprecated commands in the first
# major python-novaclient release AFTER the nova server 16.0.0 Pike release.
def emit_fixed_floating_deprecation_warning(command_name):
@ -3598,75 +3578,6 @@ def do_service_delete(cs, args):
cs.services.delete(args.id)
@utils.arg('host', metavar='<hostname>', help=_('Name of host.'))
def do_host_describe(cs, args):
"""DEPRECATED Describe a specific host."""
emit_hosts_deprecation_warning('host-describe', 'hypervisor-show')
result = cs.hosts.get(args.host)
columns = ["HOST", "PROJECT", "cpu", "memory_mb", "disk_gb"]
utils.print_list(result, columns)
@utils.arg(
'--zone',
metavar='<zone>',
default=None,
help=_('Filters the list, returning only those hosts in the availability '
'zone <zone>.'))
def do_host_list(cs, args):
"""DEPRECATED List all hosts by service."""
emit_hosts_deprecation_warning('host-list', 'hypervisor-list')
columns = ["host_name", "service", "zone"]
result = cs.hosts.list(args.zone)
utils.print_list(result, columns)
@utils.arg('host', metavar='<hostname>', help=_('Name of host.'))
@utils.arg(
'--status', metavar='<enable|disable>', default=None, dest='status',
help=_('Either enable or disable a host.'))
@utils.arg(
'--maintenance',
metavar='<enable|disable>',
default=None,
dest='maintenance',
help=_('Either put or resume host to/from maintenance.'))
def do_host_update(cs, args):
"""DEPRECATED Update host settings."""
if args.status == 'enable':
emit_hosts_deprecation_warning('host-update', 'service-enable')
elif args.status == 'disable':
emit_hosts_deprecation_warning('host-update', 'service-disable')
else:
emit_hosts_deprecation_warning('host-update')
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):
"""DEPRECATED Perform a power action on a host."""
emit_hosts_deprecation_warning('host-action')
result = cs.hosts.host_action(args.host, args.action)
utils.print_list([result], ['HOST', 'power_action'])
def _find_hypervisor(cs, hypervisor):
"""Get a hypervisor by name or ID."""
return utils.find_resource(cs.hypervisors, hypervisor)

View File

@ -0,0 +1,13 @@
---
upgrade:
- |
The following CLIs and their backing API bindings were deprecated and
capped at microversion 2.43:
* ``nova host-describe`` - superseded by ``nova hypervisor-show``
* ``nova host-list`` - superseded by ``nova hypervisor-list``
* ``nova host-update`` - superseded by ``nova service-enable`` and
``nova service-disable``
* ``nova host-action`` - no alternative by design
The CLIs and API bindings have now been removed.