Create stack in right order
-we need to first create Stack, if that doesn't throw exception, we create Overcloud. This is a sanity fix, since we are not implementing the workflows in I. -correct stack_id is being passed to Overcloud, before it was just blank Change-Id: If7364e5b35b7343a8b5d0f0278d79f500239ca40
This commit is contained in:
parent
aa0e4ea3c7
commit
9f75bc9c70
@ -30,7 +30,7 @@ LOG = logging.getLogger(__name__)
|
||||
POC_PARAMS = {'controller': 1, 'compute': 2}
|
||||
|
||||
|
||||
def parse_counts(counts):
|
||||
def parse_counts(counts, overcloud_roles):
|
||||
"""Helper for parsing the OvercloudRoleCount object
|
||||
|
||||
Given a list of OvercloudRoleCount objects return a dict of
|
||||
@ -39,12 +39,16 @@ def parse_counts(counts):
|
||||
:param counts: List of tuskar.api.controllers.v1.models.OvercloudRoleCount
|
||||
:type counts: list
|
||||
|
||||
:param overcloud_roles: Dict of (overcloud_role_id, overcloud_role) so
|
||||
we can access image_name and flavor_id of roles
|
||||
:type overcloud_roles: dict
|
||||
|
||||
:return: Dict of (image_name, count)
|
||||
:rtype: dict
|
||||
"""
|
||||
parsed_counts = {}
|
||||
for count_obj in counts:
|
||||
image_name = count_obj.overcloud_role.image_name
|
||||
image_name = overcloud_roles[count_obj.overcloud_role_id].image_name
|
||||
count = count_obj.num_nodes
|
||||
parsed_counts[image_name] = count
|
||||
|
||||
@ -76,7 +80,13 @@ def filter_template_attributes(allowed_data, attributes):
|
||||
return filtered_data
|
||||
|
||||
|
||||
def process_stack(attributes, counts, create=False):
|
||||
def get_overcloud_roles_dict():
|
||||
return dict((overcloud_role.id, overcloud_role)
|
||||
for overcloud_role in
|
||||
pecan.request.dbapi.get_overcloud_roles())
|
||||
|
||||
|
||||
def process_stack(attributes, counts, overcloud_roles, create=False):
|
||||
"""Helper function for processing the stack.
|
||||
|
||||
Given a params dict containing the Overcloud Roles and initialization
|
||||
@ -89,11 +99,16 @@ def process_stack(attributes, counts, create=False):
|
||||
:param counts: Dictionary of counts of roles to be deployed
|
||||
:type counts: dict
|
||||
|
||||
:param overcloud_roles: Dict of (overcloud_role_id, overcloud_role) so
|
||||
we can access image_name and flavor_id of roles
|
||||
:type overcloud_roles: dict
|
||||
|
||||
:param create: A flag to designate if we are creating or updating the stack
|
||||
:type create: bool
|
||||
"""
|
||||
try:
|
||||
overcloud = template_tools.merge_templates(parse_counts(counts))
|
||||
overcloud = template_tools.merge_templates(
|
||||
parse_counts(counts, overcloud_roles))
|
||||
except Exception as e:
|
||||
raise exception.HeatTemplateCreateFailed(six.text_type(e))
|
||||
|
||||
@ -117,14 +132,17 @@ def process_stack(attributes, counts, create=False):
|
||||
operation = heat_client.update_stack
|
||||
|
||||
try:
|
||||
operation(overcloud,
|
||||
filter_template_attributes(allowed_data, attributes))
|
||||
result = operation(
|
||||
overcloud,
|
||||
filter_template_attributes(allowed_data, attributes))
|
||||
except Exception as e:
|
||||
if create:
|
||||
raise exception.HeatStackCreateFailed(six.text_type(e))
|
||||
else:
|
||||
raise exception.HeatStackUpdateFailed(six.text_type(e))
|
||||
|
||||
return result
|
||||
|
||||
|
||||
class OvercloudsController(rest.RestController):
|
||||
"""REST controller for the Overcloud class."""
|
||||
@ -156,7 +174,19 @@ class OvercloudsController(rest.RestController):
|
||||
"""
|
||||
LOG.debug('Creating overcloud: %s' % transfer_overcloud)
|
||||
|
||||
# FIXME(lsmola) This is just POC of creating a stack
|
||||
# this has to be done properly with proper Work-flow abstraction of:
|
||||
# step 1- build template and start stack-create
|
||||
# step 2- put the right stack_id to the overcloud
|
||||
# step 3- initialize the stack
|
||||
# step 4- set the correct overcloud status
|
||||
stack = process_stack(transfer_overcloud.attributes,
|
||||
transfer_overcloud.counts,
|
||||
get_overcloud_roles_dict(),
|
||||
create=True)
|
||||
|
||||
# Persist to the database
|
||||
transfer_overcloud.stack_id = stack['stack']['id']
|
||||
db_overcloud = transfer_overcloud.to_db_model()
|
||||
result = pecan.request.dbapi.create_overcloud(db_overcloud)
|
||||
|
||||
@ -164,15 +194,6 @@ class OvercloudsController(rest.RestController):
|
||||
saved_overcloud =\
|
||||
models.Overcloud.from_db_model(result)
|
||||
|
||||
# FIXME(lsmola) This is just POC of creating a stack
|
||||
# this has to be done properly with proper Work-flow abstraction of:
|
||||
# step one- build template and start stack-create
|
||||
# step 2- put the right stack_id to the overcloud
|
||||
# step 3- initialize the stack
|
||||
# step 4- set the correct overcloud status
|
||||
process_stack(saved_overcloud.attributes, result.counts,
|
||||
create=True)
|
||||
|
||||
return saved_overcloud
|
||||
|
||||
@wsme.validate(models.Overcloud)
|
||||
@ -210,10 +231,11 @@ class OvercloudsController(rest.RestController):
|
||||
|
||||
# FIXME(lsmola) This is just POC of updating a stack
|
||||
# this probably should also have workflow
|
||||
# step one- build template and stack-update
|
||||
# step 1- build template and stack-update
|
||||
# step 2- set the correct overcloud status
|
||||
|
||||
process_stack(updated_overcloud.attributes, updated_overcloud.counts,
|
||||
create=True)
|
||||
get_overcloud_roles_dict(), create=True)
|
||||
|
||||
return updated_overcloud
|
||||
|
||||
@ -231,7 +253,7 @@ class OvercloudsController(rest.RestController):
|
||||
# FIXME(lsmola) this should always try to delete both overcloud
|
||||
# and stack. So it requires some exception catch over below.
|
||||
# FIXME(lsmola) there is also a workflow needed
|
||||
# step one- delete stack and set status deleting in progress to
|
||||
# step 1- delete stack and set status deleting in progress to
|
||||
# overcloud
|
||||
# step 2 - once stack is deleted, delete the overcloud
|
||||
LOG.debug('Deleting overcloud with ID: %s' % overcloud_id)
|
||||
|
@ -71,7 +71,7 @@ class OvercloudTests(base.TestCase):
|
||||
|
||||
mock_db_get.assert_called_once_with(12345)
|
||||
|
||||
def test_parse_counts(self):
|
||||
def test_parse_counts_overcloud_roles_explicit(self):
|
||||
# Setup
|
||||
overcloud_role_1 = db_models.OvercloudRole(
|
||||
image_name='overcloud-compute')
|
||||
@ -79,16 +79,19 @@ class OvercloudTests(base.TestCase):
|
||||
overcloud_role_2 = db_models.OvercloudRole(
|
||||
image_name='overcloud-block-storage')
|
||||
|
||||
mock_overcloud_roles = {1: overcloud_role_1, 2: overcloud_role_2}
|
||||
|
||||
overcloud_role_count_1 = db_models.OvercloudRoleCount(
|
||||
overcloud_role_id=2, num_nodes=5, overcloud_role=overcloud_role_1)
|
||||
overcloud_role_id=1, num_nodes=5)
|
||||
|
||||
overcloud_role_count_2 = db_models.OvercloudRoleCount(
|
||||
overcloud_role_id=2, num_nodes=9, overcloud_role=overcloud_role_2)
|
||||
overcloud_role_id=2, num_nodes=9)
|
||||
|
||||
mock_counts = [overcloud_role_count_1, overcloud_role_count_2]
|
||||
|
||||
# Test
|
||||
result = overcloud.parse_counts(mock_counts)
|
||||
result = overcloud.parse_counts(mock_counts,
|
||||
overcloud_roles=mock_overcloud_roles)
|
||||
|
||||
# Verify
|
||||
self.assertEqual(result, {'overcloud-compute': 5,
|
||||
@ -121,7 +124,7 @@ class OvercloudTests(base.TestCase):
|
||||
'tuskar.heat.client.HeatClient.__new__', return_value=mock.Mock(**{
|
||||
'validate_template.return_value': {},
|
||||
'exists_stack.return_value': False,
|
||||
'create_stack.return_value': True,
|
||||
'create_stack.return_value': {'stack': {'id': '1'}},
|
||||
})
|
||||
)
|
||||
def test_create_stack(self, mock_heat_client, mock_heat_merge_templates):
|
||||
@ -129,10 +132,10 @@ class OvercloudTests(base.TestCase):
|
||||
mock_heat_merge_templates.return_value = None
|
||||
|
||||
# Test
|
||||
response = overcloud.process_stack({}, {}, create=True)
|
||||
response = overcloud.process_stack({}, {}, {}, create=True)
|
||||
|
||||
# Verify
|
||||
self.assertEqual(response, None)
|
||||
self.assertEqual(response, {'stack': {'id': '1'}})
|
||||
|
||||
@mock.patch('tuskar.heat.template_tools.merge_templates')
|
||||
@mock.patch(
|
||||
@ -150,7 +153,7 @@ class OvercloudTests(base.TestCase):
|
||||
# Test and Verify
|
||||
self.assertRaises(
|
||||
exception.HeatStackCreateFailed,
|
||||
overcloud.process_stack, {}, {}, True)
|
||||
overcloud.process_stack, {}, {}, {}, create=True)
|
||||
|
||||
@mock.patch('tuskar.heat.template_tools.merge_templates')
|
||||
@mock.patch(
|
||||
@ -167,8 +170,8 @@ class OvercloudTests(base.TestCase):
|
||||
|
||||
# Test and Verify
|
||||
self.assertRaises(
|
||||
exception.StackAlreadyCreated, overcloud.process_stack, {}, {},
|
||||
True)
|
||||
exception.StackAlreadyCreated, overcloud.process_stack, {}, {}, {},
|
||||
create=True)
|
||||
|
||||
@mock.patch('tuskar.heat.template_tools.merge_templates')
|
||||
@mock.patch(
|
||||
@ -186,18 +189,22 @@ class OvercloudTests(base.TestCase):
|
||||
# Test and Verify
|
||||
self.assertRaises(
|
||||
exception.HeatTemplateValidateFailed, overcloud.process_stack,
|
||||
{}, {},
|
||||
True)
|
||||
{}, {}, {}, create=True)
|
||||
|
||||
@mock.patch('tuskar.db.sqlalchemy.api.Connection.get_overcloud_roles')
|
||||
@mock.patch('tuskar.api.controllers.v1.overcloud.process_stack')
|
||||
@mock.patch('tuskar.db.sqlalchemy.api.Connection.create_overcloud')
|
||||
def test_post(self, mock_db_create, mock_process_stack):
|
||||
def test_post(self, mock_db_create, mock_process_stack,
|
||||
mock_get_overcloud_roles):
|
||||
# Setup
|
||||
create_me = {'name': 'new'}
|
||||
|
||||
fake_created = db_models.Overcloud(name='created')
|
||||
mock_db_create.return_value = fake_created
|
||||
mock_process_stack.return_value = None
|
||||
mock_process_stack.return_value = {'stack': {'id': '1'}}
|
||||
mock_get_overcloud_roles.return_value = [
|
||||
mock.Mock(**{'id.return_value': 1, }),
|
||||
mock.Mock(**{'id.return_value': 2, })]
|
||||
|
||||
# Test
|
||||
response = self.app.post_json(URL_OVERCLOUDS, params=create_me)
|
||||
@ -218,7 +225,7 @@ class OvercloudTests(base.TestCase):
|
||||
'tuskar.heat.client.HeatClient.__new__', return_value=mock.Mock(**{
|
||||
'validate_template.return_value': {},
|
||||
'exists_stack.return_value': True,
|
||||
'create_stack.return_value': True,
|
||||
'update_stack.return_value': {'stack': {'id': '1'}},
|
||||
})
|
||||
)
|
||||
def test_update_stack(self, mock_heat_client, mock_heat_merge_templates):
|
||||
@ -226,10 +233,10 @@ class OvercloudTests(base.TestCase):
|
||||
mock_heat_merge_templates.return_value = None
|
||||
|
||||
# Test
|
||||
response = overcloud.process_stack({}, {})
|
||||
response = overcloud.process_stack({}, {}, {})
|
||||
|
||||
# Verify
|
||||
self.assertEqual(response, None)
|
||||
self.assertEqual(response, {'stack': {'id': '1'}})
|
||||
|
||||
@mock.patch('tuskar.heat.template_tools.merge_templates')
|
||||
@mock.patch(
|
||||
@ -247,7 +254,7 @@ class OvercloudTests(base.TestCase):
|
||||
# Test and Verify
|
||||
self.assertRaises(
|
||||
exception.HeatStackUpdateFailed, overcloud.process_stack, {},
|
||||
{})
|
||||
{}, {})
|
||||
|
||||
@mock.patch('tuskar.heat.template_tools.merge_templates')
|
||||
@mock.patch(
|
||||
@ -264,7 +271,7 @@ class OvercloudTests(base.TestCase):
|
||||
|
||||
# Test and Verify
|
||||
self.assertRaises(
|
||||
exception.StackNotFound, overcloud.process_stack, {}, {})
|
||||
exception.StackNotFound, overcloud.process_stack, {}, {}, {})
|
||||
|
||||
@mock.patch('tuskar.heat.template_tools.merge_templates')
|
||||
@mock.patch(
|
||||
@ -282,7 +289,7 @@ class OvercloudTests(base.TestCase):
|
||||
# Test and Verify
|
||||
self.assertRaises(
|
||||
exception.HeatTemplateValidateFailed, overcloud.process_stack,
|
||||
{}, {})
|
||||
{}, {}, {})
|
||||
|
||||
@mock.patch('tuskar.api.controllers.v1.overcloud.process_stack')
|
||||
@mock.patch('tuskar.db.sqlalchemy.api.Connection.update_overcloud')
|
||||
|
Loading…
x
Reference in New Issue
Block a user