Move the gathering of flavors into the CollectFlavors action
The imported actions from Mistral (namely, the nova.flavors_list) will return dictionaries. The nova api returns a Flavor, which has additional methods (get_keys) that have further properties that are not returned in the main api call. This works around that. Change-Id: I3ac99bc5abbae62bfc4352db708e25f5fa551095 Closes-Bug: #1685177
This commit is contained in:
parent
86c9c8d104
commit
6d487c39fd
@ -185,9 +185,8 @@ class CheckFlavorsAction(base.TripleOAction):
|
||||
|
||||
# TODO(bcrochet): The validation actions are temporary. This logic should
|
||||
# move to the tripleo-validations project eventually.
|
||||
def __init__(self, flavors, roles_info):
|
||||
def __init__(self, roles_info):
|
||||
super(CheckFlavorsAction, self).__init__()
|
||||
self.flavors = flavors
|
||||
self.roles_info = roles_info
|
||||
|
||||
def run(self):
|
||||
@ -198,12 +197,21 @@ class CheckFlavorsAction(base.TripleOAction):
|
||||
|
||||
:returns: dictionary flavor name -> (flavor object, scale)
|
||||
"""
|
||||
flavors = {f['name']: f for f in self.flavors}
|
||||
compute_client = self.get_compute_client()
|
||||
flavors = {f.name: {'name': f.name, 'keys': f.get_keys()}
|
||||
for f in compute_client.flavors.list()}
|
||||
|
||||
result = {}
|
||||
warnings = []
|
||||
errors = []
|
||||
|
||||
message = "Flavor '{1}' provided for the role '{0}', does not exist"
|
||||
warning_message = (
|
||||
'Flavor {0} "capabilities:boot_option" is set to '
|
||||
'"netboot". Nodes will PXE boot from the ironic '
|
||||
'conductor instead of using a local bootloader. '
|
||||
'Make sure that enough nodes are marked with the '
|
||||
'"boot_option" capability set to "netboot".')
|
||||
|
||||
for target, (flavor_name, scale) in self.roles_info.items():
|
||||
if flavor_name is None or not scale:
|
||||
@ -217,14 +225,12 @@ class CheckFlavorsAction(base.TripleOAction):
|
||||
flavor = flavors.get(flavor_name)
|
||||
|
||||
if flavor:
|
||||
if flavor.get('capabilities:boot_option', '') == 'netboot':
|
||||
warnings.append(
|
||||
'Flavor %s "capabilities:boot_option" is set to '
|
||||
'"netboot". Nodes will PXE boot from the ironic '
|
||||
'conductor instead of using a local bootloader. '
|
||||
'Make sure that enough nodes are marked with the '
|
||||
'"boot_option" capability set to "netboot".'
|
||||
% flavor_name)
|
||||
keys = flavor.get('keys', None)
|
||||
if keys:
|
||||
if keys.get('capabilities:boot_option', '') \
|
||||
== 'netboot':
|
||||
warnings.append(
|
||||
warning_message.format(flavor_name))
|
||||
|
||||
result[flavor_name] = (flavor, scale)
|
||||
else:
|
||||
@ -322,7 +328,10 @@ class VerifyProfilesAction(base.TripleOAction):
|
||||
if not scale:
|
||||
continue
|
||||
|
||||
profile = flavor.get('capabilities:profile')
|
||||
profile = None
|
||||
keys = flavor.get('keys')
|
||||
if keys:
|
||||
profile = keys.get('capabilities:profile')
|
||||
|
||||
if not profile and len(self.flavors) > 1:
|
||||
message = ('Error: The {flavor} flavor has no profile '
|
||||
|
@ -287,14 +287,39 @@ class TestCheckBootImagesAction(base.TestCase):
|
||||
self.assertIn(expected_message, messages)
|
||||
|
||||
|
||||
class FakeFlavor(object):
|
||||
name = ''
|
||||
uuid = ''
|
||||
|
||||
def __init__(self, name, keys={'capabilities:boot_option': 'local'}):
|
||||
self.uuid = uuid4()
|
||||
self.name = name
|
||||
self.keys = keys
|
||||
|
||||
def get_keys(self):
|
||||
return self.keys
|
||||
|
||||
|
||||
class TestCheckFlavorsAction(base.TestCase):
|
||||
def setUp(self):
|
||||
super(TestCheckFlavorsAction, self).setUp()
|
||||
self.flavors = [
|
||||
{'name': 'flavor1', 'capabilities:boot_option': 'local'},
|
||||
{'name': 'flavor2', 'capabilities:boot_option': 'netboot'},
|
||||
{'name': 'flavor3'}
|
||||
self.compute = mock.MagicMock()
|
||||
compute_patcher = mock.patch(
|
||||
'tripleo_common.actions.base.TripleOAction.get_compute_client',
|
||||
return_value=self.compute)
|
||||
self.mock_compute = compute_patcher.start()
|
||||
self.addCleanup(compute_patcher.stop)
|
||||
|
||||
self.mock_flavors = mock.Mock()
|
||||
self.compute.attach_mock(self.mock_flavors, 'flavors')
|
||||
self.mock_flavor_list = [
|
||||
FakeFlavor('flavor1'),
|
||||
FakeFlavor('flavor2',
|
||||
keys={'capabilities:boot_option': 'netboot'}),
|
||||
FakeFlavor('flavor3', None)
|
||||
]
|
||||
self.mock_flavors.attach_mock(
|
||||
mock.Mock(return_value=self.mock_flavor_list), 'list')
|
||||
|
||||
def test_run_success(self):
|
||||
roles_info = {
|
||||
@ -307,7 +332,7 @@ class TestCheckFlavorsAction(base.TestCase):
|
||||
'flavor1': (
|
||||
{
|
||||
'name': 'flavor1',
|
||||
'capabilities:boot_option': 'local'
|
||||
'keys': {'capabilities:boot_option': 'local'}
|
||||
}, 1)
|
||||
},
|
||||
'warnings': [],
|
||||
@ -316,7 +341,6 @@ class TestCheckFlavorsAction(base.TestCase):
|
||||
)
|
||||
|
||||
action_args = {
|
||||
'flavors': self.flavors,
|
||||
'roles_info': roles_info
|
||||
}
|
||||
action = validations.CheckFlavorsAction(**action_args)
|
||||
@ -334,11 +358,12 @@ class TestCheckFlavorsAction(base.TestCase):
|
||||
'flavor2': (
|
||||
{
|
||||
'name': 'flavor2',
|
||||
'capabilities:boot_option': 'netboot'
|
||||
'keys': {'capabilities:boot_option': 'netboot'}
|
||||
}, 1),
|
||||
'flavor3': (
|
||||
{
|
||||
'name': 'flavor3',
|
||||
'keys': None
|
||||
}, 1),
|
||||
},
|
||||
'warnings': [
|
||||
@ -353,7 +378,6 @@ class TestCheckFlavorsAction(base.TestCase):
|
||||
)
|
||||
|
||||
action_args = {
|
||||
'flavors': self.flavors,
|
||||
'roles_info': roles_info
|
||||
}
|
||||
action = validations.CheckFlavorsAction(**action_args)
|
||||
@ -377,7 +401,6 @@ class TestCheckFlavorsAction(base.TestCase):
|
||||
)
|
||||
|
||||
action_args = {
|
||||
'flavors': self.flavors,
|
||||
'roles_info': roles_info
|
||||
}
|
||||
action = validations.CheckFlavorsAction(**action_args)
|
||||
@ -485,8 +508,10 @@ class TestVerifyProfilesAction(base.TestCase):
|
||||
return {
|
||||
'name': name,
|
||||
'profile': the_profile,
|
||||
'capabilities:boot_option': 'local',
|
||||
'capabilities:profile': the_profile
|
||||
'keys': {
|
||||
'capabilities:boot_option': 'local',
|
||||
'capabilities:profile': the_profile
|
||||
}
|
||||
}
|
||||
|
||||
def _test(self, expected_result):
|
||||
|
@ -330,19 +330,12 @@ workflows:
|
||||
tasks:
|
||||
check_run_validations:
|
||||
on-complete:
|
||||
- get_flavors: <% $.run_validations %>
|
||||
- check_flavors: <% $.run_validations %>
|
||||
- send_message: <% not $.run_validations %>
|
||||
|
||||
get_flavors:
|
||||
action: nova.flavors_list
|
||||
on-success: check_flavors
|
||||
publish:
|
||||
nova_flavors: <% task(get_flavors).result %>
|
||||
|
||||
check_flavors:
|
||||
action: tripleo.validations.check_flavors
|
||||
input:
|
||||
flavors: <% $.nova_flavors %>
|
||||
roles_info: <% $.roles_info %>
|
||||
on-success: send_message
|
||||
on-error: fail_check_flavors
|
||||
|
Loading…
x
Reference in New Issue
Block a user