53 Commits
1.1.1 ... 1.2.0

Author SHA1 Message Date
ansible-zuul[bot]
bd8a3f35c2 Merge pull request #153 from Andersson007/release_branch
Release 1.2.0 commit

Reviewed-by: https://github.com/apps/ansible-zuul
2021-03-08 15:07:36 +00:00
Andrew Klychkov
edec4d767d Release 1.2.0 commit 2021-03-08 13:45:10 +01:00
ansible-zuul[bot]
0a56fb0e46 Merge pull request #150 from Andersson007/add_missed_changelog_fragments
Add missed changelog fragments

Reviewed-by: https://github.com/apps/ansible-zuul
2021-03-08 10:56:18 +00:00
Andrew Klychkov
f3b6b5e690 fix a fragment 2021-03-08 10:54:51 +01:00
Andrew Klychkov
d65a36e9ea Add missed changelog fragments 2021-03-08 10:02:48 +01:00
ansible-zuul[bot]
252b531c20 Merge pull request #120 from pneerincx/bugfix_for_24365
Bugfix for #24365: "Added option to allow SSH connection multiplexing"

Reviewed-by: https://github.com/apps/ansible-zuul
2021-03-05 18:30:48 +00:00
ansible-zuul[bot]
bc88258687 Merge pull request #118 from pneerincx/bugfix_for_17492
Bugfix for #17492 "Do not prepend PWD when path is in form user@server:path or server:path" 

Reviewed-by: https://github.com/apps/ansible-zuul
2021-03-05 18:26:53 +00:00
ansible-zuul[bot]
1747370f30 Merge pull request #144 from xlab-steampunk/teach-synchronize-about-community-docker
Inform synchronize module about community.docker collection

Reviewed-by: https://github.com/apps/ansible-zuul
2021-03-05 17:49:45 +00:00
ansible-zuul[bot]
72353d3f04 Merge pull request #143 from mperry2/acldocs
Update documentation for ACL permissions

Reviewed-by: https://github.com/apps/ansible-zuul
2021-03-05 16:48:50 +00:00
John R Barker
1822789d95 Merge branch 'main' into acldocs 2021-03-05 15:47:30 +00:00
John R Barker
ccbb679fc3 Formatting 2021-03-05 15:46:19 +00:00
Tadej Borovšak
98c86c54cd Inform synchronize module about community.docker collection
The synchronize action plugin has a built-in list of connection
plugins that it knows how to handle.

One of those connection plugins is the docker connection plugin. And
because the docker content has been moved around quite a lot, the
docker connection plugin has quite a few names:

 - docker in Ansible 2.9,
 - community.general.docker for community.general < 2.0.0, and
 - community.docker.docker since a few months ago.

And while the synchronize module already knew about the first two
names, the last one was still missing. This commit fixes that omission
and adds a third name into the mix.
2021-03-05 16:42:43 +01:00
ansible-zuul[bot]
354239d6c9 Merge pull request #147 from Andersson007/update_distr_azp
Update azure-pipelines.yml and README.md

Reviewed-by: https://github.com/apps/ansible-zuul
2021-03-05 15:40:04 +00:00
Andrew Klychkov
4825036c7e Update AZP aggregate-coverage.sh and report-coverage.sh 2021-03-05 14:25:22 +01:00
Andrew Klychkov
360d0c3441 Update azure-pipelines.yml and README.md 2021-03-05 13:53:38 +01:00
ansible-zuul[bot]
d8fb68514c Merge pull request #138 from Akasurde/sanity_fix
Fix sanity test for modules

Reviewed-by: https://github.com/apps/ansible-zuul
2021-03-02 16:27:55 +00:00
ansible-zuul[bot]
d8c6add988 Merge pull request #140 from Akasurde/posix_ci_fix
Update OS as per guidelines

Reviewed-by: https://github.com/apps/ansible-zuul
2021-03-02 15:07:09 +00:00
Abhijeet Kasurde
ea8fc70373 Fix sanity test for modules
Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
2021-03-02 18:53:06 +05:30
ansible-zuul[bot]
20f70caa1f Merge pull request #141 from Andersson007/update_default_container_ver
azure-pipelines: update default container version

Reviewed-by: https://github.com/apps/ansible-zuul
2021-03-02 13:03:37 +00:00
Abhijeet Kasurde
04f976d7d3 Update OS as per guidelines
Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
2021-03-02 17:43:15 +05:30
ansible-zuul[bot]
b6a2dee8bb Merge pull request #145 from Andersson007/remove_sanity_requirements_txt
Remove tests/sanity/requirements.txt

Reviewed-by: https://github.com/apps/ansible-zuul
2021-03-02 12:11:34 +00:00
Andrew Klychkov
5b66052067 remove upper bound (2.11) from meta/runtime.yml 2021-03-02 11:55:38 +01:00
Andrew Klychkov
2655a6ffc1 remove changelogs/fragments/.empty 2021-03-02 11:47:07 +01:00
Andrew Klychkov
bbba9beb70 Add tests/sanity/ignore-2.11.txt 2021-03-02 11:20:44 +01:00
Andrew Klychkov
a8594c5477 Remove tests/sanity/requirements.txt 2021-03-01 16:47:09 +01:00
Matt Perry
3043f737a0 Update ACL documentation
Update ACL documentation to describe support for the `X` permission for the `setfacl` command.
2021-02-25 11:40:32 -08:00
Andrew Klychkov
080ae28e7d azure-pipelines: update default container version 2021-02-18 19:21:52 +03:00
John R Barker
e1dad76ccb AZP: Ensure collection dir is writable (#139) 2021-02-15 09:57:03 +00:00
ansible-zuul[bot]
bc0fb3096b Merge pull request #129 from evan-a-a/main
firewalld: Add support for firewalld port forwarding

Reviewed-by: Adam Miller <admiller@redhat.com>
             https://github.com/maxamillion
2021-01-18 20:06:36 +00:00
Evan Anderson
1e7d82af6d firewalld: Add support for firewalld port forwarding
Fixes: ansible-collections/ansible.posix#100
2021-01-16 19:05:44 -06:00
ansible-zuul[bot]
41d49e4e08 Merge pull request #123 from gundalow/azp-coverage
AZP: Install ansible-test for coverage

Reviewed-by: https://github.com/apps/ansible-zuul
2020-12-11 16:11:34 +00:00
John Barker
6241e09ccd AZP: Install ansible-test for coverage 2020-12-11 15:33:50 +00:00
ansible-zuul[bot]
679fe78f32 Merge pull request #122 from gundalow/azp-readme-badge
AZP Badge for README.md

Reviewed-by: shipabull
             https://github.com/shipabull
2020-12-11 15:05:42 +00:00
John Barker
b8c5d6b1b7 AZP Badge for README.md 2020-12-11 14:30:52 +00:00
pneerincx
665f84d996 Removed trailing whitespace to satisfy PEP8 rule W291. 2020-12-11 15:16:03 +01:00
ansible-zuul[bot]
c359200e80 Merge pull request #121 from gundalow/azp-initial
Initial Azure Pipeline config

Reviewed-by: https://github.com/apps/ansible-zuul
2020-12-11 14:10:43 +00:00
John Barker
793b039691 Initial Azure Pipeline config 2020-12-11 13:29:10 +00:00
ansible-zuul[bot]
ef36fdc17d Merge pull request #119 from Fale/synchronize
fix indentation in doc

Reviewed-by: https://github.com/apps/ansible-zuul
2020-12-11 05:27:22 +00:00
Fabio Alessandro Locati
bcb08106d9 fix indentation in doc 2020-12-10 21:40:09 +01:00
pneerincx
cbf54f214c Added option to allow SSH connection multiplixing as opposed to hard-coded disabling it. Fixes bug #24365. 2020-12-10 20:52:34 +01:00
pneerincx
931326fb70 Bugfix for #17492. 2020-12-09 18:19:32 +01:00
ansible-zuul[bot]
6343dbdcff Merge pull request #113 from St0rmingBr4in/main
firewalld: bring back zone target set

Reviewed-by: Adam Miller <admiller@redhat.com>
             https://github.com/maxamillion
2020-12-01 18:27:47 +00:00
Adam Miller
34a12eb3f9 firewalld: add zone target set (#526)
* firewalld: add zone target set

Fixes https://github.com/ansible/ansible/issues/49232

Signed-off-by: Adam Miller <admiller@redhat.com>

* fix sanity tests, add example of zone target setting

Signed-off-by: Adam Miller <admiller@redhat.com>

* test different zone/target combination as we're not hitting default settings

Signed-off-by: Adam Miller <admiller@redhat.com>

* fix enabled values for zone operations

Signed-off-by: Adam Miller <admiller@redhat.com>

* Apply suggestions from code review

Co-authored-by: Felix Fontein <felix@fontein.de>

Co-authored-by: Felix Fontein <felix@fontein.de>
2020-11-16 12:14:10 +01:00
ansible-zuul[bot]
402e0b1f76 Merge pull request #103 from maxamillion/changelogs/add-changelog-fragment-for-pr101
add changelog fragment for PR#101

Reviewed-by: https://github.com/apps/ansible-zuul
2020-10-26 14:46:29 +00:00
Adam Miller
1268d4aa0a add changelog fragment for PR#101
Signed-off-by: Adam Miller <admiller@redhat.com>
2020-10-23 15:08:26 -05:00
ansible-zuul[bot]
5988748999 Merge pull request #101 from schurzi/main
do not persist sysctl when value is invalid

Reviewed-by: https://github.com/apps/ansible-zuul
2020-10-21 22:30:30 +00:00
Martin Schurz
5935dce47f do not persist sysctl when value is invalid
the order of actions for setting, persisting and activation is changed,
to not persist an invalid sysctl value. This is only enforced when
sysct_set is True.
2020-10-02 23:03:14 +02:00
ansible-zuul[bot]
77df4ba3fd Merge pull request #99 from dberg1/main
at: add support for AIX

Reviewed-by: https://github.com/apps/ansible-zuul
2020-09-25 16:13:04 +00:00
dberg1
1e84bce91a at: add support for AIX
AIX uses -lv options to cat a job (instead of -c for Linux).
AIX uses -r to remove a job.
Linux supports both -r and -d, so use -r since it is what POSIX says.
2020-09-25 08:59:34 +02:00
ansible-zuul[bot]
d1fff45191 Merge pull request #82 from bmv126/synchronize_private_key_issue
Fix for private_key overriding in synchronize module

Reviewed-by: Adam Miller <admiller@redhat.com>
             https://github.com/maxamillion
2020-09-18 05:24:11 +00:00
ansible-zuul[bot]
0eeaf61a1a Merge pull request #97 from rystraum/patch-1
Updated description of `use_ssh_args` option for synchronize.py

Reviewed-by: https://github.com/apps/ansible-zuul
2020-09-18 03:14:37 +00:00
Rystraum Gamonez
c96be65ec9 Updated description of use_ssh_args option
This option has interactions with `ansible_ssh_common_args` as indicated in this issue thread: https://github.com/ansible/ansible/issues/16767
2020-09-12 12:41:09 +08:00
vishwas
4b0b50439d Fix for private_key overriding in synchronize module 2020-09-04 04:16:43 -04:00
66 changed files with 3094 additions and 109 deletions

View File

@@ -0,0 +1,3 @@
## Azure Pipelines Configuration
Please see the [Documentation](https://github.com/ansible/community/wiki/Testing:-Azure-Pipelines) for more information.

View File

@@ -0,0 +1,193 @@
trigger:
batch: true
branches:
include:
- main
- stable-*
pr:
autoCancel: true
branches:
include:
- main
- stable-*
schedules:
- cron: 0 9 * * *
displayName: Nightly
always: true
branches:
include:
- main
- stable-*
variables:
- name: checkoutPath
value: ansible_collections/ansible/posix
- 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:1.8.0
pool: Standard
stages:
## Docker
- stage: Docker_devel
displayName: Docker devel
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: devel/linux/{0}/1
targets:
- name: CentOS 6
test: centos6
- name: CentOS 7
test: centos7
- name: CentOS 8
test: centos8
- name: Fedora 32
test: fedora32
- name: Fedora 33
test: fedora33
- name: openSUSE 15 py2
test: opensuse15py2
- name: openSUSE 15 py3
test: opensuse15
- name: Ubuntu 18.04
test: ubuntu1804
- name: Ubuntu 20.04
test: ubuntu2004
- stage: Docker_2_10
displayName: Docker 2.10
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.10/linux/{0}/1
targets:
- name: CentOS 6
test: centos6
- name: CentOS 7
test: centos7
- name: CentOS 8
test: centos8
- name: Fedora 30
test: fedora30
- name: Fedora 31
test: fedora31
- name: openSUSE 15 py2
test: opensuse15py2
- name: openSUSE 15 py3
test: opensuse15
- name: Ubuntu 16.04
test: ubuntu1604
- name: Ubuntu 18.04
test: ubuntu1804
- stage: Docker_2_9
displayName: Docker 2.9
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.9/linux/{0}/1
targets:
- name: CentOS 6
test: centos6
- name: CentOS 7
test: centos7
- name: CentOS 8
test: centos8
- name: Fedora 30
test: fedora30
- name: Fedora 31
test: fedora31
- name: openSUSE 15 py2
test: opensuse15py2
- name: openSUSE 15 py3
test: opensuse15
- name: Ubuntu 16.04
test: ubuntu1604
- name: Ubuntu 18.04
test: ubuntu1804
## Remote
- stage: Remote_devel
displayName: Remote devel
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: devel/{0}/1
targets:
- name: MacOS 11.1
test: macos/11.1
- name: RHEL 7.9
test: rhel/7.9
- name: RHEL 8.3
test: rhel/8.3
- name: FreeBSD 11.4
test: freebsd/11.4
- name: FreeBSD 12.2
test: freebsd/12.2
- stage: Remote_2_10
displayName: Remote 2.10
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.10/{0}/1
targets:
- name: OS X 10.11
test: osx/10.11
- name: RHEL 7.6
test: rhel/7.6
- name: RHEL 8.2
test: rhel/8.2
- name: FreeBSD 11.1
test: freebsd/11.1
- name: FreeBSD 12.1
test: freebsd/12.1
- stage: Remote_2_9
displayName: Remote 2.9
dependsOn: []
jobs:
- template: templates/matrix.yml
parameters:
testFormat: 2.9/{0}/1
targets:
- name: OS X 10.11
test: osx/10.11
- name: RHEL 7.6
test: rhel/7.6
- name: RHEL 8.1
test: rhel/8.1
- name: FreeBSD 11.1
test: freebsd/11.1
- name: FreeBSD 12.0
test: freebsd/12.0
## Finally
- stage: Summary
condition: succeededOrFailed()
dependsOn:
- Remote_2_9
- Docker_2_9
- Remote_2_10
- Docker_2_10
- Remote_devel
- Docker_devel
jobs:
- template: templates/coverage.yml

View File

@@ -0,0 +1,20 @@
#!/usr/bin/env bash
# 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 --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,60 @@
#!/usr/bin/env python
"""
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,24 @@
#!/usr/bin/env bash
# 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,27 @@
#!/usr/bin/env bash
# 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.
set -o pipefail -eu
output_path="$1"
curl --silent --show-error https://codecov.io/bash > codecov.sh
for file in "${output_path}"/reports/coverage*.xml; do
name="${file}"
name="${name##*/}" # remove path
name="${name##coverage=}" # remove 'coverage=' prefix if present
name="${name%.xml}" # remove '.xml' suffix
bash codecov.sh \
-f "${file}" \
-n "${name}" \
-X coveragepy \
-X gcov \
-X fix \
-X search \
-X xcode \
|| echo "Failed to upload code coverage report to codecov.io: ${file}"
done

View File

@@ -0,0 +1,15 @@
#!/usr/bin/env bash
# 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 --stub --venv --venv-system-site-packages --color -v

View File

@@ -0,0 +1,34 @@
#!/usr/bin/env bash
# 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,25 @@
#!/usr/bin/env python
"""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,39 @@
# 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.sh "$(outputPath)"
displayName: Publish to codecov.io
condition: gt(variables.coverageFileCount, 0)
continueOnError: true

View File

@@ -0,0 +1,55 @@
# 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,45 @@
# 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)"

View File

@@ -5,6 +5,32 @@ ansible.posix Release Notes
.. contents:: Topics
v1.2.0
======
Release Summary
---------------
This is the minor release of the ``ansible.posix`` collection.
This changelog contains all changes to the modules in this collection that
have been added after the release of ``ansible.posix`` 1.1.0.
Minor Changes
-------------
- firewalld - bring the ``target`` feature back (https://github.com/ansible-collections/ansible.posix/issues/112).
- fix sanity test for various modules.
- synchronize - add the ``ssh_connection_multiplexing`` option to allow SSH connection multiplexing (https://github.com/ansible/ansible/issues/24365).
Bugfixes
--------
- at - add AIX support (https://github.com/ansible-collections/ansible.posix/pull/99).
- synchronize - fix for private_key overriding in synchronize module.
- synchronize - add ``community.docker.docker`` to the list of supported transports (https://github.com/ansible-collections/ansible.posix/issues/132).
- synchronize - do not prepend PWD when path is in form user@server:path or server:path (https://github.com/ansible-collections/ansible.posix/pull/118).
- sysctl - do not persist sysctl when value is invalid (https://github.com/ansible-collections/ansible.posix/pull/101).
v1.1.1
======

View File

@@ -1,5 +1,7 @@
# ansible.posix
<!-- Add CI and code coverage badges here. Samples included below. -->
[![Build Status](
https://dev.azure.com/ansible/ansible.posix/_apis/build/status/CI?branchName=main)](https://dev.azure.com/ansible/ansible.posix/_build?definitionId=26)
[![Run Status](https://api.shippable.com/projects/5e669aaf8b17a60007e4d18d/badge?branch=main)]() <!--[![Codecov](https://img.shields.io/codecov/c/github/ansible-collections/ansible.posix)](https://codecov.io/gh/ansible-collections/ansible.posix)-->
<!-- Describe the collection and why a user would want to use it. What does the collection do? -->
@@ -9,7 +11,7 @@ An Ansible Collection of modules and plugins that target POSIX UNIX/Linux and de
<!--start requires_ansible-->
## Ansible version compatibility
This collection has been tested against following Ansible versions: **>=2.9,<2.11**.
This collection has been tested against following Ansible versions: **>=2.9**.
Plugins and modules within a collection may be tested with only specific Ansible versions.
A collection may contain metadata that identifies these versions.

View File

@@ -103,3 +103,34 @@ releases:
- 74_synchronize_docker.yml
- skippy_deprecation.yml
release_date: '2020-09-02'
1.2.0:
changes:
bugfixes:
- at - add AIX support (https://github.com/ansible-collections/ansible.posix/pull/99).
- synchronize - fix for private_key overriding in synchronize module.
- synchronize - add ``community.docker.docker`` to the list of supported transports
(https://github.com/ansible-collections/ansible.posix/issues/132).
- synchronize - do not prepend PWD when path is in form user@server:path or
server:path (https://github.com/ansible-collections/ansible.posix/pull/118).
- sysctl - do not persist sysctl when value is invalid (https://github.com/ansible-collections/ansible.posix/pull/101).
minor_changes:
- firewalld - bring the ``target`` feature back (https://github.com/ansible-collections/ansible.posix/issues/112).
- fix sanity test for various modules.
- synchronize - add the ``ssh_connection_multiplexing`` option to allow SSH
connection multiplexing (https://github.com/ansible/ansible/issues/24365).
release_summary: 'This is the minor release of the ``ansible.posix`` collection.
This changelog contains all changes to the modules in this collection that
have been added after the release of ``ansible.posix`` 1.1.0.'
fragments:
- 1.2.0.yml
- 101-sysctl-dont-persist-when-invalid.yml
- 118-synchronize_bugfix.yml
- 120-synchronize_add_option.yml
- 144_add_community_docker_connection_plugin_alias.yml
- 82-private-key-override-fix.yml
- 99-at_add_aix_support.yml
- firewalld_zone_target.yml
- misc_fix.yml
release_date: '2021-03-08'

View File

@@ -0,0 +1,4 @@
release_summary: |-
This is the minor release of the ``ansible.posix`` collection.
This changelog contains all changes to the modules in this collection that
have been added after the release of ``ansible.posix`` 1.1.0.

View File

@@ -0,0 +1,3 @@
---
bugfixes:
- sysctl - do not persist sysctl when value is invalid (https://github.com/ansible-collections/ansible.posix/pull/101).

View File

@@ -0,0 +1,2 @@
bugfixes:
- "synchronize - do not prepend PWD when path is in form user@server:path or server:path (https://github.com/ansible-collections/ansible.posix/pull/118)."

View File

@@ -0,0 +1,2 @@
minor_changes:
- synchronize - add the ``ssh_connection_multiplexing`` option to allow SSH connection multiplexing (https://github.com/ansible/ansible/issues/24365).

View File

@@ -0,0 +1,4 @@
---
bugfixes:
- synchronize - add ``community.docker.docker`` to the list of supported
transports (https://github.com/ansible-collections/ansible.posix/issues/132).

View File

@@ -0,0 +1,3 @@
---
bugfixes:
- synchronize - fix for private_key overriding in synchronize module.

View File

@@ -0,0 +1,2 @@
bugfixes:
- at - add AIX support (https://github.com/ansible-collections/ansible.posix/pull/99).

View File

@@ -0,0 +1,2 @@
minor_changes:
- firewalld - bring the ``target`` feature back (https://github.com/ansible-collections/ansible.posix/issues/112).

View File

@@ -0,0 +1,2 @@
minor_changes:
- fix sanity test for various modules.

View File

@@ -157,7 +157,7 @@ Parameters
<td>
</td>
<td>
<div>The permissions to apply/remove can be any combination of <code>r</code>, <code>w</code> and <code>x</code> (read, write and execute respectively)</div>
<div>The permissions to apply/remove can be any combination of <code>r</code>, <code>w</code>, <code>x</code> (read, write and execute respectively), and <code>X</code> (execute permission if the file is a directory or already has execute permission for some user)</div>
</td>
</tr>
<tr>

View File

@@ -173,6 +173,21 @@ Parameters
<div>Must be in the form PORT/PROTOCOL or PORT-PORT/PROTOCOL for port ranges.</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>port_forward</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
</td>
<td>
</td>
<td>
<div>Port and protocol to forward using firewalld.</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -360,9 +375,13 @@ Examples
permanent: yes
icmp_block: echo-request
- name: Redirect port 443 to 8443 with Rich Rule
- name: Redirect port 443 to 8443
become: yes
ansible.posix.firewalld:
rich_rule: rule family=ipv4 forward-port port=443 protocol=tcp to-port=8443
port_forward:
- port: 443
proto: tcp
toport: 8443
zone: public
permanent: yes
immediate: yes
@@ -370,7 +389,6 @@ Examples
Status
------

View File

@@ -1,6 +1,6 @@
namespace: ansible
name: posix
version: 1.1.1
version: 1.2.0
readme: README.md
authors:
- Ansible (github.com/ansible)

View File

@@ -1,2 +1,2 @@
---
requires_ansible: '>=2.9,<2.11'
requires_ansible: '>=2.9'

View File

@@ -33,7 +33,13 @@ class ActionModule(ActionBase):
def _get_absolute_path(self, path):
original_path = path
if path.startswith('rsync://'):
#
# Check if we have a local relative path and do not process
# * remote paths (some.server.domain:/some/remote/path/...)
# * URLs (rsync://...)
# * local absolute paths (/some/local/path/...)
#
if ':' in path or path.startswith('/'):
return path
if self._task._role is not None:
@@ -60,7 +66,7 @@ class ActionModule(ActionBase):
return path
# If using docker or buildah, do not add user information
if self._remote_transport not in ['docker', 'community.general.docker', 'buildah', 'containers.podman.buildah'] and user:
if self._remote_transport not in ['docker', 'community.general.docker', 'community.docker.docker', 'buildah', 'containers.podman.buildah'] and user:
user_prefix = '%s@' % (user, )
if self._host_is_ipv6_address(host):
@@ -73,8 +79,7 @@ class ActionModule(ActionBase):
if host not in C.LOCALHOST:
return self._format_rsync_rsh_target(host, path, user)
if ':' not in path and not path.startswith('/'):
path = self._get_absolute_path(path=path)
path = self._get_absolute_path(path=path)
return path
def _process_remote(self, task_args, host, path, user, port_matches_localhost_port):
@@ -103,8 +108,7 @@ class ActionModule(ActionBase):
task_args['_substitute_controller'] = True
return self._format_rsync_rsh_target(host, path, user)
if ':' not in path and not path.startswith('/'):
path = self._get_absolute_path(path=path)
path = self._get_absolute_path(path=path)
return path
def _override_module_replaced_vars(self, task_vars):
@@ -170,7 +174,7 @@ class ActionModule(ActionBase):
self._remote_transport = self._connection.transport
# Handle docker connection options
if self._remote_transport in ['docker', 'community.general.docker']:
if self._remote_transport in ['docker', 'community.general.docker', 'community.docker.docker']:
self._docker_cmd = self._connection.docker_cmd
if self._play_context.docker_extra_args:
self._docker_cmd = "%s %s" % (self._docker_cmd, self._play_context.docker_extra_args)
@@ -192,7 +196,7 @@ class ActionModule(ActionBase):
# ssh paramiko docker buildah and local are fully supported transports. Anything
# else only works with delegate_to
if delegate_to is None and self._connection.transport not in \
('ssh', 'paramiko', 'local', 'docker', 'community.general.docker', 'buildah', 'containers.podman.buildah'):
('ssh', 'paramiko', 'local', 'docker', 'community.general.docker', 'community.docker.docker', 'buildah', 'containers.podman.buildah'):
result['failed'] = True
result['msg'] = (
"synchronize uses rsync to function. rsync needs to connect to the remote "
@@ -333,10 +337,8 @@ class ActionModule(ActionBase):
user = task_vars.get('ansible_ssh_user') or self._play_context.remote_user
# Private key handling
private_key = self._play_context.private_key_file
if private_key is not None:
_tmp_args['private_key'] = private_key
# Use the private_key parameter if passed else use context private_key_file
_tmp_args['private_key'] = _tmp_args.get('private_key', self._play_context.private_key_file)
# use the mode to define src and dest's url
if _tmp_args.get('mode', 'push') == 'pull':
@@ -350,10 +352,8 @@ class ActionModule(ActionBase):
else:
# Still need to munge paths (to account for roles) even if we aren't
# copying files between hosts
if not src.startswith('/'):
src = self._get_absolute_path(path=src)
if not dest.startswith('/'):
dest = self._get_absolute_path(path=dest)
src = self._get_absolute_path(path=src)
dest = self._get_absolute_path(path=dest)
_tmp_args['src'] = src
_tmp_args['dest'] = dest
@@ -367,7 +367,7 @@ class ActionModule(ActionBase):
if not dest_is_local:
# don't escalate for docker. doing --rsync-path with docker exec fails
# and we can switch directly to the user via docker arguments
if self._play_context.become and not rsync_path and self._remote_transport not in ['docker', 'community.general.docker']:
if self._play_context.become and not rsync_path and self._remote_transport not in ['docker', 'community.general.docker', 'community.docker.docker']:
# If no rsync_path is set, become was originally set, and dest is
# remote then add privilege escalation here.
if self._play_context.become_method == 'sudo':
@@ -391,7 +391,9 @@ class ActionModule(ActionBase):
# If launching synchronize against docker container
# use rsync_opts to support container to override rsh options
if self._remote_transport in ['docker', 'community.general.docker', 'buildah', 'containers.podman.buildah'] and not use_delegate:
if self._remote_transport in [
'docker', 'community.general.docker', 'community.docker.docker', 'buildah', 'containers.podman.buildah'
] and not use_delegate:
# Replicate what we do in the module argumentspec handling for lists
if not isinstance(_tmp_args.get('rsync_opts'), MutableSequence):
tmp_rsync_opts = _tmp_args.get('rsync_opts', [])
@@ -404,7 +406,7 @@ class ActionModule(ActionBase):
if '--blocking-io' not in _tmp_args['rsync_opts']:
_tmp_args['rsync_opts'].append('--blocking-io')
if self._remote_transport in ['docker', 'community.general.docker']:
if self._remote_transport in ['docker', 'community.general.docker', 'community.docker.docker']:
if become and self._play_context.become_user:
_tmp_args['rsync_opts'].append("--rsh=%s exec -u %s -i" % (self._docker_cmd, self._play_context.become_user))
elif user is not None:

View File

@@ -3,6 +3,10 @@
# (c) 2013-2018, Adam Miller (maxamillion@fedoraproject.org)
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
# Imports and info for sanity checking
from distutils.version import LooseVersion

View File

@@ -48,6 +48,10 @@
# agrees to be bound by the terms and conditions of this License
# Agreement.
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import os

View File

@@ -28,6 +28,7 @@ options:
- The C(query) state gets the current ACL without changing it, for use in C(register) operations.
choices: [ absent, present, query ]
default: query
type: str
follow:
description:
- Whether to follow symlinks on the path if a symlink is encountered.
@@ -42,13 +43,17 @@ options:
entity:
description:
- The actual user or group that the ACL applies to when matching entity types user or group are selected.
type: str
etype:
description:
- The entity type of the ACL to apply, see C(setfacl) documentation for more info.
choices: [ group, mask, other, user ]
type: str
permissions:
description:
- The permissions to apply/remove can be any combination of C(r), C(w) and C(x) (read, write and execute respectively)
- The permissions to apply/remove can be any combination of C(r), C(w), C(x)
- (read, write and execute respectively), and C(X) (execute permission if the file is a directory or already has execute permission for some user)
type: str
entry:
description:
- DEPRECATED.
@@ -57,6 +62,7 @@ options:
- The qualifier may be empty for some types, but the type and perms are always required.
- C(-) can be used as placeholder when you do not care about permissions.
- This is now superseded by entity, type and permissions fields.
type: str
recursive:
description:
- Recursively sets the specified ACL.
@@ -75,6 +81,7 @@ options:
- Incompatible with C(state=query).
choices: [ default, mask, no_mask ]
default: default
type: str
author:
- Brian Coca (@bcoca)
- Jérémie Astori (@astorije)

View File

@@ -8,7 +8,7 @@ from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
DOCUMENTATION = r'''
---
module: at
short_description: Schedule the execution of a command or script file via the at command
@@ -29,12 +29,10 @@ options:
description:
- The count of units in the future to execute the command or script file.
type: int
required: true
units:
description:
- The type of units in the future to execute the command or script file.
type: str
required: true
choices: [ minutes, hours, days, weeks ]
state:
description:
@@ -74,6 +72,7 @@ EXAMPLES = r'''
'''
import os
import platform
import tempfile
from ansible.module_utils.basic import AnsibleModule
@@ -89,7 +88,7 @@ def add_job(module, result, at_cmd, count, units, command, script_file):
def delete_job(module, result, at_cmd, command, script_file):
for matching_job in get_matching_jobs(module, at_cmd, script_file):
at_command = "%s -d %s" % (at_cmd, matching_job)
at_command = "%s -r %s" % (at_cmd, matching_job)
rc, out, err = module.run_command(at_command, check_rc=True)
result['changed'] = True
if command:
@@ -117,7 +116,8 @@ def get_matching_jobs(module, at_cmd, script_file):
# If the script text is contained in a job add job number to list.
for current_job in current_jobs:
split_current_job = current_job.split()
at_command = "%s -c %s" % (at_cmd, split_current_job[0])
at_opt = '-c' if platform.system() != 'AIX' else '-lv'
at_command = "%s %s %s" % (at_cmd, at_opt, split_current_job[0])
rc, out, err = module.run_command(at_command, check_rc=True)
if script_file_string in out:
matching_jobs.append(split_current_job[0])

View File

@@ -50,6 +50,7 @@ options:
key_options:
description:
- A string of ssh key options to be prepended to the key in the authorized_keys file.
type: str
exclusive:
description:
- Whether to remove all other non-specified keys from the authorized_keys file.

View File

@@ -24,6 +24,32 @@ options:
- Name of a port or port range to add/remove to/from firewalld.
- Must be in the form PORT/PROTOCOL or PORT-PORT/PROTOCOL for port ranges.
type: str
port_forward:
description:
- Port and protocol to forward using firewalld.
type: list
elements: dict
suboptions:
port:
type: str
required: true
description:
- Source port to forward from
proto:
type: str
required: true
description:
- protocol to forward
choices: [udp, tcp]
toport:
type: str
required: true
description:
- destination port
toaddr:
type: str
description:
- Optional address to forward to
rich_rule:
description:
- Rich rule to add/remove to/from firewalld.
@@ -84,6 +110,13 @@ options:
description:
- Whether to run this module even when firewalld is offline.
type: bool
target:
description:
- firewalld Zone target
- If state is set to C(absent), this will reset the target to default
choices: [ default, ACCEPT, DROP, REJECT ]
type: str
version_added: 1.2.0
notes:
- Not tested on any Debian based system.
- Requires the python2 bindings of firewalld, which may not be installed by default.
@@ -164,6 +197,12 @@ EXAMPLES = r'''
permanent: yes
icmp_block: echo-request
- ansible.posix.firewalld:
zone: internal
state: present
permanent: yes
target: ACCEPT
- name: Redirect port 443 to 8443 with Rich Rule
ansible.posix.firewalld:
rich_rule: rule family=ipv4 forward-port port=443 protocol=tcp to-port=8443
@@ -571,6 +610,53 @@ class SourceTransaction(FirewallTransaction):
self.update_fw_settings(fw_zone, fw_settings)
class ZoneTargetTransaction(FirewallTransaction):
"""
ZoneTargetTransaction
"""
def __init__(self, module, action_args=None, zone=None, desired_state=None,
permanent=True, immediate=False, enabled_values=None, disabled_values=None):
super(ZoneTargetTransaction, self).__init__(
module, action_args=action_args, desired_state=desired_state, zone=zone,
permanent=permanent, immediate=immediate,
enabled_values=enabled_values or ["present", "enabled"],
disabled_values=disabled_values or ["absent", "disabled"])
self.enabled_msg = "Set zone %s target to %s" % \
(self.zone, action_args[0])
self.disabled_msg = "Reset zone %s target to default" % \
(self.zone)
self.tx_not_permanent_error_msg = "Zone operations must be permanent. " \
"Make sure you didn't set the 'permanent' flag to 'false' or the 'immediate' flag to 'true'."
def get_enabled_immediate(self, target):
self.module.fail_json(msg=self.tx_not_permanent_error_msg)
def get_enabled_permanent(self, target):
fw_zone, fw_settings = self.get_fw_zone_settings()
current_target = fw_settings.getTarget()
return (current_target == target)
def set_enabled_immediate(self, target):
self.module.fail_json(msg=self.tx_not_permanent_error_msg)
def set_enabled_permanent(self, target):
fw_zone, fw_settings = self.get_fw_zone_settings()
fw_settings.setTarget(target)
self.update_fw_settings(fw_zone, fw_settings)
def set_disabled_immediate(self, target):
self.module.fail_json(msg=self.tx_not_permanent_error_msg)
def set_disabled_permanent(self, target):
fw_zone, fw_settings = self.get_fw_zone_settings()
fw_settings.setTarget("default")
self.update_fw_settings(fw_zone, fw_settings)
class ZoneTransaction(FirewallTransaction):
"""
ZoneTransaction
@@ -618,6 +704,55 @@ class ZoneTransaction(FirewallTransaction):
zone_obj.remove()
class ForwardPortTransaction(FirewallTransaction):
"""
ForwardPortTransaction
"""
def __init__(self, module, action_args=None, zone=None, desired_state=None, permanent=False, immediate=False):
super(ForwardPortTransaction, self).__init__(
module, action_args=action_args, desired_state=desired_state, zone=zone, permanent=permanent, immediate=immediate
)
def get_enabled_immediate(self, port, proto, toport, toaddr, timeout):
forward_port = [port, proto, toport, toaddr]
if self.fw_offline:
fw_zone, fw_settings = self.get_fw_zone_settings()
forward_list = fw_settings.getForwardPorts()
else:
forward_list = self.fw.getForwardPorts(self.zone)
if forward_port in forward_list:
return True
else:
return False
def get_enabled_permanent(self, port, proto, toport, toaddr, timeout):
forward_port = (port, proto, toport, toaddr)
fw_zone, fw_settings = self.get_fw_zone_settings()
if forward_port in fw_settings.getForwardPorts():
return True
else:
return False
def set_enabled_immediate(self, port, proto, toport, toaddr, timeout):
self.fw.addForwardPort(self.zone, port, proto, toport, toaddr, timeout)
def set_enabled_permanent(self, port, proto, toport, toaddr, timeout):
fw_zone, fw_settings = self.get_fw_zone_settings()
fw_settings.addForwardPort(port, proto, toport, toaddr)
self.update_fw_settings(fw_zone, fw_settings)
def set_disabled_immediate(self, port, proto, toport, toaddr, timeout):
self.fw.removeForwardPort(self.zone, port, proto, toport, toaddr)
def set_disabled_permanent(self, port, proto, toport, toaddr, timeout):
fw_zone, fw_settings = self.get_fw_zone_settings()
fw_settings.removeForwardPort(port, proto, toport, toaddr)
self.update_fw_settings(fw_zone, fw_settings)
def main():
module = AnsibleModule(
@@ -626,6 +761,7 @@ def main():
icmp_block_inversion=dict(type='str'),
service=dict(type='str'),
port=dict(type='str'),
port_forward=dict(type='list', elements='dict'),
rich_rule=dict(type='str'),
zone=dict(type='str'),
immediate=dict(type='bool', default=False),
@@ -636,10 +772,12 @@ def main():
interface=dict(type='str'),
masquerade=dict(type='str'),
offline=dict(type='bool'),
target=dict(type='str', choices=['default', 'ACCEPT', 'DROP', 'REJECT']),
),
supports_check_mode=True,
required_by=dict(
interface=('zone',),
target=('zone',),
source=('permanent',),
),
)
@@ -671,6 +809,7 @@ def main():
rich_rule = module.params['rich_rule']
source = module.params['source']
zone = module.params['zone']
target = module.params['target']
if module.params['port'] is not None:
if '/' in module.params['port']:
@@ -682,6 +821,21 @@ def main():
else:
port = None
port_forward_toaddr = ''
port_forward = None
if module.params['port_forward'] is not None:
if len(module.params['port_forward']) > 1:
module.fail_json(msg='Only one port forward supported at a time')
port_forward = module.params['port_forward'][0]
if 'port' not in port_forward:
module.fail_json(msg='port must be specified for port forward')
if 'proto' not in port_forward:
module.fail_json(msg='proto udp/tcp must be specified for port forward')
if 'toport' not in port_forward:
module.fail_json(msg='toport must be specified for port forward')
if 'toaddr' in port_forward:
port_forward_toaddr = port_forward['toaddr']
modification_count = 0
if icmp_block is not None:
modification_count += 1
@@ -691,6 +845,8 @@ def main():
modification_count += 1
if port is not None:
modification_count += 1
if port_forward is not None:
modification_count += 1
if rich_rule is not None:
modification_count += 1
if interface is not None:
@@ -699,12 +855,14 @@ def main():
modification_count += 1
if source is not None:
modification_count += 1
if target is not None:
modification_count += 1
if modification_count > 1:
module.fail_json(
msg='can only operate on port, service, rich_rule, masquerade, icmp_block, icmp_block_inversion, interface or source at once'
)
elif modification_count > 0 and desired_state in ['absent', 'present']:
elif (modification_count > 0) and (desired_state in ['absent', 'present']) and (target is None):
module.fail_json(
msg='absent and present state can only be used in zone level operations'
)
@@ -791,6 +949,29 @@ def main():
)
)
if port_forward is not None:
transaction = ForwardPortTransaction(
module,
action_args=(str(port_forward['port']), port_forward['proto'],
str(port_forward['toport']), port_forward_toaddr, timeout),
zone=zone,
desired_state=desired_state,
permanent=permanent,
immediate=immediate
)
changed, transaction_msgs = transaction.run()
msgs = msgs + transaction_msgs
if changed is True:
msgs.append(
"Changed port_forward %s to %s" % (
"port=%s:proto=%s:toport=%s:toaddr=%s" % (
port_forward['port'], port_forward['proto'],
port_forward['toport'], port_forward_toaddr
), desired_state
)
)
if rich_rule is not None:
transaction = RichRuleTransaction(
@@ -835,6 +1016,20 @@ def main():
changed, transaction_msgs = transaction.run()
msgs = msgs + transaction_msgs
if target is not None:
transaction = ZoneTargetTransaction(
module,
action_args=(target,),
zone=zone,
desired_state=desired_state,
permanent=permanent,
immediate=immediate,
)
changed, transaction_msgs = transaction.run()
msgs = msgs + transaction_msgs
''' If there are no changes within the zone we are operating on the zone itself '''
if modification_count == 0 and desired_state in ['absent', 'present']:

View File

@@ -7,7 +7,7 @@ from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
DOCUMENTATION = r'''
---
module: seboolean
short_description: Toggles SELinux booleans
@@ -19,6 +19,7 @@ options:
description:
- Name of the boolean to configure.
required: true
type: str
persistent:
description:
- Set to C(yes) if the boolean setting should survive a reboot.

View File

@@ -20,17 +20,20 @@ version_added: "1.0.0"
options:
policy:
description:
- The name of the SELinux policy to use (e.g. C(targeted)) will be required if state is not C(disabled).
- The name of the SELinux policy to use (e.g. C(targeted)) will be required if I(state) is not C(disabled).
type: str
state:
description:
- The SELinux mode.
required: true
choices: [ disabled, enforcing, permissive ]
type: str
configfile:
description:
- The path to the SELinux configuration file, if non-standard.
default: /etc/selinux/config
aliases: [ conf, file ]
type: str
requirements: [ libselinux-python ]
author:
- Derek Carter (@goozbach) <goozbach@friocorte.com>
@@ -178,7 +181,7 @@ def main():
module = AnsibleModule(
argument_spec=dict(
policy=dict(type='str'),
state=dict(type='str', required='True', choices=['enforcing', 'permissive', 'disabled']),
state=dict(type='str', required=True, choices=['enforcing', 'permissive', 'disabled']),
configfile=dict(type='str', default='/etc/selinux/config', aliases=['conf', 'file']),
),
supports_check_mode=True,

View File

@@ -138,7 +138,17 @@ options:
default: yes
use_ssh_args:
description:
- Use the ssh_args specified in ansible.cfg.
- Use the ssh_args specified in ansible.cfg. Setting this to `yes` will also make `synchronize` use `ansible_ssh_common_args`.
type: bool
default: no
ssh_connection_multiplexing:
description:
- SSH connection multiplexing for rsync is disabled by default to prevent misconfigured ControlSockets from resulting in failed SSH connections.
This is accomplished by setting the SSH C(ControlSocket) to C(none).
- Set this option to C(yes) to allow multiplexing and reduce SSH connection overhead.
- Note that simply setting this option to C(yes) is not enough;
You must also configure SSH connection multiplexing in your SSH client config by setting values for
C(ControlMaster), C(ControlPersist) and C(ControlPath).
type: bool
default: no
rsync_opts:
@@ -147,6 +157,7 @@ options:
- Note that an empty string in C(rsync_opts) will end up transfer the current working directory.
type: list
default:
elements: str
partial:
description:
- Tells rsync to keep the partial file which should make a subsequent transfer of the rest of the file much faster.
@@ -166,6 +177,8 @@ options:
- Add a destination to hard link against during the rsync.
type: list
default:
elements: str
notes:
- rsync must be installed on both the local and remote host.
- For the C(synchronize) module, the "local host" is the host `the synchronize task originates on`, and the "destination host" is the host
@@ -314,7 +327,7 @@ EXAMPLES = r'''
# Specify the rsync binary to use on remote host and on local host
- hosts: groupofhosts
vars:
ansible_rsync_path: /usr/gnu/bin/rsync
ansible_rsync_path: /usr/gnu/bin/rsync
tasks:
- name: copy /tmp/localpath/ to remote location /tmp/remotepath
@@ -390,12 +403,13 @@ def main():
group=dict(type='bool'),
set_remote_user=dict(type='bool', default=True),
rsync_timeout=dict(type='int', default=0),
rsync_opts=dict(type='list', default=[]),
rsync_opts=dict(type='list', default=[], elements='str'),
ssh_args=dict(type='str'),
ssh_connection_multiplexing=dict(type='bool', default=False),
partial=dict(type='bool', default=False),
verify_host=dict(type='bool', default=False),
mode=dict(type='str', default='push', choices=['pull', 'push']),
link_dest=dict(type='list')
link_dest=dict(type='list', elements='str'),
),
supports_check_mode=True,
)
@@ -432,6 +446,7 @@ def main():
group = module.params['group']
rsync_opts = module.params['rsync_opts']
ssh_args = module.params['ssh_args']
ssh_connection_multiplexing = module.params['ssh_connection_multiplexing']
verify_host = module.params['verify_host']
link_dest = module.params['link_dest']
@@ -507,7 +522,9 @@ def main():
# if the user has not supplied an --rsh option go ahead and add ours
if not has_rsh:
ssh_cmd = [module.get_bin_path('ssh', required=True), '-S', 'none']
ssh_cmd = [module.get_bin_path('ssh', required=True)]
if not ssh_connection_multiplexing:
ssh_cmd.extend(['-S', 'none'])
if private_key is not None:
ssh_cmd.extend(['-i', private_key])
# If the user specified a port value

View File

@@ -9,7 +9,7 @@ from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
DOCUMENTATION = r'''
---
module: sysctl
short_description: Manage entries in sysctl.conf.
@@ -19,18 +19,21 @@ version_added: "1.0.0"
options:
name:
description:
- The dot-separated path (aka I(key)) specifying the sysctl variable.
- The dot-separated path (also known as I(key)) specifying the sysctl variable.
required: true
aliases: [ 'key' ]
type: str
value:
description:
- Desired value of the sysctl key.
aliases: [ 'val' ]
type: str
state:
description:
- Whether the entry should be present or absent in the sysctl file.
choices: [ "present", "absent" ]
default: present
type: str
ignoreerrors:
description:
- Use this option to ignore errors about unknown keys.
@@ -47,12 +50,14 @@ options:
description:
- Specifies the absolute path to C(sysctl.conf), if not C(/etc/sysctl.conf).
default: /etc/sysctl.conf
type: path
sysctl_set:
description:
- Verify token value with the sysctl command and set with -w if necessary
type: bool
default: 'no'
author: "David CHANIAL (@davixx) <david.chanial@gmail.com>"
author:
- David CHANIAL (@davixx)
'''
EXAMPLES = r'''
@@ -182,12 +187,12 @@ class SysctlModule(object):
# Do the work
if not self.module.check_mode:
if self.set_proc:
self.set_token_value(self.args['name'], self.args['value'])
if self.write_file:
self.write_sysctl()
if self.changed and self.args['reload']:
self.reload_sysctl()
if self.set_proc:
self.set_token_value(self.args['name'], self.args['value'])
def _values_is_equal(self, a, b):
"""Expects two string values. It will split the string by whitespace

View File

@@ -0,0 +1,77 @@
# Test playbook for the firewalld module - port operations
# (c) 2017, Adam Miller <admiller@redhat.com>
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
- name: firewalld port forward test permanent enabled
firewalld:
port_forward:
- port: 8080
proto: tcp
toport: 8081
permanent: true
state: enabled
register: result
- name: assert firewalld port test permanent enabled worked
assert:
that:
- result is changed
- name: firewalld port test permanent enabled rerun (verify not changed)
firewalld:
port_forward:
- port: 8080
proto: tcp
toport: 8081
permanent: true
state: enabled
register: result
- name: assert firewalld port test permanent enabled rerun worked (verify not changed)
assert:
that:
- result is not changed
- name: firewalld port test permanent disabled
firewalld:
port_forward:
- port: 8080
proto: tcp
toport: 8081
permanent: true
state: disabled
register: result
- name: assert firewalld port test permanent disabled worked
assert:
that:
- result is changed
- name: firewalld port test permanent disabled rerun (verify not changed)
firewalld:
port_forward:
- port: 8080
proto: tcp
toport: 8081
permanent: true
state: disabled
register: result
- name: assert firewalld port test permanent disabled rerun worked (verify not changed)
assert:
that:
- result is not changed

View File

@@ -33,3 +33,6 @@
# firewalld source operation test cases
- import_tasks: source_test_cases.yml
# firewalld zone target operation test cases
- import_tasks: zone_target_test_cases.yml

View File

@@ -0,0 +1,69 @@
# Test playbook for the firewalld module - source operations
# (c) 2020, Adam Miller <admiller@redhat.com>
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
- name: firewalld dmz zone target DROP
firewalld:
zone: dmz
permanent: True
state: present
target: DROP
register: result
- name: assert firewalld dmz zone target DROP present worked
assert:
that:
- result is changed
- name: firewalld dmz zone target DROP rerun (verify not changed)
firewalld:
zone: dmz
permanent: True
state: present
target: DROP
register: result
- name: assert firewalld dmz zone target DROP present worked (verify not changed)
assert:
that:
- result is not changed
- name: firewalld dmz zone target DROP absent
firewalld:
zone: dmz
permanent: True
state: absent
target: DROP
register: result
- name: assert firewalld dmz zone target DROP absent worked
assert:
that:
- result is changed
- name: firewalld dmz zone target DROP rerun (verify not changed)
firewalld:
zone: dmz
permanent: True
state: absent
target: DROP
register: result
- name: assert firewalld dmz zone target DROP present worked (verify not changed)
assert:
that:
- result is not changed

View File

@@ -48,9 +48,17 @@
var: _disable_test1
verbosity: 1
- name: Before gathering the fact
debug:
msg: "{{ ansible_selinux }}"
- name: TEST 1 | Re-gather facts
setup:
- name: After gathering the fact
debug:
msg: "{{ ansible_selinux }}"
- name: TEST 1 | Assert that status was changed, reboot_required is True, a warning was displayed, and SELinux is configured properly
assert:
that:
@@ -74,7 +82,7 @@
var: _disable_test2
verbosity: 1
- name: TEST 1 | Assert that no change is reported, a warnking was dispalyed, and reboot_required is True
- name: TEST 1 | Assert that no change is reported, a warning was displayed, and reboot_required is True
assert:
that:
- _disable_test2 is not changed
@@ -147,7 +155,7 @@
var: _state_test2
verbosity: 1
- name: TEST 2 | Assert that no change was reported, no warnings were dispalyed, and reboot_required is False
- name: TEST 2 | Assert that no change was reported, no warnings were displayed, and reboot_required is False
assert:
that:
- _state_test2 is not changed
@@ -380,7 +388,7 @@
var: _lineinfile_out1
verbosity: 1
- name: TEST 5 | Set SELinux to enforcing
- name: TEST 5 | Set SELinux to enforcing
selinux:
state: enforcing
policy: targeted

View File

@@ -289,3 +289,24 @@
- sysctl_check_mode2 is changed
- "'vm.swappiness=22' in sysctl_check_mode_conf_content.stdout_lines"
- sysctl_check_mode_current_vm_swappiness.stdout == '22'
# Test sysctl: invalid value
- name: Set invalid sysctl property using module
sysctl:
name: vm.mmap_rnd_bits
value: '1024'
state: present
reload: yes
sysctl_set: True
ignore_errors: True
register: sysctl_invalid_set1
- name: Read /etc/sysctl.conf
command: 'cat /etc/sysctl.conf'
register: sysctl_invalid_conf_content
- name: Ensure changes were not made
assert:
that:
- sysctl_invalid_set1 is failed
- "'vm.mmap_rnd_bits' not in sysctl_invalid_conf_content.stdout"

View File

@@ -1,33 +1,8 @@
plugins/module_utils/firewalld.py future-import-boilerplate
plugins/module_utils/firewalld.py metaclass-boilerplate
plugins/module_utils/mount.py future-import-boilerplate
plugins/module_utils/mount.py metaclass-boilerplate
plugins/modules/acl.py validate-modules:parameter-type-not-in-doc
plugins/modules/synchronize.py pylint:blacklisted-name
plugins/modules/synchronize.py use-argspec-type-path
plugins/modules/synchronize.py validate-modules:doc-default-does-not-match-spec
plugins/modules/synchronize.py validate-modules:nonexistent-parameter-documented
plugins/modules/synchronize.py validate-modules:parameter-list-no-elements
plugins/modules/synchronize.py validate-modules:parameter-type-not-in-doc
plugins/modules/synchronize.py validate-modules:undocumented-parameter
plugins/modules/at.py validate-modules:doc-required-mismatch
plugins/modules/authorized_key.py validate-modules:parameter-type-not-in-doc
plugins/modules/seboolean.py validate-modules:parameter-type-not-in-doc
plugins/modules/selinux.py validate-modules:invalid-ansiblemodule-schema
plugins/modules/selinux.py validate-modules:parameter-type-not-in-doc
plugins/modules/sysctl.py validate-modules:doc-missing-type
plugins/modules/sysctl.py validate-modules:parameter-type-not-in-doc
tests/unit/mock/path.py future-import-boilerplate
tests/unit/mock/path.py metaclass-boilerplate
tests/unit/mock/yaml_helper.py future-import-boilerplate
tests/unit/mock/yaml_helper.py metaclass-boilerplate
tests/unit/modules/conftest.py future-import-boilerplate
tests/unit/modules/conftest.py metaclass-boilerplate
tests/unit/modules/system/test_mount.py future-import-boilerplate
tests/unit/modules/system/test_mount.py metaclass-boilerplate
tests/unit/modules/utils.py future-import-boilerplate
tests/unit/modules/utils.py metaclass-boilerplate
tests/unit/plugins/action/test_synchronize.py future-import-boilerplate
tests/unit/plugins/action/test_synchronize.py metaclass-boilerplate
tests/utils/shippable/check_matrix.py replace-urlopen
tests/utils/shippable/timing.py shebang

View File

@@ -0,0 +1,8 @@
plugins/modules/synchronize.py pylint:blacklisted-name
plugins/modules/synchronize.py use-argspec-type-path
plugins/modules/synchronize.py validate-modules:doc-default-does-not-match-spec
plugins/modules/synchronize.py validate-modules:nonexistent-parameter-documented
plugins/modules/synchronize.py validate-modules:parameter-type-not-in-doc
plugins/modules/synchronize.py validate-modules:undocumented-parameter
tests/utils/shippable/check_matrix.py replace-urlopen
tests/utils/shippable/timing.py shebang

View File

@@ -1,30 +1,8 @@
plugins/module_utils/firewalld.py future-import-boilerplate
plugins/module_utils/firewalld.py metaclass-boilerplate
plugins/module_utils/mount.py future-import-boilerplate
plugins/module_utils/mount.py metaclass-boilerplate
plugins/modules/acl.py validate-modules:parameter-type-not-in-doc
plugins/modules/synchronize.py pylint:blacklisted-name
plugins/modules/synchronize.py use-argspec-type-path
plugins/modules/synchronize.py validate-modules:doc-default-does-not-match-spec
plugins/modules/synchronize.py validate-modules:nonexistent-parameter-documented
plugins/modules/synchronize.py validate-modules:parameter-type-not-in-doc
plugins/modules/synchronize.py validate-modules:undocumented-parameter
plugins/modules/authorized_key.py validate-modules:parameter-type-not-in-doc
plugins/modules/seboolean.py validate-modules:parameter-type-not-in-doc
plugins/modules/selinux.py validate-modules:parameter-type-not-in-doc
plugins/modules/sysctl.py validate-modules:doc-missing-type
plugins/modules/sysctl.py validate-modules:parameter-type-not-in-doc
tests/unit/mock/path.py future-import-boilerplate
tests/unit/mock/path.py metaclass-boilerplate
tests/unit/mock/yaml_helper.py future-import-boilerplate
tests/unit/mock/yaml_helper.py metaclass-boilerplate
tests/unit/modules/conftest.py future-import-boilerplate
tests/unit/modules/conftest.py metaclass-boilerplate
tests/unit/modules/system/test_mount.py future-import-boilerplate
tests/unit/modules/system/test_mount.py metaclass-boilerplate
tests/unit/modules/utils.py future-import-boilerplate
tests/unit/modules/utils.py metaclass-boilerplate
tests/unit/plugins/action/test_synchronize.py future-import-boilerplate
tests/unit/plugins/action/test_synchronize.py metaclass-boilerplate
tests/utils/shippable/check_matrix.py replace-urlopen
tests/utils/shippable/timing.py shebang

View File

@@ -1,4 +0,0 @@
packaging # needed for update-bundled and changelog
sphinx ; python_version >= '3.5' # docs build requires python 3+
sphinx-notfound-page ; python_version >= '3.5' # docs build requires python 3+
straight.plugin ; python_version >= '3.5' # needed for hacking/build-ansible.py which will host changelog generation and requires python 3+

View File

@@ -1,3 +1,7 @@
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from ansible_collections.ansible.posix.tests.unit.compat.mock import MagicMock
from ansible.utils.path import unfrackpath

View File

@@ -1,3 +1,7 @@
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import io
import yaml

View File

@@ -1,6 +1,10 @@
# Copyright (c) 2017 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import json
import pytest

View File

@@ -1,3 +1,7 @@
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import os
import tempfile

View File

@@ -1,3 +1,7 @@
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import json
from ansible_collections.ansible.posix.tests.unit.compat import unittest

View File

@@ -0,0 +1,25 @@
fixtures:
taskvars_in: taskvars_in.json
taskvars_out: taskvars_out.json
connection:
transport: 'ssh'
hostvars:
'127.0.0.1': {}
'::1': {}
'localhost': {}
_play_context:
private_key_file: ~/test.pem
task_args:
private_key: ~/.ssh/id_rsa
dest: /tmp/deleteme
src: /tmp/deleteme
asserts:
- "hasattr(SAM._connection, 'ismock')"
- "SAM._connection.transport == 'local'"
- "self._play_context.shell == 'sh'"
- "self.execute_called"
- "self.final_module_args['_local_rsync_path'] == 'rsync'"
- "self.final_module_args['src'] == '/tmp/deleteme'"
- "self.final_module_args['dest'] == 'root@el6host:/tmp/deleteme'"
- "self.final_module_args['private_key'] == '~/.ssh/id_rsa'"

View File

@@ -0,0 +1,151 @@
{
"ansible_pipelining": false,
"ansible_docker_extra_args": "",
"ansible_scp_extra_args": "",
"ansible_user": "root",
"ansible_play_hosts": [
"el6host"
],
"ansible_connection": "smart",
"ansible_ssh_common_args": "",
"environment": [],
"inventory_hostname": "el6host",
"vars": {
"ansible_check_mode": false,
"inventory_hostname": "el6host",
"inventory_file": "inventory",
"inventory_hostname_short": "el6host",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"role_names": [],
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"environment": [],
"play_hosts": [
"el6host"
],
"ansible_play_hosts": [
"el6host"
],
"hostvars": {
"el6host": {
"inventory_file": "inventory",
"group_names": [
"ungrouped"
],
"groups": {
"ungrouped": [
"el6host"
],
"all": [
"el6host"
]
},
"inventory_hostname": "el6host",
"inventory_hostname_short": "el6host",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__03600813b83569c710bf5cb2a040d6e01da927c6",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"ansible_check_mode": false,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
}
}
},
"groups": {
"ungrouped": [
"el6host"
],
"all": [
"el6host"
]
},
"group_names": [
"ungrouped"
],
"omit": "__omit_place_holder__03600813b83569c710bf5cb2a040d6e01da927c6",
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
},
"ansible_ssh_user": "root"
},
"ansible_accelerate_port": 5099,
"roledir": null,
"ansible_ssh_extra_args": "",
"ansible_ssh_host": "el6host",
"ansible_current_hosts": [
"el6host"
],
"hostvars": {
"el6host": {
"inventory_file": "inventory",
"group_names": [
"ungrouped"
],
"groups": {
"ungrouped": [
"el6host"
],
"all": [
"el6host"
]
},
"inventory_hostname": "el6host",
"inventory_hostname_short": "el6host",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__03600813b83569c710bf5cb2a040d6e01da927c6",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"ansible_check_mode": false,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
}
}
},
"group_names": [
"ungrouped"
],
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
},
"ansible_ssh_pipelining": false,
"inventory_file": "inventory",
"ansible_module_compression": "ZIP_DEFLATED",
"ansible_failed_hosts": [],
"ansible_check_mode": false,
"groups": {
"ungrouped": [
"el6host"
],
"all": [
"el6host"
]
},
"ansible_host": "el6host",
"ansible_shell_executable": "/bin/sh",
"inventory_hostname_short": "el6host",
"omit": "__omit_place_holder__03600813b83569c710bf5cb2a040d6e01da927c6",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"role_names": [],
"play_hosts": [
"el6host"
],
"ansible_sftp_extra_args": ""
}

View File

@@ -0,0 +1,156 @@
{
"ansible_pipelining": false,
"ansible_docker_extra_args": "",
"ansible_scp_extra_args": "",
"ansible_user": "root",
"ansible_play_hosts": [
"el6host"
],
"ansible_connection": "smart",
"ansible_ssh_common_args": "",
"environment": [],
"inventory_hostname": "el6host",
"vars": {
"ansible_check_mode": false,
"inventory_hostname": "el6host",
"inventory_file": "inventory",
"inventory_hostname_short": "el6host",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"role_names": [],
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"environment": [],
"play_hosts": [
"el6host"
],
"ansible_play_hosts": [
"el6host"
],
"hostvars": {
"el6host": {
"inventory_file": "inventory",
"group_names": [
"ungrouped"
],
"groups": {
"ungrouped": [
"el6host",
"::1"
],
"all": [
"el6host",
"::1"
]
},
"inventory_hostname": "el6host",
"inventory_hostname_short": "el6host",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__03600813b83569c710bf5cb2a040d6e01da927c6",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"ansible_check_mode": false,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
}
}
},
"groups": {
"ungrouped": [
"el6host"
],
"all": [
"el6host"
]
},
"group_names": [
"ungrouped"
],
"omit": "__omit_place_holder__03600813b83569c710bf5cb2a040d6e01da927c6",
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
},
"ansible_ssh_user": "root"
},
"ansible_accelerate_port": 5099,
"roledir": null,
"ansible_ssh_extra_args": "",
"ansible_ssh_host": "el6host",
"ansible_current_hosts": [
"el6host"
],
"hostvars": {
"el6host": {
"inventory_file": "inventory",
"group_names": [
"ungrouped"
],
"groups": {
"ungrouped": [
"el6host",
"::1"
],
"all": [
"el6host",
"::1"
]
},
"inventory_hostname": "el6host",
"inventory_hostname_short": "el6host",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__03600813b83569c710bf5cb2a040d6e01da927c6",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"ansible_check_mode": false,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
}
}
},
"group_names": [
"ungrouped"
],
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
},
"ansible_ssh_pipelining": false,
"inventory_file": "inventory",
"ansible_module_compression": "ZIP_DEFLATED",
"ansible_failed_hosts": [],
"ansible_check_mode": false,
"groups": {
"ungrouped": [
"el6host"
],
"all": [
"el6host"
]
},
"ansible_host": "el6host",
"ansible_shell_executable": "/bin/sh",
"inventory_hostname_short": "el6host",
"omit": "__omit_place_holder__03600813b83569c710bf5cb2a040d6e01da927c6",
"ansible_python_interpreter": "/usr/bin/python",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"role_names": [],
"play_hosts": [
"el6host"
],
"ansible_sftp_extra_args": ""
}

View File

@@ -0,0 +1,28 @@
fixtures:
taskvars_in: task_vars_in.json
taskvars_out: task_vars_out.json
task_args:
src: /tmp/deleteme
dest: /tmp/deleteme
_task:
delegate_to: u1404
_play_context:
shell: None
remote_addr: u1404
remote_user: root
private_key_file: ~/test.pem
connection:
transport: 'ssh'
hostvars:
'127.0.0.1': {}
'::1': {}
'localhost': {}
asserts:
- "hasattr(SAM._connection, 'ismock')"
- "SAM._connection.transport == 'ssh'"
- "self._play_context.shell == None"
- "self.execute_called"
- "self.final_module_args['_local_rsync_path'] == 'rsync'"
- "self.final_module_args['src'] == '/tmp/deleteme'"
- "self.final_module_args['dest'] == 'root@el6host:/tmp/deleteme'"
- "self.final_module_args['private_key'] == '~/test.pem'"

View File

@@ -0,0 +1,379 @@
{
"ansible_pipelining": false,
"ansible_docker_extra_args": "",
"ansible_scp_extra_args": "",
"ansible_user": "root",
"ansible_play_hosts": [
"el6host"
],
"ansible_connection": "smart",
"ansible_ssh_common_args": "",
"environment": [],
"inventory_hostname": "el6host",
"vars": {
"ansible_check_mode": false,
"inventory_hostname": "el6host",
"inventory_file": "inventory",
"ansible_delegated_vars": {
"u1404": {
"inventory_hostname": "u1404",
"inventory_file": "inventory",
"vars": {
"inventory_file": "inventory",
"role_names": [],
"ansible_play_hosts": [
"el6host"
],
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"ansible_check_mode": false,
"inventory_hostname": "u1404",
"inventory_hostname_short": "u1404",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"environment": [],
"ansible_ssh_user": "root",
"group_names": [
"ungrouped"
],
"play_hosts": [
"el6host"
],
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
}
},
"inventory_hostname_short": "u1404",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"group_names": [
"ungrouped"
],
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"ansible_host": "u1404",
"environment": [],
"ansible_play_hosts": [
"el6host"
],
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"ansible_check_mode": false,
"play_hosts": [
"el6host"
],
"role_names": [],
"ansible_port": null,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
},
"ansible_ssh_user": "root"
}
},
"inventory_hostname_short": "el6host",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"role_names": [],
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"environment": [],
"play_hosts": [
"el6host"
],
"ansible_play_hosts": [
"el6host"
],
"hostvars": {
"el6host": {
"inventory_file": "inventory",
"group_names": [
"ungrouped"
],
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"inventory_hostname": "el6host",
"inventory_hostname_short": "el6host",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"ansible_check_mode": false,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
}
},
"u1404": {
"inventory_file": "inventory",
"group_names": [
"ungrouped"
],
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"inventory_hostname": "u1404",
"inventory_hostname_short": "u1404",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"ansible_check_mode": false,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
}
}
},
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"group_names": [
"ungrouped"
],
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
},
"ansible_ssh_user": "root"
},
"ansible_accelerate_port": 5099,
"roledir": null,
"ansible_ssh_extra_args": "",
"ansible_ssh_host": "u1404",
"ansible_current_hosts": [
"el6host"
],
"hostvars": {
"el6host": {
"inventory_file": "inventory",
"group_names": [
"ungrouped"
],
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"inventory_hostname": "el6host",
"inventory_hostname_short": "el6host",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"ansible_check_mode": false,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
}
},
"u1404": {
"inventory_file": "inventory",
"group_names": [
"ungrouped"
],
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"inventory_hostname": "u1404",
"inventory_hostname_short": "u1404",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"ansible_check_mode": false,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
}
}
},
"group_names": [
"ungrouped"
],
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
},
"ansible_ssh_pipelining": false,
"inventory_file": "inventory",
"ansible_delegated_vars": {
"u1404": {
"inventory_hostname": "u1404",
"inventory_file": "inventory",
"vars": {
"ansible_check_mode": false,
"inventory_hostname": "u1404",
"inventory_file": "inventory",
"inventory_hostname_short": "u1404",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"environment": [],
"ansible_ssh_user": "root",
"ansible_play_hosts": [
"el6host"
],
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"group_names": [
"ungrouped"
],
"play_hosts": [
"el6host"
],
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
},
"role_names": []
},
"inventory_hostname_short": "u1404",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"group_names": [
"ungrouped"
],
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"ansible_host": "u1404",
"environment": [],
"ansible_play_hosts": [
"el6host"
],
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"ansible_check_mode": false,
"play_hosts": [
"el6host"
],
"role_names": [],
"ansible_port": null,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
},
"ansible_ssh_user": "root"
}
},
"ansible_module_compression": "ZIP_DEFLATED",
"ansible_failed_hosts": [],
"ansible_check_mode": false,
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"ansible_host": "u1404",
"ansible_shell_executable": "/bin/sh",
"inventory_hostname_short": "el6host",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"role_names": [],
"play_hosts": [
"el6host"
],
"ansible_sftp_extra_args": ""
}

View File

@@ -0,0 +1,387 @@
{
"ansible_pipelining": false,
"ansible_docker_extra_args": "",
"ansible_scp_extra_args": "",
"ansible_user": "root",
"ansible_play_hosts": [
"el6host"
],
"ansible_connection": "smart",
"ansible_ssh_common_args": "",
"environment": [],
"inventory_hostname": "el6host",
"vars": {
"ansible_check_mode": false,
"inventory_hostname": "el6host",
"inventory_file": "inventory",
"ansible_delegated_vars": {
"u1404": {
"inventory_hostname": "u1404",
"inventory_file": "inventory",
"vars": {
"inventory_file": "inventory",
"role_names": [],
"ansible_play_hosts": [
"el6host"
],
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"ansible_check_mode": false,
"inventory_hostname": "u1404",
"inventory_hostname_short": "u1404",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"environment": [],
"ansible_ssh_user": "root",
"group_names": [
"ungrouped"
],
"play_hosts": [
"el6host"
],
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
}
},
"inventory_hostname_short": "u1404",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"group_names": [
"ungrouped"
],
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"ansible_host": "u1404",
"environment": [],
"ansible_play_hosts": [
"el6host"
],
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"ansible_check_mode": false,
"play_hosts": [
"el6host"
],
"role_names": [],
"ansible_port": null,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
},
"ansible_ssh_user": "root"
}
},
"inventory_hostname_short": "el6host",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"role_names": [],
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"environment": [],
"play_hosts": [
"el6host"
],
"ansible_play_hosts": [
"el6host"
],
"hostvars": {
"el6host": {
"inventory_file": "inventory",
"group_names": [
"ungrouped"
],
"groups": {
"ungrouped": [
"el6host",
"u1404",
"::1"
],
"all": [
"el6host",
"u1404",
"::1"
]
},
"inventory_hostname": "el6host",
"inventory_hostname_short": "el6host",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"ansible_check_mode": false,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
}
},
"u1404": {
"inventory_file": "inventory",
"group_names": [
"ungrouped"
],
"groups": {
"ungrouped": [
"el6host",
"u1404",
"::1"
],
"all": [
"el6host",
"u1404",
"::1"
]
},
"inventory_hostname": "u1404",
"inventory_hostname_short": "u1404",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"ansible_check_mode": false,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
}
}
},
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"group_names": [
"ungrouped"
],
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
},
"ansible_ssh_user": "root"
},
"ansible_accelerate_port": 5099,
"roledir": null,
"ansible_ssh_extra_args": "",
"ansible_ssh_host": "u1404",
"ansible_current_hosts": [
"el6host"
],
"hostvars": {
"el6host": {
"inventory_file": "inventory",
"group_names": [
"ungrouped"
],
"groups": {
"ungrouped": [
"el6host",
"u1404",
"::1"
],
"all": [
"el6host",
"u1404",
"::1"
]
},
"inventory_hostname": "el6host",
"inventory_hostname_short": "el6host",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"ansible_check_mode": false,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
}
},
"u1404": {
"inventory_file": "inventory",
"group_names": [
"ungrouped"
],
"groups": {
"ungrouped": [
"el6host",
"u1404",
"::1"
],
"all": [
"el6host",
"u1404",
"::1"
]
},
"inventory_hostname": "u1404",
"inventory_hostname_short": "u1404",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"ansible_check_mode": false,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
}
}
},
"group_names": [
"ungrouped"
],
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
},
"ansible_ssh_pipelining": false,
"inventory_file": "inventory",
"ansible_delegated_vars": {
"u1404": {
"inventory_hostname": "u1404",
"inventory_file": "inventory",
"vars": {
"ansible_check_mode": false,
"inventory_hostname": "u1404",
"inventory_file": "inventory",
"inventory_hostname_short": "u1404",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"environment": [],
"ansible_ssh_user": "root",
"ansible_play_hosts": [
"el6host"
],
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"group_names": [
"ungrouped"
],
"play_hosts": [
"el6host"
],
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
},
"role_names": []
},
"inventory_hostname_short": "u1404",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"group_names": [
"ungrouped"
],
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"ansible_host": "u1404",
"environment": [],
"ansible_play_hosts": [
"el6host"
],
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"ansible_check_mode": false,
"play_hosts": [
"el6host"
],
"role_names": [],
"ansible_port": null,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
},
"ansible_ssh_user": "root"
}
},
"ansible_module_compression": "ZIP_DEFLATED",
"ansible_failed_hosts": [],
"ansible_check_mode": false,
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"ansible_host": "u1404",
"ansible_shell_executable": "/bin/sh",
"inventory_hostname_short": "el6host",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"role_names": [],
"play_hosts": [
"el6host"
],
"ansible_sftp_extra_args": ""
}

