2.43: Deprecate novaclient /os-hosts usage
os-hosts is deprecated in the compute REST API with microversion 2.43 via change: Ieb85653b85a1eff38a9fb0c9ff05e4cd39150ecc So nova shell and API bindings should be deprecated as well. Implements blueprint deprecate-os-hosts Change-Id: I79091edf5a2569e49e79deba312456fdcdee09e1
This commit is contained in:
parent
ff1eff18d9
commit
ea3b9f7fef
@ -25,4 +25,4 @@ API_MIN_VERSION = api_versions.APIVersion("2.1")
|
||||
# when client supported the max version, and bumped sequentially, otherwise
|
||||
# the client may break due to server side new version may include some
|
||||
# backward incompatible change.
|
||||
API_MAX_VERSION = api_versions.APIVersion("2.42")
|
||||
API_MAX_VERSION = api_versions.APIVersion("2.43")
|
||||
|
@ -11,6 +11,10 @@
|
||||
# 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
|
||||
@ -23,8 +27,14 @@ 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:
|
||||
@ -32,6 +42,7 @@ class HostsTest(utils.FixturedTestCase):
|
||||
|
||||
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:
|
||||
@ -50,6 +61,8 @@ class HostsTest(utils.FixturedTestCase):
|
||||
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)
|
||||
@ -74,6 +87,8 @@ class HostsTest(utils.FixturedTestCase):
|
||||
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')
|
||||
@ -81,6 +96,8 @@ class HostsTest(utils.FixturedTestCase):
|
||||
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')
|
||||
@ -88,6 +105,8 @@ class HostsTest(utils.FixturedTestCase):
|
||||
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')
|
||||
@ -100,3 +119,30 @@ class HostsTest(utils.FixturedTestCase):
|
||||
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')
|
||||
|
@ -2171,7 +2171,11 @@ class ShellTest(utils.TestCase):
|
||||
self.assert_called('DELETE', '/os-services/1')
|
||||
|
||||
def test_host_list(self):
|
||||
self.run_command('host-list')
|
||||
_, 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):
|
||||
@ -2179,23 +2183,40 @@ class ShellTest(utils.TestCase):
|
||||
self.assert_called('GET', '/os-hosts?zone=nova')
|
||||
|
||||
def test_host_update_status(self):
|
||||
self.run_command('host-update sample-host_1 --status enabled')
|
||||
body = {'status': 'enabled'}
|
||||
_, 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):
|
||||
self.run_command('host-update sample-host_2 --maintenance enable')
|
||||
_, 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):
|
||||
self.run_command('host-update sample-host_3 '
|
||||
'--status disabled --maintenance enable')
|
||||
body = {'status': 'disabled', 'maintenance_mode': 'enable'}
|
||||
_, 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):
|
||||
self.run_command('host-action sample-host --action startup')
|
||||
_, 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')
|
||||
|
||||
@ -2881,6 +2902,7 @@ class ShellTest(utils.TestCase):
|
||||
39, # There are no versioned wrapped shell method changes for this
|
||||
41, # There are no version-wrapped shell method changes for this.
|
||||
42, # There are no version-wrapped shell method changes for this.
|
||||
43, # There are no version-wrapped shell method changes for this.
|
||||
])
|
||||
versions_supported = set(range(0,
|
||||
novaclient.API_MAX_VERSION.ver_minor + 1))
|
||||
|
@ -14,12 +14,23 @@
|
||||
# under the License.
|
||||
|
||||
"""
|
||||
host interface (1.1 extension).
|
||||
DEPRECATED host interface (1.1 extension).
|
||||
"""
|
||||
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
|
||||
|
||||
@ -28,15 +39,19 @@ class Host(base.Resource):
|
||||
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')
|
||||
|
||||
@ -56,31 +71,39 @@ class Host(base.Resource):
|
||||
class HostManager(base.ManagerWithFind):
|
||||
resource_class = Host
|
||||
|
||||
@api_versions.wraps("2.0", "2.42")
|
||||
def get(self, host):
|
||||
"""
|
||||
Describes cpu/memory/hdd info for 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):
|
||||
"""Update status or maintenance mode for the host."""
|
||||
"""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):
|
||||
"""
|
||||
Perform an action on a host.
|
||||
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
|
||||
|
@ -55,6 +55,26 @@ CERT_DEPRECATION_WARNING = (
|
||||
)
|
||||
|
||||
|
||||
# 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)
|
||||
|
||||
|
||||
CLIENT_BDM2_KEYS = {
|
||||
'id': 'uuid',
|
||||
'source': 'source_type',
|
||||
@ -3386,7 +3406,9 @@ def do_service_delete(cs, args):
|
||||
|
||||
@utils.arg('host', metavar='<hostname>', help=_('Name of host.'))
|
||||
def do_host_describe(cs, args):
|
||||
"""Describe a specific host."""
|
||||
"""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)
|
||||
@ -3399,7 +3421,9 @@ def do_host_describe(cs, args):
|
||||
help=_('Filters the list, returning only those hosts in the availability '
|
||||
'zone <zone>.'))
|
||||
def do_host_list(cs, args):
|
||||
"""List all hosts by service."""
|
||||
"""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)
|
||||
@ -3416,7 +3440,14 @@ def do_host_list(cs, args):
|
||||
dest='maintenance',
|
||||
help=_('Either put or resume host to/from maintenance.'))
|
||||
def do_host_update(cs, args):
|
||||
"""Update host settings."""
|
||||
"""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:
|
||||
@ -3435,7 +3466,9 @@ def do_host_update(cs, args):
|
||||
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."""
|
||||
"""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'])
|
||||
|
||||
|
14
releasenotes/notes/microversion-v2_43-76db2ac463b431e4.yaml
Normal file
14
releasenotes/notes/microversion-v2_43-76db2ac463b431e4.yaml
Normal file
@ -0,0 +1,14 @@
|
||||
---
|
||||
deprecations:
|
||||
- |
|
||||
The following CLIs and their backing API bindings are 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 will be removed in the first major release after
|
||||
Nova 16.0.0 Pike is released.
|
Loading…
Reference in New Issue
Block a user