Compare commits

..

4 Commits

Author SHA1 Message Date
Felix Fontein
42b245eabf Release 6.0.0. 2022-11-07 21:49:22 +01:00
Felix Fontein
9a676bb88f Add missing changelog fragment for #5497. 2022-11-07 21:48:17 +01:00
Felix Fontein
cd26aec2f3 Add missing new modules and plugins to 6.0.0-a1 release changelog. 2022-11-07 21:46:22 +01:00
Felix Fontein
e9327a0464 Update links in README. 2022-11-07 21:45:57 +01:00
2065 changed files with 47546 additions and 107541 deletions

View File

@@ -4,6 +4,6 @@ GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://w
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-or-later
--> -->
### Description ## Azure Pipelines Configuration
Issue test description Please see the [Documentation](https://github.com/ansible/community/wiki/Testing:-Azure-Pipelines) for more information.

View File

@@ -0,0 +1,478 @@
---
# 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
trigger:
batch: true
branches:
include:
- main
- stable-*
pr:
autoCancel: true
branches:
include:
- main
- stable-*
schedules:
- cron: 0 8 * * *
displayName: Nightly (main)
always: true
branches:
include:
- main
- cron: 0 10 * * *
displayName: Nightly (active stable branches)
always: true
branches:
include:
- stable-5
- cron: 0 11 * * 0
displayName: Weekly (old stable branches)
always: true
branches:
include:
- stable-4
variables:
- name: checkoutPath
value: ansible_collections/community/general
- name: coverageBranches
value: main
- name: pipelinesCoverage
value: coverage
- name: entryPoint
value: tests/utils/shippable/shippable.sh
- name: fetchDepth
value: 0
resources:
containers:
- container: default
image: quay.io/ansible/azure-pipelines-test-container:3.0.0
pool: Standard
stages:
### Sanity
- stage: Sanity_devel
displayName: Sanity devel
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Test {0}
testFormat: devel/sanity/{0}
targets:
- test: 1
- test: 2
- test: 3
- test: 4
- test: extra
- stage: Sanity_2_14
displayName: Sanity 2.14
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Test {0}
testFormat: 2.14/sanity/{0}
targets:
- test: 1
- test: 2
- test: 3
- test: 4
- stage: Sanity_2_13
displayName: Sanity 2.13
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Test {0}
testFormat: 2.13/sanity/{0}
targets:
- test: 1
- test: 2
- test: 3
- test: 4
- stage: Sanity_2_12
displayName: Sanity 2.12
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Test {0}
testFormat: 2.12/sanity/{0}
targets:
- test: 1
- test: 2
- test: 3
- test: 4
- stage: Sanity_2_11
displayName: Sanity 2.11
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Test {0}
testFormat: 2.11/sanity/{0}
targets:
- test: 1
- test: 2
- test: 3
- test: 4
### Units
- stage: Units_devel
displayName: Units devel
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: devel/units/{0}/1
targets:
- test: 2.7
- test: 3.5
- test: 3.6
- test: 3.7
- test: 3.8
- test: 3.9
- test: '3.10'
- test: '3.11'
- stage: Units_2_14
displayName: Units 2.14
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: 2.14/units/{0}/1
targets:
- test: 2.7
- test: 3.9
- stage: Units_2_13
displayName: Units 2.13
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: 2.13/units/{0}/1
targets:
- test: 2.7
- test: 3.8
- stage: Units_2_12
displayName: Units 2.12
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: 2.12/units/{0}/1
targets:
- test: 2.6
- test: 3.8
- stage: Units_2_11
displayName: Units 2.11
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: 2.11/units/{0}/1
targets:
- test: 2.7
- test: 3.5
## Remote
- stage: Remote_devel
displayName: Remote devel
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: devel/{0}
targets:
- name: macOS 12.0
test: macos/12.0
- name: RHEL 7.9
test: rhel/7.9
- name: RHEL 9.0
test: rhel/9.0
- name: FreeBSD 12.3
test: freebsd/12.3
- name: FreeBSD 13.1
test: freebsd/13.1
groups:
- 1
- 2
- 3
- stage: Remote_2_14
displayName: Remote 2.14
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.14/{0}
targets:
- name: RHEL 9.0
test: rhel/9.0
- name: FreeBSD 13.1
test: freebsd/13.1
groups:
- 1
- 2
- 3
- stage: Remote_2_13
displayName: Remote 2.13
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.13/{0}
targets:
- name: macOS 12.0
test: macos/12.0
- name: RHEL 8.5
test: rhel/8.5
groups:
- 1
- 2
- 3
- stage: Remote_2_12
displayName: Remote 2.12
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.12/{0}
targets:
- name: macOS 11.1
test: macos/11.1
- name: RHEL 8.4
test: rhel/8.4
- name: FreeBSD 13.0
test: freebsd/13.0
groups:
- 1
- 2
- 3
- stage: Remote_2_11
displayName: Remote 2.11
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.11/{0}
targets:
- name: RHEL 7.9
test: rhel/7.9
- name: RHEL 8.3
test: rhel/8.3
groups:
- 1
- 2
- 3
### Docker
- stage: Docker_devel
displayName: Docker devel
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: devel/linux/{0}
targets:
- name: CentOS 7
test: centos7
- name: Fedora 36
test: fedora36
- name: openSUSE 15
test: opensuse15
- name: Ubuntu 20.04
test: ubuntu2004
- name: Ubuntu 22.04
test: ubuntu2204
- name: Alpine 3
test: alpine3
groups:
- 1
- 2
- 3
- stage: Docker_2_14
displayName: Docker 2.14
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.14/linux/{0}
targets:
- name: Ubuntu 20.04
test: ubuntu2004
groups:
- 1
- 2
- 3
- stage: Docker_2_13
displayName: Docker 2.13
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.13/linux/{0}
targets:
- name: Fedora 35
test: fedora35
- name: openSUSE 15 py2
test: opensuse15py2
- name: Alpine 3
test: alpine3
groups:
- 1
- 2
- 3
- stage: Docker_2_12
displayName: Docker 2.12
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.12/linux/{0}
targets:
- name: CentOS 6
test: centos6
- name: Fedora 34
test: fedora34
- name: Ubuntu 18.04
test: ubuntu1804
groups:
- 1
- 2
- 3
- stage: Docker_2_11
displayName: Docker 2.11
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.11/linux/{0}
targets:
- name: Fedora 32
test: fedora32
- name: Fedora 33
test: fedora33
- name: Alpine 3
test: alpine3
groups:
- 1
- 2
- 3
### Community Docker
- stage: Docker_community_devel
displayName: Docker (community images) devel
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: devel/linux-community/{0}
targets:
- name: Debian Bullseye
test: debian-bullseye/3.9
- name: ArchLinux
test: archlinux/3.10
- name: CentOS Stream 8
test: centos-stream8/3.8
groups:
- 1
- 2
- 3
### Generic
- stage: Generic_devel
displayName: Generic devel
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: devel/generic/{0}/1
targets:
- test: 2.7
- test: '3.11'
- stage: Generic_2_14
displayName: Generic 2.14
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: 2.14/generic/{0}/1
targets:
- test: '3.10'
- stage: Generic_2_13
displayName: Generic 2.13
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: 2.13/generic/{0}/1
targets:
- test: 3.9
- stage: Generic_2_12
displayName: Generic 2.12
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: 2.12/generic/{0}/1
targets:
- test: 3.8
- stage: Generic_2_11
displayName: Generic 2.11
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
nameFormat: Python {0}
testFormat: 2.11/generic/{0}/1
targets:
- test: 2.7
- test: 3.5
- stage: Summary
condition: succeededOrFailed()
dependsOn:
- Sanity_devel
- Sanity_2_11
- Sanity_2_12
- Sanity_2_13
- Sanity_2_14
- Units_devel
- Units_2_11
- Units_2_12
- Units_2_13
- Units_2_14
- Remote_devel
- Remote_2_11
- Remote_2_12
- Remote_2_13
- Remote_2_14
- Docker_devel
- Docker_2_11
- Docker_2_12
- Docker_2_13
- Docker_2_14
- Docker_community_devel
- Generic_devel
- Generic_2_11
- Generic_2_12
- Generic_2_13
- Generic_2_14
jobs:
- template: templates/coverage.yml

View File

@@ -0,0 +1,24 @@
#!/usr/bin/env bash
# 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
# Aggregate code coverage results for later processing.
set -o pipefail -eu
agent_temp_directory="$1"
PATH="${PWD}/bin:${PATH}"
mkdir "${agent_temp_directory}/coverage/"
options=(--venv --venv-system-site-packages --color -v)
ansible-test coverage combine --group-by command --export "${agent_temp_directory}/coverage/" "${options[@]}"
if ansible-test coverage analyze targets generate --help >/dev/null 2>&1; then
# Only analyze coverage if the installed version of ansible-test supports it.
# Doing so allows this script to work unmodified for multiple Ansible versions.
ansible-test coverage analyze targets generate "${agent_temp_directory}/coverage/coverage-analyze-targets.json" "${options[@]}"
fi

View File

@@ -0,0 +1,64 @@
#!/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
"""
Combine coverage data from multiple jobs, keeping the data only from the most recent attempt from each job.
Coverage artifacts must be named using the format: "Coverage $(System.JobAttempt) {StableUniqueNameForEachJob}"
The recommended coverage artifact name format is: Coverage $(System.JobAttempt) $(System.StageDisplayName) $(System.JobDisplayName)
Keep in mind that Azure Pipelines does not enforce unique job display names (only names).
It is up to pipeline authors to avoid name collisions when deviating from the recommended format.
"""
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import re
import shutil
import sys
def main():
"""Main program entry point."""
source_directory = sys.argv[1]
if '/ansible_collections/' in os.getcwd():
output_path = "tests/output"
else:
output_path = "test/results"
destination_directory = os.path.join(output_path, 'coverage')
if not os.path.exists(destination_directory):
os.makedirs(destination_directory)
jobs = {}
count = 0
for name in os.listdir(source_directory):
match = re.search('^Coverage (?P<attempt>[0-9]+) (?P<label>.+)$', name)
label = match.group('label')
attempt = int(match.group('attempt'))
jobs[label] = max(attempt, jobs.get(label, 0))
for label, attempt in jobs.items():
name = 'Coverage {attempt} {label}'.format(label=label, attempt=attempt)
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))
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)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,28 @@
#!/usr/bin/env bash
# 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
# Check the test results and set variables for use in later steps.
set -o pipefail -eu
if [[ "$PWD" =~ /ansible_collections/ ]]; then
output_path="tests/output"
else
output_path="test/results"
fi
echo "##vso[task.setVariable variable=outputPath]${output_path}"
if compgen -G "${output_path}"'/junit/*.xml' > /dev/null; then
echo "##vso[task.setVariable variable=haveTestResults]true"
fi
if compgen -G "${output_path}"'/bot/ansible-test-*' > /dev/null; then
echo "##vso[task.setVariable variable=haveBotResults]true"
fi
if compgen -G "${output_path}"'/coverage/*' > /dev/null; then
echo "##vso[task.setVariable variable=haveCoverageData]true"
fi

View File

@@ -0,0 +1,105 @@
#!/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
"""
Upload code coverage reports to codecov.io.
Multiple coverage files from multiple languages are accepted and aggregated after upload.
Python coverage, as well as PowerShell and Python stubs can all be uploaded.
"""
import argparse
import dataclasses
import pathlib
import shutil
import subprocess
import tempfile
import typing as t
import urllib.request
@dataclasses.dataclass(frozen=True)
class CoverageFile:
name: str
path: pathlib.Path
flags: t.List[str]
@dataclasses.dataclass(frozen=True)
class Args:
dry_run: bool
path: pathlib.Path
def parse_args() -> Args:
parser = argparse.ArgumentParser()
parser.add_argument('-n', '--dry-run', action='store_true')
parser.add_argument('path', type=pathlib.Path)
args = parser.parse_args()
# Store arguments in a typed dataclass
fields = dataclasses.fields(Args)
kwargs = {field.name: getattr(args, field.name) for field in fields}
return Args(**kwargs)
def process_files(directory: pathlib.Path) -> t.Tuple[CoverageFile, ...]:
processed = []
for file in directory.joinpath('reports').glob('coverage*.xml'):
name = file.stem.replace('coverage=', '')
# Get flags from name
flags = name.replace('-powershell', '').split('=') # Drop '-powershell' suffix
flags = [flag if not flag.startswith('stub') else flag.split('-')[0] for flag in flags] # Remove "-01" from stub files
processed.append(CoverageFile(name, file, flags))
return tuple(processed)
def upload_files(codecov_bin: pathlib.Path, files: t.Tuple[CoverageFile, ...], dry_run: bool = False) -> None:
for file in files:
cmd = [
str(codecov_bin),
'--name', file.name,
'--file', str(file.path),
]
for flag in file.flags:
cmd.extend(['--flags', flag])
if dry_run:
print(f'DRY-RUN: Would run command: {cmd}')
continue
subprocess.run(cmd, check=True)
def download_file(url: str, dest: pathlib.Path, flags: int, dry_run: bool = False) -> None:
if dry_run:
print(f'DRY-RUN: Would download {url} to {dest} and set mode to {flags:o}')
return
with urllib.request.urlopen(url) as resp:
with dest.open('w+b') as f:
# Read data in chunks rather than all at once
shutil.copyfileobj(resp, f, 64 * 1024)
dest.chmod(flags)
def main():
args = parse_args()
url = 'https://ansible-ci-files.s3.amazonaws.com/codecov/linux/codecov'
with tempfile.TemporaryDirectory(prefix='codecov-') as tmpdir:
codecov_bin = pathlib.Path(tmpdir) / 'codecov'
download_file(url, codecov_bin, 0o755, args.dry_run)
files = process_files(args.path)
upload_files(codecov_bin, files, args.dry_run)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,19 @@
#!/usr/bin/env bash
# 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
# Generate code coverage reports for uploading to Azure Pipelines and codecov.io.
set -o pipefail -eu
PATH="${PWD}/bin:${PATH}"
if ! ansible-test --help >/dev/null 2>&1; then
# Install the devel version of ansible-test for generating code coverage reports.
# This is only used by Ansible Collections, which are typically tested against multiple Ansible versions (in separate jobs).
# Since a version of ansible-test is required that can work the output from multiple older releases, the devel version is used.
pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check
fi
ansible-test coverage xml --group-by command --stub --venv --venv-system-site-packages --color -v

View File

@@ -0,0 +1,38 @@
#!/usr/bin/env bash
# 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
# Configure the test environment and run the tests.
set -o pipefail -eu
entry_point="$1"
test="$2"
read -r -a coverage_branches <<< "$3" # space separated list of branches to run code coverage on for scheduled builds
export COMMIT_MESSAGE
export COMPLETE
export COVERAGE
export IS_PULL_REQUEST
if [ "${SYSTEM_PULLREQUEST_TARGETBRANCH:-}" ]; then
IS_PULL_REQUEST=true
COMMIT_MESSAGE=$(git log --format=%B -n 1 HEAD^2)
else
IS_PULL_REQUEST=
COMMIT_MESSAGE=$(git log --format=%B -n 1 HEAD)
fi
COMPLETE=
COVERAGE=
if [ "${BUILD_REASON}" = "Schedule" ]; then
COMPLETE=yes
if printf '%s\n' "${coverage_branches[@]}" | grep -q "^${BUILD_SOURCEBRANCHNAME}$"; then
COVERAGE=yes
fi
fi
"${entry_point}" "${test}" 2>&1 | "$(dirname "$0")/time-command.py"

View File

@@ -0,0 +1,29 @@
#!/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
"""Prepends a relative timestamp to each input line from stdin and writes it to stdout."""
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import sys
import time
def main():
"""Main program entry point."""
start = time.time()
sys.stdin.reconfigure(errors='surrogateescape')
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))
sys.stdout.flush()
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,44 @@
---
# 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
# This template adds a job for processing code coverage data.
# It will upload results to Azure Pipelines and codecov.io.
# Use it from a job stage that completes after all other jobs have completed.
# This can be done by placing it in a separate summary stage that runs after the test stage(s) have completed.
jobs:
- job: Coverage
displayName: Code Coverage
container: default
workspace:
clean: all
steps:
- checkout: self
fetchDepth: $(fetchDepth)
path: $(checkoutPath)
- task: DownloadPipelineArtifact@2
displayName: Download Coverage Data
inputs:
path: coverage/
patterns: "Coverage */*=coverage.combined"
- bash: .azure-pipelines/scripts/combine-coverage.py coverage/
displayName: Combine Coverage Data
- bash: .azure-pipelines/scripts/report-coverage.sh
displayName: Generate Coverage Report
condition: gt(variables.coverageFileCount, 0)
- task: PublishCodeCoverageResults@1
inputs:
codeCoverageTool: Cobertura
# Azure Pipelines only accepts a single coverage data file.
# That means only Python or PowerShell coverage can be uploaded, but not both.
# Set the "pipelinesCoverage" variable to determine which type is uploaded.
# Use "coverage" for Python and "coverage-powershell" for PowerShell.
summaryFileLocation: "$(outputPath)/reports/$(pipelinesCoverage).xml"
displayName: Publish to Azure Pipelines
condition: gt(variables.coverageFileCount, 0)
- bash: .azure-pipelines/scripts/publish-codecov.py "$(outputPath)"
displayName: Publish to codecov.io
condition: gt(variables.coverageFileCount, 0)
continueOnError: true

View File

@@ -0,0 +1,60 @@
---
# 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
# This template uses the provided targets and optional groups to generate a matrix which is then passed to the test template.
# If this matrix template does not provide the required functionality, consider using the test template directly instead.
parameters:
# A required list of dictionaries, one per test target.
# Each item in the list must contain a "test" or "name" key.
# Both may be provided. If one is omitted, the other will be used.
- name: targets
type: object
# An optional list of values which will be used to multiply the targets list into a matrix.
# Values can be strings or numbers.
- name: groups
type: object
default: []
# An optional format string used to generate the job name.
# - {0} is the name of an item in the targets list.
- name: nameFormat
type: string
default: "{0}"
# An optional format string used to generate the test name.
# - {0} is the name of an item in the targets list.
- name: testFormat
type: string
default: "{0}"
# An optional format string used to add the group to the job name.
# {0} is the formatted name of an item in the targets list.
# {{1}} is the group -- be sure to include the double "{{" and "}}".
- name: nameGroupFormat
type: string
default: "{0} - {{1}}"
# An optional format string used to add the group to the test name.
# {0} is the formatted test of an item in the targets list.
# {{1}} is the group -- be sure to include the double "{{" and "}}".
- name: testGroupFormat
type: string
default: "{0}/{{1}}"
jobs:
- template: test.yml
parameters:
jobs:
- ${{ if eq(length(parameters.groups), 0) }}:
- ${{ each target in parameters.targets }}:
- name: ${{ format(parameters.nameFormat, coalesce(target.name, target.test)) }}
test: ${{ format(parameters.testFormat, coalesce(target.test, target.name)) }}
- ${{ if not(eq(length(parameters.groups), 0)) }}:
- ${{ each group in parameters.groups }}:
- ${{ each target in parameters.targets }}:
- name: ${{ format(format(parameters.nameGroupFormat, parameters.nameFormat), coalesce(target.name, target.test), group) }}
test: ${{ format(format(parameters.testGroupFormat, parameters.testFormat), coalesce(target.test, target.name), group) }}

View File

@@ -0,0 +1,50 @@
---
# 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
# This template uses the provided list of jobs to create test one or more test jobs.
# It can be used directly if needed, or through the matrix template.
parameters:
# A required list of dictionaries, one per test job.
# Each item in the list must contain a "job" and "name" key.
- name: jobs
type: object
jobs:
- ${{ each job in parameters.jobs }}:
- job: test_${{ replace(replace(replace(job.test, '/', '_'), '.', '_'), '-', '_') }}
displayName: ${{ job.name }}
container: default
workspace:
clean: all
steps:
- checkout: self
fetchDepth: $(fetchDepth)
path: $(checkoutPath)
- bash: .azure-pipelines/scripts/run-tests.sh "$(entryPoint)" "${{ job.test }}" "$(coverageBranches)"
displayName: Run Tests
- bash: .azure-pipelines/scripts/process-results.sh
condition: succeededOrFailed()
displayName: Process Results
- bash: .azure-pipelines/scripts/aggregate-coverage.sh "$(Agent.TempDirectory)"
condition: eq(variables.haveCoverageData, 'true')
displayName: Aggregate Coverage Data
- task: PublishTestResults@2
condition: eq(variables.haveTestResults, 'true')
inputs:
testResultsFiles: "$(outputPath)/junit/*.xml"
displayName: Publish Test Results
- task: PublishPipelineArtifact@1
condition: eq(variables.haveBotResults, 'true')
displayName: Publish Bot Results
inputs:
targetPath: "$(outputPath)/bot/"
artifactName: "Bot $(System.JobAttempt) $(System.StageDisplayName) $(System.JobDisplayName)"
- task: PublishPipelineArtifact@1
condition: eq(variables.haveCoverageData, 'true')
displayName: Publish Coverage Data
inputs:
targetPath: "$(Agent.TempDirectory)/coverage/"
artifactName: "Coverage $(System.JobAttempt) $(System.StageDisplayName) $(System.JobDisplayName)"

375
.github/BOTMETA.yml vendored
View File

