Browse Source

Merge "Support ip6tables for iptables pxe filter"

Zuul 5 months ago
parent
commit
7e63503ebe

+ 6
- 0
ironic_inspector/conf/iptables.py View File

@@ -34,6 +34,12 @@ _OPTS = [
34 34
                        'which are not in desired state are going to be '
35 35
                        'blacklisted based on the list of neighbor MACs '
36 36
                        'on these interfaces.')),
37
+    cfg.StrOpt('ip_version',
38
+               default='4',
39
+               choices=[('4', _('IPv4')),
40
+                        ('6', _('IPv6'))],
41
+               help=_('The IP version that will be used for iptables filter. '
42
+                      'Defaults to 4.')),
37 43
 ]
38 44
 
39 45
 

+ 14
- 4
ironic_inspector/pxe_filter/iptables.py View File

@@ -50,8 +50,18 @@ class IptablesFilter(pxe_filter.BaseFilter):
50 50
         self.interface = CONF.iptables.dnsmasq_interface
51 51
         self.chain = CONF.iptables.firewall_chain
52 52
         self.new_chain = self.chain + '_temp'
53
+
54
+        # Determine arguments used for pxe filtering, we only support 4 and 6
55
+        # at this time.
56
+        if CONF.iptables.ip_version == '4':
57
+            self._cmd_iptables = 'iptables'
58
+            self._dhcp_port = '67'
59
+        else:
60
+            self._cmd_iptables = 'ip6tables'
61
+            self._dhcp_port = '547'
62
+
53 63
         self.base_command = ('sudo', 'ironic-inspector-rootwrap',
54
-                             CONF.rootwrap_config, 'iptables')
64
+                             CONF.rootwrap_config, self._cmd_iptables)
55 65
 
56 66
     def reset(self):
57 67
         self.enabled = True
@@ -137,9 +147,9 @@ class IptablesFilter(pxe_filter.BaseFilter):
137 147
 
138 148
         # Swap chains
139 149
         self._iptables('-I', 'INPUT', '-i', self.interface, '-p', 'udp',
140
-                       '--dport', '67', '-j', chain)
150
+                       '--dport', self._dhcp_port, '-j', chain)
141 151
         self._iptables('-D', 'INPUT', '-i', self.interface, '-p', 'udp',
142
-                       '--dport', '67', '-j', main_chain,
152
+                       '--dport', self._dhcp_port, '-j', main_chain,
143 153
                        ignore=True)
144 154
         self._iptables('-F', main_chain, ignore=True)
145 155
         self._iptables('-X', main_chain, ignore=True)
@@ -163,7 +173,7 @@ class IptablesFilter(pxe_filter.BaseFilter):
163 173
 
164 174
     def _clean_up(self, chain):
165 175
         self._iptables('-D', 'INPUT', '-i', self.interface, '-p', 'udp',
166
-                       '--dport', '67', '-j', chain,
176
+                       '--dport', self._dhcp_port, '-j', chain,
167 177
                        ignore=True)
168 178
         self._iptables('-F', chain, ignore=True)
169 179
         self._iptables('-X', chain, ignore=True)

+ 55
- 12
ironic_inspector/test/unit/test_iptables.py View File

@@ -114,20 +114,23 @@ class TestIptablesDriver(test_base.NodeTest):
114 114
         self.assertRaisesRegex(MyError, 'Oops!', self.driver.init_filter)
115 115
         self.check_fsm([pxe_filter.Events.initialize, pxe_filter.Events.reset])
116 116
 
117
-    def test__iptables_args(self):
117
+    def _test__iptables_args(self, expected_port):
118
+        self.driver = iptables.IptablesFilter()
119
+        self.mock_iptables = self.useFixture(
120
+            fixtures.MockPatchObject(self.driver, '_iptables')).mock
118 121
         self.mock_should_enable_dhcp.return_value = True
119 122
 
120 123
         _iptables_expected_args = [
121 124
             ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
122
-             '67', '-j', self.driver.new_chain),
125
+             expected_port, '-j', self.driver.new_chain),
123 126
             ('-F', self.driver.new_chain),
