mirror of
https://github.com/ansible-collections/ansible.posix.git
synced 2026-06-09 18:15:54 +00:00
Fix all deprecated module_utils imports before ansible-core 2.24 removal
SUMMARY
Fixes all deprecated ansible.module_utils imports across the entire collection that will be removed in ansible-core 2.24.
This PR comprehensively addresses deprecation warnings reported in #686 by updating import statements in 20 files to use the new recommended import paths, and removes 8 unused test utility files that contained deprecated imports.
Deprecated imports replaced:
Deprecated import
Replacement
ansible.module_utils._text
ansible.module_utils.common.text.converters
ansible.module_utils.common._collections_compat
collections.abc
ansible.module_utils.six.moves.shlex_quote
shlex.quote
ansible.module_utils.six.moves.reduce
functools.reduce
ansible.module_utils.six.moves.urllib.parse.urlparse
urllib.parse.urlparse
ansible.module_utils.six.string_types
basestring/str (Python 2/3 compatible)
ansible.module_utils.six.text_type
str
ansible.module_utils.six.PY3
Removed (simplified Python 2/3 conditionals)
ansible.module_utils.six.with_metaclass
Native metaclass= syntax
ansible.module_utils.six.iteritems
dict.items()
Files fixed (20 files, 1 commit per file for easier review):
plugins/action/patch.py
plugins/action/synchronize.py
plugins/callback/cgroup_perf_recap.py
plugins/callback/json.py
plugins/callback/jsonl.py
plugins/callback/profile_roles.py
plugins/callback/profile_tasks.py
plugins/modules/acl.py
plugins/modules/authorized_key.py
plugins/modules/firewalld_info.py
plugins/modules/mount.py
plugins/modules/patch.py
plugins/modules/rhel_rpm_ostree.py
plugins/modules/rpm_ostree_upgrade.py
plugins/modules/seboolean.py
plugins/modules/synchronize.py
plugins/modules/sysctl.py
plugins/shell/csh.py
plugins/shell/fish.py
tests/unit/modules/system/test_mount.py
Files deleted (8 unused test utility files):
These files are dead code - none of them are imported or used anywhere in the test suite or the collection. Removing them also addresses Python 2.7 compatibility concerns raised in code review, as several contained deprecated imports that would be incorrect to fix for Python 2.
tests/unit/compat/builtins.py
tests/unit/mock/loader.py
tests/unit/mock/path.py
tests/unit/mock/procenv.py
tests/unit/mock/vault_helper.py
tests/unit/mock/yaml_helper.py
tests/unit/modules/conftest.py
tests/unit/modules/utils.py
Completeness verified with:
git grep -n -P '_compat|utils._text|utils.six' -- '*.py' | grep -v yml
This command returns no results, confirming all deprecated imports have been replaced.
Notes on Python 2.7 compatibility:
For modules that may run on Python 2.7 managed hosts (e.g., authorized_key.py, synchronize.py, sysctl.py), Python 2/3 compatible fallbacks were used instead of direct Python 3 replacements:
authorized_key.py: try/except ImportError for urllib.parse.urlparse (falls back to urlparse on Python 2)
synchronize.py: try/except ImportError for shlex.quote (falls back to pipes.quote on Python 2)
sysctl.py: uses sys.version_info to set string_types to str on Python 3 (basestring on Python 2)
Also removes corresponding pylint:ansible-bad-import-from entries from tests/sanity/ignore-2.21.txt and tests/sanity/ignore-2.22.txt where applicable.
Fixes #686
ISSUE TYPE
Bugfix Pull Request
ADDITIONAL INFORMATION
Approach:
Each file is fixed in a separate commit for easier code review. The changelog fragment is added in a final commit. Corresponding pylint:ansible-bad-import-from ignore entries in tests/sanity/ignore-2.21.txt and tests/sanity/ignore-2.22.txt are removed in the same commit as the file fix (or the file removal commit).
CI results:
All 59 checks passing (Azure Pipelines sanity, units, lint, Docker, Remote across ansible-core 2.17 through devel, and Zuul ansible/check).
Reviewed-by: Felix Fontein <felix@fontein.de>
Reviewed-by: Pavel Bar
Reviewed-by: Abhijeet Kasurde
(cherry picked from commit 2022c1bd86)
Co-authored-by: centosinfra-prod-github-app[bot] <161850885+centosinfra-prod-github-app[bot]@users.noreply.github.com>
405 lines
14 KiB
Python
405 lines
14 KiB
Python
#!/usr/bin/python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# Copyright: (c) 2021, Hideki Saito <saito@fgrep.org>
|
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
|
|
from __future__ import (absolute_import, division, print_function)
|
|
__metaclass__ = type
|
|
|
|
DOCUMENTATION = r'''
|
|
---
|
|
module: firewalld_info
|
|
short_description: Gather information about firewalld
|
|
description:
|
|
- This module gathers information about firewalld rules.
|
|
options:
|
|
active_zones:
|
|
description: Gather information about active zones.
|
|
type: bool
|
|
default: false
|
|
zones:
|
|
description:
|
|
- Gather information about specific zones.
|
|
- If only works if O(active_zones=false).
|
|
required: false
|
|
type: list
|
|
elements: str
|
|
requirements:
|
|
- firewalld >= 0.2.11
|
|
- python-firewall
|
|
- python-dbus
|
|
author:
|
|
- Hideki Saito (@saito-hideki)
|
|
'''
|
|
|
|
EXAMPLES = r'''
|
|
- name: Gather information about active zones
|
|
ansible.posix.firewalld_info:
|
|
active_zones: true
|
|
register: result
|
|
|
|
- name: Print default zone for debugging
|
|
ansible.builtin.debug:
|
|
var: result.firewalld_info.default_zone
|
|
|
|
- name: Gather information about specific zones
|
|
ansible.posix.firewalld_info:
|
|
zones:
|
|
- public
|
|
- external
|
|
- internal
|
|
register: result
|
|
'''
|
|
|
|
RETURN = r'''
|
|
active_zones:
|
|
description:
|
|
- Gather active zones only if turn it C(true).
|
|
returned: success
|
|
type: bool
|
|
sample: false
|
|
collected_zones:
|
|
description:
|
|
- A list of collected zones.
|
|
returned: success
|
|
type: list
|
|
sample: [external, internal]
|
|
undefined_zones:
|
|
description:
|
|
- A list of undefined zones in C(zones) option.
|
|
- C(undefined_zones) will be ignored for gathering process.
|
|
returned: success
|
|
type: list
|
|
sample: [foo, bar]
|
|
firewalld_info:
|
|
description:
|
|
- Returns various information about firewalld configuration.
|
|
returned: success
|
|
type: complex
|
|
contains:
|
|
version:
|
|
description:
|
|
- The version information of firewalld.
|
|
returned: success
|
|
type: str
|
|
sample: 0.8.2
|
|
default_zone:
|
|
description:
|
|
- The zone name of default zone.
|
|
returned: success
|
|
type: str
|
|
sample: public
|
|
zones:
|
|
description:
|
|
- A dict of zones to gather information.
|
|
returned: success
|
|
type: complex
|
|
contains:
|
|
zone:
|
|
description:
|
|
- The zone name registered in firewalld.
|
|
returned: success
|
|
type: complex
|
|
sample: external
|
|
contains:
|
|
target:
|
|
description:
|
|
- A list of services in the zone.
|
|
returned: success
|
|
type: str
|
|
sample: ACCEPT
|
|
icmp_block_inversion:
|
|
description:
|
|
- The ICMP block inversion to block
|
|
all ICMP requests.
|
|
returned: success
|
|
type: bool
|
|
sample: false
|
|
interfaces:
|
|
description:
|
|
- A list of network interfaces.
|
|
returned: success
|
|
type: list
|
|
sample:
|
|
- 'eth0'
|
|
- 'eth1'
|
|
sources:
|
|
description:
|
|
- A list of source network address.
|
|
returned: success
|
|
type: list
|
|
sample:
|
|
- '172.16.30.0/24'
|
|
- '172.16.31.0/24'
|
|
services:
|
|
description:
|
|
- A list of network services.
|
|
returned: success
|
|
type: list
|
|
sample:
|
|
- 'dhcp'
|
|
- 'dns'
|
|
- 'ssh'
|
|
ports:
|
|
description:
|
|
- A list of network port with protocol.
|
|
returned: success
|
|
type: list
|
|
sample:
|
|
- - "22"
|
|
- "tcp"
|
|
- - "80"
|
|
- "tcp"
|
|
protocols:
|
|
description:
|
|
- A list of network protocol.
|
|
returned: success
|
|
type: list
|
|
sample:
|
|
- "icmp"
|
|
- "ipv6-icmp"
|
|
forward:
|
|
description:
|
|
- The network interface forwarding.
|
|
- This parameter supports on python-firewall
|
|
0.9.0(or later) and is not collected in earlier
|
|
versions.
|
|
returned: success
|
|
type: bool
|
|
sample: false
|
|
masquerade:
|
|
description:
|
|
- The network interface masquerading.
|
|
returned: success
|
|
type: bool
|
|
sample: false
|
|
forward_ports:
|
|
description:
|
|
- A list of forwarding port pair with protocol.
|
|
returned: success
|
|
type: list
|
|
sample:
|
|
- "icmp"
|
|
- "ipv6-icmp"
|
|
source_ports:
|
|
description:
|
|
- A list of network source port with protocol.
|
|
returned: success
|
|
type: list
|
|
sample:
|
|
- - "30000"
|
|
- "tcp"
|
|
- - "30001"
|
|
- "tcp"
|
|
icmp_blocks:
|
|
description:
|
|
- A list of blocking icmp protocol.
|
|
returned: success
|
|
type: list
|
|
sample:
|
|
- "echo-request"
|
|
rich_rules:
|
|
description:
|
|
- A list of rich language rule.
|
|
returned: success
|
|
type: list
|
|
sample:
|
|
- "rule protocol value=\"icmp\" reject"
|
|
- "rule priority=\"32767\" reject"
|
|
'''
|
|
|
|
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
|
from ansible.module_utils.common.text.converters import to_native
|
|
from ansible_collections.ansible.posix.plugins.module_utils._respawn import respawn_module, HAS_RESPAWN_UTIL
|
|
from ansible_collections.ansible.posix.plugins.module_utils.version import StrictVersion
|
|
|
|
|
|
try:
|
|
import dbus
|
|
HAS_DBUS = True
|
|
except ImportError:
|
|
HAS_DBUS = False
|
|
|
|
try:
|
|
import firewall.client as fw_client
|
|
import firewall.config as fw_config
|
|
HAS_FIREWALLD = True
|
|
except ImportError:
|
|
HAS_FIREWALLD = False
|
|
|
|
|
|
def get_version():
|
|
return fw_config.VERSION
|
|
|
|
|
|
def get_active_zones(client):
|
|
return client.getActiveZones().keys()
|
|
|
|
|
|
def get_all_zones(client):
|
|
return client.getZones()
|
|
|
|
|
|
def get_default_zone(client):
|
|
return client.getDefaultZone()
|
|
|
|
|
|
def get_zone_settings(client, zone):
|
|
return client.getZoneSettings(zone)
|
|
|
|
|
|
def get_zone_target(zone_settings):
|
|
return zone_settings.getTarget()
|
|
|
|
|
|
def get_zone_icmp_block_inversion(zone_settings):
|
|
return zone_settings.getIcmpBlockInversion()
|
|
|
|
|
|
def get_zone_interfaces(zone_settings):
|
|
return zone_settings.getInterfaces()
|
|
|
|
|
|
def get_zone_sources(zone_settings):
|
|
return zone_settings.getSources()
|
|
|
|
|
|
def get_zone_services(zone_settings):
|
|
return zone_settings.getServices()
|
|
|
|
|
|
def get_zone_ports(zone_settings):
|
|
return zone_settings.getPorts()
|
|
|
|
|
|
def get_zone_protocols(zone_settings):
|
|
return zone_settings.getProtocols()
|
|
|
|
|
|
# This function supports python-firewall 0.9.0(or later).
|
|
def get_zone_forward(zone_settings):
|
|
return zone_settings.getForward()
|
|
|
|
|
|
def get_zone_masquerade(zone_settings):
|
|
return zone_settings.getMasquerade()
|
|
|
|
|
|
def get_zone_forward_ports(zone_settings):
|
|
return zone_settings.getForwardPorts()
|
|
|
|
|
|
def get_zone_source_ports(zone_settings):
|
|
return zone_settings.getSourcePorts()
|
|
|
|
|
|
def get_zone_icmp_blocks(zone_settings):
|
|
return zone_settings.getIcmpBlocks()
|
|
|
|
|
|
def get_zone_rich_rules(zone_settings):
|
|
return zone_settings.getRichRules()
|
|
|
|
|
|
def main():
|
|
module_args = dict(
|
|
active_zones=dict(required=False, type='bool', default=False),
|
|
zones=dict(required=False, type='list', elements='str'),
|
|
)
|
|
|
|
module = AnsibleModule(
|
|
argument_spec=module_args,
|
|
supports_check_mode=True,
|
|
)
|
|
|
|
firewalld_info = dict()
|
|
result = dict(
|
|
changed=False,
|
|
active_zones=module.params['active_zones'],
|
|
collected_zones=list(),
|
|
undefined_zones=list(),
|
|
)
|
|
|
|
# Exit with failure message if requirements modules are not installed.
|
|
if not HAS_DBUS and not HAS_FIREWALLD and HAS_RESPAWN_UTIL:
|
|
# Only respawn the module if both libraries are missing.
|
|
# If only one is available, then usage of the "wrong" (i.e. not the system one)
|
|
# python interpreter is likely not the problem.
|
|
respawn_module("firewall")
|
|
|
|
if not HAS_DBUS:
|
|
module.fail_json(msg=missing_required_lib('python-dbus'))
|
|
if not HAS_FIREWALLD:
|
|
module.fail_json(msg=missing_required_lib('python-firewall'))
|
|
|
|
# If you want to show warning messages in the task running process,
|
|
# you can append the message to the 'warn' list.
|
|
warn = list()
|
|
|
|
try:
|
|
client = fw_client.FirewallClient()
|
|
|
|
# Gather general information of firewalld.
|
|
firewalld_info['version'] = get_version()
|
|
firewalld_info['default_zone'] = get_default_zone(client)
|
|
|
|
# Gather information for zones.
|
|
zones_info = dict()
|
|
collect_zones = list()
|
|
ignore_zones = list()
|
|
if module.params['active_zones']:
|
|
collect_zones = get_active_zones(client)
|
|
elif module.params['zones']:
|
|
all_zones = get_all_zones(client)
|
|
specified_zones = module.params['zones']
|
|
collect_zones = list(set(specified_zones) & set(all_zones))
|
|
ignore_zones = list(set(specified_zones) - set(collect_zones))
|
|
if ignore_zones:
|
|
warn.append(
|
|
'Please note: zone:(%s) have been ignored in the gathering process.' % ','.join(ignore_zones))
|
|
else:
|
|
collect_zones = get_all_zones(client)
|
|
|
|
for zone in collect_zones:
|
|
# Gather settings for each zone based on the output of
|
|
# 'firewall-cmd --info-zone=<ZONE>' command.
|
|
zone_info = dict()
|
|
zone_settings = get_zone_settings(client, zone)
|
|
zone_info['target'] = get_zone_target(zone_settings)
|
|
zone_info['icmp_block_inversion'] = get_zone_icmp_block_inversion(zone_settings)
|
|
zone_info['interfaces'] = get_zone_interfaces(zone_settings)
|
|
zone_info['sources'] = get_zone_sources(zone_settings)
|
|
zone_info['services'] = get_zone_services(zone_settings)
|
|
zone_info['ports'] = get_zone_ports(zone_settings)
|
|
zone_info['protocols'] = get_zone_protocols(zone_settings)
|
|
zone_info['masquerade'] = get_zone_masquerade(zone_settings)
|
|
zone_info['forward_ports'] = get_zone_forward_ports(zone_settings)
|
|
zone_info['source_ports'] = get_zone_source_ports(zone_settings)
|
|
zone_info['icmp_blocks'] = get_zone_icmp_blocks(zone_settings)
|
|
zone_info['rich_rules'] = get_zone_rich_rules(zone_settings)
|
|
|
|
# The 'forward' parameter supports on python-firewall 0.9.0(or later).
|
|
if StrictVersion(firewalld_info['version']) >= StrictVersion('0.9.0'):
|
|
zone_info['forward'] = get_zone_forward(zone_settings)
|
|
|
|
zones_info[zone] = zone_info
|
|
firewalld_info['zones'] = zones_info
|
|
except AttributeError as e:
|
|
module.fail_json(msg=('firewalld probably not be running, Or the following method '
|
|
'is not supported with your python-firewall version. (Error: %s)') % to_native(e))
|
|
except dbus.exceptions.DBusException as e:
|
|
module.fail_json(msg=('Unable to gather firewalld settings.'
|
|
' You may need to run as the root user or'
|
|
' use become. (Error: %s)' % to_native(e)))
|
|
|
|
result['collected_zones'] = collect_zones
|
|
result['undefined_zones'] = ignore_zones
|
|
result['firewalld_info'] = firewalld_info
|
|
result['warnings'] = warn
|
|
module.exit_json(**result)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|