Merge "Support ip6tables for iptables pxe filter"
This commit is contained in:
commit
7e63503ebe
|
@ -34,6 +34,12 @@ _OPTS = [
|
||||||
'which are not in desired state are going to be '
|
'which are not in desired state are going to be '
|
||||||
'blacklisted based on the list of neighbor MACs '
|
'blacklisted based on the list of neighbor MACs '
|
||||||
'on these interfaces.')),
|
'on these interfaces.')),
|
||||||
|
cfg.StrOpt('ip_version',
|
||||||
|
default='4',
|
||||||
|
choices=[('4', _('IPv4')),
|
||||||
|
('6', _('IPv6'))],
|
||||||
|
help=_('The IP version that will be used for iptables filter. '
|
||||||
|
'Defaults to 4.')),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -50,8 +50,18 @@ class IptablesFilter(pxe_filter.BaseFilter):
|
||||||
self.interface = CONF.iptables.dnsmasq_interface
|
self.interface = CONF.iptables.dnsmasq_interface
|
||||||
self.chain = CONF.iptables.firewall_chain
|
self.chain = CONF.iptables.firewall_chain
|
||||||
self.new_chain = self.chain + '_temp'
|
self.new_chain = self.chain + '_temp'
|
||||||
|
|
||||||
|
# Determine arguments used for pxe filtering, we only support 4 and 6
|
||||||
|
# at this time.
|
||||||
|
if CONF.iptables.ip_version == '4':
|
||||||
|
self._cmd_iptables = 'iptables'
|
||||||
|
self._dhcp_port = '67'
|
||||||
|
else:
|
||||||
|
self._cmd_iptables = 'ip6tables'
|
||||||
|
self._dhcp_port = '547'
|
||||||
|
|
||||||
self.base_command = ('sudo', 'ironic-inspector-rootwrap',
|
self.base_command = ('sudo', 'ironic-inspector-rootwrap',
|
||||||
CONF.rootwrap_config, 'iptables')
|
CONF.rootwrap_config, self._cmd_iptables)
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self.enabled = True
|
self.enabled = True
|
||||||
|
@ -137,9 +147,9 @@ class IptablesFilter(pxe_filter.BaseFilter):
|
||||||
|
|
||||||
# Swap chains
|
# Swap chains
|
||||||
self._iptables('-I', 'INPUT', '-i', self.interface, '-p', 'udp',
|
self._iptables('-I', 'INPUT', '-i', self.interface, '-p', 'udp',
|
||||||
'--dport', '67', '-j', chain)
|
'--dport', self._dhcp_port, '-j', chain)
|
||||||
self._iptables('-D', 'INPUT', '-i', self.interface, '-p', 'udp',
|
self._iptables('-D', 'INPUT', '-i', self.interface, '-p', 'udp',
|
||||||
'--dport', '67', '-j', main_chain,
|
'--dport', self._dhcp_port, '-j', main_chain,
|
||||||
ignore=True)
|
ignore=True)
|
||||||
self._iptables('-F', main_chain, ignore=True)
|
self._iptables('-F', main_chain, ignore=True)
|
||||||
self._iptables('-X', main_chain, ignore=True)
|
self._iptables('-X', main_chain, ignore=True)
|
||||||
|
@ -163,7 +173,7 @@ class IptablesFilter(pxe_filter.BaseFilter):
|
||||||
|
|
||||||
def _clean_up(self, chain):
|
def _clean_up(self, chain):
|
||||||
self._iptables('-D', 'INPUT', '-i', self.interface, '-p', 'udp',
|
self._iptables('-D', 'INPUT', '-i', self.interface, '-p', 'udp',
|
||||||
'--dport', '67', '-j', chain,
|
'--dport', self._dhcp_port, '-j', chain,
|
||||||
ignore=True)
|
ignore=True)
|
||||||
self._iptables('-F', chain, ignore=True)
|
self._iptables('-F', chain, ignore=True)
|
||||||
self._iptables('-X', chain, ignore=True)
|
self._iptables('-X', chain, ignore=True)
|
||||||
|
|
|
@ -114,20 +114,23 @@ class TestIptablesDriver(test_base.NodeTest):
|
||||||
self.assertRaisesRegex(MyError, 'Oops!', self.driver.init_filter)
|
self.assertRaisesRegex(MyError, 'Oops!', self.driver.init_filter)
|
||||||
self.check_fsm([pxe_filter.Events.initialize, pxe_filter.Events.reset])
|
self.check_fsm([pxe_filter.Events.initialize, pxe_filter.Events.reset])
|
||||||
|
|
||||||
def test__iptables_args(self):
|
def _test__iptables_args(self, expected_port):
|
||||||
|
self.driver = iptables.IptablesFilter()
|
||||||
|
self.mock_iptables = self.useFixture(
|
||||||
|
fixtures.MockPatchObject(self.driver, '_iptables')).mock
|
||||||
self.mock_should_enable_dhcp.return_value = True
|
self.mock_should_enable_dhcp.return_value = True
|
||||||
|
|
||||||
_iptables_expected_args = [
|
_iptables_expected_args = [
|
||||||
('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
|
('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
|
||||||
'67', '-j', self.driver.new_chain),
|
expected_port, '-j', self.driver.new_chain),
|
||||||
('-F', self.driver.new_chain),
|
('-F', self.driver.new_chain),
|
||||||
('-X', self.driver.new_chain),
|
('-X', self.driver.new_chain),
|
||||||
('-N', self.driver.new_chain),
|
('-N', self.driver.new_chain),
|
||||||
('-A', self.driver.new_chain, '-j', 'ACCEPT'),
|
('-A', self.driver.new_chain, '-j', 'ACCEPT'),
|
||||||
('-I', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
|
('-I', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
|
||||||
'67', '-j', self.driver.new_chain),
|
expected_port, '-j', self.driver.new_chain),
|
||||||
('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
|
('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
|
||||||
'67', '-j', self.driver.chain),
|
expected_port, '-j', self.driver.chain),
|
||||||
('-F', self.driver.chain),
|
('-F', self.driver.chain),
|
||||||
('-X', self.driver.chain),
|
('-X', self.driver.chain),
|
||||||
('-E', self.driver.new_chain, self.driver.chain)
|
('-E', self.driver.new_chain, self.driver.chain)
|
||||||
|
@ -142,6 +145,14 @@ class TestIptablesDriver(test_base.NodeTest):
|
||||||
self.mock__get_blacklist.assert_called_once_with(self.mock_ironic)
|
self.mock__get_blacklist.assert_called_once_with(self.mock_ironic)
|
||||||
self.check_fsm([pxe_filter.Events.sync])
|
self.check_fsm([pxe_filter.Events.sync])
|
||||||
|
|
||||||
|
def test__iptables_args_ipv4(self):
|
||||||
|
CONF.set_override('ip_version', '4', 'iptables')
|
||||||
|
self._test__iptables_args('67')
|
||||||
|
|
||||||
|
def test__iptables_args_ipv6(self):
|
||||||
|
CONF.set_override('ip_version', '6', 'iptables')
|
||||||
|
self._test__iptables_args('547')
|
||||||
|
|
||||||
def test__iptables_kwargs(self):
|
def test__iptables_kwargs(self):
|
||||||
_iptables_expected_kwargs = [
|
_iptables_expected_kwargs = [
|
||||||
{'ignore': True},
|
{'ignore': True},
|
||||||
|
@ -163,13 +174,16 @@ class TestIptablesDriver(test_base.NodeTest):
|
||||||
self.assertEqual(kwargs, call[1])
|
self.assertEqual(kwargs, call[1])
|
||||||
self.check_fsm([pxe_filter.Events.sync])
|
self.check_fsm([pxe_filter.Events.sync])
|
||||||
|
|
||||||
def test_sync_with_blacklist(self):
|
def _test_sync_with_blacklist(self, expected_port):
|
||||||
|
self.driver = iptables.IptablesFilter()
|
||||||
|
self.mock_iptables = self.useFixture(
|
||||||
|
fixtures.MockPatchObject(self.driver, '_iptables')).mock
|
||||||
self.mock__get_blacklist.return_value = ['AA:BB:CC:DD:EE:FF']
|
self.mock__get_blacklist.return_value = ['AA:BB:CC:DD:EE:FF']
|
||||||
self.mock_should_enable_dhcp.return_value = True
|
self.mock_should_enable_dhcp.return_value = True
|
||||||
|
|
||||||
_iptables_expected_args = [
|
_iptables_expected_args = [
|
||||||
('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
|
('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
|
||||||
'67', '-j', self.driver.new_chain),
|
expected_port, '-j', self.driver.new_chain),
|
||||||
('-F', self.driver.new_chain),
|
('-F', self.driver.new_chain),
|
||||||
('-X', self.driver.new_chain),
|
('-X', self.driver.new_chain),
|
||||||
('-N', self.driver.new_chain),
|
('-N', self.driver.new_chain),
|
||||||
|
@ -178,9 +192,9 @@ class TestIptablesDriver(test_base.NodeTest):
|
||||||
self.mock__get_blacklist.return_value[0], '-j', 'DROP'),
|
self.mock__get_blacklist.return_value[0], '-j', 'DROP'),
|
||||||
('-A', self.driver.new_chain, '-j', 'ACCEPT'),
|
('-A', self.driver.new_chain, '-j', 'ACCEPT'),
|
||||||
('-I', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
|
('-I', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
|
||||||
'67', '-j', self.driver.new_chain),
|
expected_port, '-j', self.driver.new_chain),
|
||||||
('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
|
('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
|
||||||
'67', '-j', self.driver.chain),
|
expected_port, '-j', self.driver.chain),
|
||||||
('-F', self.driver.chain),
|
('-F', self.driver.chain),
|
||||||
('-X', self.driver.chain),
|
('-X', self.driver.chain),
|
||||||
('-E', self.driver.new_chain, self.driver.chain)
|
('-E', self.driver.new_chain, self.driver.chain)
|
||||||
|
@ -203,7 +217,18 @@ class TestIptablesDriver(test_base.NodeTest):
|
||||||
self.mock__get_blacklist.assert_called_once_with(self.mock_ironic)
|
self.mock__get_blacklist.assert_called_once_with(self.mock_ironic)
|
||||||
self.assertFalse(self.mock_iptables.called)
|
self.assertFalse(self.mock_iptables.called)
|
||||||
|
|
||||||
def test__iptables_clean_cache_on_error(self):
|
def test_sync_with_blacklist_ipv4(self):
|
||||||
|
CONF.set_override('ip_version', '4', 'iptables')
|
||||||
|
self._test_sync_with_blacklist('67')
|
||||||
|
|
||||||
|
def test_sync_with_blacklist_ipv6(self):
|
||||||
|
CONF.set_override('ip_version', '6', 'iptables')
|
||||||
|
self._test_sync_with_blacklist('547')
|
||||||
|
|
||||||
|
def _test__iptables_clean_cache_on_error(self, expected_port):
|
||||||
|
self.driver = iptables.IptablesFilter()
|
||||||
|
self.mock_iptables = self.useFixture(
|
||||||
|
fixtures.MockPatchObject(self.driver, '_iptables')).mock
|
||||||
self.mock__get_blacklist.return_value = ['AA:BB:CC:DD:EE:FF']
|
self.mock__get_blacklist.return_value = ['AA:BB:CC:DD:EE:FF']
|
||||||
self.mock_should_enable_dhcp.return_value = True
|
self.mock_should_enable_dhcp.return_value = True
|
||||||
|
|
||||||
|
@ -217,7 +242,7 @@ class TestIptablesDriver(test_base.NodeTest):
|
||||||
syncs_expected_args = [
|
syncs_expected_args = [
|
||||||
# driver reset
|
# driver reset
|
||||||
('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
|
('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
|
||||||
'67', '-j', self.driver.new_chain),
|
expected_port, '-j', self.driver.new_chain),
|
||||||
('-F', self.driver.new_chain),
|
('-F', self.driver.new_chain),
|
||||||
('-X', self.driver.new_chain),
|
('-X', self.driver.new_chain),
|
||||||
('-N', self.driver.new_chain),
|
('-N', self.driver.new_chain),
|
||||||
|
@ -226,9 +251,9 @@ class TestIptablesDriver(test_base.NodeTest):
|
||||||
self.mock__get_blacklist.return_value[0], '-j', 'DROP'),
|
self.mock__get_blacklist.return_value[0], '-j', 'DROP'),
|
||||||
('-A', self.driver.new_chain, '-j', 'ACCEPT'),
|
('-A', self.driver.new_chain, '-j', 'ACCEPT'),
|
||||||
('-I', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
|
('-I', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
|
||||||
'67', '-j', self.driver.new_chain),
|
expected_port, '-j', self.driver.new_chain),
|
||||||
('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
|
('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
|
||||||
'67', '-j', self.driver.chain),
|
expected_port, '-j', self.driver.chain),
|
||||||
('-F', self.driver.chain),
|
('-F', self.driver.chain),
|
||||||
('-X', self.driver.chain),
|
('-X', self.driver.chain),
|
||||||
('-E', self.driver.new_chain, self.driver.chain)
|
('-E', self.driver.new_chain, self.driver.chain)
|
||||||
|
@ -247,6 +272,24 @@ class TestIptablesDriver(test_base.NodeTest):
|
||||||
self.assertEqual(args, call[0], 'idx: %s' % idx)
|
self.assertEqual(args, call[0], 'idx: %s' % idx)
|
||||||
self.mock__get_blacklist.assert_called_once_with(self.mock_ironic)
|
self.mock__get_blacklist.assert_called_once_with(self.mock_ironic)
|
||||||
|
|
||||||
|
def test__iptables_clean_cache_on_error_ipv4(self):
|
||||||
|
CONF.set_override('ip_version', '4', 'iptables')
|
||||||
|
self._test__iptables_clean_cache_on_error('67')
|
||||||
|
|
||||||
|
def test__iptables_clean_cache_on_error_ipv6(self):
|
||||||
|
CONF.set_override('ip_version', '6', 'iptables')
|
||||||
|
self._test__iptables_clean_cache_on_error('547')
|
||||||
|
|
||||||
|
def test_iptables_command_ipv4(self):
|
||||||
|
CONF.set_override('ip_version', '4', 'iptables')
|
||||||
|
driver = iptables.IptablesFilter()
|
||||||
|
self.assertEqual(driver._cmd_iptables, 'iptables')
|
||||||
|
|
||||||
|
def test_iptables_command_ipv6(self):
|
||||||
|
CONF.set_override('ip_version', '6', 'iptables')
|
||||||
|
driver = iptables.IptablesFilter()
|
||||||
|
self.assertEqual(driver._cmd_iptables, 'ip6tables')
|
||||||
|
|
||||||
|
|
||||||
class Test_ShouldEnableDhcp(test_base.BaseTest):
|
class Test_ShouldEnableDhcp(test_base.BaseTest):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Adds a configuration option ``[iptables]ip_version`` to specify the
|
||||||
|
desired ip version for the iptables pxe filter, possible values are ``4``
|
||||||
|
and ``6``, the default value is ``4``. When set to ``6``, the iptables
|
||||||
|
pxe filter will use ``ip6tables`` command to manage rules for the DHCPv6
|
||||||
|
port ``547``.
|
|
@ -2,8 +2,9 @@
|
||||||
|
|
||||||
[Filters]
|
[Filters]
|
||||||
# ironic-inspector-rootwrap command filters for firewall manipulation
|
# ironic-inspector-rootwrap command filters for firewall manipulation
|
||||||
# ironic_inspector/firewall.py
|
# ironic_inspector/pxe_filter/iptables.py
|
||||||
iptables: CommandFilter, iptables, root
|
iptables: CommandFilter, iptables, root
|
||||||
|
ip6tables: CommandFilter, ip6tables, root
|
||||||
|
|
||||||
# ironic-inspector-rootwrap command filters for systemctl manipulation of the dnsmasq service
|
# ironic-inspector-rootwrap command filters for systemctl manipulation of the dnsmasq service
|
||||||
# ironic_inspector/pxe_filter/dnsmasq.py
|
# ironic_inspector/pxe_filter/dnsmasq.py
|
||||||
|
|
Loading…
Reference in New Issue