diff --git a/lib/ansible/modules/system/iptables.py b/lib/ansible/modules/system/iptables.py index 8489ec2f58..4352cd826d 100644 --- a/lib/ansible/modules/system/iptables.py +++ b/lib/ansible/modules/system/iptables.py @@ -156,6 +156,14 @@ options: - Specifies a log text for the rule. Only make sense with a LOG jump. type: str version_added: "2.5" + log_level: + description: + - Logging level according to the syslogd-defined priorities. + - The value can be strings or numbers from 1-8. + - This parameter is only applicable if C(jump) is set to C(LOG). + type: str + version_added: "2.8" + choices: [ '0', '1', '2', '3', '4', '5', '6', '7', 'emerg', 'alert', 'crit', 'error', 'warning', 'notice', 'info', 'debug' ] goto: description: - This specifies that the processing should continue in a user specified chain. @@ -413,6 +421,16 @@ EXAMPLES = r''' chain: '{{ item }}' flush: yes with_items: [ 'INPUT', 'OUTPUT', 'PREROUTING', 'POSTROUTING' ] + +- name: Log packets arriving into an user-defined chain + iptables: + chain: LOGGING + action: append + state: present + limit: 2/second + limit_burst: 20 + log_prefix: "IPTABLES:INFO: " + log_level: info ''' import re @@ -482,6 +500,7 @@ def construct_rule(params): if params.get('jump') and params['jump'].lower() == 'tee': append_param(rule, params['gateway'], '--gateway', False) append_param(rule, params['log_prefix'], '--log-prefix', False) + append_param(rule, params['log_level'], '--log-level', False) append_param(rule, params['to_destination'], '--to-destination', False) append_param(rule, params['to_source'], '--to-source', False) append_param(rule, params['goto'], '-g', False) @@ -602,6 +621,12 @@ def main(): jump=dict(type='str'), gateway=dict(type='str'), log_prefix=dict(type='str'), + log_level=dict(type='str', + choices=['0', '1', '2', '3', '4', '5', '6', '7', + 'emerg', 'alert', 'crit', 'error', + 'warning', 'notice', 'info', 'debug'], + default=None, + ), goto=dict(type='str'), in_interface=dict(type='str'), out_interface=dict(type='str'), @@ -650,6 +675,12 @@ def main(): if args['flush'] is False and args['chain'] is None: module.fail_json(msg="Either chain or flush parameter must be specified.") + if module.params.get('log_prefix', None) or module.params.get('log_level', None): + if module.params['jump'] is None: + module.params['jump'] = 'LOG' + elif module.params['jump'] != 'LOG': + module.fail_json(msg="Logging options can only be used with the LOG jump target.") + # Flush the table if args['flush'] is True: args['changed'] = True diff --git a/test/units/modules/system/test_iptables.py b/test/units/modules/system/test_iptables.py index dae3c1d2f0..d82beb089f 100644 --- a/test/units/modules/system/test_iptables.py +++ b/test/units/modules/system/test_iptables.py @@ -694,3 +694,38 @@ class TestIptables(ModuleTestCase): '-j', 'DROP' ]) + + def test_log_level(self): + """ Test various ways of log level flag """ + + log_levels = ['0', '1', '2', '3', '4', '5', '6', '7', + 'emerg', 'alert', 'crit', 'error', 'warning', 'notice', 'info', 'debug'] + + for log_lvl in log_levels: + set_module_args({ + 'chain': 'INPUT', + 'jump': 'LOG', + 'log_level': log_lvl, + 'source': '1.2.3.4/32', + 'log_prefix': '** DROP-this_ip **' + }) + 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']) + + self.assertEqual(run_command.call_count, 1) + self.assertEqual(run_command.call_args_list[0][0][0], [ + '/sbin/iptables', + '-t', 'filter', + '-C', 'INPUT', + '-s', '1.2.3.4/32', + '-j', 'LOG', + '--log-prefix', '** DROP-this_ip **', + '--log-level', log_lvl + ])