Skip to content

Commit d9a9f25

Browse files
authored
Merge pull request #6 from stackhpc/ib-physnet
Add Infiniband phyiscal network plugin
2 parents 3852c73 + 0222cdc commit d9a9f25

File tree

5 files changed

+136
-0
lines changed

5 files changed

+136
-0
lines changed

README.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ service, ironic inspector.
1313
Plugins
1414
=======
1515

16+
Infiniband Physical Network
17+
---------------------------
18+
19+
The ``ib_physnet`` plugin populates the ``physical_network`` field of ironic
20+
ports determined to be Infiniband ports. Ports with a ``client-id`` field
21+
in their ``extra`` attribute are determined to be IB ports.
22+
23+
The plugin is configured via the option ``[port_physnet] ib_physnet``, which is
24+
the name of the physical network to apply.
25+
1626
System Name Local Link Connection
1727
---------------------------------
1828

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,6 @@ packages =
2222

2323
[entry_points]
2424
ironic_inspector.hooks.processing =
25+
ib_physnet = stackhpc_inspector_plugins.plugins.ib_physnet:IBPhysnetHook
2526
system_name_physnet = stackhpc_inspector_plugins.plugins.system_name_physnet:SystemNamePhysnetHook
2627
system_name_llc = stackhpc_inspector_plugins.plugins.system_name_llc:SystemNameLocalLinkConnectionHook

stackhpc_inspector_plugins/conf.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919

2020

2121
PORT_PHYSNET_OPTS = [
22+
cfg.StrOpt(
23+
'ib_physnet',
24+
help=_('Name of the physical network that the Infiniband network is '
25+
'on')),
2226
cfg.ListOpt(
2327
'switch_sys_name_mapping',
2428
default=[],
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Copyright (c) 2018 StackHPC Ltd.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12+
# implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
from ironic_inspector import utils
17+
from oslo_config import cfg
18+
19+
from stackhpc_inspector_plugins.plugins import base_physnet
20+
21+
LOG = utils.getProcessingLogger(__name__)
22+
23+
CONF = cfg.CONF
24+
25+
26+
class IBPhysnetHook(base_physnet.BasePhysnetHook):
27+
"""Inspector hook to assign ports a physical network for IB interfaces.
28+
29+
This plugin sets the physical network for ports that are determined to be
30+
Infiniband ports. The physical network is given by the configuration
31+
option [port_physnet] ib_physnet.
32+
"""
33+
34+
def get_physnet(self, port, iface_name, introspection_data):
35+
"""Return a physical network to apply to a port.
36+
37+
:param port: The ironic port to patch.
38+
:param iface_name: Name of the interface.
39+
:param introspection_data: Introspection data.
40+
:returns: The physical network to set, or None.
41+
"""
42+
proc_data = introspection_data['all_interfaces'][iface_name]
43+
if proc_data.get('client_id'):
44+
LOG.debug("Interface %s is an Infiniband port, physnet %s",
45+
iface_name, CONF.port_physnet.ib_physnet)
46+
return CONF.port_physnet.ib_physnet
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Copyright (c) 2018 StackHPC Ltd.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12+
# implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
import mock
17+
18+
from ironic_inspector import node_cache
19+
from ironic_inspector.test import base as test_base
20+
from oslo_config import cfg
21+
22+
from stackhpc_inspector_plugins.plugins import ib_physnet
23+
24+
25+
class TestIBPhysnetHook(test_base.NodeTest):
26+
27+
def setUp(self):
28+
super(TestIBPhysnetHook, self).setUp()
29+
self.hook = ib_physnet.IBPhysnetHook()
30+
self.data = {
31+
'inventory': {
32+
'interfaces': [{
33+
'name': 'em1', 'mac_address': '11:11:11:11:11:11',
34+
'ipv4_address': '1.1.1.1',
35+
}],
36+
'cpu': 1,
37+
'disks': 1,
38+
'memory': 1
39+
},
40+
'all_interfaces': {
41+
'em1': {
42+
'client_id': ('ff:00:00:00:00:00:02:00:00:02:c9:00:7c:fe:'
43+
'90:03:00:3a:4b:0a'),
44+
},
45+
}
46+
}
47+
48+
ports = [mock.Mock(spec=['address', 'uuid', 'physical_network'],
49+
address=a, physical_network='physnet1')
50+
for a in ('11:11:11:11:11:11',)]
51+
self.node_info = node_cache.NodeInfo(uuid=self.uuid, started_at=0,
52+
node=self.node, ports=ports)
53+
54+
def test_expected_data_ib(self):
55+
cfg.CONF.set_override('ib_physnet', 'physnet1',
56+
group='port_physnet')
57+
port = self.node_info.ports().values()[0]
58+
physnet = self.hook.get_physnet(port, 'em1', self.data)
59+
self.assertEqual(physnet, 'physnet1')
60+
61+
def test_expected_data_client_id_is_none(self):
62+
cfg.CONF.set_override('ib_physnet', 'physnet1',
63+
group='port_physnet')
64+
self.data['all_interfaces']['em1']['client_id'] = None
65+
port = self.node_info.ports().values()[0]
66+
physnet = self.hook.get_physnet(port, 'em1', self.data)
67+
self.assertIsNone(physnet)
68+
69+
def test_expected_data_no_client_id(self):
70+
cfg.CONF.set_override('ib_physnet', 'physnet1',
71+
group='port_physnet')
72+
del self.data['all_interfaces']['em1']['client_id']
73+
port = self.node_info.ports().values()[0]
74+
physnet = self.hook.get_physnet(port, 'em1', self.data)
75+
self.assertIsNone(physnet)

0 commit comments

Comments
 (0)