ansible-core 2.17.4rc1__py3-none-any.whl → 2.18.0b1__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 +30 -53
- 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 +14 -11
- 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 +48 -31
- 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/playbook/task.py +1 -1
- ansible/plugins/__init__.py +2 -0
- ansible/plugins/action/__init__.py +7 -9
- 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.0b1.dist-info/Apache-License.txt +202 -0
- {ansible_core-2.17.4rc1.dist-info → ansible_core-2.18.0b1.dist-info}/METADATA +36 -23
- ansible_core-2.18.0b1.dist-info/MIT-license.txt +14 -0
- ansible_core-2.18.0b1.dist-info/PSF-license.txt +48 -0
- {ansible_core-2.17.4rc1.dist-info → ansible_core-2.18.0b1.dist-info}/RECORD +311 -306
- {ansible_core-2.17.4rc1.dist-info → ansible_core-2.18.0b1.dist-info}/WHEEL +1 -1
- {ansible_core-2.17.4rc1.dist-info → ansible_core-2.18.0b1.dist-info}/entry_points.txt +1 -1
- ansible_core-2.18.0b1.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 +5 -7
- 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/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/collection.cfg +1 -0
- ansible_test/_util/controller/sanity/pylint/config/default.cfg +1 -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 +14 -20
- ansible_test/config/config.yml +1 -1
- ansible_core-2.17.4rc1.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.4rc1.dist-info → ansible_core-2.18.0b1.dist-info}/COPYING +0 -0
- {ansible_core-2.17.4rc1.dist-info → ansible_core-2.18.0b1.dist-info}/top_level.txt +0 -0
ansible/cli/galaxy.py
CHANGED
|
@@ -55,7 +55,6 @@ from ansible.module_utils.common.yaml import yaml_dump, yaml_load
|
|
|
55
55
|
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
|
56
56
|
from ansible.module_utils import six
|
|
57
57
|
from ansible.parsing.dataloader import DataLoader
|
|
58
|
-
from ansible.parsing.yaml.loader import AnsibleLoader
|
|
59
58
|
from ansible.playbook.role.requirement import RoleRequirement
|
|
60
59
|
from ansible.template import Templar
|
|
61
60
|
from ansible.utils.collection_loader import AnsibleCollectionConfig
|
|
@@ -66,27 +65,6 @@ from ansible.utils.vars import load_extra_vars
|
|
|
66
65
|
display = Display()
|
|
67
66
|
urlparse = six.moves.urllib.parse.urlparse
|
|
68
67
|
|
|
69
|
-
# config definition by position: name, required, type
|
|
70
|
-
SERVER_DEF = [
|
|
71
|
-
('url', True, 'str'),
|
|
72
|
-
('username', False, 'str'),
|
|
73
|
-
('password', False, 'str'),
|
|
74
|
-
('token', False, 'str'),
|
|
75
|
-
('auth_url', False, 'str'),
|
|
76
|
-
('api_version', False, 'int'),
|
|
77
|
-
('validate_certs', False, 'bool'),
|
|
78
|
-
('client_id', False, 'str'),
|
|
79
|
-
('timeout', False, 'int'),
|
|
80
|
-
]
|
|
81
|
-
|
|
82
|
-
# config definition fields
|
|
83
|
-
SERVER_ADDITIONAL = {
|
|
84
|
-
'api_version': {'default': None, 'choices': [2, 3]},
|
|
85
|
-
'validate_certs': {'cli': [{'name': 'validate_certs'}]},
|
|
86
|
-
'timeout': {'default': C.GALAXY_SERVER_TIMEOUT, 'cli': [{'name': 'timeout'}]},
|
|
87
|
-
'token': {'default': None},
|
|
88
|
-
}
|
|
89
|
-
|
|
90
68
|
|
|
91
69
|
def with_collection_artifacts_manager(wrapped_method):
|
|
92
70
|
"""Inject an artifacts manager if not passed explicitly.
|
|
@@ -490,12 +468,31 @@ class GalaxyCLI(CLI):
|
|
|
490
468
|
ignore_errors_help = 'Ignore errors during installation and continue with the next specified ' \
|
|
491
469
|
'collection. This will not ignore dependency conflict errors.'
|
|
492
470
|
else:
|
|
493
|
-
args_kwargs['help'] = 'Role name, URL or tar file'
|
|
471
|
+
args_kwargs['help'] = 'Role name, URL or tar file. This is mutually exclusive with -r.'
|
|
494
472
|
ignore_errors_help = 'Ignore errors and continue with the next specified role.'
|
|
495
473
|
|
|
474
|
+
if self._implicit_role:
|
|
475
|
+
# might install both roles and collections
|
|
476
|
+
description_text = (
|
|
477
|
+
'Install roles and collections from file(s), URL(s) or Ansible '
|
|
478
|
+
'Galaxy to the first entry in the config COLLECTIONS_PATH for collections '
|
|
479
|
+
'and first entry in the config ROLES_PATH for roles. '
|
|
480
|
+
'The first entry in the config ROLES_PATH can be overridden by --roles-path '
|
|
481
|
+
'or -p, but this will result in only roles being installed.'
|
|
482
|
+
)
|
|
483
|
+
prog = 'ansible-galaxy install'
|
|
484
|
+
else:
|
|
485
|
+
prog = f"ansible-galaxy {galaxy_type} install"
|
|
486
|
+
description_text = (
|
|
487
|
+
'Install {0}(s) from file(s), URL(s) or Ansible '
|
|
488
|
+
'Galaxy to the first entry in the config {1}S_PATH '
|
|
489
|
+
'unless overridden by --{0}s-path.'.format(galaxy_type, galaxy_type.upper())
|
|
490
|
+
)
|
|
496
491
|
install_parser = parser.add_parser('install', parents=parents,
|
|
497
492
|
help='Install {0}(s) from file(s), URL(s) or Ansible '
|
|
498
|
-
'Galaxy'.format(galaxy_type)
|
|
493
|
+
'Galaxy'.format(galaxy_type),
|
|
494
|
+
description=description_text,
|
|
495
|
+
prog=prog,)
|
|
499
496
|
install_parser.set_defaults(func=self.execute_install)
|
|
500
497
|
|
|
501
498
|
install_parser.add_argument('args', metavar='{0}_name'.format(galaxy_type), nargs='*', **args_kwargs)
|
|
@@ -548,8 +545,12 @@ class GalaxyCLI(CLI):
|
|
|
548
545
|
'This does not apply to collections in remote Git repositories or URLs to remote tarballs.'
|
|
549
546
|
)
|
|
550
547
|
else:
|
|
551
|
-
|
|
552
|
-
|
|
548
|
+
if self._implicit_role:
|
|
549
|
+
install_parser.add_argument('-r', '--role-file', dest='requirements',
|
|
550
|
+
help='A file containing a list of collections and roles to be installed.')
|
|
551
|
+
else:
|
|
552
|
+
install_parser.add_argument('-r', '--role-file', dest='requirements',
|
|
553
|
+
help='A file containing a list of roles to be installed.')
|
|
553
554
|
|
|
554
555
|
r_re = re.compile(r'^(?<!-)-[a-zA-Z]*r[a-zA-Z]*') # -r, -fr
|
|
555
556
|
contains_r = bool([a for a in self._raw_args if r_re.match(a)])
|
|
@@ -618,25 +619,8 @@ class GalaxyCLI(CLI):
|
|
|
618
619
|
|
|
619
620
|
self.galaxy = Galaxy()
|
|
620
621
|
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
'description': 'The %s of the %s Galaxy server' % (key, section),
|
|
624
|
-
'ini': [
|
|
625
|
-
{
|
|
626
|
-
'section': 'galaxy_server.%s' % section,
|
|
627
|
-
'key': key,
|
|
628
|
-
}
|
|
629
|
-
],
|
|
630
|
-
'env': [
|
|
631
|
-
{'name': 'ANSIBLE_GALAXY_SERVER_%s_%s' % (section.upper(), key.upper())},
|
|
632
|
-
],
|
|
633
|
-
'required': required,
|
|
634
|
-
'type': option_type,
|
|
635
|
-
}
|
|
636
|
-
if key in SERVER_ADDITIONAL:
|
|
637
|
-
config_def.update(SERVER_ADDITIONAL[key])
|
|
638
|
-
|
|
639
|
-
return config_def
|
|
622
|
+
# dynamically add per server config depending on declared servers
|
|
623
|
+
C.config.load_galaxy_server_defs(C.GALAXY_SERVER_LIST)
|
|
640
624
|
|
|
641
625
|
galaxy_options = {}
|
|
642
626
|
for optional_key in ['clear_response_cache', 'no_cache']:
|
|
@@ -644,19 +628,12 @@ class GalaxyCLI(CLI):
|
|
|
644
628
|
galaxy_options[optional_key] = context.CLIARGS[optional_key]
|
|
645
629
|
|
|
646
630
|
config_servers = []
|
|
647
|
-
|
|
648
631
|
# Need to filter out empty strings or non truthy values as an empty server list env var is equal to [''].
|
|
649
632
|
server_list = [s for s in C.GALAXY_SERVER_LIST or [] if s]
|
|
650
633
|
for server_priority, server_key in enumerate(server_list, start=1):
|
|
651
|
-
# Abuse the 'plugin config' by making 'galaxy_server' a type of plugin
|
|
652
|
-
# Config definitions are looked up dynamically based on the C.GALAXY_SERVER_LIST entry. We look up the
|
|
653
|
-
# section [galaxy_server.<server>] for the values url, username, password, and token.
|
|
654
|
-
config_dict = dict((k, server_config_def(server_key, k, req, ensure_type)) for k, req, ensure_type in SERVER_DEF)
|
|
655
|
-
defs = AnsibleLoader(yaml_dump(config_dict)).get_single_data()
|
|
656
|
-
C.config.initialize_plugin_configuration_definitions('galaxy_server', server_key, defs)
|
|
657
634
|
|
|
658
635
|
# resolve the config created options above with existing config and user options
|
|
659
|
-
server_options = C.config.get_plugin_options('galaxy_server', server_key)
|
|
636
|
+
server_options = C.config.get_plugin_options(plugin_type='galaxy_server', name=server_key)
|
|
660
637
|
|
|
661
638
|
# auth_url is used to create the token, but not directly by GalaxyAPI, so
|
|
662
639
|
# it doesn't need to be passed as kwarg to GalaxyApi, same for others we pop here
|
ansible/cli/inventory.py
CHANGED
|
@@ -73,12 +73,12 @@ class InventoryCLI(CLI):
|
|
|
73
73
|
|
|
74
74
|
# list
|
|
75
75
|
self.parser.add_argument("--export", action="store_true", default=C.INVENTORY_EXPORT, dest='export',
|
|
76
|
-
help="When doing
|
|
76
|
+
help="When doing --list, represent in a way that is optimized for export,"
|
|
77
77
|
"not as an accurate representation of how Ansible has processed it")
|
|
78
78
|
self.parser.add_argument('--output', default=None, dest='output_file',
|
|
79
79
|
help="When doing --list, send the inventory to a file instead of to the screen")
|
|
80
80
|
# self.parser.add_argument("--ignore-vars-plugins", action="store_true", default=False, dest='ignore_vars_plugins',
|
|
81
|
-
# help="When doing
|
|
81
|
+
# help="When doing --list, skip vars data from vars plugins, by default, this would include group_vars/ and host_vars/")
|
|
82
82
|
|
|
83
83
|
def post_process_args(self, options):
|
|
84
84
|
options = super(InventoryCLI, self).post_process_args(options)
|
ansible/cli/pull.py
CHANGED
|
@@ -12,7 +12,7 @@ from ansible.cli import CLI
|
|
|
12
12
|
import datetime
|
|
13
13
|
import os
|
|
14
14
|
import platform
|
|
15
|
-
import
|
|
15
|
+
import secrets
|
|
16
16
|
import shlex
|
|
17
17
|
import shutil
|
|
18
18
|
import socket
|
|
@@ -140,7 +140,7 @@ class PullCLI(CLI):
|
|
|
140
140
|
|
|
141
141
|
if options.sleep:
|
|
142
142
|
try:
|
|
143
|
-
secs =
|
|
143
|
+
secs = secrets.randbelow(int(options.sleep))
|
|
144
144
|
options.sleep = secs
|
|
145
145
|
except ValueError:
|
|
146
146
|
raise AnsibleOptionsError("%s is not a number." % options.sleep)
|
|
@@ -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}"
|