[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:
Andrey Shestakov 2015-11-11 16:09:16 +02:00
parent e1af59eeb7
commit ea913ffea8
5 changed files with 152 additions and 10 deletions

View File

@ -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'
)
)

View File

@ -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

View File

@ -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):

View File

@ -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,

View File

@ -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):