View File

@@ -0,0 +1,29 @@
fixtures:
taskvars_in: task_vars_in.json
taskvars_out: task_vars_out.json
task_args:
src: /tmp/deleteme
dest: /tmp/deleteme
private_key: ~/.ssh/id_rsa
_task:
delegate_to: u1404
_play_context:
shell: None
remote_addr: u1404
remote_user: root
private_key_file: ~/test.pem
connection:
transport: 'ssh'
hostvars:
'127.0.0.1': {}
'::1': {}
'localhost': {}
asserts:
- "hasattr(SAM._connection, 'ismock')"
- "SAM._connection.transport == 'ssh'"
- "self._play_context.shell == None"
- "self.execute_called"
- "self.final_module_args['_local_rsync_path'] == 'rsync'"
- "self.final_module_args['src'] == '/tmp/deleteme'"
- "self.final_module_args['dest'] == 'root@el6host:/tmp/deleteme'"
- "self.final_module_args['private_key'] == '~/.ssh/id_rsa'"

View File

@@ -0,0 +1,379 @@
{
"ansible_pipelining": false,
"ansible_docker_extra_args": "",
"ansible_scp_extra_args": "",
"ansible_user": "root",
"ansible_play_hosts": [
"el6host"
],
"ansible_connection": "smart",
"ansible_ssh_common_args": "",
"environment": [],
"inventory_hostname": "el6host",
"vars": {
"ansible_check_mode": false,
"inventory_hostname": "el6host",
"inventory_file": "inventory",
"ansible_delegated_vars": {
"u1404": {
"inventory_hostname": "u1404",
"inventory_file": "inventory",
"vars": {
"inventory_file": "inventory",
"role_names": [],
"ansible_play_hosts": [
"el6host"
],
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"ansible_check_mode": false,
"inventory_hostname": "u1404",
"inventory_hostname_short": "u1404",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"environment": [],
"ansible_ssh_user": "root",
"group_names": [
"ungrouped"
],
"play_hosts": [
"el6host"
],
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
}
},
"inventory_hostname_short": "u1404",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"group_names": [
"ungrouped"
],
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"ansible_host": "u1404",
"environment": [],
"ansible_play_hosts": [
"el6host"
],
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"ansible_check_mode": false,
"play_hosts": [
"el6host"
],
"role_names": [],
"ansible_port": null,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
},
"ansible_ssh_user": "root"
}
},
"inventory_hostname_short": "el6host",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"role_names": [],
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"environment": [],
"play_hosts": [
"el6host"
],
"ansible_play_hosts": [
"el6host"
],
"hostvars": {
"el6host": {
"inventory_file": "inventory",
"group_names": [
"ungrouped"
],
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"inventory_hostname": "el6host",
"inventory_hostname_short": "el6host",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"ansible_check_mode": false,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
}
},
"u1404": {
"inventory_file": "inventory",
"group_names": [
"ungrouped"
],
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"inventory_hostname": "u1404",
"inventory_hostname_short": "u1404",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"ansible_check_mode": false,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
}
}
},
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"group_names": [
"ungrouped"
],
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
},
"ansible_ssh_user": "root"
},
"ansible_accelerate_port": 5099,
"roledir": null,
"ansible_ssh_extra_args": "",
"ansible_ssh_host": "u1404",
"ansible_current_hosts": [
"el6host"
],
"hostvars": {
"el6host": {
"inventory_file": "inventory",
"group_names": [
"ungrouped"
],
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"inventory_hostname": "el6host",
"inventory_hostname_short": "el6host",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"ansible_check_mode": false,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
}
},
"u1404": {
"inventory_file": "inventory",
"group_names": [
"ungrouped"
],
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"inventory_hostname": "u1404",
"inventory_hostname_short": "u1404",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"ansible_check_mode": false,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
}
}
},
"group_names": [
"ungrouped"
],
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
},
"ansible_ssh_pipelining": false,
"inventory_file": "inventory",
"ansible_delegated_vars": {
"u1404": {
"inventory_hostname": "u1404",
"inventory_file": "inventory",
"vars": {
"ansible_check_mode": false,
"inventory_hostname": "u1404",
"inventory_file": "inventory",
"inventory_hostname_short": "u1404",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"environment": [],
"ansible_ssh_user": "root",
"ansible_play_hosts": [
"el6host"
],
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"group_names": [
"ungrouped"
],
"play_hosts": [
"el6host"
],
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
},
"role_names": []
},
"inventory_hostname_short": "u1404",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"group_names": [
"ungrouped"
],
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"ansible_host": "u1404",
"environment": [],
"ansible_play_hosts": [
"el6host"
],
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"ansible_check_mode": false,
"play_hosts": [
"el6host"
],
"role_names": [],
"ansible_port": null,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
},
"ansible_ssh_user": "root"
}
},
"ansible_module_compression": "ZIP_DEFLATED",
"ansible_failed_hosts": [],
"ansible_check_mode": false,
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"ansible_host": "u1404",
"ansible_shell_executable": "/bin/sh",
"inventory_hostname_short": "el6host",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"role_names": [],
"play_hosts": [
"el6host"
],
"ansible_sftp_extra_args": ""
}