@@ -33,8 +33,6 @@ files:
maintainers: $team_ansible_core maintainers: $team_ansible_core
$becomes/pmrun.py: $becomes/pmrun.py:
maintainers: $team_ansible_core maintainers: $team_ansible_core
$becomes/run0.py:
maintainers: konstruktoid
$becomes/sesu.py: $becomes/sesu.py:
maintainers: nekonyuu maintainers: nekonyuu
$becomes/sudosu.py: $becomes/sudosu.py:
@@ -52,8 +50,6 @@ files:
$callbacks/cgroup_memory_recap.py: {} $callbacks/cgroup_memory_recap.py: {}
$callbacks/context_demo.py: {} $callbacks/context_demo.py: {}
$callbacks/counter_enabled.py: {} $callbacks/counter_enabled.py: {}
$callbacks/default_without_diff.py:
maintainers: felixfontein
$callbacks/dense.py: $callbacks/dense.py:
maintainers: dagwieers maintainers: dagwieers
$callbacks/diy.py: $callbacks/diy.py:
@@ -91,8 +87,6 @@ files:
maintainers: ryancurrah maintainers: ryancurrah
$callbacks/syslog_json.py: $callbacks/syslog_json.py:
maintainers: imjoseangel maintainers: imjoseangel
$callbacks/timestamp.py:
maintainers: kurokobo
$callbacks/unixy.py: $callbacks/unixy.py:
labels: unixy labels: unixy
maintainers: akatch maintainers: akatch
@@ -103,9 +97,6 @@ files:
$connections/funcd.py: $connections/funcd.py:
maintainers: mscherer maintainers: mscherer
$connections/iocage.py: {} $connections/iocage.py: {}
$connections/incus.py:
labels: incus
maintainers: stgraber
$connections/jail.py: $connections/jail.py:
maintainers: $team_ansible_core maintainers: $team_ansible_core
$connections/lxc.py: {} $connections/lxc.py: {}
@@ -121,8 +112,6 @@ files:
maintainers: $team_ansible_core maintainers: $team_ansible_core
$doc_fragments/: $doc_fragments/:
labels: docs_fragments labels: docs_fragments
$doc_fragments/django.py:
maintainers: russoz
$doc_fragments/hpe3par.py: $doc_fragments/hpe3par.py:
labels: hpe3par labels: hpe3par
maintainers: farhan7500 gautamphegde maintainers: farhan7500 gautamphegde
@@ -130,9 +119,7 @@ files:
labels: hwc labels: hwc
maintainers: $team_huawei maintainers: $team_huawei
$doc_fragments/nomad.py: $doc_fragments/nomad.py:
maintainers: chris93111 apecnascimento maintainers: chris93111
$doc_fragments/pipx.py:
maintainers: russoz
$doc_fragments/xenserver.py: $doc_fragments/xenserver.py:
labels: xenserver labels: xenserver
maintainers: bvitnik maintainers: bvitnik
@@ -146,8 +133,6 @@ files:
maintainers: giner maintainers: giner
$filters/from_csv.py: $filters/from_csv.py:
maintainers: Ajpantuso maintainers: Ajpantuso
$filters/from_ini.py:
maintainers: sscheib
$filters/groupby_as_dict.py: $filters/groupby_as_dict.py:
maintainers: felixfontein maintainers: felixfontein
$filters/hashids.py: $filters/hashids.py:
@@ -159,35 +144,15 @@ files:
$filters/jc.py: $filters/jc.py:
maintainers: kellyjonbrazil maintainers: kellyjonbrazil
$filters/json_query.py: {} $filters/json_query.py: {}
$filters/keep_keys.py:
maintainers: vbotka
$filters/lists.py:
maintainers: cfiehe
$filters/lists_difference.yml:
maintainers: cfiehe
$filters/lists_intersect.yml:
maintainers: cfiehe
$filters/lists_mergeby.py: $filters/lists_mergeby.py:
maintainers: vbotka maintainers: vbotka
$filters/lists_symmetric_difference.yml:
maintainers: cfiehe
$filters/lists_union.yml:
maintainers: cfiehe
$filters/random_mac.py: {} $filters/random_mac.py: {}
$filters/remove_keys.py:
maintainers: vbotka
$filters/replace_keys.py:
maintainers: vbotka
$filters/reveal_ansible_type.py:
maintainers: vbotka
$filters/time.py: $filters/time.py:
maintainers: resmo maintainers: resmo
$filters/to_days.yml: $filters/to_days.yml:
maintainers: resmo maintainers: resmo
$filters/to_hours.yml: $filters/to_hours.yml:
maintainers: resmo maintainers: resmo
$filters/to_ini.py:
maintainers: sscheib
$filters/to_milliseconds.yml: $filters/to_milliseconds.yml:
maintainers: resmo maintainers: resmo
$filters/to_minutes.yml: $filters/to_minutes.yml:
@@ -228,7 +193,7 @@ files:
labels: cloud opennebula labels: cloud opennebula
maintainers: feldsam maintainers: feldsam
$inventories/proxmox.py: $inventories/proxmox.py:
maintainers: $team_virt ilijamt krauthosting maintainers: $team_virt ilijamt
$inventories/scaleway.py: $inventories/scaleway.py:
labels: cloud scaleway labels: cloud scaleway
maintainers: $team_scaleway maintainers: $team_scaleway
@@ -239,8 +204,6 @@ files:
maintainers: ddelnano shinuza maintainers: ddelnano shinuza
$lookups/: $lookups/:
labels: lookups labels: lookups
$lookups/bitwarden_secrets_manager.py:
maintainers: jantari
$lookups/bitwarden.py: $lookups/bitwarden.py:
maintainers: lungj maintainers: lungj
$lookups/cartesian.py: {} $lookups/cartesian.py: {}
@@ -269,8 +232,6 @@ files:
$lookups/filetree.py: $lookups/filetree.py:
maintainers: dagwieers maintainers: dagwieers
$lookups/flattened.py: {} $lookups/flattened.py: {}
$lookups/github_app_access_token.py:
maintainers: weisheng-p
$lookups/hiera.py: $lookups/hiera.py:
maintainers: jparrill maintainers: jparrill
$lookups/keyring.py: {} $lookups/keyring.py: {}
@@ -280,17 +241,13 @@ files:
$lookups/manifold.py: $lookups/manifold.py:
labels: manifold labels: manifold
maintainers: galanoff maintainers: galanoff
$lookups/merge_variables.py:
maintainers: rlenferink m-a-r-k-e alpex8
$lookups/onepass: $lookups/onepass:
labels: onepassword labels: onepassword
maintainers: samdoran maintainers: samdoran
$lookups/onepassword.py: $lookups/onepassword.py:
ignore: scottsb maintainers: azenk scottsb
maintainers: azenk
$lookups/onepassword_raw.py: $lookups/onepassword_raw.py:
ignore: scottsb maintainers: azenk scottsb
maintainers: azenk
$lookups/passwordstore.py: {} $lookups/passwordstore.py: {}
$lookups/random_pet.py: $lookups/random_pet.py:
maintainers: Akasurde maintainers: Akasurde
@@ -308,19 +265,9 @@ files:
maintainers: delineaKrehl tylerezimmerman maintainers: delineaKrehl tylerezimmerman
$module_utils/: $module_utils/:
labels: module_utils labels: module_utils
$module_utils/btrfs.py:
maintainers: gnfzdz
$module_utils/cmd_runner.py:
maintainers: russoz
$module_utils/deps.py:
maintainers: russoz
$module_utils/django.py:
maintainers: russoz
$module_utils/gconftool2.py: $module_utils/gconftool2.py:
labels: gconftool2 labels: gconftool2
maintainers: russoz maintainers: russoz
$module_utils/gio_mime.py:
maintainers: russoz
$module_utils/gitlab.py: $module_utils/gitlab.py:
keywords: gitlab source_control keywords: gitlab source_control
labels: gitlab labels: gitlab
@@ -332,19 +279,15 @@ files:
maintainers: $team_huawei maintainers: $team_huawei
$module_utils/identity/keycloak/keycloak.py: $module_utils/identity/keycloak/keycloak.py:
maintainers: $team_keycloak maintainers: $team_keycloak
$module_utils/identity/keycloak/keycloak_clientsecret.py:
maintainers: $team_keycloak fynncfchen johncant
$module_utils/ipa.py: $module_utils/ipa.py:
labels: ipa labels: ipa
maintainers: $team_ipa maintainers: $team_ipa
$module_utils/jenkins.py:
labels: jenkins
maintainers: russoz
$module_utils/manageiq.py: $module_utils/manageiq.py:
labels: manageiq labels: manageiq
maintainers: $team_manageiq maintainers: $team_manageiq
$module_utils/memset.py: $module_utils/memset.py:
labels: cloud memset labels: cloud memset
maintainers: glitchcrab
$module_utils/mh/: $module_utils/mh/:
labels: module_helper labels: module_helper
maintainers: russoz maintainers: russoz
@@ -359,11 +302,6 @@ files:
$module_utils/pipx.py: $module_utils/pipx.py:
labels: pipx labels: pipx
maintainers: russoz maintainers: russoz
$module_utils/python_runner.py:
maintainers: russoz
$module_utils/puppet.py:
labels: puppet
maintainers: russoz
$module_utils/pure.py: $module_utils/pure.py:
labels: pure pure_storage labels: pure pure_storage
maintainers: $team_purestorage maintainers: $team_purestorage
@@ -375,19 +313,11 @@ files:
$module_utils/scaleway.py: $module_utils/scaleway.py:
labels: cloud scaleway labels: cloud scaleway
maintainers: $team_scaleway maintainers: $team_scaleway
$module_utils/snap.py:
labels: snap
maintainers: russoz
$module_utils/ssh.py:
maintainers: russoz
$module_utils/storage/hpe3par/hpe3par.py: $module_utils/storage/hpe3par/hpe3par.py:
maintainers: farhan7500 gautamphegde maintainers: farhan7500 gautamphegde
$module_utils/utm_utils.py: $module_utils/utm_utils.py:
labels: utm_utils labels: utm_utils
maintainers: $team_e_spirit maintainers: $team_e_spirit
$module_utils/vardict.py:
labels: vardict
maintainers: russoz
$module_utils/wdc_redfish_utils.py: $module_utils/wdc_redfish_utils.py:
labels: wdc_redfish_utils labels: wdc_redfish_utils
maintainers: $team_wdc maintainers: $team_wdc
@@ -447,15 +377,11 @@ files:
$modules/bearychat.py: $modules/bearychat.py:
maintainers: tonyseek maintainers: tonyseek
$modules/bigpanda.py: $modules/bigpanda.py:
ignore: hkariti maintainers: hkariti
$modules/bitbucket_: $modules/bitbucket_:
maintainers: catcombo maintainers: catcombo
$modules/bootc_manage.py:
maintainers: cooktheryan
$modules/bower.py: $modules/bower.py:
maintainers: mwarkentin maintainers: mwarkentin
$modules/btrfs_:
maintainers: gnfzdz
$modules/bundler.py: $modules/bundler.py:
maintainers: thoiberg maintainers: thoiberg
$modules/bzr.py: $modules/bzr.py:
@@ -485,7 +411,7 @@ files:
ignore: resmo ignore: resmo
maintainers: dmtrs maintainers: dmtrs
$modules/consul: $modules/consul:
ignore: colin-nolan Hakon ignore: colin-nolan
maintainers: $team_consul maintainers: $team_consul
$modules/copr.py: $modules/copr.py:
maintainers: schlupov maintainers: schlupov
@@ -502,7 +428,7 @@ files:
labels: datadog_event labels: datadog_event
maintainers: n0ts maintainers: n0ts
$modules/datadog_monitor.py: $modules/datadog_monitor.py:
ignore: skornehl maintainers: skornehl
$modules/dconf.py: $modules/dconf.py:
maintainers: azaghal maintainers: azaghal
$modules/deploy_helper.py: $modules/deploy_helper.py:
@@ -514,20 +440,12 @@ files:
maintainers: tintoy maintainers: tintoy
$modules/discord.py: $modules/discord.py:
maintainers: cwollinger maintainers: cwollinger
$modules/django_check.py:
maintainers: russoz
$modules/django_command.py:
maintainers: russoz
$modules/django_createcachetable.py:
maintainers: russoz
$modules/django_manage.py: $modules/django_manage.py:
ignore: scottanderson42 tastychutney ignore: scottanderson42 tastychutney
labels: django_manage labels: django_manage
maintainers: russoz maintainers: russoz
$modules/dnf_versionlock.py: $modules/dnf_versionlock.py:
maintainers: moreda maintainers: moreda
$modules/dnf_config_manager.py:
maintainers: ahyattdev
$modules/dnsimple.py: $modules/dnsimple.py:
maintainers: drcapulet maintainers: drcapulet
$modules/dnsimple_info.py: $modules/dnsimple_info.py:
@@ -550,9 +468,6 @@ files:
$modules/facter.py: $modules/facter.py:
labels: facter labels: facter
maintainers: $team_ansible_core gamethis maintainers: $team_ansible_core gamethis
$modules/facter_facts.py:
labels: facter
maintainers: russoz $team_ansible_core gamethis
$modules/filesize.py: $modules/filesize.py:
maintainers: quidame maintainers: quidame
$modules/filesystem.py: $modules/filesystem.py:
@@ -562,6 +477,8 @@ files:
maintainers: $team_flatpak maintainers: $team_flatpak
$modules/flatpak_remote.py: $modules/flatpak_remote.py:
maintainers: $team_flatpak maintainers: $team_flatpak
$modules/flowdock.py:
ignore: mcodd
$modules/gandi_livedns.py: $modules/gandi_livedns.py:
maintainers: gthiemonge maintainers: gthiemonge
$modules/gconftool2.py: $modules/gconftool2.py:
@@ -573,12 +490,8 @@ files:
$modules/gem.py: $modules/gem.py:
labels: gem labels: gem
maintainers: $team_ansible_core johanwiren maintainers: $team_ansible_core johanwiren
$modules/gio_mime.py:
maintainers: russoz
$modules/git_config.py: $modules/git_config.py:
maintainers: djmattyg007 mgedmin maintainers: djmattyg007 mgedmin
$modules/git_config_info.py:
maintainers: guenhter
$modules/github_: $modules/github_:
maintainers: stpierre maintainers: stpierre
$modules/github_deploy_key.py: $modules/github_deploy_key.py:
@@ -597,33 +510,20 @@ files:
keywords: gitlab source_control keywords: gitlab source_control
maintainers: $team_gitlab maintainers: $team_gitlab
notify: jlozadad notify: jlozadad
ignore: dj-wasabi
$modules/gitlab_branch.py: $modules/gitlab_branch.py:
maintainers: paytroff maintainers: paytroff
$modules/gitlab_issue.py:
maintainers: zvaraondrej
$modules/gitlab_label.py:
maintainers: gpongelli
$modules/gitlab_merge_request.py:
maintainers: zvaraondrej
$modules/gitlab_milestone.py:
maintainers: gpongelli
$modules/gitlab_project_variable.py: $modules/gitlab_project_variable.py:
maintainers: markuman maintainers: markuman
$modules/gitlab_instance_variable.py:
maintainers: benibr
$modules/gitlab_runner.py: $modules/gitlab_runner.py:
maintainers: SamyCoenen maintainers: SamyCoenen
$modules/gitlab_user.py: $modules/gitlab_user.py:
maintainers: LennertMertens stgrace maintainers: LennertMertens stgrace
$modules/gitlab_group_access_token.py:
maintainers: pixslx
$modules/gitlab_project_access_token.py:
maintainers: pixslx
$modules/grove.py: $modules/grove.py:
maintainers: zimbatm maintainers: zimbatm
$modules/gunicorn.py: $modules/gunicorn.py:
maintainers: agmezr maintainers: agmezr
$modules/hana_query.py:
maintainers: rainerleber
$modules/haproxy.py: $modules/haproxy.py:
maintainers: ravibhure Normo maintainers: ravibhure Normo
$modules/heroku_collaborator.py: $modules/heroku_collaborator.py:
@@ -650,11 +550,6 @@ files:
labels: homebrew_ macos labels: homebrew_ macos
maintainers: $team_macos maintainers: $team_macos
notify: chris-short notify: chris-short
$modules/homebrew_services.py:
ignore: ryansb
keywords: brew cask services darwin homebrew macosx macports osx
labels: homebrew_ macos
maintainers: $team_macos kitizz
$modules/homectl.py: $modules/homectl.py:
maintainers: jameslivulpi maintainers: jameslivulpi
$modules/honeybadger_deployment.py: $modules/honeybadger_deployment.py:
@@ -681,7 +576,7 @@ files:
ignore: jose-delarosa ignore: jose-delarosa
maintainers: $team_redfish maintainers: $team_redfish
$modules/ilo_: $modules/ilo_:
ignore: jose-delarosa varini-hp ignore: jose-delarosa
maintainers: $team_redfish maintainers: $team_redfish
$modules/imc_rest.py: $modules/imc_rest.py:
labels: cisco labels: cisco
@@ -713,13 +608,6 @@ files:
maintainers: bregman-arie maintainers: bregman-arie
$modules/ipa_: $modules/ipa_:
maintainers: $team_ipa maintainers: $team_ipa
ignore: fxfitz
$modules/ipa_getkeytab.py:
maintainers: abakanovskii
$modules/ipa_dnsrecord.py:
maintainers: $team_ipa jwbernin
$modules/ipbase_info.py:
maintainers: dominikkukacka
$modules/ipa_pwpolicy.py: $modules/ipa_pwpolicy.py:
maintainers: adralioh maintainers: adralioh
$modules/ipa_service.py: $modules/ipa_service.py:
@@ -754,9 +642,7 @@ files:
labels: jboss labels: jboss
maintainers: $team_jboss jhoekx maintainers: $team_jboss jhoekx
$modules/jenkins_build.py: $modules/jenkins_build.py:
maintainers: brettmilford unnecessary-username juanmcasanova maintainers: brettmilford unnecessary-username
$modules/jenkins_build_info.py:
maintainers: juanmcasanova
$modules/jenkins_job.py: $modules/jenkins_job.py:
maintainers: sermilrod maintainers: sermilrod
$modules/jenkins_job_info.py: $modules/jenkins_job_info.py:
@@ -766,37 +652,19 @@ files:
$modules/jenkins_script.py: $modules/jenkins_script.py:
maintainers: hogarthj maintainers: hogarthj
$modules/jira.py: $modules/jira.py:
ignore: DWSR tarka ignore: DWSR
labels: jira labels: jira
maintainers: Slezhuk pertoft maintainers: Slezhuk tarka pertoft
$modules/kdeconfig.py:
maintainers: smeso
$modules/kernel_blacklist.py: $modules/kernel_blacklist.py:
maintainers: matze maintainers: matze
$modules/keycloak_: $modules/keycloak_:
maintainers: $team_keycloak maintainers: $team_keycloak
$modules/keycloak_authentication.py: $modules/keycloak_authentication.py:
maintainers: elfelip Gaetan2907 maintainers: elfelip Gaetan2907
$modules/keycloak_authentication_required_actions.py:
maintainers: Skrekulko
$modules/keycloak_authz_authorization_scope.py:
maintainers: mattock
$modules/keycloak_authz_permission.py:
maintainers: mattock
$modules/keycloak_authz_custom_policy.py:
maintainers: mattock
$modules/keycloak_authz_permission_info.py:
maintainers: mattock
$modules/keycloak_client_rolemapping.py: $modules/keycloak_client_rolemapping.py:
maintainers: Gaetan2907 maintainers: Gaetan2907
$modules/keycloak_clientscope.py: $modules/keycloak_clientscope.py:
maintainers: Gaetan2907 maintainers: Gaetan2907
$modules/keycloak_clientscope_type.py:
maintainers: simonpahl
$modules/keycloak_clientsecret_info.py:
maintainers: fynncfchen johncant
$modules/keycloak_clientsecret_regenerate.py:
maintainers: fynncfchen johncant
$modules/keycloak_group.py: $modules/keycloak_group.py:
maintainers: adamgoossens maintainers: adamgoossens
$modules/keycloak_identity_provider.py: $modules/keycloak_identity_provider.py:
@@ -805,24 +673,12 @@ files:
maintainers: kris2kris maintainers: kris2kris
$modules/keycloak_realm_info.py: $modules/keycloak_realm_info.py:
maintainers: fynncfchen maintainers: fynncfchen
$modules/keycloak_realm_key.py:
maintainers: mattock
$modules/keycloak_role.py: $modules/keycloak_role.py:
maintainers: laurpaum maintainers: laurpaum
$modules/keycloak_user.py:
maintainers: elfelip
$modules/keycloak_user_federation.py: $modules/keycloak_user_federation.py:
maintainers: laurpaum maintainers: laurpaum
$modules/keycloak_userprofile.py:
maintainers: yeoldegrove
$modules/keycloak_component_info.py:
maintainers: desand01
$modules/keycloak_client_rolescope.py:
maintainers: desand01
$modules/keycloak_user_rolemapping.py: $modules/keycloak_user_rolemapping.py:
maintainers: bratwurzt maintainers: bratwurzt
$modules/keycloak_realm_rolemapping.py:
maintainers: agross mhuysamen Gaetan2907
$modules/keyring.py: $modules/keyring.py:
maintainers: ahussey-redhat maintainers: ahussey-redhat
$modules/keyring_info.py: $modules/keyring_info.py:
@@ -865,8 +721,6 @@ files:
maintainers: nerzhul maintainers: nerzhul
$modules/lvg.py: $modules/lvg.py:
maintainers: abulimov maintainers: abulimov
$modules/lvg_rename.py:
maintainers: lszomor
$modules/lvol.py: $modules/lvol.py:
maintainers: abulimov jhoekx zigaSRC unkaputtbar112 maintainers: abulimov jhoekx zigaSRC unkaputtbar112
$modules/lxc_container.py: $modules/lxc_container.py:
@@ -915,7 +769,7 @@ files:
labels: maven_artifact labels: maven_artifact
maintainers: tumbl3w33d turb maintainers: tumbl3w33d turb
$modules/memset_: $modules/memset_:
ignore: glitchcrab maintainers: glitchcrab
$modules/mksysb.py: $modules/mksysb.py:
labels: aix mksysb labels: aix mksysb
maintainers: $team_aix maintainers: $team_aix
@@ -951,7 +805,7 @@ files:
$modules/nmcli.py: $modules/nmcli.py:
maintainers: alcamie101 maintainers: alcamie101
$modules/nomad_: $modules/nomad_:
maintainers: chris93111 apecnascimento maintainers: chris93111
$modules/nosh.py: $modules/nosh.py:
maintainers: tacatac maintainers: tacatac
$modules/npm.py: $modules/npm.py:
@@ -960,10 +814,6 @@ files:
maintainers: shane-walker xcambar maintainers: shane-walker xcambar
$modules/nsupdate.py: $modules/nsupdate.py:
maintainers: nerzhul maintainers: nerzhul
$modules/ocapi_command.py:
maintainers: $team_wdc
$modules/ocapi_info.py:
maintainers: $team_wdc
$modules/oci_vcn.py: $modules/oci_vcn.py:
maintainers: $team_oracle rohitChaware maintainers: $team_oracle rohitChaware
$modules/odbc.py: $modules/odbc.py:
@@ -972,16 +822,13 @@ files:
maintainers: marc-sensenich maintainers: marc-sensenich
$modules/ohai.py: $modules/ohai.py:
labels: ohai labels: ohai
maintainers: $team_ansible_core maintainers: $team_ansible_core mpdehaan
ignore: mpdehaan
$modules/omapi_host.py: $modules/omapi_host.py:
maintainers: amasolov nerzhul maintainers: amasolov nerzhul
$modules/one_: $modules/one_:
maintainers: $team_opennebula maintainers: $team_opennebula
$modules/one_host.py: $modules/one_host.py:
maintainers: rvalle maintainers: rvalle
$modules/one_vnet.py:
maintainers: abakanovskii
$modules/oneandone_: $modules/oneandone_:
maintainers: aajdinov edevenport maintainers: aajdinov edevenport
$modules/onepassword_info.py: $modules/onepassword_info.py:
@@ -1038,7 +885,7 @@ files:
labels: pagerduty labels: pagerduty
maintainers: suprememoocow thaumos maintainers: suprememoocow thaumos
$modules/pagerduty_alert.py: $modules/pagerduty_alert.py:
maintainers: ApsOps xshen1 maintainers: ApsOps
$modules/pagerduty_change.py: $modules/pagerduty_change.py:
maintainers: adamvaughan maintainers: adamvaughan
$modules/pagerduty_user.py: $modules/pagerduty_user.py:
@@ -1050,7 +897,7 @@ files:
$modules/pamd.py: $modules/pamd.py:
maintainers: kevensen maintainers: kevensen
$modules/parted.py: $modules/parted.py:
maintainers: ColOfAbRiX jake2184 maintainers: ColOfAbRiX rosowiecki jake2184
$modules/pear.py: $modules/pear.py:
ignore: jle64 ignore: jle64
labels: pear labels: pear
@@ -1081,9 +928,6 @@ files:
maintainers: $team_solaris dermute maintainers: $team_solaris dermute
$modules/pmem.py: $modules/pmem.py:
maintainers: mizumm maintainers: mizumm
$modules/pnpm.py:
ignore: chrishoffman
maintainers: aretrosen
$modules/portage.py: $modules/portage.py:
ignore: sayap ignore: sayap
labels: portage labels: portage
@@ -1100,34 +944,29 @@ files:
$modules/proxmox: $modules/proxmox:
keywords: kvm libvirt proxmox qemu keywords: kvm libvirt proxmox qemu
labels: proxmox virt labels: proxmox virt
maintainers: $team_virt UnderGreen krauthosting maintainers: $team_virt
ignore: tleguern
$modules/proxmox.py: $modules/proxmox.py:
ignore: skvidal ignore: skvidal
maintainers: UnderGreen krauthosting maintainers: UnderGreen
$modules/proxmox_disk.py: $modules/proxmox_disk.py:
maintainers: castorsky krauthosting maintainers: castorsky
$modules/proxmox_kvm.py: $modules/proxmox_kvm.py:
ignore: skvidal ignore: skvidal
maintainers: helldorado krauthosting maintainers: helldorado
$modules/proxmox_nic.py: $modules/proxmox_nic.py:
maintainers: Kogelvis krauthosting maintainers: Kogelvis
$modules/proxmox_node_info.py:
maintainers: jwbernin krauthosting
$modules/proxmox_storage_contents_info.py:
maintainers: l00ptr krauthosting
$modules/proxmox_tasks_info: $modules/proxmox_tasks_info:
maintainers: paginabianca krauthosting maintainers: paginabianca
$modules/proxmox_template.py: $modules/proxmox_template.py:
ignore: skvidal ignore: skvidal
maintainers: UnderGreen krauthosting maintainers: UnderGreen
$modules/pubnub_blocks.py: $modules/pubnub_blocks.py:
maintainers: parfeon pubnub maintainers: parfeon pubnub
$modules/pulp_repo.py: $modules/pulp_repo.py:
maintainers: sysadmind maintainers: sysadmind
$modules/puppet.py: $modules/puppet.py:
labels: puppet labels: puppet
maintainers: emonty maintainers: nibalizer emonty
$modules/pushbullet.py: $modules/pushbullet.py:
maintainers: willybarro maintainers: willybarro
$modules/pushover.py: $modules/pushover.py:
@@ -1135,15 +974,54 @@ files:
$modules/python_requirements_info.py: $modules/python_requirements_info.py:
ignore: ryansb ignore: ryansb
maintainers: willthames maintainers: willthames
$modules/rax:
ignore: ryansb sivel
$modules/rax.py:
maintainers: omgjlk sivel
$modules/rax_cbs.py:
maintainers: claco
$modules/rax_cbs_attachments.py:
maintainers: claco
$modules/rax_cdb.py:
maintainers: jails
$modules/rax_cdb_database.py:
maintainers: jails
$modules/rax_cdb_user.py:
maintainers: jails
$modules/rax_clb.py:
maintainers: claco
$modules/rax_clb_nodes.py:
maintainers: neuroid
$modules/rax_clb_ssl.py:
maintainers: smashwilson
$modules/rax_files.py:
maintainers: angstwad
$modules/rax_files_objects.py:
maintainers: angstwad
$modules/rax_identity.py:
maintainers: claco
$modules/rax_mon_alarm.py:
maintainers: smashwilson
$modules/rax_mon_check.py:
maintainers: smashwilson
$modules/rax_mon_entity.py:
maintainers: smashwilson
$modules/rax_mon_notification.py:
maintainers: smashwilson
$modules/rax_mon_notification_plan.py:
maintainers: smashwilson
$modules/rax_network.py:
maintainers: claco omgjlk
$modules/rax_queue.py:
maintainers: claco
$modules/read_csv.py: $modules/read_csv.py:
maintainers: dagwieers maintainers: dagwieers
$modules/redfish_: $modules/redfish_:
ignore: jose-delarosa ignore: jose-delarosa
maintainers: $team_redfish TSKushal maintainers: $team_redfish
$modules/redhat_subscription.py: $modules/redhat_subscription.py:
labels: redhat_subscription labels: redhat_subscription
maintainers: $team_rhsm maintainers: barnabycourt alikins kahowell
ignore: barnabycourt alikins kahowell
$modules/redis.py: $modules/redis.py:
maintainers: slok maintainers: slok
$modules/redis_data.py: $modules/redis_data.py:
@@ -1166,9 +1044,9 @@ files:
labels: rhn_register labels: rhn_register
maintainers: jlaska $team_rhn maintainers: jlaska $team_rhn
$modules/rhsm_release.py: $modules/rhsm_release.py:
maintainers: seandst $team_rhsm maintainers: seandst
$modules/rhsm_repository.py: $modules/rhsm_repository.py:
maintainers: giovannisciortino $team_rhsm maintainers: giovannisciortino
$modules/riak.py: $modules/riak.py:
maintainers: drewkerrigan jsmartin maintainers: drewkerrigan jsmartin
$modules/rocketchat.py: $modules/rocketchat.py:
@@ -1189,9 +1067,12 @@ files:
maintainers: nerzhul maintainers: nerzhul
$modules/runit.py: $modules/runit.py:
maintainers: jsumners maintainers: jsumners
$modules/sap_task_list_execute:
maintainers: rainerleber
$modules/sapcar_extract.py:
maintainers: RainerLeber
$modules/say.py: $modules/say.py:
maintainers: $team_ansible_core maintainers: $team_ansible_core mpdehaan
ignore: mpdehaan
$modules/scaleway_: $modules/scaleway_:
maintainers: $team_scaleway maintainers: $team_scaleway
$modules/scaleway_compute_private_network.py: $modules/scaleway_compute_private_network.py:
@@ -1263,8 +1144,6 @@ files:
ignore: ryansb ignore: ryansb
$modules/shutdown.py: $modules/shutdown.py:
maintainers: nitzmahone samdoran aminvakil maintainers: nitzmahone samdoran aminvakil
$modules/simpleinit_msb.py:
maintainers: vaygr
$modules/sl_vm.py: $modules/sl_vm.py:
maintainers: mcltn maintainers: mcltn
$modules/slack.py: $modules/slack.py:
@@ -1277,7 +1156,7 @@ files:
maintainers: $team_solaris maintainers: $team_solaris
$modules/snap.py: $modules/snap.py:
labels: snap labels: snap
maintainers: angristan vcarceler russoz maintainers: angristan vcarceler
$modules/snap_alias.py: $modules/snap_alias.py:
labels: snap labels: snap
maintainers: russoz maintainers: russoz
@@ -1299,6 +1178,8 @@ files:
maintainers: farhan7500 gautamphegde maintainers: farhan7500 gautamphegde
$modules/ssh_config.py: $modules/ssh_config.py:
maintainers: gaqzi Akasurde maintainers: gaqzi Akasurde
$modules/stackdriver.py:
maintainers: bwhaley
$modules/stacki_host.py: $modules/stacki_host.py:
labels: stacki_host labels: stacki_host
maintainers: bsanders bbyhuy maintainers: bsanders bbyhuy
@@ -1353,25 +1234,20 @@ files:
maintainers: nate-kingsley maintainers: nate-kingsley
$modules/urpmi.py: $modules/urpmi.py:
maintainers: pmakowski maintainers: pmakowski
$modules/usb_facts.py:
maintainers: maxopoly
$modules/utm_: $modules/utm_:
keywords: sophos utm keywords: sophos utm
maintainers: $team_e_spirit maintainers: $team_e_spirit
$modules/utm_ca_host_key_cert.py: $modules/utm_ca_host_key_cert.py:
ignore: stearz maintainers: stearz
maintainers: $team_e_spirit
$modules/utm_ca_host_key_cert_info.py: $modules/utm_ca_host_key_cert_info.py:
ignore: stearz maintainers: stearz
maintainers: $team_e_spirit
$modules/utm_network_interface_address.py: $modules/utm_network_interface_address.py:
maintainers: steamx maintainers: steamx
$modules/utm_network_interface_address_info.py: $modules/utm_network_interface_address_info.py:
maintainers: steamx maintainers: steamx
$modules/utm_proxy_auth_profile.py: $modules/utm_proxy_auth_profile.py:
keywords: sophos utm keywords: sophos utm
ignore: stearz maintainers: $team_e_spirit stearz
maintainers: $team_e_spirit
$modules/utm_proxy_exception.py: $modules/utm_proxy_exception.py:
keywords: sophos utm keywords: sophos utm
maintainers: $team_e_spirit RickS-C137 maintainers: $team_e_spirit RickS-C137
@@ -1394,6 +1270,8 @@ files:
maintainers: $team_wdc maintainers: $team_wdc
$modules/wdc_redfish_info.py: $modules/wdc_redfish_info.py:
maintainers: $team_wdc maintainers: $team_wdc
$modules/webfaction_:
maintainers: quentinsf
$modules/xattr.py: $modules/xattr.py:
labels: xattr labels: xattr
maintainers: bcoca maintainers: bcoca
@@ -1420,7 +1298,7 @@ files:
labels: m:xml xml labels: m:xml xml
maintainers: dagwieers magnus919 tbielawa cmprescott sm4rk0 maintainers: dagwieers magnus919 tbielawa cmprescott sm4rk0
$modules/yarn.py: $modules/yarn.py:
ignore: chrishoffman verkaufer maintainers: chrishoffman verkaufer
$modules/yum_versionlock.py: $modules/yum_versionlock.py:
maintainers: gyptazy aminvakil maintainers: gyptazy aminvakil
$modules/zfs: $modules/zfs:
@@ -1445,69 +1323,8 @@ files:
ignore: matze ignore: matze
labels: zypper labels: zypper
maintainers: $team_suse maintainers: $team_suse
$plugin_utils/ansible_type.py:
maintainers: vbotka
$plugin_utils/keys_filter.py:
maintainers: vbotka
$plugin_utils/unsafe.py:
maintainers: felixfontein
$tests/a_module.py: $tests/a_module.py:
maintainers: felixfontein maintainers: felixfontein
$tests/ansible_type.py:
maintainers: vbotka
$tests/fqdn_valid.py:
maintainers: vbotka
#########################
docs/docsite/rst/filter_guide.rst: {}
docs/docsite/rst/filter_guide_abstract_informations.rst: {}
docs/docsite/rst/filter_guide_abstract_informations_counting_elements_in_sequence.rst:
maintainers: keilr
docs/docsite/rst/filter_guide_abstract_informations_dictionaries.rst:
maintainers: felixfontein giner
docs/docsite/rst/filter_guide_abstract_informations_grouping.rst:
maintainers: felixfontein
docs/docsite/rst/filter_guide_abstract_informations_lists_helper.rst:
maintainers: cfiehe
docs/docsite/rst/filter_guide-abstract_informations-lists_of_dictionaries-keep_keys.rst:
maintainers: vbotka
docs/docsite/rst/filter_guide-abstract_informations-lists_of_dictionaries-remove_keys.rst:
maintainers: vbotka
docs/docsite/rst/filter_guide-abstract_informations-lists_of_dictionaries-replace_keys.rst:
maintainers: vbotka
docs/docsite/rst/filter_guide-abstract_informations-lists_of_dictionaries.rst:
maintainers: vbotka
docs/docsite/rst/filter_guide_abstract_informations_merging_lists_of_dictionaries.rst:
maintainers: vbotka
docs/docsite/rst/filter_guide_conversions.rst:
maintainers: Ajpantuso kellyjonbrazil
docs/docsite/rst/filter_guide_creating_identifiers.rst:
maintainers: Ajpantuso
docs/docsite/rst/filter_guide_paths.rst: {}
docs/docsite/rst/filter_guide_selecting_json_data.rst: {}
docs/docsite/rst/filter_guide_working_with_times.rst:
maintainers: resmo
docs/docsite/rst/filter_guide_working_with_unicode.rst:
maintainers: Ajpantuso
docs/docsite/rst/filter_guide_working_with_versions.rst:
maintainers: ericzolf
docs/docsite/rst/guide_alicloud.rst:
maintainers: xiaozhu36
docs/docsite/rst/guide_cmdrunner.rst:
maintainers: russoz
docs/docsite/rst/guide_deps.rst:
maintainers: russoz
docs/docsite/rst/guide_modulehelper.rst:
maintainers: russoz
docs/docsite/rst/guide_online.rst:
maintainers: remyleone
docs/docsite/rst/guide_packet.rst:
maintainers: baldwinSPC nurfet-becirevic t0mk teebes
docs/docsite/rst/guide_scaleway.rst:
maintainers: $team_scaleway
docs/docsite/rst/guide_vardict.rst:
maintainers: russoz
docs/docsite/rst/test_guide.rst:
maintainers: felixfontein
######################### #########################
tests/: tests/:
labels: tests labels: tests
@@ -1525,6 +1342,7 @@ macros:
becomes: plugins/become becomes: plugins/become
caches: plugins/cache caches: plugins/cache
callbacks: plugins/callback callbacks: plugins/callback
cliconfs: plugins/cliconf
connections: plugins/connection connections: plugins/connection
doc_fragments: plugins/doc_fragments doc_fragments: plugins/doc_fragments
filters: plugins/filter filters: plugins/filter
@@ -1532,21 +1350,21 @@ macros:
lookups: plugins/lookup lookups: plugins/lookup
module_utils: plugins/module_utils module_utils: plugins/module_utils
modules: plugins/modules modules: plugins/modules
plugin_utils: plugins/plugin_utils terminals: plugins/terminal
tests: plugins/test tests: plugins/test
team_ansible_core: team_ansible_core:
team_aix: MorrisA bcoca d-little flynn1973 gforster kairoaraujo marvin-sinister mator molekuul ramooncamacho wtcross team_aix: MorrisA bcoca d-little flynn1973 gforster kairoaraujo marvin-sinister mator molekuul ramooncamacho wtcross
team_bsd: JoergFiedler MacLemon bcoca dch jasperla mekanix opoplawski overhacked tuxillo team_bsd: JoergFiedler MacLemon bcoca dch jasperla mekanix opoplawski overhacked tuxillo
team_consul: sgargan apollo13 Ilgmi team_consul: sgargan
team_cyberark_conjur: jvanderhoof ryanprior team_cyberark_conjur: jvanderhoof ryanprior
team_e_spirit: MatrixCrawler getjack team_e_spirit: MatrixCrawler getjack
team_flatpak: JayKayy oolongbrothers team_flatpak: JayKayy oolongbrothers
team_gitlab: Lunik Shaps marwatk waheedi zanssa scodeman metanovii sh0shin nejch lgatellier suukit team_gitlab: Lunik Shaps dj-wasabi marwatk waheedi zanssa scodeman metanovii sh0shin nejch lgatellier suukit
team_hpux: bcoca davx8342 team_hpux: bcoca davx8342
team_huawei: QijunPan TommyLike edisonxiang freesky-edward hwDCN niuzhenguo xuxiaowei0512 yanzhangi zengchen1024 zhongjun2 team_huawei: QijunPan TommyLike edisonxiang freesky-edward hwDCN niuzhenguo xuxiaowei0512 yanzhangi zengchen1024 zhongjun2
team_ipa: Akasurde Nosmoht justchris1 team_ipa: Akasurde Nosmoht fxfitz justchris1
team_jboss: Wolfant jairojunior wbrefvem team_jboss: Wolfant jairojunior wbrefvem
team_keycloak: eikef ndclt mattock thomasbach-dev team_keycloak: eikef ndclt
team_linode: InTheCloudDan decentral1se displague rmcintosh Charliekenney23 LBGarber team_linode: InTheCloudDan decentral1se displague rmcintosh Charliekenney23 LBGarber
team_macos: Akasurde kyleabenson martinm82 danieljaouen indrajitr team_macos: Akasurde kyleabenson martinm82 danieljaouen indrajitr
team_manageiq: abellotti cben gtanzillo yaacov zgalor dkorn evertmulder team_manageiq: abellotti cben gtanzillo yaacov zgalor dkorn evertmulder
@@ -1554,11 +1372,10 @@ macros:
team_opennebula: ilicmilan meerkampdvv rsmontero xorel nilsding team_opennebula: ilicmilan meerkampdvv rsmontero xorel nilsding
team_oracle: manojmeda mross22 nalsaber team_oracle: manojmeda mross22 nalsaber
team_purestorage: bannaych dnix101 genegr lionmax opslounge raekins sdodsley sile16 team_purestorage: bannaych dnix101 genegr lionmax opslounge raekins sdodsley sile16
team_redfish: mraineri tomasg2012 xmadsen renxulei rajeevkallur bhavya06 jyundt team_redfish: mraineri tomasg2012 xmadsen renxulei rajeevkallur bhavya06
team_rhn: FlossWare alikins barnabycourt vritant team_rhn: FlossWare alikins barnabycourt vritant
team_rhsm: cnsnyder ptoscano
team_scaleway: remyleone abarbare team_scaleway: remyleone abarbare
team_solaris: bcoca fishman jasperla jpdasma mator scathatheworm troy2914 xen0l team_solaris: bcoca fishman jasperla jpdasma mator scathatheworm troy2914 xen0l
team_suse: commel evrardjp lrupp AnderEnder alxgu andytom sealor team_suse: commel evrardjp lrupp toabctl AnderEnder alxgu andytom sealor
team_virt: joshainglis karmab Thulium-Drake Ajpantuso team_virt: joshainglis karmab tleguern Thulium-Drake Ajpantuso
team_wdc: mikemoerk team_wdc: mikemoerk

View File

@@ -47,7 +47,7 @@ body:
label: Component Name label: Component Name
description: >- description: >-
Write the short name of the module, plugin, task or feature below, Write the short name of the module, plugin, task or feature below,
*use your best guess if unsure*. Do not include `community.general.`! *use your best guess if unsure*.
placeholder: dnf, apt, yum, pip, user etc. placeholder: dnf, apt, yum, pip, user etc.
validations: validations:
required: true required: true

View File

@@ -46,8 +46,8 @@ body:
attributes: attributes:
label: Component Name label: Component Name
description: >- description: >-
Write the short name of the file, module, plugin, task or feature below, Write the short name of the rst file, module, plugin, task or
*use your best guess if unsure*. Do not include `community.general.`! feature below, *use your best guess if unsure*.
placeholder: mysql_user placeholder: mysql_user
validations: validations:
required: true required: true

View File

@@ -42,8 +42,8 @@ body:
attributes: attributes:
label: Component Name label: Component Name
description: >- description: >-
Write the short name of the module or plugin, or which other part(s) of the collection this feature affects. Write the short name of the module, plugin, task or feature below,
*use your best guess if unsure*. Do not include `community.general.`! *use your best guess if unsure*.
placeholder: dnf, apt, yum, pip, user etc. placeholder: dnf, apt, yum, pip, user etc.
validations: validations:
required: true required: true

View File

@@ -1,32 +0,0 @@
##### SUMMARY
<!--- Describe the change below, including rationale and design decisions -->
<!--- HINT: Include "Fixes #nnn" if you are fixing an existing issue -->
<!--- Please do not forget to include a changelog fragment:
https://docs.ansible.com/ansible/devel/community/collection_development_process.html#creating-changelog-fragments
No need to include one for docs-only or test-only PR, and for new plugin/module PRs.
Read about more details in CONTRIBUTING.md.
-->
##### ISSUE TYPE
<!--- Pick one or more below and delete the rest.
'Test Pull Request' is for PRs that add/extend tests without code changes. -->
- Bugfix Pull Request
- Docs Pull Request
- Feature Pull Request
- New Module/Plugin Pull Request
- Refactoring Pull Request
- Test Pull Request
##### COMPONENT NAME
<!--- Write the SHORT NAME of the module, plugin, task or feature below. -->
##### ADDITIONAL INFORMATION
<!--- Include additional information to help people understand the change here -->
<!--- A step-by-step reproduction of the problem is helpful if there is no related issue -->
<!--- Paste verbatim command output below, e.g. before and after your change -->
```paste below
```

View File

@@ -1,3 +0,0 @@
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

61
.github/workflows/codeql-analysis.yml vendored Normal file
View File

@@ -0,0 +1,61 @@
---
# 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
name: "Code scanning - action"
on:
schedule:
- cron: '26 19 * * 1'
permissions:
contents: read
jobs:
CodeQL-Build:
permissions:
actions: read # for github/codeql-action/init to get workflow details
contents: read # for actions/checkout to fetch code
security-events: write # for github/codeql-action/autobuild to send a status report
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
fetch-depth: 2
# If this run was triggered by a pull request event, then checkout
# the head of the pull request instead of the merge commit.
- run: git checkout HEAD^2
if: ${{ github.event_name == 'pull_request' }}
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
# Override language selection by uncommenting this and choosing your languages
# with:
# languages: go, javascript, csharp, python, cpp, java
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2

93
.github/workflows/docs-pr.yml vendored Normal file
View File

@@ -0,0 +1,93 @@
---
# 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
name: Collection Docs
concurrency:
group: docs-${{ github.head_ref }}
cancel-in-progress: true
on:
pull_request_target:
types: [opened, synchronize, reopened, closed]
paths-ignore:
- '.azure-pipelines/**'
- 'changelogs/**'
- 'meta/**'
- 'tests/**'
jobs:
build-docs:
permissions:
contents: read
name: Build Ansible Docs
uses: ansible-community/github-docs-build/.github/workflows/_shared-docs-build-pr.yml@main
with:
init-fail-on-error: true
provide-link-targets: |
ansible_collections.ansible.builtin.dict2items_filter
ansible_collections.ansible.builtin.items_lookup
ansible_collections.ansible.builtin.path_join_filter
ansible_collections.community.kubevirt.kubevirt_cdi_upload_module
ansible_collections.community.kubevirt.kubevirt_inventory
ansible_collections.community.kubevirt.kubevirt_preset_module
ansible_collections.community.kubevirt.kubevirt_pvc_module
ansible_collections.community.kubevirt.kubevirt_rs_module
ansible_collections.community.kubevirt.kubevirt_template_module
ansible_collections.community.kubevirt.kubevirt_vm_module
ansible_collections.infoblox.nios_modules.nios_a_record_module
ansible_collections.infoblox.nios_modules.nios_aaaa_record_module
ansible_collections.infoblox.nios_modules.nios_cname_record_module
ansible_collections.infoblox.nios_modules.nios_dns_view_module
ansible_collections.infoblox.nios_modules.nios_fixed_address_module
ansible_collections.infoblox.nios_modules.nios_host_record_module
ansible_collections.infoblox.nios_modules.nios_lookup_lookup
ansible_collections.infoblox.nios_modules.nios_member_module
ansible_collections.infoblox.nios_modules.nios_mx_record_module
ansible_collections.infoblox.nios_modules.nios_naptr_record_module
ansible_collections.infoblox.nios_modules.nios_network_module
ansible_collections.infoblox.nios_modules.nios_network_view_module
ansible_collections.infoblox.nios_modules.nios_next_ip_lookup
ansible_collections.infoblox.nios_modules.nios_next_network_lookup
ansible_collections.infoblox.nios_modules.nios_nsgroup_module
ansible_collections.infoblox.nios_modules.nios_ptr_record_module
ansible_collections.infoblox.nios_modules.nios_srv_record_module
ansible_collections.infoblox.nios_modules.nios_txt_record_module
ansible_collections.infoblox.nios_modules.nios_zone_module
comment:
permissions:
pull-requests: write
runs-on: ubuntu-latest
needs: build-docs
name: PR comments
steps:
- name: PR comment
uses: ansible-community/github-docs-build/actions/ansible-docs-build-comment@main
with:
body-includes: '## Docs Build'
reactions: heart
action: ${{ needs.build-docs.outputs.changed != 'true' && 'remove' || '' }}
on-closed-body: |
## Docs Build 📝
This PR is closed and any previously published docsite has been unpublished.
on-merged-body: |
## Docs Build 📝
Thank you for contribution!✨
This PR has been merged and your docs changes will be incorporated when they are next published.
body: |
## Docs Build 📝
Thank you for contribution!✨
The docsite for **this PR** is available for download as an artifact from this run:
${{ needs.build-docs.outputs.artifact-url }}
File changes:
${{ needs.build-docs.outputs.diff-files-rendered }}
${{ needs.build-docs.outputs.diff-rendered }}

35
.github/workflows/reuse.yml vendored Normal file
View File

@@ -0,0 +1,35 @@
---
# 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
name: Verify REUSE
on:
push:
branches: [main]
pull_request_target:
types: [opened, synchronize, reopened]
branches: [main]
# Run CI once per day (at 07:30 UTC)
schedule:
- cron: '30 7 * * *'
jobs:
check:
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha || '' }}
- name: Install dependencies
run: |
pip install reuse
- name: Check REUSE compliance
run: |
reuse lint

18
.gitignore vendored
View File

@@ -383,16 +383,6 @@ cython_debug/
# option (not recommended) you can uncomment the following to ignore the entire idea folder. # option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/ #.idea/
### Python Patch ###
# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
poetry.toml
# ruff
.ruff_cache/
# LSP config files
pyrightconfig.json
### Vim ### ### Vim ###
# Swap # Swap
[._]*.s[a-v][a-z] [._]*.s[a-v][a-z]
@@ -492,10 +482,6 @@ tags
# https://plugins.jetbrains.com/plugin/12206-codestream # https://plugins.jetbrains.com/plugin/12206-codestream
.idea/codestream.xml .idea/codestream.xml
# Azure Toolkit for IntelliJ plugin
# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
.idea/**/azureSettings.xml
### Windows ### ### Windows ###
# Windows thumbnail cache files # Windows thumbnail cache files
Thumbs.db Thumbs.db
@@ -526,7 +512,3 @@ $RECYCLE.BIN/
# Integration tests cloud configs # Integration tests cloud configs
tests/integration/cloud-config-*.ini tests/integration/cloud-config-*.ini
# VSCode specific extensions
.vscode/settings.json

23
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,23 @@
---
# 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
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.0.1
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: mixed-line-ending
args: [--fix=lf]
- id: fix-encoding-pragma
- id: check-ast
- id: check-merge-conflict
- id: check-symlinks
- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.9.0
hooks:
- id: rst-backticks
types: [file]
files: changelogs/fragments/.*\.(yml|yaml)$

5
.reuse/dep5 Normal file
View File

