mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-04-30 07:28:52 +00:00
Reformat everything.
This commit is contained in:
parent
3f2213791a
commit
340ff8586d
1008 changed files with 61301 additions and 58309 deletions
|
|
@ -319,41 +319,47 @@ def compile_ipv6_regexp():
|
|||
|
||||
|
||||
def main():
|
||||
command_keys = ['state', 'default', 'rule', 'logging']
|
||||
command_keys = ["state", "default", "rule", "logging"]
|
||||
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
state=dict(type='str', choices=['enabled', 'disabled', 'reloaded', 'reset']),
|
||||
default=dict(type='str', aliases=['policy'], choices=['allow', 'deny', 'reject']),
|
||||
logging=dict(type='str', choices=['full', 'high', 'low', 'medium', 'off', 'on']),
|
||||
direction=dict(type='str', choices=['in', 'incoming', 'out', 'outgoing', 'routed']),
|
||||
delete=dict(type='bool', default=False),
|
||||
route=dict(type='bool', default=False),
|
||||
insert=dict(type='int'),
|
||||
insert_relative_to=dict(choices=['zero', 'first-ipv4', 'last-ipv4', 'first-ipv6', 'last-ipv6'], default='zero'),
|
||||
rule=dict(type='str', choices=['allow', 'deny', 'limit', 'reject']),
|
||||
interface=dict(type='str', aliases=['if']),
|
||||
interface_in=dict(type='str', aliases=['if_in']),
|
||||
interface_out=dict(type='str', aliases=['if_out']),
|
||||
log=dict(type='bool', default=False),
|
||||
from_ip=dict(type='str', default='any', aliases=['from', 'src']),
|
||||
from_port=dict(type='str'),
|
||||
to_ip=dict(type='str', default='any', aliases=['dest', 'to']),
|
||||
to_port=dict(type='str', aliases=['port']),
|
||||
proto=dict(type='str', aliases=['protocol'], choices=['ah', 'any', 'esp', 'ipv6', 'tcp', 'udp', 'gre', 'igmp', 'vrrp']),
|
||||
name=dict(type='str', aliases=['app']),
|
||||
comment=dict(type='str'),
|
||||
state=dict(type="str", choices=["enabled", "disabled", "reloaded", "reset"]),
|
||||
default=dict(type="str", aliases=["policy"], choices=["allow", "deny", "reject"]),
|
||||
logging=dict(type="str", choices=["full", "high", "low", "medium", "off", "on"]),
|
||||
direction=dict(type="str", choices=["in", "incoming", "out", "outgoing", "routed"]),
|
||||
delete=dict(type="bool", default=False),
|
||||
route=dict(type="bool", default=False),
|
||||
insert=dict(type="int"),
|
||||
insert_relative_to=dict(
|
||||
choices=["zero", "first-ipv4", "last-ipv4", "first-ipv6", "last-ipv6"], default="zero"
|
||||
),
|
||||
rule=dict(type="str", choices=["allow", "deny", "limit", "reject"]),
|
||||
interface=dict(type="str", aliases=["if"]),
|
||||
interface_in=dict(type="str", aliases=["if_in"]),
|
||||
interface_out=dict(type="str", aliases=["if_out"]),
|
||||
log=dict(type="bool", default=False),
|
||||
from_ip=dict(type="str", default="any", aliases=["from", "src"]),
|
||||
from_port=dict(type="str"),
|
||||
to_ip=dict(type="str", default="any", aliases=["dest", "to"]),
|
||||
to_port=dict(type="str", aliases=["port"]),
|
||||
proto=dict(
|
||||
type="str",
|
||||
aliases=["protocol"],
|
||||
choices=["ah", "any", "esp", "ipv6", "tcp", "udp", "gre", "igmp", "vrrp"],
|
||||
),
|
||||
name=dict(type="str", aliases=["app"]),
|
||||
comment=dict(type="str"),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
mutually_exclusive=[
|
||||
['name', 'proto', 'logging'],
|
||||
["name", "proto", "logging"],
|
||||
# Mutual exclusivity with `interface` implied by `required_by`.
|
||||
['direction', 'interface_in'],
|
||||
['direction', 'interface_out'],
|
||||
["direction", "interface_in"],
|
||||
["direction", "interface_out"],
|
||||
],
|
||||
required_one_of=([command_keys]),
|
||||
required_by=dict(
|
||||
interface=('direction', ),
|
||||
interface=("direction",),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -363,16 +369,16 @@ def main():
|
|||
ipv6_regexp = compile_ipv6_regexp()
|
||||
|
||||
def filter_line_that_not_start_with(pattern, content):
|
||||
return ''.join([line for line in content.splitlines(True) if line.startswith(pattern)])
|
||||
return "".join([line for line in content.splitlines(True) if line.startswith(pattern)])
|
||||
|
||||
def filter_line_that_contains(pattern, content):
|
||||
return [line for line in content.splitlines(True) if pattern in line]
|
||||
|
||||
def filter_line_that_not_contains(pattern, content):
|
||||
return ''.join([line for line in content.splitlines(True) if not line.contains(pattern)])
|
||||
return "".join([line for line in content.splitlines(True) if not line.contains(pattern)])
|
||||
|
||||
def filter_line_that_match_func(match_func, content):
|
||||
return ''.join([line for line in content.splitlines(True) if match_func(line) is not None])
|
||||
return "".join([line for line in content.splitlines(True) if match_func(line) is not None])
|
||||
|
||||
def filter_line_that_contains_ipv4(content):
|
||||
return filter_line_that_match_func(ipv4_regexp.search, content)
|
||||
|
|
@ -387,7 +393,7 @@ def main():
|
|||
return ipv6_regexp.match(ip) is not None
|
||||
|
||||
def execute(cmd, ignore_error=False):
|
||||
cmd = ' '.join(map(itemgetter(-1), filter(itemgetter(0), cmd)))
|
||||
cmd = " ".join(map(itemgetter(-1), filter(itemgetter(0), cmd)))
|
||||
|
||||
cmds.append(cmd)
|
||||
(rc, out, err) = module.run_command(cmd, environ_update={"LANG": "C"})
|
||||
|
|
@ -398,12 +404,14 @@ def main():
|
|||
return out
|
||||
|
||||
def get_current_rules():
|
||||
user_rules_files = ["/lib/ufw/user.rules",
|
||||
"/lib/ufw/user6.rules",
|
||||
"/etc/ufw/user.rules",
|
||||
"/etc/ufw/user6.rules",
|
||||
"/var/lib/ufw/user.rules",
|
||||
"/var/lib/ufw/user6.rules"]
|
||||
user_rules_files = [
|
||||
"/lib/ufw/user.rules",
|
||||
"/lib/ufw/user6.rules",
|
||||
"/etc/ufw/user.rules",
|
||||
"/etc/ufw/user6.rules",
|
||||
"/var/lib/ufw/user.rules",
|
||||
"/var/lib/ufw/user6.rules",
|
||||
]
|
||||
|
||||
cmd = [[grep_bin], ["-h"], ["'^### tuple'"]]
|
||||
|
||||
|
|
@ -416,11 +424,11 @@ def main():
|
|||
"""
|
||||
out = execute([[ufw_bin], ["--version"]])
|
||||
|
||||
lines = [x for x in out.split('\n') if x.strip() != '']
|
||||
lines = [x for x in out.split("\n") if x.strip() != ""]
|
||||
if len(lines) == 0:
|
||||
module.fail_json(msg="Failed to get ufw version.", rc=0, out=out)
|
||||
|
||||
matches = re.search(r'^ufw.+(\d+)\.(\d+)(?:\.(\d+))?.*$', lines[0])
|
||||
matches = re.search(r"^ufw.+(\d+)\.(\d+)(?:\.(\d+))?.*$", lines[0])
|
||||
if matches is None:
|
||||
module.fail_json(msg="Failed to get ufw version.", rc=0, out=out)
|
||||
|
||||
|
|
@ -438,37 +446,35 @@ def main():
|
|||
commands = {key: params[key] for key in command_keys if params[key]}
|
||||
|
||||
# Ensure ufw is available
|
||||
ufw_bin = module.get_bin_path('ufw', True)
|
||||
grep_bin = module.get_bin_path('grep', True)
|
||||
ufw_bin = module.get_bin_path("ufw", True)
|
||||
grep_bin = module.get_bin_path("grep", True)
|
||||
|
||||
# Save the pre state and rules in order to recognize changes
|
||||
pre_state = execute([[ufw_bin], ['status verbose']])
|
||||
pre_state = execute([[ufw_bin], ["status verbose"]])
|
||||
pre_rules = get_current_rules()
|
||||
|
||||
changed = False
|
||||
|
||||
# Execute filter
|
||||
for (command, value) in commands.items():
|
||||
for command, value in commands.items():
|
||||
cmd = [[ufw_bin], [module.check_mode, "--dry-run"]]
|
||||
|
||||
cmd = [[ufw_bin], [module.check_mode, '--dry-run']]
|
||||
if command == "state":
|
||||
states = {"enabled": "enable", "disabled": "disable", "reloaded": "reload", "reset": "reset"}
|
||||
|
||||
if command == 'state':
|
||||
states = {'enabled': 'enable', 'disabled': 'disable',
|
||||
'reloaded': 'reload', 'reset': 'reset'}
|
||||
|
||||
if value in ['reloaded', 'reset']:
|
||||
if value in ["reloaded", "reset"]:
|
||||
changed = True
|
||||
|
||||
if module.check_mode:
|
||||
# "active" would also match "inactive", hence the space
|
||||
ufw_enabled = pre_state.find(" active") != -1
|
||||
if (value == 'disabled' and ufw_enabled) or (value == 'enabled' and not ufw_enabled):
|
||||
if (value == "disabled" and ufw_enabled) or (value == "enabled" and not ufw_enabled):
|
||||
changed = True
|
||||
else:
|
||||
execute(cmd + [['-f'], [states[value]]])
|
||||
execute(cmd + [["-f"], [states[value]]])
|
||||
|
||||
elif command == 'logging':
|
||||
extract = re.search(r'Logging: (on|off)(?: \(([a-z]+)\))?', pre_state)
|
||||
elif command == "logging":
|
||||
extract = re.search(r"Logging: (on|off)(?: \(([a-z]+)\))?", pre_state)
|
||||
if extract:
|
||||
current_level = extract.group(2)
|
||||
current_on_off_value = extract.group(1)
|
||||
|
|
@ -485,96 +491,102 @@ def main():
|
|||
if not module.check_mode:
|
||||
execute(cmd + [[command], [value]])
|
||||
|
||||
elif command == 'default':
|
||||
if params['direction'] not in ['outgoing', 'incoming', 'routed', None]:
|
||||
module.fail_json(msg='For default, direction must be one of "outgoing", "incoming" and "routed", or direction must not be specified.')
|
||||
elif command == "default":
|
||||
if params["direction"] not in ["outgoing", "incoming", "routed", None]:
|
||||
module.fail_json(
|
||||
msg='For default, direction must be one of "outgoing", "incoming" and "routed", or direction must not be specified.'
|
||||
)
|
||||
if module.check_mode:
|
||||
regexp = r'Default: (deny|allow|reject) \(incoming\), (deny|allow|reject) \(outgoing\), (deny|allow|reject|disabled) \(routed\)'
|
||||
regexp = r"Default: (deny|allow|reject) \(incoming\), (deny|allow|reject) \(outgoing\), (deny|allow|reject|disabled) \(routed\)"
|
||||
extract = re.search(regexp, pre_state)
|
||||
if extract is not None:
|
||||
current_default_values = {}
|
||||
current_default_values["incoming"] = extract.group(1)
|
||||
current_default_values["outgoing"] = extract.group(2)
|
||||
current_default_values["routed"] = extract.group(3)
|
||||
v = current_default_values[params['direction'] or 'incoming']
|
||||
if v not in (value, 'disabled'):
|
||||
v = current_default_values[params["direction"] or "incoming"]
|
||||
if v not in (value, "disabled"):
|
||||
changed = True
|
||||
else:
|
||||
changed = True
|
||||
else:
|
||||
execute(cmd + [[command], [value], [params['direction']]])
|
||||
execute(cmd + [[command], [value], [params["direction"]]])
|
||||
|
||||
elif command == 'rule':
|
||||
if params['direction'] not in ['in', 'out', None]:
|
||||
module.fail_json(msg='For rules, direction must be one of "in" and "out", or direction must not be specified.')
|
||||
if not params['route'] and params['interface_in'] and params['interface_out']:
|
||||
module.fail_json(msg='Only route rules can combine '
|
||||
'interface_in and interface_out')
|
||||
elif command == "rule":
|
||||
if params["direction"] not in ["in", "out", None]:
|
||||
module.fail_json(
|
||||
msg='For rules, direction must be one of "in" and "out", or direction must not be specified.'
|
||||
)
|
||||
if not params["route"] and params["interface_in"] and params["interface_out"]:
|
||||
module.fail_json(msg="Only route rules can combine interface_in and interface_out")
|
||||
# Rules are constructed according to the long format
|
||||
#
|
||||
# ufw [--dry-run] [route] [delete | insert NUM] allow|deny|reject|limit [in|out on INTERFACE] [log|log-all] \
|
||||
# [from ADDRESS [port PORT]] [to ADDRESS [port PORT]] \
|
||||
# [proto protocol] [app application] [comment COMMENT]
|
||||
cmd.append([module.boolean(params['route']), 'route'])
|
||||
cmd.append([module.boolean(params['delete']), 'delete'])
|
||||
if params['insert'] is not None and not params['delete']:
|
||||
relative_to_cmd = params['insert_relative_to']
|
||||
if relative_to_cmd == 'zero':
|
||||
insert_to = params['insert']
|
||||
cmd.append([module.boolean(params["route"]), "route"])
|
||||
cmd.append([module.boolean(params["delete"]), "delete"])
|
||||
if params["insert"] is not None and not params["delete"]:
|
||||
relative_to_cmd = params["insert_relative_to"]
|
||||
if relative_to_cmd == "zero":
|
||||
insert_to = params["insert"]
|
||||
else:
|
||||
(dummy, numbered_state, dummy) = module.run_command([ufw_bin, 'status', 'numbered'])
|
||||
numbered_line_re = re.compile(R'^\[ *([0-9]+)\] ')
|
||||
lines = [(numbered_line_re.match(line), '(v6)' in line) for line in numbered_state.splitlines()]
|
||||
(dummy, numbered_state, dummy) = module.run_command([ufw_bin, "status", "numbered"])
|
||||
numbered_line_re = re.compile(R"^\[ *([0-9]+)\] ")
|
||||
lines = [(numbered_line_re.match(line), "(v6)" in line) for line in numbered_state.splitlines()]
|
||||
lines = [(int(matcher.group(1)), ipv6) for (matcher, ipv6) in lines if matcher]
|
||||
last_number = max([no for (no, ipv6) in lines]) if lines else 0
|
||||
has_ipv4 = any(not ipv6 for (no, ipv6) in lines)
|
||||
has_ipv6 = any(ipv6 for (no, ipv6) in lines)
|
||||
if relative_to_cmd == 'first-ipv4':
|
||||
if relative_to_cmd == "first-ipv4":
|
||||
relative_to = 1
|
||||
elif relative_to_cmd == 'last-ipv4':
|
||||
elif relative_to_cmd == "last-ipv4":
|
||||
relative_to = max([no for (no, ipv6) in lines if not ipv6]) if has_ipv4 else 1
|
||||
elif relative_to_cmd == 'first-ipv6':
|
||||
elif relative_to_cmd == "first-ipv6":
|
||||
relative_to = max([no for (no, ipv6) in lines if not ipv6]) + 1 if has_ipv4 else 1
|
||||
elif relative_to_cmd == 'last-ipv6':
|
||||
elif relative_to_cmd == "last-ipv6":
|
||||
relative_to = last_number if has_ipv6 else last_number + 1
|
||||
insert_to = params['insert'] + relative_to
|
||||
insert_to = params["insert"] + relative_to
|
||||
if insert_to > last_number:
|
||||
# ufw does not like it when the insert number is larger than the
|
||||
# maximal rule number for IPv4/IPv6.
|
||||
insert_to = None
|
||||
cmd.append([insert_to is not None, f"insert {insert_to}"])
|
||||
cmd.append([value])
|
||||
cmd.append([params['direction'], params['direction']])
|
||||
cmd.append([params['interface'], f"on {params['interface']}"])
|
||||
cmd.append([params['interface_in'], f"in on {params['interface_in']}"])
|
||||
cmd.append([params['interface_out'], f"out on {params['interface_out']}"])
|
||||
cmd.append([module.boolean(params['log']), 'log'])
|
||||
cmd.append([params["direction"], params["direction"]])
|
||||
cmd.append([params["interface"], f"on {params['interface']}"])
|
||||
cmd.append([params["interface_in"], f"in on {params['interface_in']}"])
|
||||
cmd.append([params["interface_out"], f"out on {params['interface_out']}"])
|
||||
cmd.append([module.boolean(params["log"]), "log"])
|
||||
|
||||
for (key, template) in [('from_ip', "from %s"), ('from_port', "port %s"),
|
||||
('to_ip', "to %s"), ('to_port', "port %s"),
|
||||
('proto', "proto %s"), ('name', "app '%s'")]:
|
||||
for key, template in [
|
||||
("from_ip", "from %s"),
|
||||
("from_port", "port %s"),
|
||||
("to_ip", "to %s"),
|
||||
("to_port", "port %s"),
|
||||
("proto", "proto %s"),
|
||||
("name", "app '%s'"),
|
||||
]:
|
||||
value = params[key]
|
||||
cmd.append([value, template % (value)])
|
||||
|
||||
ufw_major, ufw_minor, dummy = ufw_version()
|
||||
# comment is supported only in ufw version after 0.35
|
||||
if (ufw_major == 0 and ufw_minor >= 35) or ufw_major > 0:
|
||||
cmd.append([params['comment'], f"comment '{params['comment']}'"])
|
||||
cmd.append([params["comment"], f"comment '{params['comment']}'"])
|
||||
|
||||
rules_dry = execute(cmd)
|
||||
|
||||
if module.check_mode:
|
||||
|
||||
nb_skipping_line = len(filter_line_that_contains("Skipping", rules_dry))
|
||||
|
||||
if not (nb_skipping_line > 0 and nb_skipping_line == len(rules_dry.splitlines(True))):
|
||||
|
||||
rules_dry = filter_line_that_not_start_with("### tuple", rules_dry)
|
||||
# ufw dry-run doesn't send all rules so have to compare ipv4 or ipv6 rules
|
||||
if is_starting_by_ipv4(params['from_ip']) or is_starting_by_ipv4(params['to_ip']):
|
||||
if is_starting_by_ipv4(params["from_ip"]) or is_starting_by_ipv4(params["to_ip"]):
|
||||
if filter_line_that_contains_ipv4(pre_rules) != filter_line_that_contains_ipv4(rules_dry):
|
||||
changed = True
|
||||
elif is_starting_by_ipv6(params['from_ip']) or is_starting_by_ipv6(params['to_ip']):
|
||||
elif is_starting_by_ipv6(params["from_ip"]) or is_starting_by_ipv6(params["to_ip"]):
|
||||
if filter_line_that_contains_ipv6(pre_rules) != filter_line_that_contains_ipv6(rules_dry):
|
||||
changed = True
|
||||
elif pre_rules != rules_dry:
|
||||
|
|
@ -584,12 +596,12 @@ def main():
|
|||
if module.check_mode:
|
||||
return module.exit_json(changed=changed, commands=cmds)
|
||||
else:
|
||||
post_state = execute([[ufw_bin], ['status'], ['verbose']])
|
||||
post_state = execute([[ufw_bin], ["status"], ["verbose"]])
|
||||
if not changed:
|
||||
post_rules = get_current_rules()
|
||||
changed = (pre_state != post_state) or (pre_rules != post_rules)
|
||||
return module.exit_json(changed=changed, commands=cmds, msg=post_state.rstrip())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue