Require nova_client.api_version >= 2.56
The [nova_client]/api_version defaults to 2.56 since change Idd6ebc94f81ad5d65256c80885f2addc1aaeaae1. There is compatibility code for that change but if 2.56 is not available watcher_non_live_migrate_instance will still fail if a destination host is used. Since 2.56 has been available since the Queens version of nova it should be reasonable to require at least that version of nova is running for using Watcher. This adds code which enforces the minimum version along with a release note and "watcher-status upgrade check" check method. Note that it's kind of weird for watcher to have a config option like nova_client.api_version since compute API microversions are per API request even though novaclient is constructed with the single configured version. It should really be something the client (watcher in this case) determines using version discovery and gracefully enables features if the required nova API version is available, but that's a bigger change. Change-Id: Id34938c7bb8a5ca934d997e52cac3b365414c006
This commit is contained in:
parent
1e6ce53273
commit
7489126d83
@ -81,3 +81,7 @@ Upgrade
|
||||
**2.0.0 (Stein)**
|
||||
|
||||
* Sample check to be filled in with checks as they are added in Stein.
|
||||
|
||||
**3.0.0 (Train)**
|
||||
|
||||
* A check was added to enforce the minimum required version of nova API used.
|
||||
|
@ -0,0 +1,8 @@
|
||||
---
|
||||
upgrade:
|
||||
- |
|
||||
The minimum required version of the ``[nova_client]/api_version`` value
|
||||
is now enforced to be ``2.56`` which is available since the Queens version
|
||||
of the nova compute service.
|
||||
|
||||
A ``watcher-status upgrade check`` has been added for this.
|
@ -15,8 +15,10 @@
|
||||
import sys
|
||||
|
||||
from oslo_upgradecheck import upgradecheck
|
||||
import six
|
||||
|
||||
from watcher._i18n import _
|
||||
from watcher.common import clients
|
||||
from watcher import conf
|
||||
|
||||
CONF = conf.CONF
|
||||
@ -30,17 +32,18 @@ class Checks(upgradecheck.UpgradeCommands):
|
||||
and added to _upgrade_checks tuple.
|
||||
"""
|
||||
|
||||
def _sample_check(self):
|
||||
"""This is sample check added to test the upgrade check framework
|
||||
|
||||
It needs to be removed after adding any real upgrade check
|
||||
"""
|
||||
return upgradecheck.Result(upgradecheck.Code.SUCCESS, 'Sample detail')
|
||||
def _minimum_nova_api_version(self):
|
||||
"""Checks the minimum required version of nova_client.api_version"""
|
||||
try:
|
||||
clients.check_min_nova_api_version(CONF.nova_client.api_version)
|
||||
except ValueError as e:
|
||||
return upgradecheck.Result(
|
||||
upgradecheck.Code.FAILURE, six.text_type(e))
|
||||
return upgradecheck.Result(upgradecheck.Code.SUCCESS)
|
||||
|
||||
_upgrade_checks = (
|
||||
# Sample check added for now.
|
||||
# Whereas in future real checks must be added here in tuple
|
||||
(_('Sample Check'), _sample_check),
|
||||
# Added in Train.
|
||||
(_('Minimum Nova API Version'), _minimum_nova_api_version),
|
||||
)
|
||||
|
||||
|
||||
|
@ -20,6 +20,7 @@ from keystoneauth1 import loading as ka_loading
|
||||
from keystoneclient import client as keyclient
|
||||
from monascaclient import client as monclient
|
||||
from neutronclient.neutron import client as netclient
|
||||
from novaclient import api_versions as nova_api_versions
|
||||
from novaclient import client as nvclient
|
||||
|
||||
from watcher.common import exception
|
||||
@ -34,6 +35,26 @@ CONF = cfg.CONF
|
||||
|
||||
_CLIENTS_AUTH_GROUP = 'watcher_clients_auth'
|
||||
|
||||
# NOTE(mriedem): This is the minimum required version of the nova API for
|
||||
# watcher features to work. If new features are added which require new
|
||||
# versions, they should perform version discovery and be backward compatible
|
||||
# for at least one release before raising the minimum required version.
|
||||
MIN_NOVA_API_VERSION = '2.56'
|
||||
|
||||
|
||||
def check_min_nova_api_version(config_version):
|
||||
"""Validates the minimum required nova API version.
|
||||
|
||||
:param config_version: The configured [nova_client]/api_version value
|
||||
:raises: ValueError if the configured version is less than the required
|
||||
minimum
|
||||
"""
|
||||
min_required = nova_api_versions.APIVersion(MIN_NOVA_API_VERSION)
|
||||
if nova_api_versions.APIVersion(config_version) < min_required:
|
||||
raise ValueError('Invalid nova_client.api_version %s. %s or '
|
||||
'greater is required.' % (config_version,
|
||||
MIN_NOVA_API_VERSION))
|
||||
|
||||
|
||||
class OpenStackClients(object):
|
||||
"""Convenience class to create and cache client instances."""
|
||||
@ -87,6 +108,9 @@ class OpenStackClients(object):
|
||||
return self._nova
|
||||
|
||||
novaclient_version = self._get_client_option('nova', 'api_version')
|
||||
|
||||
check_min_nova_api_version(novaclient_version)
|
||||
|
||||
nova_endpoint_type = self._get_client_option('nova', 'endpoint_type')
|
||||
nova_region_name = self._get_client_option('nova', 'region_name')
|
||||
self._nova = nvclient.Client(novaclient_version,
|
||||
|
@ -18,13 +18,24 @@
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from watcher.common import clients
|
||||
|
||||
nova_client = cfg.OptGroup(name='nova_client',
|
||||
title='Configuration Options for Nova')
|
||||
|
||||
NOVA_CLIENT_OPTS = [
|
||||
cfg.StrOpt('api_version',
|
||||
default='2.56',
|
||||
help='Version of Nova API to use in novaclient.'),
|
||||
help="""
|
||||
Version of Nova API to use in novaclient.
|
||||
|
||||
Minimum required version: %s
|
||||
|
||||
Certain Watcher features depend on a minimum version of the compute
|
||||
API being available which is enforced with this option. See
|
||||
https://docs.openstack.org/nova/latest/reference/api-microversion-history.html
|
||||
for the compute API microversion history.
|
||||
""" % clients.MIN_NOVA_API_VERSION),
|
||||
cfg.StrOpt('endpoint_type',
|
||||
default='publicURL',
|
||||
help='Type of endpoint to use in novaclient. '
|
||||
|
@ -15,8 +15,11 @@
|
||||
from oslo_upgradecheck.upgradecheck import Code
|
||||
|
||||
from watcher.cmd import status
|
||||
from watcher import conf
|
||||
from watcher.tests import base
|
||||
|
||||
CONF = conf.CONF
|
||||
|
||||
|
||||
class TestUpgradeChecks(base.TestCase):
|
||||
|
||||
@ -24,7 +27,16 @@ class TestUpgradeChecks(base.TestCase):
|
||||
super(TestUpgradeChecks, self).setUp()
|
||||
self.cmd = status.Checks()
|
||||
|
||||
def test__sample_check(self):
|
||||
check_result = self.cmd._sample_check()
|
||||
self.assertEqual(
|
||||
Code.SUCCESS, check_result.code)
|
||||
def test_minimum_nova_api_version_ok(self):
|
||||
# Tests that the default [nova_client]/api_version meets the minimum
|
||||
# required version.
|
||||
result = self.cmd._minimum_nova_api_version()
|
||||
self.assertEqual(Code.SUCCESS, result.code)
|
||||
|
||||
def test_minimum_nova_api_version_fail(self):
|
||||
# Tests the scenario that [nova_client]/api_version is less than the
|
||||
# minimum required version.
|
||||
CONF.set_override('api_version', '2.47', group='nova_client')
|
||||
result = self.cmd._minimum_nova_api_version()
|
||||
self.assertEqual(Code.FAILURE, result.code)
|
||||
self.assertIn('Invalid nova_client.api_version 2.47.', result.details)
|
||||
|
@ -26,6 +26,7 @@ from monascaclient.v2_0 import client as monclient_v2
|
||||
from neutronclient.neutron import client as netclient
|
||||
from neutronclient.v2_0 import client as netclient_v2
|
||||
from novaclient import client as nvclient
|
||||
import six
|
||||
|
||||
from watcher.common import clients
|
||||
from watcher import conf
|
||||
@ -125,11 +126,20 @@ class TestClients(base.TestCase):
|
||||
|
||||
@mock.patch.object(clients.OpenStackClients, 'session')
|
||||
def test_clients_nova_diff_vers(self, mock_session):
|
||||
CONF.set_override('api_version', '2.3', group='nova_client')
|
||||
CONF.set_override('api_version', '2.60', group='nova_client')
|
||||
osc = clients.OpenStackClients()
|
||||
osc._nova = None
|
||||
osc.nova()
|
||||
self.assertEqual('2.3', osc.nova().api_version.get_string())
|
||||
self.assertEqual('2.60', osc.nova().api_version.get_string())
|
||||
|
||||
@mock.patch.object(clients.OpenStackClients, 'session')
|
||||
def test_clients_nova_bad_min_version(self, mock_session):
|
||||
CONF.set_override('api_version', '2.47', group='nova_client')
|
||||
osc = clients.OpenStackClients()
|
||||
osc._nova = None
|
||||
ex = self.assertRaises(ValueError, osc.nova)
|
||||
self.assertIn('Invalid nova_client.api_version 2.47',
|
||||
six.text_type(ex))
|
||||
|
||||
@mock.patch.object(clients.OpenStackClients, 'session')
|
||||
def test_clients_nova_diff_endpoint(self, mock_session):
|
||||
|
Loading…
Reference in New Issue
Block a user