Merge "Add option to delete ports after introspection"
This commit is contained in:
commit
16cc7323a5
|
@ -49,6 +49,13 @@
|
|||
# Allowed values: all, active, pxe
|
||||
#add_ports = pxe
|
||||
|
||||
# Which ports (already present on a node) to keep after introspection.
|
||||
# Possible values: all (do not delete anything), present (keep ports
|
||||
# which MACs were present in introspection data), added (keep only
|
||||
# MACs that we added during introspection). (string value)
|
||||
# Allowed values: all, present, added
|
||||
#keep_ports = all
|
||||
|
||||
# Timeout after which introspection is considered failed, set to 0 to
|
||||
# disable. (integer value)
|
||||
#timeout = 3600
|
||||
|
|
|
@ -15,6 +15,7 @@ from oslo_config import cfg
|
|||
|
||||
|
||||
VALID_ADD_PORTS_VALUES = ('all', 'active', 'pxe')
|
||||
VALID_KEEP_PORTS_VALUES = ('all', 'present', 'added')
|
||||
|
||||
SERVICE_OPTS = [
|
||||
cfg.StrOpt('os_auth_url',
|
||||
|
@ -61,6 +62,14 @@ SERVICE_OPTS = [
|
|||
'from, falls back to "active" if PXE MAC is not supplied '
|
||||
'by the ramdisk).',
|
||||
choices=VALID_ADD_PORTS_VALUES),
|
||||
cfg.StrOpt('keep_ports',
|
||||
default='all',
|
||||
help='Which ports (already present on a node) to keep after '
|
||||
'introspection. Possible values: '
|
||||
'all (do not delete anything), present (keep ports which MACs '
|
||||
'were present in introspection data), added (keep only MACs '
|
||||
'that we added during introspection).',
|
||||
choices=VALID_KEEP_PORTS_VALUES),
|
||||
cfg.IntOpt('timeout',
|
||||
default=3600,
|
||||
help='Timeout after which introspection is considered failed, '
|
||||
|
|
|
@ -67,6 +67,13 @@ class ValidateInterfacesHook(base.ProcessingHook):
|
|||
'actual': CONF.discoverd.add_ports})
|
||||
sys.exit(1)
|
||||
|
||||
if CONF.discoverd.keep_ports not in conf.VALID_KEEP_PORTS_VALUES:
|
||||
LOG.critical(_LC('Accepted values for [discoverd]keep_ports are '
|
||||
'%(valid)s, got %(actual)s'),
|
||||
{'valid': conf.VALID_KEEP_PORTS_VALUES,
|
||||
'actual': CONF.discoverd.keep_ports})
|
||||
sys.exit(1)
|
||||
|
||||
def _ports_to_add(self):
|
||||
if CONF.discoverd.ports_for_inactive_interfaces:
|
||||
LOG.warning(_LW('Using deprecated option '
|
||||
|
@ -127,6 +134,28 @@ class ValidateInterfacesHook(base.ProcessingHook):
|
|||
valid_macs = [iface['mac'] for iface in valid_interfaces.values()]
|
||||
node_info['macs'] = valid_macs
|
||||
|
||||
def before_update(self, node, ports, node_info):
|
||||
"""Drop ports that are not present in the data."""
|
||||
if CONF.discoverd.keep_ports == 'present':
|
||||
expected_macs = {iface['mac']
|
||||
for iface in node_info['all_interfaces'].values()}
|
||||
elif CONF.discoverd.keep_ports == 'added':
|
||||
expected_macs = set(node_info['macs'])
|
||||
else:
|
||||
return
|
||||
|
||||
ironic = utils.get_client()
|
||||
for port in ironic.node.list_ports(node.uuid, limit=0):
|
||||
if port.address not in expected_macs:
|
||||
LOG.info(_LI("Deleting port %(port)s as its MAC %(mac)s is "
|
||||
"not in expected MAC list %(expected)s for node "
|
||||
"%(node)s"),
|
||||
{'port': port.uuid,
|
||||
'mac': port.address,
|
||||
'expected': list(sorted(expected_macs)),
|
||||
'node': node.uuid})
|
||||
ironic.port.delete(port.uuid)
|
||||
|
||||
|
||||
class RamdiskErrorHook(base.ProcessingHook):
|
||||
"""Hook to process error send from the ramdisk."""
|
||||
|
|
|
@ -325,6 +325,7 @@ class TestProcessNode(BaseTest):
|
|||
'discoverd')
|
||||
self.validate_attempts = 5
|
||||
self.data['macs'] = self.macs # validate_interfaces hook
|
||||
self.data['all_interfaces'] = self.data['interfaces']
|
||||
self.ports = self.all_ports
|
||||
self.cached_node = node_cache.NodeInfo(uuid=self.uuid,
|
||||
started_at=self.started_at)
|
||||
|
@ -509,8 +510,53 @@ class TestProcessNode(BaseTest):
|
|||
error='Failed to power off node %s, check it\'s power management'
|
||||
' configuration: boom' % self.uuid)
|
||||
|
||||
@mock.patch.object(utils, 'get_client')
|
||||
def test_keep_ports_present(self, client_mock, filters_mock,
|
||||
post_hook_mock):
|
||||
CONF.set_override('keep_ports', 'present', 'discoverd')
|
||||
|
||||
# 2 MACs valid, one invalid, one not present in data
|
||||
all_macs = self.all_macs + ['01:09:02:08:03:07']
|
||||
all_ports = [
|
||||
mock.Mock(uuid='port_uuid%d' % i, address=mac)
|
||||
for i, mac in enumerate(all_macs)
|
||||
]
|
||||
|
||||
client_mock.return_value = self.cli
|
||||
self.cli.node.list_ports.return_value = all_ports
|
||||
|
||||
self.call()
|
||||
|
||||
self.cli.node.list_ports.assert_called_once_with(self.uuid, limit=0)
|
||||
self.cli.port.delete.assert_called_once_with(all_ports[-1].uuid)
|
||||
|
||||
@mock.patch.object(utils, 'get_client')
|
||||
def test_keep_ports_added(self, client_mock, filters_mock, post_hook_mock):
|
||||
CONF.set_override('keep_ports', 'added', 'discoverd')
|
||||
|
||||
# 2 MACs valid, one invalid, one not present in data
|
||||
all_macs = self.all_macs + ['01:09:02:08:03:07']
|
||||
all_ports = [
|
||||
mock.Mock(uuid='port_uuid%d' % i, address=mac)
|
||||
for i, mac in enumerate(all_macs)
|
||||
]
|
||||
|
||||
client_mock.return_value = self.cli
|
||||
self.cli.node.list_ports.return_value = all_ports
|
||||
|
||||
self.call()
|
||||
|
||||
self.cli.node.list_ports.assert_called_once_with(self.uuid, limit=0)
|
||||
for port in all_ports[2:]:
|
||||
self.cli.port.delete.assert_any_call(port.uuid)
|
||||
self.assertEqual(2, self.cli.port.delete.call_count)
|
||||
|
||||
|
||||
class TestValidateInterfacesHook(test_base.BaseTest):
|
||||
def test_wrong_add_ports(self):
|
||||
CONF.set_override('add_ports', 'foobar', 'discoverd')
|
||||
self.assertRaises(SystemExit, std_plugins.ValidateInterfacesHook)
|
||||
|
||||
def test_wrong_keep_ports(self):
|
||||
CONF.set_override('keep_ports', 'foobar', 'discoverd')
|
||||
self.assertRaises(SystemExit, std_plugins.ValidateInterfacesHook)
|
||||
|
|
Loading…
Reference in New Issue