Allow networks in roles_data to be dict or list

With the changes to make all networks for the overcloud
neutron routed networks it makes sense to change the
schema of 'networks' in roles_data to allow the user to
specify both the networks and the subnet of each network
for a role.

Ref change: I85676ae961d34bf6a986fa813c40380d50f09711

This changes the role yaml validation to allow 'networks'
to be either a list or a dict.

Related: blueprint tripleo-routed-networks-templates
Change-Id: I773a38fd903fe287132151a4d178326a46890969
This commit is contained in:
Harald Jensås
2018-08-23 11:43:47 +02:00
parent 85f1a1dab5
commit 6d52f5b9ac
2 changed files with 47 additions and 5 deletions

View File

@@ -34,6 +34,20 @@ SAMPLE_ROLE = """
ServicesDefault:
- OS::TripleO::Services::Ntp
"""
SAMPLE_ROLE_NETWORK_DICT = """
###############################################################################
# Role: sample #
###############################################################################
- name: sample
description: |
Sample!
networks:
InternalApi:
subnet: internal_api_subnet
HostnameFormatDefault: '%stackname%-sample-%index%'
ServicesDefault:
- OS::TripleO::Services::Ntp
"""
SAMPLE_GENERATED_ROLE = """
###############################################################################
# Role: sample #
@@ -54,6 +68,16 @@ SAMPLE_ROLE_OBJ = {
'name': 'sample',
'networks': ['InternalApi']
}
SAMPLE_ROLE_OBJ_NETWORK_DICT = {
'HostnameFormatDefault': '%stackname%-sample-%index%',
'ServicesDefault': ['OS::TripleO::Services::Ntp'],
'description': 'Sample!\n',
'name': 'sample',
'networks': {
'InternalApi': {
'subnet': 'internal_api_subnet'}
}
}
class TestRolesUtils(base.TestCase):
@@ -111,6 +135,10 @@ class TestRolesUtils(base.TestCase):
role = rolesutils.validate_role_yaml(SAMPLE_ROLE)
self.assertEqual(SAMPLE_ROLE_OBJ, role)
def test_validate_role_with_network_dict(self):
role = rolesutils.validate_role_yaml(SAMPLE_ROLE_NETWORK_DICT)
self.assertEqual(SAMPLE_ROLE_OBJ_NETWORK_DICT, role)
def test_validate_role_yaml_with_file(self):
m = mock.mock_open(read_data=SAMPLE_ROLE)
with mock.patch('tripleo_common.utils.roles.open', m):
@@ -133,6 +161,12 @@ class TestRolesUtils(base.TestCase):
self.assertRaises(RoleMetadataError, rolesutils.validate_role_yaml,
yaml.safe_dump(role))
def test_validate_role_yaml_invalid_network_type(self):
role = yaml.safe_load(SAMPLE_ROLE)
role[0]['networks'] = 'should not be a string'
self.assertRaises(RoleMetadataError, rolesutils.validate_role_yaml,
yaml.safe_dump(role))
@mock.patch('tripleo_common.utils.roles.check_role_exists')
@mock.patch('tripleo_common.utils.roles.get_roles_list_from_directory')
def test_generate_roles_with_one_role_generated(self, get_roles_mock,

View File

@@ -161,7 +161,7 @@ def validate_role_yaml(role_data=None, role_path=None):
'ServicesDefault': {'type': list},
'tags': {'type': list},
'description': {'type': six.string_types},
'networks': {'type': list},
'networks': {'type': [list, dict]},
'networks_skip_config': {'type': list},
}
@@ -170,8 +170,16 @@ def validate_role_yaml(role_data=None, role_path=None):
# validate numeric metadata is numeric
for k in schema:
if k in role and not isinstance(role[k], schema[k]['type']):
msg = "Role '{}': {} is not of expected type {}".format(
role['name'], k, schema[k]['type'])
raise RoleMetadataError(msg)
if k in role:
if k == 'networks':
if not (isinstance(role[k], schema[k]['type'][0]) or
isinstance(role[k], schema[k]['type'][1])):
msg = "Role '{}': {} is not of expected type {}".format(
role['name'], k, schema[k]['type'])
raise RoleMetadataError(msg)
else:
if not isinstance(role[k], schema[k]['type']):
msg = "Role '{}': {} is not of expected type {}".format(
role['name'], k, schema[k]['type'])
raise RoleMetadataError(msg)
return role