ansible-core 2.19.0b3__py3-none-any.whl → 2.19.0b4__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.
- ansible/_internal/__init__.py +1 -1
- ansible/_internal/_json/__init__.py +1 -1
- ansible/_internal/_testing.py +26 -0
- ansible/cli/arguments/option_helpers.py +6 -2
- ansible/config/base.yml +5 -23
- ansible/config/manager.py +142 -101
- ansible/constants.py +1 -1
- ansible/inventory/manager.py +1 -0
- ansible/module_utils/ansible_release.py +1 -1
- ansible/module_utils/facts/virtual/linux.py +1 -1
- ansible/module_utils/parsing/convert_bool.py +6 -0
- ansible/modules/assemble.py +4 -4
- ansible/modules/cron.py +3 -5
- ansible/modules/dnf5.py +1 -0
- ansible/modules/git.py +1 -6
- ansible/modules/pip.py +2 -4
- ansible/modules/sysvinit.py +3 -3
- ansible/plugins/action/__init__.py +1 -1
- ansible/plugins/action/template.py +3 -0
- ansible/plugins/loader.py +3 -2
- ansible/release.py +1 -1
- ansible/utils/collection_loader/__init__.py +2 -0
- ansible/utils/display.py +4 -0
- ansible/utils/plugin_docs.py +2 -1
- {ansible_core-2.19.0b3.dist-info → ansible_core-2.19.0b4.dist-info}/METADATA +3 -2
- {ansible_core-2.19.0b3.dist-info → ansible_core-2.19.0b4.dist-info}/RECORD +36 -35
- {ansible_core-2.19.0b3.dist-info → ansible_core-2.19.0b4.dist-info}/WHEEL +1 -1
- ansible_test/_util/controller/sanity/pylint/plugins/deprecated_calls.py +12 -1
- {ansible_core-2.19.0b3.dist-info → ansible_core-2.19.0b4.dist-info}/entry_points.txt +0 -0
- {ansible_core-2.19.0b3.dist-info → ansible_core-2.19.0b4.dist-info/licenses}/COPYING +0 -0
- {ansible_core-2.19.0b3.dist-info → ansible_core-2.19.0b4.dist-info/licenses/licenses}/Apache-License.txt +0 -0
- {ansible_core-2.19.0b3.dist-info → ansible_core-2.19.0b4.dist-info/licenses/licenses}/BSD-3-Clause.txt +0 -0
- {ansible_core-2.19.0b3.dist-info → ansible_core-2.19.0b4.dist-info/licenses/licenses}/MIT-license.txt +0 -0
- {ansible_core-2.19.0b3.dist-info → ansible_core-2.19.0b4.dist-info/licenses/licenses}/PSF-license.txt +0 -0
- {ansible_core-2.19.0b3.dist-info → ansible_core-2.19.0b4.dist-info/licenses/licenses}/simplified_bsd.txt +0 -0
- {ansible_core-2.19.0b3.dist-info → ansible_core-2.19.0b4.dist-info}/top_level.txt +0 -0
ansible/_internal/__init__.py
CHANGED
@@ -18,7 +18,7 @@ def get_controller_serialize_map() -> dict[type, t.Callable]:
|
|
18
18
|
return {
|
19
19
|
_lazy_containers._AnsibleLazyTemplateDict: _profiles._JSONSerializationProfile.discard_tags,
|
20
20
|
_lazy_containers._AnsibleLazyTemplateList: _profiles._JSONSerializationProfile.discard_tags,
|
21
|
-
EncryptedString: str, # preserves tags since this is an
|
21
|
+
EncryptedString: str, # preserves tags since this is an instance of EncryptedString; if tags should be discarded from str, another entry will handle it
|
22
22
|
}
|
23
23
|
|
24
24
|
|
@@ -152,7 +152,7 @@ class AnsibleVariableVisitor:
|
|
152
152
|
result: _T
|
153
153
|
|
154
154
|
# DTFIX-RELEASE: the visitor is ignoring dict/mapping keys except for debugging and schema-aware checking, it should be doing type checks on keys
|
155
|
-
# keep in mind the allowed types for keys is a more restrictive set than for values (str and
|
155
|
+
# keep in mind the allowed types for keys is a more restrictive set than for values (str and tagged str only, not EncryptedString)
|
156
156
|
# DTFIX-RELEASE: some type lists being consulted (the ones from datatag) are probably too permissive, and perhaps should not be dynamic
|
157
157
|
|
158
158
|
if (result := self._early_visit(value, value_type)) is not _sentinel:
|
@@ -0,0 +1,26 @@
|
|
1
|
+
"""
|
2
|
+
Testing utilities for use in integration tests, not unit tests or non-test code.
|
3
|
+
Provides better error behavior than Python's `assert` statement.
|
4
|
+
"""
|
5
|
+
|
6
|
+
from __future__ import annotations
|
7
|
+
|
8
|
+
import contextlib
|
9
|
+
import typing as t
|
10
|
+
|
11
|
+
|
12
|
+
class _Checker:
|
13
|
+
@staticmethod
|
14
|
+
def check(value: object, msg: str | None = 'Value is not truthy.') -> None:
|
15
|
+
"""Raise an `AssertionError` if the given `value` is not truthy."""
|
16
|
+
if not value:
|
17
|
+
raise AssertionError(msg)
|
18
|
+
|
19
|
+
|
20
|
+
@contextlib.contextmanager
|
21
|
+
def hard_fail_context(msg: str) -> t.Generator[_Checker]:
|
22
|
+
"""Enter a context which converts all exceptions to `BaseException` and provides a `Checker` instance for making assertions."""
|
23
|
+
try:
|
24
|
+
yield _Checker()
|
25
|
+
except BaseException as ex:
|
26
|
+
raise BaseException(f"Hard failure: {msg}") from ex
|
@@ -535,13 +535,17 @@ def _tagged_type_factory(name: str, func: t.Callable[[str], object], /) -> t.Cal
|
|
535
535
|
def tag_value(value: str) -> object:
|
536
536
|
result = func(value)
|
537
537
|
|
538
|
-
if result is value:
|
538
|
+
if result is value or func is str:
|
539
539
|
# Values which are not mutated are automatically trusted for templating.
|
540
540
|
# The `is` reference equality is critically important, as other types may only alter the tags, so object equality is
|
541
541
|
# not sufficient to prevent them being tagged as trusted when they should not.
|
542
|
+
# Explicitly include all usages using the `str` type factory since it strips tags.
|
542
543
|
result = TrustedAsTemplate().tag(result)
|
543
544
|
|
544
|
-
|
545
|
+
if not (origin := Origin.get_tag(value)):
|
546
|
+
origin = Origin(description=f'<CLI option {name!r}>')
|
547
|
+
|
548
|
+
return origin.tag(result)
|
545
549
|
|
546
550
|
tag_value._name = name # simplify debugging by attaching the argument name to the function
|
547
551
|
|
ansible/config/base.yml
CHANGED
@@ -757,7 +757,7 @@ DEFAULT_HASH_BEHAVIOUR:
|
|
757
757
|
- {key: hash_behaviour, section: defaults}
|
758
758
|
DEFAULT_HOST_LIST:
|
759
759
|
name: Inventory Source
|
760
|
-
default: /etc/ansible/hosts
|
760
|
+
default: [/etc/ansible/hosts]
|
761
761
|
description: Comma-separated list of Ansible inventory sources
|
762
762
|
env:
|
763
763
|
- name: ANSIBLE_INVENTORY
|
@@ -1054,7 +1054,7 @@ DEFAULT_ROLES_PATH:
|
|
1054
1054
|
yaml: {key: defaults.roles_path}
|
1055
1055
|
DEFAULT_SELINUX_SPECIAL_FS:
|
1056
1056
|
name: Problematic file systems
|
1057
|
-
default: fuse, nfs, vboxsf, ramfs, 9p, vfat
|
1057
|
+
default: [fuse, nfs, vboxsf, ramfs, 9p, vfat]
|
1058
1058
|
description:
|
1059
1059
|
- "Some filesystems do not support safe operations and/or return inconsistent errors,
|
1060
1060
|
this setting makes Ansible 'tolerate' those in the list without causing fatal errors."
|
@@ -1199,15 +1199,6 @@ DEFAULT_VARS_PLUGIN_PATH:
|
|
1199
1199
|
ini:
|
1200
1200
|
- {key: vars_plugins, section: defaults}
|
1201
1201
|
type: pathspec
|
1202
|
-
# TODO: unused?
|
1203
|
-
#DEFAULT_VAR_COMPRESSION_LEVEL:
|
1204
|
-
# default: 0
|
1205
|
-
# description: 'TODO: write it'
|
1206
|
-
# env: [{name: ANSIBLE_VAR_COMPRESSION_LEVEL}]
|
1207
|
-
# ini:
|
1208
|
-
# - {key: var_compression_level, section: defaults}
|
1209
|
-
# type: integer
|
1210
|
-
# yaml: {key: defaults.var_compression_level}
|
1211
1202
|
DEFAULT_VAULT_ID_MATCH:
|
1212
1203
|
name: Force vault id match
|
1213
1204
|
default: False
|
@@ -1333,7 +1324,7 @@ DISPLAY_SKIPPED_HOSTS:
|
|
1333
1324
|
type: boolean
|
1334
1325
|
DISPLAY_TRACEBACK:
|
1335
1326
|
name: Control traceback display
|
1336
|
-
default: never
|
1327
|
+
default: [never]
|
1337
1328
|
description: When to include tracebacks in extended error messages
|
1338
1329
|
env:
|
1339
1330
|
- name: ANSIBLE_DISPLAY_TRACEBACK
|
@@ -1480,15 +1471,6 @@ GALAXY_COLLECTIONS_PATH_WARNING:
|
|
1480
1471
|
ini:
|
1481
1472
|
- {key: collections_path_warning, section: galaxy}
|
1482
1473
|
version_added: "2.16"
|
1483
|
-
# TODO: unused?
|
1484
|
-
#GALAXY_SCMS:
|
1485
|
-
# name: Galaxy SCMS
|
1486
|
-
# default: git, hg
|
1487
|
-
# description: Available galaxy source control management systems.
|
1488
|
-
# env: [{name: ANSIBLE_GALAXY_SCMS}]
|
1489
|
-
# ini:
|
1490
|
-
# - {key: scms, section: galaxy}
|
1491
|
-
# type: list
|
1492
1474
|
GALAXY_SERVER:
|
1493
1475
|
default: https://galaxy.ansible.com
|
1494
1476
|
description: "URL to prepend when roles don't specify the full URI, assume they are referencing this server as the source."
|
@@ -1731,7 +1713,7 @@ INVENTORY_EXPORT:
|
|
1731
1713
|
type: bool
|
1732
1714
|
INVENTORY_IGNORE_EXTS:
|
1733
1715
|
name: Inventory ignore extensions
|
1734
|
-
default: "{{
|
1716
|
+
default: "{{ REJECT_EXTS + ['.orig', '.cfg', '.retry'] }}"
|
1735
1717
|
description: List of extensions to ignore when using a directory as an inventory source.
|
1736
1718
|
env: [{name: ANSIBLE_INVENTORY_IGNORE}]
|
1737
1719
|
ini:
|
@@ -1788,7 +1770,7 @@ INJECT_FACTS_AS_VARS:
|
|
1788
1770
|
version_added: "2.5"
|
1789
1771
|
MODULE_IGNORE_EXTS:
|
1790
1772
|
name: Module ignore extensions
|
1791
|
-
default: "{{
|
1773
|
+
default: "{{ REJECT_EXTS + ['.yaml', '.yml', '.ini'] }}"
|
1792
1774
|
description:
|
1793
1775
|
- List of extensions to ignore when looking for modules to load.
|
1794
1776
|
- This is for rejecting script and binary module fallback extensions.
|
ansible/config/manager.py
CHANGED
@@ -16,11 +16,12 @@ import typing as t
|
|
16
16
|
from collections.abc import Mapping, Sequence
|
17
17
|
from jinja2.nativetypes import NativeEnvironment
|
18
18
|
|
19
|
+
from ansible._internal._datatag import _tags
|
19
20
|
from ansible.errors import AnsibleOptionsError, AnsibleError, AnsibleUndefinedConfigEntry, AnsibleRequiredOptionError
|
21
|
+
from ansible.module_utils._internal._datatag import AnsibleTagHelper
|
20
22
|
from ansible.module_utils.common.sentinel import Sentinel
|
21
23
|
from ansible.module_utils.common.text.converters import to_text, to_bytes, to_native
|
22
24
|
from ansible.module_utils.common.yaml import yaml_load
|
23
|
-
from ansible.module_utils.six import string_types
|
24
25
|
from ansible.module_utils.parsing.convert_bool import boolean
|
25
26
|
from ansible.parsing.quoting import unquote
|
26
27
|
from ansible.utils.path import cleanup_tmp_file, makedirs_safe, unfrackpath
|
@@ -50,6 +51,14 @@ GALAXY_SERVER_ADDITIONAL = {
|
|
50
51
|
}
|
51
52
|
|
52
53
|
|
54
|
+
@t.runtime_checkable
|
55
|
+
class _EncryptedStringProtocol(t.Protocol):
|
56
|
+
"""Protocol representing an `EncryptedString`, since it cannot be imported here."""
|
57
|
+
# DTFIX-FUTURE: collapse this with the one in collection loader, once we can
|
58
|
+
|
59
|
+
def _decrypt(self) -> str: ...
|
60
|
+
|
61
|
+
|
53
62
|
def _get_config_label(plugin_type: str, plugin_name: str, config: str) -> str:
|
54
63
|
"""Return a label for the given config."""
|
55
64
|
entry = f'{config!r}'
|
@@ -65,133 +74,157 @@ def _get_config_label(plugin_type: str, plugin_name: str, config: str) -> str:
|
|
65
74
|
return entry
|
66
75
|
|
67
76
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
:string: Same as 'str'
|
77
|
+
def ensure_type(value: object, value_type: str | None, origin: str | None = None, origin_ftype: str | None = None) -> t.Any:
|
78
|
+
"""
|
79
|
+
Converts `value` to the requested `value_type`; raises `ValueError` for failed conversions.
|
80
|
+
|
81
|
+
Values for `value_type` are:
|
82
|
+
|
83
|
+
* boolean/bool: Return a `bool` by applying non-strict `bool` filter rules:
|
84
|
+
'y', 'yes', 'on', '1', 'true', 't', 1, 1.0, True return True, any other value is False.
|
85
|
+
* integer/int: Return an `int`. Accepts any `str` parseable by `int` or numeric value with a zero mantissa (including `bool`).
|
86
|
+
* float: Return a `float`. Accepts any `str` parseable by `float` or numeric value (including `bool`).
|
87
|
+
* list: Return a `list`. Accepts `list` or `Sequence`. Also accepts, `str`, splitting on ',' while stripping whitespace and unquoting items.
|
88
|
+
* none: Return `None`. Accepts only the string "None".
|
89
|
+
* path: Return a resolved path. Accepts `str`.
|
90
|
+
* temppath/tmppath/tmp: Return a unique temporary directory inside the resolved path specified by the value.
|
91
|
+
* pathspec: Return a `list` of resolved paths. Accepts a `list` or `Sequence`. Also accepts `str`, splitting on ':'.
|
92
|
+
* pathlist: Return a `list` of resolved paths. Accepts a `list` or `Sequence`. Also accepts `str`, splitting on `,` while stripping whitespace from paths.
|
93
|
+
* dictionary/dict: Return a `dict`. Accepts `dict` or `Mapping`.
|
94
|
+
* string/str: Return a `str`. Accepts `bool`, `int`, `float`, `complex` or `str`.
|
95
|
+
|
96
|
+
Path resolution ensures paths are `str` with expansion of '{{CWD}}', environment variables and '~'.
|
97
|
+
Non-absolute paths are expanded relative to the basedir from `origin`, if specified.
|
98
|
+
|
99
|
+
No conversion is performed if `value_type` is unknown or `value` is `None`.
|
100
|
+
When `origin_ftype` is "ini", a `str` result will be unquoted.
|
93
101
|
"""
|
94
102
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
103
|
+
if value is None:
|
104
|
+
return None
|
105
|
+
|
106
|
+
original_value = value
|
107
|
+
copy_tags = value_type not in ('temppath', 'tmppath', 'tmp')
|
108
|
+
|
109
|
+
value = _ensure_type(value, value_type, origin)
|
110
|
+
|
111
|
+
if copy_tags and value is not original_value:
|
112
|
+
if isinstance(value, list):
|
113
|
+
value = [AnsibleTagHelper.tag_copy(original_value, item) for item in value]
|
114
|
+
|
115
|
+
value = AnsibleTagHelper.tag_copy(original_value, value)
|
116
|
+
|
117
|
+
if isinstance(value, str) and origin_ftype and origin_ftype == 'ini':
|
118
|
+
value = unquote(value)
|
119
|
+
|
120
|
+
return value
|
121
|
+
|
122
|
+
|
123
|
+
def _ensure_type(value: object, value_type: str | None, origin: str | None = None) -> t.Any:
|
124
|
+
"""Internal implementation for `ensure_type`, call that function instead."""
|
125
|
+
original_value = value
|
126
|
+
basedir = origin if origin and os.path.isabs(origin) and os.path.exists(to_bytes(origin)) else None
|
99
127
|
|
100
128
|
if value_type:
|
101
129
|
value_type = value_type.lower()
|
102
130
|
|
103
|
-
|
104
|
-
|
105
|
-
|
131
|
+
match value_type:
|
132
|
+
case 'boolean' | 'bool':
|
133
|
+
return boolean(value, strict=False)
|
134
|
+
|
135
|
+
case 'integer' | 'int':
|
136
|
+
if isinstance(value, int): # handle both int and bool (which is an int)
|
137
|
+
return int(value)
|
106
138
|
|
107
|
-
|
108
|
-
if not isinstance(value, int):
|
139
|
+
if isinstance(value, (float, str)):
|
109
140
|
try:
|
141
|
+
# use Decimal for all other source type conversions; non-zero mantissa is a failure
|
110
142
|
if (decimal_value := decimal.Decimal(value)) == (int_part := int(decimal_value)):
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
143
|
+
return int_part
|
144
|
+
except (decimal.DecimalException, ValueError):
|
145
|
+
pass
|
146
|
+
|
147
|
+
case 'float':
|
148
|
+
if isinstance(value, float):
|
149
|
+
return value
|
116
150
|
|
117
|
-
|
118
|
-
|
119
|
-
|
151
|
+
if isinstance(value, (int, str)):
|
152
|
+
try:
|
153
|
+
return float(value)
|
154
|
+
except ValueError:
|
155
|
+
pass
|
156
|
+
|
157
|
+
case 'list':
|
158
|
+
if isinstance(value, list):
|
159
|
+
return value
|
120
160
|
|
121
|
-
|
122
|
-
|
123
|
-
value = [unquote(x.strip()) for x in value.split(',')]
|
124
|
-
elif not isinstance(value, Sequence):
|
125
|
-
errmsg = 'list'
|
161
|
+
if isinstance(value, str):
|
162
|
+
return [unquote(x.strip()) for x in value.split(',')]
|
126
163
|
|
127
|
-
|
164
|
+
if isinstance(value, Sequence) and not isinstance(value, bytes):
|
165
|
+
return list(value)
|
166
|
+
|
167
|
+
case 'none':
|
128
168
|
if value == "None":
|
129
|
-
|
169
|
+
return None
|
130
170
|
|
131
|
-
|
132
|
-
|
171
|
+
case 'path':
|
172
|
+
if isinstance(value, str):
|
173
|
+
return resolve_path(value, basedir=basedir)
|
133
174
|
|
134
|
-
|
135
|
-
if isinstance(value,
|
175
|
+
case 'temppath' | 'tmppath' | 'tmp':
|
176
|
+
if isinstance(value, str):
|
136
177
|
value = resolve_path(value, basedir=basedir)
|
137
|
-
else:
|
138
|
-
errmsg = 'path'
|
139
178
|
|
140
|
-
elif value_type in ('tmp', 'temppath', 'tmppath'):
|
141
|
-
if isinstance(value, string_types):
|
142
|
-
value = resolve_path(value, basedir=basedir)
|
143
179
|
if not os.path.exists(value):
|
144
180
|
makedirs_safe(value, 0o700)
|
181
|
+
|
145
182
|
prefix = 'ansible-local-%s' % os.getpid()
|
146
183
|
value = tempfile.mkdtemp(prefix=prefix, dir=value)
|
147
184
|
atexit.register(cleanup_tmp_file, value, warn=True)
|
148
|
-
else:
|
149
|
-
errmsg = 'temppath'
|
150
185
|
|
151
|
-
|
152
|
-
|
186
|
+
return value
|
187
|
+
|
188
|
+
case 'pathspec':
|
189
|
+
if isinstance(value, str):
|
153
190
|
value = value.split(os.pathsep)
|
154
191
|
|
155
|
-
if isinstance(value, Sequence):
|
156
|
-
|
157
|
-
else:
|
158
|
-
errmsg = 'pathspec'
|
192
|
+
if isinstance(value, Sequence) and not isinstance(value, bytes) and all(isinstance(x, str) for x in value):
|
193
|
+
return [resolve_path(x, basedir=basedir) for x in value]
|
159
194
|
|
160
|
-
|
161
|
-
if isinstance(value,
|
195
|
+
case 'pathlist':
|
196
|
+
if isinstance(value, str):
|
162
197
|
value = [x.strip() for x in value.split(',')]
|
163
198
|
|
164
|
-
if isinstance(value, Sequence):
|
165
|
-
|
166
|
-
else:
|
167
|
-
errmsg = 'pathlist'
|
199
|
+
if isinstance(value, Sequence) and not isinstance(value, bytes) and all(isinstance(x, str) for x in value):
|
200
|
+
return [resolve_path(x, basedir=basedir) for x in value]
|
168
201
|
|
169
|
-
|
170
|
-
if
|
171
|
-
|
202
|
+
case 'dictionary' | 'dict':
|
203
|
+
if isinstance(value, dict):
|
204
|
+
return value
|
172
205
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
errmsg = 'string'
|
206
|
+
if isinstance(value, Mapping):
|
207
|
+
return dict(value)
|
208
|
+
|
209
|
+
case 'string' | 'str':
|
210
|
+
if isinstance(value, str):
|
211
|
+
return value
|
180
212
|
|
181
|
-
|
182
|
-
|
183
|
-
value = to_text(value, errors='surrogate_or_strict')
|
184
|
-
if origin_ftype and origin_ftype == 'ini':
|
185
|
-
value = unquote(value)
|
213
|
+
if isinstance(value, (bool, int, float, complex)):
|
214
|
+
return str(value)
|
186
215
|
|
187
|
-
|
188
|
-
|
216
|
+
if isinstance(value, _EncryptedStringProtocol):
|
217
|
+
return value._decrypt()
|
189
218
|
|
190
|
-
|
219
|
+
case _:
|
220
|
+
# FIXME: define and document a pass-through value_type (None, 'raw', 'object', '', ...) and then deprecate acceptance of unknown types
|
221
|
+
return value # return non-str values of unknown value_type as-is
|
222
|
+
|
223
|
+
raise ValueError(f'Invalid value provided for {value_type!r}: {original_value!r}')
|
191
224
|
|
192
225
|
|
193
226
|
# FIXME: see if this can live in utils/path
|
194
|
-
def resolve_path(path, basedir=None):
|
227
|
+
def resolve_path(path: str, basedir: str | None = None) -> str:
|
195
228
|
""" resolve relative or 'variable' paths """
|
196
229
|
if '{{CWD}}' in path: # allow users to force CWD using 'magic' {{CWD}}
|
197
230
|
path = path.replace('{{CWD}}', os.getcwd())
|
@@ -304,11 +337,13 @@ def _add_base_defs_deprecations(base_defs):
|
|
304
337
|
process(entry)
|
305
338
|
|
306
339
|
|
307
|
-
class ConfigManager
|
340
|
+
class ConfigManager:
|
308
341
|
|
309
342
|
DEPRECATED = [] # type: list[tuple[str, dict[str, str]]]
|
310
343
|
WARNINGS = set() # type: set[str]
|
311
344
|
|
345
|
+
_errors: list[tuple[str, Exception]]
|
346
|
+
|
312
347
|
def __init__(self, conf_file=None, defs_file=None):
|
313
348
|
|
314
349
|
self._base_defs = {}
|
@@ -329,6 +364,9 @@ class ConfigManager(object):
|
|
329
364
|
# initialize parser and read config
|
330
365
|
self._parse_config_file()
|
331
366
|
|
367
|
+
self._errors = []
|
368
|
+
"""Deferred errors that will be turned into warnings."""
|
369
|
+
|
332
370
|
# ensure we always have config def entry
|
333
371
|
self._base_defs['CONFIG_FILE'] = {'default': None, 'type': 'path'}
|
334
372
|
|
@@ -368,16 +406,16 @@ class ConfigManager(object):
|
|
368
406
|
defs = dict((k, server_config_def(server_key, k, req, value_type)) for k, req, value_type in GALAXY_SERVER_DEF)
|
369
407
|
self.initialize_plugin_configuration_definitions('galaxy_server', server_key, defs)
|
370
408
|
|
371
|
-
def template_default(self, value, variables):
|
372
|
-
if isinstance(value,
|
409
|
+
def template_default(self, value, variables, key_name: str = '<unknown>'):
|
410
|
+
if isinstance(value, str) and (value.startswith('{{') and value.endswith('}}')) and variables is not None:
|
373
411
|
# template default values if possible
|
374
412
|
# NOTE: cannot use is_template due to circular dep
|
375
413
|
try:
|
376
414
|
# FIXME: This really should be using an immutable sandboxed native environment, not just native environment
|
377
|
-
|
378
|
-
value =
|
379
|
-
except Exception:
|
380
|
-
|
415
|
+
template = NativeEnvironment().from_string(value)
|
416
|
+
value = template.render(variables)
|
417
|
+
except Exception as ex:
|
418
|
+
self._errors.append((f'Failed to template default for config {key_name}.', ex))
|
381
419
|
return value
|
382
420
|
|
383
421
|
def _read_config_yaml_file(self, yml_file):
|
@@ -631,7 +669,7 @@ class ConfigManager(object):
|
|
631
669
|
raise AnsibleRequiredOptionError(f"Required config {_get_config_label(plugin_type, plugin_name, config)} not provided.")
|
632
670
|
else:
|
633
671
|
origin = 'default'
|
634
|
-
value = self.template_default(defs[config].get('default'), variables)
|
672
|
+
value = self.template_default(defs[config].get('default'), variables, key_name=_get_config_label(plugin_type, plugin_name, config))
|
635
673
|
|
636
674
|
try:
|
637
675
|
# ensure correct type, can raise exceptions on mismatched types
|
@@ -658,7 +696,7 @@ class ConfigManager(object):
|
|
658
696
|
|
659
697
|
if isinstance(defs[config]['choices'], Mapping):
|
660
698
|
valid = ', '.join([to_text(k) for k in defs[config]['choices'].keys()])
|
661
|
-
elif isinstance(defs[config]['choices'],
|
699
|
+
elif isinstance(defs[config]['choices'], str):
|
662
700
|
valid = defs[config]['choices']
|
663
701
|
elif isinstance(defs[config]['choices'], Sequence):
|
664
702
|
valid = ', '.join([to_text(c) for c in defs[config]['choices']])
|
@@ -674,6 +712,9 @@ class ConfigManager(object):
|
|
674
712
|
else:
|
675
713
|
raise AnsibleUndefinedConfigEntry(f'No config definition exists for {_get_config_label(plugin_type, plugin_name, config)}.')
|
676
714
|
|
715
|
+
if not _tags.Origin.is_tagged_on(value):
|
716
|
+
value = _tags.Origin(description=f'<Config {origin}>').tag(value)
|
717
|
+
|
677
718
|
return value, origin
|
678
719
|
|
679
720
|
def initialize_plugin_configuration_definitions(self, plugin_type, name, defs):
|
ansible/constants.py
CHANGED
@@ -60,7 +60,7 @@ COLOR_CODES = {
|
|
60
60
|
'magenta': u'0;35', 'bright magenta': u'1;35',
|
61
61
|
'normal': u'0',
|
62
62
|
}
|
63
|
-
REJECT_EXTS =
|
63
|
+
REJECT_EXTS = ['.pyc', '.pyo', '.swp', '.bak', '~', '.rpm', '.md', '.txt', '.rst'] # this is concatenated with other config settings as lists; cannot be tuple
|
64
64
|
BOOL_TRUE = BOOLEANS_TRUE
|
65
65
|
COLLECTION_PTYPE_COMPAT = {'module': 'modules'}
|
66
66
|
|
ansible/inventory/manager.py
CHANGED
@@ -313,6 +313,7 @@ class InventoryManager(object):
|
|
313
313
|
ex.obj = origin
|
314
314
|
failures.append({'src': source, 'plugin': plugin_name, 'exc': ex})
|
315
315
|
except Exception as ex:
|
316
|
+
# DTFIX-RELEASE: fix this error handling to correctly deal with messaging
|
316
317
|
try:
|
317
318
|
# omit line number to prevent contextual display of script or possibly sensitive info
|
318
319
|
raise AnsibleError(str(ex), obj=origin) from ex
|
@@ -151,7 +151,7 @@ class LinuxVirtual(Virtual):
|
|
151
151
|
sys_vendor = get_file_content('/sys/devices/virtual/dmi/id/sys_vendor')
|
152
152
|
product_family = get_file_content('/sys/devices/virtual/dmi/id/product_family')
|
153
153
|
|
154
|
-
if product_name in ('KVM', 'KVM Server', 'Bochs', 'AHV'):
|
154
|
+
if product_name in ('KVM', 'KVM Server', 'Bochs', 'AHV', 'CloudStack KVM Hypervisor'):
|
155
155
|
guest_tech.add('kvm')
|
156
156
|
if not found_virt:
|
157
157
|
virtual_facts['virtualization_type'] = 'kvm'
|
@@ -3,6 +3,8 @@
|
|
3
3
|
|
4
4
|
from __future__ import annotations
|
5
5
|
|
6
|
+
import collections.abc as c
|
7
|
+
|
6
8
|
from ansible.module_utils.six import binary_type, text_type
|
7
9
|
from ansible.module_utils.common.text.converters import to_text
|
8
10
|
|
@@ -17,9 +19,13 @@ def boolean(value, strict=True):
|
|
17
19
|
return value
|
18
20
|
|
19
21
|
normalized_value = value
|
22
|
+
|
20
23
|
if isinstance(value, (text_type, binary_type)):
|
21
24
|
normalized_value = to_text(value, errors='surrogate_or_strict').lower().strip()
|
22
25
|
|
26
|
+
if not isinstance(value, c.Hashable):
|
27
|
+
normalized_value = None # prevent unhashable types from bombing, but keep the rest of the existing fallback/error behavior
|
28
|
+
|
23
29
|
if normalized_value in BOOLEANS_TRUE:
|
24
30
|
return True
|
25
31
|
elif normalized_value in BOOLEANS_FALSE or not strict:
|
ansible/modules/assemble.py
CHANGED
@@ -181,7 +181,7 @@ def assemble_from_fragments(src_path, delimiter=None, compiled_regexp=None, igno
|
|
181
181
|
return temp_path
|
182
182
|
|
183
183
|
|
184
|
-
def cleanup(path, result=None):
|
184
|
+
def cleanup(module, path, result=None):
|
185
185
|
# cleanup just in case
|
186
186
|
if os.path.exists(path):
|
187
187
|
try:
|
@@ -189,7 +189,7 @@ def cleanup(path, result=None):
|
|
189
189
|
except (IOError, OSError) as e:
|
190
190
|
# don't error on possible race conditions, but keep warning
|
191
191
|
if result is not None:
|
192
|
-
|
192
|
+
module.warn('Unable to remove temp file (%s): %s' % (path, to_native(e)))
|
193
193
|
|
194
194
|
|
195
195
|
def main():
|
@@ -261,7 +261,7 @@ def main():
|
|
261
261
|
(rc, out, err) = module.run_command(validate % path)
|
262
262
|
result['validation'] = dict(rc=rc, stdout=out, stderr=err)
|
263
263
|
if rc != 0:
|
264
|
-
cleanup(path)
|
264
|
+
cleanup(module, path)
|
265
265
|
module.fail_json(msg="failed to validate: rc:%s error:%s" % (rc, err))
|
266
266
|
if backup and dest_hash is not None:
|
267
267
|
result['backup_file'] = module.backup_local(dest)
|
@@ -269,7 +269,7 @@ def main():
|
|
269
269
|
module.atomic_move(path, dest, unsafe_writes=module.params['unsafe_writes'])
|
270
270
|
changed = True
|
271
271
|
|
272
|
-
cleanup(path, result)
|
272
|
+
cleanup(module, path, result)
|
273
273
|
|
274
274
|
# handle file permissions
|
275
275
|
file_args = module.load_file_common_arguments(module.params)
|
ansible/modules/cron.py
CHANGED
@@ -618,7 +618,6 @@ def main():
|
|
618
618
|
|
619
619
|
changed = False
|
620
620
|
res_args = dict()
|
621
|
-
warnings = list()
|
622
621
|
|
623
622
|
if cron_file:
|
624
623
|
|
@@ -627,8 +626,8 @@ def main():
|
|
627
626
|
|
628
627
|
cron_file_basename = os.path.basename(cron_file)
|
629
628
|
if not re.search(r'^[A-Z0-9_-]+$', cron_file_basename, re.I):
|
630
|
-
|
631
|
-
|
629
|
+
module.warn('Filename portion of cron_file ("%s") should consist' % cron_file_basename +
|
630
|
+
' solely of upper- and lower-case letters, digits, underscores, and hyphens')
|
632
631
|
|
633
632
|
# Ensure all files generated are only writable by the owning user. Primarily relevant for the cron_file option.
|
634
633
|
os.umask(int('022', 8))
|
@@ -693,7 +692,7 @@ def main():
|
|
693
692
|
if do_install:
|
694
693
|
for char in ['\r', '\n']:
|
695
694
|
if char in job.strip('\r\n'):
|
696
|
-
|
695
|
+
module.warn('Job should not contain line breaks')
|
697
696
|
break
|
698
697
|
|
699
698
|
job = crontab.get_cron_job(minute, hour, day, month, weekday, job, special_time, disabled)
|
@@ -734,7 +733,6 @@ def main():
|
|
734
733
|
res_args = dict(
|
735
734
|
jobs=crontab.get_jobnames(),
|
736
735
|
envs=crontab.get_envnames(),
|
737
|
-
warnings=warnings,
|
738
736
|
changed=changed
|
739
737
|
)
|
740
738
|
|
ansible/modules/dnf5.py
CHANGED
@@ -722,6 +722,7 @@ class Dnf5Module(YumDnf):
|
|
722
722
|
if self.security:
|
723
723
|
types.append("security")
|
724
724
|
advisory_query.filter_type(types)
|
725
|
+
conf.skip_unavailable = True # ignore packages that are of a different type, for backwards compat
|
725
726
|
settings.set_advisory_filter(advisory_query)
|
726
727
|
|
727
728
|
goal = libdnf5.base.Goal(base)
|
ansible/modules/git.py
CHANGED
@@ -317,11 +317,6 @@ remote_url_changed:
|
|
317
317
|
returned: success
|
318
318
|
type: bool
|
319
319
|
sample: True
|
320
|
-
warnings:
|
321
|
-
description: List of warnings if requested features were not available due to a too old git version.
|
322
|
-
returned: error
|
323
|
-
type: str
|
324
|
-
sample: git version is too old to fully support the depth argument. Falling back to full checkouts.
|
325
320
|
git_dir_now:
|
326
321
|
description: Contains the new path of .git directory if it is changed.
|
327
322
|
returned: success
|
@@ -1240,7 +1235,7 @@ def main():
|
|
1240
1235
|
archive_prefix = module.params['archive_prefix']
|
1241
1236
|
separate_git_dir = module.params['separate_git_dir']
|
1242
1237
|
|
1243
|
-
result = dict(changed=False
|
1238
|
+
result = dict(changed=False)
|
1244
1239
|
|
1245
1240
|
if module.params['accept_hostkey']:
|
1246
1241
|
if ssh_opts is not None:
|
ansible/modules/pip.py
CHANGED
@@ -814,10 +814,8 @@ def main():
|
|
814
814
|
elif requirements:
|
815
815
|
cmd.extend(['-r', requirements])
|
816
816
|
else:
|
817
|
-
module.
|
818
|
-
|
819
|
-
warnings=["No valid name or requirements file found."],
|
820
|
-
)
|
817
|
+
module.warn("No valid name or requirements file found.")
|
818
|
+
module.exit_json(changed=False)
|
821
819
|
|
822
820
|
if module.check_mode:
|
823
821
|
if extra_args or requirements or state == 'latest' or not name:
|
ansible/modules/sysvinit.py
CHANGED
@@ -88,9 +88,9 @@ EXAMPLES = """
|
|
88
88
|
|
89
89
|
- name: Sleep for 5 seconds between stop and start command of badly behaving service
|
90
90
|
ansible.builtin.sysvinit:
|
91
|
-
|
92
|
-
|
93
|
-
|
91
|
+
name: apache2
|
92
|
+
state: restarted
|
93
|
+
sleep: 5
|
94
94
|
|
95
95
|
- name: Make sure apache2 is started on runlevels 3 and 5
|
96
96
|
ansible.builtin.sysvinit:
|
@@ -1002,7 +1002,7 @@ class ActionBase(ABC, _AnsiblePluginInfoMixin):
|
|
1002
1002
|
# tells the module to ignore options that are not in its argspec.
|
1003
1003
|
module_args['_ansible_ignore_unknown_opts'] = ignore_unknown_opts
|
1004
1004
|
|
1005
|
-
# allow user to insert string to add context to remote
|
1005
|
+
# allow user to insert string to add context to remote logging
|
1006
1006
|
module_args['_ansible_target_log_info'] = C.config.get_config_value('TARGET_LOG_INFO', variables=task_vars)
|
1007
1007
|
|
1008
1008
|
module_args['_ansible_tracebacks_for'] = _traceback.traceback_for()
|
@@ -132,6 +132,9 @@ class ActionModule(ActionBase):
|
|
132
132
|
data_templar = self._templar.copy_with_new_env(searchpath=searchpath, available_variables=temp_vars)
|
133
133
|
resultant = data_templar.template(template_data, escape_backslashes=False, overrides=overrides)
|
134
134
|
|
135
|
+
if resultant is None:
|
136
|
+
resultant = ''
|
137
|
+
|
135
138
|
new_task = self._task.copy()
|
136
139
|
# mode is either the mode from task.args or the mode of the source file if the task.args
|
137
140
|
# mode == 'preserve'
|
ansible/plugins/loader.py
CHANGED
@@ -505,7 +505,8 @@ class PluginLoader:
|
|
505
505
|
|
506
506
|
# if type name != 'module_doc_fragment':
|
507
507
|
if type_name in C.CONFIGURABLE_PLUGINS and not C.config.has_configuration_definition(type_name, name):
|
508
|
-
|
508
|
+
# trust-tagged source propagates to loaded values; expressions and templates in config require trust
|
509
|
+
documentation_source = _tags.TrustedAsTemplate().tag(getattr(module, 'DOCUMENTATION', ''))
|
509
510
|
try:
|
510
511
|
dstring = yaml.load(_tags.Origin(path=path).tag(documentation_source), Loader=AnsibleLoader)
|
511
512
|
except ParserError as e:
|
@@ -673,7 +674,7 @@ class PluginLoader:
|
|
673
674
|
# look for any matching extension in the package location (sans filter)
|
674
675
|
found_files = [f
|
675
676
|
for f in glob.iglob(os.path.join(pkg_path, n_resource) + '.*')
|
676
|
-
if os.path.isfile(f) and not f.endswith(C.MODULE_IGNORE_EXTS)]
|
677
|
+
if os.path.isfile(f) and not any(f.endswith(ext) for ext in C.MODULE_IGNORE_EXTS)]
|
677
678
|
|
678
679
|
if not found_files:
|
679
680
|
return plugin_load_context.nope('failed fuzzy extension match for {0} in {1}'.format(full_name, acr.collection))
|
ansible/release.py
CHANGED
@@ -13,6 +13,8 @@ import typing as t
|
|
13
13
|
class _EncryptedStringProtocol(t.Protocol):
|
14
14
|
"""Protocol representing an `EncryptedString`, since it cannot be imported here."""
|
15
15
|
|
16
|
+
# DTFIX-FUTURE: collapse this with the one in config, once we can
|
17
|
+
|
16
18
|
def _decrypt(self) -> str: ...
|
17
19
|
|
18
20
|
|
ansible/utils/display.py
CHANGED
@@ -1285,6 +1285,10 @@ def format_message(summary: SummaryBase) -> str:
|
|
1285
1285
|
|
1286
1286
|
def _report_config_warnings(deprecator: PluginInfo) -> None:
|
1287
1287
|
"""Called by config to report warnings/deprecations collected during a config parse."""
|
1288
|
+
while config._errors:
|
1289
|
+
msg, exception = config._errors.pop()
|
1290
|
+
_display.error_as_warning(msg=msg, exception=exception)
|
1291
|
+
|
1288
1292
|
while config.WARNINGS:
|
1289
1293
|
warn = config.WARNINGS.pop()
|
1290
1294
|
_display.warning(warn)
|
ansible/utils/plugin_docs.py
CHANGED
@@ -154,7 +154,8 @@ def add_fragments(doc, filename, fragment_loader, is_module=False):
|
|
154
154
|
unknown_fragments.append(fragment_slug)
|
155
155
|
continue
|
156
156
|
|
157
|
-
|
157
|
+
# trust-tagged source propagates to loaded values; expressions and templates in config require trust
|
158
|
+
fragment_yaml = _tags.TrustedAsTemplate().tag(getattr(fragment_class, fragment_var, None))
|
158
159
|
if fragment_yaml is None:
|
159
160
|
if fragment_var != 'DOCUMENTATION':
|
160
161
|
# if it's asking for something specific that's missing, that's an error
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: ansible-core
|
3
|
-
Version: 2.19.
|
3
|
+
Version: 2.19.0b4
|
4
4
|
Summary: Radically simple IT automation
|
5
5
|
Author: Ansible Project
|
6
6
|
Project-URL: Homepage, https://ansible.com/
|
@@ -38,6 +38,7 @@ Requires-Dist: PyYAML>=5.1
|
|
38
38
|
Requires-Dist: cryptography
|
39
39
|
Requires-Dist: packaging
|
40
40
|
Requires-Dist: resolvelib<2.0.0,>=0.5.3
|
41
|
+
Dynamic: license-file
|
41
42
|
|
42
43
|
[](https://pypi.org/project/ansible-core)
|
43
44
|
[](https://docs.ansible.com/ansible/latest/)
|
@@ -1,14 +1,15 @@
|
|
1
1
|
ansible/__init__.py,sha256=lcN6K0RviF9nJ6bUtvmwp26GEEy7CzyYivFJ6JIsziA,1215
|
2
2
|
ansible/__main__.py,sha256=24j-7-YT4lZ2fmV80JD-VRoYBnxR7YoP_VP-orJtDt0,796
|
3
|
-
ansible/constants.py,sha256=
|
3
|
+
ansible/constants.py,sha256=qef45QpHi-yFFMvllvNKmqFpXdKKr304e5fEZnjgwZc,7989
|
4
4
|
ansible/context.py,sha256=oKYyfjfWpy8vDeProtqfnqSmuij_t75_5e5t0U_hQ1g,1933
|
5
5
|
ansible/keyword_desc.yml,sha256=5rGCsr-0B8w2D67qBD6q_2WFxfqj9ieb0V_2J-dZJ5E,7547
|
6
|
-
ansible/release.py,sha256=
|
7
|
-
ansible/_internal/__init__.py,sha256=
|
6
|
+
ansible/release.py,sha256=IXr3OR35RyOVLr9l3eiSI-Lq37a-X2gZPSBHSI-O6r8,854
|
7
|
+
ansible/_internal/__init__.py,sha256=D-vFgPGHLjzG97IvyIoyhJu5Hycp6R8LWbm5_9XYfSc,2209
|
8
8
|
ansible/_internal/_ansiballz.py,sha256=OL2FCN0jOjg1a8diutsNcs_mr0dqO7SgJPmrYCKfo1Y,11649
|
9
9
|
ansible/_internal/_collection_proxy.py,sha256=F7sde4HIxwZVszF1bYkbcNvNsy233rAEjn2OV5ENx90,1235
|
10
10
|
ansible/_internal/_locking.py,sha256=8jMXsKSNCKVZRUesZWb5Hx45g9UVVZ9JXUa_fq2004Q,669
|
11
11
|
ansible/_internal/_task.py,sha256=NCEF3sPxt99n4Gk-e00A9Ce52duffThJm0qlmgkm0nQ,3293
|
12
|
+
ansible/_internal/_testing.py,sha256=WCEwZk8_NP2f2LoY2zjh6VIw6d8bPoFspvfP3-KQMjQ,825
|
12
13
|
ansible/_internal/_wrapt.py,sha256=CLgu2S5V4NmJ9pPFIKarhqiiwAQxni5ISgr-TxARWuE,37963
|
13
14
|
ansible/_internal/_datatag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
14
15
|
ansible/_internal/_datatag/_tags.py,sha256=8ZLQUX2ggTQluwtLfFbNKa9rKNpxRhqalRzeqSUda2Y,5180
|
@@ -18,7 +19,7 @@ ansible/_internal/_errors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
|
|
18
19
|
ansible/_internal/_errors/_captured.py,sha256=UXIzFiUMZVAGYlrc2dBJDmRYYDLgj6zOOSaLth7Br5Q,4919
|
19
20
|
ansible/_internal/_errors/_handler.py,sha256=4ZX27G_jrDsomR28OVC0A9WRponpte5V-QGq5ZcDzeE,3455
|
20
21
|
ansible/_internal/_errors/_utils.py,sha256=LKS9CRb8OobJTlLjs0poHiVqmzIdLB7BIW3m3fzLFbQ,11942
|
21
|
-
ansible/_internal/_json/__init__.py,sha256=
|
22
|
+
ansible/_internal/_json/__init__.py,sha256=nYxJrXf9eqa0-ECe6cdEJBgNF9TUX3YJKsazFbtn17s,8825
|
22
23
|
ansible/_internal/_json/_legacy_encoder.py,sha256=clXiPnJ2aR5McuSbajugTPW2wav1wwklivxDKWZ1iFw,1646
|
23
24
|
ansible/_internal/_json/_profiles/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
24
25
|
ansible/_internal/_json/_profiles/_cache_persistence.py,sha256=PGtAPvMQdC6yHJcHz3HYkkmRMH8SkE4nOjhIg3SMdRA,1817
|
@@ -75,7 +76,7 @@ ansible/cli/playbook.py,sha256=yPOYqwH5qcI6uCVI2k4GrSB0thWQLjlauJOD-sFx11I,10546
|
|
75
76
|
ansible/cli/pull.py,sha256=Bvc59o9KbLRlcKTCb_pzr-vcs2owDuThpQJlK05xYM8,18425
|
76
77
|
ansible/cli/vault.py,sha256=bG_8LZ697ohjjJqb7aDryQmc9ahQggiZA2IPmgyTDnA,23195
|
77
78
|
ansible/cli/arguments/__init__.py,sha256=_4taT82hZKKTzhdXKmIgqxWwuG21XZxF874V2k1e3us,168
|
78
|
-
ansible/cli/arguments/option_helpers.py,sha256=
|
79
|
+
ansible/cli/arguments/option_helpers.py,sha256=7fJuJ0dq_nC6M1BoOicu92lNhbRwD2379JOniqEbDc0,24445
|
79
80
|
ansible/cli/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
80
81
|
ansible/cli/scripts/ansible_connection_cli_stub.py,sha256=Wz413NyoBudEJdQt6pw2UAB4IveHQma4XoHBzFSENt0,13122
|
81
82
|
ansible/collections/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -84,8 +85,8 @@ ansible/compat/__init__.py,sha256=CvyoCuJ9EdeWO3_nj5fBSQ495YP0tCbXhQ6cramBdGY,10
|
|
84
85
|
ansible/compat/importlib_resources.py,sha256=oCjsu8foADOkMNwRuWiRCjQxO8zEOc-Olc2bKo-Kgh0,572
|
85
86
|
ansible/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
86
87
|
ansible/config/ansible_builtin_runtime.yml,sha256=nwL_-rqEEmpuSHxZH70pJBiEosDKOPkYIboH3_7LVEY,376076
|
87
|
-
ansible/config/base.yml,sha256=
|
88
|
-
ansible/config/manager.py,sha256=
|
88
|
+
ansible/config/base.yml,sha256=Vy4Y6wDVN-7lnVzvTi2pWbQFZrCn9nkiGejXt5DWGWA,88674
|
89
|
+
ansible/config/manager.py,sha256=CC-JhhK4KN07rvXAfiex4sxjFSVtxsLx6E_YnpEOE88,31123
|
89
90
|
ansible/errors/__init__.py,sha256=7nJsA0zFSesC3xVN_qf4-47VQmZ4eWi6R9zTEBW7gUY,16111
|
90
91
|
ansible/executor/__init__.py,sha256=mRvbCJPA-_veSG5ka3v04G5vsarLVDeB3EWFsu6geSI,749
|
91
92
|
ansible/executor/interpreter_discovery.py,sha256=UWeAxnHknJCci2gG3zt6edx5Nj4WbHYfJVcmW_DzItY,3858
|
@@ -195,10 +196,10 @@ ansible/inventory/data.py,sha256=Hy4-36CWcKEWvTm55fLw888hjmYvmGcQN0myIZRex5A,104
|
|
195
196
|
ansible/inventory/group.py,sha256=_4q692djOZmJjk2x2UQuS03lSst8zCucJnq9kVZ2uks,9351
|
196
197
|
ansible/inventory/helpers.py,sha256=8DaVEdMhIfan6Fy65AoHO3rILtl3mDzxei4_j8r4fp4,1556
|
197
198
|
ansible/inventory/host.py,sha256=Zzod7oWrsrCfv4v8oOu40ASEsrlk3IIZH4WtGs8rbU4,4654
|
198
|
-
ansible/inventory/manager.py,sha256=
|
199
|
+
ansible/inventory/manager.py,sha256=bZppxa0x0aLvs801zhn1f0fNQhPszKFcvbAjWZmMjes,31812
|
199
200
|
ansible/module_utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
200
201
|
ansible/module_utils/_text.py,sha256=VkWgAnSNVCbTQqZgllUObBFsH3uM4EUW5srl1UR9t1g,544
|
201
|
-
ansible/module_utils/ansible_release.py,sha256=
|
202
|
+
ansible/module_utils/ansible_release.py,sha256=IXr3OR35RyOVLr9l3eiSI-Lq37a-X2gZPSBHSI-O6r8,854
|
202
203
|
ansible/module_utils/api.py,sha256=8BmCzQtp9rClsLGlDn4I9iJrUFLCdnoEIxYX59_IL9c,5756
|
203
204
|
ansible/module_utils/basic.py,sha256=e92CZBmokHTcQG-gcmxHZ8efweBMDalcoTAg9rJ-J9M,89711
|
204
205
|
ansible/module_utils/connection.py,sha256=EYcZ-JJ3GnCb8Hhdan2upLJfgfQGvzpPUHNY_qVXyKw,7675
|
@@ -343,13 +344,13 @@ ansible/module_utils/facts/virtual/base.py,sha256=BijfSGBeCSdDzK2jeeQ2oymgupItCv
|
|
343
344
|
ansible/module_utils/facts/virtual/dragonfly.py,sha256=fx8MZjy6FqfSpshxnPyGs5B4FezmYFqqTr1XibWWSeE,959
|
344
345
|
ansible/module_utils/facts/virtual/freebsd.py,sha256=Wc3hjsxrjWnLaZFBX3zM4lZpeGy4ZS5BTOXTs9SRN-I,3018
|
345
346
|
ansible/module_utils/facts/virtual/hpux.py,sha256=NLQfUpXE7Gh-eZFfLyugvnnJjWFIGv9xqjC_zV4DLKw,2823
|
346
|
-
ansible/module_utils/facts/virtual/linux.py,sha256=
|
347
|
+
ansible/module_utils/facts/virtual/linux.py,sha256=UOtZzsbO6ENkj7-0X1SHOZ8DpyQB8RcZJh3mj4dxBHU,17851
|
347
348
|
ansible/module_utils/facts/virtual/netbsd.py,sha256=53n3E9vowi8kCbFyj7vDeKocZ3OU_TLVSKRJRU8SenE,2896
|
348
349
|
ansible/module_utils/facts/virtual/openbsd.py,sha256=J8Ow7x3J5ZuHFThqAwIdAdTLV1V9vN_U965Q34TAvNA,2785
|
349
350
|
ansible/module_utils/facts/virtual/sunos.py,sha256=9wUiq-2oXlrZbaskVI9c8WmG206AH2j5KO3F5jKo3Ec,5700
|
350
351
|
ansible/module_utils/facts/virtual/sysctl.py,sha256=suvfSdKL5e_AAPCxE_EQRiqNHzpMJYSucT4URyn8Qxw,4741
|
351
352
|
ansible/module_utils/parsing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
352
|
-
ansible/module_utils/parsing/convert_bool.py,sha256=
|
353
|
+
ansible/module_utils/parsing/convert_bool.py,sha256=WN-LzXRsO96kNig3cngTu_3sjM2xxnoSXAqUfynhGQM,1265
|
353
354
|
ansible/module_utils/powershell/Ansible.ModuleUtils.AddType.psm1,sha256=NYfvSKqsTCC2YQIx-pGPpKKS3BG499v8ZqQHlHiXsOQ,20127
|
354
355
|
ansible/module_utils/powershell/Ansible.ModuleUtils.ArgvParser.psm1,sha256=x9wTV5jOpoCtFbpZW6GoZEELdL3RNOhdY91QOhYxJqk,3327
|
355
356
|
ansible/module_utils/powershell/Ansible.ModuleUtils.Backup.psm1,sha256=ebgpraCNmPwswlLHShgiviTk2thw8ch3ekF5n_I_cXg,1104
|
@@ -368,19 +369,19 @@ ansible/modules/add_host.py,sha256=VZ3gc-phY5myzGijo6AIB1omD9ykfWpoqRvzleZp3DU,3
|
|
368
369
|
ansible/modules/apt.py,sha256=eMoHgh-4SWWu6d3VmxybzP-ACTi0sKaJOkMIqrh1Sjo,62708
|
369
370
|
ansible/modules/apt_key.py,sha256=DmmNkVdRrhOCEhItsbXUA3TuAfXZW4A0CGZu4JeqL90,18485
|
370
371
|
ansible/modules/apt_repository.py,sha256=AzJnzlImqU_ZWZVBMi9xAklzfMqqTOuuOH1Jp5m16pY,31529
|
371
|
-
ansible/modules/assemble.py,sha256=
|
372
|
+
ansible/modules/assemble.py,sha256=4_Cy7mS-4Yhpz0pnj6sVes39DTlgzBLlfTKEsHCQ9D8,9271
|
372
373
|
ansible/modules/assert.py,sha256=B41GXAdBQ6XbYj9G8ENx29fhAlcnyBXm8zDqbd1TnMU,2954
|
373
374
|
ansible/modules/async_status.py,sha256=7qs2cyVvoFDLDWhVYzjsfdLPj89EKKjSDw5vZ1WbPH4,4589
|
374
375
|
ansible/modules/async_wrapper.py,sha256=3nwRroF8BImwYQVd9Yb0jldm_c6hdLpOsou53xiHaew,12011
|
375
376
|
ansible/modules/blockinfile.py,sha256=CkzCw73Kbkvgb763C1x_qUMkf6UdJJsyZC_Kiy85Unw,15450
|
376
377
|
ansible/modules/command.py,sha256=v7KAW_uI4zhBwaKBDZaHNSk3coZlyXoG9xGtDOM4MaY,14037
|
377
378
|
ansible/modules/copy.py,sha256=uLltSKg-0poPjtV9WKhq0w4Z_6wOKm8mNR8How-DHXw,26725
|
378
|
-
ansible/modules/cron.py,sha256=
|
379
|
+
ansible/modules/cron.py,sha256=trFmqi8l8jADTDyNZn1COe_-GpCi9aNQj8wUCn5O7SA,26709
|
379
380
|
ansible/modules/deb822_repository.py,sha256=kHBZlGGQ_fA3dMxx_NzjC-L2ZuhkEwTTfLS6ZC6qph4,15760
|
380
381
|
ansible/modules/debconf.py,sha256=YAS1yba0yaxPrfFCLFLQwtHxlpriNxiJiwpDnmm3JP0,9362
|
381
382
|
ansible/modules/debug.py,sha256=E2UADFGHgS78KxCiOdXoojX5G4pAAMz32VGHgaPObNs,2908
|
382
383
|
ansible/modules/dnf.py,sha256=BStesAQE40-hZRMwV8IZW5j3yIv1wd1XGXsXjW1jKfw,52289
|
383
|
-
ansible/modules/dnf5.py,sha256=
|
384
|
+
ansible/modules/dnf5.py,sha256=cMAgXt84CwnI4ujiF0gIAcQ3DXtprhLaetOyMr_z3MQ,31943
|
384
385
|
ansible/modules/dpkg_selections.py,sha256=RWtzxNNOfQ5SdwMwnt_1q-IJhLVb-nxNAriJwRHNVuI,2805
|
385
386
|
ansible/modules/expect.py,sha256=yBisXCvL8OY5c_9AibH8xY3elmKebCwoHZAJj-MFPU0,9279
|
386
387
|
ansible/modules/fail.py,sha256=kppam_caBllcF5IcKEYd-Xc--okSAOWNG9dVbpn2CwM,1659
|
@@ -390,7 +391,7 @@ ansible/modules/find.py,sha256=Ia2QUTCHzc58MiLUOFTkYa_NHgM3rGsuNDtrWVwzvrE,24051
|
|
390
391
|
ansible/modules/gather_facts.py,sha256=3t2_XMgKuB-U35tnO-JbGEsQ_E31SnZxRQ-B_DVkIu4,3107
|
391
392
|
ansible/modules/get_url.py,sha256=1JW5sLkkWbmXmh4rxNX05XHwn0QkcM10dnqqQ_PXMp8,27372
|
392
393
|
ansible/modules/getent.py,sha256=tq3z0Szq_m2gp4DOgACRvNJzh-tkXGzd2Ew8XxrGRWM,5592
|
393
|
-
ansible/modules/git.py,sha256=
|
394
|
+
ansible/modules/git.py,sha256=BtZWA4furfNfPefusAD-ihBROKHdRcBucpvpLJttxJU,57126
|
394
395
|
ansible/modules/group.py,sha256=UKbXzwsgAFWWMlgFW8R3CyzthJXXu5JHnHnj7IlqOac,23747
|
395
396
|
ansible/modules/group_by.py,sha256=_RDYbNJS27eosefvwnBCM86GyobaY-h3ZiWkd04qU68,2416
|
396
397
|
ansible/modules/hostname.py,sha256=oklIQ8jwpnRZ2IAxY5igFg1hQFSHisNjXp-6sCQzmko,28181
|
@@ -409,7 +410,7 @@ ansible/modules/package.py,sha256=ce2O1o3tzPRTyYYvYNw16OLed8ke8f5AAXMGF1vi8XU,37
|
|
409
410
|
ansible/modules/package_facts.py,sha256=Tvq3ULR8oyIx-lCJzY-wwWlL2gGiwLq9jS5H8Hjmick,17284
|
410
411
|
ansible/modules/pause.py,sha256=VzN_Ay94TYvBPTQRG0s0YTnXJkMTh8CEy2KostS2nVY,3796
|
411
412
|
ansible/modules/ping.py,sha256=80pw8eLBvT2pw8f0V3zxqExQhbsKKoA6YfPBvcncTng,2325
|
412
|
-
ansible/modules/pip.py,sha256=
|
413
|
+
ansible/modules/pip.py,sha256=GEtBIzOqZCtQbKwfWfZ-xHzDxtiXdCBe7kH7l-5ghBY,32726
|
413
414
|
ansible/modules/raw.py,sha256=hPToqCii1ZolXVSaPmu-tCouEO1PoDIYjBtevoUvqIE,3741
|
414
415
|
ansible/modules/reboot.py,sha256=P5mbaDi_k-ISjR5M0adW6yeyssahw4QvXYqSN7elypk,4808
|
415
416
|
ansible/modules/replace.py,sha256=jAnGfWD38_zo8gC-rM3LkPwch54w9j044Bpr8mjpP2Q,11683
|
@@ -426,7 +427,7 @@ ansible/modules/stat.py,sha256=cD2l6TQjwrJhIY-SCgS9W_i6WC6FreSDSudFHmH63R8,18658
|
|
426
427
|
ansible/modules/subversion.py,sha256=XEhsibJHb5rg_yioveP_c-THxbh0ZMm0d8qApk02MZg,13485
|
427
428
|
ansible/modules/systemd.py,sha256=ZJ8uKx7xsvTQvmBTl5AyyP4KOBNZcjy5rr0CVH4lw2s,24990
|
428
429
|
ansible/modules/systemd_service.py,sha256=ZJ8uKx7xsvTQvmBTl5AyyP4KOBNZcjy5rr0CVH4lw2s,24990
|
429
|
-
ansible/modules/sysvinit.py,sha256=
|
430
|
+
ansible/modules/sysvinit.py,sha256=Nrs5gLyHKZsqtm_ymFO0e0wB2KSDXYfbDt-uNlgUiF0,13962
|
430
431
|
ansible/modules/tempfile.py,sha256=3ZljXNOu06T5ObTAz5Ktm_WKFrJACHwLf-01F7isf5A,3570
|
431
432
|
ansible/modules/template.py,sha256=y1zu-ZZ0P-Cpxjddzk5V5GVpQNNfQL8E5sVeAb2plR0,4537
|
432
433
|
ansible/modules/unarchive.py,sha256=ESs24Ceb9CC1rwF06qtOfg4xZdDLmiDbmNyUjVMLefE,45943
|
@@ -479,8 +480,8 @@ ansible/playbook/role/metadata.py,sha256=h439HGUucs2gOMUJlp2M0OO0_wnWWlQmTs_sOe8
|
|
479
480
|
ansible/playbook/role/requirement.py,sha256=CNgLa0J6zZk2YQ_aeALnjQvehkkFXhrK8LQQZs7Ztzc,4173
|
480
481
|
ansible/plugins/__init__.py,sha256=h2YINajRVBLM4G5BYnGCgycC0QCF9qys_Ssb6AAM93c,8456
|
481
482
|
ansible/plugins/list.py,sha256=5lQD2AHH4ysJzPBbgYE3ASJvSZOgKppGlgPrQkmGmv8,8895
|
482
|
-
ansible/plugins/loader.py,sha256=
|
483
|
-
ansible/plugins/action/__init__.py,sha256=
|
483
|
+
ansible/plugins/loader.py,sha256=eUiuCsF3Imwl9105VzxcjCeLHHmtfW2eOBQJPVDleTs,81912
|
484
|
+
ansible/plugins/action/__init__.py,sha256=rsCmbq3w1CtXvw0GsiCArK3ab4tJB7_KLoqPkCZF40k,70111
|
484
485
|
ansible/plugins/action/add_host.py,sha256=pz8R7qzCwwinxTx4hEZ3FMsVJpMV3NEfQvn2wqLGLLY,3579
|
485
486
|
ansible/plugins/action/assemble.py,sha256=ePMLNuh7Ie2fp-An9G5yieg9mETqAi0RL5aNK3W47OM,6529
|
486
487
|
ansible/plugins/action/assert.py,sha256=k1kLWyaXNE-XTVWBX1eIHaSZpGg8O8WeJfa62vqzcLM,4007
|
@@ -504,7 +505,7 @@ ansible/plugins/action/service.py,sha256=7wupKrBwIRnxQZXPHuOiEJaf1KtkgVmfn0ntM5f
|
|
504
505
|
ansible/plugins/action/set_fact.py,sha256=G1Q0HcTaXFIykNvjSG65tFkif0dMuvMvt3T44OlrB6Y,2186
|
505
506
|
ansible/plugins/action/set_stats.py,sha256=wRmlGzp5TAaLrPlz2O6kL6F_uSGYBaxtnF4jWmB3qeY,2476
|
506
507
|
ansible/plugins/action/shell.py,sha256=pd7Dm6gAZXWNAqANd7ETHSs90le7VXAxe7pB97T_zwU,1527
|
507
|
-
ansible/plugins/action/template.py,sha256=
|
508
|
+
ansible/plugins/action/template.py,sha256=yf1OJZN8f4TqmQ2HuFtEM8HFhuxBTR7nKJEak-mz4fQ,8472
|
508
509
|
ansible/plugins/action/unarchive.py,sha256=88h7YM6B9j_2XE5Sp-02o9oKYfnLliIlD5EbVXX3ndY,4859
|
509
510
|
ansible/plugins/action/uri.py,sha256=325UaEu7OY4yXnIj8c1Y0sB_7buzp3oQRoNDVJgwPg0,3981
|
510
511
|
ansible/plugins/action/validate_argument_spec.py,sha256=U-g8PugBg3QTTqkKQwtOS3NNou12yT4NQtXqJ10qBw8,3937
|
@@ -736,7 +737,7 @@ ansible/utils/_ssh_agent.py,sha256=2WlQqytGHoSkASLBscMfBOv69QAV0YNuBfKak4dh0nk,2
|
|
736
737
|
ansible/utils/cmd_functions.py,sha256=VmGs5ntdVaaqAJHcCTpGG3rYAAcTNl1b2-Iw4YVOt9Y,2180
|
737
738
|
ansible/utils/color.py,sha256=LjJO_12OsJiavBxwSDVXtLxdTzdwd2YWUp1OJ6KcM2g,4057
|
738
739
|
ansible/utils/context_objects.py,sha256=vYulSJkzR3zxsQF_6_AqbPCCMy8WGC5dSqLFXJZqGIo,3034
|
739
|
-
ansible/utils/display.py,sha256=
|
740
|
+
ansible/utils/display.py,sha256=ym8irMsZFDCFD63XJTviZHwnvrO3eX-pJcN_Gh3G8u4,48869
|
740
741
|
ansible/utils/encrypt.py,sha256=j7DcEPr_yHSLYfYEruybjCl7kFk4rKjjTebyGx_-ZbA,7590
|
741
742
|
ansible/utils/fqcn.py,sha256=_wPNWMkR0mqRdkr6fn9FRgEkaCQHw40yardWe97FfEc,1215
|
742
743
|
ansible/utils/galaxy.py,sha256=Un3XgXhx8FoC6tkp1cZ33rmiAaRg634exKruwOVhtdQ,3855
|
@@ -747,7 +748,7 @@ ansible/utils/listify.py,sha256=kDtcewq4gWi-waCfqgHy-eITDbvXA08Gx_qvgbYI62I,1275
|
|
747
748
|
ansible/utils/lock.py,sha256=aP6MfrvWHdO_V756hwFsJG1I9QaQyFJq9W0tf7pCN3I,1306
|
748
749
|
ansible/utils/multiprocessing.py,sha256=Xgs3kXqbzVujXah0-R_D6eUcQoiapbQ-0yclNpkAvs4,614
|
749
750
|
ansible/utils/path.py,sha256=RMuCOlqUyDjIlKTAqNhD2N7iuKkL4jnvXNWh9aMtQRw,6051
|
750
|
-
ansible/utils/plugin_docs.py,sha256=
|
751
|
+
ansible/utils/plugin_docs.py,sha256=A1Fy5qaZuOnrEm896AdHi3znJkVMFveu4C0MQujSBpE,15383
|
751
752
|
ansible/utils/py3compat.py,sha256=l5x0He1q4RRPwSummCN8wHhD8PxlivcgfthllyI_XCg,578
|
752
753
|
ansible/utils/sentinel.py,sha256=3TBjBlaOB6NfoXt5MFLCHVQLbPIFx03N_glcN3cYdjo,323
|
753
754
|
ansible/utils/shlex.py,sha256=eUCZ0VkxMSEoyXCDspS9E4cI8pQWn83OFCt7sbVLB6g,841
|
@@ -757,7 +758,7 @@ ansible/utils/unicode.py,sha256=__zbdElrMS9Rrqo9H7tF8zkjKFQCFU8kTtj5cVIITxM,1100
|
|
757
758
|
ansible/utils/unsafe_proxy.py,sha256=f_oJ0jCOh28Aa4Ps5QuhlBuPJCigVwpNKdfffw3xGC0,2114
|
758
759
|
ansible/utils/vars.py,sha256=RhZssst9c2fRWvlT6YgDW3v45mmea3x1KLucyzKUsE8,11443
|
759
760
|
ansible/utils/version.py,sha256=TKmSzm_MFZVJWpvmOnIEGZzRfeHLwWmeuHj16zGqb2c,7736
|
760
|
-
ansible/utils/collection_loader/__init__.py,sha256=
|
761
|
+
ansible/utils/collection_loader/__init__.py,sha256=lwLu1LJhWz3cRzFLfNWuFdS-Rhods6aReqOaqoVaDaM,2564
|
761
762
|
ansible/utils/collection_loader/_collection_config.py,sha256=6r5DY_4kKGQz4qk7u9vsrNq__UmGFlCjtAV-HwJsFaM,3000
|
762
763
|
ansible/utils/collection_loader/_collection_finder.py,sha256=3E71MX6FU2OmBeK5BpJrh7lQ4Fg6kuiRMA4WxuO3JqY,55125
|
763
764
|
ansible/utils/collection_loader/_collection_meta.py,sha256=p2eZArsO8RCl4PlN1x2I-7A7Q8HZpdFoeqfMNVaRgiU,1815
|
@@ -767,6 +768,12 @@ ansible/vars/hostvars.py,sha256=EaRFnZbPqAv8PDMF-aS_v6igoV3MNzix_VwuPviwNLI,4365
|
|
767
768
|
ansible/vars/manager.py,sha256=pCLAvO_J_IQPBPPnOb6JHhU5t2dTXUYpj3D3eMxmJKw,28041
|
768
769
|
ansible/vars/plugins.py,sha256=Qnk83j898hQ-oiJHaKsel177tkYLwm6cCoHed4GPoiA,4519
|
769
770
|
ansible/vars/reserved.py,sha256=r7qXzXJ5uZdkRYjmyf3uSxU6EHnOVLEiMMnwOM7Q46U,2771
|
771
|
+
ansible_core-2.19.0b4.dist-info/licenses/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
772
|
+
ansible_core-2.19.0b4.dist-info/licenses/licenses/Apache-License.txt,sha256=y16Ofl9KOYjhBjwULGDcLfdWBfTEZRXnduOspt-XbhQ,11325
|
773
|
+
ansible_core-2.19.0b4.dist-info/licenses/licenses/BSD-3-Clause.txt,sha256=la0N3fE3Se8vBiuvUcFKA8b-E41G7flTic6P8CkUroE,1548
|
774
|
+
ansible_core-2.19.0b4.dist-info/licenses/licenses/MIT-license.txt,sha256=jLXp2XurnyZKbye40g9tfmLGtVlxh3pPD4n8xNqX8xc,1023
|
775
|
+
ansible_core-2.19.0b4.dist-info/licenses/licenses/PSF-license.txt,sha256=g7BC_H1qyg8Q1o5F76Vrm8ChSWYI5-dyj-CdGlNKBUo,2484
|
776
|
+
ansible_core-2.19.0b4.dist-info/licenses/licenses/simplified_bsd.txt,sha256=8R5R7R7sOa0h1Fi6RNgFgHowHBfun-OVOMzJ4rKAk2w,1237
|
770
777
|
ansible_test/__init__.py,sha256=20VPOj11c6Ut1Av9RaurgwJvFhMqkWG3vAvcCbecNKw,66
|
771
778
|
ansible_test/_data/ansible.cfg,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
772
779
|
ansible_test/_data/coveragerc,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -1010,7 +1017,7 @@ ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg,sha256=DJyZi
|
|
1010
1017
|
ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg,sha256=sp-BrEpQVZebA1FVRtb1WVegyEr5O8zj_F_1NCVuRvc,1942
|
1011
1018
|
ansible_test/_util/controller/sanity/pylint/config/collection.cfg,sha256=h2qhEF9_RvP70katitXYVjePtJDzAsGJPeARQdhBFlE,4669
|
1012
1019
|
ansible_test/_util/controller/sanity/pylint/config/default.cfg,sha256=D33wbIVfOBjkvxgWAPfN48aMZY4jh57xupsBQh6C-kg,4243
|
1013
|
-
ansible_test/_util/controller/sanity/pylint/plugins/deprecated_calls.py,sha256=
|
1020
|
+
ansible_test/_util/controller/sanity/pylint/plugins/deprecated_calls.py,sha256=1vTbPAGaA3KAiJ60dKWGrakufqIgJ5o_vwFL-e0GsaU,19447
|
1014
1021
|
ansible_test/_util/controller/sanity/pylint/plugins/deprecated_comment.py,sha256=tmQf_-2VAT2GVfwa9X9ruBcaj0Sz6Ifx4cXmdzJ99SQ,5226
|
1015
1022
|
ansible_test/_util/controller/sanity/pylint/plugins/hide_unraisable.py,sha256=s0AIoK03uqZSTwXSLvd4oXvf4WJ0Ckol5ingitHoMr4,836
|
1016
1023
|
ansible_test/_util/controller/sanity/pylint/plugins/string_format.py,sha256=Mb1Mx8WS4RulsORFgyctlFRR0Sn-PYPy4mVu_GYCD18,2359
|
@@ -1061,14 +1068,8 @@ ansible_test/config/cloud-config-vultr.ini.template,sha256=XLKHk3lg_8ReQMdWfZzhh
|
|
1061
1068
|
ansible_test/config/config.yml,sha256=1zdGucnIl6nIecZA7ISIANvqXiHWqq6Dthsk_6MUwNc,2642
|
1062
1069
|
ansible_test/config/inventory.networking.template,sha256=bFNSk8zNQOaZ_twaflrY0XZ9mLwUbRLuNT0BdIFwvn4,1335
|
1063
1070
|
ansible_test/config/inventory.winrm.template,sha256=1QU8W-GFLnYEw8yY9bVIvUAVvJYPM3hyoijf6-M7T00,1098
|
1064
|
-
ansible_core-2.19.
|
1065
|
-
ansible_core-2.19.
|
1066
|
-
ansible_core-2.19.
|
1067
|
-
ansible_core-2.19.
|
1068
|
-
ansible_core-2.19.
|
1069
|
-
ansible_core-2.19.0b3.dist-info/PSF-license.txt,sha256=g7BC_H1qyg8Q1o5F76Vrm8ChSWYI5-dyj-CdGlNKBUo,2484
|
1070
|
-
ansible_core-2.19.0b3.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
|
1071
|
-
ansible_core-2.19.0b3.dist-info/entry_points.txt,sha256=S9yJij5Im6FgRQxzkqSCnPQokC7PcWrDW_NSygZczJU,451
|
1072
|
-
ansible_core-2.19.0b3.dist-info/simplified_bsd.txt,sha256=8R5R7R7sOa0h1Fi6RNgFgHowHBfun-OVOMzJ4rKAk2w,1237
|
1073
|
-
ansible_core-2.19.0b3.dist-info/top_level.txt,sha256=IFbRLjAvih1DYzJWg3_F6t4sCzEMxRO7TOMNs6GkYHo,21
|
1074
|
-
ansible_core-2.19.0b3.dist-info/RECORD,,
|
1071
|
+
ansible_core-2.19.0b4.dist-info/METADATA,sha256=R_UmHiGlICZrxQQEitbG7calWkGy_BADvyNT33vYv3c,7732
|
1072
|
+
ansible_core-2.19.0b4.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
|
1073
|
+
ansible_core-2.19.0b4.dist-info/entry_points.txt,sha256=S9yJij5Im6FgRQxzkqSCnPQokC7PcWrDW_NSygZczJU,451
|
1074
|
+
ansible_core-2.19.0b4.dist-info/top_level.txt,sha256=IFbRLjAvih1DYzJWg3_F6t4sCzEMxRO7TOMNs6GkYHo,21
|
1075
|
+
ansible_core-2.19.0b4.dist-info/RECORD,,
|
@@ -39,6 +39,10 @@ class DeprecationCallArgs:
|
|
39
39
|
removed: object = None # only on Display.deprecated
|
40
40
|
value: object = None # only on deprecate_value
|
41
41
|
|
42
|
+
def all_args_dynamic(self) -> bool:
|
43
|
+
"""True if all args are dynamic or None, otherwise False."""
|
44
|
+
return all(arg is None or isinstance(arg, astroid.NodeNG) for arg in dataclasses.asdict(self).values())
|
45
|
+
|
42
46
|
|
43
47
|
class AnsibleDeprecatedChecker(pylint.checkers.BaseChecker):
|
44
48
|
"""Checks for deprecated calls to ensure proper usage."""
|
@@ -346,6 +350,10 @@ class AnsibleDeprecatedChecker(pylint.checkers.BaseChecker):
|
|
346
350
|
self.add_message('ansible-deprecated-date-not-permitted', node=node, args=(name,))
|
347
351
|
return
|
348
352
|
|
353
|
+
if call_args.all_args_dynamic():
|
354
|
+
# assume collection maintainers know what they're doing if all args are dynamic
|
355
|
+
return
|
356
|
+
|
349
357
|
if call_args.version and call_args.date:
|
350
358
|
self.add_message('ansible-deprecated-both-version-and-date', node=node, args=(name,))
|
351
359
|
return
|
@@ -407,10 +415,13 @@ class AnsibleDeprecatedChecker(pylint.checkers.BaseChecker):
|
|
407
415
|
self.add_message('ansible-deprecated-unnecessary-collection-name', node=node, args=('deprecator', name,))
|
408
416
|
return
|
409
417
|
|
418
|
+
if args.all_args_dynamic():
|
419
|
+
# assume collection maintainers know what they're doing if all args are dynamic
|
420
|
+
return
|
421
|
+
|
410
422
|
expected_collection_name = 'ansible.builtin' if self.is_ansible_core else self.collection_name
|
411
423
|
|
412
424
|
if args.collection_name and args.collection_name != expected_collection_name:
|
413
|
-
# if collection_name is provided and a constant, report when it does not match the expected name
|
414
425
|
self.add_message('wrong-collection-deprecated', node=node, args=(args.collection_name, name))
|
415
426
|
|
416
427
|
def check_version(self, node: astroid.Call, name: str, args: DeprecationCallArgs) -> None:
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|