diff --git a/changelogs/fragments/iptables_match_set_flag.yml b/changelogs/fragments/iptables_match_set_flag.yml new file mode 100644 index 00000000000..39e7bc14022 --- /dev/null +++ b/changelogs/fragments/iptables_match_set_flag.yml @@ -0,0 +1,3 @@ +--- +bugfixes: + - iptables - add option choices 'src,src' and 'dst,dst' in match_set_flags (https://github.com/ansible/ansible/issues/81281). diff --git a/lib/ansible/modules/iptables.py b/lib/ansible/modules/iptables.py index 36ce1bc995b..b7fd778df91 100644 --- a/lib/ansible/modules/iptables.py +++ b/lib/ansible/modules/iptables.py @@ -301,7 +301,7 @@ options: match_set: description: - Specifies a set name that can be defined by ipset. - - Must be used together with the match_set_flags parameter. + - Must be used together with the O(match_set_flags) parameter. - When the V(!) argument is prepended then it inverts the rule. - Uses the iptables set extension. type: str @@ -309,10 +309,11 @@ options: match_set_flags: description: - Specifies the necessary flags for the match_set parameter. - - Must be used together with the match_set parameter. + - Must be used together with the O(match_set) parameter. - Uses the iptables set extension. + - Choices V(dst,dst) and V(src,src) added in version 2.17. type: str - choices: [ "src", "dst", "src,dst", "dst,src" ] + choices: [ "src", "dst", "src,dst", "dst,src", "dst,dst", "src,src" ] version_added: "2.11" limit: description: @@ -820,7 +821,10 @@ def main(): src_range=dict(type='str'), dst_range=dict(type='str'), match_set=dict(type='str'), - match_set_flags=dict(type='str', choices=['src', 'dst', 'src,dst', 'dst,src']), + match_set_flags=dict( + type='str', + choices=['src', 'dst', 'src,dst', 'dst,src', 'src,src', 'dst,dst'] + ), limit=dict(type='str'), limit_burst=dict(type='str'), uid_owner=dict(type='str'), diff --git a/test/units/modules/test_iptables.py b/test/units/modules/test_iptables.py index 78062c17f91..71e25f4a1ed 100644 --- a/test/units/modules/test_iptables.py +++ b/test/units/modules/test_iptables.py @@ -947,66 +947,71 @@ class TestIptables(ModuleTestCase): def test_match_set(self): """ Test match_set together with match_set_flags """ - set_module_args({ - 'chain': 'INPUT', - 'protocol': 'tcp', - 'match_set': 'admin_hosts', - 'match_set_flags': 'src', - 'destination_port': '22', - 'jump': 'ACCEPT', - 'comment': 'this is a comment', - }) - commands_results = [ - (0, '', ''), + tests = [ + [ + { + "chain": "INPUT", + "protocol": "tcp", + "match_set": "admin_hosts", + "match_set_flags": "src", + "destination_port": "22", + "jump": "ACCEPT", + "comment": "this is a comment", + }, + [ + "/sbin/iptables", "-t", "filter", + "-C", "INPUT", "-p", "tcp", + "-j", "ACCEPT", "--destination-port", "22", + "-m", "set", "--match-set", "admin_hosts", + "src", "-m", "comment", "--comment", "this is a comment", + ], + ], + [ + { + "chain": "INPUT", + "protocol": "udp", + "match_set": "banned_hosts", + "match_set_flags": "src,dst", + "jump": "REJECT", + }, + [ + "/sbin/iptables", "-t", "filter", + "-C", "INPUT", "-p", "udp", + "-j", "REJECT", "-m", "set", + "--match-set", "banned_hosts", "src,dst", + ], + ], + [ + { + "chain": "INPUT", + "protocol": "udp", + "match_set": "banned_hosts", + "match_set_flags": "src,src", + "jump": "REJECT", + }, + [ + "/sbin/iptables", "-t", "filter", + "-C", "INPUT", "-p", "udp", + "-j", "REJECT", "-m", "set", + "--match-set", "banned_hosts", "src,src", + ], + ], ] - with patch.object(basic.AnsibleModule, 'run_command') as run_command: - run_command.side_effect = commands_results - with self.assertRaises(AnsibleExitJson) as result: - iptables.main() - self.assertTrue(result.exception.args[0]['changed']) - - self.assertEqual(run_command.call_count, 1) - self.assertEqual(run_command.call_args_list[0][0][0], [ - '/sbin/iptables', - '-t', 'filter', - '-C', 'INPUT', - '-p', 'tcp', - '-j', 'ACCEPT', - '--destination-port', '22', - '-m', 'set', - '--match-set', 'admin_hosts', 'src', - '-m', 'comment', - '--comment', 'this is a comment' - ]) - - set_module_args({ - 'chain': 'INPUT', - 'protocol': 'udp', - 'match_set': 'banned_hosts', - 'match_set_flags': 'src,dst', - 'jump': 'REJECT', - }) - commands_results = [ - (0, '', ''), - ] + for test in tests: + set_module_args(test[0]) + commands_results = [ + (0, '', ''), + ] - with patch.object(basic.AnsibleModule, 'run_command') as run_command: - run_command.side_effect = commands_results - with self.assertRaises(AnsibleExitJson) as result: - iptables.main() - self.assertTrue(result.exception.args[0]['changed']) + with patch.object(basic.AnsibleModule, 'run_command') as run_command: + run_command.side_effect = commands_results + with self.assertRaises(AnsibleExitJson) as result: + iptables.main() + self.assertTrue(result.exception.args[0]['changed']) - self.assertEqual(run_command.call_count, 1) - self.assertEqual(run_command.call_args_list[0][0][0], [ - '/sbin/iptables', - '-t', 'filter', - '-C', 'INPUT', - '-p', 'udp', - '-j', 'REJECT', - '-m', 'set', - '--match-set', 'banned_hosts', 'src,dst' - ]) + self.assertEqual(run_command.call_count, 1) + self.assertEqual(run_command.call_args_list[0][0][0], test[1]) def test_chain_creation(self): """Test chain creation when absent"""