Fix Network Templates Verification for environments with DPDK nodes
Don't check private VLAN's when there is the only node
without DPDK.
Change-Id: I94ee39df1d571e9f25b7083a23cef4be58303562
Related-Bug: #1566963
(cherry picked from commit 87f2304684
)
This commit is contained in:
parent
356a746c5c
commit
f8a987a0b5
@ -81,6 +81,16 @@ class NeutronManager(NetworkManager):
|
||||
props.append('bond_mode=%s' % bond.mode)
|
||||
return props
|
||||
|
||||
@classmethod
|
||||
def dpdk_enabled_for_node(cls, node):
|
||||
for iface in node.nic_interfaces:
|
||||
if objects.NIC.dpdk_enabled(iface):
|
||||
return True
|
||||
for iface in node.bond_interfaces:
|
||||
if objects.Bond.dpdk_enabled(iface):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class NeutronManagerLegacy(AssignIPsLegacyMixin, NeutronManager):
|
||||
pass
|
||||
@ -190,6 +200,19 @@ class NeutronManager70(
|
||||
|
||||
return endpoints
|
||||
|
||||
@classmethod
|
||||
def get_node_endpoint_by_network_role(cls, node, network_role):
|
||||
"""Get endpoint name for a given role name for node"""
|
||||
template = node.network_template
|
||||
|
||||
for role in node.all_roles:
|
||||
role_templates = template['templates_for_node_role'][role]
|
||||
for role_template in role_templates:
|
||||
role_mapping = template['templates'][role_template]['roles']
|
||||
if network_role in role_mapping:
|
||||
return role_mapping[network_role]
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def get_node_network_mapping(cls, node):
|
||||
"""Get (network, endpoint) mappings for node with loaded template
|
||||
@ -441,6 +464,29 @@ class NeutronManager70(
|
||||
}
|
||||
cls._update_attrs(node_data)
|
||||
|
||||
@classmethod
|
||||
def dpdk_enabled_for_node(cls, node):
|
||||
if node.network_template:
|
||||
endpoint_name = cls.get_node_endpoint_by_network_role(
|
||||
node, 'neutron/private')
|
||||
if not endpoint_name:
|
||||
return False
|
||||
template_names = set()
|
||||
for role in node.all_roles:
|
||||
template_names.update(
|
||||
node.network_template['templates_for_node_role'][role])
|
||||
templates = node.network_template['templates']
|
||||
for tmpl_name in template_names:
|
||||
transformations = templates[tmpl_name]['transformations']
|
||||
for t in transformations:
|
||||
if (t['action'] in ['add-port', 'add-bond'] and
|
||||
t.get('provider') == 'dpdkovs' and
|
||||
t.get('bridge') == endpoint_name):
|
||||
return True
|
||||
return False
|
||||
else:
|
||||
return super(NeutronManager70, cls).dpdk_enabled_for_node(node)
|
||||
|
||||
|
||||
class NeutronManager80(AllocateVIPs80Mixin, NeutronManager70):
|
||||
pass
|
||||
|
@ -1246,13 +1246,10 @@ class Node(NailgunObject):
|
||||
|
||||
@classmethod
|
||||
def dpdk_enabled(cls, instance):
|
||||
for iface in instance.nic_interfaces:
|
||||
if NIC.dpdk_enabled(iface):
|
||||
return True
|
||||
for iface in instance.bond_interfaces:
|
||||
if Bond.dpdk_enabled(iface):
|
||||
return True
|
||||
return False
|
||||
network_manager = Cluster.get_network_manager(instance.cluster)
|
||||
if not hasattr(network_manager, 'dpdk_enabled_for_node'):
|
||||
return False
|
||||
return network_manager.dpdk_enabled_for_node(instance)
|
||||
|
||||
@classmethod
|
||||
def sriov_enabled(cls, instance):
|
||||
|
@ -965,6 +965,13 @@ class BaseNetworkVerification(object):
|
||||
self.config = config
|
||||
|
||||
def get_ifaces_on_undeployed_node(self, node, node_json, networks_to_skip):
|
||||
"""Get list of interfaces and their VLANs to be checked for the node
|
||||
|
||||
:param node: Node object
|
||||
:param node_json: dictionary for saving result
|
||||
:param networks_to_skip: list of networks, which should be skipped
|
||||
:return:
|
||||
"""
|
||||
# Save bonds info to be able to check net-probe results w/o
|
||||
# need to access nodes in DB (node can be deleted before the test is
|
||||
# completed). This info is needed for non-deployed nodes only.
|
||||
@ -1011,6 +1018,13 @@ class BaseNetworkVerification(object):
|
||||
{'iface': iface.name, 'vlans': vlans})
|
||||
|
||||
def get_ifaces_on_deployed_node(self, node, node_json, networks_to_skip):
|
||||
"""Get list of interfaces and their VLANs to be checked for the node
|
||||
|
||||
:param node: Node object
|
||||
:param node_json: dictionary for saving result
|
||||
:param networks_to_skip: list of networks, which should be skipped
|
||||
:return:
|
||||
"""
|
||||
for iface in node.interfaces:
|
||||
# In case of present bond interfaces - collect assigned networks
|
||||
# against bonds themselves. We can check bonds as they are up on
|
||||
@ -1177,6 +1191,7 @@ class VerifyNetworksForTemplateMixin(object):
|
||||
transformations = template['transformations']
|
||||
|
||||
vlan_ids = cls._get_private_vlan_range(cluster, template)
|
||||
private_endpoint = template['roles'].get('neutron/private')
|
||||
|
||||
for transformation in transformations:
|
||||
if transformation['action'] in ['add-port', 'add-bond']:
|
||||
@ -1186,7 +1201,7 @@ class VerifyNetworksForTemplateMixin(object):
|
||||
if (transformation.get('provider', '') == 'dpdkovs' and
|
||||
node.status == consts.NODE_STATUSES.ready and
|
||||
transformation.get('bridge', '') ==
|
||||
consts.DEFAULT_BRIDGES_NAMES.br_prv):
|
||||
private_endpoint):
|
||||
continue
|
||||
yield transformation, vlan_ids
|
||||
|
||||
@ -1231,13 +1246,21 @@ class VerifyNetworksForTemplateMixin(object):
|
||||
node_json['bonds'] = bonds
|
||||
|
||||
@classmethod
|
||||
def get_ifaces_from_template_on_deployed_node(cls, node, node_json):
|
||||
def get_ifaces_from_template_on_deployed_node(cls, node, node_json,
|
||||
skip_private):
|
||||
"""Retrieves list of network interfaces on the deployed node
|
||||
|
||||
List is retrieved from the network template.
|
||||
"""
|
||||
ifaces = collections.defaultdict(set)
|
||||
net_manager = objects.Cluster.get_network_manager(node.cluster)
|
||||
private_endpoint = \
|
||||
net_manager.get_node_endpoint_by_network_role(node,
|
||||
'neutron/private')
|
||||
for transformation, vlan_ids in cls._get_transformations(node):
|
||||
if (skip_private and transformation.get('bridge', '') ==
|
||||
private_endpoint):
|
||||
continue
|
||||
if transformation['action'] == 'add-port':
|
||||
cls._add_interface(ifaces, transformation['name'], vlan_ids)
|
||||
elif transformation['action'] == 'add-bond':
|
||||
@ -1270,7 +1293,9 @@ class VerifyNetworksForTemplateMixin(object):
|
||||
def get_ifaces_on_deployed_node(self, node, node_json, networks_to_skip):
|
||||
"""Retrieves list of network interfaces on the deployed node."""
|
||||
if node.network_template:
|
||||
self.get_ifaces_from_template_on_deployed_node(node, node_json)
|
||||
self.get_ifaces_from_template_on_deployed_node(
|
||||
node, node_json,
|
||||
skip_private=consts.NETWORKS.private in networks_to_skip)
|
||||
return
|
||||
|
||||
super(VerifyNetworksForTemplateMixin, self
|
||||
|
@ -1797,3 +1797,62 @@ class TestNeutronManager80(BaseIntegrationTest):
|
||||
)
|
||||
|
||||
self._check_nic_mapping(node, expected_mapping)
|
||||
|
||||
def test_node_dpdk_enabled_w_template(self):
|
||||
template = {
|
||||
"templates_for_node_role": {
|
||||
"cinder": [],
|
||||
"controller": [],
|
||||
"test_role": [
|
||||
"storage",
|
||||
"private"
|
||||
]
|
||||
},
|
||||
"templates": {
|
||||
"storage": {
|
||||
"transformations": [
|
||||
{
|
||||
"action": "add-br",
|
||||
"name": "br-storage"
|
||||
},
|
||||
{
|
||||
"action": "add-port",
|
||||
"bridge": "br-storage",
|
||||
"name": "<% if3 %>"
|
||||
}
|
||||
],
|
||||
"roles": {
|
||||
"storage": "br-storage"
|
||||
}
|
||||
},
|
||||
"private": {
|
||||
"transformations": [
|
||||
{
|
||||
"action": "add-br",
|
||||
"name": "br-prv",
|
||||
"provider": "ovs",
|
||||
"vendor_specific": {
|
||||
"datapath_type": "netdev"
|
||||
}
|
||||
},
|
||||
{
|
||||
"action": "add-port",
|
||||
"bridge": "br-prv",
|
||||
"name": "<% if4 %>.101",
|
||||
"provider": "dpdkovs"
|
||||
}
|
||||
],
|
||||
"roles": {
|
||||
"neutron/private": "br-prv"
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
node = mock.Mock(network_template=template,
|
||||
all_roles=['test_role'])
|
||||
|
||||
self.assertTrue(self.net_manager.dpdk_enabled_for_node(node))
|
||||
|
||||
template['templates_for_node_role']['test_role'].remove('private')
|
||||
|
||||
self.assertFalse(self.net_manager.dpdk_enabled_for_node(node))
|
||||
|
@ -635,7 +635,8 @@ class TestNetworkVerificationWithTemplates90(BaseIntegrationTest):
|
||||
{"name": "eth3", "mac": "00:00:00:00:22:99"}]
|
||||
)
|
||||
self.cluster = self.env.create(
|
||||
release_kwargs={'version': 'liberty-9.0'},
|
||||
release_kwargs={'version': 'mitaka-9.0',
|
||||
'operating_system': consts.RELEASE_OS.ubuntu},
|
||||
cluster_kwargs={
|
||||
'net_provider': consts.CLUSTER_NET_PROVIDERS.neutron,
|
||||
'net_segment_type': net_type,
|
||||
@ -658,10 +659,25 @@ class TestNetworkVerificationWithTemplates90(BaseIntegrationTest):
|
||||
}]
|
||||
)
|
||||
|
||||
objects.Cluster.patch_attributes(
|
||||
self.cluster,
|
||||
{'editable': {
|
||||
'common': {
|
||||
'libvirt_type': {
|
||||
'value': consts.HYPERVISORS.kvm}}}})
|
||||
|
||||
template = self.env.read_fixtures(['network_template_90'])[0]
|
||||
template.pop('pk')
|
||||
self.upload_template(self.cluster['id'], template)
|
||||
|
||||
for node in self.cluster.nodes:
|
||||
objects.Node.update_attributes(
|
||||
node,
|
||||
{'hugepages':
|
||||
{'dpdk': {'value': 128},
|
||||
'nova': {'value': {'2048': 128}}}}
|
||||
)
|
||||
|
||||
if net_type == consts.NEUTRON_SEGMENT_TYPES.vlan:
|
||||
self.private_vlan_ids = list(range(1000, 1031))
|
||||
else:
|
||||
|
@ -537,6 +537,13 @@ class TestCheckBeforeDeploymentTask(BaseTestCase):
|
||||
|
||||
def test_dpdk_hugepages_are_not_configured(self):
|
||||
net_template = self.env.read_fixtures(['network_template_90'])[0]
|
||||
del self.cluster.nodes[0]
|
||||
self.env.create_nodes_w_interfaces_count(
|
||||
1, 6,
|
||||
roles=['compute'],
|
||||
cluster_id=self.cluster.id
|
||||
)
|
||||
self.node = self.cluster.nodes[0]
|
||||
|
||||
objects.Cluster.set_network_template(
|
||||
self.cluster,
|
||||
@ -560,6 +567,13 @@ class TestCheckBeforeDeploymentTask(BaseTestCase):
|
||||
|
||||
def test_nova_hugepages_are_not_configured_with_dpdk_enabled(self):
|
||||
net_template = self.env.read_fixtures(['network_template_90'])[0]
|
||||
del self.cluster.nodes[0]
|
||||
self.env.create_nodes_w_interfaces_count(
|
||||
1, 6,
|
||||
roles=['compute'],
|
||||
cluster_id=self.cluster.id
|
||||
)
|
||||
self.node = self.cluster.nodes[0]
|
||||
|
||||
objects.Cluster.set_network_template(
|
||||
self.cluster,
|
||||
|
Loading…
Reference in New Issue
Block a user