1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2026-04-28 22:49:00 +00:00

Reformat everything.

This commit is contained in:
Felix Fontein 2025-11-01 12:08:41 +01:00
parent 3f2213791a
commit 340ff8586d
1008 changed files with 61301 additions and 58309 deletions

View file

@ -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()