mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-10-23 12:33:59 -07:00
Bump version of main
to 12.0.0; execute announced deprecations (#10883)
* Bump version to 12.0.0. * Remove deprecated modules and plugins. * state is now required. * Change default of prepend_hash from auto to never. * Remove support for force=''. * Always delegate 'debug'. * Remove ignore_value_none and ctx_ignore_none parameters. * Remove parameters on_success and on_failure. * Update BOTMETA. * Adjust docs reference. * Forgot required=True. * Fix changelog fragment. * Adjust unit tests. * Fix changelog. Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --------- Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
This commit is contained in:
parent
f34842b7b2
commit
0b72737cab
22 changed files with 43 additions and 901 deletions
10
.github/BOTMETA.yml
vendored
10
.github/BOTMETA.yml
vendored
|
@ -99,7 +99,6 @@ files:
|
||||||
$callbacks/unixy.py:
|
$callbacks/unixy.py:
|
||||||
labels: unixy
|
labels: unixy
|
||||||
maintainers: akatch
|
maintainers: akatch
|
||||||
$callbacks/yaml.py: {}
|
|
||||||
$connections/:
|
$connections/:
|
||||||
labels: connections
|
labels: connections
|
||||||
$connections/chroot.py: {}
|
$connections/chroot.py: {}
|
||||||
|
@ -394,9 +393,6 @@ files:
|
||||||
$module_utils/puppet.py:
|
$module_utils/puppet.py:
|
||||||
labels: puppet
|
labels: puppet
|
||||||
maintainers: russoz
|
maintainers: russoz
|
||||||
$module_utils/pure.py:
|
|
||||||
labels: pure pure_storage
|
|
||||||
maintainers: $team_purestorage
|
|
||||||
$module_utils/redfish_utils.py:
|
$module_utils/redfish_utils.py:
|
||||||
labels: redfish_utils
|
labels: redfish_utils
|
||||||
maintainers: $team_redfish
|
maintainers: $team_redfish
|
||||||
|
@ -480,8 +476,6 @@ files:
|
||||||
keywords: beadm dladm illumos ipadm nexenta omnios openindiana pfexec smartos solaris sunos zfs zpool
|
keywords: beadm dladm illumos ipadm nexenta omnios openindiana pfexec smartos solaris sunos zfs zpool
|
||||||
labels: beadm solaris
|
labels: beadm solaris
|
||||||
maintainers: $team_solaris
|
maintainers: $team_solaris
|
||||||
$modules/bearychat.py:
|
|
||||||
maintainers: tonyseek
|
|
||||||
$modules/bigpanda.py:
|
$modules/bigpanda.py:
|
||||||
ignore: hkariti
|
ignore: hkariti
|
||||||
$modules/bitbucket_:
|
$modules/bitbucket_:
|
||||||
|
@ -587,9 +581,6 @@ files:
|
||||||
$modules/etcd3.py:
|
$modules/etcd3.py:
|
||||||
ignore: vfauth
|
ignore: vfauth
|
||||||
maintainers: evrardjp
|
maintainers: evrardjp
|
||||||
$modules/facter.py:
|
|
||||||
labels: facter
|
|
||||||
maintainers: $team_ansible_core gamethis
|
|
||||||
$modules/facter_facts.py:
|
$modules/facter_facts.py:
|
||||||
labels: facter
|
labels: facter
|
||||||
maintainers: russoz $team_ansible_core gamethis
|
maintainers: russoz $team_ansible_core gamethis
|
||||||
|
@ -1610,7 +1601,6 @@ macros:
|
||||||
team_networking: NilashishC Qalthos danielmellado ganeshrn justjais trishnaguha sganesh-infoblox privateip
|
team_networking: NilashishC Qalthos danielmellado ganeshrn justjais trishnaguha sganesh-infoblox privateip
|
||||||
team_opennebula: ilicmilan meerkampdvv rsmontero xorel nilsding
|
team_opennebula: ilicmilan meerkampdvv rsmontero xorel nilsding
|
||||||
team_oracle: manojmeda mross22 nalsaber
|
team_oracle: manojmeda mross22 nalsaber
|
||||||
team_purestorage: bannaych dnix101 genegr lionmax opslounge raekins sdodsley sile16
|
|
||||||
team_redfish: mraineri tomasg2012 xmadsen renxulei rajeevkallur bhavya06 jyundt
|
team_redfish: mraineri tomasg2012 xmadsen renxulei rajeevkallur bhavya06 jyundt
|
||||||
team_rhsm: cnsnyder ptoscano
|
team_rhsm: cnsnyder ptoscano
|
||||||
team_scaleway: remyleone abarbare
|
team_scaleway: remyleone abarbare
|
||||||
|
|
16
changelogs/fragments/deprecations.yml
Normal file
16
changelogs/fragments/deprecations.yml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
removed_features:
|
||||||
|
- "yaml callback plugin - the deprecated plugin has been removed. Use the default callback with ``result_format=yaml`` instead (https://github.com/ansible-collections/community.general/pull/10883)."
|
||||||
|
- "purestorage doc fragment - the modules using this doc fragment have been removed from community.general 3.0.0 (https://github.com/ansible-collections/community.general/pull/10883)."
|
||||||
|
- "pure module utils - the modules using this module utils have been removed from community.general 3.0.0 (https://github.com/ansible-collections/community.general/pull/10883)."
|
||||||
|
- "bearychat - the module has been removed as the chat service is no longer available (https://github.com/ansible-collections/community.general/pull/10883)."
|
||||||
|
- "facter - the module has been replaced by ``community.general.facter_facts`` (https://github.com/ansible-collections/community.general/pull/10883)."
|
||||||
|
- "pacemaker_cluster - the option ``state`` is now required (https://github.com/ansible-collections/community.general/pull/10883)."
|
||||||
|
- >-
|
||||||
|
opkg - the value ``""`` for the option ``force`` is no longer allowed. Omit ``force`` instead (https://github.com/ansible-collections/community.general/pull/10883).
|
||||||
|
- "cmd_runner_fmt module utils - the parameter ``ctx_ignore_none`` to argument formatters has been removed (https://github.com/ansible-collections/community.general/pull/10883)."
|
||||||
|
- "cmd_runner module utils - the parameter ``ignore_value_none`` to ``CmdRunner.__call__()`` has been removed (https://github.com/ansible-collections/community.general/pull/10883)."
|
||||||
|
- >-
|
||||||
|
mh.deco module utils - the parameters ``on_success`` and ``on_failure`` of ``cause()`` have been removed; use ``when="success"`` and ``when="failure"`` instead (https://github.com/ansible-collections/community.general/pull/10883).
|
||||||
|
breaking_changes:
|
||||||
|
- "slack - the default of ``prepend_hash`` changed from ``auto`` to ``never`` (https://github.com/ansible-collections/community.general/pull/10883)."
|
||||||
|
- "mh.base module utils - ``debug`` will now always be delegated to the underlying ``AnsibleModule`` object (https://github.com/ansible-collections/community.general/pull/10883)."
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
namespace: community
|
namespace: community
|
||||||
name: general
|
name: general
|
||||||
version: 11.4.0
|
version: 12.0.0
|
||||||
readme: README.md
|
readme: README.md
|
||||||
authors:
|
authors:
|
||||||
- Ansible (https://github.com/ansible)
|
- Ansible (https://github.com/ansible)
|
||||||
|
|
|
@ -100,7 +100,7 @@ plugin_routing:
|
||||||
warning_text: Use the 'default' callback plugin with 'display_failed_stderr
|
warning_text: Use the 'default' callback plugin with 'display_failed_stderr
|
||||||
= yes' option.
|
= yes' option.
|
||||||
yaml:
|
yaml:
|
||||||
deprecation:
|
tombstone:
|
||||||
removal_version: 12.0.0
|
removal_version: 12.0.0
|
||||||
warning_text: >-
|
warning_text: >-
|
||||||
The plugin has been superseded by the option `result_format=yaml` in callback plugin ansible.builtin.default from ansible-core 2.13 onwards.
|
The plugin has been superseded by the option `result_format=yaml` in callback plugin ansible.builtin.default from ansible-core 2.13 onwards.
|
||||||
|
@ -153,7 +153,7 @@ plugin_routing:
|
||||||
removal_version: 13.0.0
|
removal_version: 13.0.0
|
||||||
warning_text: Project Atomic was sunset by the end of 2019.
|
warning_text: Project Atomic was sunset by the end of 2019.
|
||||||
bearychat:
|
bearychat:
|
||||||
deprecation:
|
tombstone:
|
||||||
removal_version: 12.0.0
|
removal_version: 12.0.0
|
||||||
warning_text: Chat service is no longer available.
|
warning_text: Chat service is no longer available.
|
||||||
catapult:
|
catapult:
|
||||||
|
@ -257,7 +257,7 @@ plugin_routing:
|
||||||
docker_volume_info:
|
docker_volume_info:
|
||||||
redirect: community.docker.docker_volume_info
|
redirect: community.docker.docker_volume_info
|
||||||
facter:
|
facter:
|
||||||
deprecation:
|
tombstone:
|
||||||
removal_version: 12.0.0
|
removal_version: 12.0.0
|
||||||
warning_text: Use community.general.facter_facts instead.
|
warning_text: Use community.general.facter_facts instead.
|
||||||
flowdock:
|
flowdock:
|
||||||
|
@ -1084,7 +1084,7 @@ plugin_routing:
|
||||||
removal_version: 15.0.0
|
removal_version: 15.0.0
|
||||||
warning_text: The proxmox content has been moved to community.proxmox.
|
warning_text: The proxmox content has been moved to community.proxmox.
|
||||||
purestorage:
|
purestorage:
|
||||||
deprecation:
|
tombstone:
|
||||||
removal_version: 12.0.0
|
removal_version: 12.0.0
|
||||||
warning_text: The modules for purestorage were removed in community.general 3.0.0, this document fragment was left behind.
|
warning_text: The modules for purestorage were removed in community.general 3.0.0, this document fragment was left behind.
|
||||||
rackspace:
|
rackspace:
|
||||||
|
@ -1121,7 +1121,7 @@ plugin_routing:
|
||||||
removal_version: 15.0.0
|
removal_version: 15.0.0
|
||||||
warning_text: The proxmox content has been moved to community.proxmox.
|
warning_text: The proxmox content has been moved to community.proxmox.
|
||||||
pure:
|
pure:
|
||||||
deprecation:
|
tombstone:
|
||||||
removal_version: 12.0.0
|
removal_version: 12.0.0
|
||||||
warning_text: The modules for purestorage were removed in community.general 3.0.0, this module util was left behind.
|
warning_text: The modules for purestorage were removed in community.general 3.0.0, this module util was left behind.
|
||||||
rax:
|
rax:
|
||||||
|
|
|
@ -1,195 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2017 Ansible Project
|
|
||||||
# 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
|
|
||||||
|
|
||||||
# Make coding more python3-ish
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
DOCUMENTATION = r"""
|
|
||||||
author: Unknown (!UNKNOWN)
|
|
||||||
name: yaml
|
|
||||||
type: stdout
|
|
||||||
short_description: YAML-ized Ansible screen output
|
|
||||||
deprecated:
|
|
||||||
removed_in: 12.0.0
|
|
||||||
why: Starting in ansible-core 2.13, the P(ansible.builtin.default#callback) callback has support for printing output in
|
|
||||||
YAML format.
|
|
||||||
alternative: Use O(ansible.builtin.default#callback:result_format=yaml).
|
|
||||||
description:
|
|
||||||
- Ansible output that can be quite a bit easier to read than the default JSON formatting.
|
|
||||||
extends_documentation_fragment:
|
|
||||||
- default_callback
|
|
||||||
requirements:
|
|
||||||
- set as stdout in configuration
|
|
||||||
seealso:
|
|
||||||
- plugin: ansible.builtin.default
|
|
||||||
plugin_type: callback
|
|
||||||
description: >-
|
|
||||||
There is a parameter O(ansible.builtin.default#callback:result_format) in P(ansible.builtin.default#callback) that allows
|
|
||||||
you to change the output format to YAML.
|
|
||||||
notes:
|
|
||||||
- With ansible-core 2.13 or newer, you can instead specify V(yaml) for the parameter O(ansible.builtin.default#callback:result_format)
|
|
||||||
in P(ansible.builtin.default#callback).
|
|
||||||
"""
|
|
||||||
|
|
||||||
import yaml
|
|
||||||
import json
|
|
||||||
import re
|
|
||||||
import string
|
|
||||||
from collections.abc import Mapping, Sequence
|
|
||||||
|
|
||||||
from ansible.module_utils.common.text.converters import to_text
|
|
||||||
from ansible.plugins.callback import strip_internal_keys, module_response_deepcopy
|
|
||||||
from ansible.plugins.callback.default import CallbackModule as Default
|
|
||||||
|
|
||||||
|
|
||||||
# from http://stackoverflow.com/a/15423007/115478
|
|
||||||
def should_use_block(value):
|
|
||||||
"""Returns true if string should be in block format"""
|
|
||||||
for c in "\u000a\u000d\u001c\u001d\u001e\u0085\u2028\u2029":
|
|
||||||
if c in value:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def adjust_str_value_for_block(value):
|
|
||||||
# we care more about readable than accuracy, so...
|
|
||||||
# ...no trailing space
|
|
||||||
value = value.rstrip()
|
|
||||||
# ...and non-printable characters
|
|
||||||
value = ''.join(x for x in value if x in string.printable or ord(x) >= 0xA0)
|
|
||||||
# ...tabs prevent blocks from expanding
|
|
||||||
value = value.expandtabs()
|
|
||||||
# ...and odd bits of whitespace
|
|
||||||
value = re.sub(r'[\x0b\x0c\r]', '', value)
|
|
||||||
# ...as does trailing space
|
|
||||||
value = re.sub(r' +\n', '\n', value)
|
|
||||||
return value
|
|
||||||
|
|
||||||
|
|
||||||
def create_string_node(tag, value, style, default_style):
|
|
||||||
if style is None:
|
|
||||||
if should_use_block(value):
|
|
||||||
style = '|'
|
|
||||||
value = adjust_str_value_for_block(value)
|
|
||||||
else:
|
|
||||||
style = default_style
|
|
||||||
return yaml.representer.ScalarNode(tag, value, style=style)
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
|
||||||
from ansible.module_utils.common.yaml import HAS_LIBYAML
|
|
||||||
# import below was added in https://github.com/ansible/ansible/pull/85039,
|
|
||||||
# first contained in ansible-core 2.19.0b2:
|
|
||||||
from ansible.utils.vars import transform_to_native_types
|
|
||||||
|
|
||||||
if HAS_LIBYAML:
|
|
||||||
from yaml.cyaml import CSafeDumper as SafeDumper
|
|
||||||
else:
|
|
||||||
from yaml import SafeDumper
|
|
||||||
|
|
||||||
class MyDumper(SafeDumper):
|
|
||||||
def represent_scalar(self, tag, value, style=None):
|
|
||||||
"""Uses block style for multi-line strings"""
|
|
||||||
node = create_string_node(tag, value, style, self.default_style)
|
|
||||||
if self.alias_key is not None:
|
|
||||||
self.represented_objects[self.alias_key] = node
|
|
||||||
return node
|
|
||||||
|
|
||||||
except ImportError:
|
|
||||||
# In case transform_to_native_types cannot be imported, we either have ansible-core 2.19.0b1
|
|
||||||
# (or some random commit from the devel or stable-2.19 branch after merging the DT changes
|
|
||||||
# and before transform_to_native_types was added), or we have a version without the DT changes.
|
|
||||||
|
|
||||||
# Here we simply assume we have a version without the DT changes, and thus can continue as
|
|
||||||
# with ansible-core 2.18 and before.
|
|
||||||
|
|
||||||
transform_to_native_types = None
|
|
||||||
|
|
||||||
from ansible.parsing.yaml.dumper import AnsibleDumper
|
|
||||||
|
|
||||||
class MyDumper(AnsibleDumper): # pylint: disable=inherit-non-class
|
|
||||||
def represent_scalar(self, tag, value, style=None):
|
|
||||||
"""Uses block style for multi-line strings"""
|
|
||||||
node = create_string_node(tag, value, style, self.default_style)
|
|
||||||
if self.alias_key is not None:
|
|
||||||
self.represented_objects[self.alias_key] = node
|
|
||||||
return node
|
|
||||||
|
|
||||||
|
|
||||||
def transform_recursively(value, transform):
|
|
||||||
# Since 2.19.0b7, this should no longer be needed:
|
|
||||||
# https://github.com/ansible/ansible/issues/85325
|
|
||||||
# https://github.com/ansible/ansible/pull/85389
|
|
||||||
if isinstance(value, Mapping):
|
|
||||||
return {transform(k): transform(v) for k, v in value.items()}
|
|
||||||
if isinstance(value, Sequence) and not isinstance(value, (str, bytes)):
|
|
||||||
return [transform(e) for e in value]
|
|
||||||
return transform(value)
|
|
||||||
|
|
||||||
|
|
||||||
class CallbackModule(Default):
|
|
||||||
|
|
||||||
"""
|
|
||||||
Variation of the Default output which uses nicely readable YAML instead
|
|
||||||
of JSON for printing results.
|
|
||||||
"""
|
|
||||||
|
|
||||||
CALLBACK_VERSION = 2.0
|
|
||||||
CALLBACK_TYPE = 'stdout'
|
|
||||||
CALLBACK_NAME = 'community.general.yaml'
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super(CallbackModule, self).__init__()
|
|
||||||
|
|
||||||
def _dump_results(self, result, indent=None, sort_keys=True, keep_invocation=False):
|
|
||||||
if result.get('_ansible_no_log', False):
|
|
||||||
return json.dumps(dict(censored="The output has been hidden due to the fact that 'no_log: true' was specified for this result"))
|
|
||||||
|
|
||||||
# All result keys stating with _ansible_ are internal, so remove them from the result before we output anything.
|
|
||||||
abridged_result = strip_internal_keys(module_response_deepcopy(result))
|
|
||||||
|
|
||||||
# remove invocation unless specifically wanting it
|
|
||||||
if not keep_invocation and self._display.verbosity < 3 and 'invocation' in result:
|
|
||||||
del abridged_result['invocation']
|
|
||||||
|
|
||||||
# remove diff information from screen output
|
|
||||||
if self._display.verbosity < 3 and 'diff' in result:
|
|
||||||
del abridged_result['diff']
|
|
||||||
|
|
||||||
# remove exception from screen output
|
|
||||||
if 'exception' in abridged_result:
|
|
||||||
del abridged_result['exception']
|
|
||||||
|
|
||||||
dumped = ''
|
|
||||||
|
|
||||||
# put changed and skipped into a header line
|
|
||||||
if 'changed' in abridged_result:
|
|
||||||
dumped += f"changed={str(abridged_result['changed']).lower()} "
|
|
||||||
del abridged_result['changed']
|
|
||||||
|
|
||||||
if 'skipped' in abridged_result:
|
|
||||||
dumped += f"skipped={str(abridged_result['skipped']).lower()} "
|
|
||||||
del abridged_result['skipped']
|
|
||||||
|
|
||||||
# if we already have stdout, we don't need stdout_lines
|
|
||||||
if 'stdout' in abridged_result and 'stdout_lines' in abridged_result:
|
|
||||||
abridged_result['stdout_lines'] = '<omitted>'
|
|
||||||
|
|
||||||
# if we already have stderr, we don't need stderr_lines
|
|
||||||
if 'stderr' in abridged_result and 'stderr_lines' in abridged_result:
|
|
||||||
abridged_result['stderr_lines'] = '<omitted>'
|
|
||||||
|
|
||||||
if abridged_result:
|
|
||||||
dumped += '\n'
|
|
||||||
if transform_to_native_types is not None:
|
|
||||||
abridged_result = transform_recursively(abridged_result, lambda v: transform_to_native_types(v, redact=False))
|
|
||||||
dumped += to_text(yaml.dump(abridged_result, allow_unicode=True, width=1000, Dumper=MyDumper, default_flow_style=False))
|
|
||||||
|
|
||||||
# indent by a couple of spaces
|
|
||||||
dumped = '\n '.join(dumped.split('\n')).rstrip()
|
|
||||||
return dumped
|
|
||||||
|
|
||||||
def _serialize_diff(self, diff):
|
|
||||||
return to_text(yaml.dump(diff, allow_unicode=True, width=1000, Dumper=AnsibleDumper, default_flow_style=False))
|
|
|
@ -1,51 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Copyright (c) 2017, Simon Dodsley <simon@purestorage.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
|
|
||||||
|
|
||||||
|
|
||||||
class ModuleDocFragment(object):
|
|
||||||
|
|
||||||
# Documentation fragment for FlashBlade
|
|
||||||
FB = r"""
|
|
||||||
options:
|
|
||||||
fb_url:
|
|
||||||
description:
|
|
||||||
- FlashBlade management IP address or Hostname.
|
|
||||||
type: str
|
|
||||||
api_token:
|
|
||||||
description:
|
|
||||||
- FlashBlade API token for admin privileged user.
|
|
||||||
type: str
|
|
||||||
notes:
|
|
||||||
- This module requires the C(purity_fb) Python library.
|
|
||||||
- You must set E(PUREFB_URL) and E(PUREFB_API) environment variables if O(fb_url) and O(api_token) arguments are not passed
|
|
||||||
to the module directly.
|
|
||||||
requirements:
|
|
||||||
- purity_fb >= 1.1
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Documentation fragment for FlashArray
|
|
||||||
FA = r"""
|
|
||||||
options:
|
|
||||||
fa_url:
|
|
||||||
description:
|
|
||||||
- FlashArray management IPv4 address or Hostname.
|
|
||||||
type: str
|
|
||||||
required: true
|
|
||||||
api_token:
|
|
||||||
description:
|
|
||||||
- FlashArray API token for admin privileged user.
|
|
||||||
type: str
|
|
||||||
required: true
|
|
||||||
notes:
|
|
||||||
- This module requires the C(purestorage) Python library.
|
|
||||||
- You must set E(PUREFA_URL) and E(PUREFA_API) environment variables if O(fa_url) and O(api_token) arguments are not passed
|
|
||||||
to the module directly.
|
|
||||||
requirements:
|
|
||||||
- purestorage
|
|
||||||
"""
|
|
|
@ -132,16 +132,7 @@ class CmdRunner(object):
|
||||||
def binary(self):
|
def binary(self):
|
||||||
return self.command[0]
|
return self.command[0]
|
||||||
|
|
||||||
# remove parameter ignore_value_none in community.general 12.0.0
|
def __call__(self, args_order=None, output_process=None, check_mode_skip=False, check_mode_return=None, **kwargs):
|
||||||
def __call__(self, args_order=None, output_process=None, ignore_value_none=None, check_mode_skip=False, check_mode_return=None, **kwargs):
|
|
||||||
if ignore_value_none is None:
|
|
||||||
ignore_value_none = True
|
|
||||||
else:
|
|
||||||
self.module.deprecate(
|
|
||||||
"Using ignore_value_none when creating the runner context is now deprecated, "
|
|
||||||
"and the parameter will be removed in community.general 12.0.0. ",
|
|
||||||
version="12.0.0", collection_name="community.general"
|
|
||||||
)
|
|
||||||
if output_process is None:
|
if output_process is None:
|
||||||
output_process = _process_as_is
|
output_process = _process_as_is
|
||||||
if args_order is None:
|
if args_order is None:
|
||||||
|
@ -153,7 +144,6 @@ class CmdRunner(object):
|
||||||
return _CmdRunnerContext(runner=self,
|
return _CmdRunnerContext(runner=self,
|
||||||
args_order=args_order,
|
args_order=args_order,
|
||||||
output_process=output_process,
|
output_process=output_process,
|
||||||
ignore_value_none=ignore_value_none, # DEPRECATION: remove in community.general 12.0.0
|
|
||||||
check_mode_skip=check_mode_skip,
|
check_mode_skip=check_mode_skip,
|
||||||
check_mode_return=check_mode_return, **kwargs)
|
check_mode_return=check_mode_return, **kwargs)
|
||||||
|
|
||||||
|
@ -165,12 +155,10 @@ class CmdRunner(object):
|
||||||
|
|
||||||
|
|
||||||
class _CmdRunnerContext(object):
|
class _CmdRunnerContext(object):
|
||||||
def __init__(self, runner, args_order, output_process, ignore_value_none, check_mode_skip, check_mode_return, **kwargs):
|
def __init__(self, runner, args_order, output_process, check_mode_skip, check_mode_return, **kwargs):
|
||||||
self.runner = runner
|
self.runner = runner
|
||||||
self.args_order = tuple(args_order)
|
self.args_order = tuple(args_order)
|
||||||
self.output_process = output_process
|
self.output_process = output_process
|
||||||
# DEPRECATION: parameter ignore_value_none at the context level is deprecated and will be removed in community.general 12.0.0
|
|
||||||
self.ignore_value_none = ignore_value_none
|
|
||||||
self.check_mode_skip = check_mode_skip
|
self.check_mode_skip = check_mode_skip
|
||||||
self.check_mode_return = check_mode_return
|
self.check_mode_return = check_mode_return
|
||||||
self.run_command_args = dict(kwargs)
|
self.run_command_args = dict(kwargs)
|
||||||
|
@ -209,8 +197,7 @@ class _CmdRunnerContext(object):
|
||||||
value = named_args[arg_name]
|
value = named_args[arg_name]
|
||||||
elif not runner.arg_formats[arg_name].ignore_missing_value:
|
elif not runner.arg_formats[arg_name].ignore_missing_value:
|
||||||
raise MissingArgumentValue(self.args_order, arg_name)
|
raise MissingArgumentValue(self.args_order, arg_name)
|
||||||
# DEPRECATION: remove parameter ctx_ignore_none in 12.0.0
|
self.cmd.extend(runner.arg_formats[arg_name](value))
|
||||||
self.cmd.extend(runner.arg_formats[arg_name](value, ctx_ignore_none=self.ignore_value_none))
|
|
||||||
except MissingArgumentValue:
|
except MissingArgumentValue:
|
||||||
raise
|
raise
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -226,7 +213,6 @@ class _CmdRunnerContext(object):
|
||||||
@property
|
@property
|
||||||
def run_info(self):
|
def run_info(self):
|
||||||
return dict(
|
return dict(
|
||||||
ignore_value_none=self.ignore_value_none, # DEPRECATION: remove in community.general 12.0.0
|
|
||||||
check_rc=self.check_rc,
|
check_rc=self.check_rc,
|
||||||
environ_update=self.environ_update,
|
environ_update=self.environ_update,
|
||||||
args_order=self.args_order,
|
args_order=self.args_order,
|
||||||
|
|
|
@ -16,16 +16,13 @@ def _ensure_list(value):
|
||||||
|
|
||||||
|
|
||||||
class _ArgFormat(object):
|
class _ArgFormat(object):
|
||||||
# DEPRECATION: set default value for ignore_none to True in community.general 12.0.0
|
def __init__(self, func, ignore_none=True, ignore_missing_value=False):
|
||||||
def __init__(self, func, ignore_none=None, ignore_missing_value=False):
|
|
||||||
self.func = func
|
self.func = func
|
||||||
self.ignore_none = ignore_none
|
self.ignore_none = ignore_none
|
||||||
self.ignore_missing_value = ignore_missing_value
|
self.ignore_missing_value = ignore_missing_value
|
||||||
|
|
||||||
# DEPRECATION: remove parameter ctx_ignore_none in community.general 12.0.0
|
def __call__(self, value):
|
||||||
def __call__(self, value, ctx_ignore_none=True):
|
ignore_none = self.ignore_none if self.ignore_none is not None else True
|
||||||
# DEPRECATION: replace ctx_ignore_none with True in community.general 12.0.0
|
|
||||||
ignore_none = self.ignore_none if self.ignore_none is not None else ctx_ignore_none
|
|
||||||
if value is None and ignore_none:
|
if value is None and ignore_none:
|
||||||
return []
|
return []
|
||||||
f = self.func
|
f = self.func
|
||||||
|
|
|
@ -15,9 +15,8 @@ from ansible_collections.community.general.plugins.module_utils.mh.deco import m
|
||||||
class ModuleHelperBase(object):
|
class ModuleHelperBase(object):
|
||||||
module = None
|
module = None
|
||||||
ModuleHelperException = _MHE
|
ModuleHelperException = _MHE
|
||||||
# in 12.0.0 add 'debug' to the tuple
|
|
||||||
_delegated_to_module = (
|
_delegated_to_module = (
|
||||||
'check_mode', 'get_bin_path', 'warn', 'deprecate',
|
'check_mode', 'get_bin_path', 'warn', 'deprecate', 'debug',
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, module=None):
|
def __init__(self, module=None):
|
||||||
|
@ -29,18 +28,6 @@ class ModuleHelperBase(object):
|
||||||
if not isinstance(self.module, AnsibleModule):
|
if not isinstance(self.module, AnsibleModule):
|
||||||
self.module = AnsibleModule(**self.module)
|
self.module = AnsibleModule(**self.module)
|
||||||
|
|
||||||
# in 12.0.0 remove this if statement entirely
|
|
||||||
if hasattr(self, 'debug'):
|
|
||||||
msg = (
|
|
||||||
"This class ({cls}) has an attribute 'debug' defined and that is deprecated. "
|
|
||||||
"Method 'debug' will be an integral part of ModuleHelper in community.general "
|
|
||||||
"12.0.0, delegated to the underlying AnsibleModule object. "
|
|
||||||
"Please rename the existing attribute to prevent this message from showing.".format(cls=self.__class__.__name__)
|
|
||||||
)
|
|
||||||
self.deprecate(msg, version="12.0.0", collection_name="community.general")
|
|
||||||
else:
|
|
||||||
self._delegated_to_module = self._delegated_to_module + ('debug',)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def diff_mode(self):
|
def diff_mode(self):
|
||||||
return self.module._diff
|
return self.module._diff
|
||||||
|
|
|
@ -13,22 +13,16 @@ from functools import wraps
|
||||||
from ansible_collections.community.general.plugins.module_utils.mh.exceptions import ModuleHelperException
|
from ansible_collections.community.general.plugins.module_utils.mh.exceptions import ModuleHelperException
|
||||||
|
|
||||||
|
|
||||||
def cause_changes(on_success=None, on_failure=None, when=None):
|
def cause_changes(when=None):
|
||||||
# Parameters on_success and on_failure are deprecated and should be removed in community.general 12.0.0
|
|
||||||
|
|
||||||
def deco(func):
|
def deco(func):
|
||||||
@wraps(func)
|
@wraps(func)
|
||||||
def wrapper(self, *args, **kwargs):
|
def wrapper(self, *args, **kwargs):
|
||||||
try:
|
try:
|
||||||
func(self, *args, **kwargs)
|
func(self, *args, **kwargs)
|
||||||
if on_success is not None:
|
if when == "success":
|
||||||
self.changed = on_success
|
|
||||||
elif when == "success":
|
|
||||||
self.changed = True
|
self.changed = True
|
||||||
except Exception:
|
except Exception:
|
||||||
if on_failure is not None:
|
if when == "failure":
|
||||||
self.changed = on_failure
|
|
||||||
elif when == "failure":
|
|
||||||
self.changed = True
|
self.changed = True
|
||||||
raise
|
raise
|
||||||
finally:
|
finally:
|
||||||
|
|
|
@ -1,115 +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), Simon Dodsley <simon@purestorage.com>,2017
|
|
||||||
# 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
|
|
||||||
|
|
||||||
HAS_PURESTORAGE = True
|
|
||||||
try:
|
|
||||||
from purestorage import purestorage
|
|
||||||
except ImportError:
|
|
||||||
HAS_PURESTORAGE = False
|
|
||||||
|
|
||||||
HAS_PURITY_FB = True
|
|
||||||
try:
|
|
||||||
from purity_fb import PurityFb, FileSystem, FileSystemSnapshot, SnapshotSuffix, rest # noqa: F401, pylint: disable=unused-import
|
|
||||||
except ImportError:
|
|
||||||
HAS_PURITY_FB = False
|
|
||||||
|
|
||||||
# (TODO: remove next line!)
|
|
||||||
from functools import wraps # noqa: F401, pylint: disable=unused-import
|
|
||||||
from os import environ
|
|
||||||
# (TODO: remove next line!)
|
|
||||||
from os import path # noqa: F401, pylint: disable=unused-import
|
|
||||||
import platform
|
|
||||||
|
|
||||||
VERSION = 1.2
|
|
||||||
USER_AGENT_BASE = 'Ansible'
|
|
||||||
API_AGENT_VERSION = 1.5
|
|
||||||
|
|
||||||
|
|
||||||
def get_system(module):
|
|
||||||
"""Return System Object or Fail"""
|
|
||||||
user_agent = '%(base)s %(class)s/%(version)s (%(platform)s)' % {
|
|
||||||
'base': USER_AGENT_BASE,
|
|
||||||
'class': __name__,
|
|
||||||
'version': VERSION,
|
|
||||||
'platform': platform.platform()
|
|
||||||
}
|
|
||||||
array_name = module.params['fa_url']
|
|
||||||
api = module.params['api_token']
|
|
||||||
|
|
||||||
if array_name and api:
|
|
||||||
system = purestorage.FlashArray(array_name, api_token=api, user_agent=user_agent)
|
|
||||||
elif environ.get('PUREFA_URL') and environ.get('PUREFA_API'):
|
|
||||||
system = purestorage.FlashArray(environ.get('PUREFA_URL'), api_token=(environ.get('PUREFA_API')), user_agent=user_agent)
|
|
||||||
else:
|
|
||||||
module.fail_json(msg="You must set PUREFA_URL and PUREFA_API environment variables or the fa_url and api_token module arguments")
|
|
||||||
try:
|
|
||||||
system.get()
|
|
||||||
except Exception:
|
|
||||||
module.fail_json(msg="Pure Storage FlashArray authentication failed. Check your credentials")
|
|
||||||
return system
|
|
||||||
|
|
||||||
|
|
||||||
def get_blade(module):
|
|
||||||
"""Return System Object or Fail"""
|
|
||||||
user_agent = '%(base)s %(class)s/%(version)s (%(platform)s)' % {
|
|
||||||
'base': USER_AGENT_BASE,
|
|
||||||
'class': __name__,
|
|
||||||
'version': VERSION,
|
|
||||||
'platform': platform.platform()
|
|
||||||
}
|
|
||||||
blade_name = module.params['fb_url']
|
|
||||||
api = module.params['api_token']
|
|
||||||
|
|
||||||
if blade_name and api:
|
|
||||||
blade = PurityFb(blade_name)
|
|
||||||
blade.disable_verify_ssl()
|
|
||||||
try:
|
|
||||||
blade.login(api)
|
|
||||||
versions = blade.api_version.list_versions().versions
|
|
||||||
if API_AGENT_VERSION in versions:
|
|
||||||
blade._api_client.user_agent = user_agent
|
|
||||||
except rest.ApiException as e:
|
|
||||||
module.fail_json(msg="Pure Storage FlashBlade authentication failed. Check your credentials")
|
|
||||||
elif environ.get('PUREFB_URL') and environ.get('PUREFB_API'):
|
|
||||||
blade = PurityFb(environ.get('PUREFB_URL'))
|
|
||||||
blade.disable_verify_ssl()
|
|
||||||
try:
|
|
||||||
blade.login(environ.get('PUREFB_API'))
|
|
||||||
versions = blade.api_version.list_versions().versions
|
|
||||||
if API_AGENT_VERSION in versions:
|
|
||||||
blade._api_client.user_agent = user_agent
|
|
||||||
except rest.ApiException as e:
|
|
||||||
module.fail_json(msg="Pure Storage FlashBlade authentication failed. Check your credentials")
|
|
||||||
else:
|
|
||||||
module.fail_json(msg="You must set PUREFB_URL and PUREFB_API environment variables or the fb_url and api_token module arguments")
|
|
||||||
return blade
|
|
||||||
|
|
||||||
|
|
||||||
def purefa_argument_spec():
|
|
||||||
"""Return standard base dictionary used for the argument_spec argument in AnsibleModule"""
|
|
||||||
|
|
||||||
return dict(
|
|
||||||
fa_url=dict(),
|
|
||||||
api_token=dict(no_log=True),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def purefb_argument_spec():
|
|
||||||
"""Return standard base dictionary used for the argument_spec argument in AnsibleModule"""
|
|
||||||
|
|
||||||
return dict(
|
|
||||||
fb_url=dict(),
|
|
||||||
api_token=dict(no_log=True),
|
|
||||||
)
|
|
|
@ -1,176 +0,0 @@
|
||||||
#!/usr/bin/python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (c) 2016, Jiangge Zhang <tonyseek@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
|
|
||||||
|
|
||||||
DOCUMENTATION = r"""
|
|
||||||
module: bearychat
|
|
||||||
short_description: Send BearyChat notifications
|
|
||||||
description:
|
|
||||||
- The M(community.general.bearychat) module sends notifications to U(https://bearychat.com) using the Incoming Robot integration.
|
|
||||||
deprecated:
|
|
||||||
removed_in: 12.0.0
|
|
||||||
why: Chat service is no longer available.
|
|
||||||
alternative: There is none.
|
|
||||||
author: "Jiangge Zhang (@tonyseek)"
|
|
||||||
extends_documentation_fragment:
|
|
||||||
- community.general.attributes
|
|
||||||
attributes:
|
|
||||||
check_mode:
|
|
||||||
support: none
|
|
||||||
diff_mode:
|
|
||||||
support: none
|
|
||||||
options:
|
|
||||||
url:
|
|
||||||
type: str
|
|
||||||
description:
|
|
||||||
- BearyChat WebHook URL. This authenticates you to the bearychat service. It looks like
|
|
||||||
V(https://hook.bearychat.com/=ae2CF/incoming/e61bd5c57b164e04b11ac02e66f47f60).
|
|
||||||
required: true
|
|
||||||
text:
|
|
||||||
type: str
|
|
||||||
description:
|
|
||||||
- Message to send.
|
|
||||||
markdown:
|
|
||||||
description:
|
|
||||||
- If V(true), text is parsed as markdown.
|
|
||||||
default: true
|
|
||||||
type: bool
|
|
||||||
channel:
|
|
||||||
type: str
|
|
||||||
description:
|
|
||||||
- Channel to send the message to. If absent, the message goes to the default channel selected by the O(url).
|
|
||||||
attachments:
|
|
||||||
type: list
|
|
||||||
elements: dict
|
|
||||||
description:
|
|
||||||
- Define a list of attachments. For more information, see
|
|
||||||
U(https://github.com/bearyinnovative/bearychat-tutorial/blob/master/robots/incoming.md#attachments).
|
|
||||||
"""
|
|
||||||
|
|
||||||
EXAMPLES = r"""
|
|
||||||
- name: Send notification message via BearyChat
|
|
||||||
local_action:
|
|
||||||
module: bearychat
|
|
||||||
url: |
|
|
||||||
https://hook.bearychat.com/=ae2CF/incoming/e61bd5c57b164e04b11ac02e66f47f60
|
|
||||||
text: "{{ inventory_hostname }} completed"
|
|
||||||
|
|
||||||
- name: Send notification message via BearyChat all options
|
|
||||||
local_action:
|
|
||||||
module: bearychat
|
|
||||||
url: |
|
|
||||||
https://hook.bearychat.com/=ae2CF/incoming/e61bd5c57b164e04b11ac02e66f47f60
|
|
||||||
text: "{{ inventory_hostname }} completed"
|
|
||||||
markdown: false
|
|
||||||
channel: "#ansible"
|
|
||||||
attachments:
|
|
||||||
- title: "Ansible on {{ inventory_hostname }}"
|
|
||||||
text: "May the Force be with you."
|
|
||||||
color: "#ffffff"
|
|
||||||
images:
|
|
||||||
- http://example.com/index.png
|
|
||||||
"""
|
|
||||||
|
|
||||||
RETURN = r"""
|
|
||||||
msg:
|
|
||||||
description: Execution result.
|
|
||||||
returned: success
|
|
||||||
type: str
|
|
||||||
sample: "OK"
|
|
||||||
"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
from ansible.module_utils.six.moves.urllib.parse import urlparse, urlunparse
|
|
||||||
HAS_URLPARSE = True
|
|
||||||
except Exception:
|
|
||||||
HAS_URLPARSE = False
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
|
||||||
from ansible.module_utils.urls import fetch_url
|
|
||||||
|
|
||||||
|
|
||||||
def build_payload_for_bearychat(module, text, markdown, channel, attachments):
|
|
||||||
payload = {}
|
|
||||||
if text is not None:
|
|
||||||
payload['text'] = text
|
|
||||||
if markdown is not None:
|
|
||||||
payload['markdown'] = markdown
|
|
||||||
if channel is not None:
|
|
||||||
payload['channel'] = channel
|
|
||||||
if attachments is not None:
|
|
||||||
payload.setdefault('attachments', []).extend(
|
|
||||||
build_payload_for_bearychat_attachment(
|
|
||||||
module, item.get('title'), item.get('text'), item.get('color'),
|
|
||||||
item.get('images'))
|
|
||||||
for item in attachments)
|
|
||||||
payload = 'payload=%s' % module.jsonify(payload)
|
|
||||||
return payload
|
|
||||||
|
|
||||||
|
|
||||||
def build_payload_for_bearychat_attachment(module, title, text, color, images):
|
|
||||||
attachment = {}
|
|
||||||
if title is not None:
|
|
||||||
attachment['title'] = title
|
|
||||||
if text is not None:
|
|
||||||
attachment['text'] = text
|
|
||||||
if color is not None:
|
|
||||||
attachment['color'] = color
|
|
||||||
if images is not None:
|
|
||||||
target_images = attachment.setdefault('images', [])
|
|
||||||
if not isinstance(images, (list, tuple)):
|
|
||||||
images = [images]
|
|
||||||
for image in images:
|
|
||||||
if isinstance(image, dict) and 'url' in image:
|
|
||||||
image = {'url': image['url']}
|
|
||||||
elif hasattr(image, 'startswith') and image.startswith('http'):
|
|
||||||
image = {'url': image}
|
|
||||||
else:
|
|
||||||
module.fail_json(
|
|
||||||
msg="BearyChat doesn't have support for this kind of "
|
|
||||||
"attachment image")
|
|
||||||
target_images.append(image)
|
|
||||||
return attachment
|
|
||||||
|
|
||||||
|
|
||||||
def do_notify_bearychat(module, url, payload):
|
|
||||||
response, info = fetch_url(module, url, data=payload)
|
|
||||||
if info['status'] != 200:
|
|
||||||
url_info = urlparse(url)
|
|
||||||
obscured_incoming_webhook = urlunparse(
|
|
||||||
(url_info.scheme, url_info.netloc, '[obscured]', '', '', ''))
|
|
||||||
module.fail_json(
|
|
||||||
msg=" failed to send %s to %s: %s" % (
|
|
||||||
payload, obscured_incoming_webhook, info['msg']))
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
module = AnsibleModule(argument_spec={
|
|
||||||
'url': dict(type='str', required=True, no_log=True),
|
|
||||||
'text': dict(type='str'),
|
|
||||||
'markdown': dict(default=True, type='bool'),
|
|
||||||
'channel': dict(type='str'),
|
|
||||||
'attachments': dict(type='list', elements='dict'),
|
|
||||||
})
|
|
||||||
|
|
||||||
if not HAS_URLPARSE:
|
|
||||||
module.fail_json(msg='urlparse is not installed')
|
|
||||||
|
|
||||||
url = module.params['url']
|
|
||||||
text = module.params['text']
|
|
||||||
markdown = module.params['markdown']
|
|
||||||
channel = module.params['channel']
|
|
||||||
attachments = module.params['attachments']
|
|
||||||
|
|
||||||
payload = build_payload_for_bearychat(
|
|
||||||
module, text, markdown, channel, attachments)
|
|
||||||
do_notify_bearychat(module, url, payload)
|
|
||||||
|
|
||||||
module.exit_json(msg="OK")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
|
@ -1,82 +0,0 @@
|
||||||
#!/usr/bin/python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Copyright (c) 2012, Michael DeHaan <michael.dehaan@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
|
|
||||||
|
|
||||||
DOCUMENTATION = r"""
|
|
||||||
module: facter
|
|
||||||
short_description: Runs the discovery program C(facter) on the remote system
|
|
||||||
description:
|
|
||||||
- Runs the C(facter) discovery program (U(https://github.com/puppetlabs/facter)) on the remote system, returning JSON data
|
|
||||||
that can be useful for inventory purposes.
|
|
||||||
deprecated:
|
|
||||||
removed_in: 12.0.0
|
|
||||||
why: The module has been replaced by M(community.general.facter_facts).
|
|
||||||
alternative: Use M(community.general.facter_facts) instead.
|
|
||||||
extends_documentation_fragment:
|
|
||||||
- community.general.attributes
|
|
||||||
attributes:
|
|
||||||
check_mode:
|
|
||||||
support: none
|
|
||||||
diff_mode:
|
|
||||||
support: none
|
|
||||||
options:
|
|
||||||
arguments:
|
|
||||||
description:
|
|
||||||
- Specifies arguments for facter.
|
|
||||||
type: list
|
|
||||||
elements: str
|
|
||||||
requirements:
|
|
||||||
- facter
|
|
||||||
- ruby-json
|
|
||||||
author:
|
|
||||||
- Ansible Core Team
|
|
||||||
- Michael DeHaan
|
|
||||||
"""
|
|
||||||
|
|
||||||
EXAMPLES = r"""
|
|
||||||
# Example command-line invocation
|
|
||||||
# ansible www.example.net -m facter
|
|
||||||
|
|
||||||
- name: Execute facter no arguments
|
|
||||||
community.general.facter:
|
|
||||||
|
|
||||||
- name: Execute facter with arguments
|
|
||||||
community.general.facter:
|
|
||||||
arguments:
|
|
||||||
- -p
|
|
||||||
- system_uptime
|
|
||||||
- timezone
|
|
||||||
- is_virtual
|
|
||||||
"""
|
|
||||||
import json
|
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
module = AnsibleModule(
|
|
||||||
argument_spec=dict(
|
|
||||||
arguments=dict(type='list', elements='str')
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
facter_path = module.get_bin_path(
|
|
||||||
'facter',
|
|
||||||
opt_dirs=['/opt/puppetlabs/bin'])
|
|
||||||
|
|
||||||
cmd = [facter_path, "--json"]
|
|
||||||
if module.params['arguments']:
|
|
||||||
cmd += module.params['arguments']
|
|
||||||
|
|
||||||
rc, out, err = module.run_command(cmd, check_rc=True)
|
|
||||||
module.exit_json(**json.loads(out))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
|
@ -13,7 +13,7 @@ DOCUMENTATION = r"""
|
||||||
module: ohai
|
module: ohai
|
||||||
short_description: Returns inventory data from I(Ohai)
|
short_description: Returns inventory data from I(Ohai)
|
||||||
description:
|
description:
|
||||||
- Similar to the M(community.general.facter) module, this runs the I(Ohai) discovery program (U(https://docs.chef.io/ohai.html))
|
- Similar to the M(community.general.facter_facts) module, this runs the I(Ohai) discovery program (U(https://docs.chef.io/ohai.html))
|
||||||
on the remote host and returns JSON inventory data. I(Ohai) data is a bit more verbose and nested than I(facter).
|
on the remote host and returns JSON inventory data. I(Ohai) data is a bit more verbose and nested than I(facter).
|
||||||
extends_documentation_fragment:
|
extends_documentation_fragment:
|
||||||
- community.general.attributes
|
- community.general.attributes
|
||||||
|
|
|
@ -43,10 +43,7 @@ options:
|
||||||
force:
|
force:
|
||||||
description:
|
description:
|
||||||
- The C(opkg --force) parameter used.
|
- The C(opkg --force) parameter used.
|
||||||
- State V("") is deprecated and will be removed in community.general 12.0.0. Please omit the parameter O(force) to obtain
|
|
||||||
the same behavior.
|
|
||||||
choices:
|
choices:
|
||||||
- ""
|
|
||||||
- "depends"
|
- "depends"
|
||||||
- "maintainer"
|
- "maintainer"
|
||||||
- "reinstall"
|
- "reinstall"
|
||||||
|
@ -128,7 +125,7 @@ class Opkg(StateModuleHelper):
|
||||||
argument_spec=dict(
|
argument_spec=dict(
|
||||||
name=dict(aliases=["pkg"], required=True, type="list", elements="str"),
|
name=dict(aliases=["pkg"], required=True, type="list", elements="str"),
|
||||||
state=dict(default="present", choices=["present", "installed", "absent", "removed"]),
|
state=dict(default="present", choices=["present", "installed", "absent", "removed"]),
|
||||||
force=dict(choices=["", "depends", "maintainer", "reinstall", "overwrite", "downgrade", "space",
|
force=dict(choices=["depends", "maintainer", "reinstall", "overwrite", "downgrade", "space",
|
||||||
"postinstall", "remove", "checksum", "removal-of-dependent-packages"]),
|
"postinstall", "remove", "checksum", "removal-of-dependent-packages"]),
|
||||||
update_cache=dict(default=False, type='bool'),
|
update_cache=dict(default=False, type='bool'),
|
||||||
executable=dict(type="path"),
|
executable=dict(type="path"),
|
||||||
|
@ -147,15 +144,6 @@ class Opkg(StateModuleHelper):
|
||||||
removed="remove",
|
removed="remove",
|
||||||
)
|
)
|
||||||
|
|
||||||
def _force(value):
|
|
||||||
# 12.0.0 function _force() to be removed entirely
|
|
||||||
if value == "":
|
|
||||||
self.deprecate('Value "" is deprecated. Simply omit the parameter "force" to prevent any --force-X argument when running opkg',
|
|
||||||
version="12.0.0",
|
|
||||||
collection_name="community.general")
|
|
||||||
value = None
|
|
||||||
return cmd_runner_fmt.as_optval("--force-")(value, ctx_ignore_none=True)
|
|
||||||
|
|
||||||
dir, cmd = os.path.split(self.vars.executable) if self.vars.executable else (None, "opkg")
|
dir, cmd = os.path.split(self.vars.executable) if self.vars.executable else (None, "opkg")
|
||||||
|
|
||||||
self.runner = CmdRunner(
|
self.runner = CmdRunner(
|
||||||
|
@ -164,7 +152,7 @@ class Opkg(StateModuleHelper):
|
||||||
arg_formats=dict(
|
arg_formats=dict(
|
||||||
package=cmd_runner_fmt.as_list(),
|
package=cmd_runner_fmt.as_list(),
|
||||||
state=cmd_runner_fmt.as_map(state_map),
|
state=cmd_runner_fmt.as_map(state_map),
|
||||||
force=cmd_runner_fmt.as_func(_force), # 12.0.0 replace with cmd_runner_fmt.as_optval("--force-")
|
force=cmd_runner_fmt.as_optval("--force-"),
|
||||||
update_cache=cmd_runner_fmt.as_bool("update"),
|
update_cache=cmd_runner_fmt.as_bool("update"),
|
||||||
version=cmd_runner_fmt.as_fixed("--version"),
|
version=cmd_runner_fmt.as_fixed("--version"),
|
||||||
),
|
),
|
||||||
|
|
|
@ -30,6 +30,7 @@ options:
|
||||||
- The value V(maintenance) has been added in community.general 11.1.0.
|
- The value V(maintenance) has been added in community.general 11.1.0.
|
||||||
choices: [cleanup, offline, online, restart, maintenance]
|
choices: [cleanup, offline, online, restart, maintenance]
|
||||||
type: str
|
type: str
|
||||||
|
required: true
|
||||||
name:
|
name:
|
||||||
description:
|
description:
|
||||||
- Specify which node of the cluster you want to manage. V(null) == the cluster status itself, V(all) == check the status
|
- Specify which node of the cluster you want to manage. V(null) == the cluster status itself, V(all) == check the status
|
||||||
|
@ -74,7 +75,7 @@ class PacemakerCluster(StateModuleHelper):
|
||||||
module = dict(
|
module = dict(
|
||||||
argument_spec=dict(
|
argument_spec=dict(
|
||||||
state=dict(type='str', choices=[
|
state=dict(type='str', choices=[
|
||||||
'cleanup', 'offline', 'online', 'restart', 'maintenance']),
|
'cleanup', 'offline', 'online', 'restart', 'maintenance'], required=True),
|
||||||
name=dict(type='str', aliases=['node']),
|
name=dict(type='str', aliases=['node']),
|
||||||
timeout=dict(type='int', default=300),
|
timeout=dict(type='int', default=300),
|
||||||
force=dict(type='bool', default=True)
|
force=dict(type='bool', default=True)
|
||||||
|
@ -106,13 +107,6 @@ class PacemakerCluster(StateModuleHelper):
|
||||||
collection_name='community.general'
|
collection_name='community.general'
|
||||||
)
|
)
|
||||||
|
|
||||||
if not self.module.params['state']:
|
|
||||||
self.module.deprecate(
|
|
||||||
'Parameter "state" values not set is being deprecated. Make sure to provide a value for "state"',
|
|
||||||
version='12.0.0',
|
|
||||||
collection_name='community.general'
|
|
||||||
)
|
|
||||||
|
|
||||||
def __quit_module__(self):
|
def __quit_module__(self):
|
||||||
self.vars.set('value', self._get()['out'])
|
self.vars.set('value', self._get()['out'])
|
||||||
|
|
||||||
|
|
|
@ -143,10 +143,10 @@ options:
|
||||||
prefixes only cover a small set of the prefixes that should not have a V(#) prepended. Since an exact condition which
|
prefixes only cover a small set of the prefixes that should not have a V(#) prepended. Since an exact condition which
|
||||||
O(channel) values must not have the V(#) prefix is not known, the value V(auto) for this option is deprecated in the
|
O(channel) values must not have the V(#) prefix is not known, the value V(auto) for this option is deprecated in the
|
||||||
future. It is best to explicitly set O(prepend_hash=always) or O(prepend_hash=never) to obtain the needed behavior.
|
future. It is best to explicitly set O(prepend_hash=always) or O(prepend_hash=never) to obtain the needed behavior.
|
||||||
- The B(current default) is V(auto), which has been B(deprecated) since community.general 10.2.0. It is going to change
|
- Before community.general 12.0.0, the default was V(auto). It has been deprecated since community.general 10.2.0.
|
||||||
to V(never) in community.general 12.0.0. To prevent deprecation warnings you can explicitly set O(prepend_hash) to
|
- Note that V(auto) will be deprecated in a future version.
|
||||||
the value you want. We suggest to only use V(always) or V(never), but not V(auto), when explicitly setting a value.
|
# TODO: Deprecate 'auto' in community.general 13.0.0
|
||||||
# when the default changes in community.general 12.0.0, add deprecation for the `auto` value for 14.0.0
|
default: never
|
||||||
choices:
|
choices:
|
||||||
- 'always'
|
- 'always'
|
||||||
- 'never'
|
- 'never'
|
||||||
|
@ -466,7 +466,7 @@ def main():
|
||||||
attachments=dict(type='list', elements='dict'),
|
attachments=dict(type='list', elements='dict'),
|
||||||
blocks=dict(type='list', elements='dict'),
|
blocks=dict(type='list', elements='dict'),
|
||||||
message_id=dict(type='str'),
|
message_id=dict(type='str'),
|
||||||
prepend_hash=dict(type='str', choices=['always', 'never', 'auto']),
|
prepend_hash=dict(type='str', choices=['always', 'never', 'auto'], default='never'),
|
||||||
),
|
),
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
|
@ -487,15 +487,6 @@ def main():
|
||||||
message_id = module.params['message_id']
|
message_id = module.params['message_id']
|
||||||
prepend_hash = module.params['prepend_hash']
|
prepend_hash = module.params['prepend_hash']
|
||||||
|
|
||||||
if prepend_hash is None:
|
|
||||||
module.deprecate(
|
|
||||||
"The default value 'auto' for 'prepend_hash' is deprecated and will change to 'never' in community.general 12.0.0."
|
|
||||||
" You can explicitly set 'prepend_hash' in your task to avoid this deprecation warning",
|
|
||||||
version="12.0.0",
|
|
||||||
collection_name="community.general",
|
|
||||||
)
|
|
||||||
prepend_hash = 'auto'
|
|
||||||
|
|
||||||
color_choices = ['normal', 'good', 'warning', 'danger']
|
color_choices = ['normal', 'good', 'warning', 'danger']
|
||||||
if color not in color_choices and not is_valid_hex_color(color):
|
if color not in color_choices and not is_valid_hex_color(color):
|
||||||
module.fail_json(msg="Color value specified should be either one of %r "
|
module.fail_json(msg="Color value specified should be either one of %r "
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
# Copyright (c) Ansible Project
|
|
||||||
# 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
|
|
||||||
|
|
||||||
azp/posix/1
|
|
||||||
needs/target/callback
|
|
|
@ -1,7 +0,0 @@
|
||||||
---
|
|
||||||
# Copyright (c) Ansible Project
|
|
||||||
# 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
|
|
||||||
|
|
||||||
dependencies:
|
|
||||||
- setup_remote_tmp_dir
|
|
|
@ -1,143 +0,0 @@
|
||||||
---
|
|
||||||
####################################################################
|
|
||||||
# WARNING: These are designed specifically for Ansible tests #
|
|
||||||
# and should not be used as examples of how to write Ansible roles #
|
|
||||||
####################################################################
|
|
||||||
|
|
||||||
# Copyright (c) Ansible Project
|
|
||||||
# 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
|
|
||||||
|
|
||||||
- name: Write vault password to disk
|
|
||||||
ansible.builtin.copy:
|
|
||||||
dest: "{{ remote_tmp_dir }}/vault-password"
|
|
||||||
content: asdf
|
|
||||||
|
|
||||||
- name: Run tests
|
|
||||||
include_role:
|
|
||||||
name: callback
|
|
||||||
vars:
|
|
||||||
tests:
|
|
||||||
- name: Basic run
|
|
||||||
environment:
|
|
||||||
ANSIBLE_NOCOLOR: 'true'
|
|
||||||
ANSIBLE_FORCE_COLOR: 'false'
|
|
||||||
ANSIBLE_STDOUT_CALLBACK: community.general.yaml
|
|
||||||
playbook: |
|
|
||||||
- hosts: testhost
|
|
||||||
gather_facts: false
|
|
||||||
tasks:
|
|
||||||
- name: Sample task name
|
|
||||||
debug:
|
|
||||||
msg: sample debug msg
|
|
||||||
expected_output:
|
|
||||||
- ""
|
|
||||||
- "PLAY [testhost] ****************************************************************"
|
|
||||||
- ""
|
|
||||||
- "TASK [Sample task name] ********************************************************"
|
|
||||||
- "ok: [testhost] => "
|
|
||||||
- " msg: sample debug msg"
|
|
||||||
- ""
|
|
||||||
- "PLAY RECAP *********************************************************************"
|
|
||||||
- "testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
|
|
||||||
|
|
||||||
- name: Test umlauts in multiline
|
|
||||||
environment:
|
|
||||||
ANSIBLE_NOCOLOR: 'true'
|
|
||||||
ANSIBLE_FORCE_COLOR: 'false'
|
|
||||||
ANSIBLE_STDOUT_CALLBACK: community.general.yaml
|
|
||||||
playbook: |
|
|
||||||
- hosts: testhost
|
|
||||||
gather_facts: false
|
|
||||||
tasks:
|
|
||||||
- name: Umlaut output
|
|
||||||
debug:
|
|
||||||
msg: "äöü\néêè\nßï☺"
|
|
||||||
expected_output:
|
|
||||||
- ""
|
|
||||||
- "PLAY [testhost] ****************************************************************"
|
|
||||||
- ""
|
|
||||||
- "TASK [Umlaut output] ***********************************************************"
|
|
||||||
- "ok: [testhost] => "
|
|
||||||
- " msg: |-"
|
|
||||||
- " äöü"
|
|
||||||
- " éêè"
|
|
||||||
- " ßï☺"
|
|
||||||
- ""
|
|
||||||
- "PLAY RECAP *********************************************************************"
|
|
||||||
- "testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
|
|
||||||
|
|
||||||
- name: Test to_yaml
|
|
||||||
environment:
|
|
||||||
ANSIBLE_NOCOLOR: 'true'
|
|
||||||
ANSIBLE_FORCE_COLOR: 'false'
|
|
||||||
ANSIBLE_STDOUT_CALLBACK: community.general.yaml
|
|
||||||
playbook: !unsafe |
|
|
||||||
- hosts: testhost
|
|
||||||
gather_facts: false
|
|
||||||
vars:
|
|
||||||
data: |
|
|
||||||
line 1
|
|
||||||
line 2
|
|
||||||
line 3
|
|
||||||
tasks:
|
|
||||||
- name: Test to_yaml
|
|
||||||
debug:
|
|
||||||
msg: "{{ data | to_yaml }}"
|
|
||||||
expected_output:
|
|
||||||
- ""
|
|
||||||
- "PLAY [testhost] ****************************************************************"
|
|
||||||
- ""
|
|
||||||
- "TASK [Test to_yaml] ************************************************************"
|
|
||||||
- "ok: [testhost] => "
|
|
||||||
- " msg: |-"
|
|
||||||
- " 'line 1"
|
|
||||||
- " "
|
|
||||||
- " line 2"
|
|
||||||
- " "
|
|
||||||
- " line 3"
|
|
||||||
- " "
|
|
||||||
- " '"
|
|
||||||
- ""
|
|
||||||
- "PLAY RECAP *********************************************************************"
|
|
||||||
- "testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
|
|
||||||
- name: Some more fun with data tagging
|
|
||||||
environment:
|
|
||||||
ANSIBLE_NOCOLOR: 'true'
|
|
||||||
ANSIBLE_FORCE_COLOR: 'false'
|
|
||||||
ANSIBLE_STDOUT_CALLBACK: community.general.yaml
|
|
||||||
extra_cli_arguments: "--vault-password-file {{ remote_tmp_dir }}/vault-password"
|
|
||||||
playbook: !unsafe |
|
|
||||||
- hosts: testhost
|
|
||||||
gather_facts: false
|
|
||||||
vars:
|
|
||||||
foo: bar
|
|
||||||
baz: !vault |
|
|
||||||
$ANSIBLE_VAULT;1.1;AES256
|
|
||||||
30393064316433636636373336363538663034643135363938646665393661353833633865313765
|
|
||||||
3835366434646339313337663335393865336163663434310a316161313662666466333332353731
|
|
||||||
64663064366461643162666137303737643164376134303034306366383830336232363837636638
|
|
||||||
3830653338626130360a313639623231353931356563313065373661303262646337383534663932
|
|
||||||
64353461663065333362346264326335373032313333343539646661656634653138646332313639
|
|
||||||
3566313765626464613734623664663266336237646139373935
|
|
||||||
tasks:
|
|
||||||
- name: Test regular string
|
|
||||||
debug:
|
|
||||||
var: foo
|
|
||||||
- name: Test vaulted string
|
|
||||||
debug:
|
|
||||||
var: baz
|
|
||||||
expected_output:
|
|
||||||
- ""
|
|
||||||
- "PLAY [testhost] ****************************************************************"
|
|
||||||
- ""
|
|
||||||
- "TASK [Test regular string] *****************************************************"
|
|
||||||
- "ok: [testhost] => "
|
|
||||||
- " foo: bar"
|
|
||||||
- ""
|
|
||||||
- "TASK [Test vaulted string] *****************************************************"
|
|
||||||
- "ok: [testhost] => "
|
|
||||||
- " baz: aBcDeFgHiJkLmNoPqRsTuVwXyZ012345"
|
|
||||||
- ""
|
|
||||||
- "PLAY RECAP *********************************************************************"
|
|
||||||
- "testhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
|
|
|
@ -205,7 +205,7 @@ TC_RUNNER = dict(
|
||||||
results="0-/-ni-/-nu"
|
results="0-/-ni-/-nu"
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
aa_bb_ignore_none_with_none=(
|
aa_bb_with_none=(
|
||||||
dict(
|
dict(
|
||||||
args_bundle=dict(
|
args_bundle=dict(
|
||||||
aa=dict(type="int", value=49, fmt_func=cmd_runner_fmt.as_opt_eq_val, fmt_arg="--answer"),
|
aa=dict(type="int", value=49, fmt_func=cmd_runner_fmt.as_opt_eq_val, fmt_arg="--answer"),
|
||||||
|
@ -214,7 +214,6 @@ TC_RUNNER = dict(
|
||||||
runner_init_args=dict(default_args_order=['bb', 'aa']),
|
runner_init_args=dict(default_args_order=['bb', 'aa']),
|
||||||
runner_ctx_args=dict(
|
runner_ctx_args=dict(
|
||||||
args_order=['aa', 'bb'],
|
args_order=['aa', 'bb'],
|
||||||
ignore_value_none=True, # default
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
dict(runner_ctx_run_args=dict(bb=None), rc=0, out="ni", err="nu"),
|
dict(runner_ctx_run_args=dict(bb=None), rc=0, out="ni", err="nu"),
|
||||||
|
@ -224,25 +223,6 @@ TC_RUNNER = dict(
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
aa_bb_ignore_not_none_with_none=(
|
|
||||||
dict(
|
|
||||||
args_bundle=dict(
|
|
||||||
aa=dict(type="int", value=49, fmt_func=cmd_runner_fmt.as_opt_eq_val, fmt_arg="--answer"),
|
|
||||||
bb=dict(fmt_func=cmd_runner_fmt.as_bool, fmt_arg="--bb-here"),
|
|
||||||
),
|
|
||||||
runner_init_args=dict(default_args_order=['bb', 'aa']),
|
|
||||||
runner_ctx_args=dict(
|
|
||||||
args_order=['aa', 'bb'],
|
|
||||||
ignore_value_none=False,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
dict(runner_ctx_run_args=dict(aa=None, bb=True), rc=0, out="ni", err="nu"),
|
|
||||||
dict(
|
|
||||||
run_info=dict(
|
|
||||||
cmd=['/mock/bin/testing', '--answer=None', '--bb-here'],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
aa_bb_fixed=(
|
aa_bb_fixed=(
|
||||||
dict(
|
dict(
|
||||||
args_bundle=dict(
|
args_bundle=dict(
|
||||||
|
|
|
@ -23,12 +23,6 @@ CAUSE_CHG_DECO_PARAMS = ['deco_args', 'expect_exception', 'expect_changed']
|
||||||
CAUSE_CHG_DECO = dict(
|
CAUSE_CHG_DECO = dict(
|
||||||
none_succ=dict(deco_args={}, expect_exception=False, expect_changed=None),
|
none_succ=dict(deco_args={}, expect_exception=False, expect_changed=None),
|
||||||
none_fail=dict(deco_args={}, expect_exception=True, expect_changed=None),
|
none_fail=dict(deco_args={}, expect_exception=True, expect_changed=None),
|
||||||
onsucc_succ=dict(deco_args=dict(on_success=True), expect_exception=False, expect_changed=True),
|
|
||||||
onsucc_fail=dict(deco_args=dict(on_success=True), expect_exception=True, expect_changed=None),
|
|
||||||
onfail_succ=dict(deco_args=dict(on_failure=True), expect_exception=False, expect_changed=None),
|
|
||||||
onfail_fail=dict(deco_args=dict(on_failure=True), expect_exception=True, expect_changed=True),
|
|
||||||
onboth_succ=dict(deco_args=dict(on_success=True, on_failure=True), expect_exception=False, expect_changed=True),
|
|
||||||
onboth_fail=dict(deco_args=dict(on_success=True, on_failure=True), expect_exception=True, expect_changed=True),
|
|
||||||
whensucc_succ=dict(deco_args=dict(when="success"), expect_exception=False, expect_changed=True),
|
whensucc_succ=dict(deco_args=dict(when="success"), expect_exception=False, expect_changed=True),
|
||||||
whensucc_fail=dict(deco_args=dict(when="success"), expect_exception=True, expect_changed=None),
|
whensucc_fail=dict(deco_args=dict(when="success"), expect_exception=True, expect_changed=None),
|
||||||
whenfail_succ=dict(deco_args=dict(when="failure"), expect_exception=False, expect_changed=None),
|
whenfail_succ=dict(deco_args=dict(when="failure"), expect_exception=False, expect_changed=None),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue