mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-04-30 10:26:52 +00:00
Compare commits
75 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f88b8c85d7 | ||
|
|
6385fbe038 | ||
|
|
4b6cd41512 | ||
|
|
8c429ac69d | ||
|
|
30eb35cb95 | ||
|
|
33f3e7172b | ||
|
|
c2751dd6f5 | ||
|
|
d3dd685ad4 | ||
|
|
696b6e737a | ||
|
|
45d16053ee | ||
|
|
1d4fd21702 | ||
|
|
bfcdeeab91 | ||
|
|
5dcb3b8f59 | ||
|
|
42c20a754b | ||
|
|
75b6b4d792 | ||
|
|
a0c4308bed | ||
|
|
6437fe15c8 | ||
|
|
baddfa5a80 | ||
|
|
b7d1483a08 | ||
|
|
b87121e1eb | ||
|
|
cb17703c36 | ||
|
|
05d457dca7 | ||
|
|
7fce59fbc6 | ||
|
|
de6967d3ff | ||
|
|
bbb9b03b5e | ||
|
|
a0d6487f6d | ||
|
|
88bfb6dda3 | ||
|
|
d637db7623 | ||
|
|
2198588afa | ||
|
|
9d6db6002c | ||
|
|
dd9c86dfc0 | ||
|
|
a266ba1d6e | ||
|
|
4167d8ebeb | ||
|
|
e9064bbf97 | ||
|
|
79a5e6745b | ||
|
|
b5d57a35d6 | ||
|
|
44dfe9e1ab | ||
|
|
4d05149b6c | ||
|
|
31bab91c31 | ||
|
|
ccdf82f163 | ||
|
|
1670f8693a | ||
|
|
d58777ff5e | ||
|
|
68f2433577 | ||
|
|
0f6dfd1ebb | ||
|
|
43f0152969 | ||
|
|
68bd8babf7 | ||
|
|
ca805badc0 | ||
|
|
5b571fd53f | ||
|
|
68b2385efd | ||
|
|
b5c965939f | ||
|
|
136c7debe3 | ||
|
|
5d16a88298 | ||
|
|
02ed21b2a6 | ||
|
|
b769b0bc01 | ||
|
|
ebaf2e71d5 | ||
|
|
e3535de323 | ||
|
|
6169699b24 | ||
|
|
e714d15891 | ||
|
|
dda90768f5 | ||
|
|
cd548f779a | ||
|
|
c1ba162ec0 | ||
|
|
2d99eb92de | ||
|
|
e0bd7e334e | ||
|
|
1d09a36e0f | ||
|
|
bb6d5fb735 | ||
|
|
8242f6fa46 | ||
|
|
88eee5fbb4 | ||
|
|
5945c56b4c | ||
|
|
4514e271af | ||
|
|
f49c5f79a7 | ||
|
|
2d07481e64 | ||
|
|
41f815be57 | ||
|
|
8d4e702d89 | ||
|
|
303bac630a | ||
|
|
213dc22217 |
@@ -29,6 +29,7 @@ schedules:
|
||||
always: true
|
||||
branches:
|
||||
include:
|
||||
- stable-12
|
||||
- stable-11
|
||||
- cron: 0 11 * * 0
|
||||
displayName: Weekly (old stable branches)
|
||||
@@ -170,10 +171,10 @@ stages:
|
||||
parameters:
|
||||
testFormat: devel/{0}
|
||||
targets:
|
||||
- name: Alpine 3.22
|
||||
test: alpine/3.22
|
||||
# - name: Fedora 42
|
||||
# test: fedora/42
|
||||
- name: Alpine 3.23
|
||||
test: alpine/3.23
|
||||
# - name: Fedora 43
|
||||
# test: fedora/43
|
||||
- name: Ubuntu 22.04
|
||||
test: ubuntu/22.04
|
||||
- name: Ubuntu 24.04
|
||||
@@ -190,14 +191,15 @@ stages:
|
||||
targets:
|
||||
- name: macOS 15.3
|
||||
test: macos/15.3
|
||||
- name: RHEL 10.0
|
||||
test: rhel/10.0
|
||||
- name: RHEL 9.6
|
||||
test: rhel/9.6
|
||||
- name: RHEL 10.1
|
||||
test: rhel/10.1
|
||||
- name: RHEL 9.7
|
||||
test: rhel/9.7
|
||||
# TODO: enable this ASAP!
|
||||
# - name: FreeBSD 15.0
|
||||
# test: freebsd/15.0
|
||||
- name: FreeBSD 14.3
|
||||
test: freebsd/14.3
|
||||
- name: FreeBSD 13.5
|
||||
test: freebsd/13.5
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
@@ -210,8 +212,8 @@ stages:
|
||||
parameters:
|
||||
testFormat: 2.20/{0}
|
||||
targets:
|
||||
- name: RHEL 10.0
|
||||
test: rhel/10.0
|
||||
- name: RHEL 10.1
|
||||
test: rhel/10.1
|
||||
- name: FreeBSD 14.3
|
||||
test: freebsd/14.3
|
||||
groups:
|
||||
@@ -226,10 +228,8 @@ stages:
|
||||
parameters:
|
||||
testFormat: 2.19/{0}
|
||||
targets:
|
||||
- name: RHEL 9.5
|
||||
test: rhel/9.5
|
||||
- name: RHEL 10.0
|
||||
test: rhel/10.0
|
||||
- name: RHEL 10.1
|
||||
test: rhel/10.1
|
||||
- name: FreeBSD 14.2
|
||||
test: freebsd/14.2
|
||||
groups:
|
||||
@@ -246,8 +246,6 @@ stages:
|
||||
targets:
|
||||
- name: macOS 14.3
|
||||
test: macos/14.3
|
||||
- name: RHEL 9.4
|
||||
test: rhel/9.4
|
||||
- name: FreeBSD 14.1
|
||||
test: freebsd/14.1
|
||||
groups:
|
||||
@@ -264,10 +262,10 @@ stages:
|
||||
parameters:
|
||||
testFormat: devel/linux/{0}
|
||||
targets:
|
||||
- name: Fedora 42
|
||||
test: fedora42
|
||||
- name: Alpine 3.22
|
||||
test: alpine322
|
||||
- name: Fedora 43
|
||||
test: fedora43
|
||||
- name: Alpine 3.23
|
||||
test: alpine323
|
||||
- name: Ubuntu 22.04
|
||||
test: ubuntu2204
|
||||
- name: Ubuntu 24.04
|
||||
@@ -343,7 +341,7 @@ stages:
|
||||
- name: Debian 13 Trixie
|
||||
test: debian-13-trixie/3.13
|
||||
- name: ArchLinux
|
||||
test: archlinux/3.13
|
||||
test: archlinux/3.14
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
|
||||
@@ -43,20 +43,20 @@ def main():
|
||||
jobs[label] = max(attempt, jobs.get(label, 0))
|
||||
|
||||
for label, attempt in jobs.items():
|
||||
name = "Coverage {attempt} {label}".format(label=label, attempt=attempt)
|
||||
name = f"Coverage {attempt} {label}"
|
||||
source = os.path.join(source_directory, name)
|
||||
source_files = os.listdir(source)
|
||||
|
||||
for source_file in source_files:
|
||||
source_path = os.path.join(source, source_file)
|
||||
destination_path = os.path.join(destination_directory, source_file + "." + label)
|
||||
print('"%s" -> "%s"' % (source_path, destination_path))
|
||||
print(f'"{source_path}" -> "{destination_path}"')
|
||||
shutil.copyfile(source_path, destination_path)
|
||||
count += 1
|
||||
|
||||
print("Coverage file count: %d" % count)
|
||||
print("##vso[task.setVariable variable=coverageFileCount]%d" % count)
|
||||
print("##vso[task.setVariable variable=outputPath]%s" % output_path)
|
||||
print(f"Coverage file count: {count}")
|
||||
print(f"##vso[task.setVariable variable=coverageFileCount]{count}")
|
||||
print(f"##vso[task.setVariable variable=outputPath]{output_path}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -15,7 +15,6 @@ import pathlib
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
import typing as t
|
||||
import urllib.request
|
||||
|
||||
|
||||
@@ -23,7 +22,7 @@ import urllib.request
|
||||
class CoverageFile:
|
||||
name: str
|
||||
path: pathlib.Path
|
||||
flags: t.List[str]
|
||||
flags: list[str]
|
||||
|
||||
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
@@ -46,7 +45,7 @@ def parse_args() -> Args:
|
||||
return Args(**kwargs)
|
||||
|
||||
|
||||
def process_files(directory: pathlib.Path) -> t.Tuple[CoverageFile, ...]:
|
||||
def process_files(directory: pathlib.Path) -> tuple[CoverageFile, ...]:
|
||||
processed = []
|
||||
for file in directory.joinpath("reports").glob("coverage*.xml"):
|
||||
name = file.stem.replace("coverage=", "")
|
||||
@@ -62,7 +61,7 @@ def process_files(directory: pathlib.Path) -> t.Tuple[CoverageFile, ...]:
|
||||
return tuple(processed)
|
||||
|
||||
|
||||
def upload_files(codecov_bin: pathlib.Path, files: t.Tuple[CoverageFile, ...], dry_run: bool = False) -> None:
|
||||
def upload_files(codecov_bin: pathlib.Path, files: tuple[CoverageFile, ...], dry_run: bool = False) -> None:
|
||||
for file in files:
|
||||
cmd = [
|
||||
str(codecov_bin),
|
||||
|
||||
@@ -19,8 +19,8 @@ def main():
|
||||
sys.stdout.reconfigure(errors="surrogateescape")
|
||||
|
||||
for line in sys.stdin:
|
||||
seconds = time.time() - start
|
||||
sys.stdout.write("%02d:%02d %s" % (seconds // 60, seconds % 60, line))
|
||||
seconds = int(time.time() - start)
|
||||
sys.stdout.write(f"{seconds // 60:02}:{seconds % 60:02} {line}")
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
|
||||
@@ -11,3 +11,5 @@ eaa5e07b2866e05b6c7b5628ca92e9cb1142d008
|
||||
# Code reformatting
|
||||
340ff8586d4f1cb6a0f3c934eb42589bcc29c0ea
|
||||
e530d2906a1f61df89861286ac57c951a247f32c
|
||||
b769b0bc01520d12699d3911e1fc290b813cde40
|
||||
dd9c86dfc094131f223ffb59e5a3d9f2dfc5875d
|
||||
|
||||
21
.github/BOTMETA.yml
vendored
21
.github/BOTMETA.yml
vendored
@@ -65,6 +65,9 @@ files:
|
||||
$callbacks/log_plays.py: {}
|
||||
$callbacks/loganalytics.py:
|
||||
maintainers: zhcli
|
||||
$callbacks/loganalytics_ingestion.py:
|
||||
ignore: zhcli
|
||||
maintainers: pboushy vsh47 wtcline-intc
|
||||
$callbacks/logdna.py: {}
|
||||
$callbacks/logentries.py: {}
|
||||
$callbacks/logstash.py:
|
||||
@@ -133,6 +136,8 @@ files:
|
||||
$doc_fragments/hwc.py:
|
||||
labels: hwc
|
||||
maintainers: $team_huawei
|
||||
$doc_fragments/_icinga2_api.py:
|
||||
maintainers: cfiehe
|
||||
$doc_fragments/nomad.py:
|
||||
maintainers: chris93111 apecnascimento
|
||||
$doc_fragments/pipx.py:
|
||||
@@ -216,6 +221,10 @@ files:
|
||||
maintainers: resmo
|
||||
$filters/to_time_unit.yml:
|
||||
maintainers: resmo
|
||||
$filters/to_toml.py:
|
||||
maintainers: milliams
|
||||
$filters/to_toml.yml:
|
||||
maintainers: milliams
|
||||
$filters/to_weeks.yml:
|
||||
maintainers: resmo
|
||||
$filters/to_yaml.py:
|
||||
@@ -358,6 +367,8 @@ files:
|
||||
keywords: cloud huawei hwc
|
||||
labels: huawei hwc_utils networking
|
||||
maintainers: $team_huawei
|
||||
$module_utils/_icinga2.py:
|
||||
maintainers: cfiehe
|
||||
$module_utils/identity/keycloak/keycloak.py:
|
||||
maintainers: $team_keycloak
|
||||
$module_utils/identity/keycloak/keycloak_clientsecret.py:
|
||||
@@ -709,6 +720,8 @@ files:
|
||||
maintainers: $team_huawei huaweicloud
|
||||
$modules/ibm_sa_:
|
||||
maintainers: tzure
|
||||
$modules/icinga2_downtime.py:
|
||||
maintainers: cfiehe
|
||||
$modules/icinga2_feature.py:
|
||||
maintainers: nerzhul
|
||||
$modules/icinga2_host.py:
|
||||
@@ -853,6 +866,8 @@ files:
|
||||
maintainers: fynncfchen
|
||||
$modules/keycloak_realm_key.py:
|
||||
maintainers: mattock
|
||||
$modules/keycloak_realm_localization.py:
|
||||
maintainers: danekja
|
||||
$modules/keycloak_role.py:
|
||||
maintainers: laurpaum
|
||||
$modules/keycloak_user.py:
|
||||
@@ -1333,6 +1348,8 @@ files:
|
||||
maintainers: farhan7500 gautamphegde
|
||||
$modules/ssh_config.py:
|
||||
maintainers: gaqzi Akasurde
|
||||
$modules/sssd_info.py:
|
||||
maintainers: a-gabidullin
|
||||
$modules/stacki_host.py:
|
||||
labels: stacki_host
|
||||
maintainers: bsanders bbyhuy
|
||||
@@ -1498,14 +1515,14 @@ files:
|
||||
maintainers: vbotka
|
||||
$plugin_utils/unsafe.py:
|
||||
maintainers: felixfontein
|
||||
$plugin_utils/_tags.py:
|
||||
maintainers: felixfontein
|
||||
$tests/a_module.py:
|
||||
maintainers: felixfontein
|
||||
$tests/ansible_type.py:
|
||||
maintainers: vbotka
|
||||
$tests/fqdn_valid.py:
|
||||
maintainers: vbotka
|
||||
$modules/sssd_info.py:
|
||||
maintainers: a-gabidullin
|
||||
#########################
|
||||
docs/docsite/rst/filter_guide.rst: {}
|
||||
docs/docsite/rst/filter_guide_abstract_informations.rst: {}
|
||||
|
||||
26
.mypy.ini
26
.mypy.ini
@@ -14,6 +14,8 @@ warn_redundant_casts = True
|
||||
# warn_return_any = True
|
||||
warn_unreachable = True
|
||||
|
||||
exclude = tests/integration/targets/django_.*/files/.*
|
||||
|
||||
[mypy-ansible.*]
|
||||
# ansible-core has partial typing information
|
||||
follow_untyped_imports = True
|
||||
@@ -24,6 +26,10 @@ follow_untyped_imports = True
|
||||
# 3. That have no types and type stubs.
|
||||
[mypy-aerospike.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-antsibull_nox.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-asyncore.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-boto3.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-bs4.*]
|
||||
@@ -38,6 +44,8 @@ ignore_missing_imports = True
|
||||
ignore_missing_imports = True
|
||||
[mypy-crypt.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-daemon.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-datadog.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-dbus.*]
|
||||
@@ -62,6 +70,8 @@ ignore_missing_imports = True
|
||||
ignore_missing_imports = True
|
||||
[mypy-github3.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-gssapi.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-hashids.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-heroku3.*]
|
||||
@@ -122,6 +132,10 @@ ignore_missing_imports = True
|
||||
ignore_missing_imports = True
|
||||
[mypy-nomad.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-nopackagewiththisname.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-nox.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-oci.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-oneandone.*]
|
||||
@@ -144,6 +158,8 @@ ignore_missing_imports = True
|
||||
ignore_missing_imports = True
|
||||
[mypy-pingdom.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-pkg_resources.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-portage.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-potatoes_that_will_never_be_there.*]
|
||||
@@ -174,6 +190,8 @@ ignore_missing_imports = True
|
||||
ignore_missing_imports = True
|
||||
[mypy-rpm.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-ruamel.yaml.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-salt.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-selinux.*]
|
||||
@@ -186,6 +204,10 @@ ignore_missing_imports = True
|
||||
ignore_missing_imports = True
|
||||
[mypy-sha.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-smtpd.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-smtpd_tls.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-SoftLayer.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-spotinst_sdk.*]
|
||||
@@ -198,10 +220,14 @@ ignore_missing_imports = True
|
||||
ignore_missing_imports = True
|
||||
[mypy-thycotic.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-tomlkit.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-univention.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-vexatapi.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-voluptuous.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-websocket.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-XenAPI.*]
|
||||
|
||||
250
CHANGELOG.md
250
CHANGELOG.md
File diff suppressed because one or more lines are too long
175
CHANGELOG.rst
175
CHANGELOG.rst
@@ -6,6 +6,181 @@ Community General Release Notes
|
||||
|
||||
This changelog describes changes after version 11.0.0.
|
||||
|
||||
v12.4.0
|
||||
=======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Regular bugfix and feature release.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- ModuleHelper module utils - allow to ignore specific exceptions in ``module_fails_on_exception`` decorator (https://github.com/ansible-collections/community.general/pull/11488).
|
||||
- from_ini filter plugin - add ``delimiters`` parameter to allow correctly parsing more INI documents (https://github.com/ansible-collections/community.general/issues/11506, https://github.com/ansible-collections/community.general/pull/11512).
|
||||
- keycloak_client - add ``valid_post_logout_redirect_uris`` option to configure post logout redirect URIs for a client, and ``backchannel_logout_url`` option to configure the backchannel logout URL for a client (https://github.com/ansible-collections/community.general/issues/6812, https://github.com/ansible-collections/community.general/issues/4892, https://github.com/ansible-collections/community.general/pull/11473).
|
||||
- keycloak_client_rolemapping, keycloak_realm_rolemapping, keycloak_group - optimize retrieval of groups by name to use Keycloak search API with exact matching instead of fetching all groups (https://github.com/ansible-collections/community.general/pull/11503).
|
||||
- keycloak_realm - add support for ``localizationTexts`` option in Keycloak realms (https://github.com/ansible-collections/community.general/pull/11513).
|
||||
- keycloak_realm_key - add support for auto-generated key providers (``rsa-generated``, ``rsa-enc-generated``, ``hmac-generated``, ``aes-generated``, ``ecdsa-generated``, ``ecdh-generated``, ``eddsa-generated``), ``java-keystore`` provider, additional algorithms (HMAC, ECDSA, ECDH, EdDSA, AES), and new config options (``secret_size``, ``key_size``, ``elliptic_curve``, ``keystore``, ``keystore_password``, ``key_alias``, ``key_password``). Also makes ``config.private_key`` and ``config.certificate`` optional as they are only required for imported key providers (https://github.com/ansible-collections/community.general/pull/11468).
|
||||
- redfish_info - add Redfish Root data to results of successful ``CheckAvailability`` command (https://github.com/ansible-collections/community.general/pull/11504).
|
||||
- seport - adds support for DCCP and SCTP protocols (https://github.com/ansible-collections/community.general/pull/11486).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- keycloak module utils - fix ``TypeError`` crash when managing users whose username or email contains special characters such as ``+`` (https://github.com/ansible-collections/community.general/issues/10305, https://github.com/ansible-collections/community.general/pull/11472).
|
||||
- keycloak module utils - use proper URL encoding (``urllib.parse.quote``) for query parameters in authorization permission name searches, replacing fragile manual space replacement (https://github.com/ansible-collections/community.general/pull/11472).
|
||||
- keycloak_client - fix idempotency bug caused by ``null`` flow overrides value differences for non-existing flow overrides (https://github.com/ansible-collections/community.general/issues/11430, https://github.com/ansible-collections/community.general/pull/11455).
|
||||
- keycloak_client - remove IDs as change from diff result for protocol mappers (https://github.com/ansible-collections/community.general/issues/11453, https://github.com/ansible-collections/community.general/pull/11454).
|
||||
- keycloak_realm_key - fix ``KeyError`` crash when managing realm keys where Keycloak does not return ``active``, ``enabled``, or ``algorithm`` fields in the config response (https://github.com/ansible-collections/community.general/issues/11459, https://github.com/ansible-collections/community.general/pull/11470).
|
||||
- keycloak_user_federation - mapper config item can be an array (https://github.com/ansible-collections/community.general/issues/11502, https://github.com/ansible-collections/community.general/pull/11515).
|
||||
- keycloak_user_rolemapping - fix ``TypeError`` crash when adding a client role to a user who has no existing roles for that client (https://github.com/ansible-collections/community.general/issues/10960, https://github.com/ansible-collections/community.general/pull/11471).
|
||||
- maven_artifact - fix SNAPSHOT version resolution to pick the newest matching ``<snapshotVersion>`` entry by ``<updated>`` timestamp instead of the first. Repositories like GitHub Packages keep all historical entries in ``<snapshotVersions>`` (oldest first), causing the module to resolve to the oldest snapshot instead of the latest (https://github.com/ansible-collections/community.general/issues/5117, https://github.com/ansible-collections/community.general/issues/11489, https://github.com/ansible-collections/community.general/pull/11501).
|
||||
- nsupdate - fix ``AttributeError`` when using the module without TSIG authentication (https://github.com/ansible-collections/community.general/issues/11460, https://github.com/ansible-collections/community.general/pull/11461).
|
||||
- python_requirements_info - use ``importlib.metadata`` if ``pkg_resources`` from ``setuptools`` cannot be imported. That module has been removed from setuptools 82.0.0 (https://github.com/ansible-collections/community.general/issues/11491, https://github.com/ansible-collections/community.general/pull/11492).
|
||||
- splunk callback plugin - replace deprecated callback function (https://github.com/ansible-collections/community.general/pull/11485).
|
||||
|
||||
New Plugins
|
||||
-----------
|
||||
|
||||
Callback
|
||||
~~~~~~~~
|
||||
|
||||
- community.general.loganalytics_ingestion - Posts task results to an Azure Log Analytics workspace using the new Logs Ingestion API.
|
||||
|
||||
New Modules
|
||||
-----------
|
||||
|
||||
- community.general.icinga2_downtime - Manages Icinga 2 downtimes.
|
||||
- community.general.keycloak_realm_localization - Allows management of Keycloak realm localization overrides via the Keycloak API.
|
||||
|
||||
v12.3.0
|
||||
=======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Regular feature and bugfix release.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- alicloud_ecs module utils - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- android_sdk - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- archive - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- bitbucket_pipeline_known_host - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- chroot connection plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- cobbler inventory plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- copr - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- cronvar - simplify handling unknown exceptions (https://github.com/ansible-collections/community.general/pull/11340).
|
||||
- cronvar - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- crypttab - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- elasticsearch_plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- gitlab_group - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- gitlab_issue - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- gitlab_merge_request - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- gitlab_project - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- gunicorn - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- htpasswd - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- idrac_redfish_info - add multiple manager support to ``GetManagerAttributes`` command (https://github.com/ansible-collections/community.general/pull/11294).
|
||||
- imc_rest - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- incus connection plugin - improve code readability (https://github.com/ansible-collections/community.general/pull/11346).
|
||||
- incus connection plugin - simplify regular expression matching commands (https://github.com/ansible-collections/community.general/pull/11347).
|
||||
- ini_file - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- interfaces_file - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- iptables_state - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- jail connection plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- jenkins_credential - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- jenkins_plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- jenkins_script - move ``import`` statemetns to the top of the file (https://github.com/ansible-collections/community.general/pull/11396).
|
||||
- kdeconfig - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- known_hosts module utils - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- layman - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- linode - move ``import`` statemetns to the top of the file (https://github.com/ansible-collections/community.general/pull/11396).
|
||||
- linode inventory plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- listen_ports_facts - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- locale_gen - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- logentries callback plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- lvm_pv - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- lxc connection plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- lxd inventory plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- lxd module utils - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- manageiq module utils - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- manageiq_alert_profiles - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- modprobe - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- mssql_db - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- nagios - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- netcup_dns - support diff mode (https://github.com/ansible-collections/community.general/pull/11376).
|
||||
- nmcli - add idempotency check (https://github.com/ansible-collections/community.general/pull/11114).
|
||||
- nmcli - add support for IPv6 routing rules (https://github.com/ansible-collections/community.general/issues/7094, https://github.com/ansible-collections/community.general/pull/11413).
|
||||
- nosh - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- nsupdate - add support for server FQDN and the GSS-TSIG key algorithm (https://github.com/ansible-collections/community.general/issues/5730, https://github.com/ansible-collections/community.general/pull/11425).
|
||||
- nsupdate modules plugin - replace aliased errors with proper Python error (https://github.com/ansible-collections/community.general/pull/11391).
|
||||
- oci_utils module utils - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- omapi_host - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- one_image - move ``import`` statemetns to the top of the file (https://github.com/ansible-collections/community.general/pull/11396).
|
||||
- one_image_info - move ``import`` statemetns to the top of the file (https://github.com/ansible-collections/community.general/pull/11396).
|
||||
- one_service - move ``import`` statemetns to the top of the file (https://github.com/ansible-collections/community.general/pull/11396).
|
||||
- one_vm - move ``import`` statemetns to the top of the file (https://github.com/ansible-collections/community.general/pull/11396).
|
||||
- one_vm - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- opennebula inventory plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- pam_limits - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- pamd - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- parted - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- pmem - simplify text tests without using regular expression (https://github.com/ansible-collections/community.general/pull/11388).
|
||||
- pubnub_blocks - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- pulp_repo - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- read_csv - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- redfish_utils module utils - adds support of ``@Redfish.Settings`` in ``ComputerSystem`` attributes for ``set_boot_override`` function (https://github.com/ansible-collections/community.general/issues/11297, https://github.com/ansible-collections/community.general/pull/11322).
|
||||
- redhat_subscription - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- rhsm_repository - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- runit - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- scaleway_ip - added ``project`` parameter (https://github.com/ansible-collections/community.general/issues/11367, https://github.com/ansible-collections/community.general/pull/11368).
|
||||
- scaleway_security_group - added ``project`` parameter (https://github.com/ansible-collections/community.general/issues/11364, https://github.com/ansible-collections/community.general/pull/11366).
|
||||
- sensu_check - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- sensu_client - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- sensu_handler - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- sensu_subscription - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- seport - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- serverless - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- slackpkg - refactor function ``query_packages()`` (https://github.com/ansible-collections/community.general/pull/11390).
|
||||
- solaris_zone - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- sorcery - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- spotinst_aws_elastigroup - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- sudoers - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- svc - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- timestamp callback plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- timezone - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- univention_umc module utils - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- wakeonlan - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- wsl connection plugin - add option ``wsl_remote_ssh_shell_type``. Support PowerShell in addition to cmd as the Windows shell (https://github.com/ansible-collections/community.general/issues/11307, https://github.com/ansible-collections/community.general/pull/11308).
|
||||
- wsl connection plugin - replace aliased errors with proper Python error (https://github.com/ansible-collections/community.general/pull/11391).
|
||||
- wsl connection plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- xfs_quota - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- yaml cache plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- zone connection plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- zypper - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- zypper_repository - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- cloudflare_dns - also allow ``flag=128`` for CAA records (https://github.com/ansible-collections/community.general/issues/11355, https://github.com/ansible-collections/community.general/pull/11377).
|
||||
- gem - add compatibility with Ruby 4 rubygems (https://github.com/ansible-collections/community.general/issues/11397, https://github.com/ansible-collections/community.general/pull/11442).
|
||||
- incus connection plugin - fix parsing of commands for Windows, enforcing a ``\`` after the drive letter and colon symbol (https://github.com/ansible-collections/community.general/pull/11347).
|
||||
- keycloak_client - fix idempotency bug caused by ``null`` client attribute value differences for non-existing client attributes (https://github.com/ansible-collections/community.general/issues/11443, https://github.com/ansible-collections/community.general/pull/11444).
|
||||
- logstash_plugin - fix argument order when using ``version`` parameter. The plugin name must come after options like ``--version`` for the ``logstash-plugin`` CLI to work correctly (https://github.com/ansible-collections/community.general/issues/10745, https://github.com/ansible-collections/community.general/pull/11440).
|
||||
- pmem - fix test for invalid data input (https://github.com/ansible-collections/community.general/pull/11388).
|
||||
|
||||
New Plugins
|
||||
-----------
|
||||
|
||||
Filter
|
||||
~~~~~~
|
||||
|
||||
- community.general.to_toml - Convert variable to TOML string.
|
||||
|
||||
v12.2.0
|
||||
=======
|
||||
|
||||
|
||||
@@ -20,8 +20,15 @@ stable_branches = [ "stable-*" ]
|
||||
[sessions]
|
||||
|
||||
[sessions.lint]
|
||||
code_files = ["."] # consider all Python files in the collection
|
||||
run_isort = false
|
||||
run_black = false
|
||||
run_ruff_autofix = true
|
||||
ruff_autofix_config = "ruff.toml"
|
||||
ruff_autofix_select = [
|
||||
"I",
|
||||
"RUF022",
|
||||
]
|
||||
run_ruff_check = true
|
||||
ruff_check_config = "ruff.toml"
|
||||
run_ruff_format = true
|
||||
|
||||
@@ -1627,3 +1627,262 @@ releases:
|
||||
name: sssd_info
|
||||
namespace: ''
|
||||
release_date: '2025-12-29'
|
||||
12.3.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- cloudflare_dns - also allow ``flag=128`` for CAA records (https://github.com/ansible-collections/community.general/issues/11355,
|
||||
https://github.com/ansible-collections/community.general/pull/11377).
|
||||
- gem - add compatibility with Ruby 4 rubygems (https://github.com/ansible-collections/community.general/issues/11397,
|
||||
https://github.com/ansible-collections/community.general/pull/11442).
|
||||
- 'incus connection plugin - fix parsing of commands for Windows, enforcing
|
||||
a ``\`` after the drive letter and colon symbol (https://github.com/ansible-collections/community.general/pull/11347).
|
||||
|
||||
'
|
||||
- keycloak_client - fix idempotency bug caused by ``null`` client attribute
|
||||
value differences for non-existing client attributes (https://github.com/ansible-collections/community.general/issues/11443,
|
||||
https://github.com/ansible-collections/community.general/pull/11444).
|
||||
- logstash_plugin - fix argument order when using ``version`` parameter. The
|
||||
plugin name must come after options like ``--version`` for the ``logstash-plugin``
|
||||
CLI to work correctly (https://github.com/ansible-collections/community.general/issues/10745,
|
||||
https://github.com/ansible-collections/community.general/pull/11440).
|
||||
- pmem - fix test for invalid data input (https://github.com/ansible-collections/community.general/pull/11388).
|
||||
minor_changes:
|
||||
- alicloud_ecs module utils - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- android_sdk - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- archive - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- bitbucket_pipeline_known_host - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- chroot connection plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- cobbler inventory plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- copr - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- cronvar - simplify handling unknown exceptions (https://github.com/ansible-collections/community.general/pull/11340).
|
||||
- cronvar - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- crypttab - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- elasticsearch_plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- gitlab_group - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- gitlab_issue - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- gitlab_merge_request - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- gitlab_project - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- gunicorn - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- htpasswd - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- idrac_redfish_info - add multiple manager support to ``GetManagerAttributes``
|
||||
command (https://github.com/ansible-collections/community.general/pull/11294).
|
||||
- imc_rest - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- incus connection plugin - improve code readability (https://github.com/ansible-collections/community.general/pull/11346).
|
||||
- incus connection plugin - simplify regular expression matching commands
|
||||
(https://github.com/ansible-collections/community.general/pull/11347).
|
||||
- ini_file - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- interfaces_file - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- iptables_state - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- jail connection plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- jenkins_credential - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- jenkins_plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- jenkins_script - move ``import`` statemetns to the top of the file (https://github.com/ansible-collections/community.general/pull/11396).
|
||||
- kdeconfig - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- known_hosts module utils - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- layman - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- linode - move ``import`` statemetns to the top of the file (https://github.com/ansible-collections/community.general/pull/11396).
|
||||
- linode inventory plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- listen_ports_facts - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- locale_gen - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- logentries callback plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- lvm_pv - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11343).
|
||||
- lxc connection plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- lxd inventory plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- lxd module utils - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- manageiq module utils - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- manageiq_alert_profiles - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- modprobe - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- mssql_db - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- nagios - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- netcup_dns - support diff mode (https://github.com/ansible-collections/community.general/pull/11376).
|
||||
- nmcli - add idempotency check (https://github.com/ansible-collections/community.general/pull/11114).
|
||||
- nmcli - add support for IPv6 routing rules (https://github.com/ansible-collections/community.general/issues/7094,
|
||||
https://github.com/ansible-collections/community.general/pull/11413).
|
||||
- nosh - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- nsupdate - add support for server FQDN and the GSS-TSIG key algorithm (https://github.com/ansible-collections/community.general/issues/5730,
|
||||
https://github.com/ansible-collections/community.general/pull/11425).
|
||||
- nsupdate modules plugin - replace aliased errors with proper Python error
|
||||
(https://github.com/ansible-collections/community.general/pull/11391).
|
||||
- oci_utils module utils - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- omapi_host - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- one_image - move ``import`` statemetns to the top of the file (https://github.com/ansible-collections/community.general/pull/11396).
|
||||
- one_image_info - move ``import`` statemetns to the top of the file (https://github.com/ansible-collections/community.general/pull/11396).
|
||||
- one_service - move ``import`` statemetns to the top of the file (https://github.com/ansible-collections/community.general/pull/11396).
|
||||
- one_vm - move ``import`` statemetns to the top of the file (https://github.com/ansible-collections/community.general/pull/11396).
|
||||
- one_vm - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- opennebula inventory plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- pam_limits - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- pamd - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- parted - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- pmem - simplify text tests without using regular expression (https://github.com/ansible-collections/community.general/pull/11388).
|
||||
- pubnub_blocks - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- pulp_repo - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- read_csv - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- redfish_utils module utils - adds support of ``@Redfish.Settings`` in ``ComputerSystem``
|
||||
attributes for ``set_boot_override`` function (https://github.com/ansible-collections/community.general/issues/11297,
|
||||
https://github.com/ansible-collections/community.general/pull/11322).
|
||||
- redhat_subscription - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- rhsm_repository - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- runit - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- scaleway_ip - added ``project`` parameter (https://github.com/ansible-collections/community.general/issues/11367,
|
||||
https://github.com/ansible-collections/community.general/pull/11368).
|
||||
- scaleway_security_group - added ``project`` parameter (https://github.com/ansible-collections/community.general/issues/11364,
|
||||
https://github.com/ansible-collections/community.general/pull/11366).
|
||||
- sensu_check - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- sensu_client - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- sensu_handler - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- sensu_subscription - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- seport - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- serverless - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- slackpkg - refactor function ``query_packages()`` (https://github.com/ansible-collections/community.general/pull/11390).
|
||||
- solaris_zone - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- sorcery - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- spotinst_aws_elastigroup - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- sudoers - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- svc - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- timestamp callback plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- timezone - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- univention_umc module utils - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- wakeonlan - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- wsl connection plugin - add option ``wsl_remote_ssh_shell_type``. Support
|
||||
PowerShell in addition to cmd as the Windows shell (https://github.com/ansible-collections/community.general/issues/11307,
|
||||
https://github.com/ansible-collections/community.general/pull/11308).
|
||||
- wsl connection plugin - replace aliased errors with proper Python error
|
||||
(https://github.com/ansible-collections/community.general/pull/11391).
|
||||
- wsl connection plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- xfs_quota - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- yaml cache plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- zone connection plugin - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11341).
|
||||
- zypper - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
- zypper_repository - update to Python 3.7 idioms (https://github.com/ansible-collections/community.general/pull/11344).
|
||||
release_summary: Regular feature and bugfix release.
|
||||
fragments:
|
||||
- 11114-nmcli-idempotency.yml
|
||||
- 11301-idrac-info-multi-manager.yml
|
||||
- 11308-wsl-shell-type.yml
|
||||
- 11322-handle-redfish-settings-in-setbootoverride.yml
|
||||
- 11340-cronvar-simplify-exc.yml
|
||||
- 11341-pyupgrade-1.yml
|
||||
- 11343-pyupgrade-3.yml
|
||||
- 11344-pyupgrade-4.yml
|
||||
- 11346-incus-readability.yml
|
||||
- 11347-incus-regex.yml
|
||||
- 11366-scaleway-sg-project-param.yml
|
||||
- 11368-scaleway-ip-project-param.yml
|
||||
- 11376-netcup-dns-diff-mode.yml
|
||||
- 11377-cloudflare_dns-caa.yml
|
||||
- 11388-pmem-redundant-regexps.yml
|
||||
- 11390-slackpkg-query.yml
|
||||
- 11391-ruff-cases-11.yml
|
||||
- 11396-in-def-imports.yml
|
||||
- 11413-nmcli-routing-rules6.yml
|
||||
- 11425-nsupdate-gss-tsig.yml
|
||||
- 11440-logstash-plugin-fix-version-argument-order.yml
|
||||
- 11442-gem-module-ruby-4.yml
|
||||
- 11443-fix-keycloak-client-diff-for-null-attributes.yml
|
||||
- 12.3.0.yml
|
||||
plugins:
|
||||
filter:
|
||||
- description: Convert variable to TOML string.
|
||||
name: to_toml
|
||||
namespace: null
|
||||
release_date: '2026-01-26'
|
||||
12.4.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- keycloak module utils - fix ``TypeError`` crash when managing users whose
|
||||
username or email contains special characters such as ``+`` (https://github.com/ansible-collections/community.general/issues/10305,
|
||||
https://github.com/ansible-collections/community.general/pull/11472).
|
||||
- keycloak module utils - use proper URL encoding (``urllib.parse.quote``)
|
||||
for query parameters in authorization permission name searches, replacing
|
||||
fragile manual space replacement (https://github.com/ansible-collections/community.general/pull/11472).
|
||||
- keycloak_client - fix idempotency bug caused by ``null`` flow overrides
|
||||
value differences for non-existing flow overrides (https://github.com/ansible-collections/community.general/issues/11430,
|
||||
https://github.com/ansible-collections/community.general/pull/11455).
|
||||
- keycloak_client - remove IDs as change from diff result for protocol mappers
|
||||
(https://github.com/ansible-collections/community.general/issues/11453,
|
||||
https://github.com/ansible-collections/community.general/pull/11454).
|
||||
- keycloak_realm_key - fix ``KeyError`` crash when managing realm keys where
|
||||
Keycloak does not return ``active``, ``enabled``, or ``algorithm`` fields
|
||||
in the config response (https://github.com/ansible-collections/community.general/issues/11459,
|
||||
https://github.com/ansible-collections/community.general/pull/11470).
|
||||
- keycloak_user_federation - mapper config item can be an array (https://github.com/ansible-collections/community.general/issues/11502,
|
||||
https://github.com/ansible-collections/community.general/pull/11515).
|
||||
- keycloak_user_rolemapping - fix ``TypeError`` crash when adding a client
|
||||
role to a user who has no existing roles for that client (https://github.com/ansible-collections/community.general/issues/10960,
|
||||
https://github.com/ansible-collections/community.general/pull/11471).
|
||||
- maven_artifact - fix SNAPSHOT version resolution to pick the newest matching
|
||||
``<snapshotVersion>`` entry by ``<updated>`` timestamp instead of the first.
|
||||
Repositories like GitHub Packages keep all historical entries in ``<snapshotVersions>``
|
||||
(oldest first), causing the module to resolve to the oldest snapshot instead
|
||||
of the latest (https://github.com/ansible-collections/community.general/issues/5117,
|
||||
https://github.com/ansible-collections/community.general/issues/11489, https://github.com/ansible-collections/community.general/pull/11501).
|
||||
- nsupdate - fix ``AttributeError`` when using the module without TSIG authentication
|
||||
(https://github.com/ansible-collections/community.general/issues/11460,
|
||||
https://github.com/ansible-collections/community.general/pull/11461).
|
||||
- python_requirements_info - use ``importlib.metadata`` if ``pkg_resources``
|
||||
from ``setuptools`` cannot be imported. That module has been removed from
|
||||
setuptools 82.0.0 (https://github.com/ansible-collections/community.general/issues/11491,
|
||||
https://github.com/ansible-collections/community.general/pull/11492).
|
||||
- splunk callback plugin - replace deprecated callback function (https://github.com/ansible-collections/community.general/pull/11485).
|
||||
minor_changes:
|
||||
- ModuleHelper module utils - allow to ignore specific exceptions in ``module_fails_on_exception``
|
||||
decorator (https://github.com/ansible-collections/community.general/pull/11488).
|
||||
- from_ini filter plugin - add ``delimiters`` parameter to allow correctly
|
||||
parsing more INI documents (https://github.com/ansible-collections/community.general/issues/11506,
|
||||
https://github.com/ansible-collections/community.general/pull/11512).
|
||||
- keycloak_client - add ``valid_post_logout_redirect_uris`` option to configure
|
||||
post logout redirect URIs for a client, and ``backchannel_logout_url`` option
|
||||
to configure the backchannel logout URL for a client (https://github.com/ansible-collections/community.general/issues/6812,
|
||||
https://github.com/ansible-collections/community.general/issues/4892, https://github.com/ansible-collections/community.general/pull/11473).
|
||||
- keycloak_client_rolemapping, keycloak_realm_rolemapping, keycloak_group
|
||||
- optimize retrieval of groups by name to use Keycloak search API with exact
|
||||
matching instead of fetching all groups (https://github.com/ansible-collections/community.general/pull/11503).
|
||||
- keycloak_realm - add support for ``localizationTexts`` option in Keycloak
|
||||
realms (https://github.com/ansible-collections/community.general/pull/11513).
|
||||
- keycloak_realm_key - add support for auto-generated key providers (``rsa-generated``,
|
||||
``rsa-enc-generated``, ``hmac-generated``, ``aes-generated``, ``ecdsa-generated``,
|
||||
``ecdh-generated``, ``eddsa-generated``), ``java-keystore`` provider, additional
|
||||
algorithms (HMAC, ECDSA, ECDH, EdDSA, AES), and new config options (``secret_size``,
|
||||
``key_size``, ``elliptic_curve``, ``keystore``, ``keystore_password``, ``key_alias``,
|
||||
``key_password``). Also makes ``config.private_key`` and ``config.certificate``
|
||||
optional as they are only required for imported key providers (https://github.com/ansible-collections/community.general/pull/11468).
|
||||
- redfish_info - add Redfish Root data to results of successful ``CheckAvailability``
|
||||
command (https://github.com/ansible-collections/community.general/pull/11504).
|
||||
- seport - adds support for DCCP and SCTP protocols (https://github.com/ansible-collections/community.general/pull/11486).
|
||||
release_summary: Regular bugfix and feature release.
|
||||
fragments:
|
||||
- 11430-fix-keycloak-client-diff-for-flow-overrides.yml
|
||||
- 11453-keycloak-client-protocol-mapper-ids.yml
|
||||
- 11485-avoid-deprected-callback.yml
|
||||
- 11486-seport-dccp-sctp.yaml
|
||||
- 11488-mh-ensure-compatibiliy-with-module-tests.yml
|
||||
- 11492-python_requires_info.yml
|
||||
- 11502-keycloak-config-mapper.yaml
|
||||
- 11503-keycloak-group-search-optimization.yml
|
||||
- 11504-redfish-info-add-results-to-return.yml
|
||||
- 11512-from_ini-delimiters.yaml
|
||||
- 11513-keycloak-realm-localizationTexts-support.yml
|
||||
- 12.4.0.yml
|
||||
- 5117-maven-artifact-snapshot-resolution.yml
|
||||
- fix-nsupdate-keyring.yml
|
||||
- keycloak-client-add-missing-fields.yml
|
||||
- keycloak-realm-key-generated-providers.yml
|
||||
- keycloak-realm-key-keyerror-bugfix.yml
|
||||
- keycloak-url-encode-query-params.yml
|
||||
- keycloak-user-rolemapping-client-none-check.yml
|
||||
modules:
|
||||
- description: Manages Icinga 2 downtimes.
|
||||
name: icinga2_downtime
|
||||
namespace: ''
|
||||
- description: Allows management of Keycloak realm localization overrides via
|
||||
the Keycloak API.
|
||||
name: keycloak_realm_localization
|
||||
namespace: ''
|
||||
plugins:
|
||||
callback:
|
||||
- description: Posts task results to an Azure Log Analytics workspace using
|
||||
the new Logs Ingestion API.
|
||||
name: loganalytics_ingestion
|
||||
namespace: null
|
||||
release_date: '2026-02-23'
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import sys
|
||||
from io import StringIO
|
||||
|
||||
from ruamel.yaml import YAML
|
||||
from ruamel.yaml import YAML # type: ignore[import-not-found]
|
||||
|
||||
|
||||
def main() -> None:
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
namespace: community
|
||||
name: general
|
||||
version: 12.2.0
|
||||
version: 12.4.0
|
||||
readme: README.md
|
||||
authors:
|
||||
- Ansible (https://github.com/ansible)
|
||||
@@ -19,3 +19,5 @@ repository: https://github.com/ansible-collections/community.general
|
||||
documentation: https://docs.ansible.com/projects/ansible/latest/collections/community/general/
|
||||
homepage: https://github.com/ansible-collections/community.general
|
||||
issues: https://github.com/ansible-collections/community.general/issues
|
||||
build_ignore:
|
||||
- .nox
|
||||
|
||||
@@ -40,6 +40,7 @@ action_groups:
|
||||
- keycloak_realm
|
||||
- keycloak_realm_key
|
||||
- keycloak_realm_keys_metadata_info
|
||||
- keycloak_realm_localization
|
||||
- keycloak_realm_rolemapping
|
||||
- keycloak_role
|
||||
- keycloak_user
|
||||
@@ -378,6 +379,10 @@ plugin_routing:
|
||||
warning_text: Use community.general.idrac_redfish_info instead.
|
||||
idrac_server_config_profile:
|
||||
redirect: dellemc.openmanage.idrac_server_config_profile
|
||||
jboss:
|
||||
deprecation:
|
||||
removal_version: 14.0.0
|
||||
warning_text: Use role middleware_automation.wildfly.wildfly_app_deploy instead.
|
||||
jenkins_job_facts:
|
||||
tombstone:
|
||||
removal_version: 3.0.0
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
import nox
|
||||
import nox # type: ignore[import-not-found]
|
||||
|
||||
# Whether the noxfile is running in CI:
|
||||
IN_CI = os.environ.get("CI") == "true"
|
||||
|
||||
|
||||
try:
|
||||
import antsibull_nox
|
||||
import antsibull_nox # type: ignore[import-not-found]
|
||||
except ImportError:
|
||||
print("You need to install antsibull-nox in the same Python environment as nox.")
|
||||
sys.exit(1)
|
||||
|
||||
@@ -7,10 +7,10 @@ from __future__ import annotations
|
||||
import time
|
||||
import typing as t
|
||||
|
||||
from ansible.plugins.action import ActionBase
|
||||
from ansible.errors import AnsibleActionFail, AnsibleConnectionFailure
|
||||
from ansible.utils.vars import merge_hash
|
||||
from ansible.plugins.action import ActionBase
|
||||
from ansible.utils.display import Display
|
||||
from ansible.utils.vars import merge_hash
|
||||
|
||||
display = Display()
|
||||
|
||||
|
||||
@@ -6,12 +6,11 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
import typing as t
|
||||
|
||||
from ansible.errors import AnsibleError, AnsibleConnectionFailure
|
||||
from ansible.module_utils.common.text.converters import to_native, to_text
|
||||
from ansible.errors import AnsibleConnectionFailure, AnsibleError
|
||||
from ansible.module_utils.common.collections import is_string
|
||||
from ansible.module_utils.common.text.converters import to_native, to_text
|
||||
from ansible.plugins.action import ActionBase
|
||||
from ansible.utils.display import Display
|
||||
|
||||
|
||||
@@ -92,9 +92,8 @@ EXAMPLES = r"""
|
||||
|
||||
from re import compile as re_compile
|
||||
|
||||
from ansible.plugins.become import BecomeBase
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
|
||||
from ansible.plugins.become import BecomeBase
|
||||
|
||||
ansi_color_codes = re_compile(to_bytes(r"\x1B\[[0-9;]+m"))
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ notes:
|
||||
"""
|
||||
|
||||
from shlex import quote as shlex_quote
|
||||
|
||||
from ansible.plugins.become import BecomeBase
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
DOCUMENTATION = r"""
|
||||
name: run0
|
||||
short_description: Systemd's run0
|
||||
@@ -78,8 +77,8 @@ EXAMPLES = r"""
|
||||
|
||||
from re import compile as re_compile
|
||||
|
||||
from ansible.plugins.become import BecomeBase
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
from ansible.plugins.become import BecomeBase
|
||||
|
||||
ansi_color_codes = re_compile(to_bytes(r"\x1B\[[0-9;]+m"))
|
||||
|
||||
|
||||
4
plugins/cache/memcached.py
vendored
4
plugins/cache/memcached.py
vendored
@@ -49,11 +49,11 @@ options:
|
||||
import collections
|
||||
import os
|
||||
import time
|
||||
from multiprocessing import Lock
|
||||
from collections.abc import MutableSet
|
||||
from itertools import chain
|
||||
from multiprocessing import Lock
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from collections.abc import MutableSet
|
||||
from ansible.plugins.cache import BaseCacheModule
|
||||
from ansible.utils.display import Display
|
||||
|
||||
|
||||
6
plugins/cache/redis.py
vendored
6
plugins/cache/redis.py
vendored
@@ -66,17 +66,17 @@ options:
|
||||
section: defaults
|
||||
"""
|
||||
|
||||
import json
|
||||
import re
|
||||
import time
|
||||
import json
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.parsing.ajson import AnsibleJSONEncoder, AnsibleJSONDecoder
|
||||
from ansible.parsing.ajson import AnsibleJSONDecoder, AnsibleJSONEncoder
|
||||
from ansible.plugins.cache import BaseCacheModule
|
||||
from ansible.utils.display import Display
|
||||
|
||||
try:
|
||||
from redis import StrictRedis, VERSION
|
||||
from redis import VERSION, StrictRedis
|
||||
|
||||
HAS_REDIS = True
|
||||
except ImportError:
|
||||
|
||||
5
plugins/cache/yaml.py
vendored
5
plugins/cache/yaml.py
vendored
@@ -46,9 +46,8 @@ options:
|
||||
import os
|
||||
|
||||
import yaml
|
||||
|
||||
from ansible.parsing.yaml.loader import AnsibleLoader
|
||||
from ansible.parsing.yaml.dumper import AnsibleDumper
|
||||
from ansible.parsing.yaml.loader import AnsibleLoader
|
||||
from ansible.plugins.cache import BaseFileCacheModule
|
||||
|
||||
|
||||
@@ -58,7 +57,7 @@ class CacheModule(BaseFileCacheModule):
|
||||
"""
|
||||
|
||||
def _load(self, filepath):
|
||||
with open(os.path.abspath(filepath), "r", encoding="utf-8") as f:
|
||||
with open(os.path.abspath(filepath), encoding="utf-8") as f:
|
||||
return AnsibleLoader(f).get_single_data()
|
||||
|
||||
def _dump(self, value, filepath):
|
||||
|
||||
@@ -41,8 +41,8 @@ options:
|
||||
key: cur_mem_file
|
||||
"""
|
||||
|
||||
import time
|
||||
import threading
|
||||
import time
|
||||
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
|
||||
|
||||
@@ -23,9 +23,9 @@ requirements:
|
||||
"""
|
||||
|
||||
from ansible import constants as C
|
||||
from ansible.playbook.task_include import TaskInclude
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
from ansible.utils.color import colorize, hostcolor
|
||||
from ansible.playbook.task_include import TaskInclude
|
||||
|
||||
|
||||
class CallbackModule(CallbackBase):
|
||||
|
||||
@@ -27,13 +27,13 @@ try:
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
import sys
|
||||
from collections.abc import MutableMapping, MutableSequence
|
||||
|
||||
from ansible.plugins.callback.default import CallbackModule as CallbackModule_default
|
||||
from ansible.utils.color import colorize, hostcolor
|
||||
from ansible.utils.display import Display
|
||||
|
||||
import sys
|
||||
|
||||
display = Display()
|
||||
|
||||
|
||||
|
||||
@@ -778,10 +778,11 @@ playbook.yml: >-
|
||||
|
||||
import sys
|
||||
from contextlib import contextmanager
|
||||
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.plugins.callback.default import CallbackModule as Default
|
||||
from ansible.template import Templar
|
||||
from ansible.vars.manager import VariableManager
|
||||
from ansible.plugins.callback.default import CallbackModule as Default
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
|
||||
try:
|
||||
from ansible.template import trust_as_template # noqa: F401, pylint: disable=unused-import
|
||||
|
||||
@@ -81,7 +81,6 @@ import getpass
|
||||
import socket
|
||||
import time
|
||||
import uuid
|
||||
|
||||
from collections import OrderedDict
|
||||
from contextlib import closing
|
||||
from os.path import basename
|
||||
@@ -92,7 +91,7 @@ from ansible.plugins.callback import CallbackBase
|
||||
|
||||
ELASTIC_LIBRARY_IMPORT_ERROR: ImportError | None
|
||||
try:
|
||||
from elasticapm import Client, capture_span, trace_parent_from_string, instrument, label
|
||||
from elasticapm import Client, capture_span, instrument, label, trace_parent_from_string
|
||||
except ImportError as imp_exc:
|
||||
ELASTIC_LIBRARY_IMPORT_ERROR = imp_exc
|
||||
else:
|
||||
|
||||
@@ -27,16 +27,15 @@ options:
|
||||
key: log_folder
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import time
|
||||
import json
|
||||
|
||||
from ansible.utils.path import makedirs_safe
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
from collections.abc import MutableMapping
|
||||
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
from ansible.parsing.ajson import AnsibleJSONEncoder
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
|
||||
from ansible.utils.path import makedirs_safe
|
||||
|
||||
# NOTE: in Ansible 1.2 or later general logging is available without
|
||||
# this plugin, just set ANSIBLE_LOG_PATH as an environment variable
|
||||
|
||||
@@ -51,14 +51,13 @@ examples: |-
|
||||
shared_key = dZD0kCbKl3ehZG6LHFMuhtE0yHiFCmetzFMc2u+roXIUQuatqU924SsAAAAPemhjbGlAemhjbGktTUJQAQIDBA==
|
||||
"""
|
||||
|
||||
import base64
|
||||
import getpass
|
||||
import hashlib
|
||||
import hmac
|
||||
import base64
|
||||
import json
|
||||
import uuid
|
||||
import socket
|
||||
import getpass
|
||||
|
||||
import uuid
|
||||
from os.path import basename
|
||||
|
||||
from ansible.module_utils.ansible_release import __version__ as ansible_version
|
||||
|
||||
340
plugins/callback/loganalytics_ingestion.py
Normal file
340
plugins/callback/loganalytics_ingestion.py
Normal file
@@ -0,0 +1,340 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright (c) Ansible project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
DOCUMENTATION = """
|
||||
name: loganalytics_ingestion
|
||||
type: notification
|
||||
short_description: Posts task results to an Azure Log Analytics workspace using the new Logs Ingestion API
|
||||
author:
|
||||
- Wade Cline (@wtcline-intc) <wade.cline@intel.com>
|
||||
- Sriramoju Vishal Bharath (@vsh47) <sriramoju.vishal.bharath@intel.com>
|
||||
- Cyrus Li (@zhcli) <cyrus1006@gmail.com>
|
||||
description:
|
||||
- This callback plugin will post task results in JSON format to an Azure Log Analytics workspace using the new Logs Ingestion API.
|
||||
version_added: "12.4.0"
|
||||
requirements:
|
||||
- The callback plugin has been enabled.
|
||||
- An Azure Log Analytics workspace has been established.
|
||||
- A Data Collection Rule (DCR) and custom table are created.
|
||||
options:
|
||||
dce_url:
|
||||
description: URL of the Data Collection Endpoint (DCE) for Azure Logs Ingestion API.
|
||||
type: str
|
||||
required: true
|
||||
env:
|
||||
- name: ANSIBLE_LOGANALYTICS_DCE_URL
|
||||
ini:
|
||||
- section: callback_loganalytics
|
||||
key: dce_url
|
||||
dcr_id:
|
||||
description: Data Collection Rule (DCR) ID for the Azure Log Ingestion API.
|
||||
type: str
|
||||
required: true
|
||||
env:
|
||||
- name: ANSIBLE_LOGANALYTICS_DCR_ID
|
||||
ini:
|
||||
- section: callback_loganalytics
|
||||
key: dcr_id
|
||||
disable_attempts:
|
||||
description:
|
||||
- When O(disable_on_failure=true), number of plugin failures that must occur before the plugin is disabled.
|
||||
- This helps prevent outright plugin failure from a single, transient network issue.
|
||||
type: int
|
||||
default: 3
|
||||
env:
|
||||
- name: ANSIBLE_LOGANALYTICS_DISABLE_ATTEMPTS
|
||||
ini:
|
||||
- section: callback_loganalytics
|
||||
key: disable_attempts
|
||||
disable_on_failure:
|
||||
description: Stop trying to send data on plugin failure.
|
||||
type: bool
|
||||
default: true
|
||||
env:
|
||||
- name: ANSIBLE_LOGANALYTICS_DISABLE_ON_FAILURE
|
||||
ini:
|
||||
- section: callback_loganalytics
|
||||
key: disable_on_failure
|
||||
client_id:
|
||||
description: Client ID of the Azure App registration for OAuth2 authentication ("Modern Authentication").
|
||||
type: str
|
||||
required: true
|
||||
env:
|
||||
- name: ANSIBLE_LOGANALYTICS_CLIENT_ID
|
||||
ini:
|
||||
- section: callback_loganalytics
|
||||
key: client_id
|
||||
client_secret:
|
||||
description: Client Secret of the Azure App registration.
|
||||
type: str
|
||||
required: true
|
||||
env:
|
||||
- name: ANSIBLE_LOGANALYTICS_CLIENT_SECRET
|
||||
ini:
|
||||
- section: callback_loganalytics
|
||||
key: client_secret
|
||||
include_content:
|
||||
description: Send the content to the Azure Log Analytics workspace.
|
||||
type: bool
|
||||
default: false
|
||||
env:
|
||||
- name: ANSIBLE_LOGANALYTICS_INCLUDE_CONTENT
|
||||
ini:
|
||||
- section: callback_loganalytics
|
||||
key: include_content
|
||||
include_task_args:
|
||||
description: Send the task args to the Azure Log Analytics workspace.
|
||||
type: bool
|
||||
default: false
|
||||
env:
|
||||
- name: ANSIBLE_LOGANALYTICS_INCLUDE_TASK_ARGS
|
||||
ini:
|
||||
- section: callback_loganalytics
|
||||
key: include_task_args
|
||||
stream_name:
|
||||
description: The name of the stream used to send the logs to the Azure Log Analytics workspace.
|
||||
type: str
|
||||
required: true
|
||||
env:
|
||||
- name: ANSIBLE_LOGANALYTICS_STREAM_NAME
|
||||
ini:
|
||||
- section: callback_loganalytics
|
||||
key: stream_name
|
||||
tenant_id:
|
||||
description: Tenant ID for the Azure Active Directory.
|
||||
type: str
|
||||
required: true
|
||||
env:
|
||||
- name: ANSIBLE_LOGANALYTICS_TENANT_ID
|
||||
ini:
|
||||
- section: callback_loganalytics
|
||||
key: tenant_id
|
||||
timeout:
|
||||
description: Timeout for the HTTP requests to the Azure Log Analytics API.
|
||||
type: int
|
||||
default: 2
|
||||
env:
|
||||
- name: ANSIBLE_LOGANALYTICS_TIMEOUT
|
||||
ini:
|
||||
- section: callback_loganalytics
|
||||
key: timeout
|
||||
seealso:
|
||||
- name: Logs Ingestion API
|
||||
description: Overview of Logs Ingestion API in Azure Monitor
|
||||
link: https://learn.microsoft.com/en-us/azure/azure-monitor/logs/logs-ingestion-api-overview
|
||||
notes:
|
||||
- Triple verbosity logging (C(-vvv)) can be used to generate JSON sample data for creating the table schema in Azure Log Analytics.
|
||||
Search for the string C(Event Data:) in the output in order to locate the data sample.
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
examples: |
|
||||
Enable the plugin in ansible.cfg:
|
||||
[defaults]
|
||||
callback_enabled = community.general.loganalytics_ingestion
|
||||
Set the environment variables:
|
||||
export ANSIBLE_LOGANALYTICS_DCE_URL=https://my-dce.ingest.monitor.azure.com
|
||||
export ANSIBLE_LOGANALYTICS_DCR_ID=dcr-xxxxxx
|
||||
export ANSIBLE_LOGANALYTICS_CLIENT_ID=xxxxxxxx
|
||||
export ANSIBLE_LOGANALYTICS_CLIENT_SECRET=xxxxxxxx
|
||||
export ANSIBLE_LOGANALYTICS_TENANT_ID=xxxxxxxx
|
||||
export ANSIBLE_LOGANALYTICS_STREAM_NAME=Custom-MyTable
|
||||
"""
|
||||
|
||||
import getpass
|
||||
import json
|
||||
import socket
|
||||
import uuid
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from os.path import basename
|
||||
from urllib.parse import urlencode
|
||||
|
||||
from ansible.module_utils.urls import open_url
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
from ansible.utils.display import Display
|
||||
|
||||
display = Display()
|
||||
|
||||
|
||||
class AzureLogAnalyticsIngestionSource:
|
||||
def __init__(
|
||||
self,
|
||||
dce_url,
|
||||
dcr_id,
|
||||
disable_attempts,
|
||||
disable_on_failure,
|
||||
client_id,
|
||||
client_secret,
|
||||
tenant_id,
|
||||
stream_name,
|
||||
include_task_args,
|
||||
include_content,
|
||||
timeout,
|
||||
fqcn,
|
||||
):
|
||||
self.dce_url = dce_url
|
||||
self.dcr_id = dcr_id
|
||||
self.disabled = False
|
||||
self.disable_attempts = disable_attempts
|
||||
self.disable_on_failure = disable_on_failure
|
||||
self.client_id = client_id
|
||||
self.client_secret = client_secret
|
||||
self.failures = 0
|
||||
self.tenant_id = tenant_id
|
||||
self.stream_name = stream_name
|
||||
self.include_task_args = include_task_args
|
||||
self.include_content = include_content
|
||||
self.token_expiration_time = None
|
||||
self.session = str(uuid.uuid4())
|
||||
self.host = socket.gethostname()
|
||||
self.user = getpass.getuser()
|
||||
self.timeout = timeout
|
||||
self.fqcn = fqcn
|
||||
|
||||
self.bearer_token = self.get_bearer_token()
|
||||
|
||||
# OAuth2 authentication method to get a Bearer token
|
||||
# This replaces the shared_key authentication mechanism
|
||||
def get_bearer_token(self):
|
||||
url = f"https://login.microsoftonline.com/{self.tenant_id}/oauth2/v2.0/token"
|
||||
headers = {"Content-Type": "application/x-www-form-urlencoded"}
|
||||
data = urlencode(
|
||||
{
|
||||
"grant_type": "client_credentials",
|
||||
"client_id": self.client_id,
|
||||
"client_secret": self.client_secret,
|
||||
# The scope value comes from https://learn.microsoft.com/en-us/azure/azure-monitor/logs/logs-ingestion-api-overview#headers
|
||||
# and https://learn.microsoft.com/en-us/entra/identity-platform/scopes-oidc#the-default-scope
|
||||
"scope": "https://monitor.azure.com/.default",
|
||||
}
|
||||
)
|
||||
response = open_url(url, data=data, force=True, headers=headers, method="POST", timeout=self.timeout)
|
||||
j = json.loads(response.read().decode("utf-8"))
|
||||
self.token_expiration_time = datetime.now() + timedelta(seconds=j.get("expires_in"))
|
||||
return j.get("access_token")
|
||||
|
||||
def is_token_valid(self):
|
||||
return datetime.now() + timedelta(seconds=10) < self.token_expiration_time
|
||||
|
||||
# Method to send event data to the Azure Logs Ingestion API
|
||||
# This replaces the legacy API call and now uses the Logs Ingestion API endpoint
|
||||
def send_event(self, event_data):
|
||||
if not self.is_token_valid():
|
||||
self.bearer_token = self.get_bearer_token()
|
||||
ingestion_url = (
|
||||
f"{self.dce_url}/dataCollectionRules/{self.dcr_id}/streams/{self.stream_name}?api-version=2023-01-01"
|
||||
)
|
||||
headers = {"Authorization": f"Bearer {self.bearer_token}", "Content-Type": "application/json"}
|
||||
open_url(ingestion_url, data=json.dumps(event_data), headers=headers, method="POST", timeout=self.timeout)
|
||||
|
||||
def _rfc1123date(self):
|
||||
return datetime.now(timezone.utc).strftime("%a, %d %b %Y %H:%M:%S GMT")
|
||||
|
||||
# This method wraps the private method with the appropriate error handling.
|
||||
def send_to_loganalytics(self, playbook_name, result, state):
|
||||
if self.disabled:
|
||||
return
|
||||
try:
|
||||
self._send_to_loganalytics(playbook_name, result, state)
|
||||
except Exception as e:
|
||||
display.warning(f"{self.fqcn} callback plugin failure: {e}.")
|
||||
if self.disable_on_failure:
|
||||
self.failures += 1
|
||||
if self.failures >= self.disable_attempts:
|
||||
display.warning(
|
||||
f"{self.fqcn} callback plugin failures exceed maximum of '{self.disable_attempts}'! Disabling plugin!"
|
||||
)
|
||||
self.disabled = True
|
||||
else:
|
||||
display.v(f"{self.fqcn} callback plugin failure {self.failures}/{self.disable_attempts}")
|
||||
|
||||
def _send_to_loganalytics(self, playbook_name, result, state):
|
||||
ansible_role = str(result._task._role) if result._task._role else None
|
||||
|
||||
# Include/Exclude task args
|
||||
if not self.include_task_args:
|
||||
result._task_fields.pop("args", None)
|
||||
|
||||
# Include/Exclude content
|
||||
if not self.include_content:
|
||||
result._result.pop("content", None)
|
||||
|
||||
# Build the event data
|
||||
event_data = [
|
||||
{
|
||||
"TimeGenerated": self._rfc1123date(),
|
||||
"Host": result._host.name,
|
||||
"User": self.user,
|
||||
"Playbook": playbook_name,
|
||||
"Role": ansible_role,
|
||||
"TaskName": result._task.get_name(),
|
||||
"Task": result._task_fields,
|
||||
"Action": result._task_fields["action"],
|
||||
"State": state,
|
||||
"Result": result._result,
|
||||
"Session": self.session,
|
||||
}
|
||||
]
|
||||
|
||||
# The data displayed here can be used as a sample file in order to create the table's schema.
|
||||
display.vvv(f"Event Data: {json.dumps(event_data)}")
|
||||
|
||||
self.send_event(event_data)
|
||||
|
||||
|
||||
class CallbackModule(CallbackBase):
|
||||
CALLBACK_VERSION = 2.0
|
||||
CALLBACK_TYPE = "notification"
|
||||
CALLBACK_NAME = "loganalytics_ingestion"
|
||||
CALLBACK_NEEDS_ENABLED = True
|
||||
|
||||
def __init__(self, display=None):
|
||||
super().__init__(display=display)
|
||||
self.start_datetimes = {}
|
||||
self.playbook_name = None
|
||||
self.azure_loganalytics = None
|
||||
self.fqcn = f"community.general.{self.CALLBACK_NAME}"
|
||||
|
||||
def set_options(self, task_keys=None, var_options=None, direct=None):
|
||||
super().set_options(task_keys=task_keys, var_options=var_options, direct=direct)
|
||||
|
||||
# Set options for the new Azure Logs Ingestion API configuration
|
||||
self.client_id = self.get_option("client_id")
|
||||
self.client_secret = self.get_option("client_secret")
|
||||
self.dce_url = self.get_option("dce_url")
|
||||
self.dcr_id = self.get_option("dcr_id")
|
||||
self.disable_attempts = self.get_option("disable_attempts")
|
||||
self.disable_on_failure = self.get_option("disable_on_failure")
|
||||
self.include_content = self.get_option("include_content")
|
||||
self.include_task_args = self.get_option("include_task_args")
|
||||
self.stream_name = self.get_option("stream_name")
|
||||
self.tenant_id = self.get_option("tenant_id")
|
||||
self.timeout = self.get_option("timeout")
|
||||
|
||||
# Initialize the AzureLogAnalyticsIngestionSource with the new settings
|
||||
self.azure_loganalytics = AzureLogAnalyticsIngestionSource(
|
||||
self.dce_url,
|
||||
self.dcr_id,
|
||||
self.disable_attempts,
|
||||
self.disable_on_failure,
|
||||
self.client_id,
|
||||
self.client_secret,
|
||||
self.tenant_id,
|
||||
self.stream_name,
|
||||
self.include_task_args,
|
||||
self.include_content,
|
||||
self.timeout,
|
||||
self.fqcn,
|
||||
)
|
||||
|
||||
def v2_playbook_on_start(self, playbook):
|
||||
self.playbook_name = basename(playbook._file_name)
|
||||
|
||||
# Build event data and send it to the Logs Ingestion API
|
||||
def v2_runner_on_failed(self, result, **kwargs):
|
||||
self.azure_loganalytics.send_to_loganalytics(self.playbook_name, result, "FAILED")
|
||||
|
||||
def v2_runner_on_ok(self, result, **kwargs):
|
||||
self.azure_loganalytics.send_to_loganalytics(self.playbook_name, result, "OK")
|
||||
@@ -55,12 +55,13 @@ options:
|
||||
default: ansible
|
||||
"""
|
||||
|
||||
import logging
|
||||
import json
|
||||
import logging
|
||||
import socket
|
||||
from uuid import getnode
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
|
||||
from ansible.parsing.ajson import AnsibleJSONEncoder
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
|
||||
try:
|
||||
from logdna import LogDNAHandler
|
||||
|
||||
@@ -96,8 +96,8 @@ examples: >-
|
||||
"""
|
||||
|
||||
import os
|
||||
import socket
|
||||
import random
|
||||
import socket
|
||||
import time
|
||||
import uuid
|
||||
|
||||
@@ -178,7 +178,7 @@ class PlainTextSocketAppender:
|
||||
while True:
|
||||
try:
|
||||
self._conn.send(to_bytes(multiline, errors="surrogate_or_strict"))
|
||||
except socket.error:
|
||||
except OSError:
|
||||
self.reopen_connection()
|
||||
continue
|
||||
break
|
||||
|
||||
@@ -94,12 +94,13 @@ ansible.cfg: |
|
||||
}
|
||||
"""
|
||||
|
||||
import os
|
||||
import json
|
||||
from ansible import context
|
||||
import logging
|
||||
import os
|
||||
import socket
|
||||
import uuid
|
||||
import logging
|
||||
|
||||
from ansible import context
|
||||
|
||||
try:
|
||||
import logstash
|
||||
|
||||
@@ -79,10 +79,10 @@ options:
|
||||
version_added: 8.2.0
|
||||
"""
|
||||
|
||||
import email.utils
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import email.utils
|
||||
import smtplib
|
||||
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
|
||||
@@ -148,15 +148,15 @@ from ansible.plugins.callback import CallbackBase
|
||||
OTEL_LIBRARY_IMPORT_ERROR: ImportError | None
|
||||
try:
|
||||
from opentelemetry import trace
|
||||
from opentelemetry.trace import SpanKind
|
||||
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter as GRPCOTLPSpanExporter
|
||||
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter as HTTPOTLPSpanExporter
|
||||
from opentelemetry.sdk.resources import SERVICE_NAME, Resource
|
||||
from opentelemetry.trace.status import Status, StatusCode
|
||||
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
|
||||
from opentelemetry.sdk.trace import TracerProvider
|
||||
from opentelemetry.sdk.trace.export import BatchSpanProcessor, SimpleSpanProcessor
|
||||
from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter
|
||||
from opentelemetry.trace import SpanKind
|
||||
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
|
||||
from opentelemetry.trace.status import Status, StatusCode
|
||||
except ImportError as imp_exc:
|
||||
OTEL_LIBRARY_IMPORT_ERROR = imp_exc
|
||||
else:
|
||||
|
||||
@@ -22,7 +22,7 @@ ansible.cfg: |-
|
||||
callbacks_enabled=community.general.print_task
|
||||
"""
|
||||
|
||||
from yaml import load, dump
|
||||
from yaml import dump, load
|
||||
|
||||
try:
|
||||
from yaml import CSafeDumper as SafeDumper
|
||||
|
||||
@@ -18,9 +18,9 @@ description:
|
||||
- This plugin uses C(say) or C(espeak) to "speak" about play events.
|
||||
"""
|
||||
|
||||
import os
|
||||
import platform
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
from ansible.module_utils.common.process import get_bin_path
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
|
||||
@@ -39,9 +39,8 @@ EXAMPLES = r"""
|
||||
import difflib
|
||||
|
||||
from ansible import constants as C
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
|
||||
DONT_COLORIZE = False
|
||||
COLORS = {
|
||||
|
||||
@@ -83,11 +83,10 @@ examples: >-
|
||||
authtoken = f23blad6-5965-4537-bf69-5b5a545blabla88
|
||||
"""
|
||||
|
||||
import json
|
||||
import uuid
|
||||
import socket
|
||||
import getpass
|
||||
|
||||
import json
|
||||
import socket
|
||||
import uuid
|
||||
from os.path import basename
|
||||
|
||||
from ansible.module_utils.ansible_release import __version__ as ansible_version
|
||||
@@ -255,7 +254,7 @@ class CallbackModule(CallbackBase):
|
||||
self._runtime(result),
|
||||
)
|
||||
|
||||
def runner_on_async_failed(self, result, **kwargs):
|
||||
def v2_runner_on_async_failed(self, result, **kwargs):
|
||||
self.splunk.send_event(
|
||||
self.url,
|
||||
self.authtoken,
|
||||
|
||||
@@ -40,11 +40,10 @@ examples: |-
|
||||
url = https://endpoint1.collection.us2.sumologic.com/receiver/v1/http/R8moSv1d8EW9LAUFZJ6dbxCFxwLH6kfCdcBfddlfxCbLuL-BN5twcTpMk__pYy_cDmp==
|
||||
"""
|
||||
|
||||
import json
|
||||
import uuid
|
||||
import socket
|
||||
import getpass
|
||||
|
||||
import json
|
||||
import socket
|
||||
import uuid
|
||||
from os.path import basename
|
||||
|
||||
from ansible.module_utils.ansible_release import __version__ as ansible_version
|
||||
|
||||
@@ -56,7 +56,6 @@ options:
|
||||
|
||||
import logging
|
||||
import logging.handlers
|
||||
|
||||
import socket
|
||||
|
||||
from ansible.plugins.callback import CallbackBase
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
DOCUMENTATION = r"""
|
||||
name: timestamp
|
||||
type: stdout
|
||||
@@ -49,12 +48,13 @@ extends_documentation_fragment:
|
||||
"""
|
||||
|
||||
|
||||
import sys
|
||||
import types
|
||||
from datetime import datetime
|
||||
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.plugins.callback.default import CallbackModule as Default
|
||||
from ansible.utils.display import get_text_width
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from datetime import datetime
|
||||
import types
|
||||
import sys
|
||||
|
||||
# Store whether the zoneinfo module is available
|
||||
_ZONEINFO_AVAILABLE = sys.version_info >= (3, 9)
|
||||
@@ -89,7 +89,7 @@ def banner(self, msg, color=None, cows=True):
|
||||
msg = msg.strip()
|
||||
try:
|
||||
star_len = self.columns - get_text_width(msg) - timestamp_len
|
||||
except EnvironmentError:
|
||||
except OSError:
|
||||
star_len = self.columns - len(msg) - timestamp_len
|
||||
if star_len <= 3:
|
||||
star_len = 3
|
||||
|
||||
@@ -20,11 +20,12 @@ requirements:
|
||||
"""
|
||||
|
||||
from os.path import basename
|
||||
|
||||
from ansible import constants as C
|
||||
from ansible import context
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.utils.color import colorize, hostcolor
|
||||
from ansible.plugins.callback.default import CallbackModule as CallbackModule_default
|
||||
from ansible.utils.color import colorize, hostcolor
|
||||
|
||||
|
||||
class CallbackModule(CallbackModule_default):
|
||||
|
||||
@@ -80,7 +80,7 @@ from ansible.errors import AnsibleError
|
||||
from ansible.module_utils.basic import is_executable
|
||||
from ansible.module_utils.common.process import get_bin_path
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
from ansible.plugins.connection import ConnectionBase, BUFSIZE
|
||||
from ansible.plugins.connection import BUFSIZE, ConnectionBase
|
||||
from ansible.utils.display import Display
|
||||
|
||||
display = Display()
|
||||
@@ -200,7 +200,7 @@ class Connection(ConnectionBase):
|
||||
raise AnsibleError(f"failed to transfer file {in_path} to {out_path}") from e
|
||||
if p.returncode != 0:
|
||||
raise AnsibleError(f"failed to transfer file {in_path} to {out_path}:\n{stdout}\n{stderr}")
|
||||
except IOError as e:
|
||||
except OSError as e:
|
||||
raise AnsibleError(f"file or module does not exist at: {in_path}") from e
|
||||
|
||||
def fetch_file(self, in_path, out_path):
|
||||
|
||||
@@ -35,8 +35,8 @@ except ImportError:
|
||||
pass
|
||||
|
||||
import os
|
||||
import tempfile
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.plugins.connection import ConnectionBase
|
||||
|
||||
@@ -79,9 +79,9 @@ options:
|
||||
|
||||
import os
|
||||
import re
|
||||
from subprocess import call, Popen, PIPE
|
||||
from subprocess import PIPE, Popen, call
|
||||
|
||||
from ansible.errors import AnsibleError, AnsibleConnectionFailure, AnsibleFileNotFound
|
||||
from ansible.errors import AnsibleConnectionFailure, AnsibleError, AnsibleFileNotFound
|
||||
from ansible.module_utils.common.process import get_bin_path
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
||||
from ansible.plugins.connection import ConnectionBase
|
||||
@@ -104,11 +104,11 @@ class Connection(ConnectionBase):
|
||||
if getattr(self._shell, "_IS_WINDOWS", False):
|
||||
# Initializing regular expression patterns to match on a PowerShell or cmd command line.
|
||||
self.powershell_regex_pattern = re.compile(
|
||||
r"^(?P<executable>(\"?([a-z]:)?[a-z0-9 ()\\.]+)?powershell(\.exe)?\"?|(([a-z]:)?[a-z0-9()\\.]+)?powershell(\.exe)?)\s+.*(?P<command>-c(ommand)?)\s+", # noqa: E501
|
||||
r'^"?(?P<executable>(?:[a-z]:\\)?[a-z0-9 ()\\.]*powershell(?:\.exe)?)"?\s+(?P<args>.*)(?P<command>-c(?:ommand)?)\s+(?P<post_args>.*(\n.*)*)',
|
||||
re.IGNORECASE,
|
||||
)
|
||||
self.cmd_regex_pattern = re.compile(
|
||||
r"^(?P<executable>(\"?([a-z]:)?[a-z0-9 ()\\.]+)?cmd(\.exe)?\"?|(([a-z]:)?[a-z0-9()\\.]+)?cmd(\.exe)?)\s+.*(?P<command>/c)\s+",
|
||||
r'^"?(?P<executable>(?:[a-z]:\\)?[a-z0-9 ()\\.]*cmd(?:\.exe)?)"?\s+(?P<args>.*)(?P<command>/c)\s+(?P<post_args>.*)',
|
||||
re.IGNORECASE,
|
||||
)
|
||||
|
||||
@@ -142,30 +142,25 @@ class Connection(ConnectionBase):
|
||||
]
|
||||
|
||||
if getattr(self._shell, "_IS_WINDOWS", False):
|
||||
if (
|
||||
(regex_match := self.powershell_regex_pattern.match(cmd))
|
||||
and (regex_pattern := self.powershell_regex_pattern)
|
||||
) or ((regex_match := self.cmd_regex_pattern.match(cmd)) and (regex_pattern := self.cmd_regex_pattern)):
|
||||
if regex_match := self.powershell_regex_pattern.match(cmd):
|
||||
regex_pattern = self.powershell_regex_pattern
|
||||
elif regex_match := self.cmd_regex_pattern.match(cmd):
|
||||
regex_pattern = self.cmd_regex_pattern
|
||||
|
||||
if regex_match:
|
||||
self._display.vvvvvv(
|
||||
f'Found keyword: "{regex_match.group("command")}" based on regex: {regex_pattern.pattern}',
|
||||
host=self._instance(),
|
||||
)
|
||||
|
||||
# Split the command on the argument -c(ommand) for PowerShell or /c for cmd.
|
||||
before_command_argument, after_command_argument = cmd.split(regex_match.group("command"), 1)
|
||||
|
||||
exec_cmd.extend(
|
||||
[
|
||||
# To avoid splitting on a space contained in the path, set the executable as the first argument.
|
||||
regex_match.group("executable").strip('"'),
|
||||
# Remove the executable path and split the rest by space.
|
||||
*(before_command_argument[len(regex_match.group("executable")) :].lstrip().split(" ")),
|
||||
# Set the command argument depending on cmd or powershell.
|
||||
regex_match.group("command"),
|
||||
# Add the rest of the command at the end.
|
||||
after_command_argument,
|
||||
]
|
||||
)
|
||||
# To avoid splitting on a space contained in the path, set the executable as the first argument.
|
||||
exec_cmd.append(regex_match.group("executable"))
|
||||
if args := regex_match.group("args"):
|
||||
exec_cmd.extend(args.strip().split(" "))
|
||||
# Set the command argument depending on cmd or powershell and the rest of it
|
||||
exec_cmd.append(regex_match.group("command"))
|
||||
if post_args := regex_match.group("post_args"):
|
||||
exec_cmd.append(post_args.strip())
|
||||
else:
|
||||
# For anything else using -EncodedCommand or else, just split on space.
|
||||
exec_cmd.extend(cmd.split(" "))
|
||||
|
||||
@@ -33,11 +33,12 @@ options:
|
||||
|
||||
import subprocess
|
||||
|
||||
from ansible_collections.community.general.plugins.connection.jail import Connection as Jail
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
from ansible.utils.display import Display
|
||||
|
||||
from ansible_collections.community.general.plugins.connection.jail import Connection as Jail
|
||||
|
||||
display = Display()
|
||||
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ from shlex import quote as shlex_quote
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.module_utils.common.process import get_bin_path
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
||||
from ansible.plugins.connection import ConnectionBase, BUFSIZE
|
||||
from ansible.plugins.connection import BUFSIZE, ConnectionBase
|
||||
from ansible.utils.display import Display
|
||||
|
||||
display = Display()
|
||||
@@ -172,7 +172,7 @@ class Connection(ConnectionBase):
|
||||
raise AnsibleError(
|
||||
f"failed to transfer file {in_path} to {out_path}:\n{to_native(stdout)}\n{to_native(stderr)}"
|
||||
)
|
||||
except IOError as e:
|
||||
except OSError as e:
|
||||
raise AnsibleError(f"file or module does not exist at: {in_path}") from e
|
||||
|
||||
def fetch_file(self, in_path, out_path):
|
||||
|
||||
@@ -31,12 +31,12 @@ options:
|
||||
- name: ansible_lxc_executable
|
||||
"""
|
||||
|
||||
import errno
|
||||
import fcntl
|
||||
import os
|
||||
import select
|
||||
import shutil
|
||||
import traceback
|
||||
import select
|
||||
import fcntl
|
||||
import errno
|
||||
|
||||
HAS_LIBLXC = False
|
||||
try:
|
||||
@@ -94,7 +94,7 @@ class Connection(ConnectionBase):
|
||||
while len(read_fds) > 0 or len(write_fds) > 0:
|
||||
try:
|
||||
ready_reads, ready_writes, dummy = select.select(read_fds, write_fds, [])
|
||||
except select.error as e:
|
||||
except OSError as e:
|
||||
if e.args[0] == errno.EINTR:
|
||||
continue
|
||||
raise
|
||||
@@ -173,7 +173,7 @@ class Connection(ConnectionBase):
|
||||
raise errors.AnsibleFileNotFound(msg)
|
||||
try:
|
||||
src_file = open(in_path, "rb")
|
||||
except IOError as e:
|
||||
except OSError as e:
|
||||
traceback.print_exc()
|
||||
raise errors.AnsibleError(f"failed to open input file to {in_path}") from e
|
||||
try:
|
||||
@@ -184,7 +184,7 @@ class Connection(ConnectionBase):
|
||||
|
||||
try:
|
||||
self.container.attach_wait(write_file, None)
|
||||
except IOError as e:
|
||||
except OSError as e:
|
||||
traceback.print_exc()
|
||||
msg = f"failed to transfer file to {out_path}"
|
||||
raise errors.AnsibleError(msg) from e
|
||||
@@ -200,7 +200,7 @@ class Connection(ConnectionBase):
|
||||
|
||||
try:
|
||||
dst_file = open(out_path, "wb")
|
||||
except IOError as e:
|
||||
except OSError as e:
|
||||
traceback.print_exc()
|
||||
msg = f"failed to open output file {out_path}"
|
||||
raise errors.AnsibleError(msg) from e
|
||||
@@ -217,7 +217,7 @@ class Connection(ConnectionBase):
|
||||
|
||||
try:
|
||||
self.container.attach_wait(write_file, None)
|
||||
except IOError as e:
|
||||
except OSError as e:
|
||||
traceback.print_exc()
|
||||
msg = f"failed to transfer file from {in_path} to {out_path}"
|
||||
raise errors.AnsibleError(msg) from e
|
||||
|
||||
@@ -74,9 +74,9 @@ options:
|
||||
"""
|
||||
|
||||
import os
|
||||
from subprocess import Popen, PIPE
|
||||
from subprocess import PIPE, Popen
|
||||
|
||||
from ansible.errors import AnsibleError, AnsibleConnectionFailure, AnsibleFileNotFound
|
||||
from ansible.errors import AnsibleConnectionFailure, AnsibleError, AnsibleFileNotFound
|
||||
from ansible.module_utils.common.process import get_bin_path
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
||||
from ansible.plugins.connection import ConnectionBase
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
DOCUMENTATION = r"""
|
||||
name: qubes
|
||||
short_description: Interact with an existing QubesOS AppVM
|
||||
@@ -40,9 +39,9 @@ options:
|
||||
|
||||
import subprocess
|
||||
|
||||
from ansible.errors import AnsibleConnectionFailure
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
from ansible.plugins.connection import ConnectionBase, ensure_connect
|
||||
from ansible.errors import AnsibleConnectionFailure
|
||||
from ansible.utils.display import Display
|
||||
|
||||
display = Display()
|
||||
|
||||
@@ -16,8 +16,8 @@ description:
|
||||
- This allows you to use existing Saltstack infrastructure to connect to targets.
|
||||
"""
|
||||
|
||||
import os
|
||||
import base64
|
||||
import os
|
||||
|
||||
from ansible import errors
|
||||
from ansible.plugins.connection import ConnectionBase
|
||||
|
||||
@@ -231,6 +231,18 @@ options:
|
||||
required: true
|
||||
vars:
|
||||
- name: wsl_distribution
|
||||
wsl_remote_ssh_shell_type:
|
||||
description:
|
||||
- The shell type expected in the SSH session (not inside the WSL session).
|
||||
- See also C(ansible_shell_type).
|
||||
type: string
|
||||
choices:
|
||||
- cmd
|
||||
- powershell
|
||||
default: cmd
|
||||
vars:
|
||||
- name: wsl_remote_ssh_shell_type
|
||||
version_added: 12.2.0
|
||||
wsl_user:
|
||||
description:
|
||||
- WSL distribution user.
|
||||
@@ -312,25 +324,25 @@ import io
|
||||
import os
|
||||
import pathlib
|
||||
import shlex
|
||||
import socket
|
||||
import tempfile
|
||||
import traceback
|
||||
import typing as t
|
||||
from binascii import hexlify
|
||||
from subprocess import list2cmdline
|
||||
|
||||
from ansible.errors import (
|
||||
AnsibleAuthenticationFailure,
|
||||
AnsibleConnectionFailure,
|
||||
AnsibleError,
|
||||
)
|
||||
from ansible_collections.community.general.plugins.module_utils._filelock import FileLock, LockTimeout
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
||||
from ansible.playbook.play_context import PlayContext
|
||||
from ansible.plugins.connection import ConnectionBase
|
||||
from ansible.utils.display import Display
|
||||
from ansible.utils.path import makedirs_safe
|
||||
from binascii import hexlify
|
||||
from subprocess import list2cmdline
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils._filelock import FileLock, LockTimeout
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
|
||||
PARAMIKO_IMPORT_ERR: str | None
|
||||
try:
|
||||
@@ -475,7 +487,7 @@ class Connection(ConnectionBase):
|
||||
try:
|
||||
ssh.load_system_host_keys(ssh_known_hosts)
|
||||
break
|
||||
except IOError:
|
||||
except OSError:
|
||||
pass # file was not found, but not required to function
|
||||
except paramiko.hostkeys.InvalidHostKey as e:
|
||||
raise AnsibleConnectionFailure(f"Invalid host key: {to_text(e.line)}") from e
|
||||
@@ -578,18 +590,32 @@ class Connection(ConnectionBase):
|
||||
wsl_distribution = self.get_option("wsl_distribution")
|
||||
become = self.get_option("become")
|
||||
become_user = self.get_option("become_user")
|
||||
wsl_remote_ssh_shell_type = self.get_option("wsl_remote_ssh_shell_type")
|
||||
is_integration_test = os.getenv("_ANSIBLE_TEST_WSL_CONNECTION_PLUGIN_WAERI5TEPHEESHA2FAE8")
|
||||
if "%" in cmd:
|
||||
if wsl_remote_ssh_shell_type == "powershell":
|
||||
# there is no universal way to escape '%' here
|
||||
# if this is raised, add a workaround to allow the specific situation (if possible)
|
||||
raise AnsibleError("The command contains '%', cannot safely escape it for Powershell")
|
||||
else:
|
||||
cmd = cmd.replace("%", "^%")
|
||||
if become and become_user:
|
||||
wsl_user = become_user
|
||||
else:
|
||||
wsl_user = self.get_option("wsl_user")
|
||||
args = ["wsl.exe", "--distribution", wsl_distribution]
|
||||
args = ["wsl.exe"]
|
||||
if wsl_remote_ssh_shell_type == "powershell" and not is_integration_test:
|
||||
# Powershell stop-parsing token, treat the rest as arguments to the native command wsl.exe
|
||||
args.append("--%")
|
||||
args.extend(["--distribution", wsl_distribution])
|
||||
if wsl_user:
|
||||
args.extend(["--user", wsl_user])
|
||||
args.extend(["--"])
|
||||
args.extend(shlex.split(cmd))
|
||||
if os.getenv("_ANSIBLE_TEST_WSL_CONNECTION_PLUGIN_WAERI5TEPHEESHA2FAE8"):
|
||||
if is_integration_test:
|
||||
return shlex.join(args)
|
||||
return list2cmdline(args) # see https://github.com/python/cpython/blob/3.11/Lib/subprocess.py#L576
|
||||
else:
|
||||
return list2cmdline(args) # see https://github.com/python/cpython/blob/3.11/Lib/subprocess.py#L576
|
||||
|
||||
def exec_command(self, cmd: str, in_data: bytes | None = None, sudoable: bool = True) -> tuple[int, bytes, bytes]:
|
||||
"""run a command on inside a WSL distribution"""
|
||||
@@ -667,7 +693,7 @@ class Connection(ConnectionBase):
|
||||
elif in_data == b"":
|
||||
chan.shutdown_write()
|
||||
|
||||
except socket.timeout as e:
|
||||
except TimeoutError as e:
|
||||
raise AnsibleError(f"ssh timed out waiting for privilege escalation.\n{to_text(become_output)}") from e
|
||||
|
||||
stdout = b"".join(chan.makefile("rb", bufsize))
|
||||
|
||||
@@ -35,7 +35,7 @@ from shlex import quote as shlex_quote
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.module_utils.common.process import get_bin_path
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
from ansible.plugins.connection import ConnectionBase, BUFSIZE
|
||||
from ansible.plugins.connection import BUFSIZE, ConnectionBase
|
||||
from ansible.utils.display import Display
|
||||
|
||||
display = Display()
|
||||
@@ -169,7 +169,7 @@ class Connection(ConnectionBase):
|
||||
raise AnsibleError(f"failed to transfer file {in_path} to {out_path}") from e
|
||||
if p.returncode != 0:
|
||||
raise AnsibleError(f"failed to transfer file {in_path} to {out_path}:\n{stdout}\n{stderr}")
|
||||
except IOError as e:
|
||||
except OSError as e:
|
||||
raise AnsibleError(f"file or module does not exist at: {in_path}") from e
|
||||
|
||||
def fetch_file(self, in_path, out_path):
|
||||
|
||||
30
plugins/doc_fragments/_icinga2_api.py
Normal file
30
plugins/doc_fragments/_icinga2_api.py
Normal file
@@ -0,0 +1,30 @@
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
# SPDX-FileCopyrightText: 2026 Christoph Fiehe <christoph.fiehe@gmail.com>
|
||||
|
||||
# Note that this doc fragment is **PRIVATE** to the collection. It can have breaking changes at any time.
|
||||
# Do not use this from other collections or standalone plugins/modules!
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
class ModuleDocFragment:
|
||||
# Use together with ansible.builtin.url and icinga2_argument_spec from
|
||||
# ansible_collections.community.general.plugins.module_utils._icinga2
|
||||
DOCUMENTATION = r"""
|
||||
options:
|
||||
url:
|
||||
description:
|
||||
- URL of the Icinga 2 REST API.
|
||||
type: str
|
||||
required: true
|
||||
ca_path:
|
||||
description:
|
||||
- CA certificates bundle to use to verify the Icinga 2 server certificate.
|
||||
type: path
|
||||
timeout:
|
||||
description:
|
||||
- How long to wait for the server to send data before giving up.
|
||||
type: int
|
||||
default: 10
|
||||
"""
|
||||
@@ -41,8 +41,8 @@ EXAMPLES = r"""
|
||||
# Produces ['a', 'ab', 'abc']
|
||||
"""
|
||||
|
||||
from itertools import accumulate
|
||||
from collections.abc import Sequence
|
||||
from itertools import accumulate
|
||||
|
||||
from ansible.errors import AnsibleFilterError
|
||||
|
||||
|
||||
@@ -34,9 +34,10 @@ _value:
|
||||
type: dictionary
|
||||
"""
|
||||
|
||||
from ansible.errors import AnsibleFilterError
|
||||
from collections.abc import Sequence
|
||||
from collections import Counter
|
||||
from collections.abc import Sequence
|
||||
|
||||
from ansible.errors import AnsibleFilterError
|
||||
|
||||
|
||||
def counter(sequence):
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from ansible.errors import AnsibleFilterError
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
from ansible.module_utils.common.collections import is_string
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
|
||||
try:
|
||||
from zlib import crc32
|
||||
|
||||
@@ -80,11 +80,11 @@ _value:
|
||||
from ansible.errors import AnsibleFilterError
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.csv import (
|
||||
CSVError,
|
||||
CustomDialectFailureError,
|
||||
DialectNotAvailableError,
|
||||
initialize_dialect,
|
||||
read_csv,
|
||||
CSVError,
|
||||
DialectNotAvailableError,
|
||||
CustomDialectFailureError,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -16,6 +16,20 @@ options:
|
||||
description: A string containing an INI document.
|
||||
type: string
|
||||
required: true
|
||||
delimiters:
|
||||
description: A list of characters used as delimiters in the INI document.
|
||||
type: list
|
||||
elements: string
|
||||
default:
|
||||
- "="
|
||||
- ":"
|
||||
version_added: 12.4.0
|
||||
seealso:
|
||||
- plugin: community.general.to_ini
|
||||
plugin_type: filter
|
||||
- plugin: ansible.builtin.ini
|
||||
plugin_type: lookup
|
||||
- module: community.general.ini_file
|
||||
"""
|
||||
|
||||
EXAMPLES = r"""
|
||||
@@ -43,17 +57,21 @@ _value:
|
||||
"""
|
||||
|
||||
|
||||
from io import StringIO
|
||||
from configparser import ConfigParser
|
||||
from io import StringIO
|
||||
|
||||
from ansible.errors import AnsibleFilterError
|
||||
from ansible.module_utils.common.collections import is_sequence
|
||||
|
||||
|
||||
class IniParser(ConfigParser):
|
||||
"""Implements a configparser which is able to return a dict"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(interpolation=None)
|
||||
def __init__(self, delimiters=None):
|
||||
if delimiters is None:
|
||||
super().__init__(interpolation=None)
|
||||
else:
|
||||
super().__init__(interpolation=None, delimiters=delimiters)
|
||||
self.optionxform = str
|
||||
|
||||
def as_dict(self):
|
||||
@@ -68,13 +86,21 @@ class IniParser(ConfigParser):
|
||||
return d
|
||||
|
||||
|
||||
def from_ini(obj):
|
||||
def from_ini(obj, delimiters=None):
|
||||
"""Read the given string as INI file and return a dict"""
|
||||
|
||||
if not isinstance(obj, str):
|
||||
raise AnsibleFilterError(f"from_ini requires a str, got {type(obj)}")
|
||||
if delimiters is not None:
|
||||
if not is_sequence(delimiters):
|
||||
raise AnsibleFilterError(f"from_ini's delimiters parameter must be a sequence, got {type(delimiters)}")
|
||||
delimiters = tuple(delimiters)
|
||||
if not all(isinstance(elt, str) for elt in delimiters):
|
||||
raise AnsibleFilterError(
|
||||
f"from_ini's delimiters parameter must be a sequence of strings, got {delimiters!r}"
|
||||
)
|
||||
|
||||
parser = IniParser()
|
||||
parser = IniParser(delimiters=delimiters)
|
||||
|
||||
try:
|
||||
parser.read_file(StringIO(obj))
|
||||
|
||||
@@ -52,9 +52,10 @@ _value:
|
||||
type: dictionary
|
||||
"""
|
||||
|
||||
from ansible.errors import AnsibleFilterError
|
||||
from collections.abc import Mapping, Sequence
|
||||
|
||||
from ansible.errors import AnsibleFilterError
|
||||
|
||||
|
||||
def groupby_as_dict(sequence, attribute):
|
||||
"""
|
||||
|
||||
@@ -8,7 +8,6 @@ from ansible.errors import (
|
||||
AnsibleError,
|
||||
AnsibleFilterError,
|
||||
)
|
||||
|
||||
from ansible.module_utils.common.collections import is_sequence
|
||||
|
||||
try:
|
||||
|
||||
@@ -74,9 +74,10 @@ _value:
|
||||
type: any
|
||||
"""
|
||||
|
||||
from ansible.errors import AnsibleError, AnsibleFilterError
|
||||
import importlib
|
||||
|
||||
from ansible.errors import AnsibleError, AnsibleFilterError
|
||||
|
||||
try:
|
||||
import jc
|
||||
|
||||
|
||||
@@ -6,11 +6,10 @@ from __future__ import annotations
|
||||
|
||||
import typing as t
|
||||
from json import loads
|
||||
|
||||
from ansible.errors import AnsibleFilterError
|
||||
|
||||
|
||||
if t.TYPE_CHECKING:
|
||||
from typing import Any
|
||||
from collections.abc import Callable
|
||||
|
||||
JSONPATCH_IMPORT_ERROR: ImportError | None
|
||||
@@ -31,7 +30,7 @@ OPERATIONS_NEEDING_VALUE = ["add", "replace", "test"]
|
||||
class FilterModule:
|
||||
"""Filter plugin."""
|
||||
|
||||
def check_json_object(self, filter_name: str, object_name: str, inp: Any):
|
||||
def check_json_object(self, filter_name: str, object_name: str, inp: t.Any):
|
||||
if isinstance(inp, (str, bytes, bytearray)):
|
||||
try:
|
||||
return loads(inp)
|
||||
@@ -64,9 +63,9 @@ class FilterModule:
|
||||
inp: str | list | dict | bytes | bytearray,
|
||||
op: str,
|
||||
path: str,
|
||||
value: Any = None,
|
||||
value: t.Any = None,
|
||||
**kwargs: dict,
|
||||
) -> Any:
|
||||
) -> t.Any:
|
||||
if not HAS_LIB:
|
||||
raise AnsibleFilterError(
|
||||
"You need to install 'jsonpatch' package prior to running 'json_patch' filter"
|
||||
@@ -110,7 +109,7 @@ class FilterModule:
|
||||
operations: list,
|
||||
/,
|
||||
fail_test: bool = False,
|
||||
) -> Any:
|
||||
) -> t.Any:
|
||||
if not HAS_LIB:
|
||||
raise AnsibleFilterError(
|
||||
"You need to install 'jsonpatch' package prior to running 'json_patch_recipe' filter"
|
||||
@@ -160,7 +159,7 @@ class FilterModule:
|
||||
|
||||
return result
|
||||
|
||||
def filters(self) -> dict[str, Callable[..., Any]]:
|
||||
def filters(self) -> dict[str, Callable[..., t.Any]]:
|
||||
"""Map filter plugin names to their functions.
|
||||
|
||||
Returns:
|
||||
|
||||
@@ -194,13 +194,13 @@ _value:
|
||||
elements: dictionary
|
||||
"""
|
||||
|
||||
from ansible.errors import AnsibleFilterError
|
||||
from collections.abc import Mapping, Sequence
|
||||
from ansible.utils.vars import merge_hash
|
||||
|
||||
from collections import defaultdict
|
||||
from collections.abc import Mapping, Sequence
|
||||
from operator import itemgetter
|
||||
|
||||
from ansible.errors import AnsibleFilterError
|
||||
from ansible.utils.vars import merge_hash
|
||||
|
||||
|
||||
def list_mergeby(x, y, index, recursive=False, list_merge="replace"):
|
||||
"""Merge 2 lists by attribute 'index'. The function 'merge_hash'
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from ansible.errors import AnsibleFilterError
|
||||
|
||||
from ansible.errors import AnsibleFilterError
|
||||
|
||||
UNIT_FACTORS = {
|
||||
"ms": [],
|
||||
|
||||
@@ -16,6 +16,12 @@ options:
|
||||
description: The dictionary that should be converted to the INI format.
|
||||
type: dictionary
|
||||
required: true
|
||||
seealso:
|
||||
- plugin: ansible.builtin.ini
|
||||
plugin_type: lookup
|
||||
- module: community.general.ini_file
|
||||
- plugin: community.general.from_ini
|
||||
plugin_type: filter
|
||||
"""
|
||||
|
||||
EXAMPLES = r"""
|
||||
@@ -50,6 +56,7 @@ _value:
|
||||
from collections.abc import Mapping
|
||||
from configparser import ConfigParser
|
||||
from io import StringIO
|
||||
|
||||
from ansible.errors import AnsibleFilterError
|
||||
|
||||
|
||||
|
||||
50
plugins/filter/to_toml.py
Normal file
50
plugins/filter/to_toml.py
Normal file
@@ -0,0 +1,50 @@
|
||||
# Copyright (c) Contributors to the Ansible project
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import typing as t
|
||||
from collections.abc import Mapping
|
||||
|
||||
from ansible.module_utils.common.collections import is_sequence
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
|
||||
TOMLKIT_IMPORT_ERROR: ImportError | None
|
||||
try:
|
||||
from tomlkit import dumps
|
||||
except ImportError as imp_exc:
|
||||
TOMLKIT_IMPORT_ERROR = imp_exc
|
||||
else:
|
||||
TOMLKIT_IMPORT_ERROR = None
|
||||
|
||||
from ansible.errors import AnsibleError, AnsibleFilterError
|
||||
|
||||
from ansible_collections.community.general.plugins.plugin_utils._tags import remove_all_tags
|
||||
|
||||
|
||||
def _stringify_keys(value: t.Any) -> t.Any:
|
||||
"""Recursively convert all keys to strings."""
|
||||
if isinstance(value, Mapping):
|
||||
return {to_text(k): _stringify_keys(v) for k, v in value.items()}
|
||||
if is_sequence(value):
|
||||
return [_stringify_keys(e) for e in value]
|
||||
return value
|
||||
|
||||
|
||||
def to_toml(value: t.Mapping, *, redact_sensitive_values: bool = False) -> str:
|
||||
"""Serialize input as TOML."""
|
||||
if TOMLKIT_IMPORT_ERROR:
|
||||
raise AnsibleError("tomlkit must be installed to use this plugin") from TOMLKIT_IMPORT_ERROR
|
||||
if not isinstance(value, Mapping):
|
||||
raise AnsibleFilterError("to_toml only accepts dictionaries.")
|
||||
return dumps(
|
||||
remove_all_tags(_stringify_keys(value), redact_sensitive_values=redact_sensitive_values),
|
||||
)
|
||||
|
||||
|
||||
class FilterModule:
|
||||
def filters(self):
|
||||
return {
|
||||
"to_toml": to_toml,
|
||||
}
|
||||
42
plugins/filter/to_toml.yml
Normal file
42
plugins/filter/to_toml.yml
Normal file
@@ -0,0 +1,42 @@
|
||||
# Copyright (c) Contributors to the Ansible project
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
DOCUMENTATION:
|
||||
name: to_toml
|
||||
author:
|
||||
- Matt Williaks (@milliams)
|
||||
version_added: 12.3.0
|
||||
short_description: Convert variable to TOML string
|
||||
description:
|
||||
- Converts an Ansible variable into a TOML string representation.
|
||||
- This filter functions as a wrapper to the L(Python TOML Kit library, https://pypi.org/project/tomlkit/)'s C(tomlkit.dumps) function.
|
||||
requirements:
|
||||
- tomlkit
|
||||
positional: _input
|
||||
options:
|
||||
_input:
|
||||
description:
|
||||
- A variable or expression that returns a data structure.
|
||||
type: dict
|
||||
required: true
|
||||
redact_sensitive_values:
|
||||
description:
|
||||
- If set to V(true), vaulted strings are replaced by V(<redacted>) instead of being decrypted.
|
||||
- With future ansible-core versions, this can extend to other strings tagged as sensitive.
|
||||
- B(Note) that with ansible-core 2.18 and before this might not yield the expected result
|
||||
since these versions of ansible-core strip the vault information away from strings that are
|
||||
part of more complex data structures specified in C(vars).
|
||||
type: bool
|
||||
default: false
|
||||
|
||||
EXAMPLES: |
|
||||
---
|
||||
# Dump variable in a template to create a TOML document
|
||||
value: "{{ my_config | community.general.to_toml }}"
|
||||
|
||||
RETURN:
|
||||
_value:
|
||||
description:
|
||||
- The TOML serialized string representing the variable structure inputted.
|
||||
type: string
|
||||
@@ -5,7 +5,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import typing as t
|
||||
from collections.abc import Mapping, Set
|
||||
|
||||
from yaml import dump
|
||||
|
||||
@@ -14,81 +13,7 @@ try:
|
||||
except ImportError:
|
||||
from yaml import SafeDumper # type: ignore
|
||||
|
||||
from ansible.module_utils.common.collections import is_sequence
|
||||
|
||||
try:
|
||||
# This is ansible-core 2.19+
|
||||
from ansible.utils.vars import transform_to_native_types
|
||||
from ansible.parsing.vault import VaultHelper, VaultLib
|
||||
|
||||
HAS_TRANSFORM_TO_NATIVE_TYPES = True
|
||||
except ImportError:
|
||||
HAS_TRANSFORM_TO_NATIVE_TYPES = False
|
||||
|
||||
from ansible.parsing.yaml.objects import AnsibleVaultEncryptedUnicode
|
||||
from ansible.utils.unsafe_proxy import AnsibleUnsafe
|
||||
|
||||
|
||||
def _to_native_types_compat(value: t.Any, *, redact_value: str | None) -> t.Any:
|
||||
"""Compatibility function for ansible-core 2.18 and before."""
|
||||
if value is None:
|
||||
return value
|
||||
if isinstance(value, AnsibleUnsafe):
|
||||
# This only works up to ansible-core 2.18:
|
||||
return _to_native_types_compat(value._strip_unsafe(), redact_value=redact_value) # type: ignore
|
||||
# But that's fine, since this code path isn't taken on ansible-core 2.19+ anyway.
|
||||
if isinstance(value, Mapping):
|
||||
return {
|
||||
_to_native_types_compat(key, redact_value=redact_value): _to_native_types_compat(
|
||||
val, redact_value=redact_value
|
||||
)
|
||||
for key, val in value.items()
|
||||
}
|
||||
if isinstance(value, Set):
|
||||
return {_to_native_types_compat(elt, redact_value=redact_value) for elt in value}
|
||||
if is_sequence(value):
|
||||
return [_to_native_types_compat(elt, redact_value=redact_value) for elt in value]
|
||||
if isinstance(value, AnsibleVaultEncryptedUnicode):
|
||||
if redact_value is not None:
|
||||
return redact_value
|
||||
# This only works up to ansible-core 2.18:
|
||||
return value.data
|
||||
# But that's fine, since this code path isn't taken on ansible-core 2.19+ anyway.
|
||||
if isinstance(value, bytes):
|
||||
return bytes(value)
|
||||
if isinstance(value, str):
|
||||
return str(value)
|
||||
|
||||
return value
|
||||
|
||||
|
||||
def _to_native_types(value: t.Any, *, redact: bool) -> t.Any:
|
||||
if isinstance(value, Mapping):
|
||||
return {_to_native_types(k, redact=redact): _to_native_types(v, redact=redact) for k, v in value.items()}
|
||||
if is_sequence(value):
|
||||
return [_to_native_types(e, redact=redact) for e in value]
|
||||
if redact:
|
||||
ciphertext = VaultHelper.get_ciphertext(value, with_tags=False)
|
||||
if ciphertext and VaultLib.is_encrypted(ciphertext):
|
||||
return "<redacted>"
|
||||
return transform_to_native_types(value, redact=redact)
|
||||
|
||||
|
||||
def remove_all_tags(value: t.Any, *, redact_sensitive_values: bool = False) -> t.Any:
|
||||
"""
|
||||
Remove all tags from all values in the input.
|
||||
|
||||
If ``redact_sensitive_values`` is ``True``, all sensitive values will be redacted.
|
||||
"""
|
||||
if HAS_TRANSFORM_TO_NATIVE_TYPES:
|
||||
return _to_native_types(value, redact=redact_sensitive_values)
|
||||
|
||||
return _to_native_types_compat( # type: ignore[unreachable]
|
||||
value,
|
||||
redact_value="<redacted>"
|
||||
if redact_sensitive_values
|
||||
else None, # same string as in ansible-core 2.19 by transform_to_native_types()
|
||||
)
|
||||
from ansible_collections.community.general.plugins.plugin_utils._tags import remove_all_tags
|
||||
|
||||
|
||||
def to_yaml(
|
||||
|
||||
@@ -197,7 +197,7 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
|
||||
data = self.cobbler.get_profiles(self.token)
|
||||
else:
|
||||
data = self.cobbler.get_profiles()
|
||||
except (socket.gaierror, socket.error, xmlrpc_client.ProtocolError):
|
||||
except (socket.gaierror, OSError, xmlrpc_client.ProtocolError):
|
||||
self._reload_cache()
|
||||
else:
|
||||
self._init_cache()
|
||||
@@ -221,7 +221,7 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
|
||||
data[i] = self.cobbler.get_system_as_rendered(host["name"], self.token)
|
||||
else:
|
||||
data[i] = self.cobbler.get_system_as_rendered(host["name"])
|
||||
except (socket.gaierror, socket.error, xmlrpc_client.ProtocolError):
|
||||
except (socket.gaierror, OSError, xmlrpc_client.ProtocolError):
|
||||
self._reload_cache()
|
||||
else:
|
||||
self._init_cache()
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
DOCUMENTATION = r"""
|
||||
name: gitlab_runners
|
||||
author:
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
DOCUMENTATION = r"""
|
||||
name: icinga2
|
||||
short_description: Icinga2 inventory source
|
||||
@@ -97,8 +96,8 @@ import json
|
||||
from urllib.error import HTTPError
|
||||
|
||||
from ansible.errors import AnsibleParserError
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
|
||||
from ansible.module_utils.urls import open_url
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
|
||||
|
||||
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
|
||||
|
||||
|
||||
@@ -83,11 +83,12 @@ remotes:
|
||||
- remote-2:default
|
||||
"""
|
||||
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
|
||||
from ansible.utils.display import Display
|
||||
from json import loads
|
||||
from subprocess import check_output
|
||||
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
|
||||
from ansible.utils.display import Display
|
||||
|
||||
display = Display()
|
||||
|
||||
|
||||
|
||||
@@ -170,13 +170,13 @@ groups:
|
||||
test: inventory_hostname.startswith('test')
|
||||
"""
|
||||
|
||||
import re
|
||||
import os
|
||||
from subprocess import Popen, PIPE
|
||||
import re
|
||||
from subprocess import PIPE, Popen
|
||||
|
||||
from ansible.errors import AnsibleError, AnsibleParserError
|
||||
from ansible.module_utils.common.text.converters import to_native, to_text
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, Constructable
|
||||
from ansible.utils.display import Display
|
||||
|
||||
display = Display()
|
||||
|
||||
@@ -125,15 +125,14 @@ compose:
|
||||
"""
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, Constructable
|
||||
|
||||
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
|
||||
|
||||
|
||||
try:
|
||||
from linode_api4 import LinodeClient
|
||||
from linode_api4.objects.linode import Instance
|
||||
from linode_api4.errors import ApiError as LinodeApiError
|
||||
from linode_api4.objects.linode import Instance
|
||||
|
||||
HAS_LINODE = True
|
||||
except ImportError:
|
||||
@@ -203,7 +202,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
ips += [instance.ips.ipv6.slaac, instance.ips.ipv6.link_local]
|
||||
ips += instance.ips.ipv6.pools
|
||||
|
||||
for ip_type in set(ip.type for ip in ips):
|
||||
for ip_type in {ip.type for ip in ips}:
|
||||
self.inventory.set_variable(
|
||||
hostname, ip_type, make_unsafe(self._ip_data([ip for ip in ips if ip.type == ip_type]))
|
||||
)
|
||||
|
||||
@@ -167,15 +167,16 @@ groupby:
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
import os
|
||||
from urllib.parse import urlencode
|
||||
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin
|
||||
from ansible.module_utils.common.text.converters import to_native, to_text
|
||||
from ansible.module_utils.common.dict_transformations import dict_merge
|
||||
from ansible.errors import AnsibleError, AnsibleParserError
|
||||
from ansible.module_utils.common.dict_transformations import dict_merge
|
||||
from ansible.module_utils.common.text.converters import to_native, to_text
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.lxd import LXDClient, LXDClientException
|
||||
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
|
||||
|
||||
@@ -210,9 +211,9 @@ class InventoryModule(BaseInventoryPlugin):
|
||||
Returns:
|
||||
dict(json_data): json data"""
|
||||
try:
|
||||
with open(path, "r") as json_file:
|
||||
with open(path) as json_file:
|
||||
return json.load(json_file)
|
||||
except (IOError, json.decoder.JSONDecodeError) as err:
|
||||
except (OSError, json.decoder.JSONDecodeError) as err:
|
||||
raise AnsibleParserError(f"Could not load the test data from {to_native(path)}: {err}") from err
|
||||
|
||||
def save_json_data(self, path, file_name=None):
|
||||
@@ -242,7 +243,7 @@ class InventoryModule(BaseInventoryPlugin):
|
||||
cwd = os.path.abspath(os.path.dirname(__file__))
|
||||
with open(os.path.abspath(os.path.join(cwd, *path)), "w") as json_file:
|
||||
json.dump(self.data, json_file)
|
||||
except IOError as err:
|
||||
except OSError as err:
|
||||
raise AnsibleParserError(f"Could not save data: {err}") from err
|
||||
|
||||
def verify_file(self, path):
|
||||
|
||||
@@ -125,14 +125,13 @@ groups:
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
from subprocess import Popen, PIPE
|
||||
from subprocess import PIPE, Popen
|
||||
|
||||
from ansible import constants as C
|
||||
from ansible.errors import AnsibleParserError
|
||||
from ansible.module_utils.common.text.converters import to_native, to_text
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
|
||||
from ansible.module_utils.common.process import get_bin_path
|
||||
from ansible.module_utils.common.text.converters import to_native, to_text
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, Constructable
|
||||
|
||||
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
|
||||
|
||||
|
||||
@@ -64,10 +64,10 @@ from sys import version as python_version
|
||||
from urllib.parse import urljoin
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.module_utils.ansible_release import __version__ as ansible_version
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.module_utils.urls import open_url
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.module_utils.ansible_release import __version__ as ansible_version
|
||||
|
||||
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
DOCUMENTATION = r"""
|
||||
name: opennebula
|
||||
author:
|
||||
@@ -90,14 +89,14 @@ try:
|
||||
except ImportError:
|
||||
HAS_PYONE = False
|
||||
|
||||
import os
|
||||
from collections import namedtuple
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
|
||||
|
||||
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
|
||||
|
||||
from collections import namedtuple
|
||||
import os
|
||||
|
||||
|
||||
class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||
NAME = "community.general.opennebula"
|
||||
@@ -119,10 +118,10 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||
if authfile is None:
|
||||
authfile = os.path.join(os.environ.get("HOME"), ".one", "one_auth")
|
||||
try:
|
||||
with open(authfile, "r") as fp:
|
||||
with open(authfile) as fp:
|
||||
authstring = fp.read().rstrip()
|
||||
username, password = authstring.split(":")
|
||||
except (OSError, IOError) as e:
|
||||
except OSError as e:
|
||||
raise AnsibleError(f"Could not find or read ONE_AUTH file at '{authfile}'") from e
|
||||
except Exception as e:
|
||||
raise AnsibleError(f"Error occurs when reading ONE_AUTH file at '{authfile}'") from e
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
DOCUMENTATION = r"""
|
||||
name: scaleway
|
||||
author:
|
||||
@@ -118,8 +117,8 @@ variables:
|
||||
ansible_user: "'admin'"
|
||||
"""
|
||||
|
||||
import os
|
||||
import json
|
||||
import os
|
||||
|
||||
YAML_IMPORT_ERROR: ImportError | None
|
||||
try:
|
||||
@@ -129,14 +128,15 @@ except ImportError as exc:
|
||||
else:
|
||||
YAML_IMPORT_ERROR = None
|
||||
|
||||
import urllib.parse as urllib_parse
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.module_utils.urls import open_url
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.scaleway import SCALEWAY_LOCATION, parse_pagination_link
|
||||
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
|
||||
from ansible.module_utils.urls import open_url
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
|
||||
import urllib.parse as urllib_parse
|
||||
|
||||
|
||||
def _fetch_information(token, url):
|
||||
|
||||
@@ -72,14 +72,13 @@ groups:
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from subprocess import Popen, PIPE
|
||||
from collections.abc import MutableMapping
|
||||
from subprocess import PIPE, Popen
|
||||
|
||||
from ansible.errors import AnsibleParserError
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
||||
from collections.abc import MutableMapping
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
|
||||
from ansible.module_utils.common.process import get_bin_path
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, Constructable
|
||||
|
||||
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ import ssl
|
||||
from time import sleep
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, Constructable
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.version import LooseVersion
|
||||
from ansible_collections.community.general.plugins.plugin_utils.unsafe import make_unsafe
|
||||
|
||||
@@ -77,7 +77,6 @@ import base64
|
||||
|
||||
from ansible.errors import AnsibleLookupError
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
|
||||
from ansible.utils.display import Display
|
||||
|
||||
display = Display()
|
||||
|
||||
@@ -118,7 +118,7 @@ _raw:
|
||||
elements: list
|
||||
"""
|
||||
|
||||
from subprocess import Popen, PIPE
|
||||
from subprocess import PIPE, Popen
|
||||
|
||||
from ansible.errors import AnsibleError, AnsibleOptionsError
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
DOCUMENTATION = r"""
|
||||
name: bitwarden_secrets_manager
|
||||
author:
|
||||
@@ -67,7 +66,7 @@ _raw:
|
||||
elements: dict
|
||||
"""
|
||||
|
||||
from subprocess import Popen, PIPE
|
||||
from subprocess import PIPE, Popen
|
||||
from time import sleep
|
||||
|
||||
from ansible.errors import AnsibleLookupError
|
||||
|
||||
@@ -42,8 +42,8 @@ _raw:
|
||||
"""
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.parsing.splitter import parse_kv
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
|
||||
try:
|
||||
import chef
|
||||
|
||||
@@ -61,11 +61,9 @@ import re
|
||||
from importlib import import_module
|
||||
|
||||
import yaml
|
||||
|
||||
from ansible.errors import AnsibleLookupError
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
|
||||
|
||||
FQCN_RE = re.compile(r"^[A-Za-z0-9_]+\.[A-Za-z0-9_]+$")
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
DOCUMENTATION = r"""
|
||||
author: Unknown (!UNKNOWN)
|
||||
name: consul_kv
|
||||
@@ -112,9 +111,9 @@ _raw:
|
||||
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from ansible.errors import AnsibleError, AnsibleAssertionError
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.errors import AnsibleAssertionError, AnsibleError
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
|
||||
try:
|
||||
import consul
|
||||
|
||||
@@ -79,12 +79,11 @@ _result:
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
from subprocess import PIPE
|
||||
from subprocess import Popen
|
||||
from subprocess import PIPE, Popen
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_native
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.utils.display import Display
|
||||
|
||||
display = Display()
|
||||
|
||||
@@ -118,8 +118,9 @@ _list:
|
||||
key2: bar
|
||||
"""
|
||||
|
||||
from ansible.errors import AnsibleLookupError
|
||||
from collections.abc import Mapping, Sequence
|
||||
|
||||
from ansible.errors import AnsibleLookupError
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.template import Templar
|
||||
|
||||
|
||||
@@ -240,20 +240,20 @@ _list:
|
||||
- C(strings).
|
||||
"""
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.module_utils.parsing.convert_bool import boolean
|
||||
from ansible.utils.display import Display
|
||||
import socket
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.module_utils.parsing.convert_bool import boolean
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.utils.display import Display
|
||||
|
||||
try:
|
||||
import dns.exception
|
||||
import dns.name
|
||||
import dns.rdataclass
|
||||
import dns.resolver
|
||||
import dns.reversename
|
||||
import dns.rdataclass
|
||||
from dns.rdatatype import (
|
||||
A,
|
||||
AAAA,
|
||||
CAA,
|
||||
CNAME,
|
||||
@@ -274,6 +274,7 @@ try:
|
||||
SSHFP,
|
||||
TLSA,
|
||||
TXT,
|
||||
A,
|
||||
)
|
||||
|
||||
HAVE_DNS = True
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
DOCUMENTATION = r"""
|
||||
name: dsv
|
||||
author: Adam Migus (@amigus) <adam@migus.org>
|
||||
@@ -96,9 +95,8 @@ try:
|
||||
except ImportError:
|
||||
sdk_is_missing = True
|
||||
|
||||
from ansible.utils.display import Display
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
|
||||
from ansible.utils.display import Display
|
||||
|
||||
display = Display()
|
||||
|
||||
|
||||
@@ -69,8 +69,8 @@ _raw:
|
||||
|
||||
import json
|
||||
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.module_utils.urls import open_url
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
|
||||
# this can be made configurable, not should not use ansible.cfg
|
||||
#
|
||||
|
||||
@@ -124,11 +124,11 @@ _raw:
|
||||
description: Time of last metadata update or creation (depends on OS).
|
||||
type: float
|
||||
"""
|
||||
import grp
|
||||
import os
|
||||
import pwd
|
||||
import grp
|
||||
import stat
|
||||
import re
|
||||
import stat
|
||||
|
||||
HAVE_SELINUX = False
|
||||
try:
|
||||
@@ -138,8 +138,8 @@ try:
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.module_utils.common.text.converters import to_native, to_text
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.utils.display import Display
|
||||
|
||||
display = Display()
|
||||
|
||||
@@ -83,7 +83,7 @@ except ImportError:
|
||||
HAS_PYTHON_JWT = False # vs pyjwt
|
||||
if HAS_JWT and hasattr(jwt, "JWT"):
|
||||
HAS_PYTHON_JWT = True
|
||||
from jwt import jwk_from_pem, JWT # type: ignore[attr-defined]
|
||||
from jwt import JWT, jwk_from_pem # type: ignore[attr-defined]
|
||||
|
||||
jwt_instance = JWT()
|
||||
|
||||
@@ -95,12 +95,12 @@ except ImportError:
|
||||
HAS_CRYPTOGRAPHY = False
|
||||
|
||||
|
||||
import time
|
||||
import json
|
||||
import time
|
||||
from urllib.error import HTTPError
|
||||
|
||||
from ansible.module_utils.urls import open_url
|
||||
from ansible.errors import AnsibleError, AnsibleOptionsError
|
||||
from ansible.module_utils.urls import open_url
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.utils.display import Display
|
||||
|
||||
|
||||
@@ -67,9 +67,9 @@ _raw:
|
||||
elements: str
|
||||
"""
|
||||
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.utils.cmd_functions import run_cmd
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
|
||||
|
||||
class Hiera:
|
||||
|
||||
@@ -39,7 +39,7 @@ _raw:
|
||||
elements: str
|
||||
"""
|
||||
|
||||
from subprocess import Popen, PIPE
|
||||
from subprocess import PIPE, Popen
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
||||
|
||||
@@ -59,8 +59,8 @@ _raw:
|
||||
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.module_utils.common.text.converters import to_native, to_text
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
|
||||
HAVE_LMDB = True
|
||||
try:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user