124 127
             ('-X', self.driver.new_chain),
125 128
             ('-N', self.driver.new_chain),
126 129
             ('-A', self.driver.new_chain, '-j', 'ACCEPT'),
127 130
             ('-I', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
128
-             '67', '-j', self.driver.new_chain),
131
+             expected_port, '-j', self.driver.new_chain),
129 132
             ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
130
-             '67', '-j', self.driver.chain),
133
+             expected_port, '-j', self.driver.chain),
131 134
             ('-F', self.driver.chain),
132 135
             ('-X', self.driver.chain),
133 136
             ('-E', self.driver.new_chain, self.driver.chain)
@@ -142,6 +145,14 @@ class TestIptablesDriver(test_base.NodeTest):
142 145
         self.mock__get_blacklist.assert_called_once_with(self.mock_ironic)
143 146
         self.check_fsm([pxe_filter.Events.sync])
144 147
 
148
+    def test__iptables_args_ipv4(self):
149
+        CONF.set_override('ip_version', '4', 'iptables')
150
+        self._test__iptables_args('67')
151
+
152
+    def test__iptables_args_ipv6(self):
153
+        CONF.set_override('ip_version', '6', 'iptables')
154
+        self._test__iptables_args('547')
155
+
145 156
     def test__iptables_kwargs(self):
146 157
         _iptables_expected_kwargs = [
147 158
             {'ignore': True},
@@ -163,13 +174,16 @@ class TestIptablesDriver(test_base.NodeTest):
163 174
             self.assertEqual(kwargs, call[1])
164 175
         self.check_fsm([pxe_filter.Events.sync])
165 176
 
166
-    def test_sync_with_blacklist(self):
177
+    def _test_sync_with_blacklist(self, expected_port):
178
+        self.driver = iptables.IptablesFilter()
179
+        self.mock_iptables = self.useFixture(
180
+            fixtures.MockPatchObject(self.driver, '_iptables')).mock
167 181
         self.mock__get_blacklist.return_value = ['AA:BB:CC:DD:EE:FF']
168 182
         self.mock_should_enable_dhcp.return_value = True
169 183
 
170 184
         _iptables_expected_args = [
171 185
             ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
172
-             '67', '-j', self.driver.new_chain),
186
+             expected_port, '-j', self.driver.new_chain),
173 187
             ('-F', self.driver.new_chain),
174 188
             ('-X', self.driver.new_chain),
175 189
             ('-N', self.driver.new_chain),
@@ -178,9 +192,9 @@ class TestIptablesDriver(test_base.NodeTest):
178 192
              self.mock__get_blacklist.return_value[0], '-j', 'DROP'),
179 193
             ('-A', self.driver.new_chain, '-j', 'ACCEPT'),
180 194
             ('-I', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
181
-             '67', '-j', self.driver.new_chain),
195
+             expected_port, '-j', self.driver.new_chain),
182 196
             ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
183
-             '67', '-j', self.driver.chain),
197
+             expected_port, '-j', self.driver.chain),
184 198
             ('-F', self.driver.chain),
185 199
             ('-X', self.driver.chain),
186 200
             ('-E', self.driver.new_chain, self.driver.chain)
@@ -203,7 +217,18 @@ class TestIptablesDriver(test_base.NodeTest):
203 217
         self.mock__get_blacklist.assert_called_once_with(self.mock_ironic)
204 218
         self.assertFalse(self.mock_iptables.called)
205 219
 
206
-    def test__iptables_clean_cache_on_error(self):
220
+    def test_sync_with_blacklist_ipv4(self):
221
+        CONF.set_override('ip_version', '4', 'iptables')
222
+        self._test_sync_with_blacklist('67')
223
+
224
+    def test_sync_with_blacklist_ipv6(self):
225
+        CONF.set_override('ip_version', '6', 'iptables')
226
+        self._test_sync_with_blacklist('547')
227
+
228
+    def _test__iptables_clean_cache_on_error(self, expected_port):
229
+        self.driver = iptables.IptablesFilter()
230
+        self.mock_iptables = self.useFixture(
231
+            fixtures.MockPatchObject(self.driver, '_iptables')).mock
207 232
         self.mock__get_blacklist.return_value = ['AA:BB:CC:DD:EE:FF']
