ansible-core 2.19.3rc1__py3-none-any.whl → 2.20.0b2__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/_internal/__init__.py +1 -4
- ansible/_internal/_ansiballz/_builder.py +1 -3
- ansible/_internal/_collection_proxy.py +7 -9
- ansible/_internal/_json/__init__.py +3 -4
- ansible/_internal/_templating/_engine.py +1 -1
- ansible/_internal/_templating/_jinja_plugins.py +1 -2
- ansible/_internal/_wrapt.py +105 -301
- ansible/cli/__init__.py +11 -10
- ansible/cli/adhoc.py +1 -2
- ansible/cli/arguments/option_helpers.py +1 -1
- ansible/cli/config.py +5 -6
- ansible/cli/doc.py +70 -68
- ansible/cli/galaxy.py +15 -24
- ansible/cli/inventory.py +0 -1
- ansible/cli/playbook.py +0 -1
- ansible/cli/pull.py +0 -1
- ansible/cli/scripts/ansible_connection_cli_stub.py +1 -1
- ansible/collections/list.py +4 -2
- ansible/config/base.yml +1 -25
- ansible/config/manager.py +0 -2
- ansible/executor/play_iterator.py +42 -20
- ansible/executor/playbook_executor.py +0 -9
- ansible/executor/task_executor.py +26 -18
- ansible/executor/task_queue_manager.py +1 -3
- ansible/galaxy/api.py +33 -80
- ansible/galaxy/collection/__init__.py +4 -17
- ansible/galaxy/dependency_resolution/dataclasses.py +0 -10
- ansible/galaxy/dependency_resolution/providers.py +24 -118
- ansible/galaxy/role.py +1 -33
- ansible/inventory/manager.py +2 -3
- ansible/keyword_desc.yml +0 -3
- ansible/module_utils/_internal/_datatag/__init__.py +2 -10
- ansible/module_utils/_internal/_no_six.py +86 -0
- ansible/module_utils/_text.py +28 -8
- ansible/module_utils/ansible_release.py +2 -2
- ansible/module_utils/basic.py +26 -23
- ansible/module_utils/common/_collections_compat.py +11 -2
- ansible/module_utils/common/collections.py +8 -3
- ansible/module_utils/common/dict_transformations.py +1 -2
- ansible/module_utils/common/network.py +4 -2
- ansible/module_utils/common/parameters.py +32 -41
- ansible/module_utils/common/text/converters.py +109 -23
- ansible/module_utils/common/text/formatters.py +6 -2
- ansible/module_utils/common/validation.py +11 -9
- ansible/module_utils/connection.py +8 -3
- ansible/module_utils/facts/hardware/linux.py +23 -7
- ansible/module_utils/facts/hardware/netbsd.py +1 -1
- ansible/module_utils/facts/hardware/sunos.py +2 -1
- ansible/module_utils/facts/packages.py +6 -2
- ansible/module_utils/facts/system/distribution.py +2 -1
- ansible/module_utils/facts/system/env.py +6 -3
- ansible/module_utils/facts/system/local.py +3 -1
- ansible/module_utils/parsing/convert_bool.py +6 -2
- ansible/module_utils/service.py +2 -3
- ansible/module_utils/six/__init__.py +19 -6
- ansible/module_utils/yumdnf.py +0 -5
- ansible/modules/apt.py +18 -13
- ansible/modules/apt_repository.py +1 -1
- ansible/modules/assemble.py +5 -9
- ansible/modules/blockinfile.py +39 -23
- ansible/modules/cron.py +26 -35
- ansible/modules/deb822_repository.py +83 -12
- ansible/modules/dnf.py +3 -7
- ansible/modules/dnf5.py +4 -6
- ansible/modules/expect.py +0 -3
- ansible/modules/find.py +1 -2
- ansible/modules/get_url.py +1 -1
- ansible/modules/git.py +4 -5
- ansible/modules/include_vars.py +1 -1
- ansible/modules/known_hosts.py +7 -1
- ansible/modules/lineinfile.py +71 -63
- ansible/modules/package_facts.py +1 -1
- ansible/modules/pip.py +8 -2
- ansible/modules/replace.py +6 -6
- ansible/modules/service.py +3 -4
- ansible/modules/stat.py +20 -0
- ansible/modules/uri.py +9 -10
- ansible/modules/user.py +1 -2
- ansible/modules/wait_for.py +2 -2
- ansible/modules/wait_for_connection.py +2 -1
- ansible/modules/yum_repository.py +1 -16
- ansible/parsing/dataloader.py +24 -31
- ansible/parsing/mod_args.py +3 -0
- ansible/parsing/vault/__init__.py +1 -2
- ansible/playbook/base.py +8 -56
- ansible/playbook/block.py +1 -63
- ansible/playbook/collectionsearch.py +1 -2
- ansible/playbook/handler.py +1 -7
- ansible/playbook/helpers.py +15 -20
- ansible/playbook/included_file.py +1 -1
- ansible/playbook/play.py +105 -49
- ansible/playbook/play_context.py +4 -0
- ansible/playbook/role/__init__.py +10 -65
- ansible/playbook/role/definition.py +3 -4
- ansible/playbook/role/include.py +2 -3
- ansible/playbook/role/metadata.py +1 -12
- ansible/playbook/role/requirement.py +1 -2
- ansible/playbook/role_include.py +1 -2
- ansible/playbook/taggable.py +16 -5
- ansible/playbook/task.py +51 -55
- ansible/plugins/action/__init__.py +20 -19
- ansible/plugins/action/add_host.py +1 -2
- ansible/plugins/action/fetch.py +3 -5
- ansible/plugins/action/group_by.py +1 -2
- ansible/plugins/action/include_vars.py +20 -22
- ansible/plugins/action/script.py +1 -3
- ansible/plugins/action/template.py +1 -2
- ansible/plugins/action/uri.py +4 -2
- ansible/plugins/cache/__init__.py +1 -0
- ansible/plugins/callback/__init__.py +13 -6
- ansible/plugins/connection/__init__.py +3 -7
- ansible/plugins/connection/local.py +2 -3
- ansible/plugins/connection/psrp.py +0 -2
- ansible/plugins/connection/ssh.py +2 -7
- ansible/plugins/connection/winrm.py +0 -2
- ansible/plugins/doc_fragments/result_format_callback.py +15 -0
- ansible/plugins/filter/core.py +4 -5
- ansible/plugins/filter/encryption.py +3 -27
- ansible/plugins/filter/mathstuff.py +1 -2
- ansible/plugins/filter/to_nice_yaml.yml +31 -3
- ansible/plugins/filter/to_yaml.yml +29 -12
- ansible/plugins/inventory/__init__.py +1 -2
- ansible/plugins/inventory/toml.py +3 -6
- ansible/plugins/inventory/yaml.py +1 -2
- ansible/plugins/loader.py +3 -4
- ansible/plugins/lookup/password.py +1 -2
- ansible/plugins/lookup/subelements.py +2 -3
- ansible/plugins/lookup/url.py +1 -1
- ansible/plugins/lookup/varnames.py +1 -2
- ansible/plugins/shell/__init__.py +9 -4
- ansible/plugins/shell/powershell.py +8 -24
- ansible/plugins/strategy/__init__.py +6 -3
- ansible/plugins/test/core.py +4 -1
- ansible/plugins/test/falsy.yml +1 -1
- ansible/plugins/test/regex.yml +18 -6
- ansible/plugins/test/truthy.yml +1 -1
- ansible/release.py +2 -2
- ansible/template/__init__.py +3 -7
- ansible/utils/collection_loader/_collection_config.py +5 -0
- ansible/utils/collection_loader/_collection_finder.py +11 -14
- ansible/utils/context_objects.py +7 -4
- ansible/utils/display.py +7 -6
- ansible/utils/encrypt.py +0 -5
- ansible/utils/helpers.py +6 -2
- ansible/utils/jsonrpc.py +7 -3
- ansible/utils/plugin_docs.py +49 -38
- ansible/utils/ssh_functions.py +0 -19
- ansible/utils/unsafe_proxy.py +7 -7
- ansible/vars/clean.py +2 -3
- ansible/vars/manager.py +28 -22
- ansible/vars/plugins.py +1 -31
- {ansible_core-2.19.3rc1.dist-info → ansible_core-2.20.0b2.dist-info}/METADATA +3 -3
- {ansible_core-2.19.3rc1.dist-info → ansible_core-2.20.0b2.dist-info}/RECORD +199 -200
- ansible_test/_data/completion/docker.txt +7 -7
- ansible_test/_data/completion/network.txt +0 -1
- ansible_test/_data/completion/remote.txt +4 -4
- ansible_test/_data/requirements/ansible-test.txt +1 -1
- ansible_test/_data/requirements/sanity.changelog.txt +1 -1
- ansible_test/_data/requirements/sanity.pep8.txt +1 -1
- ansible_test/_data/requirements/sanity.pylint.txt +4 -4
- ansible_test/_internal/cache.py +2 -5
- ansible_test/_internal/cli/compat.py +1 -1
- ansible_test/_internal/commands/coverage/combine.py +1 -3
- ansible_test/_internal/commands/integration/__init__.py +3 -7
- ansible_test/_internal/commands/integration/cloud/httptester.py +1 -1
- ansible_test/_internal/commands/integration/coverage.py +1 -3
- ansible_test/_internal/commands/integration/filters.py +5 -10
- ansible_test/_internal/commands/sanity/validate_modules.py +1 -5
- ansible_test/_internal/commands/units/__init__.py +1 -13
- ansible_test/_internal/completion.py +2 -5
- ansible_test/_internal/config.py +2 -7
- ansible_test/_internal/coverage_util.py +1 -1
- ansible_test/_internal/delegation.py +2 -0
- ansible_test/_internal/docker_util.py +1 -1
- ansible_test/_internal/host_profiles.py +6 -11
- ansible_test/_internal/provider/__init__.py +2 -5
- ansible_test/_internal/provisioning.py +2 -5
- ansible_test/_internal/pypi_proxy.py +1 -1
- ansible_test/_internal/target.py +2 -6
- ansible_test/_internal/thread.py +1 -4
- ansible_test/_internal/util.py +9 -14
- ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py +14 -19
- ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py +40 -27
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py +31 -18
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py +1 -2
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py +59 -71
- ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py +1 -2
- ansible_test/_util/target/cli/ansible_test_cli_stub.py +4 -2
- ansible_test/_util/target/common/constants.py +2 -2
- ansible_test/_util/target/setup/bootstrap.sh +0 -6
- ansible/utils/py3compat.py +0 -27
- ansible_test/_data/pytest/config/legacy.ini +0 -4
- {ansible_core-2.19.3rc1.dist-info → ansible_core-2.20.0b2.dist-info}/WHEEL +0 -0
- {ansible_core-2.19.3rc1.dist-info → ansible_core-2.20.0b2.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.19.3rc1.dist-info → ansible_core-2.20.0b2.dist-info}/licenses/COPYING +0 -0
- {ansible_core-2.19.3rc1.dist-info → ansible_core-2.20.0b2.dist-info}/licenses/licenses/Apache-License.txt +0 -0
- {ansible_core-2.19.3rc1.dist-info → ansible_core-2.20.0b2.dist-info}/licenses/licenses/BSD-3-Clause.txt +0 -0
- {ansible_core-2.19.3rc1.dist-info → ansible_core-2.20.0b2.dist-info}/licenses/licenses/MIT-license.txt +0 -0
- {ansible_core-2.19.3rc1.dist-info → ansible_core-2.20.0b2.dist-info}/licenses/licenses/PSF-license.txt +0 -0
- {ansible_core-2.19.3rc1.dist-info → ansible_core-2.20.0b2.dist-info}/licenses/licenses/simplified_bsd.txt +0 -0
- {ansible_core-2.19.3rc1.dist-info → ansible_core-2.20.0b2.dist-info}/top_level.txt +0 -0
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
|
+
import collections.abc as _c
|
|
8
9
|
import functools
|
|
9
10
|
import typing as t
|
|
10
11
|
|
|
@@ -24,7 +25,6 @@ from ansible.galaxy.dependency_resolution.versioning import (
|
|
|
24
25
|
is_pre_release,
|
|
25
26
|
meets_requirements,
|
|
26
27
|
)
|
|
27
|
-
from ansible.module_utils.six import string_types
|
|
28
28
|
from ansible.utils.version import SemanticVersion, LooseVersion
|
|
29
29
|
|
|
30
30
|
try:
|
|
@@ -38,16 +38,16 @@ except ImportError:
|
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
# TODO: add python requirements to ansible-test's ansible-core distribution info and remove the hardcoded lowerbound/upperbound fallback
|
|
41
|
-
RESOLVELIB_LOWERBOUND = SemanticVersion("0.
|
|
41
|
+
RESOLVELIB_LOWERBOUND = SemanticVersion("0.8.0")
|
|
42
42
|
RESOLVELIB_UPPERBOUND = SemanticVersion("2.0.0")
|
|
43
43
|
RESOLVELIB_VERSION = SemanticVersion.from_loose_version(LooseVersion(resolvelib_version))
|
|
44
44
|
|
|
45
45
|
|
|
46
|
-
class
|
|
46
|
+
class CollectionDependencyProvider(AbstractProvider):
|
|
47
47
|
"""Delegate providing a requirement interface for the resolver."""
|
|
48
48
|
|
|
49
49
|
def __init__(
|
|
50
|
-
self,
|
|
50
|
+
self,
|
|
51
51
|
apis, # type: MultiGalaxyAPIProxy
|
|
52
52
|
concrete_artifacts_manager=None, # type: ConcreteArtifactsManager
|
|
53
53
|
preferred_candidates=None, # type: t.Iterable[Candidate]
|
|
@@ -103,8 +103,14 @@ class CollectionDependencyProviderBase(AbstractProvider):
|
|
|
103
103
|
"""
|
|
104
104
|
return requirement_or_candidate.canonical_package_id
|
|
105
105
|
|
|
106
|
-
def get_preference(
|
|
107
|
-
|
|
106
|
+
def get_preference(
|
|
107
|
+
self,
|
|
108
|
+
identifier: str,
|
|
109
|
+
resolutions: _c.Mapping[str, Candidate],
|
|
110
|
+
candidates: _c.Mapping[str, _c.Iterator[Candidate]],
|
|
111
|
+
information: _c.Iterator[t.NamedTuple],
|
|
112
|
+
backtrack_causes: _c.Sequence,
|
|
113
|
+
) -> float | int:
|
|
108
114
|
"""Return sort key function return value for given requirement.
|
|
109
115
|
|
|
110
116
|
This result should be based on preference that is defined as
|
|
@@ -112,38 +118,6 @@ class CollectionDependencyProviderBase(AbstractProvider):
|
|
|
112
118
|
The lower the return value is, the more preferred this
|
|
113
119
|
group of arguments is.
|
|
114
120
|
|
|
115
|
-
resolvelib >=0.5.3, <0.7.0
|
|
116
|
-
|
|
117
|
-
:param resolution: Currently pinned candidate, or ``None``.
|
|
118
|
-
|
|
119
|
-
:param candidates: A list of possible candidates.
|
|
120
|
-
|
|
121
|
-
:param information: A list of requirement information.
|
|
122
|
-
|
|
123
|
-
Each ``information`` instance is a named tuple with two entries:
|
|
124
|
-
|
|
125
|
-
* ``requirement`` specifies a requirement contributing to
|
|
126
|
-
the current candidate list
|
|
127
|
-
|
|
128
|
-
* ``parent`` specifies the candidate that provides
|
|
129
|
-
(depended on) the requirement, or `None`
|
|
130
|
-
to indicate a root requirement.
|
|
131
|
-
|
|
132
|
-
resolvelib >=0.7.0, < 0.8.0
|
|
133
|
-
|
|
134
|
-
:param identifier: The value returned by ``identify()``.
|
|
135
|
-
|
|
136
|
-
:param resolutions: Mapping of identifier, candidate pairs.
|
|
137
|
-
|
|
138
|
-
:param candidates: Possible candidates for the identifier.
|
|
139
|
-
Mapping of identifier, list of candidate pairs.
|
|
140
|
-
|
|
141
|
-
:param information: Requirement information of each package.
|
|
142
|
-
Mapping of identifier, list of named tuple pairs.
|
|
143
|
-
The named tuples have the entries ``requirement`` and ``parent``.
|
|
144
|
-
|
|
145
|
-
resolvelib >=0.8.0, <= 1.0.1
|
|
146
|
-
|
|
147
121
|
:param identifier: The value returned by ``identify()``.
|
|
148
122
|
|
|
149
123
|
:param resolutions: Mapping of identifier, candidate pairs.
|
|
@@ -179,10 +153,6 @@ class CollectionDependencyProviderBase(AbstractProvider):
|
|
|
179
153
|
the value is, the more preferred this requirement is (i.e. the
|
|
180
154
|
sorting function is called with ``reverse=False``).
|
|
181
155
|
"""
|
|
182
|
-
raise NotImplementedError
|
|
183
|
-
|
|
184
|
-
def _get_preference(self, candidates):
|
|
185
|
-
# type: (list[Candidate]) -> t.Union[float, int]
|
|
186
156
|
if any(
|
|
187
157
|
candidate in self._preferred_candidates
|
|
188
158
|
for candidate in candidates
|
|
@@ -192,8 +162,12 @@ class CollectionDependencyProviderBase(AbstractProvider):
|
|
|
192
162
|
return float('-inf')
|
|
193
163
|
return len(candidates)
|
|
194
164
|
|
|
195
|
-
def find_matches(
|
|
196
|
-
|
|
165
|
+
def find_matches(
|
|
166
|
+
self,
|
|
167
|
+
identifier: str,
|
|
168
|
+
requirements: _c.Mapping[str, _c.Iterator[Requirement]],
|
|
169
|
+
incompatibilities: _c.Mapping[str, _c.Iterator[Candidate]],
|
|
170
|
+
) -> list[Candidate]:
|
|
197
171
|
r"""Find all possible candidates satisfying given requirements.
|
|
198
172
|
|
|
199
173
|
This tries to get candidates based on the requirements' types.
|
|
@@ -204,32 +178,13 @@ class CollectionDependencyProviderBase(AbstractProvider):
|
|
|
204
178
|
For a "named" requirement, Galaxy-compatible APIs are consulted
|
|
205
179
|
to find concrete candidates for this requirement. If there's a
|
|
206
180
|
pre-installed candidate, it's prepended in front of others.
|
|
207
|
-
|
|
208
|
-
resolvelib >=0.5.3, <0.6.0
|
|
209
|
-
|
|
210
|
-
:param requirements: A collection of requirements which all of \
|
|
211
|
-
the returned candidates must match. \
|
|
212
|
-
All requirements are guaranteed to have \
|
|
213
|
-
the same identifier. \
|
|
214
|
-
The collection is never empty.
|
|
215
|
-
|
|
216
|
-
resolvelib >=0.6.0
|
|
217
|
-
|
|
218
|
-
:param identifier: The value returned by ``identify()``.
|
|
219
|
-
|
|
220
|
-
:param requirements: The requirements all returned candidates must satisfy.
|
|
221
|
-
Mapping of identifier, iterator of requirement pairs.
|
|
222
|
-
|
|
223
|
-
:param incompatibilities: Incompatible versions that must be excluded
|
|
224
|
-
from the returned list.
|
|
225
|
-
|
|
226
|
-
:returns: An iterable that orders candidates by preference, \
|
|
227
|
-
e.g. the most preferred candidate comes first.
|
|
228
181
|
"""
|
|
229
|
-
|
|
182
|
+
return [
|
|
183
|
+
match for match in self._find_matches(list(requirements[identifier]))
|
|
184
|
+
if not any(match.ver == incompat.ver for incompat in incompatibilities[identifier])
|
|
185
|
+
]
|
|
230
186
|
|
|
231
|
-
def _find_matches(self, requirements):
|
|
232
|
-
# type: (list[Requirement]) -> list[Candidate]
|
|
187
|
+
def _find_matches(self, requirements: list[Requirement]) -> list[Candidate]:
|
|
233
188
|
# FIXME: The first requirement may be a Git repo followed by
|
|
234
189
|
# FIXME: its cloned tmp dir. Using only the first one creates
|
|
235
190
|
# FIXME: loops that prevent any further dependency exploration.
|
|
@@ -278,7 +233,7 @@ class CollectionDependencyProviderBase(AbstractProvider):
|
|
|
278
233
|
# NOTE: Another known mistake is setting a minor part of the SemVer notation
|
|
279
234
|
# NOTE: skipping the "patch" bit like "1.0" which is assumed non-compliant even
|
|
280
235
|
# NOTE: after the conversion to string.
|
|
281
|
-
if not isinstance(version,
|
|
236
|
+
if not isinstance(version, str):
|
|
282
237
|
raise ValueError(version_err)
|
|
283
238
|
elif version != '*':
|
|
284
239
|
try:
|
|
@@ -457,52 +412,3 @@ class CollectionDependencyProviderBase(AbstractProvider):
|
|
|
457
412
|
self._make_req_from_dict({'name': dep_name, 'version': dep_req})
|
|
458
413
|
for dep_name, dep_req in req_map.items()
|
|
459
414
|
]
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
# Classes to handle resolvelib API changes between minor versions for 0.X
|
|
463
|
-
class CollectionDependencyProvider050(CollectionDependencyProviderBase):
|
|
464
|
-
def find_matches(self, requirements): # type: ignore[override]
|
|
465
|
-
# type: (list[Requirement]) -> list[Candidate]
|
|
466
|
-
return self._find_matches(requirements)
|
|
467
|
-
|
|
468
|
-
def get_preference(self, resolution, candidates, information): # type: ignore[override]
|
|
469
|
-
# type: (t.Optional[Candidate], list[Candidate], list[t.NamedTuple]) -> t.Union[float, int]
|
|
470
|
-
return self._get_preference(candidates)
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
class CollectionDependencyProvider060(CollectionDependencyProviderBase):
|
|
474
|
-
def find_matches(self, identifier, requirements, incompatibilities): # type: ignore[override]
|
|
475
|
-
# type: (str, t.Mapping[str, t.Iterator[Requirement]], t.Mapping[str, t.Iterator[Requirement]]) -> list[Candidate]
|
|
476
|
-
return [
|
|
477
|
-
match for match in self._find_matches(list(requirements[identifier]))
|
|
478
|
-
if not any(match.ver == incompat.ver for incompat in incompatibilities[identifier])
|
|
479
|
-
]
|
|
480
|
-
|
|
481
|
-
def get_preference(self, resolution, candidates, information): # type: ignore[override]
|
|
482
|
-
# type: (t.Optional[Candidate], list[Candidate], list[t.NamedTuple]) -> t.Union[float, int]
|
|
483
|
-
return self._get_preference(candidates)
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
class CollectionDependencyProvider070(CollectionDependencyProvider060):
|
|
487
|
-
def get_preference(self, identifier, resolutions, candidates, information): # type: ignore[override]
|
|
488
|
-
# type: (str, t.Mapping[str, Candidate], t.Mapping[str, t.Iterator[Candidate]], t.Iterator[t.NamedTuple]) -> t.Union[float, int]
|
|
489
|
-
return self._get_preference(list(candidates[identifier]))
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
class CollectionDependencyProvider080(CollectionDependencyProvider060):
|
|
493
|
-
def get_preference(self, identifier, resolutions, candidates, information, backtrack_causes): # type: ignore[override]
|
|
494
|
-
# type: (str, t.Mapping[str, Candidate], t.Mapping[str, t.Iterator[Candidate]], t.Iterator[t.NamedTuple], t.Sequence) -> t.Union[float, int]
|
|
495
|
-
return self._get_preference(list(candidates[identifier]))
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
def _get_provider(): # type () -> CollectionDependencyProviderBase
|
|
499
|
-
if RESOLVELIB_VERSION >= SemanticVersion("0.8.0"):
|
|
500
|
-
return CollectionDependencyProvider080
|
|
501
|
-
if RESOLVELIB_VERSION >= SemanticVersion("0.7.0"):
|
|
502
|
-
return CollectionDependencyProvider070
|
|
503
|
-
if RESOLVELIB_VERSION >= SemanticVersion("0.6.0"):
|
|
504
|
-
return CollectionDependencyProvider060
|
|
505
|
-
return CollectionDependencyProvider050
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
CollectionDependencyProvider = _get_provider()
|
ansible/galaxy/role.py
CHANGED
|
@@ -23,7 +23,6 @@ from __future__ import annotations
|
|
|
23
23
|
|
|
24
24
|
import errno
|
|
25
25
|
import datetime
|
|
26
|
-
import functools
|
|
27
26
|
import os
|
|
28
27
|
import tarfile
|
|
29
28
|
import tempfile
|
|
@@ -46,32 +45,6 @@ from ansible.utils.path import is_subpath, unfrackpath
|
|
|
46
45
|
display = Display()
|
|
47
46
|
|
|
48
47
|
|
|
49
|
-
@functools.cache
|
|
50
|
-
def _check_working_data_filter() -> bool:
|
|
51
|
-
"""
|
|
52
|
-
Check if tarfile.data_filter implementation is working
|
|
53
|
-
for the current Python version or not
|
|
54
|
-
"""
|
|
55
|
-
|
|
56
|
-
# Implemented the following code to circumvent broken implementation of data_filter
|
|
57
|
-
# in tarfile. See for more information - https://github.com/python/cpython/issues/107845
|
|
58
|
-
# deprecated: description='probing broken data filter implementation' python_version='3.11'
|
|
59
|
-
ret = False
|
|
60
|
-
if hasattr(tarfile, 'data_filter'):
|
|
61
|
-
# We explicitly check if tarfile.data_filter is broken or not
|
|
62
|
-
ti = tarfile.TarInfo('docs/README.md')
|
|
63
|
-
ti.type = tarfile.SYMTYPE
|
|
64
|
-
ti.linkname = '../README.md'
|
|
65
|
-
|
|
66
|
-
try:
|
|
67
|
-
tarfile.data_filter(ti, '/foo')
|
|
68
|
-
except tarfile.LinkOutsideDestinationError:
|
|
69
|
-
pass
|
|
70
|
-
else:
|
|
71
|
-
ret = True
|
|
72
|
-
return ret
|
|
73
|
-
|
|
74
|
-
|
|
75
48
|
class GalaxyRole(object):
|
|
76
49
|
|
|
77
50
|
SUPPORTED_SCMS = set(['git', 'hg'])
|
|
@@ -418,12 +391,7 @@ class GalaxyRole(object):
|
|
|
418
391
|
relative_path = os.path.join(*full_path.replace(relative_path_dir, "", 1).split(os.sep))
|
|
419
392
|
setattr(member, attr, relative_path)
|
|
420
393
|
|
|
421
|
-
|
|
422
|
-
# deprecated: description='extract fallback without filter' python_version='3.11'
|
|
423
|
-
role_tar_file.extract(member, to_native(self.path), filter='data') # type: ignore[call-arg]
|
|
424
|
-
else:
|
|
425
|
-
# Remove along with manual path filter once Python 3.12 is minimum supported version
|
|
426
|
-
role_tar_file.extract(member, to_native(self.path))
|
|
394
|
+
role_tar_file.extract(member, to_native(self.path), filter='data')
|
|
427
395
|
|
|
428
396
|
# write out the install info file for later use
|
|
429
397
|
self._write_galaxy_install_info()
|
ansible/inventory/manager.py
CHANGED
|
@@ -33,7 +33,6 @@ from ansible._internal import _json, _wrapt
|
|
|
33
33
|
from ansible._internal._json import EncryptedStringBehavior
|
|
34
34
|
from ansible.errors import AnsibleError, AnsibleOptionsError
|
|
35
35
|
from ansible.inventory.data import InventoryData
|
|
36
|
-
from ansible.module_utils.six import string_types
|
|
37
36
|
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
|
38
37
|
from ansible.parsing.utils.addresses import parse_address
|
|
39
38
|
from ansible.plugins.loader import inventory_loader
|
|
@@ -112,7 +111,7 @@ def split_host_pattern(pattern):
|
|
|
112
111
|
results = (split_host_pattern(p) for p in pattern)
|
|
113
112
|
# flatten the results
|
|
114
113
|
return list(itertools.chain.from_iterable(results))
|
|
115
|
-
elif not isinstance(pattern,
|
|
114
|
+
elif not isinstance(pattern, str):
|
|
116
115
|
pattern = to_text(pattern, errors='surrogate_or_strict')
|
|
117
116
|
|
|
118
117
|
# If it's got commas in it, we'll treat it as a straightforward
|
|
@@ -162,7 +161,7 @@ class InventoryManager(object):
|
|
|
162
161
|
# the inventory dirs, files, script paths or lists of hosts
|
|
163
162
|
if sources is None:
|
|
164
163
|
self._sources = []
|
|
165
|
-
elif isinstance(sources,
|
|
164
|
+
elif isinstance(sources, str):
|
|
166
165
|
self._sources = [sources]
|
|
167
166
|
else:
|
|
168
167
|
self._sources = sources
|
ansible/keyword_desc.yml
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
accelerate: "*DEPRECATED*, set to True to use accelerate connection plugin."
|
|
2
|
-
accelerate_ipv6: "*DEPRECATED*, set to True to force accelerate plugin to use ipv6 for its connection."
|
|
3
|
-
accelerate_port: "*DEPRECATED*, set to override default port use for accelerate connection."
|
|
4
1
|
action: "The 'action' to execute for a task, it normally translates into a C(module) or action plugin."
|
|
5
2
|
args: "A secondary way to add arguments into a task. Takes a dictionary in which keys map to options and values."
|
|
6
3
|
always: List of tasks, in a block, that execute no matter if there is an error in the block or not.
|
|
@@ -500,17 +500,9 @@ class AnsibleDatatagBase(AnsibleSerializableDataclass, metaclass=abc.ABCMeta):
|
|
|
500
500
|
_known_tag_type_map: t.Dict[str, t.Type[AnsibleDatatagBase]] = {}
|
|
501
501
|
_known_tag_types: t.Set[t.Type[AnsibleDatatagBase]] = set()
|
|
502
502
|
|
|
503
|
-
if sys.version_info >= (3, 9):
|
|
504
|
-
# Include the key and value types in the type hints on Python 3.9 and later.
|
|
505
|
-
# Earlier versions do not support subscriptable dict.
|
|
506
|
-
# deprecated: description='always use subscriptable dict' python_version='3.8'
|
|
507
|
-
class _AnsibleTagsMapping(dict[type[_TAnsibleDatatagBase], _TAnsibleDatatagBase]):
|
|
508
|
-
__slots__ = _NO_INSTANCE_STORAGE
|
|
509
503
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
class _AnsibleTagsMapping(dict):
|
|
513
|
-
__slots__ = _NO_INSTANCE_STORAGE
|
|
504
|
+
class _AnsibleTagsMapping(dict[type[_TAnsibleDatatagBase], _TAnsibleDatatagBase]):
|
|
505
|
+
__slots__ = _NO_INSTANCE_STORAGE
|
|
514
506
|
|
|
515
507
|
|
|
516
508
|
class _EmptyROInternalTagsMapping(dict):
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
import types
|
|
5
|
+
|
|
6
|
+
from ansible.module_utils.common import warnings
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# INLINED FROM THE SIX LIBRARY, see lib/ansible/module_utils/six/__init__.py
|
|
10
|
+
# Copyright (c) 2010-2024 Benjamin Peterson
|
|
11
|
+
def with_metaclass(meta, *bases):
|
|
12
|
+
"""Create a base class with a metaclass."""
|
|
13
|
+
|
|
14
|
+
# This requires a bit of explanation: the basic idea is to make a dummy
|
|
15
|
+
# metaclass for one level of class instantiation that replaces itself with
|
|
16
|
+
# the actual metaclass.
|
|
17
|
+
class metaclass(type):
|
|
18
|
+
|
|
19
|
+
def __new__(cls, name, this_bases, d):
|
|
20
|
+
if sys.version_info[:2] >= (3, 7):
|
|
21
|
+
# This version introduced PEP 560 that requires a bit
|
|
22
|
+
# of extra care (we mimic what is done by __build_class__).
|
|
23
|
+
resolved_bases = types.resolve_bases(bases)
|
|
24
|
+
if resolved_bases is not bases:
|
|
25
|
+
d['__orig_bases__'] = bases
|
|
26
|
+
else:
|
|
27
|
+
resolved_bases = bases
|
|
28
|
+
return meta(name, resolved_bases, d)
|
|
29
|
+
|
|
30
|
+
@classmethod
|
|
31
|
+
def __prepare__(cls, name, this_bases):
|
|
32
|
+
return meta.__prepare__(name, bases)
|
|
33
|
+
|
|
34
|
+
return type.__new__(metaclass, 'temporary_class', (), {})
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def add_metaclass(metaclass):
|
|
38
|
+
"""Class decorator for creating a class with a metaclass."""
|
|
39
|
+
|
|
40
|
+
def wrapper(cls):
|
|
41
|
+
orig_vars = cls.__dict__.copy()
|
|
42
|
+
slots = orig_vars.get('__slots__')
|
|
43
|
+
if slots is not None:
|
|
44
|
+
if isinstance(slots, str):
|
|
45
|
+
slots = [slots]
|
|
46
|
+
for slots_var in slots:
|
|
47
|
+
orig_vars.pop(slots_var)
|
|
48
|
+
orig_vars.pop('__dict__', None)
|
|
49
|
+
orig_vars.pop('__weakref__', None)
|
|
50
|
+
if hasattr(cls, '__qualname__'):
|
|
51
|
+
orig_vars['__qualname__'] = cls.__qualname__
|
|
52
|
+
return metaclass(cls.__name__, cls.__bases__, orig_vars)
|
|
53
|
+
|
|
54
|
+
return wrapper
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def iteritems(d, **kw):
|
|
58
|
+
return iter(d.items(**kw))
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
_mini_six = {
|
|
62
|
+
"PY2": False,
|
|
63
|
+
"PY3": True,
|
|
64
|
+
"text_type": str,
|
|
65
|
+
"binary_type": bytes,
|
|
66
|
+
"string_types": (str,),
|
|
67
|
+
"integer_types": (int,),
|
|
68
|
+
"iteritems": iteritems,
|
|
69
|
+
"add_metaclass": add_metaclass,
|
|
70
|
+
"with_metaclass": with_metaclass,
|
|
71
|
+
}
|
|
72
|
+
# INLINED SIX END
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def deprecate(importable_name: str, module_name: str, *deprecated_args) -> object:
|
|
76
|
+
"""Inject import-time deprecation warnings."""
|
|
77
|
+
if not (importable_name in deprecated_args and (importable := _mini_six.get(importable_name, ...) is not ...)):
|
|
78
|
+
raise AttributeError(f"module {module_name!r} has no attribute {importable_name!r}")
|
|
79
|
+
|
|
80
|
+
# TODO Inspect and remove all calls to this function in 2.24
|
|
81
|
+
warnings.deprecate(
|
|
82
|
+
msg=f"Importing {importable_name!r} from {module_name!r} is deprecated.",
|
|
83
|
+
version="2.24",
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
return importable
|
ansible/module_utils/_text.py
CHANGED
|
@@ -1,15 +1,35 @@
|
|
|
1
1
|
# Copyright (c), Toshio Kuratomi <tkuratomi@ansible.com> 2016
|
|
2
2
|
# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
|
|
3
3
|
|
|
4
|
-
"""
|
|
5
|
-
.. warn:: Use ansible.module_utils.common.text.converters instead.
|
|
6
|
-
"""
|
|
7
4
|
from __future__ import annotations
|
|
8
5
|
|
|
9
|
-
|
|
10
|
-
# pylint: disable=unused-import
|
|
11
|
-
import codecs
|
|
6
|
+
from ansible.module_utils.common import warnings as _warnings
|
|
12
7
|
|
|
13
|
-
from ansible.module_utils.six import PY3, text_type, binary_type
|
|
14
8
|
|
|
15
|
-
|
|
9
|
+
_mini_six = {
|
|
10
|
+
"binary_type": bytes,
|
|
11
|
+
"text_type": str,
|
|
12
|
+
"PY3": True,
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def __getattr__(importable_name: str) -> object:
|
|
17
|
+
"""Inject import-time deprecation warnings."""
|
|
18
|
+
help_text: str | None = None
|
|
19
|
+
importable: object
|
|
20
|
+
if importable_name == "codecs":
|
|
21
|
+
import codecs
|
|
22
|
+
importable = codecs
|
|
23
|
+
elif importable_name in {"to_bytes", "to_native", "to_text"}:
|
|
24
|
+
from ansible.module_utils.common.text import converters
|
|
25
|
+
importable = getattr(converters, importable_name)
|
|
26
|
+
help_text = "Use ansible.module_utils.common.text.converters instead."
|
|
27
|
+
elif (importable := _mini_six.get(importable_name, ...)) is ...:
|
|
28
|
+
raise AttributeError(f"module {__name__!r} has no attribute {importable_name!r}")
|
|
29
|
+
|
|
30
|
+
_warnings.deprecate(
|
|
31
|
+
msg=f"Importing {importable_name!r} from {__name__!r} is deprecated.",
|
|
32
|
+
version="2.24",
|
|
33
|
+
help_text=help_text,
|
|
34
|
+
)
|
|
35
|
+
return importable
|
ansible/module_utils/basic.py
CHANGED
|
@@ -11,12 +11,13 @@ import typing as t
|
|
|
11
11
|
|
|
12
12
|
# Used for determining if the system is running a new enough python version
|
|
13
13
|
# and should only restrict on our documented minimum versions
|
|
14
|
-
_PY_MIN = (3,
|
|
14
|
+
_PY_MIN = (3, 9)
|
|
15
15
|
|
|
16
16
|
if sys.version_info < _PY_MIN:
|
|
17
17
|
print(json.dumps(dict(
|
|
18
18
|
failed=True,
|
|
19
|
-
msg=f"
|
|
19
|
+
msg=f"Ansible requires Python {'.'.join(map(str, _PY_MIN))} or newer on the target. "
|
|
20
|
+
f"Current version: {''.join(sys.version.splitlines())}",
|
|
20
21
|
)))
|
|
21
22
|
sys.exit(1)
|
|
22
23
|
|
|
@@ -45,6 +46,15 @@ import tempfile
|
|
|
45
46
|
import time
|
|
46
47
|
import traceback
|
|
47
48
|
|
|
49
|
+
from collections.abc import (
|
|
50
|
+
KeysView,
|
|
51
|
+
Mapping,
|
|
52
|
+
MutableMapping,
|
|
53
|
+
Sequence,
|
|
54
|
+
MutableSequence,
|
|
55
|
+
Set,
|
|
56
|
+
MutableSet,
|
|
57
|
+
)
|
|
48
58
|
from functools import reduce
|
|
49
59
|
|
|
50
60
|
try:
|
|
@@ -122,13 +132,6 @@ def _get_available_hash_algorithms():
|
|
|
122
132
|
AVAILABLE_HASH_ALGORITHMS = _get_available_hash_algorithms()
|
|
123
133
|
|
|
124
134
|
from ansible.module_utils.common import json as _json
|
|
125
|
-
|
|
126
|
-
from ansible.module_utils.six.moves.collections_abc import (
|
|
127
|
-
KeysView,
|
|
128
|
-
Mapping, MutableMapping,
|
|
129
|
-
Sequence, MutableSequence,
|
|
130
|
-
Set, MutableSet,
|
|
131
|
-
)
|
|
132
135
|
from ansible.module_utils.common.locale import get_best_parsable_locale
|
|
133
136
|
from ansible.module_utils.common.process import get_bin_path
|
|
134
137
|
from ansible.module_utils.common.file import (
|
|
@@ -2185,6 +2188,18 @@ def get_module_path():
|
|
|
2185
2188
|
return os.path.dirname(os.path.realpath(__file__))
|
|
2186
2189
|
|
|
2187
2190
|
|
|
2191
|
+
_mini_six = {
|
|
2192
|
+
"b": lambda s: s.encode("latin-1"),
|
|
2193
|
+
"PY2": False,
|
|
2194
|
+
"PY3": True,
|
|
2195
|
+
"text_type": str,
|
|
2196
|
+
"binary_type": bytes,
|
|
2197
|
+
"string_types": (str,),
|
|
2198
|
+
"integer_types": (int,),
|
|
2199
|
+
"iteritems": lambda d, **kw: iter(d.items(**kw)),
|
|
2200
|
+
}
|
|
2201
|
+
|
|
2202
|
+
|
|
2188
2203
|
def __getattr__(importable_name):
|
|
2189
2204
|
"""Inject import-time deprecation warnings."""
|
|
2190
2205
|
if importable_name == 'datetime':
|
|
@@ -2202,24 +2217,12 @@ def __getattr__(importable_name):
|
|
|
2202
2217
|
elif importable_name == 'repeat':
|
|
2203
2218
|
from itertools import repeat
|
|
2204
2219
|
importable = repeat
|
|
2205
|
-
elif importable_name in {
|
|
2206
|
-
'PY2', 'PY3', 'b', 'binary_type', 'integer_types',
|
|
2207
|
-
'iteritems', 'string_types', 'text_type',
|
|
2208
|
-
}:
|
|
2209
|
-
import importlib
|
|
2210
|
-
importable = getattr(
|
|
2211
|
-
importlib.import_module('ansible.module_utils.six'),
|
|
2212
|
-
importable_name
|
|
2213
|
-
)
|
|
2214
2220
|
elif importable_name == 'map':
|
|
2215
2221
|
importable = map
|
|
2216
2222
|
elif importable_name == 'shlex_quote':
|
|
2217
2223
|
importable = shlex.quote
|
|
2218
|
-
|
|
2219
|
-
raise AttributeError(
|
|
2220
|
-
f'cannot import name {importable_name !r} '
|
|
2221
|
-
f"from '{__name__}' ({__file__ !s})"
|
|
2222
|
-
)
|
|
2224
|
+
elif (importable := _mini_six.get(importable_name, ...)) is ...:
|
|
2225
|
+
raise AttributeError(f"module {__name__!r} has no attribute {importable_name!r}")
|
|
2223
2226
|
|
|
2224
2227
|
deprecate(
|
|
2225
2228
|
msg=f"Importing '{importable_name}' from '{__name__}' is deprecated.",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
|
|
3
3
|
"""Collections ABC import shim.
|
|
4
4
|
|
|
5
|
-
Use `
|
|
5
|
+
Use `collections.abc` instead.
|
|
6
6
|
This module exists only for backwards compatibility.
|
|
7
7
|
"""
|
|
8
8
|
|
|
@@ -10,7 +10,7 @@ from __future__ import annotations
|
|
|
10
10
|
|
|
11
11
|
# Although this was originally intended for internal use only, it has wide adoption in collections.
|
|
12
12
|
# This is due in part to sanity tests previously recommending its use over `collections` imports.
|
|
13
|
-
from
|
|
13
|
+
from collections.abc import ( # pylint: disable=unused-import
|
|
14
14
|
MappingView,
|
|
15
15
|
ItemsView,
|
|
16
16
|
KeysView,
|
|
@@ -25,3 +25,12 @@ from ansible.module_utils.six.moves.collections_abc import ( # pylint: disable=
|
|
|
25
25
|
Iterable,
|
|
26
26
|
Iterator,
|
|
27
27
|
)
|
|
28
|
+
|
|
29
|
+
from ansible.module_utils.common import warnings as _warnings
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
_warnings.deprecate(
|
|
33
|
+
msg="The `ansible.module_utils.common._collections_compat` module is deprecated.",
|
|
34
|
+
help_text="Use `collections.abc` from the Python standard library instead.",
|
|
35
|
+
version="2.24",
|
|
36
|
+
)
|
|
@@ -6,9 +6,10 @@
|
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
from collections.abc import Hashable, Mapping, MutableMapping, Sequence # pylint: disable=unused-import
|
|
10
|
+
|
|
11
|
+
from ansible.module_utils._internal import _no_six
|
|
9
12
|
from ansible.module_utils.common import warnings as _warnings
|
|
10
|
-
from ansible.module_utils.six import binary_type, text_type
|
|
11
|
-
from ansible.module_utils.six.moves.collections_abc import Hashable, Mapping, MutableMapping, Sequence # pylint: disable=unused-import
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
class ImmutableDict(Hashable, Mapping):
|
|
@@ -67,7 +68,7 @@ class ImmutableDict(Hashable, Mapping):
|
|
|
67
68
|
|
|
68
69
|
def is_string(seq):
|
|
69
70
|
"""Identify whether the input has a string-like type (including bytes)."""
|
|
70
|
-
return isinstance(seq, (
|
|
71
|
+
return isinstance(seq, (str, bytes))
|
|
71
72
|
|
|
72
73
|
|
|
73
74
|
def is_iterable(seq, include_strings=False):
|
|
@@ -114,3 +115,7 @@ def count(seq):
|
|
|
114
115
|
for elem in seq:
|
|
115
116
|
counters[elem] = counters.get(elem, 0) + 1
|
|
116
117
|
return counters
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def __getattr__(importable_name):
|
|
121
|
+
return _no_six.deprecate(importable_name, __name__, "binary_type", "text_type")
|
|
@@ -7,10 +7,9 @@ from __future__ import annotations
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
import re
|
|
10
|
+
from collections.abc import MutableMapping
|
|
10
11
|
from copy import deepcopy
|
|
11
12
|
|
|
12
|
-
from ansible.module_utils.six.moves.collections_abc import MutableMapping
|
|
13
|
-
|
|
14
13
|
|
|
15
14
|
def camel_dict_to_snake_dict(camel_dict, reversible=False, ignore_list=()):
|
|
16
15
|
"""
|
|
@@ -6,11 +6,13 @@
|
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
8
|
import re
|
|
9
|
+
|
|
10
|
+
# backward compat
|
|
11
|
+
from builtins import zip # pylint: disable=unused-import
|
|
12
|
+
|
|
9
13
|
from struct import pack
|
|
10
14
|
from socket import inet_ntoa
|
|
11
15
|
|
|
12
|
-
from ansible.module_utils.six.moves import zip
|
|
13
|
-
|
|
14
16
|
|
|
15
17
|
VALID_MASKS = [2**8 - 2**i for i in range(0, 9)]
|
|
16
18
|
|