ansible-core 2.17.6__py3-none-any.whl → 2.18.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ansible-core might be problematic. Click here for more details.
- ansible/__main__.py +2 -17
- ansible/cli/__init__.py +3 -15
- ansible/cli/config.py +187 -24
- ansible/cli/console.py +1 -1
- ansible/cli/doc.py +38 -16
- ansible/cli/galaxy.py +3 -49
- ansible/cli/inventory.py +2 -2
- ansible/cli/pull.py +2 -2
- ansible/cli/scripts/ansible_connection_cli_stub.py +1 -10
- ansible/config/base.yml +127 -57
- ansible/config/manager.py +89 -11
- ansible/constants.py +32 -9
- ansible/errors/__init__.py +5 -0
- ansible/executor/interpreter_discovery.py +1 -1
- ansible/executor/play_iterator.py +16 -0
- ansible/executor/playbook_executor.py +1 -4
- ansible/executor/powershell/become_wrapper.ps1 +4 -5
- ansible/executor/powershell/bootstrap_wrapper.ps1 +2 -3
- ansible/executor/powershell/exec_wrapper.ps1 +1 -1
- ansible/executor/powershell/module_manifest.py +2 -2
- ansible/executor/task_executor.py +50 -39
- ansible/executor/task_queue_manager.py +1 -1
- ansible/executor/task_result.py +1 -1
- ansible/galaxy/api.py +3 -4
- ansible/galaxy/collection/__init__.py +21 -10
- ansible/galaxy/collection/concrete_artifact_manager.py +2 -2
- ansible/galaxy/collection/galaxy_api_proxy.py +10 -16
- ansible/galaxy/collection/gpg.py +17 -23
- ansible/galaxy/data/COPYING +7 -0
- ansible/galaxy/data/apb/Dockerfile.j2 +1 -0
- ansible/galaxy/data/apb/Makefile.j2 +1 -0
- ansible/galaxy/data/apb/README.md +7 -3
- ansible/galaxy/data/apb/apb.yml.j2 +1 -0
- ansible/galaxy/data/apb/defaults/main.yml.j2 +1 -0
- ansible/galaxy/data/apb/handlers/main.yml.j2 +1 -0
- ansible/galaxy/data/apb/meta/main.yml.j2 +1 -0
- ansible/galaxy/data/apb/playbooks/deprovision.yml.j2 +1 -0
- ansible/galaxy/data/apb/playbooks/provision.yml.j2 +1 -0
- ansible/galaxy/data/apb/tasks/main.yml.j2 +1 -0
- ansible/galaxy/data/apb/tests/ansible.cfg +1 -0
- ansible/galaxy/data/apb/tests/inventory +1 -0
- ansible/galaxy/data/apb/tests/test.yml.j2 +1 -0
- ansible/galaxy/data/apb/vars/main.yml.j2 +1 -0
- ansible/galaxy/data/collections_galaxy_meta.yml +1 -0
- ansible/galaxy/data/container/defaults/main.yml.j2 +1 -0
- ansible/galaxy/data/container/handlers/main.yml.j2 +1 -0
- ansible/galaxy/data/container/meta/container.yml.j2 +1 -0
- ansible/galaxy/data/container/meta/main.yml.j2 +1 -0
- ansible/galaxy/data/container/tasks/main.yml.j2 +1 -0
- ansible/galaxy/data/container/tests/ansible.cfg +1 -0
- ansible/galaxy/data/container/tests/inventory +1 -0
- ansible/galaxy/data/container/tests/test.yml.j2 +1 -0
- ansible/galaxy/data/container/vars/main.yml.j2 +1 -0
- ansible/galaxy/data/default/collection/README.md.j2 +1 -0
- ansible/galaxy/data/default/collection/galaxy.yml.j2 +1 -0
- ansible/galaxy/data/default/collection/meta/runtime.yml +1 -0
- ansible/galaxy/data/default/collection/plugins/README.md.j2 +1 -0
- ansible/galaxy/data/default/role/defaults/main.yml.j2 +1 -0
- ansible/galaxy/data/default/role/handlers/main.yml.j2 +1 -0
- ansible/galaxy/data/default/role/meta/main.yml.j2 +1 -0
- ansible/galaxy/data/default/role/tasks/main.yml.j2 +1 -0
- ansible/galaxy/data/default/role/tests/inventory +1 -0
- ansible/galaxy/data/default/role/tests/test.yml.j2 +1 -0
- ansible/galaxy/data/default/role/vars/main.yml.j2 +1 -0
- ansible/galaxy/data/network/cliconf_plugins/example.py.j2 +1 -0
- ansible/galaxy/data/network/defaults/main.yml.j2 +1 -0
- ansible/galaxy/data/network/library/example_command.py.j2 +1 -0
- ansible/galaxy/data/network/library/example_config.py.j2 +1 -0
- ansible/galaxy/data/network/library/example_facts.py.j2 +1 -0
- ansible/galaxy/data/network/meta/main.yml.j2 +1 -0
- ansible/galaxy/data/network/module_utils/example.py.j2 +1 -0
- ansible/galaxy/data/network/netconf_plugins/example.py.j2 +1 -0
- ansible/galaxy/data/network/tasks/main.yml.j2 +1 -0
- ansible/galaxy/data/network/terminal_plugins/example.py.j2 +1 -0
- ansible/galaxy/data/network/tests/inventory +1 -0
- ansible/galaxy/data/network/tests/test.yml.j2 +1 -0
- ansible/galaxy/data/network/vars/main.yml.j2 +1 -0
- ansible/galaxy/dependency_resolution/providers.py +3 -3
- ansible/galaxy/role.py +1 -1
- ansible/galaxy/token.py +20 -8
- ansible/keyword_desc.yml +1 -1
- ansible/module_utils/_internal/__init__.py +0 -0
- ansible/module_utils/_internal/_concurrent/__init__.py +0 -0
- ansible/module_utils/_internal/_concurrent/_daemon_threading.py +28 -0
- ansible/module_utils/_internal/_concurrent/_futures.py +21 -0
- ansible/module_utils/ansible_release.py +2 -2
- ansible/module_utils/api.py +2 -2
- ansible/module_utils/basic.py +8 -8
- ansible/module_utils/common/collections.py +1 -1
- ansible/module_utils/common/file.py +0 -6
- ansible/module_utils/common/process.py +22 -9
- ansible/module_utils/common/text/converters.py +5 -8
- ansible/module_utils/common/text/formatters.py +20 -4
- ansible/module_utils/common/validation.py +33 -25
- ansible/module_utils/compat/paramiko.py +6 -1
- ansible/module_utils/compat/selinux.py +2 -2
- ansible/module_utils/connection.py +8 -24
- ansible/module_utils/csharp/Ansible.Become.cs +14 -25
- ansible/module_utils/csharp/Ansible.Process.cs +1 -1
- ansible/module_utils/distro/__init__.py +1 -1
- ansible/module_utils/distro/_distro.py +8 -4
- ansible/module_utils/facts/collector.py +2 -0
- ansible/module_utils/facts/default_collectors.py +3 -1
- ansible/module_utils/facts/hardware/aix.py +54 -52
- ansible/module_utils/facts/hardware/darwin.py +37 -34
- ansible/module_utils/facts/hardware/freebsd.py +55 -15
- ansible/module_utils/facts/hardware/hpux.py +3 -0
- ansible/module_utils/facts/hardware/linux.py +101 -57
- ansible/module_utils/facts/hardware/netbsd.py +3 -0
- ansible/module_utils/facts/hardware/openbsd.py +4 -1
- ansible/module_utils/facts/hardware/sunos.py +7 -1
- ansible/module_utils/facts/network/aix.py +16 -17
- ansible/module_utils/facts/network/fc_wwn.py +4 -1
- ansible/module_utils/facts/network/hpux.py +21 -4
- ansible/module_utils/facts/network/iscsi.py +7 -8
- ansible/module_utils/facts/network/linux.py +0 -2
- ansible/module_utils/facts/other/facter.py +9 -4
- ansible/module_utils/facts/other/ohai.py +5 -5
- ansible/module_utils/facts/packages.py +49 -7
- ansible/module_utils/facts/sysctl.py +33 -31
- ansible/module_utils/facts/system/distribution.py +1 -1
- ansible/module_utils/facts/system/local.py +12 -22
- ansible/module_utils/facts/system/service_mgr.py +3 -1
- ansible/module_utils/facts/system/systemd.py +47 -0
- ansible/module_utils/powershell/Ansible.ModuleUtils.AddType.psm1 +1 -1
- ansible/module_utils/powershell/Ansible.ModuleUtils.CamelConversion.psm1 +1 -1
- ansible/module_utils/splitter.py +1 -1
- ansible/modules/add_host.py +1 -1
- ansible/modules/apt.py +43 -32
- ansible/modules/apt_key.py +6 -6
- ansible/modules/apt_repository.py +23 -14
- ansible/modules/assemble.py +7 -2
- ansible/modules/assert.py +4 -4
- ansible/modules/blockinfile.py +3 -6
- ansible/modules/command.py +1 -1
- ansible/modules/copy.py +4 -4
- ansible/modules/cron.py +13 -10
- ansible/modules/deb822_repository.py +16 -17
- ansible/modules/debconf.py +9 -9
- ansible/modules/debug.py +1 -1
- ansible/modules/dnf.py +79 -164
- ansible/modules/dnf5.py +54 -29
- ansible/modules/dpkg_selections.py +2 -2
- ansible/modules/expect.py +2 -2
- ansible/modules/fetch.py +2 -2
- ansible/modules/file.py +5 -3
- ansible/modules/find.py +40 -12
- ansible/modules/gather_facts.py +4 -2
- ansible/modules/get_url.py +29 -24
- ansible/modules/git.py +35 -35
- ansible/modules/group.py +71 -1
- ansible/modules/hostname.py +2 -4
- ansible/modules/include_vars.py +5 -5
- ansible/modules/iptables.py +13 -16
- ansible/modules/known_hosts.py +16 -13
- ansible/modules/lineinfile.py +1 -4
- ansible/modules/meta.py +6 -1
- ansible/modules/mount_facts.py +651 -0
- ansible/modules/package_facts.py +63 -80
- ansible/modules/pause.py +4 -3
- ansible/modules/pip.py +14 -14
- ansible/modules/replace.py +1 -4
- ansible/modules/rpm_key.py +31 -11
- ansible/modules/service.py +8 -8
- ansible/modules/service_facts.py +20 -5
- ansible/modules/set_stats.py +1 -1
- ansible/modules/setup.py +3 -3
- ansible/modules/stat.py +3 -3
- ansible/modules/subversion.py +1 -1
- ansible/modules/systemd.py +16 -10
- ansible/modules/systemd_service.py +16 -10
- ansible/modules/sysvinit.py +4 -4
- ansible/modules/unarchive.py +35 -22
- ansible/modules/uri.py +24 -18
- ansible/modules/user.py +145 -12
- ansible/modules/validate_argument_spec.py +3 -3
- ansible/modules/wait_for_connection.py +2 -1
- ansible/modules/yum_repository.py +136 -179
- ansible/parsing/dataloader.py +2 -2
- ansible/parsing/mod_args.py +11 -10
- ansible/parsing/vault/__init__.py +8 -3
- ansible/parsing/yaml/constructor.py +10 -8
- ansible/parsing/yaml/objects.py +1 -1
- ansible/playbook/base.py +12 -23
- ansible/playbook/helpers.py +4 -0
- ansible/playbook/loop_control.py +8 -0
- ansible/playbook/play.py +4 -22
- ansible/playbook/play_context.py +0 -16
- ansible/playbook/playbook_include.py +2 -2
- ansible/playbook/role/__init__.py +2 -2
- ansible/plugins/__init__.py +2 -0
- ansible/plugins/action/__init__.py +7 -9
- ansible/plugins/action/dnf.py +7 -5
- ansible/plugins/action/package.py +5 -4
- ansible/plugins/action/reboot.py +2 -2
- ansible/plugins/become/__init__.py +1 -1
- ansible/plugins/callback/__init__.py +44 -3
- ansible/plugins/callback/default.py +1 -1
- ansible/plugins/cliconf/__init__.py +1 -1
- ansible/plugins/connection/paramiko_ssh.py +2 -80
- ansible/plugins/connection/psrp.py +33 -82
- ansible/plugins/connection/ssh.py +0 -8
- ansible/plugins/connection/winrm.py +46 -1
- ansible/plugins/doc_fragments/connection_pipelining.py +2 -2
- ansible/plugins/doc_fragments/constructed.py +10 -10
- ansible/plugins/doc_fragments/default_callback.py +8 -8
- ansible/plugins/doc_fragments/files.py +5 -5
- ansible/plugins/doc_fragments/inventory_cache.py +2 -2
- ansible/plugins/doc_fragments/result_format_callback.py +6 -6
- ansible/plugins/doc_fragments/return_common.py +1 -1
- ansible/plugins/doc_fragments/shell_common.py +2 -10
- ansible/plugins/doc_fragments/shell_windows.py +0 -9
- ansible/plugins/doc_fragments/url.py +2 -2
- ansible/plugins/doc_fragments/url_windows.py +4 -5
- ansible/plugins/doc_fragments/validate.py +1 -1
- ansible/plugins/filter/core.py +2 -0
- ansible/plugins/filter/human_to_bytes.yml +9 -0
- ansible/plugins/filter/password_hash.yml +1 -1
- ansible/plugins/filter/strftime.yml +1 -1
- ansible/plugins/filter/to_nice_json.yml +7 -3
- ansible/plugins/filter/to_uuid.yml +1 -1
- ansible/plugins/inventory/script.py +1 -1
- ansible/plugins/list.py +1 -1
- ansible/plugins/loader.py +0 -11
- ansible/plugins/lookup/config.py +1 -1
- ansible/plugins/lookup/csvfile.py +21 -9
- ansible/plugins/lookup/env.py +8 -9
- ansible/plugins/lookup/ini.py +10 -1
- ansible/plugins/lookup/random_choice.py +2 -2
- ansible/plugins/lookup/url.py +7 -2
- ansible/plugins/shell/__init__.py +15 -20
- ansible/plugins/shell/powershell.py +9 -6
- ansible/plugins/strategy/__init__.py +16 -7
- ansible/plugins/test/core.py +23 -1
- ansible/plugins/test/issubset.yml +1 -1
- ansible/plugins/test/subset.yml +1 -1
- ansible/plugins/test/timedout.yml +20 -0
- ansible/plugins/test/vault_encrypted.yml +6 -6
- ansible/plugins/test/vaulted_file.yml +19 -0
- ansible/release.py +2 -2
- ansible/template/__init__.py +3 -8
- ansible/utils/collection_loader/_collection_finder.py +23 -55
- ansible/utils/display.py +44 -31
- ansible/utils/jsonrpc.py +1 -1
- ansible/utils/listify.py +1 -5
- ansible/utils/path.py +3 -0
- ansible/utils/vars.py +18 -27
- ansible/vars/manager.py +7 -150
- ansible/vars/plugins.py +1 -1
- ansible_core-2.18.0.dist-info/Apache-License.txt +202 -0
- {ansible_core-2.17.6.dist-info → ansible_core-2.18.0.dist-info}/METADATA +36 -23
- ansible_core-2.18.0.dist-info/MIT-license.txt +14 -0
- ansible_core-2.18.0.dist-info/PSF-license.txt +48 -0
- {ansible_core-2.17.6.dist-info → ansible_core-2.18.0.dist-info}/RECORD +316 -311
- {ansible_core-2.17.6.dist-info → ansible_core-2.18.0.dist-info}/entry_points.txt +1 -1
- ansible_core-2.18.0.dist-info/simplified_bsd.txt +8 -0
- ansible_test/_data/completion/docker.txt +7 -7
- ansible_test/_data/completion/remote.txt +5 -4
- ansible_test/_data/completion/windows.txt +4 -4
- ansible_test/_data/requirements/ansible-test.txt +1 -2
- ansible_test/_data/requirements/constraints.txt +1 -2
- ansible_test/_data/requirements/sanity.ansible-doc.txt +3 -3
- ansible_test/_data/requirements/sanity.changelog.in +1 -1
- ansible_test/_data/requirements/sanity.changelog.txt +4 -4
- ansible_test/_data/requirements/sanity.import.plugin.txt +2 -2
- ansible_test/_data/requirements/sanity.import.txt +1 -1
- ansible_test/_data/requirements/sanity.integration-aliases.txt +1 -1
- ansible_test/_data/requirements/sanity.pep8.txt +1 -1
- ansible_test/_data/requirements/sanity.pylint.txt +6 -8
- ansible_test/_data/requirements/sanity.runtime-metadata.txt +2 -2
- ansible_test/_data/requirements/sanity.validate-modules.txt +3 -3
- ansible_test/_data/requirements/sanity.yamllint.in +1 -0
- ansible_test/_data/requirements/sanity.yamllint.txt +1 -1
- ansible_test/_internal/ansible_util.py +8 -35
- ansible_test/_internal/ci/azp.py +1 -1
- ansible_test/_internal/classification/__init__.py +0 -2
- ansible_test/_internal/cli/parsers/key_value_parsers.py +3 -0
- ansible_test/_internal/commands/integration/cloud/hcloud.py +1 -1
- ansible_test/_internal/commands/integration/cloud/httptester.py +1 -1
- ansible_test/_internal/commands/integration/cloud/nios.py +1 -1
- ansible_test/_internal/commands/sanity/__init__.py +96 -19
- ansible_test/_internal/commands/sanity/pylint.py +20 -24
- ansible_test/_internal/completion.py +2 -0
- ansible_test/_internal/constants.py +0 -1
- ansible_test/_internal/coverage_util.py +1 -2
- ansible_test/_internal/docker_util.py +1 -1
- ansible_test/_internal/encoding.py +4 -4
- ansible_test/_internal/host_configs.py +10 -0
- ansible_test/_internal/host_profiles.py +9 -13
- ansible_test/_internal/pypi_proxy.py +1 -1
- ansible_test/_internal/python_requirements.py +5 -14
- ansible_test/_internal/timeout.py +1 -1
- ansible_test/_internal/util.py +40 -0
- ansible_test/_internal/util_common.py +5 -1
- ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.json +3 -1
- ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py +6 -3
- ansible_test/_util/controller/sanity/code-smell/empty-init.json +0 -2
- ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg +5 -0
- ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg +5 -0
- ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg +5 -0
- ansible_test/_util/controller/sanity/pylint/config/collection.cfg +6 -0
- ansible_test/_util/controller/sanity/pylint/config/default.cfg +6 -0
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated.py +1 -19
- ansible_test/_util/controller/sanity/shellcheck/exclude.txt +1 -0
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +67 -2
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +27 -5
- ansible_test/_util/target/cli/ansible_test_cli_stub.py +0 -0
- ansible_test/_util/target/common/constants.py +2 -2
- ansible_test/_util/target/injector/python.py +5 -0
- ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py +6 -0
- ansible_test/_util/target/sanity/import/importer.py +1 -1
- ansible_test/_util/target/setup/bootstrap.sh +6 -17
- ansible_test/_util/target/setup/requirements.py +18 -24
- ansible_test/config/config.yml +1 -1
- ansible_core-2.17.6.data/scripts/ansible-test +0 -44
- ansible_test/_data/requirements/sanity.mypy.in +0 -10
- ansible_test/_data/requirements/sanity.mypy.txt +0 -18
- ansible_test/_internal/commands/sanity/mypy.py +0 -274
- ansible_test/_util/controller/sanity/mypy/ansible-core.ini +0 -116
- ansible_test/_util/controller/sanity/mypy/ansible-test.ini +0 -27
- ansible_test/_util/controller/sanity/mypy/modules.ini +0 -92
- ansible_test/_util/controller/sanity/mypy/packaging.ini +0 -20
- {ansible_core-2.17.6.dist-info → ansible_core-2.18.0.dist-info}/COPYING +0 -0
- {ansible_core-2.17.6.dist-info → ansible_core-2.18.0.dist-info}/WHEEL +0 -0
- {ansible_core-2.17.6.dist-info → ansible_core-2.18.0.dist-info}/top_level.txt +0 -0
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
1
|
# Copyright: (c) 2017, Ansible Project
|
|
3
2
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
4
3
|
from __future__ import annotations
|
|
5
4
|
|
|
6
5
|
import fcntl
|
|
7
|
-
import hashlib
|
|
8
6
|
import io
|
|
9
7
|
import os
|
|
10
8
|
import pickle
|
|
@@ -40,13 +38,6 @@ def read_stream(byte_stream):
|
|
|
40
38
|
if len(data) < size:
|
|
41
39
|
raise Exception("EOF found before data was complete")
|
|
42
40
|
|
|
43
|
-
data_hash = to_text(byte_stream.readline().strip())
|
|
44
|
-
if data_hash != hashlib.sha1(data).hexdigest():
|
|
45
|
-
raise Exception("Read {0} bytes, but data did not match checksum".format(size))
|
|
46
|
-
|
|
47
|
-
# restore escaped loose \r characters
|
|
48
|
-
data = data.replace(br'\r', b'\r')
|
|
49
|
-
|
|
50
41
|
return data
|
|
51
42
|
|
|
52
43
|
|
|
@@ -221,7 +212,7 @@ def main(args=None):
|
|
|
221
212
|
""" Called to initiate the connect to the remote device
|
|
222
213
|
"""
|
|
223
214
|
|
|
224
|
-
parser = opt_help.create_base_parser(prog=
|
|
215
|
+
parser = opt_help.create_base_parser(prog=None)
|
|
225
216
|
opt_help.add_verbosity_options(parser)
|
|
226
217
|
parser.add_argument('playbook_pid')
|
|
227
218
|
parser.add_argument('task_uuid')
|
ansible/config/base.yml
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# Copyright (c) 2017 Ansible Project
|
|
2
2
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
3
3
|
---
|
|
4
|
+
_ANSIBLE_CONNECTION_PATH:
|
|
5
|
+
env:
|
|
6
|
+
- name: _ANSIBLE_CONNECTION_PATH
|
|
7
|
+
name: Overrides the location of the Ansible persistent connection helper script.
|
|
8
|
+
description:
|
|
9
|
+
- For internal use only.
|
|
10
|
+
type: path
|
|
11
|
+
version_added: "2.18"
|
|
4
12
|
ANSIBLE_HOME:
|
|
5
13
|
name: The Ansible home path
|
|
6
14
|
description:
|
|
@@ -25,6 +33,9 @@ ANSIBLE_CONNECTION_PATH:
|
|
|
25
33
|
- {key: ansible_connection_path, section: persistent_connection}
|
|
26
34
|
yaml: {key: persistent_connection.ansible_connection_path}
|
|
27
35
|
version_added: "2.8"
|
|
36
|
+
deprecated:
|
|
37
|
+
why: This setting has no effect.
|
|
38
|
+
version: "2.22"
|
|
28
39
|
ANSIBLE_COW_SELECTION:
|
|
29
40
|
name: Cowsay filter selection
|
|
30
41
|
default: default
|
|
@@ -293,6 +304,14 @@ COLOR_HIGHLIGHT:
|
|
|
293
304
|
env: [{name: ANSIBLE_COLOR_HIGHLIGHT}]
|
|
294
305
|
ini:
|
|
295
306
|
- {key: highlight, section: colors}
|
|
307
|
+
COLOR_INCLUDED:
|
|
308
|
+
name: Color for 'included' task status
|
|
309
|
+
default: cyan
|
|
310
|
+
description: Defines the color to use when showing 'Included' task status.
|
|
311
|
+
env: [{name: ANSIBLE_COLOR_INCLUDED}]
|
|
312
|
+
ini:
|
|
313
|
+
- {key: included, section: colors}
|
|
314
|
+
version_added: '2.18'
|
|
296
315
|
COLOR_OK:
|
|
297
316
|
name: Color for 'ok' task status
|
|
298
317
|
default: green
|
|
@@ -328,6 +347,54 @@ COLOR_WARN:
|
|
|
328
347
|
env: [{name: ANSIBLE_COLOR_WARN}]
|
|
329
348
|
ini:
|
|
330
349
|
- {key: warn, section: colors}
|
|
350
|
+
COLOR_DOC_MODULE:
|
|
351
|
+
name: Color for module name in the ansible-doc output
|
|
352
|
+
default: yellow
|
|
353
|
+
description: Defines the color to use when emitting a module name in the ansible-doc output.
|
|
354
|
+
env: [{name: ANSIBLE_COLOR_DOC_MODULE}]
|
|
355
|
+
ini:
|
|
356
|
+
- {key: doc_module, section: colors}
|
|
357
|
+
version_added: '2.18'
|
|
358
|
+
COLOR_DOC_REFERENCE:
|
|
359
|
+
name: Color for cross-reference in the ansible-doc output
|
|
360
|
+
default: magenta
|
|
361
|
+
description: Defines the color to use when emitting cross-reference in the ansible-doc output.
|
|
362
|
+
env: [{name: ANSIBLE_COLOR_DOC_REFERENCE}]
|
|
363
|
+
ini:
|
|
364
|
+
- {key: doc_reference, section: colors}
|
|
365
|
+
version_added: '2.18'
|
|
366
|
+
COLOR_DOC_LINK:
|
|
367
|
+
name: Color for Link in ansible-doc output
|
|
368
|
+
default: cyan
|
|
369
|
+
description: Defines the color to use when emitting a link in the ansible-doc output.
|
|
370
|
+
env: [{name: ANSIBLE_COLOR_DOC_LINK}]
|
|
371
|
+
ini:
|
|
372
|
+
- {key: doc_link, section: colors}
|
|
373
|
+
version_added: '2.18'
|
|
374
|
+
COLOR_DOC_DEPRECATED:
|
|
375
|
+
name: Color for deprecated value in ansible-doc output
|
|
376
|
+
default: magenta
|
|
377
|
+
description: Defines the color to use when emitting a deprecated value in the ansible-doc output.
|
|
378
|
+
env: [{name: ANSIBLE_COLOR_DOC_DEPRECATED}]
|
|
379
|
+
ini:
|
|
380
|
+
- {key: doc_deprecated, section: colors}
|
|
381
|
+
version_added: '2.18'
|
|
382
|
+
COLOR_DOC_CONSTANT:
|
|
383
|
+
name: Color for constant in ansible-doc output
|
|
384
|
+
default: dark gray
|
|
385
|
+
description: Defines the color to use when emitting a constant in the ansible-doc output.
|
|
386
|
+
env: [{name: ANSIBLE_COLOR_DOC_CONSTANT}]
|
|
387
|
+
ini:
|
|
388
|
+
- {key: doc_constant, section: colors}
|
|
389
|
+
version_added: '2.18'
|
|
390
|
+
COLOR_DOC_PLUGIN:
|
|
391
|
+
name: Color for the plugin in ansible-doc output
|
|
392
|
+
default: yellow
|
|
393
|
+
description: Defines the color to use when emitting a plugin name in the ansible-doc output.
|
|
394
|
+
env: [{name: ANSIBLE_COLOR_DOC_PLUGIN}]
|
|
395
|
+
ini:
|
|
396
|
+
- {key: doc_plugin, section: colors}
|
|
397
|
+
version_added: '2.18'
|
|
331
398
|
CONNECTION_PASSWORD_FILE:
|
|
332
399
|
name: Connection password file
|
|
333
400
|
default: ~
|
|
@@ -582,24 +649,6 @@ DEFAULT_EXECUTABLE:
|
|
|
582
649
|
env: [{name: ANSIBLE_EXECUTABLE}]
|
|
583
650
|
ini:
|
|
584
651
|
- {key: executable, section: defaults}
|
|
585
|
-
DEFAULT_FACT_PATH:
|
|
586
|
-
name: local fact path
|
|
587
|
-
description:
|
|
588
|
-
- "This option allows you to globally configure a custom path for 'local_facts' for the implied :ref:`ansible_collections.ansible.builtin.setup_module` task when using fact gathering."
|
|
589
|
-
- "If not set, it will fall back to the default from the ``ansible.builtin.setup`` module: ``/etc/ansible/facts.d``."
|
|
590
|
-
- "This does **not** affect user defined tasks that use the ``ansible.builtin.setup`` module."
|
|
591
|
-
- The real action being created by the implicit task is currently ``ansible.legacy.gather_facts`` module, which then calls the configured fact modules,
|
|
592
|
-
by default this will be ``ansible.builtin.setup`` for POSIX systems but other platforms might have different defaults.
|
|
593
|
-
env: [{name: ANSIBLE_FACT_PATH}]
|
|
594
|
-
ini:
|
|
595
|
-
- {key: fact_path, section: defaults}
|
|
596
|
-
type: string
|
|
597
|
-
deprecated:
|
|
598
|
-
# TODO: when removing set playbook/play.py to default=None
|
|
599
|
-
why: the module_defaults keyword is a more generic version and can apply to all calls to the
|
|
600
|
-
M(ansible.builtin.gather_facts) or M(ansible.builtin.setup) actions
|
|
601
|
-
version: "2.18"
|
|
602
|
-
alternatives: module_defaults
|
|
603
652
|
DEFAULT_FILTER_PLUGIN_PATH:
|
|
604
653
|
name: Jinja2 Filter Plugins Path
|
|
605
654
|
default: '{{ ANSIBLE_HOME ~ "/plugins/filter:/usr/share/ansible/plugins/filter" }}'
|
|
@@ -643,39 +692,6 @@ DEFAULT_GATHERING:
|
|
|
643
692
|
implicit: "the cache plugin will be ignored and facts will be gathered per play unless 'gather_facts: False' is set."
|
|
644
693
|
explicit: facts will not be gathered unless directly requested in the play.
|
|
645
694
|
smart: each new host that has no facts discovered will be scanned, but if the same host is addressed in multiple plays it will not be contacted again in the run.
|
|
646
|
-
DEFAULT_GATHER_SUBSET:
|
|
647
|
-
name: Gather facts subset
|
|
648
|
-
description:
|
|
649
|
-
- Set the `gather_subset` option for the :ref:`ansible_collections.ansible.builtin.setup_module` task in the implicit fact gathering.
|
|
650
|
-
See the module documentation for specifics.
|
|
651
|
-
- "It does **not** apply to user defined ``ansible.builtin.setup`` tasks."
|
|
652
|
-
env: [{name: ANSIBLE_GATHER_SUBSET}]
|
|
653
|
-
ini:
|
|
654
|
-
- key: gather_subset
|
|
655
|
-
section: defaults
|
|
656
|
-
version_added: "2.1"
|
|
657
|
-
type: list
|
|
658
|
-
deprecated:
|
|
659
|
-
# TODO: when removing set playbook/play.py to default=None
|
|
660
|
-
why: the module_defaults keyword is a more generic version and can apply to all calls to the
|
|
661
|
-
M(ansible.builtin.gather_facts) or M(ansible.builtin.setup) actions
|
|
662
|
-
version: "2.18"
|
|
663
|
-
alternatives: module_defaults
|
|
664
|
-
DEFAULT_GATHER_TIMEOUT:
|
|
665
|
-
name: Gather facts timeout
|
|
666
|
-
description:
|
|
667
|
-
- Set the timeout in seconds for the implicit fact gathering, see the module documentation for specifics.
|
|
668
|
-
- "It does **not** apply to user defined :ref:`ansible_collections.ansible.builtin.setup_module` tasks."
|
|
669
|
-
env: [{name: ANSIBLE_GATHER_TIMEOUT}]
|
|
670
|
-
ini:
|
|
671
|
-
- {key: gather_timeout, section: defaults}
|
|
672
|
-
type: integer
|
|
673
|
-
deprecated:
|
|
674
|
-
# TODO: when removing set playbook/play.py to default=None
|
|
675
|
-
why: the module_defaults keyword is a more generic version and can apply to all calls to the
|
|
676
|
-
M(ansible.builtin.gather_facts) or M(ansible.builtin.setup) actions
|
|
677
|
-
version: "2.18"
|
|
678
|
-
alternatives: module_defaults
|
|
679
695
|
DEFAULT_HASH_BEHAVIOUR:
|
|
680
696
|
name: Hash merge behaviour
|
|
681
697
|
default: replace
|
|
@@ -810,7 +826,9 @@ DEFAULT_LOCAL_TMP:
|
|
|
810
826
|
DEFAULT_LOG_PATH:
|
|
811
827
|
name: Ansible log file path
|
|
812
828
|
default: ~
|
|
813
|
-
description:
|
|
829
|
+
description:
|
|
830
|
+
- File to which Ansible will log on the controller.
|
|
831
|
+
- When not set the logging is disabled.
|
|
814
832
|
env: [{name: ANSIBLE_LOG_PATH}]
|
|
815
833
|
ini:
|
|
816
834
|
- {key: log_path, section: defaults}
|
|
@@ -1008,7 +1026,7 @@ DEFAULT_STDOUT_CALLBACK:
|
|
|
1008
1026
|
EDITOR:
|
|
1009
1027
|
name: editor application to use
|
|
1010
1028
|
default: vi
|
|
1011
|
-
|
|
1029
|
+
description:
|
|
1012
1030
|
- for the cases in which Ansible needs to return a file within an editor, this chooses the application to use.
|
|
1013
1031
|
ini:
|
|
1014
1032
|
- section: defaults
|
|
@@ -1510,6 +1528,23 @@ GALAXY_REQUIRED_VALID_SIGNATURE_COUNT:
|
|
|
1510
1528
|
- The number of signatures that must be successful during GPG signature verification while installing or verifying collections.
|
|
1511
1529
|
- This should be a positive integer or all to indicate all signatures must successfully validate the collection.
|
|
1512
1530
|
- Prepend + to the value to fail if no valid signatures are found for the collection.
|
|
1531
|
+
GALAXY_COLLECTION_IMPORT_POLL_INTERVAL:
|
|
1532
|
+
description:
|
|
1533
|
+
- The initial interval in seconds for polling the import status of a collection.
|
|
1534
|
+
- This interval increases exponentially based on the :ref:`galaxy_collection_import_poll_factor`, with a maximum delay of 30 seconds.
|
|
1535
|
+
type: float
|
|
1536
|
+
default: 2.0
|
|
1537
|
+
env:
|
|
1538
|
+
- name: ANSIBLE_GALAXY_COLLECTION_IMPORT_POLL_INTERVAL
|
|
1539
|
+
version_added: '2.18'
|
|
1540
|
+
GALAXY_COLLECTION_IMPORT_POLL_FACTOR:
|
|
1541
|
+
description:
|
|
1542
|
+
- The multiplier used to increase the :ref:`galaxy_collection_import_poll_interval` when checking the collection import status.
|
|
1543
|
+
type: float
|
|
1544
|
+
default: 1.5
|
|
1545
|
+
env:
|
|
1546
|
+
- name: ANSIBLE_GALAXY_COLLECTION_IMPORT_POLL_FACTOR
|
|
1547
|
+
version_added: "2.18"
|
|
1513
1548
|
HOST_KEY_CHECKING:
|
|
1514
1549
|
# NOTE: constant not in use by ssh/paramiko plugins anymore, but they do support the same configuration sources
|
|
1515
1550
|
# TODO: check non ssh connection plugins for use/migration
|
|
@@ -1562,12 +1597,12 @@ _INTERPRETER_PYTHON_DISTRO_MAP:
|
|
|
1562
1597
|
INTERPRETER_PYTHON_FALLBACK:
|
|
1563
1598
|
name: Ordered list of Python interpreters to check for in discovery
|
|
1564
1599
|
default:
|
|
1600
|
+
- python3.13
|
|
1565
1601
|
- python3.12
|
|
1566
1602
|
- python3.11
|
|
1567
1603
|
- python3.10
|
|
1568
1604
|
- python3.9
|
|
1569
1605
|
- python3.8
|
|
1570
|
-
- python3.7
|
|
1571
1606
|
- /usr/bin/python3
|
|
1572
1607
|
- python3
|
|
1573
1608
|
vars:
|
|
@@ -1771,7 +1806,7 @@ OLD_PLUGIN_CACHE_CLEARING:
|
|
|
1771
1806
|
PAGER:
|
|
1772
1807
|
name: pager application to use
|
|
1773
1808
|
default: less
|
|
1774
|
-
|
|
1809
|
+
description:
|
|
1775
1810
|
- for the cases in which Ansible needs to return output in a pageable fashion, this chooses the application to use.
|
|
1776
1811
|
ini:
|
|
1777
1812
|
- section: defaults
|
|
@@ -1973,7 +2008,11 @@ TASK_TIMEOUT:
|
|
|
1973
2008
|
name: Task Timeout
|
|
1974
2009
|
default: 0
|
|
1975
2010
|
description:
|
|
1976
|
-
- Set the maximum time (in seconds)
|
|
2011
|
+
- Set the maximum time (in seconds) for a task action to execute in.
|
|
2012
|
+
- Timeout runs independently from templating or looping.
|
|
2013
|
+
It applies per each attempt of executing the task's action and remains unchanged by the total time spent on a task.
|
|
2014
|
+
- When the action execution exceeds the timeout, Ansible interrupts the process.
|
|
2015
|
+
This is registered as a failure due to outside circumstances, not a task failure, to receive appropriate response and recovery process.
|
|
1977
2016
|
- If set to 0 (the default) there is no timeout.
|
|
1978
2017
|
env: [{name: ANSIBLE_TASK_TIMEOUT}]
|
|
1979
2018
|
ini:
|
|
@@ -2104,4 +2143,35 @@ VERBOSE_TO_STDERR:
|
|
|
2104
2143
|
- section: defaults
|
|
2105
2144
|
key: verbose_to_stderr
|
|
2106
2145
|
type: bool
|
|
2107
|
-
|
|
2146
|
+
_Z_TEST_ENTRY:
|
|
2147
|
+
name: testentry
|
|
2148
|
+
description: for tests
|
|
2149
|
+
env:
|
|
2150
|
+
- name: ANSIBLE_TEST_ENTRY
|
|
2151
|
+
- name: ANSIBLE_TEST_ENTRY_D
|
|
2152
|
+
deprecated:
|
|
2153
|
+
why: for testing
|
|
2154
|
+
version: '3.30'
|
|
2155
|
+
alternatives: nothing
|
|
2156
|
+
ini:
|
|
2157
|
+
- section: testing
|
|
2158
|
+
key: valid
|
|
2159
|
+
- section: testing
|
|
2160
|
+
key: deprecated
|
|
2161
|
+
deprecated:
|
|
2162
|
+
why: for testing
|
|
2163
|
+
version: '3.30'
|
|
2164
|
+
alternatives: nothing
|
|
2165
|
+
_Z_TEST_ENTRY_2:
|
|
2166
|
+
version_added: '2.18'
|
|
2167
|
+
name: testentry
|
|
2168
|
+
description: for tests
|
|
2169
|
+
deprecated:
|
|
2170
|
+
why: for testing
|
|
2171
|
+
version: '3.30'
|
|
2172
|
+
alternatives: nothing
|
|
2173
|
+
env:
|
|
2174
|
+
- name: ANSIBLE_TEST_ENTRY2
|
|
2175
|
+
ini:
|
|
2176
|
+
- section: testing
|
|
2177
|
+
key: valid2
|
ansible/config/manager.py
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
from __future__ import annotations
|
|
5
5
|
|
|
6
6
|
import atexit
|
|
7
|
+
import decimal
|
|
7
8
|
import configparser
|
|
8
9
|
import os
|
|
9
10
|
import os.path
|
|
@@ -15,7 +16,7 @@ from collections import namedtuple
|
|
|
15
16
|
from collections.abc import Mapping, Sequence
|
|
16
17
|
from jinja2.nativetypes import NativeEnvironment
|
|
17
18
|
|
|
18
|
-
from ansible.errors import AnsibleOptionsError, AnsibleError
|
|
19
|
+
from ansible.errors import AnsibleOptionsError, AnsibleError, AnsibleRequiredOptionError
|
|
19
20
|
from ansible.module_utils.common.text.converters import to_text, to_bytes, to_native
|
|
20
21
|
from ansible.module_utils.common.yaml import yaml_load
|
|
21
22
|
from ansible.module_utils.six import string_types
|
|
@@ -29,6 +30,26 @@ Setting = namedtuple('Setting', 'name value origin type')
|
|
|
29
30
|
|
|
30
31
|
INTERNAL_DEFS = {'lookup': ('_terms',)}
|
|
31
32
|
|
|
33
|
+
GALAXY_SERVER_DEF = [
|
|
34
|
+
('url', True, 'str'),
|
|
35
|
+
('username', False, 'str'),
|
|
36
|
+
('password', False, 'str'),
|
|
37
|
+
('token', False, 'str'),
|
|
38
|
+
('auth_url', False, 'str'),
|
|
39
|
+
('api_version', False, 'int'),
|
|
40
|
+
('validate_certs', False, 'bool'),
|
|
41
|
+
('client_id', False, 'str'),
|
|
42
|
+
('timeout', False, 'int'),
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
# config definition fields
|
|
46
|
+
GALAXY_SERVER_ADDITIONAL = {
|
|
47
|
+
'api_version': {'default': None, 'choices': [2, 3]},
|
|
48
|
+
'validate_certs': {'cli': [{'name': 'validate_certs'}]},
|
|
49
|
+
'timeout': {'cli': [{'name': 'timeout'}]},
|
|
50
|
+
'token': {'default': None},
|
|
51
|
+
}
|
|
52
|
+
|
|
32
53
|
|
|
33
54
|
def _get_entry(plugin_type, plugin_name, config):
|
|
34
55
|
''' construct entry for requested config '''
|
|
@@ -81,10 +102,18 @@ def ensure_type(value, value_type, origin=None, origin_ftype=None):
|
|
|
81
102
|
value = boolean(value, strict=False)
|
|
82
103
|
|
|
83
104
|
elif value_type in ('integer', 'int'):
|
|
84
|
-
|
|
105
|
+
if not isinstance(value, int):
|
|
106
|
+
try:
|
|
107
|
+
if (decimal_value := decimal.Decimal(value)) == (int_part := int(decimal_value)):
|
|
108
|
+
value = int_part
|
|
109
|
+
else:
|
|
110
|
+
errmsg = 'int'
|
|
111
|
+
except decimal.DecimalException as e:
|
|
112
|
+
raise ValueError from e
|
|
85
113
|
|
|
86
114
|
elif value_type == 'float':
|
|
87
|
-
|
|
115
|
+
if not isinstance(value, float):
|
|
116
|
+
value = float(value)
|
|
88
117
|
|
|
89
118
|
elif value_type == 'list':
|
|
90
119
|
if isinstance(value, string_types):
|
|
@@ -153,7 +182,7 @@ def ensure_type(value, value_type, origin=None, origin_ftype=None):
|
|
|
153
182
|
value = unquote(value)
|
|
154
183
|
|
|
155
184
|
if errmsg:
|
|
156
|
-
raise ValueError('Invalid type provided for "
|
|
185
|
+
raise ValueError(f'Invalid type provided for "{errmsg}": {value!r}')
|
|
157
186
|
|
|
158
187
|
return to_text(value, errors='surrogate_or_strict', nonstring='passthru')
|
|
159
188
|
|
|
@@ -302,6 +331,42 @@ class ConfigManager(object):
|
|
|
302
331
|
# ensure we always have config def entry
|
|
303
332
|
self._base_defs['CONFIG_FILE'] = {'default': None, 'type': 'path'}
|
|
304
333
|
|
|
334
|
+
def load_galaxy_server_defs(self, server_list):
|
|
335
|
+
|
|
336
|
+
def server_config_def(section, key, required, option_type):
|
|
337
|
+
config_def = {
|
|
338
|
+
'description': 'The %s of the %s Galaxy server' % (key, section),
|
|
339
|
+
'ini': [
|
|
340
|
+
{
|
|
341
|
+
'section': 'galaxy_server.%s' % section,
|
|
342
|
+
'key': key,
|
|
343
|
+
}
|
|
344
|
+
],
|
|
345
|
+
'env': [
|
|
346
|
+
{'name': 'ANSIBLE_GALAXY_SERVER_%s_%s' % (section.upper(), key.upper())},
|
|
347
|
+
],
|
|
348
|
+
'required': required,
|
|
349
|
+
'type': option_type,
|
|
350
|
+
}
|
|
351
|
+
if key in GALAXY_SERVER_ADDITIONAL:
|
|
352
|
+
config_def.update(GALAXY_SERVER_ADDITIONAL[key])
|
|
353
|
+
# ensure we always have a default timeout
|
|
354
|
+
if key == 'timeout' and 'default' not in config_def:
|
|
355
|
+
config_def['default'] = self.get_config_value('GALAXY_SERVER_TIMEOUT')
|
|
356
|
+
|
|
357
|
+
return config_def
|
|
358
|
+
|
|
359
|
+
if server_list:
|
|
360
|
+
for server_key in server_list:
|
|
361
|
+
if not server_key:
|
|
362
|
+
# To filter out empty strings or non truthy values as an empty server list env var is equal to [''].
|
|
363
|
+
continue
|
|
364
|
+
|
|
365
|
+
# Config definitions are looked up dynamically based on the C.GALAXY_SERVER_LIST entry. We look up the
|
|
366
|
+
# section [galaxy_server.<server>] for the values url, username, password, and token.
|
|
367
|
+
defs = dict((k, server_config_def(server_key, k, req, value_type)) for k, req, value_type in GALAXY_SERVER_DEF)
|
|
368
|
+
self.initialize_plugin_configuration_definitions('galaxy_server', server_key, defs)
|
|
369
|
+
|
|
305
370
|
def template_default(self, value, variables):
|
|
306
371
|
if isinstance(value, string_types) and (value.startswith('{{') and value.endswith('}}')) and variables is not None:
|
|
307
372
|
# template default values if possible
|
|
@@ -357,7 +422,7 @@ class ConfigManager(object):
|
|
|
357
422
|
def get_plugin_options(self, plugin_type, name, keys=None, variables=None, direct=None):
|
|
358
423
|
|
|
359
424
|
options = {}
|
|
360
|
-
defs = self.get_configuration_definitions(plugin_type, name)
|
|
425
|
+
defs = self.get_configuration_definitions(plugin_type=plugin_type, name=name)
|
|
361
426
|
for option in defs:
|
|
362
427
|
options[option] = self.get_config_value(option, plugin_type=plugin_type, plugin_name=name, keys=keys, variables=variables, direct=direct)
|
|
363
428
|
|
|
@@ -366,7 +431,7 @@ class ConfigManager(object):
|
|
|
366
431
|
def get_plugin_vars(self, plugin_type, name):
|
|
367
432
|
|
|
368
433
|
pvars = []
|
|
369
|
-
for pdef in self.get_configuration_definitions(plugin_type, name).values():
|
|
434
|
+
for pdef in self.get_configuration_definitions(plugin_type=plugin_type, name=name).values():
|
|
370
435
|
if 'vars' in pdef and pdef['vars']:
|
|
371
436
|
for var_entry in pdef['vars']:
|
|
372
437
|
pvars.append(var_entry['name'])
|
|
@@ -375,7 +440,7 @@ class ConfigManager(object):
|
|
|
375
440
|
def get_plugin_options_from_var(self, plugin_type, name, variable):
|
|
376
441
|
|
|
377
442
|
options = []
|
|
378
|
-
for option_name, pdef in self.get_configuration_definitions(plugin_type, name).items():
|
|
443
|
+
for option_name, pdef in self.get_configuration_definitions(plugin_type=plugin_type, name=name).items():
|
|
379
444
|
if 'vars' in pdef and pdef['vars']:
|
|
380
445
|
for var_entry in pdef['vars']:
|
|
381
446
|
if variable == var_entry['name']:
|
|
@@ -417,7 +482,6 @@ class ConfigManager(object):
|
|
|
417
482
|
for cdef in list(ret.keys()):
|
|
418
483
|
if cdef.startswith('_'):
|
|
419
484
|
del ret[cdef]
|
|
420
|
-
|
|
421
485
|
return ret
|
|
422
486
|
|
|
423
487
|
def _loop_entries(self, container, entry_list):
|
|
@@ -472,7 +536,7 @@ class ConfigManager(object):
|
|
|
472
536
|
origin = None
|
|
473
537
|
origin_ftype = None
|
|
474
538
|
|
|
475
|
-
defs = self.get_configuration_definitions(plugin_type, plugin_name)
|
|
539
|
+
defs = self.get_configuration_definitions(plugin_type=plugin_type, name=plugin_name)
|
|
476
540
|
if config in defs:
|
|
477
541
|
|
|
478
542
|
aliases = defs[config].get('aliases', [])
|
|
@@ -562,8 +626,8 @@ class ConfigManager(object):
|
|
|
562
626
|
if value is None:
|
|
563
627
|
if defs[config].get('required', False):
|
|
564
628
|
if not plugin_type or config not in INTERNAL_DEFS.get(plugin_type, {}):
|
|
565
|
-
raise
|
|
566
|
-
|
|
629
|
+
raise AnsibleRequiredOptionError("No setting was provided for required configuration %s" %
|
|
630
|
+
to_native(_get_entry(plugin_type, plugin_name, config)))
|
|
567
631
|
else:
|
|
568
632
|
origin = 'default'
|
|
569
633
|
value = self.template_default(defs[config].get('default'), variables)
|
|
@@ -617,3 +681,17 @@ class ConfigManager(object):
|
|
|
617
681
|
self._plugins[plugin_type] = {}
|
|
618
682
|
|
|
619
683
|
self._plugins[plugin_type][name] = defs
|
|
684
|
+
|
|
685
|
+
@staticmethod
|
|
686
|
+
def get_deprecated_msg_from_config(dep_docs, include_removal=False):
|
|
687
|
+
|
|
688
|
+
removal = ''
|
|
689
|
+
if include_removal:
|
|
690
|
+
if 'removed_at_date' in dep_docs:
|
|
691
|
+
removal = f"Will be removed in a release after {dep_docs['removed_at_date']}\n\t"
|
|
692
|
+
else:
|
|
693
|
+
removal = f"Will be removed in: Ansible {dep_docs['removed_in']}\n\t"
|
|
694
|
+
|
|
695
|
+
# TODO: choose to deprecate either singular or plural
|
|
696
|
+
alt = dep_docs.get('alternatives', dep_docs.get('alternative', 'none'))
|
|
697
|
+
return f"Reason: {dep_docs['why']}\n\t{removal}Alternatives: {alt}"
|
ansible/constants.py
CHANGED
|
@@ -15,6 +15,10 @@ from ansible.module_utils.parsing.convert_bool import BOOLEANS_TRUE
|
|
|
15
15
|
from ansible.release import __version__
|
|
16
16
|
from ansible.utils.fqcn import add_internal_fqcns
|
|
17
17
|
|
|
18
|
+
# initialize config manager/config data to read/store global settings
|
|
19
|
+
# and generate 'pseudo constants' for app consumption.
|
|
20
|
+
config = ConfigManager()
|
|
21
|
+
|
|
18
22
|
|
|
19
23
|
def _warning(msg):
|
|
20
24
|
''' display is not guaranteed here, nor it being the full class, but try anyways, fallback to sys.stderr.write '''
|
|
@@ -36,6 +40,28 @@ def _deprecated(msg, version):
|
|
|
36
40
|
sys.stderr.write(' [DEPRECATED] %s, to be removed in %s\n' % (msg, version))
|
|
37
41
|
|
|
38
42
|
|
|
43
|
+
def handle_config_noise(display=None):
|
|
44
|
+
|
|
45
|
+
if display is not None:
|
|
46
|
+
w = display.warning
|
|
47
|
+
d = display.deprecated
|
|
48
|
+
else:
|
|
49
|
+
w = _warning
|
|
50
|
+
d = _deprecated
|
|
51
|
+
|
|
52
|
+
while config.WARNINGS:
|
|
53
|
+
warn = config.WARNINGS.pop()
|
|
54
|
+
w(warn)
|
|
55
|
+
|
|
56
|
+
while config.DEPRECATED:
|
|
57
|
+
# tuple with name and options
|
|
58
|
+
dep = config.DEPRECATED.pop(0)
|
|
59
|
+
msg = config.get_deprecated_msg_from_config(dep[1])
|
|
60
|
+
# use tabs only for ansible-doc?
|
|
61
|
+
msg = msg.replace("\t", "")
|
|
62
|
+
d(f"{dep[0]} option. {msg}", version=dep[1]['version'])
|
|
63
|
+
|
|
64
|
+
|
|
39
65
|
def set_constant(name, value, export=vars()):
|
|
40
66
|
''' sets constants and returns resolved options dict '''
|
|
41
67
|
export[name] = value
|
|
@@ -152,10 +178,10 @@ INTERNAL_STATIC_VARS = frozenset(
|
|
|
152
178
|
]
|
|
153
179
|
)
|
|
154
180
|
LOCALHOST = ('127.0.0.1', 'localhost', '::1')
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
181
|
+
WIN_MOVED = ['ansible.windows.win_command', 'ansible.windows.win_shell']
|
|
182
|
+
MODULE_REQUIRE_ARGS_SIMPLE = ['command', 'raw', 'script', 'shell', 'win_command', 'win_shell']
|
|
183
|
+
MODULE_REQUIRE_ARGS = tuple(add_internal_fqcns(MODULE_REQUIRE_ARGS_SIMPLE) + WIN_MOVED)
|
|
184
|
+
MODULE_NO_JSON = tuple(add_internal_fqcns(('command', 'win_command', 'shell', 'win_shell', 'raw')) + WIN_MOVED)
|
|
159
185
|
RESTRICTED_RESULT_KEYS = ('ansible_rsync_path', 'ansible_playbook_python', 'ansible_facts')
|
|
160
186
|
SYNTHETIC_COLLECTIONS = ('ansible.builtin', 'ansible.legacy')
|
|
161
187
|
TREE_DIR = None
|
|
@@ -218,11 +244,8 @@ MAGIC_VARIABLE_MAPPING = dict(
|
|
|
218
244
|
)
|
|
219
245
|
|
|
220
246
|
# POPULATE SETTINGS FROM CONFIG ###
|
|
221
|
-
config = ConfigManager()
|
|
222
|
-
|
|
223
|
-
# Generate constants from config
|
|
224
247
|
for setting in config.get_configuration_definitions():
|
|
225
248
|
set_constant(setting, config.get_config_value(setting, variables=vars()))
|
|
226
249
|
|
|
227
|
-
|
|
228
|
-
|
|
250
|
+
# emit any warnings or deprecations
|
|
251
|
+
handle_config_noise()
|
ansible/errors/__init__.py
CHANGED
|
@@ -231,6 +231,11 @@ class AnsibleOptionsError(AnsibleError):
|
|
|
231
231
|
pass
|
|
232
232
|
|
|
233
233
|
|
|
234
|
+
class AnsibleRequiredOptionError(AnsibleOptionsError):
|
|
235
|
+
''' bad or incomplete options passed '''
|
|
236
|
+
pass
|
|
237
|
+
|
|
238
|
+
|
|
234
239
|
class AnsibleParserError(AnsibleError):
|
|
235
240
|
''' something was detected early that is wrong about a playbook or data file '''
|
|
236
241
|
pass
|
|
@@ -41,7 +41,7 @@ class InterpreterDiscoveryRequiredError(Exception):
|
|
|
41
41
|
def discover_interpreter(action, interpreter_name, discovery_mode, task_vars):
|
|
42
42
|
# interpreter discovery is a 2-step process with the target. First, we use a simple shell-agnostic bootstrap to
|
|
43
43
|
# get the system type from uname, and find any random Python that can get us the info we need. For supported
|
|
44
|
-
# target OS types, we'll dispatch a Python script that calls
|
|
44
|
+
# target OS types, we'll dispatch a Python script that calls platform.dist() (for older platforms, where available)
|
|
45
45
|
# and brings back /etc/os-release (if present). The proper Python path is looked up in a table of known
|
|
46
46
|
# distros/versions with included Pythons; if nothing is found, depending on the discovery mode, either the
|
|
47
47
|
# default fallback of /usr/bin/python is used (if we know it's there), or discovery fails.
|
|
@@ -653,3 +653,19 @@ class PlayIterator:
|
|
|
653
653
|
|
|
654
654
|
def clear_notification(self, hostname: str, notification: str) -> None:
|
|
655
655
|
self._host_states[hostname].handler_notifications.remove(notification)
|
|
656
|
+
|
|
657
|
+
def end_host(self, hostname: str) -> None:
|
|
658
|
+
"""Used by ``end_host``, ``end_batch`` and ``end_play`` meta tasks to end executing given host."""
|
|
659
|
+
state = self.get_active_state(self.get_state_for_host(hostname))
|
|
660
|
+
if state.run_state == IteratingStates.RESCUE:
|
|
661
|
+
# This is a special case for when ending a host occurs in rescue.
|
|
662
|
+
# By definition the meta task responsible for ending the host
|
|
663
|
+
# is the last task, so we need to clear the fail state to mark
|
|
664
|
+
# the host as rescued.
|
|
665
|
+
# The reason we need to do that is because this operation is
|
|
666
|
+
# normally done when PlayIterator transitions from rescue to
|
|
667
|
+
# always when only then we can say that rescue didn't fail
|
|
668
|
+
# but with ending a host via meta task, we don't get to that transition.
|
|
669
|
+
self.set_fail_state_for_host(hostname, FailedStates.NONE)
|
|
670
|
+
self.set_run_state_for_host(hostname, IteratingStates.COMPLETE)
|
|
671
|
+
self._play._removed_hosts.append(hostname)
|
|
@@ -195,10 +195,7 @@ class PlaybookExecutor:
|
|
|
195
195
|
result = self._tqm.RUN_FAILED_HOSTS
|
|
196
196
|
break_play = True
|
|
197
197
|
|
|
198
|
-
# check the number of failures here
|
|
199
|
-
# failure percentage allowed, or if any errors are fatal. If either of those
|
|
200
|
-
# conditions are met, we break out, otherwise we only break out if the entire
|
|
201
|
-
# batch failed
|
|
198
|
+
# check the number of failures here and break out if the entire batch failed
|
|
202
199
|
failed_hosts_count = len(self._tqm._failed_hosts) + len(self._tqm._unreachable_hosts) - \
|
|
203
200
|
(previously_failed + previously_unreachable)
|
|
204
201
|
|
|
@@ -116,12 +116,11 @@ Write-AnsibleLog "INFO - parsed become input, user: '$username', type: '$logon_t
|
|
|
116
116
|
# set to Stop and cannot be changed. Also need to split the payload from the wrapper to prevent potentially
|
|
117
117
|
# sensitive content from being logged by the scriptblock logger.
|
|
118
118
|
$bootstrap_wrapper = {
|
|
119
|
-
|
|
120
|
-
$
|
|
121
|
-
$split_parts = $
|
|
119
|
+
[Console]::InputEncoding = [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding
|
|
120
|
+
$ew = [System.Console]::In.ReadToEnd()
|
|
121
|
+
$split_parts = $ew.Split(@("`0`0`0`0"), 2, [StringSplitOptions]::RemoveEmptyEntries)
|
|
122
122
|
Set-Variable -Name json_raw -Value $split_parts[1]
|
|
123
|
-
|
|
124
|
-
&$exec_wrapper
|
|
123
|
+
&([ScriptBlock]::Create($split_parts[0]))
|
|
125
124
|
}
|
|
126
125
|
$exec_command = [System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($bootstrap_wrapper.ToString()))
|
|
127
126
|
$lp_command_line = "powershell.exe -NonInteractive -NoProfile -ExecutionPolicy Bypass -EncodedCommand $exec_command"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
try { [Console]::InputEncoding = [Console]::OutputEncoding = New-Object System.Text.UTF8Encoding } catch { $null = $_ }
|
|
2
2
|
|
|
3
3
|
if ($PSVersionTable.PSVersion -lt [Version]"3.0") {
|
|
4
4
|
'{"failed":true,"msg":"Ansible requires PowerShell v3.0 or newer"}'
|
|
@@ -9,5 +9,4 @@ $exec_wrapper_str = $input | Out-String
|
|
|
9
9
|
$split_parts = $exec_wrapper_str.Split(@("`0`0`0`0"), 2, [StringSplitOptions]::RemoveEmptyEntries)
|
|
10
10
|
If (-not $split_parts.Length -eq 2) { throw "invalid payload" }
|
|
11
11
|
Set-Variable -Name json_raw -Value $split_parts[1]
|
|
12
|
-
|
|
13
|
-
&$exec_wrapper
|
|
12
|
+
& ([ScriptBlock]::Create($split_parts[0]))
|
|
@@ -16,7 +16,7 @@ begin {
|
|
|
16
16
|
.SYNOPSIS
|
|
17
17
|
Converts a JSON string to a Hashtable/Array in the fastest way
|
|
18
18
|
possible. Unfortunately ConvertFrom-Json is still faster but outputs
|
|
19
|
-
a PSCustomObject which is
|
|
19
|
+
a PSCustomObject which is cumbersome for module consumption.
|
|
20
20
|
|
|
21
21
|
.PARAMETER InputObject
|
|
22
22
|
[String] The JSON string to deserialize.
|