Merge pull request #97 from n-pochet/feature/add-openstack-utilities

Add a way to compare OS release pair
This commit is contained in:
Liam Young
2018-08-09 09:36:29 +01:00
committed by GitHub
7 changed files with 193 additions and 0 deletions

1
.gitignore vendored
View File

@@ -5,5 +5,6 @@ dist/
.local
zaza.egg-info/
.coverage
.vscode/
# Sphinx
doc/build

View File

@@ -227,3 +227,18 @@ class TestJujuUtils(ut_utils.BaseTestCase):
self.model.run_on_leader.assert_called_with(
'application', 'leader-get --format=yaml ')
self.assertFalse(self.yaml.load.called)
def test_get_machine_series(self):
self.patch(
'zaza.utilities.juju.get_machine_status',
new_callable=mock.MagicMock(),
name='_get_machine_status'
)
self._get_machine_status.return_value = 'xenial'
expected = 'xenial'
actual = juju_utils.get_machine_series('6')
self._get_machine_status.assert_called_with(
machine='6',
key='series'
)
self.assertEqual(expected, actual)

View File

@@ -645,3 +645,78 @@ class TestOpenStackUtils(ut_utils.BaseTestCase):
with self.assertRaises(exceptions.NeutronBGPSpeakerMissing):
openstack_utils.neutron_bgp_speaker_appears_on_agent(
_neutronclient, 'FAKE_AGENT_ID')
def test_get_current_openstack_release_pair(self):
self.patch(
'zaza.utilities.openstack.get_current_os_versions',
new_callable=mock.MagicMock(),
name='_get_os_version'
)
self.patch(
'zaza.utilities.juju.get_machines_for_application',
new_callable=mock.MagicMock(),
name='_get_machines'
)
self.patch(
'zaza.utilities.juju.get_machine_series',
new_callable=mock.MagicMock(),
name='_get_machine_series'
)
# No machine returned
self._get_machines.return_value = []
with self.assertRaises(exceptions.ApplicationNotFound):
openstack_utils.get_current_os_release_pair()
# No series returned
self._get_machines.return_value = ['6']
self._get_machine_series.return_value = None
with self.assertRaises(exceptions.SeriesNotFound):
openstack_utils.get_current_os_release_pair()
# No OS Version returned
self._get_machine_series.return_value = 'xenial'
self._get_os_version.return_value = {}
with self.assertRaises(exceptions.OSVersionNotFound):
openstack_utils.get_current_os_release_pair()
# Normal scenario, argument passed
self._get_os_version.return_value = {'keystone': 'mitaka'}
expected = 'xenial_mitaka'
result = openstack_utils.get_current_os_release_pair('keystone')
self.assertEqual(expected, result)
# Normal scenario, default value used
self._get_os_version.return_value = {'keystone': 'mitaka'}
expected = 'xenial_mitaka'
result = openstack_utils.get_current_os_release_pair()
self.assertEqual(expected, result)
def test_get_openstack_release(self):
self.patch(
'zaza.utilities.openstack.get_current_os_release_pair',
new_callable=mock.MagicMock(),
name='_get_os_rel_pair'
)
# Bad release pair
release_pair = 'bad'
with self.assertRaises(exceptions.ReleasePairNotFound):
openstack_utils.get_os_release(release_pair)
# Normal scenario
expected = 4
result = openstack_utils.get_os_release('xenial_mitaka')
self.assertEqual(expected, result)
# Normal scenario with current release pair
self._get_os_rel_pair.return_value = 'xenial_mitaka'
expected = 4
result = openstack_utils.get_os_release()
self.assertEqual(expected, result)
# We can compare releases xenial_queens > xenial_mitaka
xenial_queens = openstack_utils.get_os_release('xenial_queens')
xenial_mitaka = openstack_utils.get_os_release('xenial_mitaka')
release_comp = xenial_queens > xenial_mitaka
self.assertTrue(release_comp)

View File

@@ -29,3 +29,36 @@ class NeutronBGPSpeakerMissing(Exception):
"""No BGP speaker appeared on agent."""
pass
class ApplicationNotFound(Exception):
"""Application not found in machines."""
def __init__(self, application):
"""Create Application not found exception.
:param application: Name of the application
:type application: string
:returns: ApplicationNotFound Exception
"""
msg = ("{} application was not found in machines.".
format(application))
super(ApplicationNotFound, self).__init__(msg)
class SeriesNotFound(Exception):
"""Series not found in status."""
pass
class OSVersionNotFound(Exception):
"""OS Version not found."""
pass
class ReleasePairNotFound(Exception):
"""Release pair was not found in OPENSTACK_RELEASES_PAIRS."""
pass

View File

@@ -115,6 +115,20 @@ def get_machine_status(machine, key=None):
return status
def get_machine_series(machine):
"""Return the juju series for a machine.
:param machine: Machine number
:type machine: string
:returns: Juju series
:rtype: string
"""
return get_machine_status(
machine=machine,
key='series'
)
def get_machine_uuids_for_application(application):
"""Return machine uuids for a given application.

View File

@@ -6,6 +6,7 @@ from .os_versions import (
OPENSTACK_CODENAMES,
SWIFT_CODENAMES,
PACKAGE_CODENAMES,
OPENSTACK_RELEASES_PAIRS,
)
from glanceclient import Client as GlanceClient
@@ -1123,6 +1124,54 @@ def get_application_config_keys(application):
return list(application_config.keys())
def get_current_os_release_pair(application='keystone'):
"""Return OpenStack Release pair name.
:param application: Name of application
:type application: string
:returns: Name of the OpenStack release pair
:rtype: str
:raises: exceptions.ApplicationNotFound
:raises: exceptions.SeriesNotFound
:raises: exceptions.OSVersionNotFound
"""
machines = juju_utils.get_machines_for_application(application)
if len(machines) >= 1:
machine = machines[0]
else:
raise exceptions.ApplicationNotFound(application)
series = juju_utils.get_machine_series(machine)
if not series:
raise exceptions.SeriesNotFound()
os_version = get_current_os_versions([application]).get(application)
if not os_version:
raise exceptions.OSVersionNotFound()
return '{}_{}'.format(series, os_version)
def get_os_release(release_pair=None):
"""Return index of release in OPENSTACK_RELEASES_PAIRS.
:returns: Index of the release
:rtype: int
:raises: exceptions.ReleasePairNotFound
"""
if release_pair is None:
release_pair = get_current_os_release_pair()
try:
index = OPENSTACK_RELEASES_PAIRS.index(release_pair)
except ValueError:
msg = 'Release pair: {} not found in {}'.format(
release_pair,
OPENSTACK_RELEASES_PAIRS
)
raise exceptions.ReleasePairNotFound(msg)
return index
def get_application_config_option(application, option):
"""Return application configuration.

View File

@@ -37,6 +37,12 @@ OPENSTACK_CODENAMES = OrderedDict([
('2018.1', 'queens'),
])
OPENSTACK_RELEASES_PAIRS = [
'trusty_icehouse', 'trusty_kilo', 'trusty_liberty',
'trusty_mitaka', 'xenial_mitaka', 'xenial_newton',
'yakkety_newton', 'xenial_ocata', 'zesty_ocata',
'xenial_pike', 'artful_pike', 'xenial_queens',
'bionic_queens', 'bionic_rocky', 'cosmic_rocky']
# The ugly duckling - must list releases oldest to newest
SWIFT_CODENAMES = OrderedDict([