View File

@@ -0,0 +1,387 @@
{
"ansible_pipelining": false,
"ansible_docker_extra_args": "",
"ansible_scp_extra_args": "",
"ansible_user": "root",
"ansible_play_hosts": [
"el6host"
],
"ansible_connection": "smart",
"ansible_ssh_common_args": "",
"environment": [],
"inventory_hostname": "el6host",
"vars": {
"ansible_check_mode": false,
"inventory_hostname": "el6host",
"inventory_file": "inventory",
"ansible_delegated_vars": {
"u1404": {
"inventory_hostname": "u1404",
"inventory_file": "inventory",
"vars": {
"inventory_file": "inventory",
"role_names": [],
"ansible_play_hosts": [
"el6host"
],
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"ansible_check_mode": false,
"inventory_hostname": "u1404",
"inventory_hostname_short": "u1404",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"environment": [],
"ansible_ssh_user": "root",
"group_names": [
"ungrouped"
],
"play_hosts": [
"el6host"
],
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
}
},
"inventory_hostname_short": "u1404",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"group_names": [
"ungrouped"
],
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"ansible_host": "u1404",
"environment": [],
"ansible_play_hosts": [
"el6host"
],
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"ansible_check_mode": false,
"play_hosts": [
"el6host"
],
"role_names": [],
"ansible_port": null,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
},
"ansible_ssh_user": "root"
}
},
"inventory_hostname_short": "el6host",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"role_names": [],
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"environment": [],
"play_hosts": [
"el6host"
],
"ansible_play_hosts": [
"el6host"
],
"hostvars": {
"el6host": {
"inventory_file": "inventory",
"group_names": [
"ungrouped"
],
"groups": {
"ungrouped": [
"el6host",
"u1404",
"::1"
],
"all": [
"el6host",
"u1404",
"::1"
]
},
"inventory_hostname": "el6host",
"inventory_hostname_short": "el6host",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"ansible_check_mode": false,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
}
},
"u1404": {
"inventory_file": "inventory",
"group_names": [
"ungrouped"
],
"groups": {
"ungrouped": [
"el6host",
"u1404",
"::1"
],
"all": [
"el6host",
"u1404",
"::1"
]
},
"inventory_hostname": "u1404",
"inventory_hostname_short": "u1404",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"ansible_check_mode": false,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
}
}
},
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"group_names": [
"ungrouped"
],
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
},
"ansible_ssh_user": "root"
},
"ansible_accelerate_port": 5099,
"roledir": null,
"ansible_ssh_extra_args": "",
"ansible_ssh_host": "u1404",
"ansible_current_hosts": [
"el6host"
],
"hostvars": {
"el6host": {
"inventory_file": "inventory",
"group_names": [
"ungrouped"
],
"groups": {
"ungrouped": [
"el6host",
"u1404",
"::1"
],
"all": [
"el6host",
"u1404",
"::1"
]
},
"inventory_hostname": "el6host",
"inventory_hostname_short": "el6host",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"ansible_check_mode": false,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
}
},
"u1404": {
"inventory_file": "inventory",
"group_names": [
"ungrouped"
],
"groups": {
"ungrouped": [
"el6host",
"u1404",
"::1"
],
"all": [
"el6host",
"u1404",
"::1"
]
},
"inventory_hostname": "u1404",
"inventory_hostname_short": "u1404",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"ansible_check_mode": false,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
}
}
},
"group_names": [
"ungrouped"
],
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
},
"ansible_ssh_pipelining": false,
"inventory_file": "inventory",
"ansible_delegated_vars": {
"u1404": {
"inventory_hostname": "u1404",
"inventory_file": "inventory",
"vars": {
"ansible_check_mode": false,
"inventory_hostname": "u1404",
"inventory_file": "inventory",
"inventory_hostname_short": "u1404",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"environment": [],
"ansible_ssh_user": "root",
"ansible_play_hosts": [
"el6host"
],
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"group_names": [
"ungrouped"
],
"play_hosts": [
"el6host"
],
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
},
"role_names": []
},
"inventory_hostname_short": "u1404",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"group_names": [
"ungrouped"
],
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"ansible_host": "u1404",
"environment": [],
"ansible_play_hosts": [
"el6host"
],
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"ansible_check_mode": false,
"play_hosts": [
"el6host"
],
"role_names": [],
"ansible_port": null,
"ansible_version": {
"major": 2,
"full": "2.2.0",
"string": "2.2.0",
"minor": 2,
"revision": 0
},
"ansible_ssh_user": "root"
}
},
"ansible_module_compression": "ZIP_DEFLATED",
"ansible_failed_hosts": [],
"ansible_check_mode": false,
"groups": {
"ungrouped": [
"el6host",
"u1404"
],
"all": [
"el6host",
"u1404"
]
},
"ansible_host": "u1404",
"ansible_shell_executable": "/bin/sh",
"inventory_hostname_short": "el6host",
"omit": "__omit_place_holder__2433ce0463ffd13b68850ce9cdd98a1cde088e22",
"inventory_dir": "/home/jtanner/workspace/issues/AP-15905",
"playbook_dir": "/home/jtanner/workspace/issues/AP-15905",
"ansible_ssh_user": "root",
"role_names": [],
"play_hosts": [
"el6host"
],
"ansible_sftp_extra_args": ""
}

