[Ironic] Add transformations for Ironic
This change introduces L2 transformations for baremetal network and L3 neutron network. Change-Id: I565c703dca6cedaa74f0bf426d82ecde79257ecb Implements: blueprint fuel-integrate-ironic (partially)
This commit is contained in:
parent
e1af59eeb7
commit
ea913ffea8
|
@ -103,6 +103,7 @@ DEFAULT_BRIDGES_NAMES = Enum(
|
|||
'br-mesh',
|
||||
'br-aux',
|
||||
'br-baremetal',
|
||||
'br-ironic',
|
||||
names=(
|
||||
'br_fw_admin',
|
||||
'br_storage',
|
||||
|
@ -113,7 +114,8 @@ DEFAULT_BRIDGES_NAMES = Enum(
|
|||
'br_ex',
|
||||
'br_mesh',
|
||||
'br_aux',
|
||||
'br_baremetal'
|
||||
'br_baremetal',
|
||||
'br_ironic'
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -1320,6 +1320,11 @@ class GenerateL23Mixin80(object):
|
|||
"bridge": consts.DEFAULT_BRIDGES_NAMES.br_floating,
|
||||
"vlan_range": None
|
||||
}
|
||||
if objects.Cluster.is_component_enabled(cluster, 'ironic'):
|
||||
l2["phys_nets"]["physnet-ironic"] = {
|
||||
"bridge": consts.DEFAULT_BRIDGES_NAMES.br_ironic,
|
||||
"vlan_range": None
|
||||
}
|
||||
return l2
|
||||
|
||||
@classmethod
|
||||
|
@ -1335,6 +1340,38 @@ class GenerateL23Mixin80(object):
|
|||
}
|
||||
return ext_net
|
||||
|
||||
@classmethod
|
||||
def _generate_baremetal_network(cls, cluster):
|
||||
ng = objects.NetworkGroup.get_from_node_group_by_name(
|
||||
objects.Cluster.get_default_group(cluster).id, 'baremetal')
|
||||
return {
|
||||
"L3": {
|
||||
"subnet": ng.cidr,
|
||||
"nameservers": cluster.network_config.dns_nameservers,
|
||||
"gateway": cluster.network_config.baremetal_gateway,
|
||||
"floating": utils.join_range(
|
||||
cluster.network_config.baremetal_range),
|
||||
"enable_dhcp": True
|
||||
},
|
||||
"L2": {
|
||||
"network_type": "flat",
|
||||
"segment_id": None,
|
||||
"router_ext": False,
|
||||
"physnet": "physnet-ironic"
|
||||
},
|
||||
"tenant": objects.Cluster.get_creds(
|
||||
cluster)['tenant']['value'],
|
||||
"shared": True
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def generate_predefined_networks(cls, cluster):
|
||||
nets = NeutronNetworkDeploymentSerializer70.\
|
||||
generate_predefined_networks(cluster)
|
||||
if objects.Cluster.is_component_enabled(cluster, 'ironic'):
|
||||
nets["baremetal"] = cls._generate_baremetal_network(cluster)
|
||||
return nets
|
||||
|
||||
|
||||
class NeutronNetworkDeploymentSerializer80(
|
||||
GenerateL23Mixin80,
|
||||
|
@ -1378,6 +1415,12 @@ class NeutronNetworkDeploymentSerializer80(
|
|||
if objects.Cluster.is_component_enabled(node.cluster, 'ironic'):
|
||||
transformations.insert(0, cls.add_bridge(
|
||||
consts.DEFAULT_BRIDGES_NAMES.br_baremetal))
|
||||
transformations.append(cls.add_bridge(
|
||||
consts.DEFAULT_BRIDGES_NAMES.br_ironic, provider='ovs'))
|
||||
transformations.append(cls.add_patch(
|
||||
bridges=[consts.DEFAULT_BRIDGES_NAMES.br_ironic,
|
||||
consts.DEFAULT_BRIDGES_NAMES.br_baremetal],
|
||||
provider='ovs'))
|
||||
return transformations
|
||||
|
||||
|
||||
|
|
|
@ -1158,6 +1158,17 @@ class EnvironmentManager(object):
|
|||
expect_errors=expect_errors
|
||||
)
|
||||
|
||||
def _set_additional_component(self, cluster, component, value):
|
||||
attrs = cluster.attributes.editable
|
||||
attrs['additional_components'][component]['value'] = value
|
||||
self.app.patch(
|
||||
reverse(
|
||||
'ClusterAttributesHandler',
|
||||
kwargs={'cluster_id': cluster.id}),
|
||||
params=jsonutils.dumps({'editable': attrs}),
|
||||
headers=self.default_headers
|
||||
)
|
||||
|
||||
|
||||
class BaseTestCase(TestCase):
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from copy import deepcopy
|
||||
|
||||
from nailgun import consts
|
||||
from nailgun.db.sqlalchemy import models
|
||||
from nailgun import objects
|
||||
|
@ -33,13 +35,50 @@ from nailgun.test.integration.test_orchestrator_serializer_70 import \
|
|||
TestDeploymentHASerializer70
|
||||
|
||||
|
||||
class TestNetworkTemplateSerializer80(BaseDeploymentSerializer):
|
||||
class TestSerializer80Mixin(object):
|
||||
env_version = "2015.1.0-8.0"
|
||||
|
||||
def prepare_for_deployment(self, nodes, *_):
|
||||
objects.NodeCollection.prepare_for_deployment(nodes)
|
||||
|
||||
def _check_baremetal_neutron_attrs(self, cluster):
|
||||
self.env._set_additional_component(cluster, 'ironic', True)
|
||||
self.env.create_node(cluster_id=cluster.id,
|
||||
roles=['controller'])
|
||||
self.prepare_for_deployment(self.env.nodes)
|
||||
serialized_for_astute = self.serializer.serialize(
|
||||
cluster, cluster.nodes)
|
||||
for node in serialized_for_astute:
|
||||
expected_network = {
|
||||
"network_type": "flat",
|
||||
"segment_id": None,
|
||||
"router_ext": False,
|
||||
"physnet": "physnet-ironic"
|
||||
}
|
||||
self.assertEqual(expected_network, node['quantum_settings']
|
||||
['predefined_networks']['baremetal']['L2'])
|
||||
self.assertIn("physnet-ironic",
|
||||
node['quantum_settings']['L2']['phys_nets'])
|
||||
self.assertEqual(consts.DEFAULT_BRIDGES_NAMES.br_ironic,
|
||||
(node['quantum_settings']['L2']['phys_nets']
|
||||
["physnet-ironic"]["bridge"]))
|
||||
|
||||
|
||||
class TestNetworkTemplateSerializer80(
|
||||
TestSerializer80Mixin,
|
||||
BaseDeploymentSerializer
|
||||
):
|
||||
env_version = '2015.1.0-8.0'
|
||||
prepare_for_deployment = objects.NodeCollection.prepare_for_deployment
|
||||
|
||||
def setUp(self, *args):
|
||||
super(TestNetworkTemplateSerializer80, self).setUp()
|
||||
cluster = self.create_env(consts.CLUSTER_MODES.ha_compact)
|
||||
cluster = self.env.create(
|
||||
release_kwargs={'version': self.env_version},
|
||||
cluster_kwargs={
|
||||
'mode': consts.CLUSTER_MODES.ha_compact,
|
||||
'net_provider': consts.CLUSTER_NET_PROVIDERS.neutron,
|
||||
'net_segment_type': consts.NEUTRON_SEGMENT_TYPES.vlan})
|
||||
self.net_template = self.env.read_fixtures(['network_template'])[0]
|
||||
self.cluster = self.db.query(models.Cluster).get(cluster['id'])
|
||||
|
||||
|
@ -55,15 +94,29 @@ class TestNetworkTemplateSerializer80(BaseDeploymentSerializer):
|
|||
net_serializer = serializer.get_net_provider_serializer(self.cluster)
|
||||
self.assertIs(net_serializer, NeutronNetworkTemplateSerializer80)
|
||||
|
||||
|
||||
class TestSerializer80Mixin(object):
|
||||
env_version = "2015.1.0-8.0"
|
||||
|
||||
def prepare_for_deployment(self, nodes, *_):
|
||||
objects.NodeCollection.prepare_for_deployment(nodes)
|
||||
def test_baremetal_neutron_attrs(self):
|
||||
brmtl_template = deepcopy(
|
||||
self.net_template['adv_net_template']['default'])
|
||||
brmtl_template['network_assignments']['baremetal'] = {
|
||||
'ep': 'br-baremetal'}
|
||||
brmtl_template['templates_for_node_role']['controller'].append(
|
||||
'baremetal')
|
||||
brmtl_template['nic_mapping']['default']['if8'] = 'eth7'
|
||||
brmtl_template['network_scheme']['baremetal'] = {
|
||||
'endpoints': ['br-baremetal'],
|
||||
'transformations': [],
|
||||
'roles': {'baremetal': 'br-baremetal'}}
|
||||
self.cluster.network_config.configuration_template = {
|
||||
'adv_net_template': {'default': brmtl_template}, 'pk': 1}
|
||||
serializer_type = get_serializer_for_cluster(self.cluster)
|
||||
self.serializer = serializer_type(AstuteGraph(self.cluster))
|
||||
self._check_baremetal_neutron_attrs(self.cluster)
|
||||
|
||||
|
||||
class TestDeploymentAttributesSerialization80(BaseDeploymentSerializer):
|
||||
class TestDeploymentAttributesSerialization80(
|
||||
TestSerializer80Mixin,
|
||||
BaseDeploymentSerializer
|
||||
):
|
||||
env_version = '2015.1.0-8.0'
|
||||
|
||||
def setUp(self):
|
||||
|
@ -95,6 +148,31 @@ class TestDeploymentAttributesSerialization80(BaseDeploymentSerializer):
|
|||
node['quantum_settings']['L2']['phys_nets']['physnet1']
|
||||
)
|
||||
|
||||
def test_baremetal_transformations(self):
|
||||
self.env._set_additional_component(self.cluster_db, 'ironic', True)
|
||||
self.env.create_node(cluster_id=self.cluster_db.id,
|
||||
roles=['primary-controller'])
|
||||
self.prepare_for_deployment(self.env.nodes)
|
||||
serialized_for_astute = self.serializer.serialize(
|
||||
self.cluster_db, self.cluster_db.nodes)
|
||||
for node in serialized_for_astute:
|
||||
transformations = node['network_scheme']['transformations']
|
||||
baremetal_brs = filter(lambda t: t.get('name') ==
|
||||
consts.DEFAULT_BRIDGES_NAMES.br_baremetal,
|
||||
transformations)
|
||||
baremetal_ports = filter(lambda t: t.get('name') == "eth0.104",
|
||||
transformations)
|
||||
expected_patch = {
|
||||
'action': 'add-patch',
|
||||
'bridges': [consts.DEFAULT_BRIDGES_NAMES.br_ironic,
|
||||
consts.DEFAULT_BRIDGES_NAMES.br_baremetal],
|
||||
'provider': 'ovs'}
|
||||
self.assertEqual(len(baremetal_brs), 1)
|
||||
self.assertEqual(len(baremetal_ports), 1)
|
||||
self.assertEqual(baremetal_ports[0]['bridge'],
|
||||
consts.DEFAULT_BRIDGES_NAMES.br_baremetal)
|
||||
self.assertIn(expected_patch, transformations)
|
||||
|
||||
|
||||
class TestSerializeInterfaceDriversData80(
|
||||
TestSerializer80Mixin,
|
||||
|
|
|
@ -1232,6 +1232,14 @@ class TestClusterObject(BaseTestCase):
|
|||
self.assertDictEqual(
|
||||
volumes_metadata, expected_volumes_metadata)
|
||||
|
||||
def test_cluster_is_component_enabled(self):
|
||||
cluster = self.env.clusters[0]
|
||||
self.assertFalse(objects.Cluster.is_component_enabled(cluster,
|
||||
'ironic'))
|
||||
self.env._set_additional_component(cluster, 'ironic', True)
|
||||
self.assertTrue(objects.Cluster.is_component_enabled(cluster,
|
||||
'ironic'))
|
||||
|
||||
|
||||
class TestClusterObjectVirtRoles(BaseTestCase):
|
||||
|
||||
|
|
Loading…
Reference in New Issue