summaryrefslogtreecommitdiffstats
path: root/ansible_collections/community/general/plugins/module_utils
diff options
context:
space:
mode:
Diffstat (limited to 'ansible_collections/community/general/plugins/module_utils')
-rw-r--r--ansible_collections/community/general/plugins/module_utils/cmd_runner.py11
-rw-r--r--ansible_collections/community/general/plugins/module_utils/django.py85
-rw-r--r--ansible_collections/community/general/plugins/module_utils/gandi_livedns_api.py8
-rw-r--r--ansible_collections/community/general/plugins/module_utils/gitlab.py5
-rw-r--r--ansible_collections/community/general/plugins/module_utils/homebrew.py115
-rw-r--r--ansible_collections/community/general/plugins/module_utils/mh/mixins/deps.py47
-rw-r--r--ansible_collections/community/general/plugins/module_utils/mh/mixins/vars.py6
-rw-r--r--ansible_collections/community/general/plugins/module_utils/mh/module_helper.py42
-rw-r--r--ansible_collections/community/general/plugins/module_utils/module_helper.py10
-rw-r--r--ansible_collections/community/general/plugins/module_utils/puppet.py1
-rw-r--r--ansible_collections/community/general/plugins/module_utils/python_runner.py34
-rw-r--r--ansible_collections/community/general/plugins/module_utils/rax.py334
-rw-r--r--ansible_collections/community/general/plugins/module_utils/redhat.py240
-rw-r--r--ansible_collections/community/general/plugins/module_utils/rundeck.py4
-rw-r--r--ansible_collections/community/general/plugins/module_utils/vardict.py2
15 files changed, 307 insertions, 637 deletions
diff --git a/ansible_collections/community/general/plugins/module_utils/cmd_runner.py b/ansible_collections/community/general/plugins/module_utils/cmd_runner.py
index 864987120..2bf2b32e8 100644
--- a/ansible_collections/community/general/plugins/module_utils/cmd_runner.py
+++ b/ansible_collections/community/general/plugins/module_utils/cmd_runner.py
@@ -129,8 +129,15 @@ class _Format(object):
return _ArgFormat(lambda value: ["{0}={1}".format(arg, value)], ignore_none=ignore_none)
@staticmethod
- def as_list(ignore_none=None):
- return _ArgFormat(_ensure_list, ignore_none=ignore_none)
+ def as_list(ignore_none=None, min_len=0, max_len=None):
+ def func(value):
+ value = _ensure_list(value)
+ if len(value) < min_len:
+ raise ValueError("Parameter must have at least {0} element(s)".format(min_len))
+ if max_len is not None and len(value) > max_len:
+ raise ValueError("Parameter must have at most {0} element(s)".format(max_len))
+ return value
+ return _ArgFormat(func, ignore_none=ignore_none)
@staticmethod
def as_fixed(args):
diff --git a/ansible_collections/community/general/plugins/module_utils/django.py b/ansible_collections/community/general/plugins/module_utils/django.py
new file mode 100644
index 000000000..fbaf840db
--- /dev/null
+++ b/ansible_collections/community/general/plugins/module_utils/django.py
@@ -0,0 +1,85 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2024, Alexei Znamensky <russoz@gmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+from ansible_collections.community.general.plugins.module_utils.cmd_runner import cmd_runner_fmt
+from ansible_collections.community.general.plugins.module_utils.python_runner import PythonRunner
+from ansible_collections.community.general.plugins.module_utils.module_helper import ModuleHelper
+
+
+django_std_args = dict(
+ # environmental options
+ venv=dict(type="path"),
+ # default options of django-admin
+ settings=dict(type="str", required=True),
+ pythonpath=dict(type="path"),
+ traceback=dict(type="bool"),
+ verbosity=dict(type="int", choices=[0, 1, 2, 3]),
+ skip_checks=dict(type="bool"),
+)
+
+_django_std_arg_fmts = dict(
+ command=cmd_runner_fmt.as_list(),
+ settings=cmd_runner_fmt.as_opt_eq_val("--settings"),
+ pythonpath=cmd_runner_fmt.as_opt_eq_val("--pythonpath"),
+ traceback=cmd_runner_fmt.as_bool("--traceback"),
+ verbosity=cmd_runner_fmt.as_opt_val("--verbosity"),
+ no_color=cmd_runner_fmt.as_fixed("--no-color"),
+ skip_checks=cmd_runner_fmt.as_bool("--skip-checks"),
+)
+
+
+class _DjangoRunner(PythonRunner):
+ def __init__(self, module, arg_formats=None, **kwargs):
+ arg_fmts = dict(arg_formats) if arg_formats else {}
+ arg_fmts.update(_django_std_arg_fmts)
+
+ super(_DjangoRunner, self).__init__(module, ["-m", "django"], arg_formats=arg_fmts, **kwargs)
+
+ def __call__(self, output_process=None, ignore_value_none=True, check_mode_skip=False, check_mode_return=None, **kwargs):
+ args_order = (
+ ("command", "no_color", "settings", "pythonpath", "traceback", "verbosity", "skip_checks") + self._prepare_args_order(self.default_args_order)
+ )
+ return super(_DjangoRunner, self).__call__(args_order, output_process, ignore_value_none, check_mode_skip, check_mode_return, **kwargs)
+
+
+class DjangoModuleHelper(ModuleHelper):
+ module = {}
+ use_old_vardict = False
+ django_admin_cmd = None
+ arg_formats = {}
+ django_admin_arg_order = ()
+ use_old_vardict = False
+
+ def __init__(self):
+ argument_spec = dict(django_std_args)
+ argument_spec.update(self.module.get("argument_spec", {}))
+ self.module["argument_spec"] = argument_spec
+ super(DjangoModuleHelper, self).__init__(self.module)
+ if self.django_admin_cmd is not None:
+ self.vars.command = self.django_admin_cmd
+
+ def __run__(self):
+ runner = _DjangoRunner(self.module,
+ default_args_order=self.django_admin_arg_order,
+ arg_formats=self.arg_formats,
+ venv=self.vars.venv,
+ check_rc=True)
+ with runner() as ctx:
+ results = ctx.run()
+ self.vars.stdout = ctx.results_out
+ self.vars.stderr = ctx.results_err
+ self.vars.cmd = ctx.cmd
+ if self.verbosity >= 3:
+ self.vars.run_info = ctx.run_info
+
+ return results
+
+ @classmethod
+ def execute(cls):
+ cls().run()
diff --git a/ansible_collections/community/general/plugins/module_utils/gandi_livedns_api.py b/ansible_collections/community/general/plugins/module_utils/gandi_livedns_api.py
index 53245d44d..824fea46e 100644
--- a/ansible_collections/community/general/plugins/module_utils/gandi_livedns_api.py
+++ b/ansible_collections/community/general/plugins/module_utils/gandi_livedns_api.py
@@ -33,6 +33,7 @@ class GandiLiveDNSAPI(object):
def __init__(self, module):
self.module = module
self.api_key = module.params['api_key']
+ self.personal_access_token = module.params['personal_access_token']
def _build_error_message(self, module, info):
s = ''
@@ -50,7 +51,12 @@ class GandiLiveDNSAPI(object):
return s
def _gandi_api_call(self, api_call, method='GET', payload=None, error_on_404=True):
- headers = {'Authorization': 'Apikey {0}'.format(self.api_key),
+ authorization_header = (
+ 'Bearer {0}'.format(self.personal_access_token)
+ if self.personal_access_token
+ else 'Apikey {0}'.format(self.api_key)
+ )
+ headers = {'Authorization': authorization_header,
'Content-Type': 'application/json'}
data = None
if payload:
diff --git a/ansible_collections/community/general/plugins/module_utils/gitlab.py b/ansible_collections/community/general/plugins/module_utils/gitlab.py
index b1354d8a9..224789a71 100644
--- a/ansible_collections/community/general/plugins/module_utils/gitlab.py
+++ b/ansible_collections/community/general/plugins/module_utils/gitlab.py
@@ -115,6 +115,11 @@ def gitlab_authentication(module, min_version=None):
# Changelog : https://github.com/python-gitlab/python-gitlab/releases/tag/v1.13.0
# This condition allow to still support older version of the python-gitlab library
if LooseVersion(gitlab.__version__) < LooseVersion("1.13.0"):
+ module.deprecate(
+ "GitLab basic auth is deprecated and will be removed in next major version, "
+ "using another auth method (API token or OAuth) is strongly recommended.",
+ version='10.0.0',
+ collection_name='community.general')
gitlab_instance = gitlab.Gitlab(url=gitlab_url, ssl_verify=verify, email=gitlab_user, password=gitlab_password,
private_token=gitlab_token, api_version=4)
else:
diff --git a/ansible_collections/community/general/plugins/module_utils/homebrew.py b/ansible_collections/community/general/plugins/module_utils/homebrew.py
new file mode 100644
index 000000000..281683210
--- /dev/null
+++ b/ansible_collections/community/general/plugins/module_utils/homebrew.py
@@ -0,0 +1,115 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) Ansible project
+# Simplified BSD License (see LICENSES/BSD-2-Clause.txt or https://opensource.org/licenses/BSD-2-Clause)
+# SPDX-License-Identifier: BSD-2-Clause
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+import os
+import re
+from ansible.module_utils.six import string_types
+
+
+def _create_regex_group_complement(s):
+ lines = (line.strip() for line in s.split("\n") if line.strip())
+ chars = filter(None, (line.split("#")[0].strip() for line in lines))
+ group = r"[^" + r"".join(chars) + r"]"
+ return re.compile(group)
+
+
+class HomebrewValidate(object):
+ # class regexes ------------------------------------------------ {{{
+ VALID_PATH_CHARS = r"""
+ \w # alphanumeric characters (i.e., [a-zA-Z0-9_])
+ \s # spaces
+ : # colons
+ {sep} # the OS-specific path separator
+ . # dots
+ \- # dashes
+ """.format(
+ sep=os.path.sep
+ )
+
+ VALID_BREW_PATH_CHARS = r"""
+ \w # alphanumeric characters (i.e., [a-zA-Z0-9_])
+ \s # spaces
+ {sep} # the OS-specific path separator
+ . # dots
+ \- # dashes
+ """.format(
+ sep=os.path.sep
+ )
+
+ VALID_PACKAGE_CHARS = r"""
+ \w # alphanumeric characters (i.e., [a-zA-Z0-9_])
+ . # dots
+ / # slash (for taps)
+ \+ # plusses
+ \- # dashes
+ : # colons (for URLs)
+ @ # at-sign
+ """
+
+ INVALID_PATH_REGEX = _create_regex_group_complement(VALID_PATH_CHARS)
+ INVALID_BREW_PATH_REGEX = _create_regex_group_complement(VALID_BREW_PATH_CHARS)
+ INVALID_PACKAGE_REGEX = _create_regex_group_complement(VALID_PACKAGE_CHARS)
+ # /class regexes ----------------------------------------------- }}}
+
+ # class validations -------------------------------------------- {{{
+ @classmethod
+ def valid_path(cls, path):
+ """
+ `path` must be one of:
+ - list of paths
+ - a string containing only:
+ - alphanumeric characters
+ - dashes
+ - dots
+ - spaces
+ - colons
+ - os.path.sep
+ """
+
+ if isinstance(path, string_types):
+ return not cls.INVALID_PATH_REGEX.search(path)
+
+ try:
+ iter(path)
+ except TypeError:
+ return False
+ else:
+ paths = path
+ return all(cls.valid_brew_path(path_) for path_ in paths)
+
+ @classmethod
+ def valid_brew_path(cls, brew_path):
+ """
+ `brew_path` must be one of:
+ - None
+ - a string containing only:
+ - alphanumeric characters
+ - dashes
+ - dots
+ - spaces
+ - os.path.sep
+ """
+
+ if brew_path is None:
+ return True
+
+ return isinstance(
+ brew_path, string_types
+ ) and not cls.INVALID_BREW_PATH_REGEX.search(brew_path)
+
+ @classmethod
+ def valid_package(cls, package):
+ """A valid package is either None or alphanumeric."""
+
+ if package is None:
+ return True
+
+ return isinstance(
+ package, string_types
+ ) and not cls.INVALID_PACKAGE_REGEX.search(package)
diff --git a/ansible_collections/community/general/plugins/module_utils/mh/mixins/deps.py b/ansible_collections/community/general/plugins/module_utils/mh/mixins/deps.py
index 772df8c0e..dd879ff4b 100644
--- a/ansible_collections/community/general/plugins/module_utils/mh/mixins/deps.py
+++ b/ansible_collections/community/general/plugins/module_utils/mh/mixins/deps.py
@@ -7,13 +7,14 @@
from __future__ import absolute_import, division, print_function
__metaclass__ = type
-import traceback
-
-from ansible_collections.community.general.plugins.module_utils.mh.base import ModuleHelperBase
-from ansible_collections.community.general.plugins.module_utils.mh.deco import module_fails_on_exception
-
class DependencyCtxMgr(object):
+ """
+ DEPRECATION WARNING
+
+ This class is deprecated and will be removed in community.general 11.0.0
+ Modules should use plugins/module_utils/deps.py instead.
+ """
def __init__(self, name, msg=None):
self.name = name
self.msg = msg
@@ -35,39 +36,3 @@ class DependencyCtxMgr(object):
@property
def text(self):
return self.msg or str(self.exc_val)
-
-
-class DependencyMixin(ModuleHelperBase):
- """
- THIS CLASS IS BEING DEPRECATED.
- See the deprecation notice in ``DependencyMixin.fail_on_missing_deps()`` below.
-
- Mixin for mapping module options to running a CLI command with its arguments.
- """
- _dependencies = []
-
- @classmethod
- def dependency(cls, name, msg):
- cls._dependencies.append(DependencyCtxMgr(name, msg))
- return cls._dependencies[-1]
-
- def fail_on_missing_deps(self):
- if not self._dependencies:
- return
- self.module.deprecate(
- 'The DependencyMixin is being deprecated. '
- 'Modules should use community.general.plugins.module_utils.deps instead.',
- version='9.0.0',
- collection_name='community.general',
- )
- for d in self._dependencies:
- if not d.has_it:
- self.module.fail_json(changed=False,
- exception="\n".join(traceback.format_exception(d.exc_type, d.exc_val, d.exc_tb)),
- msg=d.text,
- **self.output)
-
- @module_fails_on_exception
- def run(self):
- self.fail_on_missing_deps()
- super(DependencyMixin, self).run()
diff --git a/ansible_collections/community/general/plugins/module_utils/mh/mixins/vars.py b/ansible_collections/community/general/plugins/module_utils/mh/mixins/vars.py
index 91f4e4a18..161560973 100644
--- a/ansible_collections/community/general/plugins/module_utils/mh/mixins/vars.py
+++ b/ansible_collections/community/general/plugins/module_utils/mh/mixins/vars.py
@@ -14,7 +14,7 @@ class VarMeta(object):
"""
DEPRECATION WARNING
- This class is deprecated and will be removed in community.general 10.0.0
+ This class is deprecated and will be removed in community.general 11.0.0
Modules should use the VarDict from plugins/module_utils/vardict.py instead.
"""
@@ -70,7 +70,7 @@ class VarDict(object):
"""
DEPRECATION WARNING
- This class is deprecated and will be removed in community.general 10.0.0
+ This class is deprecated and will be removed in community.general 11.0.0
Modules should use the VarDict from plugins/module_utils/vardict.py instead.
"""
def __init__(self):
@@ -139,7 +139,7 @@ class VarsMixin(object):
"""
DEPRECATION WARNING
- This class is deprecated and will be removed in community.general 10.0.0
+ This class is deprecated and will be removed in community.general 11.0.0
Modules should use the VarDict from plugins/module_utils/vardict.py instead.
"""
def __init__(self, module=None):
diff --git a/ansible_collections/community/general/plugins/module_utils/mh/module_helper.py b/ansible_collections/community/general/plugins/module_utils/mh/module_helper.py
index c33efb16b..ca95199d9 100644
--- a/ansible_collections/community/general/plugins/module_utils/mh/module_helper.py
+++ b/ansible_collections/community/general/plugins/module_utils/mh/module_helper.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# (c) 2020, Alexei Znamensky <russoz@gmail.com>
-# Copyright (c) 2020, Ansible Project
+# (c) 2020-2024, Alexei Znamensky <russoz@gmail.com>
+# Copyright (c) 2020-2024, Ansible Project
# Simplified BSD License (see LICENSES/BSD-2-Clause.txt or https://opensource.org/licenses/BSD-2-Clause)
# SPDX-License-Identifier: BSD-2-Clause
@@ -10,23 +10,40 @@ __metaclass__ = type
from ansible.module_utils.common.dict_transformations import dict_merge
+from ansible_collections.community.general.plugins.module_utils.vardict import VarDict as _NewVarDict # remove "as NewVarDict" in 11.0.0
# (TODO: remove AnsibleModule!) pylint: disable-next=unused-import
-from ansible_collections.community.general.plugins.module_utils.mh.base import ModuleHelperBase, AnsibleModule # noqa: F401
+from ansible_collections.community.general.plugins.module_utils.mh.base import AnsibleModule # noqa: F401 DEPRECATED, remove in 11.0.0
+from ansible_collections.community.general.plugins.module_utils.mh.base import ModuleHelperBase
from ansible_collections.community.general.plugins.module_utils.mh.mixins.state import StateMixin
-from ansible_collections.community.general.plugins.module_utils.mh.mixins.deps import DependencyMixin
-from ansible_collections.community.general.plugins.module_utils.mh.mixins.vars import VarsMixin
+# (TODO: remove mh.mixins.vars!) pylint: disable-next=unused-import
+from ansible_collections.community.general.plugins.module_utils.mh.mixins.vars import VarsMixin, VarDict as _OldVarDict # noqa: F401 remove in 11.0.0
from ansible_collections.community.general.plugins.module_utils.mh.mixins.deprecate_attrs import DeprecateAttrsMixin
-class ModuleHelper(DeprecateAttrsMixin, VarsMixin, DependencyMixin, ModuleHelperBase):
+class ModuleHelper(DeprecateAttrsMixin, ModuleHelperBase):
facts_name = None
output_params = ()
diff_params = ()
change_params = ()
facts_params = ()
+ use_old_vardict = True # remove in 11.0.0
+ mute_vardict_deprecation = False
def __init__(self, module=None):
- super(ModuleHelper, self).__init__(module)
+ if self.use_old_vardict: # remove first half of the if in 11.0.0
+ self.vars = _OldVarDict()
+ super(ModuleHelper, self).__init__(module)
+ if not self.mute_vardict_deprecation:
+ self.module.deprecate(
+ "This class is using the old VarDict from ModuleHelper, which is deprecated. "
+ "Set the class variable use_old_vardict to False and make the necessary adjustments."
+ "The old VarDict class will be removed in community.general 11.0.0",
+ version="11.0.0", collection_name="community.general"
+ )
+ else:
+ self.vars = _NewVarDict()
+ super(ModuleHelper, self).__init__(module)
+
for name, value in self.module.params.items():
self.vars.set(
name, value,
@@ -36,6 +53,12 @@ class ModuleHelper(DeprecateAttrsMixin, VarsMixin, DependencyMixin, ModuleHelper
fact=name in self.facts_params,
)
+ def update_vars(self, meta=None, **kwargs):
+ if meta is None:
+ meta = {}
+ for k, v in kwargs.items():
+ self.vars.set(k, v, **meta)
+
def update_output(self, **kwargs):
self.update_vars(meta={"output": True}, **kwargs)
@@ -43,7 +66,10 @@ class ModuleHelper(DeprecateAttrsMixin, VarsMixin, DependencyMixin, ModuleHelper
self.update_vars(meta={"fact": True}, **kwargs)
def _vars_changed(self):
- return any(self.vars.has_changed(v) for v in self.vars.change_vars())
+ if self.use_old_vardict:
+ return any(self.vars.has_changed(v) for v in self.vars.change_vars())
+
+ return self.vars.has_changed
def has_changed(self):
return self.changed or self._vars_changed()
diff --git a/ansible_collections/community/general/plugins/module_utils/module_helper.py b/ansible_collections/community/general/plugins/module_utils/module_helper.py
index 5aa16c057..366699329 100644
--- a/ansible_collections/community/general/plugins/module_utils/module_helper.py
+++ b/ansible_collections/community/general/plugins/module_utils/module_helper.py
@@ -9,14 +9,14 @@ __metaclass__ = type
# pylint: disable=unused-import
-
from ansible_collections.community.general.plugins.module_utils.mh.module_helper import (
- ModuleHelper, StateModuleHelper, AnsibleModule
+ ModuleHelper, StateModuleHelper,
+ AnsibleModule # remove in 11.0.0
)
-from ansible_collections.community.general.plugins.module_utils.mh.mixins.state import StateMixin # noqa: F401
-from ansible_collections.community.general.plugins.module_utils.mh.mixins.deps import DependencyCtxMgr, DependencyMixin # noqa: F401
+from ansible_collections.community.general.plugins.module_utils.mh.mixins.state import StateMixin # noqa: F401 remove in 11.0.0
+from ansible_collections.community.general.plugins.module_utils.mh.mixins.deps import DependencyCtxMgr # noqa: F401 remove in 11.0.0
from ansible_collections.community.general.plugins.module_utils.mh.exceptions import ModuleHelperException # noqa: F401
from ansible_collections.community.general.plugins.module_utils.mh.deco import (
cause_changes, module_fails_on_exception, check_mode_skip, check_mode_skip_returns,
)
-from ansible_collections.community.general.plugins.module_utils.mh.mixins.vars import VarMeta, VarDict, VarsMixin # noqa: F401
+from ansible_collections.community.general.plugins.module_utils.mh.mixins.vars import VarMeta, VarDict, VarsMixin # noqa: F401 remove in 11.0.0
diff --git a/ansible_collections/community/general/plugins/module_utils/puppet.py b/ansible_collections/community/general/plugins/module_utils/puppet.py
index f05b0673f..e06683b3e 100644
--- a/ansible_collections/community/general/plugins/module_utils/puppet.py
+++ b/ansible_collections/community/general/plugins/module_utils/puppet.py
@@ -103,6 +103,7 @@ def puppet_runner(module):
modulepath=cmd_runner_fmt.as_opt_eq_val("--modulepath"),
_execute=cmd_runner_fmt.as_func(execute_func),
summarize=cmd_runner_fmt.as_bool("--summarize"),
+ waitforlock=cmd_runner_fmt.as_opt_val("--waitforlock"),
debug=cmd_runner_fmt.as_bool("--debug"),
verbose=cmd_runner_fmt.as_bool("--verbose"),
),
diff --git a/ansible_collections/community/general/plugins/module_utils/python_runner.py b/ansible_collections/community/general/plugins/module_utils/python_runner.py
new file mode 100644
index 000000000..f678f247b
--- /dev/null
+++ b/ansible_collections/community/general/plugins/module_utils/python_runner.py
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2024, Alexei Znamensky <russoz@gmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+import os
+
+from ansible_collections.community.general.plugins.module_utils.cmd_runner import CmdRunner, _ensure_list
+
+
+class PythonRunner(CmdRunner):
+ def __init__(self, module, command, arg_formats=None, default_args_order=(),
+ check_rc=False, force_lang="C", path_prefix=None, environ_update=None,
+ python="python", venv=None):
+ self.python = python
+ self.venv = venv
+ self.has_venv = venv is not None
+
+ if (os.path.isabs(python) or '/' in python):
+ self.python = python
+ elif self.has_venv:
+ path_prefix = os.path.join(venv, "bin")
+ if environ_update is None:
+ environ_update = {}
+ environ_update["PATH"] = "%s:%s" % (path_prefix, os.environ["PATH"])
+ environ_update["VIRTUAL_ENV"] = venv
+
+ python_cmd = [self.python] + _ensure_list(command)
+
+ super(PythonRunner, self).__init__(module, python_cmd, arg_formats, default_args_order,
+ check_rc, force_lang, path_prefix, environ_update)
diff --git a/ansible_collections/community/general/plugins/module_utils/rax.py b/ansible_collections/community/general/plugins/module_utils/rax.py
deleted file mode 100644
index 6331c0d1b..000000000
--- a/ansible_collections/community/general/plugins/module_utils/rax.py
+++ /dev/null
@@ -1,334 +0,0 @@
-# -*- coding: utf-8 -*-
-# This code is part of Ansible, but is an independent component.
-# This particular file snippet, and this file snippet only, is BSD licensed.
-# Modules you write using this snippet, which is embedded dynamically by
-# Ansible still belong to the author of the module, and may assign their own
-# license to the complete work.
-#
-# Copyright (c), Michael DeHaan <michael.dehaan@gmail.com>, 2012-2013
-#
-# Simplified BSD License (see LICENSES/BSD-2-Clause.txt or https://opensource.org/licenses/BSD-2-Clause)
-# SPDX-License-Identifier: BSD-2-Clause
-
-from __future__ import (absolute_import, division, print_function)
-__metaclass__ = type
-
-
-import os
-import re
-from uuid import UUID
-
-from ansible.module_utils.six import text_type, binary_type
-
-FINAL_STATUSES = ('ACTIVE', 'ERROR')
-VOLUME_STATUS = ('available', 'attaching', 'creating', 'deleting', 'in-use',
- 'error', 'error_deleting')
-
-CLB_ALGORITHMS = ['RANDOM', 'LEAST_CONNECTIONS', 'ROUND_ROBIN',
- 'WEIGHTED_LEAST_CONNECTIONS', 'WEIGHTED_ROUND_ROBIN']
-CLB_PROTOCOLS = ['DNS_TCP', 'DNS_UDP', 'FTP', 'HTTP', 'HTTPS', 'IMAPS',
- 'IMAPv4', 'LDAP', 'LDAPS', 'MYSQL', 'POP3', 'POP3S', 'SMTP',
- 'TCP', 'TCP_CLIENT_FIRST', 'UDP', 'UDP_STREAM', 'SFTP']
-
-NON_CALLABLES = (text_type, binary_type, bool, dict, int, list, type(None))
-PUBLIC_NET_ID = "00000000-0000-0000-0000-000000000000"
-SERVICE_NET_ID = "11111111-1111-1111-1111-111111111111"
-
-
-def rax_slugify(value):
- """Prepend a key with rax_ and normalize the key name"""
- return 'rax_%s' % (re.sub(r'[^\w-]', '_', value).lower().lstrip('_'))
-
-
-def rax_clb_node_to_dict(obj):
- """Function to convert a CLB Node object to a dict"""
- if not obj:
- return {}
- node = obj.to_dict()
- node['id'] = obj.id
- node['weight'] = obj.weight
- return node
-
-
-def rax_to_dict(obj, obj_type='standard'):
- """Generic function to convert a pyrax object to a dict
-
- obj_type values:
- standard
- clb
- server
-
- """
- instance = {}
- for key in dir(obj):
- value = getattr(obj, key)
- if obj_type == 'clb' and key == 'nodes':
- instance[key] = []
- for node in value:
- instance[key].append(rax_clb_node_to_dict(node))
- elif (isinstance(value, list) and len(value) > 0 and
- not isinstance(value[0], NON_CALLABLES)):
- instance[key] = []
- for item in value:
- instance[key].append(rax_to_dict(item))
- elif (isinstance(value, NON_CALLABLES) and not key.startswith('_')):
- if obj_type == 'server':
- if key == 'image':
- if not value:
- instance['rax_boot_source'] = 'volume'
- else:
- instance['rax_boot_source'] = 'local'
- key = rax_slugify(key)
- instance[key] = value
-
- if obj_type == 'server':
- for attr in ['id', 'accessIPv4', 'name', 'status']:
- instance[attr] = instance.get(rax_slugify(attr))
-
- return instance
-
-
-def rax_find_bootable_volume(module, rax_module, server, exit=True):
- """Find a servers bootable volume"""
- cs = rax_module.cloudservers
- cbs = rax_module.cloud_blockstorage
- server_id = rax_module.utils.get_id(server)
- volumes = cs.volumes.get_server_volumes(server_id)
- bootable_volumes = []
- for volume in volumes:
- vol = cbs.get(volume)
- if module.boolean(vol.bootable):
- bootable_volumes.append(vol)
- if not bootable_volumes:
- if exit:
- module.fail_json(msg='No bootable volumes could be found for '
- 'server %s' % server_id)
- else:
- return False
- elif len(bootable_volumes) > 1:
- if exit:
- module.fail_json(msg='Multiple bootable volumes found for server '
- '%s' % server_id)
- else:
- return False
-
- return bootable_volumes[0]
-
-
-def rax_find_image(module, rax_module, image, exit=True):
- """Find a server image by ID or Name"""
- cs = rax_module.cloudservers
- try:
- UUID(image)
- except ValueError:
- try:
- image = cs.images.find(human_id=image)
- except (cs.exceptions.NotFound, cs.exceptions.NoUniqueMatch):
- try:
- image = cs.images.find(name=image)
- except (cs.exceptions.NotFound,
- cs.exceptions.NoUniqueMatch):
- if exit:
- module.fail_json(msg='No matching image found (%s)' %
- image)
- else:
- return False
-
- return rax_module.utils.get_id(image)
-
-
-def rax_find_volume(module, rax_module, name):
- """Find a Block storage volume by ID or name"""
- cbs = rax_module.cloud_blockstorage
- try:
- UUID(name)
- volume = cbs.get(name)
- except ValueError:
- try:
- volume = cbs.find(name=name)
- except rax_module.exc.NotFound:
- volume = None
- except Exception as e:
- module.fail_json(msg='%s' % e)
- return volume
-
-
-def rax_find_network(module, rax_module, network):
- """Find a cloud network by ID or name"""
- cnw = rax_module.cloud_networks
- try:
- UUID(network)
- except ValueError:
- if network.lower() == 'public':
- return cnw.get_server_networks(PUBLIC_NET_ID)
- elif network.lower() == 'private':
- return cnw.get_server_networks(SERVICE_NET_ID)
- else:
- try:
- network_obj = cnw.find_network_by_label(network)
- except (rax_module.exceptions.NetworkNotFound,
- rax_module.exceptions.NetworkLabelNotUnique):
- module.fail_json(msg='No matching network found (%s)' %
- network)
- else:
- return cnw.get_server_networks(network_obj)
- else:
- return cnw.get_server_networks(network)
-
-
-def rax_find_server(module, rax_module, server):
- """Find a Cloud Server by ID or name"""
- cs = rax_module.cloudservers
- try:
- UUID(server)
- server = cs.servers.get(server)
- except ValueError:
- servers = cs.servers.list(search_opts=dict(name='^%s$' % server))
- if not servers:
- module.fail_json(msg='No Server was matched by name, '
- 'try using the Server ID instead')
- if len(servers) > 1:
- module.fail_json(msg='Multiple servers matched by name, '
- 'try using the Server ID instead')
-
- # We made it this far, grab the first and hopefully only server
- # in the list
- server = servers[0]
- return server
-
-
-def rax_find_loadbalancer(module, rax_module, loadbalancer):
- """Find a Cloud Load Balancer by ID or name"""
- clb = rax_module.cloud_loadbalancers
- try:
- found = clb.get(loadbalancer)
- except Exception:
- found = []
- for lb in clb.list():
- if loadbalancer == lb.name:
- found.append(lb)
-
- if not found:
- module.fail_json(msg='No loadbalancer was matched')
-
- if len(found) > 1:
- module.fail_json(msg='Multiple loadbalancers matched')
-
- # We made it this far, grab the first and hopefully only item
- # in the list
- found = found[0]
-
- return found
-
-
-def rax_argument_spec():
- """Return standard base dictionary used for the argument_spec
- argument in AnsibleModule
-
- """
- return dict(
- api_key=dict(type='str', aliases=['password'], no_log=True),
- auth_endpoint=dict(type='str'),
- credentials=dict(type='path', aliases=['creds_file']),
- env=dict(type='str'),
- identity_type=dict(type='str', default='rackspace'),
- region=dict(type='str'),
- tenant_id=dict(type='str'),
- tenant_name=dict(type='str'),
- username=dict(type='str'),
- validate_certs=dict(type='bool', aliases=['verify_ssl']),
- )
-
-
-def rax_required_together():
- """Return the default list used for the required_together argument to
- AnsibleModule"""
- return [['api_key', 'username']]
-
-
-def setup_rax_module(module, rax_module, region_required=True):
- """Set up pyrax in a standard way for all modules"""
- rax_module.USER_AGENT = 'ansible/%s %s' % (module.ansible_version,
- rax_module.USER_AGENT)
-
- api_key = module.params.get('api_key')
- auth_endpoint = module.params.get('auth_endpoint')
- credentials = module.params.get('credentials')
- env = module.params.get('env')
- identity_type = module.params.get('identity_type')
- region = module.params.get('region')
- tenant_id = module.params.get('tenant_id')
- tenant_name = module.params.get('tenant_name')
- username = module.params.get('username')
- verify_ssl = module.params.get('validate_certs')
-
- if env is not None:
- rax_module.set_environment(env)
-
- rax_module.set_setting('identity_type', identity_type)
- if verify_ssl is not None:
- rax_module.set_setting('verify_ssl', verify_ssl)
- if auth_endpoint is not None:
- rax_module.set_setting('auth_endpoint', auth_endpoint)
- if tenant_id is not None:
- rax_module.set_setting('tenant_id', tenant_id)
- if tenant_name is not None:
- rax_module.set_setting('tenant_name', tenant_name)
-
- try:
- username = username or os.environ.get('RAX_USERNAME')
- if not username:
- username = rax_module.get_setting('keyring_username')
- if username:
- api_key = 'USE_KEYRING'
- if not api_key:
- api_key = os.environ.get('RAX_API_KEY')
- credentials = (credentials or os.environ.get('RAX_CREDENTIALS') or
- os.environ.get('RAX_CREDS_FILE'))
- region = (region or os.environ.get('RAX_REGION') or
- rax_module.get_setting('region'))
- except KeyError as e:
- module.fail_json(msg='Unable to load %s' % e.message)
-
- try:
- if api_key and username:
- if api_key == 'USE_KEYRING':
- rax_module.keyring_auth(username, region=region)
- else:
- rax_module.set_credentials(username, api_key=api_key,
- region=region)
- elif credentials:
- credentials = os.path.expanduser(credentials)
- rax_module.set_credential_file(credentials, region=region)
- else:
- raise Exception('No credentials supplied!')
- except Exception as e:
- if e.message:
- msg = str(e.message)
- else:
- msg = repr(e)
- module.fail_json(msg=msg)
-
- if region_required and region not in rax_module.regions:
- module.fail_json(msg='%s is not a valid region, must be one of: %s' %
- (region, ','.join(rax_module.regions)))
-
- return rax_module
-
-
-def rax_scaling_group_personality_file(module, files):
- if not files:
- return []
-
- results = []
- for rpath, lpath in files.items():
- lpath = os.path.expanduser(lpath)
- try:
- with open(lpath, 'r') as f:
- results.append({
- 'path': rpath,
- 'contents': f.read(),
- })
- except Exception as e:
- module.fail_json(msg='Failed to load %s: %s' % (lpath, str(e)))
- return results
diff --git a/ansible_collections/community/general/plugins/module_utils/redhat.py b/ansible_collections/community/general/plugins/module_utils/redhat.py
index 110159ddf..321386a0a 100644
--- a/ansible_collections/community/general/plugins/module_utils/redhat.py
+++ b/ansible_collections/community/general/plugins/module_utils/redhat.py
@@ -15,10 +15,8 @@ __metaclass__ = type
import os
-import re
import shutil
import tempfile
-import types
from ansible.module_utils.six.moves import configparser
@@ -76,241 +74,3 @@ class RegistrationBase(object):
def subscribe(self, **kwargs):
raise NotImplementedError("Must be implemented by a sub-class")
-
-
-class Rhsm(RegistrationBase):
- """
- DEPRECATION WARNING
-
- This class is deprecated and will be removed in community.general 9.0.0.
- There is no replacement for it; please contact the community.general
- maintainers in case you are using it.
- """
-
- def __init__(self, module, username=None, password=None):
- RegistrationBase.__init__(self, module, username, password)
- self.config = self._read_config()
- self.module = module
- self.module.deprecate(
- 'The Rhsm class is deprecated with no replacement.',
- version='9.0.0',
- collection_name='community.general',
- )
-
- def _read_config(self, rhsm_conf='/etc/rhsm/rhsm.conf'):
- '''
- Load RHSM configuration from /etc/rhsm/rhsm.conf.
- Returns:
- * ConfigParser object
- '''
-
- # Read RHSM defaults ...
- cp = configparser.ConfigParser()
- cp.read(rhsm_conf)
-
- # Add support for specifying a default value w/o having to standup some configuration
- # Yeah, I know this should be subclassed ... but, oh well
- def get_option_default(self, key, default=''):
- sect, opt = key.split('.', 1)
- if self.has_section(sect) and self.has_option(sect, opt):
- return self.get(sect, opt)
- else:
- return default
-
- cp.get_option = types.MethodType(get_option_default, cp, configparser.ConfigParser)
-
- return cp
-
- def enable(self):
- '''
- Enable the system to receive updates from subscription-manager.
- This involves updating affected yum plugins and removing any
- conflicting yum repositories.
- '''
- RegistrationBase.enable(self)
- self.update_plugin_conf('rhnplugin', False)
- self.update_plugin_conf('subscription-manager', True)
-
- def configure(self, **kwargs):
- '''
- Configure the system as directed for registration with RHN
- Raises:
- * Exception - if error occurs while running command
- '''
- args = ['subscription-manager', 'config']
-
- # Pass supplied **kwargs as parameters to subscription-manager. Ignore
- # non-configuration parameters and replace '_' with '.'. For example,
- # 'server_hostname' becomes '--system.hostname'.
- for k, v in kwargs.items():
- if re.search(r'^(system|rhsm)_', k):
- args.append('--%s=%s' % (k.replace('_', '.'), v))
-
- self.module.run_command(args, check_rc=True)
-
- @property
- def is_registered(self):
- '''
- Determine whether the current system
- Returns:
- * Boolean - whether the current system is currently registered to
- RHN.
- '''
- args = ['subscription-manager', 'identity']
- rc, stdout, stderr = self.module.run_command(args, check_rc=False)
- if rc == 0:
- return True
- else:
- return False
-
- def register(self, username, password, autosubscribe, activationkey):
- '''
- Register the current system to the provided RHN server
- Raises:
- * Exception - if error occurs while running command
- '''
- args = ['subscription-manager', 'register']
-
- # Generate command arguments
- if activationkey:
- args.append('--activationkey "%s"' % activationkey)
- else:
- if autosubscribe:
- args.append('--autosubscribe')
- if username:
- args.extend(['--username', username])
- if password:
- args.extend(['--password', password])
-
- # Do the needful...
- rc, stderr, stdout = self.module.run_command(args, check_rc=True)
-
- def unsubscribe(self):
- '''
- Unsubscribe a system from all subscribed channels
- Raises:
- * Exception - if error occurs while running command
- '''
- args = ['subscription-manager', 'unsubscribe', '--all']
- rc, stderr, stdout = self.module.run_command(args, check_rc=True)
-
- def unregister(self):
- '''
- Unregister a currently registered system
- Raises:
- * Exception - if error occurs while running command
- '''
- args = ['subscription-manager', 'unregister']
- rc, stderr, stdout = self.module.run_command(args, check_rc=True)
- self.update_plugin_conf('rhnplugin', False)
- self.update_plugin_conf('subscription-manager', False)
-
- def subscribe(self, regexp):
- '''
- Subscribe current system to available pools matching the specified
- regular expression
- Raises:
- * Exception - if error occurs while running command
- '''
-
- # Available pools ready for subscription
- available_pools = RhsmPools(self.module)
-
- for pool in available_pools.filter(regexp):
- pool.subscribe()
-
-
-class RhsmPool(object):
- """
- Convenience class for housing subscription information
-
- DEPRECATION WARNING
-
- This class is deprecated and will be removed in community.general 9.0.0.
- There is no replacement for it; please contact the community.general
- maintainers in case you are using it.
- """
-
- def __init__(self, module, **kwargs):
- self.module = module
- for k, v in kwargs.items():
- setattr(self, k, v)
- self.module.deprecate(
- 'The RhsmPool class is deprecated with no replacement.',
- version='9.0.0',
- collection_name='community.general',
- )
-
- def __str__(self):
- return str(self.__getattribute__('_name'))
-
- def subscribe(self):
- args = "subscription-manager subscribe --pool %s" % self.PoolId
- rc, stdout, stderr = self.module.run_command(args, check_rc=True)
- if rc == 0:
- return True
- else:
- return False
-
-
-class RhsmPools(object):
- """
- This class is used for manipulating pools subscriptions with RHSM
-
- DEPRECATION WARNING
-
- This class is deprecated and will be removed in community.general 9.0.0.
- There is no replacement for it; please contact the community.general
- maintainers in case you are using it.
- """
-
- def __init__(self, module):
- self.module = module
- self.products = self._load_product_list()
- self.module.deprecate(
- 'The RhsmPools class is deprecated with no replacement.',
- version='9.0.0',
- collection_name='community.general',
- )
-
- def __iter__(self):
- return self.products.__iter__()
-
- def _load_product_list(self):
- """
- Loads list of all available pools for system in data structure
- """
- args = "subscription-manager list --available"
- rc, stdout, stderr = self.module.run_command(args, check_rc=True)
-
- products = []
- for line in stdout.split('\n'):
- # Remove leading+trailing whitespace
- line = line.strip()
- # An empty line implies the end of an output group
- if len(line) == 0:
- continue
- # If a colon ':' is found, parse
- elif ':' in line:
- (key, value) = line.split(':', 1)
- key = key.strip().replace(" ", "") # To unify
- value = value.strip()
- if key in ['ProductName', 'SubscriptionName']:
- # Remember the name for later processing
- products.append(RhsmPool(self.module, _name=value, key=value))
- elif products:
- # Associate value with most recently recorded product
- products[-1].__setattr__(key, value)
- # FIXME - log some warning?
- # else:
- # warnings.warn("Unhandled subscription key/value: %s/%s" % (key,value))
- return products
-
- def filter(self, regexp='^$'):
- '''
- Return a list of RhsmPools whose name matches the provided regular expression
- '''
- r = re.compile(regexp)
- for product in self.products:
- if r.search(product._name):
- yield product
diff --git a/ansible_collections/community/general/plugins/module_utils/rundeck.py b/ansible_collections/community/general/plugins/module_utils/rundeck.py
index 7df68a360..cffca7b4e 100644
--- a/ansible_collections/community/general/plugins/module_utils/rundeck.py
+++ b/ansible_collections/community/general/plugins/module_utils/rundeck.py
@@ -28,7 +28,7 @@ def api_argument_spec():
return api_argument_spec
-def api_request(module, endpoint, data=None, method="GET"):
+def api_request(module, endpoint, data=None, method="GET", content_type="application/json"):
"""Manages Rundeck API requests via HTTP(S)
:arg module: The AnsibleModule (used to get url, api_version, api_token, etc).
@@ -63,7 +63,7 @@ def api_request(module, endpoint, data=None, method="GET"):
data=json.dumps(data),
method=method,
headers={
- "Content-Type": "application/json",
+ "Content-Type": content_type,
"Accept": "application/json",
"X-Rundeck-Auth-Token": module.params["api_token"]
}
diff --git a/ansible_collections/community/general/plugins/module_utils/vardict.py b/ansible_collections/community/general/plugins/module_utils/vardict.py
index cfcce4d4d..51f802483 100644
--- a/ansible_collections/community/general/plugins/module_utils/vardict.py
+++ b/ansible_collections/community/general/plugins/module_utils/vardict.py
@@ -100,7 +100,7 @@ class _Variable(object):
return
def __str__(self):
- return "<_Variable: value={0!r}, initial={1!r}, diff={2}, output={3}, change={4}, verbosity={5}>".format(
+ return "<Variable: value={0!r}, initial={1!r}, diff={2}, output={3}, change={4}, verbosity={5}>".format(
self.value, self.initial_value, self.diff, self.output, self.change, self.verbosity
)