View File

@@ -1,3 +1,7 @@
from __future__ import absolute_import, division, print_function
__metaclass__ = type
'''
(Epdb) pprint(DeepDiff(self.final_task_vars, out_task_vars), indent=2)
{ 'dic_item_added': set([u"root['ansible_python_interpreter']"]),
@@ -251,6 +255,23 @@ class TestSynchronizeAction(unittest.TestCase):
x = SynchronizeTester()
x.runtest(fixturepath=os.path.join(self.fixturedir, 'delegate_remote_su'))
@patch('ansible_collections.ansible.posix.plugins.action.synchronize.connection_loader', FakePluginLoader)
def test_basic_with_private_key(self):
x = SynchronizeTester()
x.runtest(fixturepath=os.path.join(self.fixturedir, 'basic_with_private_key'))
@patch('ansible_collections.ansible.posix.plugins.action.synchronize.connection_loader', FakePluginLoader)
def test_delegate_remote_with_private_key(self):
# delegate to other remote host and use the module param private_key
x = SynchronizeTester()
x.runtest(fixturepath=os.path.join(self.fixturedir, 'delegate_remote_with_private_key'))
@patch('ansible_collections.ansible.posix.plugins.action.synchronize.connection_loader', FakePluginLoader)
def test_delegate_remote_play_context_private_key(self):
# delegate to other remote host and use the play context private_key
x = SynchronizeTester()
x.runtest(fixturepath=os.path.join(self.fixturedir, 'delegate_remote_play_context_private_key'))
@patch.object(ActionModule, '_low_level_execute_command', side_effect=BreakPoint)
@patch.object(ActionModule, '_remote_expand_user', side_effect=ActionModule._remote_expand_user, autospec=True)
def test_remote_user_not_in_local_tmpdir(self, spy_remote_expand_user, ll_ec):

View File

@@ -0,0 +1 @@
remote.sh

View File

@@ -14,13 +14,16 @@ function join {
echo "$*";
}
# Ensure we can write other collections to this dir
sudo chown "$(whoami)" "${PWD}/../../"
test="$(join / "${args[@]:1}")"
docker images ansible/ansible
docker images quay.io/ansible/*
docker ps
for container in $(docker ps --format '{{.Image}} {{.ID}}' | grep -v '^drydock/' | sed 's/^.* //'); do
for container in $(docker ps --format '{{.Image}} {{.ID}}' | grep -v -e '^drydock/' -e '^quay.io/ansible/azure-pipelines-test-container:' | sed 's/^.* //'); do
docker rm -f "${container}" || true # ignore errors
done
@@ -59,12 +62,16 @@ else
retry pip install "https://github.com/ansible/ansible/archive/stable-${ansible_version}.tar.gz" --disable-pip-version-check
fi
export ANSIBLE_COLLECTIONS_PATHS="${HOME}/.ansible"
SHIPPABLE_RESULT_DIR="$(pwd)/shippable"
TEST_DIR="${ANSIBLE_COLLECTIONS_PATHS}/ansible_collections/ansible/posix"
mkdir -p "${TEST_DIR}"
cp -aT "${SHIPPABLE_BUILD_DIR}" "${TEST_DIR}"
cd "${TEST_DIR}"
if [ "${SHIPPABLE_BUILD_ID:-}" ]; then
export ANSIBLE_COLLECTIONS_PATHS="${HOME}/.ansible"
SHIPPABLE_RESULT_DIR="$(pwd)/shippable"
TEST_DIR="${ANSIBLE_COLLECTIONS_PATHS}/ansible_collections/ansible/posix"
mkdir -p "${TEST_DIR}"
cp -aT "${SHIPPABLE_BUILD_DIR}" "${TEST_DIR}"
cd "${TEST_DIR}"
else
export ANSIBLE_COLLECTIONS_PATHS="${PWD}/../../../"
fi
# START: HACK install dependencies
retry ansible-galaxy collection install community.general
@@ -187,7 +194,7 @@ function cleanup
fi
}
trap cleanup EXIT
if [ "${SHIPPABLE_BUILD_ID:-}" ]; then trap cleanup EXIT; fi
if [[ "${COVERAGE:-}" == "--coverage" ]]; then
timeout=60
@@ -197,5 +204,5 @@ fi
ansible-test env --dump --show --timeout "${timeout}" --color -v
"tests/utils/shippable/check_matrix.py"
if [ "${SHIPPABLE_BUILD_ID:-}" ]; then "tests/utils/shippable/check_matrix.py"; fi
"tests/utils/shippable/${script}.sh" "${test}"