208 233
         self.mock_should_enable_dhcp.return_value = True
209 234
 
@@ -217,7 +242,7 @@ class TestIptablesDriver(test_base.NodeTest):
217 242
         syncs_expected_args = [
218 243
             # driver reset
219 244
             ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
220
-             '67', '-j', self.driver.new_chain),
245
+             expected_port, '-j', self.driver.new_chain),
221 246
             ('-F', self.driver.new_chain),
222 247
             ('-X', self.driver.new_chain),
223 248
             ('-N', self.driver.new_chain),
@@ -226,9 +251,9 @@ class TestIptablesDriver(test_base.NodeTest):
226 251
              self.mock__get_blacklist.return_value[0], '-j', 'DROP'),
227 252
             ('-A', self.driver.new_chain, '-j', 'ACCEPT'),
228 253
             ('-I', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
229
-             '67', '-j', self.driver.new_chain),
254
+             expected_port, '-j', self.driver.new_chain),
230 255
             ('-D', 'INPUT', '-i', 'br-ctlplane', '-p', 'udp', '--dport',
231
-             '67', '-j', self.driver.chain),
256
+             expected_port, '-j', self.driver.chain),
232 257
             ('-F', self.driver.chain),
233 258
             ('-X', self.driver.chain),
234 259
             ('-E', self.driver.new_chain, self.driver.chain)
@@ -247,6 +272,24 @@ class TestIptablesDriver(test_base.NodeTest):
247 272
             self.assertEqual(args, call[0], 'idx: %s' % idx)
248 273
         self.mock__get_blacklist.assert_called_once_with(self.mock_ironic)
249 274
 
275
+    def test__iptables_clean_cache_on_error_ipv4(self):
276
+        CONF.set_override('ip_version', '4', 'iptables')
277
+        self._test__iptables_clean_cache_on_error('67')
278
+
279
+    def test__iptables_clean_cache_on_error_ipv6(self):
280
+        CONF.set_override('ip_version', '6', 'iptables')
281
+        self._test__iptables_clean_cache_on_error('547')
282
+
283
+    def test_iptables_command_ipv4(self):
284
+        CONF.set_override('ip_version', '4', 'iptables')
285
+        driver = iptables.IptablesFilter()
286
+        self.assertEqual(driver._cmd_iptables, 'iptables')
287
+
288
+    def test_iptables_command_ipv6(self):
289
+        CONF.set_override('ip_version', '6', 'iptables')
290
+        driver = iptables.IptablesFilter()
291
+        self.assertEqual(driver._cmd_iptables, 'ip6tables')
292
+
250 293
 
251 294
 class Test_ShouldEnableDhcp(test_base.BaseTest):
252 295
     def setUp(self):

+ 8
- 0
releasenotes/notes/support-ip6tables-ce30f614de502adb.yaml View File

@@ -0,0 +1,8 @@
1
+---
2
+features:
3
+  - |
4
+    Adds a configuration option ``[iptables]ip_version`` to specify the
5
+    desired ip version for the iptables pxe filter, possible values are ``4``
6
+    and ``6``, the default value is ``4``. When set to ``6``, the iptables
7
+    pxe filter will use ``ip6tables`` command to manage rules for the DHCPv6
8
+    port ``547``.

+ 2
- 1
rootwrap.d/ironic-inspector.filters View File

@@ -2,8 +2,9 @@
2 2
 
3 3
 [Filters]
4 4
 # ironic-inspector-rootwrap command filters for firewall manipulation
5
-# ironic_inspector/firewall.py
5
+# ironic_inspector/pxe_filter/iptables.py
6 6
 iptables: CommandFilter, iptables, root
7
+ip6tables: CommandFilter, ip6tables, root
7 8
 
8 9
 # ironic-inspector-rootwrap command filters for systemctl manipulation of the dnsmasq service
9 10
 # ironic_inspector/pxe_filter/dnsmasq.py

Loading…
Cancel
Save