@@ -0,0 +1,5 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Files: changelogs/fragments/*
Copyright: Ansible Project
License: GPL-3.0-or-later

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -31,9 +31,7 @@ Also, consider taking up a valuable, reviewed, but abandoned pull request which
* Try committing your changes with an informative but short commit message. * Try committing your changes with an informative but short commit message.
* Do not squash your commits and force-push to your branch if not needed. Reviews of your pull request are much easier with individual commits to comprehend the pull request history. All commits of your pull request branch will be squashed into one commit by GitHub upon merge. * Do not squash your commits and force-push to your branch if not needed. Reviews of your pull request are much easier with individual commits to comprehend the pull request history. All commits of your pull request branch will be squashed into one commit by GitHub upon merge.
* Do not add merge commits to your PR. The bot will complain and you will have to rebase ([instructions for rebasing](https://docs.ansible.com/ansible/latest/dev_guide/developing_rebasing.html)) to remove them before your PR can be merged. To avoid that git automatically does merges during pulls, you can configure it to do rebases instead by running `git config pull.rebase true` inside the repository checkout. * Do not add merge commits to your PR. The bot will complain and you will have to rebase ([instructions for rebasing](https://docs.ansible.com/ansible/latest/dev_guide/developing_rebasing.html)) to remove them before your PR can be merged. To avoid that git automatically does merges during pulls, you can configure it to do rebases instead by running `git config pull.rebase true` inside the repository checkout.
* Make sure your PR includes a [changelog fragment](https://docs.ansible.com/ansible/devel/community/collection_development_process.html#creating-a-changelog-fragment). * Make sure your PR includes a [changelog fragment](https://docs.ansible.com/ansible/devel/community/development_process.html#changelogs-how-to). (You must not include a fragment for new modules or new plugins, except for test and filter plugins. Also you shouldn't include one for docs-only changes. If you're not sure, simply don't include one, we'll tell you whether one is needed or not :) )
* You must not include a fragment for new modules or new plugins. Also you shouldn't include one for docs-only changes. (If you're not sure, simply don't include one, we'll tell you whether one is needed or not :) )
* Please always include a link to the pull request itself, and if the PR is about an issue, also a link to the issue. Also make sure the fragment ends with a period, and begins with a lower-case letter after `-`. (Again, if you don't do this, we'll add suggestions to fix it, so don't worry too much :) )
* Avoid reformatting unrelated parts of the codebase in your PR. These types of changes will likely be requested for reversion, create additional work for reviewers, and may cause approval to be delayed. * Avoid reformatting unrelated parts of the codebase in your PR. These types of changes will likely be requested for reversion, create additional work for reviewers, and may cause approval to be delayed.
You can also read [our Quick-start development guide](https://github.com/ansible/community-docs/blob/main/create_pr_quick_start_guide.rst). You can also read [our Quick-start development guide](https://github.com/ansible/community-docs/blob/main/create_pr_quick_start_guide.rst).
@@ -44,49 +42,7 @@ If you want to test a PR locally, refer to [our testing guide](https://github.co
If you find any inconsistencies or places in this document which can be improved, feel free to raise an issue or pull request to fix it. If you find any inconsistencies or places in this document which can be improved, feel free to raise an issue or pull request to fix it.
## Run sanity or unit locally (with antsibull-nox) ## Run sanity, unit or integration tests locally
The easiest way to run sanity and unit tests locally is to use [antsibull-nox](https://ansible.readthedocs.io/projects/antsibull-nox/).
(If you have [nox](https://nox.thea.codes/en/stable/) installed, it will automatically install antsibull-nox in a virtual environment for you.)
### Sanity tests
The following commands show how to run ansible-test sanity tests:
```.bash
# Run basic sanity tests for all files in the collection:
nox -Re ansible-test-sanity-devel
# Run basic sanity tests for the given files and directories:
nox -Re ansible-test-sanity-devel -- plugins/modules/system/pids.py tests/integration/targets/pids/
# Run all other sanity tests for all files in the collection:
nox -R
```
If you replace `-Re` with `-e`, respectively. If you leave `-R` away, then the virtual environments will be re-created. The `-R` re-uses them (if they already exist).
### Unit tests
The following commands show how to run unit tests:
```.bash
# Run all unit tests:
nox -Re ansible-test-units-devel
# Run all unit tests for one Python version (a lot faster):
nox -Re ansible-test-units-devel -- --python 3.13
# Run a specific unit test (for the nmcli module) for one Python version:
nox -Re ansible-test-units-devel -- --python 3.13 tests/unit/plugins/modules/net_tools/test_nmcli.py
```
If you replace `-Re` with `-e`, then the virtual environments will be re-created. The `-R` re-uses them (if they already exist).
## Run basic sanity, unit or integration tests locally (with ansible-test)
Instead of using antsibull-nox, you can also run sanity and unit tests with ansible-test directly.
This also allows you to run integration tests.
You have to check out the repository into a specific path structure to be able to run `ansible-test`. The path to the git checkout must end with `.../ansible_collections/community/general`. Please see [our testing guide](https://github.com/ansible/community-docs/blob/main/test_pr_locally_guide.rst) for instructions on how to check out the repository into a correct path structure. The short version of these instructions is: You have to check out the repository into a specific path structure to be able to run `ansible-test`. The path to the git checkout must end with `.../ansible_collections/community/general`. Please see [our testing guide](https://github.com/ansible/community-docs/blob/main/test_pr_locally_guide.rst) for instructions on how to check out the repository into a correct path structure. The short version of these instructions is:
@@ -98,27 +54,16 @@ cd ~/dev/ansible_collections/community/general
Then you can run `ansible-test` (which is a part of [ansible-core](https://pypi.org/project/ansible-core/)) inside the checkout. The following example commands expect that you have installed Docker or Podman. Note that Podman has only been supported by more recent ansible-core releases. If you are using Docker, the following will work with Ansible 2.9+. Then you can run `ansible-test` (which is a part of [ansible-core](https://pypi.org/project/ansible-core/)) inside the checkout. The following example commands expect that you have installed Docker or Podman. Note that Podman has only been supported by more recent ansible-core releases. If you are using Docker, the following will work with Ansible 2.9+.
### Basic sanity tests The following commands show how to run sanity tests:
The following commands show how to run basic sanity tests:
```.bash ```.bash
# Run basic sanity tests for all files in the collection: # Run sanity tests for all files in the collection:
ansible-test sanity --docker -v ansible-test sanity --docker -v
# Run basic sanity tests for the given files and directories: # Run sanity tests for the given files and directories:
ansible-test sanity --docker -v plugins/modules/system/pids.py tests/integration/targets/pids/ ansible-test sanity --docker -v plugins/modules/system/pids.py tests/integration/targets/pids/
``` ```
### Unit tests
Note that for running unit tests, you need to install required collections in the same folder structure that `community.general` is checked out in.
Right now, you need to install [`community.internal_test_tools`](https://github.com/ansible-collections/community.internal_test_tools).
If you want to use the latest version from GitHub, you can run:
```
git clone https://github.com/ansible-collections/community.internal_test_tools.git ~/dev/ansible_collections/community/internal_test_tools
```
The following commands show how to run unit tests: The following commands show how to run unit tests:
```.bash ```.bash
@@ -132,42 +77,13 @@ ansible-test units --docker -v --python 3.8
ansible-test units --docker -v --python 3.8 tests/unit/plugins/modules/net_tools/test_nmcli.py ansible-test units --docker -v --python 3.8 tests/unit/plugins/modules/net_tools/test_nmcli.py
``` ```
### Integration tests
Note that for running integration tests, you need to install required collections in the same folder structure that `community.general` is checked out in.
Right now, depending on the test, you need to install [`ansible.posix`](https://github.com/ansible-collections/ansible.posix), [`community.crypto`](https://github.com/ansible-collections/community.crypto), and [`community.docker`](https://github.com/ansible-collections/community.docker):
If you want to use the latest versions from GitHub, you can run:
```
mkdir -p ~/dev/ansible_collections/ansible
git clone https://github.com/ansible-collections/ansible.posix.git ~/dev/ansible_collections/ansible/posix
git clone https://github.com/ansible-collections/community.crypto.git ~/dev/ansible_collections/community/crypto
git clone https://github.com/ansible-collections/community.docker.git ~/dev/ansible_collections/community/docker
```
The following commands show how to run integration tests: The following commands show how to run integration tests:
#### In Docker
Integration tests on Docker have the following parameters:
- `image_name` (required): The name of the Docker image. To get the list of supported Docker images, run
`ansible-test integration --help` and look for _target docker images_.
- `test_name` (optional): The name of the integration test.
For modules, this equals the short name of the module; for example, `pacman` in case of `community.general.pacman`.
For plugins, the plugin type is added before the plugin's short name, for example `callback_yaml` for the `community.general.yaml` callback.
```.bash ```.bash
# Test all plugins/modules on fedora40 # Run integration tests for the interfaces_files module in a Docker container using the
ansible-test integration -v --docker fedora40 # fedora35 operating system image (the supported images depend on your ansible-core version):
ansible-test integration --docker fedora35 -v interfaces_file
# Template
ansible-test integration -v --docker image_name test_name
# Example community.general.ini_file module on fedora40 Docker image:
ansible-test integration -v --docker fedora40 ini_file
```
#### Without isolation
```.bash
# Run integration tests for the flattened lookup **without any isolation**: # Run integration tests for the flattened lookup **without any isolation**:
ansible-test integration -v lookup_flattened ansible-test integration -v lookup_flattened
``` ```
@@ -205,3 +121,19 @@ Creating new modules and plugins requires a bit more work than other Pull Reques
listed as `maintainers` will be pinged for new issues and PRs that modify the module/plugin or its tests. listed as `maintainers` will be pinged for new issues and PRs that modify the module/plugin or its tests.
When you add a new plugin/module, we expect that you perform maintainer duty for at least some time after contributing it. When you add a new plugin/module, we expect that you perform maintainer duty for at least some time after contributing it.
## pre-commit
To help ensure high-quality contributions this repository includes a [pre-commit](https://pre-commit.com) configuration which
corrects and tests against common issues that would otherwise cause CI to fail. To begin using these pre-commit hooks see
the [Installation](#installation) section below.
This is optional and not required to contribute to this repository.
### Installation
Follow the [instructions](https://pre-commit.com/#install) provided with pre-commit and run `pre-commit install` under the repository base. If for any reason you would like to disable the pre-commit hooks run `pre-commit uninstall`.
This is optional to run it locally.
You can trigger it locally with `pre-commit run --all-files` or even to run only for a given file `pre-commit run --files YOUR_FILE`.

View File

@@ -6,12 +6,8 @@ SPDX-License-Identifier: GPL-3.0-or-later
# Community General Collection # Community General Collection
[![Documentation](https://img.shields.io/badge/docs-brightgreen.svg)](https://docs.ansible.com/ansible/latest/collections/community/general/) [![Build Status](https://dev.azure.com/ansible/community.general/_apis/build/status/CI?branchName=stable-6)](https://dev.azure.com/ansible/community.general/_build?definitionId=31)
[![Build Status](https://dev.azure.com/ansible/community.general/_apis/build/status/CI?branchName=stable-9)](https://dev.azure.com/ansible/community.general/_build?definitionId=31)
[![EOL CI](https://github.com/ansible-collections/community.general/actions/workflows/ansible-test.yml/badge.svg?branch=stable-9)](https://github.com/ansible-collections/community.general/actions)
[![Nox CI](https://github.com/ansible-collections/community.general/actions/workflows/nox.yml/badge.svg?branch=stable-9)](https://github.com/ansible-collections/community.general/actions)
[![Codecov](https://img.shields.io/codecov/c/github/ansible-collections/community.general)](https://codecov.io/gh/ansible-collections/community.general) [![Codecov](https://img.shields.io/codecov/c/github/ansible-collections/community.general)](https://codecov.io/gh/ansible-collections/community.general)
[![REUSE status](https://api.reuse.software/badge/github.com/ansible-collections/community.general)](https://api.reuse.software/info/github.com/ansible-collections/community.general)
This repository contains the `community.general` Ansible Collection. The collection is a part of the Ansible package and includes many modules and plugins supported by Ansible community which are not part of more specialized community collections. This repository contains the `community.general` Ansible Collection. The collection is a part of the Ansible package and includes many modules and plugins supported by Ansible community which are not part of more specialized community collections.
@@ -25,21 +21,11 @@ We follow [Ansible Code of Conduct](https://docs.ansible.com/ansible/latest/comm
If you encounter abusive behavior violating the [Ansible Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html), please refer to the [policy violations](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html#policy-violations) section of the Code of Conduct for information on how to raise a complaint. If you encounter abusive behavior violating the [Ansible Code of Conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html), please refer to the [policy violations](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html#policy-violations) section of the Code of Conduct for information on how to raise a complaint.
## Communication
* Join the Ansible forum:
* [Get Help](https://forum.ansible.com/c/help/6): get help or help others. This is for questions about modules or plugins in the collection. Please add appropriate tags if you start new discussions.
* [Tag `community-general`](https://forum.ansible.com/tag/community-general): discuss the *collection itself*, instead of specific modules or plugins.
* [Social Spaces](https://forum.ansible.com/c/chat/4): gather and interact with fellow enthusiasts.
* [News & Announcements](https://forum.ansible.com/c/news/5): track project-wide announcements including social events.
* The Ansible [Bullhorn newsletter](https://docs.ansible.com/ansible/devel/community/communication.html#the-bullhorn): used to announce releases and important changes.
For more information about communication, see the [Ansible communication guide](https://docs.ansible.com/ansible/devel/community/communication.html).
## Tested with Ansible ## Tested with Ansible
Tested with the current ansible-core 2.13, ansible-core 2.14, ansible-core 2.15, ansible-core 2.16, ansible-core 2.17, ansible-core 2.18, and ansible-core 2.19 releases. Ansible-core versions before 2.13.0 are not supported. This includes all ansible-base 2.10 and Ansible 2.9 releases. Tested with the current ansible-core 2.11, ansible-core 2.12, ansible-core 2.13, ansible-core 2.14 releases and the current development version of ansible-core. Ansible-core versions before 2.11.0 are not supported. This includes all ansible-base 2.10 and Ansible 2.9 releases.
Parts of this collection will not work with ansible-core 2.11 on Python 3.12+.
## External requirements ## External requirements
@@ -47,13 +33,13 @@ Some modules and plugins require external libraries. Please check the requiremen
## Included content ## Included content
Please check the included content on the [Ansible Galaxy page for this collection](https://galaxy.ansible.com/ui/repo/published/community/general/) or the [documentation on the Ansible docs site](https://docs.ansible.com/ansible/latest/collections/community/general/). Please check the included content on the [Ansible Galaxy page for this collection](https://galaxy.ansible.com/community/general) or the [documentation on the Ansible docs site](https://docs.ansible.com/ansible/latest/collections/community/general/).
## Using this collection ## Using this collection
This collection is shipped with the Ansible package. So if you have it installed, no more action is required. This collection is shipped with the Ansible package. So if you have it installed, no more action is required.
If you have a minimal installation (only Ansible Core installed) or you want to use the latest version of the collection along with the whole Ansible package, you need to install the collection from [Ansible Galaxy](https://galaxy.ansible.com/ui/repo/published/community/general/) manually with the `ansible-galaxy` command-line tool: If you have a minimal installation (only Ansible Core installed) or you want to use the latest version of the collection along with the whole Ansible package, you need to install the collection from [Ansible Galaxy](https://galaxy.ansible.com/community/general) manually with the `ansible-galaxy` command-line tool:
ansible-galaxy collection install community.general ansible-galaxy collection install community.general
@@ -70,7 +56,7 @@ Note that if you install the collection manually, it will not be upgraded automa
ansible-galaxy collection install community.general --upgrade ansible-galaxy collection install community.general --upgrade
``` ```
You can also install a specific version of the collection, for example, if you need to downgrade when something is broken in the latest version (please report an issue in this repository). Use the following syntax where `X.Y.Z` can be any [available version](https://galaxy.ansible.com/ui/repo/published/community/general/): You can also install a specific version of the collection, for example, if you need to downgrade when something is broken in the latest version (please report an issue in this repository). Use the following syntax where `X.Y.Z` can be any [available version](https://galaxy.ansible.com/community/general):
```bash ```bash
ansible-galaxy collection install community.general:==X.Y.Z ansible-galaxy collection install community.general:==X.Y.Z
@@ -86,13 +72,13 @@ We are actively accepting new contributors.
All types of contributions are very welcome. All types of contributions are very welcome.
You don't know how to start? Refer to our [contribution guide](https://github.com/ansible-collections/community.general/blob/main/CONTRIBUTING.md)! You don't know how to start? Refer to our [contribution guide](https://github.com/ansible-collections/community.general/blob/stable-6/CONTRIBUTING.md)!
The current maintainers are listed in the [commit-rights.md](https://github.com/ansible-collections/community.general/blob/main/commit-rights.md#people) file. If you have questions or need help, feel free to mention them in the proposals. The current maintainers are listed in the [commit-rights.md](https://github.com/ansible-collections/community.general/blob/stable-6/commit-rights.md#people) file. If you have questions or need help, feel free to mention them in the proposals.
You can find more information in the [developer guide for collections](https://docs.ansible.com/ansible/devel/dev_guide/developing_collections.html#contributing-to-collections), and in the [Ansible Community Guide](https://docs.ansible.com/ansible/latest/community/index.html). You can find more information in the [developer guide for collections](https://docs.ansible.com/ansible/devel/dev_guide/developing_collections.html#contributing-to-collections), and in the [Ansible Community Guide](https://docs.ansible.com/ansible/latest/community/index.html).
Also for some notes specific to this collection see [our CONTRIBUTING documentation](https://github.com/ansible-collections/community.general/blob/main/CONTRIBUTING.md). Also for some notes specific to this collection see [our CONTRIBUTING documentation](https://github.com/ansible-collections/community.general/blob/stable-6/CONTRIBUTING.md).
### Running tests ### Running tests
@@ -102,7 +88,7 @@ See [here](https://docs.ansible.com/ansible/devel/dev_guide/developing_collectio
To learn how to maintain / become a maintainer of this collection, refer to: To learn how to maintain / become a maintainer of this collection, refer to:
* [Committer guidelines](https://github.com/ansible-collections/community.general/blob/main/commit-rights.md). * [Committer guidelines](https://github.com/ansible-collections/community.general/blob/stable-6/commit-rights.md).
* [Maintainer guidelines](https://github.com/ansible/community-docs/blob/main/maintaining.rst). * [Maintainer guidelines](https://github.com/ansible/community-docs/blob/main/maintaining.rst).
It is necessary for maintainers of this collection to be subscribed to: It is necessary for maintainers of this collection to be subscribed to:
@@ -112,13 +98,25 @@ It is necessary for maintainers of this collection to be subscribed to:
They also should be subscribed to Ansible's [The Bullhorn newsletter](https://docs.ansible.com/ansible/devel/community/communication.html#the-bullhorn). They also should be subscribed to Ansible's [The Bullhorn newsletter](https://docs.ansible.com/ansible/devel/community/communication.html#the-bullhorn).
## Communication
We announce important development changes and releases through Ansible's [The Bullhorn newsletter](https://eepurl.com/gZmiEP). If you are a collection developer, be sure you are subscribed.
Join us in the `#ansible` (general use questions and support), `#ansible-community` (community and collection development questions), and other [IRC channels](https://docs.ansible.com/ansible/devel/community/communication.html#irc-channels) on [Libera.chat](https://libera.chat).
We take part in the global quarterly [Ansible Contributor Summit](https://github.com/ansible/community/wiki/Contributor-Summit) virtually or in-person. Track [The Bullhorn newsletter](https://eepurl.com/gZmiEP) and join us.
For more information about communities, meetings and agendas see [Community Wiki](https://github.com/ansible/community/wiki/Community).
For more information about communication, refer to Ansible's the [Communication guide](https://docs.ansible.com/ansible/devel/community/communication.html).
## Publishing New Version ## Publishing New Version
See the [Releasing guidelines](https://github.com/ansible/community-docs/blob/main/releasing_collections.rst) to learn how to release this collection. See the [Releasing guidelines](https://github.com/ansible/community-docs/blob/main/releasing_collections.rst) to learn how to release this collection.
## Release notes ## Release notes
See the [changelog](https://github.com/ansible-collections/community.general/blob/stable-9/CHANGELOG.md). See the [changelog](https://github.com/ansible-collections/community.general/blob/stable-6/CHANGELOG.rst).
## Roadmap ## Roadmap
@@ -137,8 +135,8 @@ See [this issue](https://github.com/ansible-collections/community.general/issues
This collection is primarily licensed and distributed as a whole under the GNU General Public License v3.0 or later. This collection is primarily licensed and distributed as a whole under the GNU General Public License v3.0 or later.
See [LICENSES/GPL-3.0-or-later.txt](https://github.com/ansible-collections/community.general/blob/stable-9/COPYING) for the full text. See [LICENSES/GPL-3.0-or-later.txt](https://github.com/ansible-collections/community.general/blob/stable-6/COPYING) for the full text.
Parts of the collection are licensed under the [BSD 2-Clause license](https://github.com/ansible-collections/community.general/blob/stable-9/LICENSES/BSD-2-Clause.txt), the [MIT license](https://github.com/ansible-collections/community.general/blob/stable-9/LICENSES/MIT.txt), and the [PSF 2.0 license](https://github.com/ansible-collections/community.general/blob/stable-9/LICENSES/PSF-2.0.txt). Parts of the collection are licensed under the [BSD 2-Clause license](https://github.com/ansible-collections/community.general/blob/stable-6/LICENSES/BSD-2-Clause.txt), the [MIT license](https://github.com/ansible-collections/community.general/blob/stable-6/LICENSES/MIT.txt), and the [PSF 2.0 license](https://github.com/ansible-collections/community.general/blob/stable-6/LICENSES/PSF-2.0.txt).
All files have a machine readable `SDPX-License-Identifier:` comment denoting its respective license(s) or an equivalent entry in an accompanying `.license` file. Only changelog fragments (which will not be part of a release) are covered by a blanket statement in `REUSE.toml`. This conforms to the [REUSE specification](https://reuse.software/spec/). All files have a machine readable `SDPX-License-Identifier:` comment denoting its respective license(s) or an equivalent entry in an accompanying `.license` file. Only changelog fragments (which will not be part of a release) are covered by a blanket statement in `.reuse/dep5`. This conforms to the [REUSE specification](https://reuse.software/spec/).

View File

@@ -1,11 +0,0 @@
# 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
version = 1
[[annotations]]
path = "changelogs/fragments/**"
precedence = "aggregate"
SPDX-FileCopyrightText = "Ansible Project"
SPDX-License-Identifier = "GPL-3.0-or-later"

View File

@@ -1,68 +0,0 @@
# 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
# SPDX-FileCopyrightText: 2025 Felix Fontein <felix@fontein.de>
[collection_sources]
"ansible.posix" = "git+https://github.com/ansible-collections/ansible.posix.git,main"
"community.crypto" = "git+https://github.com/ansible-collections/community.crypto.git,main"
"community.docker" = "git+https://github.com/ansible-collections/community.docker.git,main"
"community.internal_test_tools" = "git+https://github.com/ansible-collections/community.internal_test_tools.git,main"
[collection_sources_per_ansible.'2.13']
"community.crypto" = "git+https://github.com/ansible-collections/community.crypto.git,stable-2"
[collection_sources_per_ansible.'2.14']
"community.crypto" = "git+https://github.com/ansible-collections/community.crypto.git,stable-2"
[collection_sources_per_ansible.'2.15']
# community.crypto's main branch needs ansible-core >= 2.17
"community.crypto" = "git+https://github.com/ansible-collections/community.crypto.git,stable-2"
[collection_sources_per_ansible.'2.16']
# community.crypto's main branch needs ansible-core >= 2.17
"community.crypto" = "git+https://github.com/ansible-collections/community.crypto.git,stable-2"
[vcs]
vcs = "git"
development_branch = "main"
stable_branches = [ "stable-*" ]
[sessions]
[sessions.docs_check]
validate_collection_refs="all"
[sessions.license_check]
[sessions.extra_checks]
run_no_unwanted_files = true
no_unwanted_files_module_extensions = [".py"]
no_unwanted_files_yaml_extensions = [".yml"]
run_action_groups = true
[[sessions.extra_checks.action_groups_config]]
name = "consul"
pattern = "^consul_.*$"
exclusions = [
"consul_acl",
"consul_acl_bootstrap",
"consul_kv",
]
doc_fragment = "community.general.consul.actiongroup_consul"
[[sessions.extra_checks.action_groups_config]]
name = "proxmox"
pattern = "^proxmox(_.*)?$"
exclusions = []
doc_fragment = "community.general.proxmox.actiongroup_proxmox"
[sessions.build_import_check]
run_galaxy_importer = true
[sessions.ansible_test_sanity]
include_devel = false
max_version = "2.19"
[sessions.ansible_test_units]
include_devel = false
max_version = "2.19"

File diff suppressed because it is too large Load Diff

View File

@@ -7,37 +7,28 @@ changelog_filename_template: ../CHANGELOG.rst
changelog_filename_version_depth: 0 changelog_filename_version_depth: 0
changes_file: changelog.yaml changes_file: changelog.yaml
changes_format: combined changes_format: combined
ignore_other_fragment_extensions: true
keep_fragments: false keep_fragments: false
mention_ancestor: true mention_ancestor: true
flatmap: true
new_plugins_after_name: removed_features new_plugins_after_name: removed_features
notesdir: fragments notesdir: fragments
output_formats:
- md
- rst
prelude_section_name: release_summary prelude_section_name: release_summary
prelude_section_title: Release Summary prelude_section_title: Release Summary
sections: sections:
- - major_changes - - major_changes
- Major Changes - Major Changes
- - minor_changes - - minor_changes
- Minor Changes - Minor Changes
- - breaking_changes - - breaking_changes
- Breaking Changes / Porting Guide - Breaking Changes / Porting Guide
- - deprecated_features - - deprecated_features
- Deprecated Features - Deprecated Features
- - removed_features - - removed_features
- Removed Features (previously deprecated) - Removed Features (previously deprecated)
- - security_fixes - - security_fixes
- Security Fixes - Security Fixes
- - bugfixes - - bugfixes
- Bugfixes - Bugfixes
- - known_issues - - known_issues
- Known Issues - Known Issues
title: Community General title: Community General
trivial_section_name: trivial
use_fqcn: true
add_plugin_period: true
changelog_nice_yaml: true
changelog_sort: version
vcs: auto

View File

@@ -8,15 +8,3 @@ sections:
toctree: toctree:
- filter_guide - filter_guide
- test_guide - test_guide
- title: Cloud Guides
toctree:
- guide_alicloud
- guide_online
- guide_packet
- guide_scaleway
- title: Developer Guides
toctree:
- guide_deps
- guide_vardict
- guide_cmdrunner
- guide_modulehelper

View File

@@ -1,61 +0,0 @@
<!--
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
-->
# Docs helper. Create RST file.
The playbook `playbook.yml` writes a RST file that can be used in
docs/docsite/rst. The usage of this helper is recommended but not
mandatory. You can stop reading here and update the RST file manually
if you don't want to use this helper.
## Run the playbook
If you want to generate the RST file by this helper fit the variables
in the playbook and the template to your needs. Then, run the play
```sh
shell> ansible-playbook playbook.yml
```
## Copy RST to docs/docsite/rst
Copy the RST file to `docs/docsite/rst` and remove it from this
directory.
## Update the checksums
Substitute the variables and run the below commands
```sh
shell> sha1sum {{ target_vars }} > {{ target_sha1 }}
shell> sha1sum {{ file_rst }} > {{ file_sha1 }}
```
## Playbook explained
The playbook includes the variable *tests* from the integration tests
and creates the RST file from the template. The playbook will
terminate if:
* The file with the variable *tests* was changed
* The RST file was changed
This means that this helper is probably not up to date.
### The file with the variable *tests* was changed
This means that somebody updated the integration tests. Review the
changes and update the template if needed. Update the checksum to pass
the integrity test. The playbook message provides you with the
command.
### The RST file was changed
This means that somebody updated the RST file manually. Review the
changes and update the template. Update the checksum to pass the
integrity test. The playbook message provides you with the
command. Make sure that the updated template will create identical RST
file. Only then apply your changes.

View File

@@ -1,80 +0,0 @@
..
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
keep_keys
"""""""""
Use the filter :ansplugin:`community.general.keep_keys#filter` if you have a list of dictionaries and want to keep certain keys only.
.. note:: The output of the examples in this section use the YAML callback plugin. Quoting: "Ansible output that can be quite a bit easier to read than the default JSON formatting." See :ansplugin:`the documentation for the community.general.yaml callback plugin <community.general.yaml#callback>`.
Let us use the below list in the following examples:
.. code-block:: yaml
input:
{{ tests.0.input | to_yaml(indent=2) | indent(5) }}
{% for i in tests[0:1]|subelements('group') %}
* {{ i.1.d }}
.. code-block:: yaml+jinja
:emphasize-lines: 1
target: {{ i.1.tt }}
result: "{{ lookup('file', target ~ '/templates/' ~ i.0.template) }}"
{% endfor %}
gives
.. code-block:: yaml
:emphasize-lines: 1-
result:
{{ tests.0.result | to_yaml(indent=2) | indent(5) }}
.. versionadded:: 9.1.0
* The results of the below examples 1-5 are all the same:
.. code-block:: yaml
:emphasize-lines: 1-
result:
{{ tests.1.result | to_yaml(indent=2) | indent(5) }}
{% for i in tests[1:2]|subelements('group') %}
{{ loop.index }}. {{ i.1.d }}
.. code-block:: yaml+jinja
:emphasize-lines: 1,2
mp: {{ i.1.mp }}
target: {{ i.1.tt }}
result: "{{ lookup('file', target ~ '/templates/' ~ i.0.template) }}"
{% endfor %}
* The results of the below examples 6-9 are all the same:
.. code-block:: yaml
:emphasize-lines: 1-
result:
{{ tests.2.result | to_yaml(indent=2) | indent(5) }}
{% for i in tests[2:3]|subelements('group') %}
{{ loop.index + 5 }}. {{ i.1.d }}
.. code-block:: yaml+jinja
:emphasize-lines: 1,2
mp: {{ i.1.mp }}
target: {{ i.1.tt }}
result: "{{ lookup('file', target ~ '/templates/' ~ i.0.template) }}"
{% endfor %}

View File

@@ -1 +0,0 @@
8690afce792abc95693c2f61f743ee27388b1592 ../../rst/filter_guide-abstract_informations-lists_of_dictionaries-keep_keys.rst

View File

@@ -1,79 +0,0 @@
---
# 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
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Create docs REST files
# shell> ansible-playbook playbook.yml
#
# Proofread and copy created *.rst file into the directory
# docs/docsite/rst. Do not add *.rst in this directory to the version
# control.
#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# community.general/docs/docsite/helper/keep_keys/playbook.yml
- name: Create RST file for docs/docsite/rst
hosts: localhost
gather_facts: false
vars:
plugin: keep_keys
plugin_type: filter
docs_path:
- filter_guide
- abstract_informations
- lists_of_dictionaries
file_base: "{{ (docs_path + [plugin]) | join('-') }}"
file_rst: ../../rst/{{ file_base }}.rst
file_sha1: "{{ plugin }}.rst.sha1"
target: "../../../../tests/integration/targets/{{ plugin_type }}_{{ plugin }}"
target_vars: "{{ target }}/vars/main/tests.yml"
target_sha1: tests.yml.sha1
tasks:
- name: Test integrity tests.yml
when:
- integrity | d(true) | bool
- lookup('file', target_sha1) != lookup('pipe', 'sha1sum ' ~ target_vars)
block:
- name: Changed tests.yml
ansible.builtin.debug:
msg: |
Changed {{ target_vars }}
Review the changes and update {{ target_sha1 }}
shell> sha1sum {{ target_vars }} > {{ target_sha1 }}
- name: Changed tests.yml end host
ansible.builtin.meta: end_play
- name: Test integrity RST file
when:
- integrity | d(true) | bool
- lookup('file', file_sha1) != lookup('pipe', 'sha1sum ' ~ file_rst)
block:
- name: Changed RST file
ansible.builtin.debug:
msg: |
Changed {{ file_rst }}
Review the changes and update {{ file_sha1 }}
shell> sha1sum {{ file_rst }} > {{ file_sha1 }}
- name: Changed RST file end host
ansible.builtin.meta: end_play
- name: Include target vars
include_vars:
file: "{{ target_vars }}"
- name: Create RST file
ansible.builtin.template:
src: "{{ file_base }}.rst.j2"
dest: "{{ file_base }}.rst"

View File

@@ -1 +0,0 @@
c6fc4ee2017d9222675bcd13cc4f88ba8d14f38d ../../../../tests/integration/targets/filter_keep_keys/vars/main/tests.yml

View File

@@ -1,3 +0,0 @@
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

View File

@@ -2,11 +2,17 @@
# Copyright (c) Ansible Project # 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) # 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 # SPDX-License-Identifier: GPL-3.0-or-later
list1: list1:
- {name: foo, extra: true} - name: foo
- {name: bar, extra: false} extra: true
- {name: meh, extra: true} - name: bar
extra: false
- name: meh
extra: true
list2: list2:
- {name: foo, path: /foo} - name: foo
- {name: baz, path: /baz} path: /foo
- name: baz
path: /baz

View File

@@ -2,12 +2,14 @@
# Copyright (c) Ansible Project # 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) # 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 # SPDX-License-Identifier: GPL-3.0-or-later
list1: list1:
- name: myname01 - name: myname01
param01: param01:
x: default_value x: default_value
y: default_value y: default_value
list: [default_value] list:
- default_value
- name: myname02 - name: myname02
param01: [1, 1, 2, 3] param01: [1, 1, 2, 3]
@@ -16,6 +18,7 @@ list2:
param01: param01:
y: patch_value y: patch_value
z: patch_value z: patch_value
list: [patch_value] list:
- patch_value
- name: myname02 - name: myname02
param01: [3, 4, 4] param01: [3, 4, 4, {key: value}]

View File

@@ -8,7 +8,7 @@
dir: example-001_vars dir: example-001_vars
- debug: - debug:
var: list3 var: list3
when: debug | d(false) | bool when: debug|d(false)|bool
- template: - template:
src: list3.out.j2 src: list3.out.j2
dest: example-001.out dest: example-001.out

View File

@@ -2,5 +2,6 @@
# Copyright (c) Ansible Project # 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) # 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 # SPDX-License-Identifier: GPL-3.0-or-later
list3: "{{ list1 |
list3: "{{ list1|
community.general.lists_mergeby(list2, 'name') }}" community.general.lists_mergeby(list2, 'name') }}"

View File

@@ -8,7 +8,7 @@
dir: example-002_vars dir: example-002_vars
- debug: - debug:
var: list3 var: list3
when: debug | d(false) | bool when: debug|d(false)|bool
- template: - template:
src: list3.out.j2 src: list3.out.j2
dest: example-002.out dest: example-002.out

View File

@@ -2,5 +2,6 @@
# Copyright (c) Ansible Project # 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) # 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 # SPDX-License-Identifier: GPL-3.0-or-later
list3: "{{ [list1, list2] |
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name') }}" community.general.lists_mergeby('name') }}"

View File

@@ -8,7 +8,7 @@
dir: example-003_vars dir: example-003_vars
- debug: - debug:
var: list3 var: list3
when: debug | d(false) | bool when: debug|d(false)|bool
- template: - template:
src: list3.out.j2 src: list3.out.j2
dest: example-003.out dest: example-003.out

View File

@@ -2,6 +2,7 @@
# Copyright (c) Ansible Project # 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) # 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 # SPDX-License-Identifier: GPL-3.0-or-later
list3: "{{ [list1, list2] |
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name', community.general.lists_mergeby('name',
recursive=true) }}" recursive=true) }}"

View File

@@ -8,7 +8,7 @@
dir: example-004_vars dir: example-004_vars
- debug: - debug:
var: list3 var: list3
when: debug | d(false) | bool when: debug|d(false)|bool
- template: - template:
src: list3.out.j2 src: list3.out.j2
dest: example-004.out dest: example-004.out

View File

@@ -2,7 +2,8 @@
# Copyright (c) Ansible Project # 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) # 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 # SPDX-License-Identifier: GPL-3.0-or-later
list3: "{{ [list1, list2] |
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name', community.general.lists_mergeby('name',
recursive=true, recursive=true,
list_merge='keep') }}" list_merge='keep') }}"

View File

@@ -8,7 +8,7 @@
dir: example-005_vars dir: example-005_vars
- debug: - debug:
var: list3 var: list3
when: debug | d(false) | bool when: debug|d(false)|bool
- template: - template:
src: list3.out.j2 src: list3.out.j2
dest: example-005.out dest: example-005.out

View File

@@ -2,7 +2,8 @@
# Copyright (c) Ansible Project # 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) # 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 # SPDX-License-Identifier: GPL-3.0-or-later
list3: "{{ [list1, list2] |
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name', community.general.lists_mergeby('name',
recursive=true, recursive=true,
list_merge='append') }}" list_merge='append') }}"

View File

@@ -8,7 +8,7 @@
dir: example-006_vars dir: example-006_vars
- debug: - debug:
var: list3 var: list3
when: debug | d(false) | bool when: debug|d(false)|bool
- template: - template:
src: list3.out.j2 src: list3.out.j2
dest: example-006.out dest: example-006.out

View File

@@ -2,7 +2,8 @@
# Copyright (c) Ansible Project # 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) # 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 # SPDX-License-Identifier: GPL-3.0-or-later
list3: "{{ [list1, list2] |
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name', community.general.lists_mergeby('name',
recursive=true, recursive=true,
list_merge='prepend') }}" list_merge='prepend') }}"

View File

@@ -8,7 +8,7 @@
dir: example-007_vars dir: example-007_vars
- debug: - debug:
var: list3 var: list3
when: debug|d(false) | bool when: debug|d(false)|bool
- template: - template:
src: list3.out.j2 src: list3.out.j2
dest: example-007.out dest: example-007.out

View File

@@ -2,7 +2,8 @@
# Copyright (c) Ansible Project # 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) # 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 # SPDX-License-Identifier: GPL-3.0-or-later
list3: "{{ [list1, list2] |
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name', community.general.lists_mergeby('name',
recursive=true, recursive=true,
list_merge='append_rp') }}" list_merge='append_rp') }}"

View File

@@ -8,7 +8,7 @@
dir: example-008_vars dir: example-008_vars
- debug: - debug:
var: list3 var: list3
when: debug | d(false) | bool when: debug|d(false)|bool
- template: - template:
src: list3.out.j2 src: list3.out.j2
dest: example-008.out dest: example-008.out

View File

@@ -2,7 +2,8 @@
# Copyright (c) Ansible Project # 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) # 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 # SPDX-License-Identifier: GPL-3.0-or-later
list3: "{{ [list1, list2] |
list3: "{{ [list1, list2]|
community.general.lists_mergeby('name', community.general.lists_mergeby('name',
recursive=true, recursive=true,
list_merge='prepend_rp') }}" list_merge='prepend_rp') }}"

View File

@@ -1,14 +0,0 @@
---
# 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
- name: 9. Merge single list by common attribute 'name'
include_vars:
dir: example-009_vars
- debug:
var: list3
when: debug | d(false) | bool
- template:
src: list3.out.j2
dest: example-009.out

View File

@@ -1 +0,0 @@
../default-common.yml

View File

@@ -1,6 +0,0 @@
---
# 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
list3: "{{ [list1 + list2, []] |
community.general.lists_mergeby('name') }}"

View File

@@ -4,75 +4,51 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
examples: examples:
- title: Two lists - label: 'In the example below the lists are merged by the attribute ``name``:'
description: 'In the example below the lists are merged by the attribute ``name``:'
file: example-001_vars/list3.yml file: example-001_vars/list3.yml
lang: 'yaml+jinja' lang: 'yaml+jinja'
- title: - label: 'This produces:'
description: 'This produces:'
file: example-001.out file: example-001.out
lang: 'yaml' lang: 'yaml'
- title: List of two lists - label: 'It is possible to use a list of lists as an input of the filter:'
description: 'It is possible to use a list of lists as an input of the filter:'
file: example-002_vars/list3.yml file: example-002_vars/list3.yml
lang: 'yaml+jinja' lang: 'yaml+jinja'
- title: - label: 'This produces the same result as in the previous example:'
description: 'This produces the same result as in the previous example:'
file: example-002.out file: example-002.out
lang: 'yaml' lang: 'yaml'
- title: Single list - label: 'Example ``list_merge=replace`` (default):'
description: 'It is possible to merge single list:'
file: example-009_vars/list3.yml
lang: 'yaml+jinja'
- title:
description: 'This produces the same result as in the previous example:'
file: example-009.out
lang: 'yaml'
- title: list_merge=replace (default)
description: 'Example :ansopt:`community.general.lists_mergeby#filter:list_merge=replace` (default):'
file: example-003_vars/list3.yml file: example-003_vars/list3.yml
lang: 'yaml+jinja' lang: 'yaml+jinja'
- title: - label: 'This produces:'
description: 'This produces:'
file: example-003.out file: example-003.out
lang: 'yaml' lang: 'yaml'
- title: list_merge=keep - label: 'Example ``list_merge=keep``:'
description: 'Example :ansopt:`community.general.lists_mergeby#filter:list_merge=keep`:'
file: example-004_vars/list3.yml file: example-004_vars/list3.yml
lang: 'yaml+jinja' lang: 'yaml+jinja'
- title: - label: 'This produces:'
description: 'This produces:'
file: example-004.out file: example-004.out
lang: 'yaml' lang: 'yaml'
- title: list_merge=append - label: 'Example ``list_merge=append``:'
description: 'Example :ansopt:`community.general.lists_mergeby#filter:list_merge=append`:'
file: example-005_vars/list3.yml file: example-005_vars/list3.yml
lang: 'yaml+jinja' lang: 'yaml+jinja'
- title: - label: 'This produces:'
description: 'This produces:'
file: example-005.out file: example-005.out
lang: 'yaml' lang: 'yaml'
- title: list_merge=prepend - label: 'Example ``list_merge=prepend``:'
description: 'Example :ansopt:`community.general.lists_mergeby#filter:list_merge=prepend`:'
file: example-006_vars/list3.yml file: example-006_vars/list3.yml
lang: 'yaml+jinja' lang: 'yaml+jinja'
- title: - label: 'This produces:'
description: 'This produces:'
file: example-006.out file: example-006.out
lang: 'yaml' lang: 'yaml'
- title: list_merge=append_rp - label: 'Example ``list_merge=append_rp``:'
description: 'Example :ansopt:`community.general.lists_mergeby#filter:list_merge=append_rp`:'
file: example-007_vars/list3.yml file: example-007_vars/list3.yml
lang: 'yaml+jinja' lang: 'yaml+jinja'
- title: - label: 'This produces:'
description: 'This produces:'
file: example-007.out file: example-007.out
lang: 'yaml' lang: 'yaml'
- title: list_merge=prepend_rp - label: 'Example ``list_merge=prepend_rp``:'
description: 'Example :ansopt:`community.general.lists_mergeby#filter:list_merge=prepend_rp`:'
file: example-008_vars/list3.yml file: example-008_vars/list3.yml
lang: 'yaml+jinja' lang: 'yaml+jinja'
- title: - label: 'This produces:'
description: 'This produces:'
file: example-008.out file: example-008.out
lang: 'yaml' lang: 'yaml'

View File

@@ -4,10 +4,10 @@
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-or-later
{% for i in examples %} {% for i in examples %}
{{ i.description }} {{ i.label }}
.. code-block:: {{ i.lang }} .. code-block:: {{ i.lang }}
{{ lookup('file', i.file) | split('\n') | reject('match', '^(#|---)') | join ('\n') | indent(2) }} {{ lookup('file', i.file)|indent(2) }}
{% endfor %} {% endfor %}

View File

@@ -1,7 +0,0 @@
---
# 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
examples_one: true
examples_all: true
merging_lists_of_dictionaries: true

View File

@@ -6,69 +6,57 @@
Merging lists of dictionaries Merging lists of dictionaries
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you have two or more lists of dictionaries and want to combine them into a list of merged dictionaries, where the dictionaries are merged by an attribute, you can use the :ansplugin:`community.general.lists_mergeby <community.general.lists_mergeby#filter>` filter. If you have two or more lists of dictionaries and want to combine them into a list of merged dictionaries, where the dictionaries are merged by an attribute, you can use the ``lists_mergeby`` filter.
.. note:: The output of the examples in this section use the YAML callback plugin. Quoting: "Ansible output that can be quite a bit easier to read than the default JSON formatting." See the documentation for the :ansplugin:`community.general.yaml callback plugin <community.general.yaml#callback>`. .. note:: The output of the examples in this section use the YAML callback plugin. Quoting: "Ansible output that can be quite a bit easier to read than the default JSON formatting." See :ref:`the documentation for the community.general.yaml callback plugin <ansible_collections.community.general.yaml_callback>`.
Let us use the lists below in the following examples: Let us use the lists below in the following examples:
.. code-block:: yaml .. code-block:: yaml
{{ lookup('file', 'default-common.yml') | split('\n') | reject('match', '^(#|---)') | join ('\n') | indent(2) }} {{ lookup('file', 'default-common.yml')|indent(2) }}
{% for i in examples[0:2] %} {% for i in examples[0:2] %}
{% if i.title | d('', true) | length > 0 %} {{ i.label }}
{{ i.title }}
{{ "%s" % ('"' * i.title|length) }}
{% endif %}
{{ i.description }}
.. code-block:: {{ i.lang }} .. code-block:: {{ i.lang }}
{{ lookup('file', i.file) | split('\n') | reject('match', '^(#|---)') | join ('\n') | indent(2) }} {{ lookup('file', i.file)|indent(2) }}
{% endfor %} {% endfor %}
.. versionadded:: 2.0.0 .. versionadded:: 2.0.0
{% for i in examples[2:6] %} {% for i in examples[2:4] %}
{% if i.title | d('', true) | length > 0 %} {{ i.label }}
{{ i.title }}
{{ "%s" % ('"' * i.title|length) }}
{% endif %}
{{ i.description }}
.. code-block:: {{ i.lang }} .. code-block:: {{ i.lang }}
{{ lookup('file', i.file) | split('\n') | reject('match', '^(#|---)') | join ('\n') | indent(2) }} {{ lookup('file', i.file)|indent(2) }}
{% endfor %} {% endfor %}
The filter also accepts two optional parameters: :ansopt:`community.general.lists_mergeby#filter:recursive` and :ansopt:`community.general.lists_mergeby#filter:list_merge`. This is available since community.general 4.4.0. The filter also accepts two optional parameters: ``recursive`` and ``list_merge``. These parameters are only supported when used with ansible-base 2.10 or ansible-core, but not with Ansible 2.9. This is available since community.general 4.4.0.
**recursive** **recursive**
Is a boolean, default to ``false``. Should the :ansplugin:`community.general.lists_mergeby#filter` filter recursively merge nested hashes. Note: It does not depend on the value of the ``hash_behaviour`` setting in ``ansible.cfg``. Is a boolean, default to ``False``. Should the ``community.general.lists_mergeby`` recursively merge nested hashes. Note: It does not depend on the value of the ``hash_behaviour`` setting in ``ansible.cfg``.
**list_merge** **list_merge**
Is a string, its possible values are :ansval:`replace` (default), :ansval:`keep`, :ansval:`append`, :ansval:`prepend`, :ansval:`append_rp` or :ansval:`prepend_rp`. It modifies the behaviour of :ansplugin:`community.general.lists_mergeby#filter` when the hashes to merge contain arrays/lists. Is a string, its possible values are ``replace`` (default), ``keep``, ``append``, ``prepend``, ``append_rp`` or ``prepend_rp``. It modifies the behaviour of ``community.general.lists_mergeby`` when the hashes to merge contain arrays/lists.
The examples below set :ansopt:`community.general.lists_mergeby#filter:recursive=true` and display the differences among all six options of :ansopt:`community.general.lists_mergeby#filter:list_merge`. Functionality of the parameters is exactly the same as in the filter :ansplugin:`ansible.builtin.combine#filter`. See :ref:`Combining hashes/dictionaries <combine_filter>` to learn details about these options. The examples below set ``recursive=true`` and display the differences among all six options of ``list_merge``. Functionality of the parameters is exactly the same as in the filter ``combine``. See :ref:`Combining hashes/dictionaries <combine_filter>` to learn details about these options.
Let us use the lists below in the following examples Let us use the lists below in the following examples
.. code-block:: yaml .. code-block:: yaml
{{ lookup('file', 'default-recursive-true.yml') | split('\n') | reject('match', '^(#|---)') | join ('\n') |indent(2) }} {{ lookup('file', 'default-recursive-true.yml')|indent(2) }}
{% for i in examples[6:] %} {% for i in examples[4:16] %}
{% if i.title | d('', true) | length > 0 %} {{ i.label }}
{{ i.title }}
{{ "%s" % ('"' * i.title|length) }}
{% endif %}
{{ i.description }}
.. code-block:: {{ i.lang }} .. code-block:: {{ i.lang }}
{{ lookup('file', i.file) | split('\n') | reject('match', '^(#|---)') | join ('\n') |indent(2) }} {{ lookup('file', i.file)|indent(2) }}
{% endfor %} {% endfor %}

View File

@@ -4,4 +4,4 @@ GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://w
SPDX-License-Identifier: GPL-3.0-or-later SPDX-License-Identifier: GPL-3.0-or-later
#} #}
list3: list3:
{{ list3 | to_yaml(indent=2, sort_keys=false) | indent(2) }} {{ list3|to_nice_yaml(indent=0) }}

View File

@@ -5,7 +5,7 @@
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# 1) Run all examples and create example-XXX.out # 1) Run all examples and create example-XXX.out
# shell> ansible-playbook playbook.yml -e examples_one=true # shell> ansible-playbook playbook.yml -e examples=true
# #
# 2) Optionally, for testing, create examples_all.rst # 2) Optionally, for testing, create examples_all.rst
# shell> ansible-playbook playbook.yml -e examples_all=true # shell> ansible-playbook playbook.yml -e examples_all=true
@@ -45,20 +45,18 @@
tags: t007 tags: t007
- import_tasks: example-008.yml - import_tasks: example-008.yml
tags: t008 tags: t008
- import_tasks: example-009.yml when: examples|d(false)|bool
tags: t009
when: examples_one | d(false) | bool
- block: - block:
- include_vars: examples.yml - include_vars: examples.yml
- template: - template:
src: examples_all.rst.j2 src: examples_all.rst.j2
dest: examples_all.rst dest: examples_all.rst
when: examples_all | d(false) | bool when: examples_all|d(false)|bool
- block: - block:
- include_vars: examples.yml - include_vars: examples.yml
- template: - template:
src: filter_guide_abstract_informations_merging_lists_of_dictionaries.rst.j2 src: filter_guide_abstract_informations_merging_lists_of_dictionaries.rst.j2
dest: filter_guide_abstract_informations_merging_lists_of_dictionaries.rst dest: filter_guide_abstract_informations_merging_lists_of_dictionaries.rst
when: merging_lists_of_dictionaries | d(false) | bool when: merging_lists_of_dictionaries|d(false)|bool

View File

@@ -1,61 +0,0 @@
<!--
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
-->
# Docs helper. Create RST file.
The playbook `playbook.yml` writes a RST file that can be used in
docs/docsite/rst. The usage of this helper is recommended but not
mandatory. You can stop reading here and update the RST file manually
if you don't want to use this helper.
## Run the playbook
If you want to generate the RST file by this helper fit the variables
in the playbook and the template to your needs. Then, run the play
```sh
shell> ansible-playbook playbook.yml
```
## Copy RST to docs/docsite/rst
Copy the RST file to `docs/docsite/rst` and remove it from this
directory.
## Update the checksums
Substitute the variables and run the below commands
```sh
shell> sha1sum {{ target_vars }} > {{ target_sha1 }}
shell> sha1sum {{ file_rst }} > {{ file_sha1 }}
```
## Playbook explained
The playbook includes the variable *tests* from the integration tests
and creates the RST file from the template. The playbook will
terminate if:
* The file with the variable *tests* was changed
* The RST file was changed
This means that this helper is probably not up to date.
### The file with the variable *tests* was changed
This means that somebody updated the integration tests. Review the
changes and update the template if needed. Update the checksum to pass
the integrity test. The playbook message provides you with the
command.
### The RST file was changed
This means that somebody updated the RST file manually. Review the
changes and update the template. Update the checksum to pass the
integrity test. The playbook message provides you with the
command. Make sure that the updated template will create identical RST
file. Only then apply your changes.

View File

@@ -1,80 +0,0 @@
..
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
remove_keys
"""""""""""
Use the filter :ansplugin:`community.general.remove_keys#filter` if you have a list of dictionaries and want to remove certain keys.
.. note:: The output of the examples in this section use the YAML callback plugin. Quoting: "Ansible output that can be quite a bit easier to read than the default JSON formatting." See See :ansplugin:`the documentation for the community.general.yaml callback plugin <community.general.yaml#callback>`.
Let us use the below list in the following examples:
.. code-block:: yaml
input:
{{ tests.0.input | to_yaml(indent=2) | indent(5) }}
{% for i in tests[0:1]|subelements('group') %}
* {{ i.1.d }}
.. code-block:: yaml+jinja
:emphasize-lines: 1
target: {{ i.1.tt }}
result: "{{ lookup('file', target ~ '/templates/' ~ i.0.template) }}"
{% endfor %}
gives
.. code-block:: yaml
:emphasize-lines: 1-
result:
{{ tests.0.result | to_yaml(indent=2) | indent(5) }}
.. versionadded:: 9.1.0
* The results of the below examples 1-5 are all the same:
.. code-block:: yaml
:emphasize-lines: 1-
result:
{{ tests.1.result | to_yaml(indent=2) | indent(5) }}
{% for i in tests[1:2]|subelements('group') %}
{{ loop.index }}. {{ i.1.d }}
.. code-block:: yaml+jinja
:emphasize-lines: 1,2
mp: {{ i.1.mp }}
target: {{ i.1.tt }}
result: "{{ lookup('file', target ~ '/templates/' ~ i.0.template) }}"
{% endfor %}
* The results of the below examples 6-9 are all the same:
.. code-block:: yaml
:emphasize-lines: 1-
result:
{{ tests.2.result | to_yaml(indent=2) | indent(5) }}
{% for i in tests[2:3]|subelements('group') %}
{{ loop.index + 5 }}. {{ i.1.d }}
.. code-block:: yaml+jinja
:emphasize-lines: 1,2
mp: {{ i.1.mp }}
target: {{ i.1.tt }}
result: "{{ lookup('file', target ~ '/templates/' ~ i.0.template) }}"
{% endfor %}

View File

@@ -1,79 +0,0 @@
---
# 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
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Create docs REST files
# shell> ansible-playbook playbook.yml
#
# Proofread and copy created *.rst file into the directory
# docs/docsite/rst. Do not add *.rst in this directory to the version
# control.
#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# community.general/docs/docsite/helper/remove_keys/playbook.yml
- name: Create RST file for docs/docsite/rst
hosts: localhost
gather_facts: false
vars:
plugin: remove_keys
plugin_type: filter
docs_path:
- filter_guide
- abstract_informations
- lists_of_dictionaries
file_base: "{{ (docs_path + [plugin]) | join('-') }}"
file_rst: ../../rst/{{ file_base }}.rst
file_sha1: "{{ plugin }}.rst.sha1"
target: "../../../../tests/integration/targets/{{ plugin_type }}_{{ plugin }}"
target_vars: "{{ target }}/vars/main/tests.yml"
target_sha1: tests.yml.sha1
tasks:
- name: Test integrity tests.yml
when:
- integrity | d(true) | bool
- lookup('file', target_sha1) != lookup('pipe', 'sha1sum ' ~ target_vars)
block:
- name: Changed tests.yml
ansible.builtin.debug:
msg: |
Changed {{ target_vars }}
Review the changes and update {{ target_sha1 }}
shell> sha1sum {{ target_vars }} > {{ target_sha1 }}
- name: Changed tests.yml end host
ansible.builtin.meta: end_play
- name: Test integrity RST file
when:
- integrity | d(true) | bool
- lookup('file', file_sha1) != lookup('pipe', 'sha1sum ' ~ file_rst)
block:
- name: Changed RST file
ansible.builtin.debug:
msg: |
Changed {{ file_rst }}
Review the changes and update {{ file_sha1 }}
shell> sha1sum {{ file_rst }} > {{ file_sha1 }}
- name: Changed RST file end host
ansible.builtin.meta: end_play
- name: Include target vars
include_vars:
file: "{{ target_vars }}"
- name: Create RST file
ansible.builtin.template:
src: "{{ file_base }}.rst.j2"
dest: "{{ file_base }}.rst"

View File

@@ -1 +0,0 @@
3cc606b42e3d450cf6323f25930f7c5a591fa086 ../../rst/filter_guide-abstract_informations-lists_of_dictionaries-remove_keys.rst

View File

@@ -1,3 +0,0 @@
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

View File

@@ -1 +0,0 @@
0554335045f02d8c37b824355b0cf86864cee9a5 ../../../../tests/integration/targets/filter_remove_keys/vars/main/tests.yml

View File

@@ -1,3 +0,0 @@
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

View File

@@ -1,61 +0,0 @@
<!--
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
-->
# Docs helper. Create RST file.
The playbook `playbook.yml` writes a RST file that can be used in
docs/docsite/rst. The usage of this helper is recommended but not
mandatory. You can stop reading here and update the RST file manually
if you don't want to use this helper.
## Run the playbook
If you want to generate the RST file by this helper fit the variables
in the playbook and the template to your needs. Then, run the play
```sh
shell> ansible-playbook playbook.yml
```
## Copy RST to docs/docsite/rst
Copy the RST file to `docs/docsite/rst` and remove it from this
directory.
## Update the checksums
Substitute the variables and run the below commands
```sh
shell> sha1sum {{ target_vars }} > {{ target_sha1 }}
shell> sha1sum {{ file_rst }} > {{ file_sha1 }}
```
## Playbook explained
The playbook includes the variable *tests* from the integration tests
and creates the RST file from the template. The playbook will
terminate if:
* The file with the variable *tests* was changed
* The RST file was changed
This means that this helper is probably not up to date.
### The file with the variable *tests* was changed
This means that somebody updated the integration tests. Review the
changes and update the template if needed. Update the checksum to pass
the integrity test. The playbook message provides you with the
command.
### The RST file was changed
This means that somebody updated the RST file manually. Review the
changes and update the template. Update the checksum to pass the
integrity test. The playbook message provides you with the
command. Make sure that the updated template will create identical RST
file. Only then apply your changes.

View File

@@ -1,110 +0,0 @@
..
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
replace_keys
""""""""""""
Use the filter :ansplugin:`community.general.replace_keys#filter` if you have a list of dictionaries and want to replace certain keys.
.. note:: The output of the examples in this section use the YAML callback plugin. Quoting: "Ansible output that can be quite a bit easier to read than the default JSON formatting." See :ansplugin:`the documentation for the community.general.yaml callback plugin <community.general.yaml#callback>`.
Let us use the below list in the following examples:
.. code-block:: yaml
input:
{{ tests.0.input | to_yaml(indent=2) | indent(5) }}
{% for i in tests[0:1]|subelements('group') %}
* {{ i.1.d }}
.. code-block:: yaml+jinja
:emphasize-lines: 1-3
target:
{{ i.1.tt | to_yaml(indent=2) | indent(5) }}
result: "{{ lookup('file', target ~ '/templates/' ~ i.0.template) }}"
{% endfor %}
gives
.. code-block:: yaml
:emphasize-lines: 1-
result:
{{ tests.0.result | to_yaml(indent=2) | indent(5) }}
.. versionadded:: 9.1.0
* The results of the below examples 1-3 are all the same:
.. code-block:: yaml
:emphasize-lines: 1-
result:
{{ tests.1.result | to_yaml(indent=2) | indent(5) }}
{% for i in tests[1:2]|subelements('group') %}
{{ loop.index }}. {{ i.1.d }}
.. code-block:: yaml+jinja
:emphasize-lines: 1-4
mp: {{ i.1.mp }}
target:
{{ i.1.tt | to_yaml(indent=2) | indent(5) }}
result: "{{ lookup('file', target ~ '/templates/' ~ i.0.template) }}"
{% endfor %}
* The results of the below examples 4-5 are the same:
.. code-block:: yaml
:emphasize-lines: 1-
result:
{{ tests.2.result | to_yaml(indent=2) | indent(5) }}
{% for i in tests[2:3]|subelements('group') %}
{{ loop.index + 3 }}. {{ i.1.d }}
.. code-block:: yaml+jinja
:emphasize-lines: 1-3
mp: {{ i.1.mp }}
target:
{{ i.1.tt | to_yaml(indent=2) | indent(5) }}
result: "{{ lookup('file', target ~ '/templates/' ~ i.0.template) }}"
{% endfor %}
{% for i in tests[3:4]|subelements('group') %}
{{ loop.index + 5 }}. {{ i.1.d }}
.. code-block:: yaml
:emphasize-lines: 1-
input:
{{ i.0.input | to_yaml(indent=2) | indent(5) }}
.. code-block:: yaml+jinja
:emphasize-lines: 1-4
mp: {{ i.1.mp }}
target:
{{ i.1.tt | to_yaml(indent=2) | indent(5) }}
result: "{{ lookup('file', target ~ '/templates/' ~ i.0.template) }}"
gives
.. code-block:: yaml
:emphasize-lines: 1-
result:
{{ i.0.result | to_yaml(indent=2) | indent(5) }}
{% endfor %}

View File

@@ -1,79 +0,0 @@
---
# 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
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Create docs REST files
# shell> ansible-playbook playbook.yml
#
# Proofread and copy created *.rst file into the directory
# docs/docsite/rst. Do not add *.rst in this directory to the version
# control.
#
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# community.general/docs/docsite/helper/replace_keys/playbook.yml
- name: Create RST file for docs/docsite/rst
hosts: localhost
gather_facts: false
vars:
plugin: replace_keys
plugin_type: filter
docs_path:
- filter_guide
- abstract_informations
- lists_of_dictionaries
file_base: "{{ (docs_path + [plugin]) | join('-') }}"
file_rst: ../../rst/{{ file_base }}.rst
file_sha1: "{{ plugin }}.rst.sha1"
target: "../../../../tests/integration/targets/{{ plugin_type }}_{{ plugin }}"
target_vars: "{{ target }}/vars/main/tests.yml"
target_sha1: tests.yml.sha1
tasks:
- name: Test integrity tests.yml
when:
- integrity | d(true) | bool
- lookup('file', target_sha1) != lookup('pipe', 'sha1sum ' ~ target_vars)
block:
- name: Changed tests.yml
ansible.builtin.debug:
msg: |
Changed {{ target_vars }}
Review the changes and update {{ target_sha1 }}
shell> sha1sum {{ target_vars }} > {{ target_sha1 }}
- name: Changed tests.yml end host
ansible.builtin.meta: end_play
- name: Test integrity RST file
when:
- integrity | d(true) | bool
- lookup('file', file_sha1) != lookup('pipe', 'sha1sum ' ~ file_rst)
block:
- name: Changed RST file
ansible.builtin.debug:
msg: |
Changed {{ file_rst }}
Review the changes and update {{ file_sha1 }}
shell> sha1sum {{ file_rst }} > {{ file_sha1 }}
- name: Changed RST file end host
ansible.builtin.meta: end_play
- name: Include target vars
include_vars:
file: "{{ target_vars }}"
- name: Create RST file
ansible.builtin.template:
src: "{{ file_base }}.rst.j2"
dest: "{{ file_base }}.rst"

View File

@@ -1 +0,0 @@
403f23c02ac02b1c3b611cb14f9b3ba59dc3f587 ../../rst/filter_guide-abstract_informations-lists_of_dictionaries-replace_keys.rst

View File

@@ -1,3 +0,0 @@
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

View File

@@ -1 +0,0 @@
2e54f3528c95cca746d5748f1ed7ada56ad0890e ../../../../tests/integration/targets/filter_replace_keys/vars/main/tests.yml

View File

@@ -1,3 +0,0 @@
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

View File

@@ -9,8 +9,6 @@ edit_on_github:
path_prefix: '' path_prefix: ''
extra_links: extra_links:
- description: Ask for help
url: https://forum.ansible.com/c/help/6/none
- description: Submit a bug report - description: Submit a bug report
url: https://github.com/ansible-collections/community.general/issues/new?assignees=&labels=&template=bug_report.yml url: https://github.com/ansible-collections/community.general/issues/new?assignees=&labels=&template=bug_report.yml
- description: Request a feature - description: Request a feature
@@ -24,10 +22,6 @@ communication:
- topic: General usage and support questions - topic: General usage and support questions
network: Libera network: Libera
channel: '#ansible' channel: '#ansible'
forums: mailing_lists:
- topic: "Ansible Forum: General usage and support questions" - topic: Ansible Project List
# The following URL directly points to the "Get Help" section url: https://groups.google.com/g/ansible-project
url: https://forum.ansible.com/c/help/6/none
- topic: "Ansible Forum: Discussions about the collection itself, not for specific modules or plugins"
# The following URL directly points to the "community-general" tag
url: https://forum.ansible.com/tag/community-general

View File

@@ -1,151 +0,0 @@
..
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
keep_keys
"""""""""
Use the filter :ansplugin:`community.general.keep_keys#filter` if you have a list of dictionaries and want to keep certain keys only.
.. note:: The output of the examples in this section use the YAML callback plugin. Quoting: "Ansible output that can be quite a bit easier to read than the default JSON formatting." See :ansplugin:`the documentation for the community.general.yaml callback plugin <community.general.yaml#callback>`.
Let us use the below list in the following examples:
.. code-block:: yaml
input:
- k0_x0: A0
k1_x1: B0
k2_x2: [C0]
k3_x3: foo
- k0_x0: A1
k1_x1: B1
k2_x2: [C1]
k3_x3: bar
* By default, match keys that equal any of the items in the target.
.. code-block:: yaml+jinja
:emphasize-lines: 1
target: ['k0_x0', 'k1_x1']
result: "{{ input | community.general.keep_keys(target=target) }}"
gives
.. code-block:: yaml
:emphasize-lines: 1-
result:
- {k0_x0: A0, k1_x1: B0}
- {k0_x0: A1, k1_x1: B1}
.. versionadded:: 9.1.0
* The results of the below examples 1-5 are all the same:
.. code-block:: yaml
:emphasize-lines: 1-
result:
- {k0_x0: A0, k1_x1: B0}
- {k0_x0: A1, k1_x1: B1}
1. Match keys that equal any of the items in the target.
.. code-block:: yaml+jinja
:emphasize-lines: 1,2
mp: equal
target: ['k0_x0', 'k1_x1']
result: "{{ input | community.general.keep_keys(target=target, matching_parameter=mp) }}"
2. Match keys that start with any of the items in the target.
.. code-block:: yaml+jinja
:emphasize-lines: 1,2
mp: starts_with
target: ['k0', 'k1']
result: "{{ input | community.general.keep_keys(target=target, matching_parameter=mp) }}"
3. Match keys that end with any of the items in target.
.. code-block:: yaml+jinja
:emphasize-lines: 1,2
mp: ends_with
target: ['x0', 'x1']
result: "{{ input | community.general.keep_keys(target=target, matching_parameter=mp) }}"
4. Match keys by the regex.
.. code-block:: yaml+jinja
:emphasize-lines: 1,2
mp: regex
target: ['^.*[01]_x.*$']
result: "{{ input | community.general.keep_keys(target=target, matching_parameter=mp) }}"
5. Match keys by the regex.
.. code-block:: yaml+jinja
:emphasize-lines: 1,2
mp: regex
target: ^.*[01]_x.*$
result: "{{ input | community.general.keep_keys(target=target, matching_parameter=mp) }}"
* The results of the below examples 6-9 are all the same:
.. code-block:: yaml
:emphasize-lines: 1-
result:
- {k0_x0: A0}
- {k0_x0: A1}
6. Match keys that equal the target.
.. code-block:: yaml+jinja
:emphasize-lines: 1,2
mp: equal
target: k0_x0
result: "{{ input | community.general.keep_keys(target=target, matching_parameter=mp) }}"
7. Match keys that start with the target.
.. code-block:: yaml+jinja
:emphasize-lines: 1,2
mp: starts_with
target: k0
result: "{{ input | community.general.keep_keys(target=target, matching_parameter=mp) }}"
8. Match keys that end with the target.
.. code-block:: yaml+jinja
:emphasize-lines: 1,2
mp: ends_with
target: x0
result: "{{ input | community.general.keep_keys(target=target, matching_parameter=mp) }}"
9. Match keys by the regex.
.. code-block:: yaml+jinja
:emphasize-lines: 1,2
mp: regex
target: ^.*0_x.*$
result: "{{ input | community.general.keep_keys(target=target, matching_parameter=mp) }}"

View File

@@ -1,159 +0,0 @@
..
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
remove_keys
"""""""""""
Use the filter :ansplugin:`community.general.remove_keys#filter` if you have a list of dictionaries and want to remove certain keys.
.. note:: The output of the examples in this section use the YAML callback plugin. Quoting: "Ansible output that can be quite a bit easier to read than the default JSON formatting." See See :ansplugin:`the documentation for the community.general.yaml callback plugin <community.general.yaml#callback>`.
Let us use the below list in the following examples:
.. code-block:: yaml
input:
- k0_x0: A0
k1_x1: B0
k2_x2: [C0]
k3_x3: foo
- k0_x0: A1
k1_x1: B1
k2_x2: [C1]
k3_x3: bar
* By default, match keys that equal any of the items in the target.
.. code-block:: yaml+jinja
:emphasize-lines: 1
target: ['k0_x0', 'k1_x1']
result: "{{ input | community.general.remove_keys(target=target) }}"
gives
.. code-block:: yaml
:emphasize-lines: 1-
result:
- k2_x2: [C0]
k3_x3: foo
- k2_x2: [C1]
k3_x3: bar
.. versionadded:: 9.1.0
* The results of the below examples 1-5 are all the same:
.. code-block:: yaml
:emphasize-lines: 1-
result:
- k2_x2: [C0]
k3_x3: foo
- k2_x2: [C1]
k3_x3: bar
1. Match keys that equal any of the items in the target.
.. code-block:: yaml+jinja
:emphasize-lines: 1,2
mp: equal
target: ['k0_x0', 'k1_x1']
result: "{{ input | community.general.remove_keys(target=target, matching_parameter=mp) }}"
2. Match keys that start with any of the items in the target.
.. code-block:: yaml+jinja
:emphasize-lines: 1,2
mp: starts_with
target: ['k0', 'k1']
result: "{{ input | community.general.remove_keys(target=target, matching_parameter=mp) }}"
3. Match keys that end with any of the items in target.
.. code-block:: yaml+jinja
:emphasize-lines: 1,2
mp: ends_with
target: ['x0', 'x1']
result: "{{ input | community.general.remove_keys(target=target, matching_parameter=mp) }}"
4. Match keys by the regex.
.. code-block:: yaml+jinja
:emphasize-lines: 1,2
mp: regex
target: ['^.*[01]_x.*$']
result: "{{ input | community.general.remove_keys(target=target, matching_parameter=mp) }}"
5. Match keys by the regex.
.. code-block:: yaml+jinja
:emphasize-lines: 1,2
mp: regex
target: ^.*[01]_x.*$
result: "{{ input | community.general.remove_keys(target=target, matching_parameter=mp) }}"
* The results of the below examples 6-9 are all the same:
.. code-block:: yaml
:emphasize-lines: 1-
result:
- k1_x1: B0
k2_x2: [C0]
k3_x3: foo
- k1_x1: B1
k2_x2: [C1]
k3_x3: bar
6. Match keys that equal the target.
.. code-block:: yaml+jinja
:emphasize-lines: 1,2
mp: equal
target: k0_x0
result: "{{ input | community.general.remove_keys(target=target, matching_parameter=mp) }}"
7. Match keys that start with the target.
.. code-block:: yaml+jinja
:emphasize-lines: 1,2
mp: starts_with
target: k0
result: "{{ input | community.general.remove_keys(target=target, matching_parameter=mp) }}"
8. Match keys that end with the target.
.. code-block:: yaml+jinja
:emphasize-lines: 1,2
mp: ends_with
target: x0
result: "{{ input | community.general.remove_keys(target=target, matching_parameter=mp) }}"
9. Match keys by the regex.
.. code-block:: yaml+jinja
:emphasize-lines: 1,2
mp: regex
target: ^.*0_x.*$
result: "{{ input | community.general.remove_keys(target=target, matching_parameter=mp) }}"

View File

@@ -1,175 +0,0 @@
..
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
replace_keys
""""""""""""
Use the filter :ansplugin:`community.general.replace_keys#filter` if you have a list of dictionaries and want to replace certain keys.
.. note:: The output of the examples in this section use the YAML callback plugin. Quoting: "Ansible output that can be quite a bit easier to read than the default JSON formatting." See :ansplugin:`the documentation for the community.general.yaml callback plugin <community.general.yaml#callback>`.
Let us use the below list in the following examples:
.. code-block:: yaml
input:
- k0_x0: A0
k1_x1: B0
k2_x2: [C0]
k3_x3: foo
- k0_x0: A1
k1_x1: B1
k2_x2: [C1]
k3_x3: bar
* By default, match keys that equal any of the attributes before.
.. code-block:: yaml+jinja
:emphasize-lines: 1-3
target:
- {after: a0, before: k0_x0}
- {after: a1, before: k1_x1}
result: "{{ input | community.general.replace_keys(target=target) }}"
gives
.. code-block:: yaml
:emphasize-lines: 1-
result:
- a0: A0
a1: B0
k2_x2: [C0]
k3_x3: foo
- a0: A1
a1: B1
k2_x2: [C1]
k3_x3: bar
.. versionadded:: 9.1.0
* The results of the below examples 1-3 are all the same:
.. code-block:: yaml
:emphasize-lines: 1-
result:
- a0: A0
a1: B0
k2_x2: [C0]
k3_x3: foo
- a0: A1
a1: B1
k2_x2: [C1]
k3_x3: bar
1. Replace keys that starts with any of the attributes before.
.. code-block:: yaml+jinja
:emphasize-lines: 1-4
mp: starts_with
target:
- {after: a0, before: k0}
- {after: a1, before: k1}
result: "{{ input | community.general.replace_keys(target=target, matching_parameter=mp) }}"
2. Replace keys that ends with any of the attributes before.
.. code-block:: yaml+jinja
:emphasize-lines: 1-4
mp: ends_with
target:
- {after: a0, before: x0}
- {after: a1, before: x1}
result: "{{ input | community.general.replace_keys(target=target, matching_parameter=mp) }}"
3. Replace keys that match any regex of the attributes before.
.. code-block:: yaml+jinja
:emphasize-lines: 1-4
mp: regex
target:
- {after: a0, before: ^.*0_x.*$}
- {after: a1, before: ^.*1_x.*$}
result: "{{ input | community.general.replace_keys(target=target, matching_parameter=mp) }}"
* The results of the below examples 4-5 are the same:
.. code-block:: yaml
:emphasize-lines: 1-
result:
- {X: foo}
- {X: bar}
4. If more keys match the same attribute before the last one will be used.
.. code-block:: yaml+jinja
:emphasize-lines: 1-3
mp: regex
target:
- {after: X, before: ^.*_x.*$}
result: "{{ input | community.general.replace_keys(target=target, matching_parameter=mp) }}"
5. If there are items with equal attribute before the first one will be used.
.. code-block:: yaml+jinja
:emphasize-lines: 1-3
mp: regex
target:
- {after: X, before: ^.*_x.*$}
- {after: Y, before: ^.*_x.*$}
result: "{{ input | community.general.replace_keys(target=target, matching_parameter=mp) }}"
6. If there are more matches for a key the first one will be used.
.. code-block:: yaml
:emphasize-lines: 1-
input:
- {aaa1: A, bbb1: B, ccc1: C}
- {aaa2: D, bbb2: E, ccc2: F}
.. code-block:: yaml+jinja
:emphasize-lines: 1-4
mp: starts_with
target:
- {after: X, before: a}
- {after: Y, before: aa}
result: "{{ input | community.general.replace_keys(target=target, matching_parameter=mp) }}"
gives
.. code-block:: yaml
:emphasize-lines: 1-
result:
- {X: A, bbb1: B, ccc1: C}
- {X: D, bbb2: E, ccc2: F}

View File

@@ -1,18 +0,0 @@
..
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
.. _ansible_collections.community.general.docsite.filter_guide.filter_guide_abstract_informations.lists_of_dicts:
Lists of dictionaries
^^^^^^^^^^^^^^^^^^^^^
Filters to manage keys in a list of dictionaries:
.. toctree::
:maxdepth: 1
filter_guide-abstract_informations-lists_of_dictionaries-keep_keys
filter_guide-abstract_informations-lists_of_dictionaries-remove_keys
filter_guide-abstract_informations-lists_of_dictionaries-replace_keys

View File

@@ -11,7 +11,5 @@ Abstract transformations
filter_guide_abstract_informations_dictionaries filter_guide_abstract_informations_dictionaries
filter_guide_abstract_informations_grouping filter_guide_abstract_informations_grouping
filter_guide-abstract_informations-lists_of_dictionaries
filter_guide_abstract_informations_merging_lists_of_dictionaries filter_guide_abstract_informations_merging_lists_of_dictionaries
filter_guide_abstract_informations_lists_helper
filter_guide_abstract_informations_counting_elements_in_sequence filter_guide_abstract_informations_counting_elements_in_sequence

View File

@@ -6,7 +6,7 @@
Counting elements in a sequence Counting elements in a sequence
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The :ansplugin:`community.general.counter filter plugin <community.general.counter#filter>` allows you to count (hashable) elements in a sequence. Elements are returned as dictionary keys and their counts are stored as dictionary values. The ``community.general.counter`` filter plugin allows you to count (hashable) elements in a sequence. Elements are returned as dictionary keys and their counts are stored as dictionary values.
.. code-block:: yaml+jinja .. code-block:: yaml+jinja

View File

@@ -6,7 +6,7 @@
Dictionaries Dictionaries
^^^^^^^^^^^^ ^^^^^^^^^^^^
You can use the :ansplugin:`community.general.dict_kv filter <community.general.dict_kv#filter>` to create a single-entry dictionary with ``value | community.general.dict_kv(key)``: You can use the ``dict_kv`` filter to create a single-entry dictionary with ``value | community.general.dict_kv(key)``:
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
@@ -58,7 +58,7 @@ This produces:
.. versionadded:: 2.0.0 .. versionadded:: 2.0.0
If you need to convert a list of key-value pairs to a dictionary, you can use the ``dict`` function. Unfortunately, this function cannot be used with ``map``. For this, the :ansplugin:`community.general.dict filter <community.general.dict#filter>` can be used: If you need to convert a list of key-value pairs to a dictionary, you can use the ``dict`` function. Unfortunately, this function cannot be used with ``map``. For this, the ``community.general.dict`` filter can be used:
.. code-block:: yaml+jinja .. code-block:: yaml+jinja

View File

@@ -6,7 +6,7 @@
Grouping Grouping
^^^^^^^^ ^^^^^^^^
If you have a list of dictionaries, the Jinja2 ``groupby`` filter allows to group the list by an attribute. This results in a list of ``(grouper, list)`` namedtuples, where ``list`` contains all dictionaries where the selected attribute equals ``grouper``. If you know that for every ``grouper``, there will be a most one entry in that list, you can use the :ansplugin:`community.general.groupby_as_dict filter <community.general.groupby_as_dict#filter>` to convert the original list into a dictionary which maps ``grouper`` to the corresponding dictionary. If you have a list of dictionaries, the Jinja2 ``groupby`` filter allows to group the list by an attribute. This results in a list of ``(grouper, list)`` namedtuples, where ``list`` contains all dictionaries where the selected attribute equals ``grouper``. If you know that for every ``grouper``, there will be a most one entry in that list, you can use the ``community.general.groupby_as_dict`` filter to convert the original list into a dictionary which maps ``grouper`` to the corresponding dictionary.
One example is ``ansible_facts.mounts``, which is a list of dictionaries where each has one ``device`` element to indicate the device which is mounted. Therefore, ``ansible_facts.mounts | community.general.groupby_as_dict('device')`` is a dictionary mapping a device to the mount information: One example is ``ansible_facts.mounts``, which is a list of dictionaries where each has one ``device`` element to indicate the device which is mounted. Therefore, ``ansible_facts.mounts | community.general.groupby_as_dict('device')`` is a dictionary mapping a device to the mount information:

View File

@@ -1,81 +0,0 @@
..
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
Union, intersection and difference of lists
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Starting with Ansible Core 2.16, the builtin filters :ansplugin:`ansible.builtin.union#filter`, :ansplugin:`ansible.builtin.intersect#filter`, :ansplugin:`ansible.builtin.difference#filter` and :ansplugin:`ansible.builtin.symmetric_difference#filter` began to behave differently and do no longer preserve the item order. Items in the resulting lists are returned in arbitrary order and the order can vary between subsequent runs.
The Ansible community.general collection provides the following additional list filters:
- :ansplugin:`community.general.lists_union#filter`
- :ansplugin:`community.general.lists_intersect#filter`
- :ansplugin:`community.general.lists_difference#filter`
- :ansplugin:`community.general.lists_symmetric_difference#filter`
These filters preserve the item order, eliminate duplicates and are an extended version of the builtin ones, because they can operate on more than two lists.
.. note:: Stick to the builtin filters, when item order is not important or when you do not need the n-ary operating mode. The builtin filters are faster, because they rely mostly on sets as their underlying datastructure.
Let us use the lists below in the following examples:
.. code-block:: yaml
A: [9, 5, 7, 1, 9, 4, 10, 5, 9, 7]
B: [4, 1, 2, 8, 3, 1, 7]
C: [10, 2, 1, 9, 1]
The union of ``A`` and ``B`` can be written as:
.. code-block:: yaml+jinja
result: "{{ A | community.general.lists_union(B) }}"
This statement produces:
.. code-block:: yaml
result: [9, 5, 7, 1, 4, 10, 2, 8, 3]
If you want to calculate the intersection of ``A``, ``B`` and ``C``, you can use the following statement:
.. code-block:: yaml+jinja
result: "{{ A | community.general.lists_intersect(B, C) }}"
Alternatively, you can use a list of lists as an input of the filter
.. code-block:: yaml+jinja
result: "{{ [A, B] | community.general.lists_intersect(C) }}"
or
.. code-block:: yaml+jinja
result: "{{ [A, B, C] | community.general.lists_intersect(flatten=true) }}"
All three statements are equivalent and give:
.. code-block:: yaml
result: [1]
.. note:: Be aware that in most cases, filter calls without any argument require ``flatten=true``, otherwise the input is returned as result. The reason for this is, that the input is considered as a variable argument and is wrapped by an additional outer list. ``flatten=true`` ensures that this list is removed before the input is processed by the filter logic.
The filters :ansplugin:`community.general.lists_difference#filter` or :ansplugin:`community.general.lists_symmetric_difference#filter` can be used in the same way as the filters in the examples above. They calculate the difference or the symmetric difference between two or more lists and preserve the item order.
For example, the symmetric difference of ``A``, ``B`` and ``C`` may be written as:
.. code-block:: yaml+jinja
result: "{{ A | community.general.lists_symmetric_difference(B, C) }}"
This gives:
.. code-block:: yaml
result: [5, 8, 3, 1]

View File

@@ -6,30 +6,33 @@
Merging lists of dictionaries Merging lists of dictionaries
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you have two or more lists of dictionaries and want to combine them into a list of merged dictionaries, where the dictionaries are merged by an attribute, you can use the :ansplugin:`community.general.lists_mergeby <community.general.lists_mergeby#filter>` filter. If you have two or more lists of dictionaries and want to combine them into a list of merged dictionaries, where the dictionaries are merged by an attribute, you can use the ``lists_mergeby`` filter.
.. note:: The output of the examples in this section use the YAML callback plugin. Quoting: "Ansible output that can be quite a bit easier to read than the default JSON formatting." See the documentation for the :ansplugin:`community.general.yaml callback plugin <community.general.yaml#callback>`. .. note:: The output of the examples in this section use the YAML callback plugin. Quoting: "Ansible output that can be quite a bit easier to read than the default JSON formatting." See :ref:`the documentation for the community.general.yaml callback plugin <ansible_collections.community.general.yaml_callback>`.
Let us use the lists below in the following examples: Let us use the lists below in the following examples:
.. code-block:: yaml .. code-block:: yaml
list1: list1:
- {name: foo, extra: true} - name: foo
- {name: bar, extra: false} extra: true
- {name: meh, extra: true} - name: bar
extra: false
- name: meh
extra: true
list2: list2:
- {name: foo, path: /foo} - name: foo
- {name: baz, path: /baz} path: /foo
- name: baz
path: /baz
Two lists
"""""""""
In the example below the lists are merged by the attribute ``name``: In the example below the lists are merged by the attribute ``name``:
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
list3: "{{ list1 | list3: "{{ list1|
community.general.lists_mergeby(list2, 'name') }}" community.general.lists_mergeby(list2, 'name') }}"
This produces: This produces:
@@ -37,21 +40,24 @@ This produces:
.. code-block:: yaml .. code-block:: yaml
list3: list3:
- {name: bar, extra: false} - extra: false
- {name: baz, path: /baz} name: bar
- {name: foo, extra: true, path: /foo} - name: baz
- {name: meh, extra: true} path: /baz
- extra: true
name: foo
path: /foo
- extra: true
name: meh
.. versionadded:: 2.0.0 .. versionadded:: 2.0.0
List of two lists
"""""""""""""""""
It is possible to use a list of lists as an input of the filter: It is possible to use a list of lists as an input of the filter:
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
list3: "{{ [list1, list2] | list3: "{{ [list1, list2]|
community.general.lists_mergeby('name') }}" community.general.lists_mergeby('name') }}"
This produces the same result as in the previous example: This produces the same result as in the previous example:
@@ -59,40 +65,26 @@ This produces the same result as in the previous example:
.. code-block:: yaml .. code-block:: yaml
list3: list3:
- {name: bar, extra: false} - extra: false
- {name: baz, path: /baz} name: bar
- {name: foo, extra: true, path: /foo} - name: baz
- {name: meh, extra: true} path: /baz
- extra: true
Single list name: foo
""""""""""" path: /foo
It is possible to merge single list: - extra: true
name: meh
.. code-block:: yaml+jinja
list3: "{{ [list1 + list2, []] |
community.general.lists_mergeby('name') }}"
This produces the same result as in the previous example:
.. code-block:: yaml
list3:
- {name: bar, extra: false}
- {name: baz, path: /baz}
- {name: foo, extra: true, path: /foo}
- {name: meh, extra: true}
The filter also accepts two optional parameters: :ansopt:`community.general.lists_mergeby#filter:recursive` and :ansopt:`community.general.lists_mergeby#filter:list_merge`. This is available since community.general 4.4.0. The filter also accepts two optional parameters: ``recursive`` and ``list_merge``. These parameters are only supported when used with ansible-base 2.10 or ansible-core, but not with Ansible 2.9. This is available since community.general 4.4.0.
**recursive** **recursive**
Is a boolean, default to ``false``. Should the :ansplugin:`community.general.lists_mergeby#filter` filter recursively merge nested hashes. Note: It does not depend on the value of the ``hash_behaviour`` setting in ``ansible.cfg``. Is a boolean, default to ``False``. Should the ``community.general.lists_mergeby`` recursively merge nested hashes. Note: It does not depend on the value of the ``hash_behaviour`` setting in ``ansible.cfg``.
**list_merge** **list_merge**
Is a string, its possible values are :ansval:`replace` (default), :ansval:`keep`, :ansval:`append`, :ansval:`prepend`, :ansval:`append_rp` or :ansval:`prepend_rp`. It modifies the behaviour of :ansplugin:`community.general.lists_mergeby#filter` when the hashes to merge contain arrays/lists. Is a string, its possible values are ``replace`` (default), ``keep``, ``append``, ``prepend``, ``append_rp`` or ``prepend_rp``. It modifies the behaviour of ``community.general.lists_mergeby`` when the hashes to merge contain arrays/lists.
The examples below set :ansopt:`community.general.lists_mergeby#filter:recursive=true` and display the differences among all six options of :ansopt:`community.general.lists_mergeby#filter:list_merge`. Functionality of the parameters is exactly the same as in the filter :ansplugin:`ansible.builtin.combine#filter`. See :ref:`Combining hashes/dictionaries <combine_filter>` to learn details about these options. The examples below set ``recursive=true`` and display the differences among all six options of ``list_merge``. Functionality of the parameters is exactly the same as in the filter ``combine``. See :ref:`Combining hashes/dictionaries <combine_filter>` to learn details about these options.
Let us use the lists below in the following examples Let us use the lists below in the following examples
@@ -103,7 +95,8 @@ Let us use the lists below in the following examples
param01: param01:
x: default_value x: default_value
y: default_value y: default_value
list: [default_value] list:
- default_value
- name: myname02 - name: myname02
param01: [1, 1, 2, 3] param01: [1, 1, 2, 3]
@@ -112,17 +105,16 @@ Let us use the lists below in the following examples
param01: param01:
y: patch_value y: patch_value
z: patch_value z: patch_value
list: [patch_value] list:
- patch_value
- name: myname02 - name: myname02
param01: [3, 4, 4] param01: [3, 4, 4, {key: value}]
list_merge=replace (default) Example ``list_merge=replace`` (default):
""""""""""""""""""""""""""""
Example :ansopt:`community.general.lists_mergeby#filter:list_merge=replace` (default):
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
list3: "{{ [list1, list2] | list3: "{{ [list1, list2]|
community.general.lists_mergeby('name', community.general.lists_mergeby('name',
recursive=true) }}" recursive=true) }}"
@@ -131,22 +123,25 @@ This produces:
.. code-block:: yaml .. code-block:: yaml
list3: list3:
- name: myname01 - name: myname01
param01: param01:
x: default_value list:
y: patch_value - patch_value
list: [patch_value] x: default_value
z: patch_value y: patch_value
- name: myname02 z: patch_value
param01: [3, 4, 4] - name: myname02
param01:
- 3
- 4
- 4
- key: value
list_merge=keep Example ``list_merge=keep``:
"""""""""""""""
Example :ansopt:`community.general.lists_mergeby#filter:list_merge=keep`:
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
list3: "{{ [list1, list2] | list3: "{{ [list1, list2]|
community.general.lists_mergeby('name', community.general.lists_mergeby('name',
recursive=true, recursive=true,
list_merge='keep') }}" list_merge='keep') }}"
@@ -156,22 +151,25 @@ This produces:
.. code-block:: yaml .. code-block:: yaml
list3: list3:
- name: myname01 - name: myname01
param01: param01:
x: default_value list:
y: patch_value - default_value
list: [default_value] x: default_value
z: patch_value y: patch_value
- name: myname02 z: patch_value
param01: [1, 1, 2, 3] - name: myname02
param01:
- 1
- 1
- 2
- 3
list_merge=append Example ``list_merge=append``:
"""""""""""""""""
Example :ansopt:`community.general.lists_mergeby#filter:list_merge=append`:
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
list3: "{{ [list1, list2] | list3: "{{ [list1, list2]|
community.general.lists_mergeby('name', community.general.lists_mergeby('name',
recursive=true, recursive=true,
list_merge='append') }}" list_merge='append') }}"
@@ -181,22 +179,30 @@ This produces:
.. code-block:: yaml .. code-block:: yaml
list3: list3:
- name: myname01 - name: myname01
param01: param01:
x: default_value list:
y: patch_value - default_value
list: [default_value, patch_value] - patch_value
z: patch_value x: default_value
- name: myname02 y: patch_value
param01: [1, 1, 2, 3, 3, 4, 4] z: patch_value
- name: myname02
param01:
- 1
- 1
- 2
- 3
- 3
- 4
- 4
- key: value
list_merge=prepend Example ``list_merge=prepend``:
""""""""""""""""""
Example :ansopt:`community.general.lists_mergeby#filter:list_merge=prepend`:
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
list3: "{{ [list1, list2] | list3: "{{ [list1, list2]|
community.general.lists_mergeby('name', community.general.lists_mergeby('name',
recursive=true, recursive=true,
list_merge='prepend') }}" list_merge='prepend') }}"
@@ -206,22 +212,30 @@ This produces:
.. code-block:: yaml .. code-block:: yaml
list3: list3:
- name: myname01 - name: myname01
param01: param01:
x: default_value list:
y: patch_value - patch_value
list: [patch_value, default_value] - default_value
z: patch_value x: default_value
- name: myname02 y: patch_value
param01: [3, 4, 4, 1, 1, 2, 3] z: patch_value
- name: myname02
param01:
- 3
- 4
- 4
- key: value
- 1
- 1
- 2
- 3
list_merge=append_rp Example ``list_merge=append_rp``:
""""""""""""""""""""
Example :ansopt:`community.general.lists_mergeby#filter:list_merge=append_rp`:
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
list3: "{{ [list1, list2] | list3: "{{ [list1, list2]|
community.general.lists_mergeby('name', community.general.lists_mergeby('name',
recursive=true, recursive=true,
list_merge='append_rp') }}" list_merge='append_rp') }}"
@@ -231,22 +245,29 @@ This produces:
.. code-block:: yaml .. code-block:: yaml
list3: list3:
- name: myname01 - name: myname01
param01: param01:
x: default_value list:
y: patch_value - default_value
list: [default_value, patch_value] - patch_value
z: patch_value x: default_value
- name: myname02 y: patch_value
param01: [1, 1, 2, 3, 4, 4] z: patch_value
- name: myname02
param01:
- 1
- 1
- 2
- 3
- 4
- 4
- key: value
list_merge=prepend_rp Example ``list_merge=prepend_rp``:
"""""""""""""""""""""
Example :ansopt:`community.general.lists_mergeby#filter:list_merge=prepend_rp`:
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
list3: "{{ [list1, list2] | list3: "{{ [list1, list2]|
community.general.lists_mergeby('name', community.general.lists_mergeby('name',
recursive=true, recursive=true,
list_merge='prepend_rp') }}" list_merge='prepend_rp') }}"
@@ -256,12 +277,21 @@ This produces:
.. code-block:: yaml .. code-block:: yaml
list3: list3:
- name: myname01 - name: myname01
param01: param01:
x: default_value list:
y: patch_value - patch_value
list: [patch_value, default_value] - default_value
z: patch_value x: default_value
- name: myname02 y: patch_value
param01: [3, 4, 4, 1, 1, 2] z: patch_value
- name: myname02
param01:
- 3
- 4
- 4
- key: value
- 1
- 1
- 2

View File

@@ -9,7 +9,7 @@ Conversions
Parsing CSV files Parsing CSV files
^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
Ansible offers the :ansplugin:`community.general.read_csv module <community.general.read_csv#module>` to read CSV files. Sometimes you need to convert strings to CSV files instead. For this, the :ansplugin:`community.general.from_csv filter <community.general.from_csv#filter>` exists. Ansible offers the :ref:`community.general.read_csv module <ansible_collections.community.general.read_csv_module>` to read CSV files. Sometimes you need to convert strings to CSV files instead. For this, the ``from_csv`` filter exists.
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
@@ -42,7 +42,7 @@ This produces:
] ]
} }
The :ansplugin:`community.general.from_csv filter <community.general.from_csv#filter>` has several keyword arguments to control its behavior: The ``from_csv`` filter has several keyword arguments to control its behavior:
:dialect: Dialect of the CSV file. Default is ``excel``. Other possible choices are ``excel-tab`` and ``unix``. If one of ``delimiter``, ``skipinitialspace`` or ``strict`` is specified, ``dialect`` is ignored. :dialect: Dialect of the CSV file. Default is ``excel``. Other possible choices are ``excel-tab`` and ``unix``. If one of ``delimiter``, ``skipinitialspace`` or ``strict`` is specified, ``dialect`` is ignored.
:fieldnames: A set of column names to use. If not provided, the first line of the CSV is assumed to contain the column names. :fieldnames: A set of column names to use. If not provided, the first line of the CSV is assumed to contain the column names.
@@ -55,7 +55,7 @@ The :ansplugin:`community.general.from_csv filter <community.general.from_csv#fi
Converting to JSON Converting to JSON
^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^
`JC <https://pypi.org/project/jc/>`_ is a CLI tool and Python library which allows to interpret output of various CLI programs as JSON. It is also available as a filter in community.general, called :ansplugin:`community.general.jc#filter`. This filter needs the `jc Python library <https://pypi.org/project/jc/>`_ installed on the controller. `JC <https://pypi.org/project/jc/>`_ is a CLI tool and Python library which allows to interpret output of various CLI programs as JSON. It is also available as a filter in community.general. This filter needs the `jc Python library <https://pypi.org/project/jc/>`_ installed on the controller.
.. code-block:: yaml+jinja .. code-block:: yaml+jinja

View File

@@ -11,7 +11,7 @@ The following filters allow to create identifiers.
Hashids Hashids
^^^^^^^ ^^^^^^^
`Hashids <https://hashids.org/>`_ allow to convert sequences of integers to short unique string identifiers. The :ansplugin:`community.general.hashids_encode#filter` and :ansplugin:`community.general.hashids_decode#filter` filters need the `hashids Python library <https://pypi.org/project/hashids/>`_ installed on the controller. `Hashids <https://hashids.org/>`_ allow to convert sequences of integers to short unique string identifiers. This filter needs the `hashids Python library <https://pypi.org/project/hashids/>`_ installed on the controller.
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
@@ -52,7 +52,7 @@ The hashids filters accept keyword arguments to allow fine-tuning the hashids ge
Random MACs Random MACs
^^^^^^^^^^^ ^^^^^^^^^^^
You can use the :ansplugin:`community.general.random_mac filter <community.general.random_mac#filter>` to complete a partial `MAC address <https://en.wikipedia.org/wiki/MAC_address>`_ to a random 6-byte MAC address. You can use the ``random_mac`` filter to complete a partial `MAC address <https://en.wikipedia.org/wiki/MAC_address>`_ to a random 6-byte MAC address.
.. code-block:: yaml+jinja .. code-block:: yaml+jinja

View File

@@ -6,4 +6,14 @@
Paths Paths
----- -----
The :ansplugin:`ansible.builtin.path_join filter <ansible.builtin.path_join#filter>` has been added in ansible-base 2.10. Community.general 3.0.0 and newer contains an alias ``community.general.path_join`` for this filter that could be used on Ansible 2.9 as well. Since community.general no longer supports Ansible 2.9, this is now a simple redirect to :ansplugin:`ansible.builtin.path_join filter <ansible.builtin.path_join#filter>`. The ``path_join`` filter has been added in ansible-base 2.10. If you want to use this filter, but also need to support Ansible 2.9, you can use ``community.general``'s ``path_join`` shim, ``community.general.path_join``. This filter redirects to ``path_join`` for ansible-base 2.10 and ansible-core 2.11 or newer, and re-implements the filter for Ansible 2.9.
.. code-block:: yaml+jinja
# ansible-base 2.10 or newer:
path: {{ ('/etc', path, 'subdir', file) | path_join }}
# Also works with Ansible 2.9:
path: {{ ('/etc', path, 'subdir', file) | community.general.path_join }}
.. versionadded:: 3.0.0

View File

@@ -8,7 +8,7 @@
Selecting JSON data: JSON queries Selecting JSON data: JSON queries
--------------------------------- ---------------------------------
To select a single element or a data subset from a complex data structure in JSON format (for example, Ansible facts), use the :ansplugin:`community.general.json_query filter <community.general.json_query#filter>`. The :ansplugin:`community.general.json_query#filter` filter lets you query a complex JSON structure and iterate over it using a loop structure. To select a single element or a data subset from a complex data structure in JSON format (for example, Ansible facts), use the ``json_query`` filter. The ``json_query`` filter lets you query a complex JSON structure and iterate over it using a loop structure.
.. note:: You must manually install the **jmespath** dependency on the Ansible controller before using this filter. This filter is built upon **jmespath**, and you can use the same syntax. For examples, see `jmespath examples <http://jmespath.org/examples.html>`_. .. note:: You must manually install the **jmespath** dependency on the Ansible controller before using this filter. This filter is built upon **jmespath**, and you can use the same syntax. For examples, see `jmespath examples <http://jmespath.org/examples.html>`_.
@@ -124,7 +124,7 @@ To get a hash map with all ports and names of a cluster:
var: item var: item
loop: "{{ domain_definition | community.general.json_query(server_name_cluster1_query) }}" loop: "{{ domain_definition | community.general.json_query(server_name_cluster1_query) }}"
vars: vars:
server_name_cluster1_query: "domain.server[?cluster=='cluster1'].{name: name, port: port}" server_name_cluster1_query: "domain.server[?cluster=='cluster2'].{name: name, port: port}"
To extract ports from all clusters with name starting with 'server1': To extract ports from all clusters with name starting with 'server1':
@@ -146,4 +146,4 @@ To extract ports from all clusters with name containing 'server1':
vars: vars:
server_name_query: "domain.server[?contains(name,'server1')].port" server_name_query: "domain.server[?contains(name,'server1')].port"
.. note:: while using ``starts_with`` and ``contains``, you have to use ``to_json | from_json`` filter for correct parsing of data structure. .. note:: while using ``starts_with`` and ``contains``, you have to use `` to_json | from_json `` filter for correct parsing of data structure.

View File

@@ -6,9 +6,9 @@
Working with times Working with times
------------------ ------------------
The :ansplugin:`community.general.to_time_unit filter <community.general.to_time_unit#filter>` allows to convert times from a human-readable string to a unit. For example, ``'4h 30min 12second' | community.general.to_time_unit('hour')`` gives the number of hours that correspond to 4 hours, 30 minutes and 12 seconds. The ``to_time_unit`` filter allows to convert times from a human-readable string to a unit. For example, ``'4h 30min 12second' | community.general.to_time_unit('hour')`` gives the number of hours that correspond to 4 hours, 30 minutes and 12 seconds.
There are shorthands to directly convert to various units, like :ansplugin:`community.general.to_hours#filter`, :ansplugin:`community.general.to_minutes#filter`, :ansplugin:`community.general.to_seconds#filter`, and so on. The following table lists all units that can be used: There are shorthands to directly convert to various units, like ``to_hours``, ``to_minutes``, ``to_seconds``, and so on. The following table lists all units that can be used:
.. list-table:: Units .. list-table:: Units
:widths: 25 25 25 25 :widths: 25 25 25 25
@@ -21,37 +21,37 @@ There are shorthands to directly convert to various units, like :ansplugin:`comm
* - Millisecond * - Millisecond
- 1/1000 second - 1/1000 second
- ``ms``, ``millisecond``, ``milliseconds``, ``msec``, ``msecs``, ``msecond``, ``mseconds`` - ``ms``, ``millisecond``, ``milliseconds``, ``msec``, ``msecs``, ``msecond``, ``mseconds``
- :ansplugin:`community.general.to_milliseconds#filter` - ``to_milliseconds``
* - Second * - Second
- 1 second - 1 second
- ``s``, ``sec``, ``secs``, ``second``, ``seconds`` - ``s``, ``sec``, ``secs``, ``second``, ``seconds``
- :ansplugin:`community.general.to_seconds#filter` - ``to_seconds``
* - Minute * - Minute
- 60 seconds - 60 seconds
- ``m``, ``min``, ``mins``, ``minute``, ``minutes`` - ``m``, ``min``, ``mins``, ``minute``, ``minutes``
- :ansplugin:`community.general.to_minutes#filter` - ``to_minutes``
* - Hour * - Hour
- 60*60 seconds - 60*60 seconds
- ``h``, ``hour``, ``hours`` - ``h``, ``hour``, ``hours``
- :ansplugin:`community.general.to_hours#filter` - ``to_hours``
* - Day * - Day
- 24*60*60 seconds - 24*60*60 seconds
- ``d``, ``day``, ``days`` - ``d``, ``day``, ``days``
- :ansplugin:`community.general.to_days#filter` - ``to_days``
* - Week * - Week
- 7*24*60*60 seconds - 7*24*60*60 seconds
- ``w``, ``week``, ``weeks`` - ``w``, ``week``, ``weeks``
- :ansplugin:`community.general.to_weeks#filter` - ``to_weeks``
* - Month * - Month
- 30*24*60*60 seconds - 30*24*60*60 seconds
- ``mo``, ``month``, ``months`` - ``mo``, ``month``, ``months``
- :ansplugin:`community.general.to_months#filter` - ``to_months``
* - Year * - Year
- 365*24*60*60 seconds - 365*24*60*60 seconds
- ``y``, ``year``, ``years`` - ``y``, ``year``, ``years``
- :ansplugin:`community.general.to_years#filter` - ``to_years``
Note that months and years are using a simplified representation: a month is 30 days, and a year is 365 days. If you need different definitions of months or years, you can pass them as keyword arguments. For example, if you want a year to be 365.25 days, and a month to be 30.5 days, you can write ``'11months 4' | community.general.to_years(year=365.25, month=30.5)``. These keyword arguments can be specified to :ansplugin:`community.general.to_time_unit#filter` and to all shorthand filters. Note that months and years are using a simplified representation: a month is 30 days, and a year is 365 days. If you need different definitions of months or years, you can pass them as keyword arguments. For example, if you want a year to be 365.25 days, and a month to be 30.5 days, you can write ``'11months 4' | community.general.to_years(year=365.25, month=30.5)``. These keyword arguments can be specified to ``to_time_unit`` and to all shorthand filters.
.. code-block:: yaml+jinja .. code-block:: yaml+jinja

View File

@@ -6,9 +6,9 @@
Working with Unicode Working with Unicode
--------------------- ---------------------
`Unicode <https://unicode.org/main.html>`_ makes it possible to produce two strings which may be visually equivalent, but are comprised of distinctly different characters/character sequences. To address this Unicode defines `normalization forms <https://unicode.org/reports/tr15/>`_ which avoid these distinctions by choosing a unique character sequence for a given visual representation. `Unicode <https://unicode.org/main.html>`_ makes it possible to produce two strings which may be visually equivalent, but are comprised of distinctly different characters/character sequences. To address this ``Unicode`` defines `normalization forms <https://unicode.org/reports/tr15/>`_ which avoid these distinctions by choosing a unique character sequence for a given visual representation.
You can use the :ansplugin:`community.general.unicode_normalize filter <community.general.unicode_normalize#filter>` to normalize Unicode strings within your playbooks. You can use the ``community.general.unicode_normalize`` filter to normalize ``Unicode`` strings within your playbooks.
.. code-block:: yaml+jinja .. code-block:: yaml+jinja
@@ -28,7 +28,7 @@ This produces:
"msg": true "msg": true
} }
The :ansplugin:`community.general.unicode_normalize filter <community.general.unicode_normalize#filter>` accepts a keyword argument :ansopt:`community.general.unicode_normalize#filter:form` to select the Unicode form used to normalize the input string. The ``community.general.unicode_normalize`` filter accepts a keyword argument to select the ``Unicode`` form used to normalize the input string.
:form: One of ``'NFC'`` (default), ``'NFD'``, ``'NFKC'``, or ``'NFKD'``. See the `Unicode reference <https://unicode.org/reports/tr15/>`_ for more information. :form: One of ``'NFC'`` (default), ``'NFD'``, ``'NFKC'``, or ``'NFKD'``. See the `Unicode reference <https://unicode.org/reports/tr15/>`_ for more information.

View File

@@ -6,7 +6,7 @@
Working with versions Working with versions
--------------------- ---------------------
If you need to sort a list of version numbers, the Jinja ``sort`` filter is problematic. Since it sorts lexicographically, ``2.10`` will come before ``2.9``. To treat version numbers correctly, you can use the :ansplugin:`community.general.version_sort filter <community.general.version_sort#filter>`: If you need to sort a list of version numbers, the Jinja ``sort`` filter is problematic. Since it sorts lexicographically, ``2.10`` will come before ``2.9``. To treat version numbers correctly, you can use the ``version_sort`` filter:
.. code-block:: yaml+jinja .. code-block:: yaml+jinja

View File

@@ -1,96 +0,0 @@
..
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
.. _ansible_collections.community.general.docsite.guide_alicloud:
Alibaba Cloud Compute Services Guide
====================================
Introduction
````````````
The community.general collection contains several modules for controlling and managing Alibaba Cloud Compute Services (Alicloud). This guide
explains how to use the Alicloud Ansible modules together.
All Alicloud modules require ``footmark`` - install it on your control machine with ``pip install footmark``.
Cloud modules, including Alicloud modules, are usually executed on your local machine (the control machine) with ``connection: local``, rather than on remote machines defined in your hosts.
Normally, you'll use the following pattern for plays that provision Alicloud resources:
.. code-block:: yaml
- hosts: localhost
connection: local
vars:
- ...
tasks:
- ...
Authentication
``````````````
You can specify your Alicloud authentication credentials (access key and secret key) by passing them as
environment variables or by storing them in a vars file.
To pass authentication credentials as environment variables:
.. code-block:: console
export ALICLOUD_ACCESS_KEY='Alicloud123'
export ALICLOUD_SECRET_KEY='AlicloudSecret123'
To store authentication credentials in a vars file, encrypt them with :ref:`Ansible Vault <vault>` to keep them secure, then list them:
.. code-block:: yaml
---
alicloud_access_key: "--REMOVED--"
alicloud_secret_key: "--REMOVED--"
Note that if you store your credentials in a vars file, you need to refer to them in each Alicloud module. For example:
.. code-block:: yaml+jinja
- community.general.ali_instance:
alicloud_access_key: "{{ alicloud_access_key }}"
alicloud_secret_key: "{{ alicloud_secret_key }}"
image_id: "..."
Provisioning
````````````
Alicloud modules create Alicloud ECS instances (:ansplugin:`community.general.ali_instance#module`) and retrieve information on these (:ansplugin:`community.general.ali_instance_info#module`).
You can use the ``count`` parameter to control the number of resources you create or terminate. For example, if you want exactly 5 instances tagged ``NewECS``, set the ``count`` of instances to 5 and the ``count_tag`` to ``NewECS``, as shown in the last task of the example playbook below. If there are no instances with the tag ``NewECS``, the task creates 5 new instances. If there are 2 instances with that tag, the task creates 3 more. If there are 8 instances with that tag, the task terminates 3 of those instances.
If you do not specify a ``count_tag``, the task creates the number of instances you specify in ``count`` with the ``instance_name`` you provide.
.. code-block:: yaml+jinja
# alicloud_setup.yml
- hosts: localhost
connection: local
tasks:
- name: Create a set of instances
community.general.ali_instance:
instance_type: ecs.n4.small
image_id: "{{ ami_id }}"
instance_name: "My-new-instance"
instance_tags:
Name: NewECS
Version: 0.0.1
count: 5
count_tag:
Name: NewECS
allocate_public_ip: true
max_bandwidth_out: 50
register: create_instance
In the example playbook above, data about the instances created by this playbook is saved in the variable defined by the ``register`` keyword in the task.
Each Alicloud module offers a variety of parameter options. Not all options are demonstrated in the above example. See each individual module for further details and examples.

View File

@@ -1,499 +0,0 @@
..
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
.. _ansible_collections.community.general.docsite.guide_cmdrunner:
Command Runner guide
====================
Introduction
^^^^^^^^^^^^
The ``ansible_collections.community.general.plugins.module_utils.cmd_runner`` module util provides the
``CmdRunner`` class to help execute external commands. The class is a wrapper around
the standard ``AnsibleModule.run_command()`` method, handling command arguments, localization setting,
output processing output, check mode, and other features.
It is even more useful when one command is used in multiple modules, so that you can define all options
in a module util file, and each module uses the same runner with different arguments.
For the sake of clarity, throughout this guide, unless otherwise specified, we use the term *option* when referring to
Ansible module options, and the term *argument* when referring to the command line arguments for the external command.
Quickstart
""""""""""
``CmdRunner`` defines a command and a set of coded instructions on how to format
the command-line arguments, in which specific order, for a particular execution.
It relies on ``ansible.module_utils.basic.AnsibleModule.run_command()`` to actually execute the command.
There are other features, see more details throughout this document.
To use ``CmdRunner`` you must start by creating an object. The example below is a simplified
version of the actual code in :ansplugin:`community.general.ansible_galaxy_install#module`:
.. code-block:: python
from ansible_collections.community.general.plugins.module_utils.cmd_runner import CmdRunner, cmd_runner_fmt
runner = CmdRunner(
module,
command="ansible-galaxy",
arg_formats=dict(
type=cmd_runner_fmt.as_func(lambda v: [] if v == 'both' else [v]),
galaxy_cmd=cmd_runner_fmt.as_list(),
upgrade=cmd_runner_fmt.as_bool("--upgrade"),
requirements_file=cmd_runner_fmt.as_opt_val('-r'),
dest=cmd_runner_fmt.as_opt_val('-p'),
force=cmd_runner_fmt.as_bool("--force"),
no_deps=cmd_runner_fmt.as_bool("--no-deps"),
version=cmd_runner_fmt.as_fixed("--version"),
name=cmd_runner_fmt.as_list(),
)
)
This is meant to be done once, then every time you need to execute the command you create a context and pass values as needed:
.. code-block:: python
# Run the command with these arguments, when values exist for them
with runner("type galaxy_cmd upgrade force no_deps dest requirements_file name", output_process=process) as ctx:
ctx.run(galaxy_cmd="install", upgrade=upgrade)
# version is fixed, requires no value
with runner("version") as ctx:
dummy, stdout, dummy = ctx.run()
# passes arg 'data' to AnsibleModule.run_command()
with runner("type name", data=stdin_data) as ctx:
dummy, stdout, dummy = ctx.run()
# Another way of expressing it
dummy, stdout, dummy = runner("version").run()
Note that you can pass values for the arguments when calling ``run()``, otherwise ``CmdRunner``
uses the module options with the exact same names to provide values for the runner arguments.
If no value is passed and no module option is found for the name specified, then an exception is raised, unless
the argument is using ``cmd_runner_fmt.as_fixed`` as format function like the ``version`` in the example above.
See more about it below.
In the first example, values of ``type``, ``force``, ``no_deps`` and others
are taken straight from the module, whilst ``galaxy_cmd`` and ``upgrade`` are
passed explicitly.
.. note::
It is not possible to automatically retrieve values of suboptions.
That generates a resulting command line similar to (example taken from the
output of an integration test):
.. code-block:: python
[
"<venv>/bin/ansible-galaxy",
"collection",
"install",
"--upgrade",
"-p",
"<collection-install-path>",
"netbox.netbox",
]
Argument formats
^^^^^^^^^^^^^^^^
As seen in the example, ``CmdRunner`` expects a parameter named ``arg_formats``
defining how to format each CLI named argument.
An "argument format" is nothing but a function to transform the value of a variable
into something formatted for the command line.
Argument format function
""""""""""""""""""""""""
An ``arg_format`` function is defined in the form similar to:
.. code-block:: python
def func(value):
return ["--some-param-name", value]
The parameter ``value`` can be of any type - although there are convenience
mechanisms to help handling sequence and mapping objects.
The result is expected to be of the type ``Sequence[str]`` type (most commonly
``list[str]`` or ``tuple[str]``), otherwise it is considered to be a ``str``,
and it is coerced into ``list[str]``.
This resulting sequence of strings is added to the command line when that
argument is actually used.
For example, if ``func`` returns:
- ``["nee", 2, "shruberries"]``, the command line adds arguments ``"nee" "2" "shruberries"``.
- ``2 == 2``, the command line adds argument ``True``.
- ``None``, the command line adds argument ``None``.
- ``[]``, the command line adds no command line argument for that particular argument.
Convenience format methods
""""""""""""""""""""""""""
In the same module as ``CmdRunner`` there is a class ``cmd_runner_fmt`` which
provides a set of convenience methods that return format functions for common cases.
In the first block of code in the `Quickstart`_ section you can see the importing of
that class:
.. code-block:: python
from ansible_collections.community.general.plugins.module_utils.cmd_runner import CmdRunner, cmd_runner_fmt
The same example shows how to make use of some of them in the instantiation of the ``CmdRunner`` object.
A description of each one of the convenience methods available and examples of how to use them is found below.
In these descriptions ``value`` refers to the single parameter passed to the formatting function.
- ``cmd_runner_fmt.as_list()``
This method does not receive any parameter, function returns ``value`` as-is.
- Creation:
``cmd_runner_fmt.as_list()``
- Examples:
+----------------------+---------------------+
| Value | Outcome |
+======================+=====================+
| ``["foo", "bar"]`` | ``["foo", "bar"]`` |
+----------------------+---------------------+
| ``"foobar"`` | ``["foobar"]`` |
+----------------------+---------------------+
- ``cmd_runner_fmt.as_bool()``
This method receives two different parameters: ``args_true`` and ``args_false``, latter being optional.
If the boolean evaluation of ``value`` is ``True``, the format function returns ``args_true``.
If the boolean evaluation is ``False``, then the function returns ``args_false`` if it was provided, or ``[]`` otherwise.
- Creation (one arg):
``cmd_runner_fmt.as_bool("--force")``
- Examples:
+------------+--------------------+
| Value | Outcome |
+============+====================+
| ``True`` | ``["--force"]`` |
+------------+--------------------+
| ``False`` | ``[]`` |
+------------+--------------------+
- Creation (two args, ``None`` treated as ``False``):
``cmd_runner_fmt.as_bool("--relax", "--dont-do-it")``
- Examples:
+------------+----------------------+
| Value | Outcome |
+============+======================+
| ``True`` | ``["--relax"]`` |
+------------+----------------------+
| ``False`` | ``["--dont-do-it"]`` |
+------------+----------------------+
| | ``["--dont-do-it"]`` |
+------------+----------------------+
- Creation (two args, ``None`` is ignored):
``cmd_runner_fmt.as_bool("--relax", "--dont-do-it", ignore_none=True)``
- Examples:
+------------+----------------------+
| Value | Outcome |
+============+======================+
| ``True`` | ``["--relax"]`` |
+------------+----------------------+
| ``False`` | ``["--dont-do-it"]`` |
+------------+----------------------+
| | ``[]`` |
+------------+----------------------+
- ``cmd_runner_fmt.as_bool_not()``
This method receives one parameter, which is returned by the function when the boolean evaluation
of ``value`` is ``False``.
- Creation:
``cmd_runner_fmt.as_bool_not("--no-deps")``
- Examples:
+-------------+---------------------+
| Value | Outcome |
+=============+=====================+
| ``True`` | ``[]`` |
+-------------+---------------------+
| ``False`` | ``["--no-deps"]`` |
+-------------+---------------------+
- ``cmd_runner_fmt.as_optval()``
This method receives one parameter ``arg``, the function returns the string concatenation
of ``arg`` and ``value``.
- Creation:
``cmd_runner_fmt.as_optval("-i")``
- Examples:
+---------------+---------------------+
| Value | Outcome |
+===============+=====================+
| ``3`` | ``["-i3"]`` |
+---------------+---------------------+
| ``foobar`` | ``["-ifoobar"]`` |
+---------------+---------------------+
- ``cmd_runner_fmt.as_opt_val()``
This method receives one parameter ``arg``, the function returns ``[arg, value]``.
- Creation:
``cmd_runner_fmt.as_opt_val("--name")``
- Examples:
+--------------+--------------------------+
| Value | Outcome |
+==============+==========================+
| ``abc`` | ``["--name", "abc"]`` |
+--------------+--------------------------+
- ``cmd_runner_fmt.as_opt_eq_val()``
This method receives one parameter ``arg``, the function returns the string of the form
``{arg}={value}``.
- Creation:
``cmd_runner_fmt.as_opt_eq_val("--num-cpus")``
- Examples:
+------------+-------------------------+
| Value | Outcome |
+============+=========================+
| ``10`` | ``["--num-cpus=10"]`` |
+------------+-------------------------+
- ``cmd_runner_fmt.as_fixed()``
This method receives one parameter ``arg``, the function expects no ``value`` - if one
is provided then it is ignored.
The function returns ``arg`` as-is.
- Creation:
``cmd_runner_fmt.as_fixed("--version")``
- Examples:
+---------+-----------------------+
| Value | Outcome |
+=========+=======================+
| | ``["--version"]`` |
+---------+-----------------------+
| 57 | ``["--version"]`` |
+---------+-----------------------+
- Note:
This is the only special case in which a value can be missing for the formatting function.
The example also comes from the code in `Quickstart`_.
In that case, the module has code to determine the command's version so that it can assert compatibility.
There is no *value* to be passed for that CLI argument.
- ``cmd_runner_fmt.as_map()``
This method receives one parameter ``arg`` which must be a dictionary, and an optional parameter ``default``.
The function returns the evaluation of ``arg[value]``.
If ``value not in arg``, then it returns ``default`` if defined, otherwise ``[]``.
- Creation:
``cmd_runner_fmt.as_map(dict(a=1, b=2, c=3), default=42)``
- Examples:
+---------------------+---------------+
| Value | Outcome |
+=====================+===============+
| ``"b"`` | ``["2"]`` |
+---------------------+---------------+
| ``"yabadabadoo"`` | ``["42"]`` |
+---------------------+---------------+
- Note:
If ``default`` is not specified, invalid values return an empty list, meaning they are silently ignored.
- ``cmd_runner_fmt.as_func()``
This method receives one parameter ``arg`` which is itself is a format function and it must abide by the rules described above.
- Creation:
``cmd_runner_fmt.as_func(lambda v: [] if v == 'stable' else ['--channel', '{0}'.format(v)])``
- Note:
The outcome for that depends entirely on the function provided by the developer.
Other features for argument formatting
""""""""""""""""""""""""""""""""""""""
Some additional features are available as decorators:
- ``cmd_runner_fmt.unpack args()``
This decorator unpacks the incoming ``value`` as a list of elements.
For example, in ``ansible_collections.community.general.plugins.module_utils.puppet``, it is used as:
.. code-block:: python
@cmd_runner_fmt.unpack_args
def execute_func(execute, manifest):
if execute:
return ["--execute", execute]
else:
return [manifest]
runner = CmdRunner(
module,
command=_prepare_base_cmd(),
path_prefix=_PUPPET_PATH_PREFIX,
arg_formats=dict(
# ...
_execute=cmd_runner_fmt.as_func(execute_func),
# ...
),
)
Then, in :ansplugin:`community.general.puppet#module` it is put to use with:
.. code-block:: python
with runner(args_order) as ctx:
rc, stdout, stderr = ctx.run(_execute=[p['execute'], p['manifest']])
- ``cmd_runner_fmt.unpack_kwargs()``
Conversely, this decorator unpacks the incoming ``value`` as a ``dict``-like object.
- ``cmd_runner_fmt.stack()``
This decorator assumes ``value`` is a sequence and concatenates the output
of the wrapped function applied to each element of the sequence.
For example, in :ansplugin:`community.general.django_check#module`, the argument format for ``database``
is defined as:
.. code-block:: python
arg_formats = dict(
# ...
database=cmd_runner_fmt.stack(cmd_runner_fmt.as_opt_val)("--database"),
# ...
)
When receiving a list ``["abc", "def"]``, the output is:
.. code-block:: python
["--database", "abc", "--database", "def"]
Command Runner
^^^^^^^^^^^^^^
Settings that can be passed to the ``CmdRunner`` constructor are:
- ``module: AnsibleModule``
Module instance. Mandatory parameter.
- ``command: str | list[str]``
Command to be executed. It can be a single string, the executable name, or a list
of strings containing the executable name as the first element and, optionally, fixed parameters.
Those parameters are used in all executions of the runner.
The *executable* pointed by this parameter (whether itself when ``str`` or its first element when ``list``) is
processed using ``AnsibleModule.get_bin_path()`` *unless* it is an absolute path or contains the character ``/``.
- ``arg_formats: dict``
Mapping of argument names to formatting functions.
- ``default_args_order: str``
As the name suggests, a default ordering for the arguments. When
this is passed, the context can be created without specifying ``args_order``. Defaults to ``()``.
- ``check_rc: bool``
When ``True``, if the return code from the command is not zero, the module exits
with an error. Defaults to ``False``.
- ``path_prefix: list[str]``
If the command being executed is installed in a non-standard directory path,
additional paths might be provided to search for the executable. Defaults to ``None``.
- ``environ_update: dict``
Pass additional environment variables to be set during the command execution.
Defaults to ``None``.
- ``force_lang: str``
It is usually important to force the locale to one specific value, so that responses are consistent and, therefore, parseable.
Please note that using this option (which is enabled by default) overwrites the environment variables ``LANGUAGE`` and ``LC_ALL``.
To disable this mechanism, set this parameter to ``None``.
In community.general 9.1.0 a special value ``auto`` was introduced for this parameter, with the effect
that ``CmdRunner`` then tries to determine the best parseable locale for the runtime.
It should become the default value in the future, but for the time being the default value is ``C``.
When creating a context, the additional settings that can be passed to the call are:
- ``args_order: str``
Establishes the order in which the arguments are rendered in the command line.
This parameter is mandatory unless ``default_args_order`` was provided to the runner instance.
- ``output_process: func``
Function to transform the output of the executable into different values or formats.
See examples in section below.
- ``check_mode_skip: bool``
Whether to skip the actual execution of the command when the module is in check mode.
Defaults to ``False``.
- ``check_mode_return: any``
If ``check_mode_skip=True``, then return this value instead.
- valid named arguments to ``AnsibleModule.run_command()``
Other than ``args``, any valid argument to ``run_command()`` can be passed when setting up the run context.
For example, ``data`` can be used to send information to the command's standard input.
Or ``cwd`` can be used to run the command inside a specific working directory.
Additionally, any other valid parameters for ``AnsibleModule.run_command()`` may be passed, but unexpected behavior
might occur if redefining options already present in the runner or its context creation. Use with caution.
Processing results
^^^^^^^^^^^^^^^^^^
As mentioned, ``CmdRunner`` uses ``AnsibleModule.run_command()`` to execute the external command,
and it passes the return value from that method back to caller. That means that,
by default, the result is going to be a tuple ``(rc, stdout, stderr)``.
If you need to transform or process that output, you can pass a function to the context,
as the ``output_process`` parameter. It must be a function like:
.. code-block:: python
def process(rc, stdout, stderr):
# do some magic
return processed_value # whatever that is
In that case, the return of ``run()`` is the ``processed_value`` returned by the function.
PythonRunner
^^^^^^^^^^^^
The ``PythonRunner`` class is a specialized version of ``CmdRunner``, geared towards the execution of
Python scripts. It features two extra and mutually exclusive parameters ``python`` and ``venv`` in its constructor:
.. code-block:: python
from ansible_collections.community.general.plugins.module_utils.python_runner import PythonRunner
from ansible_collections.community.general.plugins.module_utils.cmd_runner import cmd_runner_fmt
runner = PythonRunner(
module,
command=["-m", "django"],
arg_formats=dict(...),
python="python",
venv="/path/to/some/venv",
)
The default value for ``python`` is the string ``python``, and the for ``venv`` it is ``None``.
The command line produced by such a command with ``python="python3.12"`` is something like:
.. code-block:: shell
/usr/bin/python3.12 -m django <arg1> <arg2> ...
And the command line for ``venv="/work/venv"`` is like:
.. code-block:: shell
/work/venv/bin/python -m django <arg1> <arg2> ...
You may provide the value of the ``command`` argument as a string (in that case the string is used as a script name)
or as a list, in which case the elements of the list must be valid arguments for the Python interpreter, as in the example above.
See `Command line and environment <https://docs.python.org/3/using/cmdline.html>`_ for more details.
If the parameter ``python`` is an absolute path, or contains directory separators, such as ``/``, then it is used
as-is, otherwise the runtime ``PATH`` is searched for that command name.
Other than that, everything else works as in ``CmdRunner``.
.. versionadded:: 4.8.0

Some files were not shown because too many files have changed in this diff Show More