mirror of
https://github.com/ansible-collections/ansible.posix.git
synced 2026-05-07 05:43:04 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
31559441dc | ||
|
|
6c3892c01b | ||
|
|
5717de0974 | ||
|
|
e270777b8d |
@@ -4,12 +4,7 @@
|
|||||||
# SPDX-FileCopyrightText: 2024, Ansible Project
|
# SPDX-FileCopyrightText: 2024, Ansible Project
|
||||||
|
|
||||||
skip_list:
|
skip_list:
|
||||||
- meta-runtime[unsupported-version] # This rule doesn't make any sense
|
- meta-runtime[unsupported-version] # Tis rule doesn't make any sense
|
||||||
- fqcn[deep] # This rule produces false positives for files in tests/unit/plugins/action/fixtures/
|
- fqcn[deep] # This rule produces false positives for files in tests/unit/plugins/action/fixtures/
|
||||||
- sanity[cannot-ignore] # This rule is skipped to keep backward compatibility with Python 2
|
|
||||||
|
|
||||||
exclude_paths:
|
exclude_paths:
|
||||||
- changelogs/
|
- changelogs/
|
||||||
- .github/
|
|
||||||
- tests/
|
|
||||||
- meta/
|
|
||||||
|
|||||||
@@ -37,13 +37,13 @@ variables:
|
|||||||
resources:
|
resources:
|
||||||
containers:
|
containers:
|
||||||
- container: default
|
- container: default
|
||||||
image: quay.io/ansible/azure-pipelines-test-container:7.0.0
|
image: quay.io/ansible/azure-pipelines-test-container:6.0.0
|
||||||
|
|
||||||
pool: Standard
|
pool: Standard
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- stage: Sanity_devel
|
- stage: Sanity_devel
|
||||||
displayName: Ansible devel Sanity & Units & Lint
|
displayName: Ansible devel sanity
|
||||||
dependsOn: []
|
dependsOn: []
|
||||||
jobs:
|
jobs:
|
||||||
- template: templates/matrix.yml
|
- template: templates/matrix.yml
|
||||||
@@ -57,57 +57,8 @@ stages:
|
|||||||
test: units
|
test: units
|
||||||
- name: Lint
|
- name: Lint
|
||||||
test: lint
|
test: lint
|
||||||
|
|
||||||
- stage: Sanity_2_21
|
|
||||||
displayName: Ansible 2.21 Sanity & Units & Lint
|
|
||||||
dependsOn: []
|
|
||||||
jobs:
|
|
||||||
- template: templates/matrix.yml
|
|
||||||
parameters:
|
|
||||||
nameFormat: "{0}"
|
|
||||||
testFormat: 2.21/{0}
|
|
||||||
targets:
|
|
||||||
- name: Sanity
|
|
||||||
test: sanity
|
|
||||||
- name: Units
|
|
||||||
test: units
|
|
||||||
- name: Lint
|
|
||||||
test: lint
|
|
||||||
|
|
||||||
- stage: Sanity_2_20
|
|
||||||
displayName: Ansible 2.20 Sanity & Units & Lint
|
|
||||||
dependsOn: []
|
|
||||||
jobs:
|
|
||||||
- template: templates/matrix.yml
|
|
||||||
parameters:
|
|
||||||
nameFormat: "{0}"
|
|
||||||
testFormat: 2.20/{0}
|
|
||||||
targets:
|
|
||||||
- name: Sanity
|
|
||||||
test: sanity
|
|
||||||
- name: Units
|
|
||||||
test: units
|
|
||||||
- name: Lint
|
|
||||||
test: lint
|
|
||||||
|
|
||||||
- stage: Sanity_2_19
|
|
||||||
displayName: Ansible 2.19 Sanity & Units & Lint
|
|
||||||
dependsOn: []
|
|
||||||
jobs:
|
|
||||||
- template: templates/matrix.yml
|
|
||||||
parameters:
|
|
||||||
nameFormat: "{0}"
|
|
||||||
testFormat: 2.19/{0}
|
|
||||||
targets:
|
|
||||||
- name: Sanity
|
|
||||||
test: sanity
|
|
||||||
- name: Units
|
|
||||||
test: units
|
|
||||||
- name: Lint
|
|
||||||
test: lint
|
|
||||||
|
|
||||||
- stage: Sanity_2_18
|
- stage: Sanity_2_18
|
||||||
displayName: Ansible 2.18 Sanity & Units & Lint
|
displayName: Ansible 2.18 sanity
|
||||||
dependsOn: []
|
dependsOn: []
|
||||||
jobs:
|
jobs:
|
||||||
- template: templates/matrix.yml
|
- template: templates/matrix.yml
|
||||||
@@ -121,7 +72,47 @@ stages:
|
|||||||
test: units
|
test: units
|
||||||
- name: Lint
|
- name: Lint
|
||||||
test: lint
|
test: lint
|
||||||
|
- stage: Sanity_2_17
|
||||||
|
displayName: Ansible 2.17 sanity
|
||||||
|
dependsOn: []
|
||||||
|
jobs:
|
||||||
|
- template: templates/matrix.yml
|
||||||
|
parameters:
|
||||||
|
nameFormat: "{0}"
|
||||||
|
testFormat: 2.17/{0}
|
||||||
|
targets:
|
||||||
|
- name: Sanity
|
||||||
|
test: sanity
|
||||||
|
- name: Units
|
||||||
|
test: units
|
||||||
|
- name: Lint
|
||||||
|
test: lint
|
||||||
|
- stage: Sanity_2_16
|
||||||
|
displayName: Ansible 2.16 sanity
|
||||||
|
dependsOn: []
|
||||||
|
jobs:
|
||||||
|
- template: templates/matrix.yml
|
||||||
|
parameters:
|
||||||
|
nameFormat: "{0}"
|
||||||
|
testFormat: 2.16/{0}
|
||||||
|
targets:
|
||||||
|
- name: Sanity
|
||||||
|
test: sanity
|
||||||
|
- name: Units
|
||||||
|
test: units
|
||||||
|
- stage: Sanity_2_15
|
||||||
|
displayName: Ansible 2.15 sanity
|
||||||
|
dependsOn: []
|
||||||
|
jobs:
|
||||||
|
- template: templates/matrix.yml
|
||||||
|
parameters:
|
||||||
|
nameFormat: "{0}"
|
||||||
|
testFormat: 2.15/{0}
|
||||||
|
targets:
|
||||||
|
- name: Sanity
|
||||||
|
test: sanity
|
||||||
|
- name: Units
|
||||||
|
test: units
|
||||||
## Docker
|
## Docker
|
||||||
- stage: Docker_devel
|
- stage: Docker_devel
|
||||||
displayName: Docker devel
|
displayName: Docker devel
|
||||||
@@ -131,60 +122,14 @@ stages:
|
|||||||
parameters:
|
parameters:
|
||||||
testFormat: devel/linux/{0}/1
|
testFormat: devel/linux/{0}/1
|
||||||
targets:
|
targets:
|
||||||
- name: Fedora 44
|
- name: Fedora 40
|
||||||
test: fedora44
|
test: fedora40
|
||||||
- name: Ubuntu 22.04
|
- name: Ubuntu 22.04
|
||||||
test: ubuntu2204
|
test: ubuntu2204
|
||||||
- name: Ubuntu 24.04
|
- name: Ubuntu 24.04
|
||||||
test: ubuntu2404
|
test: ubuntu2404
|
||||||
|
|
||||||
- stage: Docker_2_21
|
|
||||||
displayName: Docker 2.21
|
|
||||||
dependsOn: []
|
|
||||||
jobs:
|
|
||||||
- template: templates/matrix.yml
|
|
||||||
parameters:
|
|
||||||
testFormat: devel/linux/{0}/1
|
|
||||||
targets:
|
|
||||||
- name: Fedora 44
|
|
||||||
test: fedora44
|
|
||||||
- name: Ubuntu 22.04
|
|
||||||
test: ubuntu2204
|
|
||||||
- name: Ubuntu 24.04
|
|
||||||
test: ubuntu2404
|
|
||||||
|
|
||||||
- stage: Docker_2_20
|
|
||||||
displayName: Docker 2.20
|
|
||||||
dependsOn: []
|
|
||||||
jobs:
|
|
||||||
- template: templates/matrix.yml
|
|
||||||
parameters:
|
|
||||||
testFormat: 2.20/linux/{0}/1
|
|
||||||
targets:
|
|
||||||
- name: Fedora 42
|
|
||||||
test: fedora42
|
|
||||||
- name: Ubuntu 22.04
|
|
||||||
test: ubuntu2204
|
|
||||||
- name: Ubuntu 24.04
|
|
||||||
test: ubuntu2404
|
|
||||||
|
|
||||||
- stage: Docker_2_19
|
|
||||||
displayName: Docker 2.19
|
|
||||||
dependsOn: []
|
|
||||||
jobs:
|
|
||||||
- template: templates/matrix.yml
|
|
||||||
parameters:
|
|
||||||
testFormat: 2.19/linux/{0}/1
|
|
||||||
targets:
|
|
||||||
- name: Fedora 41
|
|
||||||
test: fedora41
|
|
||||||
- name: Ubuntu 22.04
|
|
||||||
test: ubuntu2204
|
|
||||||
- name: Ubuntu 24.04
|
|
||||||
test: ubuntu2404
|
|
||||||
|
|
||||||
- stage: Docker_2_18
|
- stage: Docker_2_18
|
||||||
displayName: Docker 2.18
|
displayName: Docker devel
|
||||||
dependsOn: []
|
dependsOn: []
|
||||||
jobs:
|
jobs:
|
||||||
- template: templates/matrix.yml
|
- template: templates/matrix.yml
|
||||||
@@ -197,6 +142,55 @@ stages:
|
|||||||
test: ubuntu2204
|
test: ubuntu2204
|
||||||
- name: Ubuntu 24.04
|
- name: Ubuntu 24.04
|
||||||
test: ubuntu2404
|
test: ubuntu2404
|
||||||
|
- stage: Docker_2_17
|
||||||
|
displayName: Docker 2.17
|
||||||
|
dependsOn: []
|
||||||
|
jobs:
|
||||||
|
- template: templates/matrix.yml
|
||||||
|
parameters:
|
||||||
|
testFormat: 2.17/linux/{0}/1
|
||||||
|
targets:
|
||||||
|
- name: Fedora 39
|
||||||
|
test: fedora39
|
||||||
|
- name: Ubuntu 20.04
|
||||||
|
test: ubuntu2004
|
||||||
|
- name: Ubuntu 22.04
|
||||||
|
test: ubuntu2204
|
||||||
|
- stage: Docker_2_16
|
||||||
|
displayName: Docker 2.16
|
||||||
|
dependsOn: []
|
||||||
|
jobs:
|
||||||
|
- template: templates/matrix.yml
|
||||||
|
parameters:
|
||||||
|
testFormat: 2.16/linux/{0}/1
|
||||||
|
targets:
|
||||||
|
- name: CentOS 7
|
||||||
|
test: centos7
|
||||||
|
- name: Fedora 38
|
||||||
|
test: fedora38
|
||||||
|
- name: Ubuntu 20.04
|
||||||
|
test: ubuntu2004
|
||||||
|
- name: Ubuntu 22.04
|
||||||
|
test: ubuntu2204
|
||||||
|
|
||||||
|
- stage: Docker_2_15
|
||||||
|
displayName: Docker 2.15
|
||||||
|
dependsOn: []
|
||||||
|
jobs:
|
||||||
|
- template: templates/matrix.yml
|
||||||
|
parameters:
|
||||||
|
testFormat: 2.15/linux/{0}/1
|
||||||
|
targets:
|
||||||
|
- name: CentOS 7
|
||||||
|
test: centos7
|
||||||
|
- name: Fedora 37
|
||||||
|
test: fedora37
|
||||||
|
- name: openSUSE 15 py3
|
||||||
|
test: opensuse15
|
||||||
|
- name: Ubuntu 20.04
|
||||||
|
test: ubuntu2004
|
||||||
|
- name: Ubuntu 22.04
|
||||||
|
test: ubuntu2204
|
||||||
|
|
||||||
## Remote
|
## Remote
|
||||||
- stage: Remote_devel
|
- stage: Remote_devel
|
||||||
@@ -207,100 +201,85 @@ stages:
|
|||||||
parameters:
|
parameters:
|
||||||
testFormat: devel/{0}/1
|
testFormat: devel/{0}/1
|
||||||
targets:
|
targets:
|
||||||
- name: RHEL 10.1
|
- name: RHEL 9.4
|
||||||
test: rhel/10.1
|
test: rhel/9.4
|
||||||
- name: RHEL 9.7
|
- name: FreeBSD 13.3
|
||||||
test: rhel/9.7
|
test: freebsd/13.3
|
||||||
- name: FreeBSD 14.4
|
|
||||||
test: freebsd/14.4
|
|
||||||
- name: FreeBSD 15.0
|
|
||||||
test: freebsd/15.0
|
|
||||||
|
|
||||||
- stage: Remote_2_21
|
|
||||||
displayName: Remote 2.21
|
|
||||||
dependsOn: []
|
|
||||||
jobs:
|
|
||||||
- template: templates/matrix.yml
|
|
||||||
parameters:
|
|
||||||
testFormat: devel/{0}/1
|
|
||||||
targets:
|
|
||||||
- name: RHEL 10.1
|
|
||||||
test: rhel/10.1
|
|
||||||
- name: RHEL 9.7
|
|
||||||
test: rhel/9.7
|
|
||||||
- name: FreeBSD 14.4
|
|
||||||
test: freebsd/14.4
|
|
||||||
- name: FreeBSD 15.0
|
|
||||||
test: freebsd/15.0
|
|
||||||
|
|
||||||
- stage: Remote_2_20
|
|
||||||
displayName: Remote 2.20
|
|
||||||
dependsOn: []
|
|
||||||
jobs:
|
|
||||||
- template: templates/matrix.yml
|
|
||||||
parameters:
|
|
||||||
testFormat: 2.20/{0}/1
|
|
||||||
targets:
|
|
||||||
- name: RHEL 10.1
|
|
||||||
test: rhel/10.1
|
|
||||||
- name: RHEL 9.7
|
|
||||||
test: rhel/9.7
|
|
||||||
- name: FreeBSD 14.3
|
|
||||||
test: freebsd/14.3
|
|
||||||
- name: FreeBSD 13.5
|
|
||||||
test: freebsd/13.5
|
|
||||||
|
|
||||||
- stage: Remote_2_19
|
|
||||||
displayName: Remote 2.19
|
|
||||||
dependsOn: []
|
|
||||||
jobs:
|
|
||||||
- template: templates/matrix.yml
|
|
||||||
parameters:
|
|
||||||
testFormat: 2.19/{0}/1
|
|
||||||
targets:
|
|
||||||
- name: RHEL 10.1
|
|
||||||
test: rhel/10.1
|
|
||||||
- name: RHEL 9.7
|
|
||||||
test: rhel/9.7
|
|
||||||
- name: FreeBSD 14.2
|
|
||||||
test: freebsd/14.2
|
|
||||||
- name: FreeBSD 13.5
|
|
||||||
test: freebsd/13.5
|
|
||||||
|
|
||||||
- stage: Remote_2_18
|
- stage: Remote_2_18
|
||||||
displayName: Remote 2.18
|
displayName: Remote devel
|
||||||
dependsOn: []
|
dependsOn: []
|
||||||
jobs:
|
jobs:
|
||||||
- template: templates/matrix.yml
|
- template: templates/matrix.yml
|
||||||
parameters:
|
parameters:
|
||||||
testFormat: 2.18/{0}/1
|
testFormat: 2.18/{0}/1
|
||||||
targets:
|
targets:
|
||||||
- name: RHEL 10.1
|
- name: RHEL 9.4
|
||||||
test: rhel/10.1
|
test: rhel/9.4
|
||||||
- name: RHEL 9.7
|
- name: FreeBSD 13.3
|
||||||
test: rhel/9.7
|
test: freebsd/13.3
|
||||||
- name: FreeBSD 13.5
|
- stage: Remote_2_17
|
||||||
test: freebsd/13.5
|
displayName: Remote 2.17
|
||||||
|
dependsOn: []
|
||||||
|
jobs:
|
||||||
|
- template: templates/matrix.yml
|
||||||
|
parameters:
|
||||||
|
testFormat: 2.17/{0}/1
|
||||||
|
targets:
|
||||||
|
- name: RHEL 9.3
|
||||||
|
test: rhel/9.3
|
||||||
|
- name: FreeBSD 13.3
|
||||||
|
test: freebsd/13.3
|
||||||
|
- stage: Remote_2_16
|
||||||
|
displayName: Remote 2.16
|
||||||
|
dependsOn: []
|
||||||
|
jobs:
|
||||||
|
- template: templates/matrix.yml
|
||||||
|
parameters:
|
||||||
|
testFormat: 2.16/{0}/1
|
||||||
|
targets:
|
||||||
|
- name: RHEL 8.8
|
||||||
|
test: rhel/8.8
|
||||||
|
- name: RHEL 9.2
|
||||||
|
test: rhel/9.2
|
||||||
|
- name: FreeBSD 13.2
|
||||||
|
test: freebsd/13.2
|
||||||
|
|
||||||
|
- stage: Remote_2_15
|
||||||
|
displayName: Remote 2.15
|
||||||
|
dependsOn: []
|
||||||
|
jobs:
|
||||||
|
- template: templates/matrix.yml
|
||||||
|
parameters:
|
||||||
|
testFormat: 2.15/{0}/1
|
||||||
|
targets:
|
||||||
|
- name: RHEL 7.9
|
||||||
|
test: rhel/7.9
|
||||||
|
- name: RHEL 8.7
|
||||||
|
test: rhel/8.7
|
||||||
|
- name: RHEL 9.1
|
||||||
|
test: rhel/9.1
|
||||||
|
- name: FreeBSD 13.2
|
||||||
|
test: freebsd/13.2
|
||||||
|
|
||||||
## Finally
|
## Finally
|
||||||
|
|
||||||
- stage: Summary
|
- stage: Summary
|
||||||
condition: succeededOrFailed()
|
condition: succeededOrFailed()
|
||||||
dependsOn:
|
dependsOn:
|
||||||
|
- Sanity_2_15
|
||||||
|
- Remote_2_15
|
||||||
|
- Docker_2_15
|
||||||
|
- Sanity_2_16
|
||||||
|
- Remote_2_16
|
||||||
|
- Docker_2_16
|
||||||
|
- Sanity_2_17
|
||||||
|
- Remote_2_17
|
||||||
|
- Docker_2_17
|
||||||
- Sanity_2_18
|
- Sanity_2_18
|
||||||
- Remote_2_18
|
- Remote_2_18
|
||||||
- Docker_2_18
|
- Docker_2_18
|
||||||
- Sanity_2_19
|
|
||||||
- Remote_2_19
|
|
||||||
- Docker_2_19
|
|
||||||
- Sanity_2_20
|
|
||||||
- Remote_2_20
|
|
||||||
- Docker_2_20
|
|
||||||
- Sanity_2_21
|
|
||||||
- Remote_2_21
|
|
||||||
- Docker_2_21
|
|
||||||
- Sanity_devel
|
- Sanity_devel
|
||||||
- Remote_devel
|
# - Remote_devel # Wait for test environment release
|
||||||
- Docker_devel
|
# - Docker_devel # Wait for test environment release
|
||||||
jobs:
|
jobs:
|
||||||
- template: templates/coverage.yml
|
- template: templates/coverage.yml
|
||||||
|
|||||||
53
.github/BOTMETA.yml
vendored
Normal file
53
.github/BOTMETA.yml
vendored
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
---
|
||||||
|
automerge: false
|
||||||
|
files:
|
||||||
|
$module_utils/mount.py:
|
||||||
|
labels: mount
|
||||||
|
$modules/acl.py:
|
||||||
|
authors: astorije bcoca
|
||||||
|
labels: acl
|
||||||
|
ignore: astorije
|
||||||
|
$modules/at.py:
|
||||||
|
authors: risaacson
|
||||||
|
labels: at
|
||||||
|
$modules/authorized_key.py:
|
||||||
|
authors: ansible
|
||||||
|
labels: authorized_key
|
||||||
|
$modules/mount.py:
|
||||||
|
authors: ansible skvidal
|
||||||
|
maintainers: jtyr
|
||||||
|
labels: mount
|
||||||
|
ignore: skvidal
|
||||||
|
$modules/patch.py:
|
||||||
|
authors: jirutka luisperlaz
|
||||||
|
$modules/seboolean.py:
|
||||||
|
authors: sfromm
|
||||||
|
labels: seboolean
|
||||||
|
$modules/selinux.py:
|
||||||
|
authors: goozbach
|
||||||
|
maintainers: samdoran
|
||||||
|
labels: selinux
|
||||||
|
$modules/synchronize.py:
|
||||||
|
authors: tima
|
||||||
|
labels: synchronize
|
||||||
|
$modules/sysctl.py:
|
||||||
|
authors: davixx
|
||||||
|
maintainers: Akasurde
|
||||||
|
labels: sysctl
|
||||||
|
$plugins/:
|
||||||
|
labels: profile
|
||||||
|
$plugins/debug.py:
|
||||||
|
labels: debug
|
||||||
|
$plugins/patch.py:
|
||||||
|
labels: patch
|
||||||
|
$plugins/skippy.py:
|
||||||
|
$plugins/synchronize.py:
|
||||||
|
labels: synchronize
|
||||||
|
$plugins/timer.py:
|
||||||
|
macros:
|
||||||
|
actions: plugins/action
|
||||||
|
callbacks: plugins/callback
|
||||||
|
module_utils: plugins/module_utils
|
||||||
|
modules: plugins/modules
|
||||||
|
plugins: plugins/plugins
|
||||||
|
shells: plugins/shell
|
||||||
35
.github/workflows/certification.yml
vendored
35
.github/workflows/certification.yml
vendored
@@ -1,35 +0,0 @@
|
|||||||
---
|
|
||||||
# This workflow calls the latest version of the
|
|
||||||
# reusable workflow.
|
|
||||||
# You can copy this file into your respository if
|
|
||||||
# you want to check against pinned versions of
|
|
||||||
# Automation Hub tests.
|
|
||||||
name: Run collection certification checks
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
branches: [main]
|
|
||||||
workflow_dispatch:
|
|
||||||
schedule:
|
|
||||||
- cron: '0 6 * * *'
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: cert-ver-${{ github.head_ref || github.run_id }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
|
|
||||||
# Files that are not related to the core functionality
|
|
||||||
# of your collection can cause Ansible Lint to fail.
|
|
||||||
# If this happens, add an .ansible-lint file that includes
|
|
||||||
# those files and directories to the root of your
|
|
||||||
# repository; for example:
|
|
||||||
# https://github.com/ansible-collections/partner-certification-checker/blob/main/.ansible-lint
|
|
||||||
# https://github.com/ansible-collections/partner-certification-checker/blob/main/.ansible-lint
|
|
||||||
|
|
||||||
# If there are sanity test failures that cannot be fixed and are allowed to ignore
|
|
||||||
# https://docs.ansible.com/projects/lint/rules/sanity/, create a sanity ignore file
|
|
||||||
# https://docs.ansible.com/projects/ansible/devel/dev_guide/testing/sanity/ignores.html#ignore-file-location
|
|
||||||
# for each affected version of ansible-core (for example, `tests/sanity/ignore-2.18.txt`) and add corresponding entries.
|
|
||||||
jobs:
|
|
||||||
call:
|
|
||||||
uses: ansible-collections/partner-certification-checker/.github/workflows/certification-reusable.yml@v0.1
|
|
||||||
@@ -4,57 +4,6 @@ ansible.posix Release Notes
|
|||||||
|
|
||||||
.. contents:: Topics
|
.. contents:: Topics
|
||||||
|
|
||||||
v2.0.0
|
|
||||||
======
|
|
||||||
|
|
||||||
Release Summary
|
|
||||||
---------------
|
|
||||||
|
|
||||||
This is the major release of the ``ansible.posix`` collection.
|
|
||||||
This changelog contains all changes to the modules and plugins
|
|
||||||
in this collection that have been added after the release of
|
|
||||||
``ansible.posix`` 1.6.2
|
|
||||||
|
|
||||||
Minor Changes
|
|
||||||
-------------
|
|
||||||
|
|
||||||
- authorized_keys - allow using absolute path to a file as a SSH key(s) source (https://github.com/ansible-collections/ansible.posix/pull/568)
|
|
||||||
- callback plugins - Add recap information to timer, profile_roles and profile_tasks callback outputs (https://github.com/ansible-collections/ansible.posix/pull/387).
|
|
||||||
|
|
||||||
Breaking Changes / Porting Guide
|
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
- firewalld - Changed the type of forward and masquerade options from str to bool (https://github.com/ansible-collections/ansible.posix/issues/582).
|
|
||||||
- firewalld - Changed the type of icmp_block_inversion option from str to bool (https://github.com/ansible-collections/ansible.posix/issues/586).
|
|
||||||
|
|
||||||
Removed Features (previously deprecated)
|
|
||||||
----------------------------------------
|
|
||||||
|
|
||||||
- skippy - Remove skippy pluglin as it is no longer supported(https://github.com/ansible-collections/ansible.posix/issues/350).
|
|
||||||
|
|
||||||
Bugfixes
|
|
||||||
--------
|
|
||||||
|
|
||||||
- acl - Fixed to set ACLs on paths mounted with NFS version 4 correctly (https://github.com/ansible-collections/ansible.posix/issues/240).
|
|
||||||
- mount - Handle ``boot`` option on Linux, NetBSD and OpenBSD correctly (https://github.com/ansible-collections/ansible.posix/issues/364).
|
|
||||||
- mount - If a comment is appended to a fstab entry, state present creates a double-entry (https://github.com/ansible-collections/ansible.posix/issues/595).
|
|
||||||
|
|
||||||
v1.6.2
|
|
||||||
======
|
|
||||||
|
|
||||||
Release Summary
|
|
||||||
---------------
|
|
||||||
|
|
||||||
This is the bugfix release of the stable version ``ansible.posix`` collection.
|
|
||||||
This changelog contains all changes to the modules and plugins
|
|
||||||
in this collection that have been added after the release of
|
|
||||||
``ansible.posix`` 1.6.1.
|
|
||||||
|
|
||||||
Bugfixes
|
|
||||||
--------
|
|
||||||
|
|
||||||
- backport - Drop ansible-core 2.14 and set 2.15 minimum version (https://github.com/ansible-collections/ansible.posix/issues/578).
|
|
||||||
|
|
||||||
v1.6.1
|
v1.6.1
|
||||||
======
|
======
|
||||||
|
|
||||||
|
|||||||
135
README.md
135
README.md
@@ -2,7 +2,10 @@
|
|||||||
<!-- Add CI and code coverage badges here. Samples included below. -->
|
<!-- Add CI and code coverage badges here. Samples included below. -->
|
||||||
[](https://dev.azure.com/ansible/ansible.posix/_build?definitionId=26)
|
https://dev.azure.com/ansible/ansible.posix/_apis/build/status/CI?branchName=main)](https://dev.azure.com/ansible/ansible.posix/_build?definitionId=26)
|
||||||
[](https://codecov.io/gh/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? -->
|
||||||
|
An Ansible Collection of modules and plugins that target POSIX UNIX/Linux and derivative Operating Systems.
|
||||||
|
|
||||||
## Communication
|
## Communication
|
||||||
|
|
||||||
@@ -11,102 +14,88 @@ https://dev.azure.com/ansible/ansible.posix/_apis/build/status/CI?branchName=mai
|
|||||||
* [Social Spaces](https://forum.ansible.com/c/chat/4): gather and interact with fellow enthusiasts.
|
* [Social Spaces](https://forum.ansible.com/c/chat/4): gather and interact with fellow enthusiasts.
|
||||||
* [News & Announcements](https://forum.ansible.com/c/news/5): track project-wide announcements including social events.
|
* [News & Announcements](https://forum.ansible.com/c/news/5): track project-wide announcements including social events.
|
||||||
|
|
||||||
## Description
|
|
||||||
|
|
||||||
<!-- Describe the collection and why a user would want to use it. What does the collection do? -->
|
|
||||||
An Ansible Collection of modules and plugins that target POSIX UNIX/Linux and derivative Operating Systems.
|
|
||||||
|
|
||||||
## Requirements
|
|
||||||
|
|
||||||
* Python:
|
|
||||||
* The Python interpreter version must meet Ansible Core's requirements.
|
|
||||||
* Ansible Core:
|
|
||||||
- ansible-core 2.16 or later
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
Before using this collection, you need to install it with the Ansible Galaxy command-line tool:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
ansible-galaxy collection install ansible.posix
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also include it in a requirements.yml file and install it with ansible-galaxy collection install -r requirements.yml, using the format:
|
|
||||||
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
collections:
|
|
||||||
- name: ansible.posix
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that if you install any collections from Ansible Galaxy, they will not be upgraded automatically when you upgrade the Ansible package.
|
|
||||||
To upgrade the collection to the latest available version, run the following command:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
ansible-galaxy collection install ansible.posix --upgrade
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also install a specific version of the collection, for example, if you need to downgrade when something is broken in the latest version (please report an issue in this repository). Use the following syntax to install version 2.0.0:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
ansible-galaxy collection install ansible.posix:==2.0.0
|
|
||||||
```
|
|
||||||
|
|
||||||
See [using Ansible collections](https://docs.ansible.com/ansible/devel/user_guide/collections_using.html) for more details.
|
|
||||||
|
|
||||||
* The Ansible [Bullhorn newsletter](https://docs.ansible.com/ansible/devel/community/communication.html#the-bullhorn): used to announce releases and important changes.
|
* The Ansible [Bullhorn newsletter](https://docs.ansible.com/ansible/devel/community/communication.html#the-bullhorn): used to announce releases and important changes.
|
||||||
|
|
||||||
For more information about communication, see the [Ansible communication guide](https://docs.ansible.com/ansible/devel/community/communication.html).
|
For more information about communication, see the [Ansible communication guide](https://docs.ansible.com/ansible/devel/community/communication.html).
|
||||||
|
|
||||||
## Use Cases
|
## Supported Versions of Ansible
|
||||||
|
<!--start requires_ansible-->
|
||||||
|
## Ansible version compatibility
|
||||||
|
|
||||||
You can see the general use-cases as an example by `ansible-doc` command like below.
|
This collection has been tested against following Ansible versions: **>=2.15**.
|
||||||
|
<!--end requires_ansible-->
|
||||||
|
|
||||||
For example, ansible.posix.firewalld module:
|
## Included content
|
||||||
```shell
|
Check out [Ansible Galaxy](https://galaxy.ansible.com/ui/repo/published/ansible/posix/content/) or [the Ansible documentation](https://docs.ansible.com/ansible/devel/collections/ansible/posix/) for all modules and plugins included in this collection.
|
||||||
ansible-doc ansible.posix.firewalld
|
|
||||||
|
## Installing this collection
|
||||||
|
|
||||||
|
You can install the ``ansible.posix`` collection with the Ansible Galaxy CLI:
|
||||||
|
|
||||||
|
ansible-galaxy collection install ansible.posix
|
||||||
|
|
||||||
|
You can also include it in a `requirements.yml` file and install it with `ansible-galaxy collection install -r requirements.yml`, using the format:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
collections:
|
||||||
|
- name: ansible.posix
|
||||||
```
|
```
|
||||||
|
|
||||||
Also, if you want to confirm the plugins descriptions, you can follow the following option with `ansible-doc` command:
|
## Using this collection
|
||||||
|
|
||||||
For example, ansible.posix.profile_tasks callback plugin:
|
<!--Include some quick examples that cover the most common use cases for your collection content. -->
|
||||||
```shell
|
|
||||||
ansible-doc -t callback ansible.posix.profile_tasks
|
|
||||||
```
|
|
||||||
|
|
||||||
## Testing
|
See [Ansible Using collections](https://docs.ansible.com/ansible/latest/user_guide/collections_using.html) for more details.
|
||||||
|
|
||||||
The following ansible-core versions have been tested with this collection:
|
## Contributing to this collection
|
||||||
|
|
||||||
- ansible-core 2.20 (devel)
|
<!--Describe how the community can contribute to your collection. At a minimum, include how and where users can create issues to report problems or request features for this collection. List contribution requirements, including preferred workflows and necessary testing, so you can benefit from community PRs. If you are following general Ansible contributor guidelines, you can link to - [Ansible Community Guide](https://docs.ansible.com/ansible/latest/community/index.html). -->
|
||||||
- ansible-core 2.19 (stable) *
|
|
||||||
- ansible-core 2.18 (stable)
|
|
||||||
- ansible-core 2.17 (stable)
|
|
||||||
|
|
||||||
## Contributing
|
We welcome community contributions to this collection. See [Contributing to Ansible-maintained collections](https://docs.ansible.com/ansible/devel/community/contributing_maintained_collections.html#contributing-maintained-collections) for complete details.
|
||||||
|
|
||||||
We welcome community contributions to this collection. For more details, see [Contributing to Ansible-maintained collections](https://docs.ansible.com/ansible/devel/community/contributing_maintained_collections.html#contributing-maintained-collections) for complete details.
|
|
||||||
|
|
||||||
* [Issues](https://github.com/ansible-collections/ansible.posix/issues)
|
* [Issues](https://github.com/ansible-collections/ansible.posix/issues)
|
||||||
* [Pull Requests](https://github.com/ansible-collections/ansible.posix/pulls)
|
* [Pull Requests](https://github.com/ansible-collections/ansible.posix/pulls)
|
||||||
* [Ansible Community Guide](https://docs.ansible.com/ansible/latest/community/index.html)
|
* [Ansible Community Guide](https://docs.ansible.com/ansible/latest/community/index.html)
|
||||||
|
|
||||||
|
### Code of Conduct
|
||||||
|
This collection follows the Ansible project's
|
||||||
|
[Code of Conduct](https://docs.ansible.com/ansible/devel/community/code_of_conduct.html).
|
||||||
|
Please read and familiarize yourself with this document.
|
||||||
|
|
||||||
## Support
|
## Release notes
|
||||||
|
|
||||||
See [Communication](#Communication) section.
|
|
||||||
|
|
||||||
## Release Notes and Roadmap
|
|
||||||
|
|
||||||
See [changelog](https://github.com/ansible-collections/ansible.posix/blob/main/CHANGELOG.rst) for more details.
|
See [changelog](https://github.com/ansible-collections/ansible.posix/blob/main/CHANGELOG.rst) for more details.
|
||||||
|
|
||||||
## Related Information
|
## External requirements
|
||||||
|
|
||||||
This document was written using the following [template](https://access.redhat.com/articles/7068606).
|
None
|
||||||
|
|
||||||
The README has been carefully prepared to cover the [community template](https://github.com/ansible-collections/collection_template/blob/main/README.md), but if you find any problems, please file a [documentation issue](https://github.com/ansible-collections/ansible.posix/issues/new?assignees=&labels=&projects=&template=documentation_report.md).
|
## Tested with Ansible
|
||||||
|
|
||||||
## License Information
|
<!-- List the versions of Ansible the collection has been tested with. Must match what is in galaxy.yml. -->
|
||||||
|
|
||||||
|
- ansible-core 2.19 (devel)
|
||||||
|
- ansible-core 2.18 (stable) *
|
||||||
|
- ansible-core 2.17 (stable)
|
||||||
|
- ansible-core 2.16 (stable)
|
||||||
|
- ansible-core 2.15 (stable)
|
||||||
|
|
||||||
|
*Note: For ansible-core 2.18, CI only covers sanity tests and no integration tests will be run until the test environment is released.*
|
||||||
|
|
||||||
|
## Roadmap
|
||||||
|
|
||||||
|
<!-- Optional. Include the roadmap for this collection, and the proposed release/versioning strategy so users can anticipate the upgrade/update cycle. -->
|
||||||
|
|
||||||
|
## More information
|
||||||
|
|
||||||
|
<!-- List out where the user can find additional information, such as working group meeting times, slack/IRC channels, or documentation for the product this collection automates. At a minimum, link to: -->
|
||||||
|
|
||||||
|
- [Ansible Collection overview](https://github.com/ansible-collections/overview)
|
||||||
|
- [Ansible User guide](https://docs.ansible.com/ansible/latest/user_guide/index.html)
|
||||||
|
- [Ansible Developer guide](https://docs.ansible.com/ansible/latest/dev_guide/index.html)
|
||||||
|
- [Ansible Community code of conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html)
|
||||||
|
|
||||||
|
## Licensing
|
||||||
|
|
||||||
GNU General Public License v3.0 or later.
|
GNU General Public License v3.0 or later.
|
||||||
|
|
||||||
|
|||||||
@@ -429,64 +429,3 @@ releases:
|
|||||||
- 571_ci_bump_core_version.yml
|
- 571_ci_bump_core_version.yml
|
||||||
- 572_revert_removal_of_skippy.yml
|
- 572_revert_removal_of_skippy.yml
|
||||||
release_date: '2024-10-11'
|
release_date: '2024-10-11'
|
||||||
1.6.2:
|
|
||||||
changes:
|
|
||||||
bugfixes:
|
|
||||||
- backport - Drop ansible-core 2.14 and set 2.15 minimum version (https://github.com/ansible-collections/ansible.posix/issues/578).
|
|
||||||
release_summary: 'This is the bugfix release of the stable version ``ansible.posix``
|
|
||||||
collection.
|
|
||||||
|
|
||||||
This changelog contains all changes to the modules and plugins
|
|
||||||
|
|
||||||
in this collection that have been added after the release of
|
|
||||||
|
|
||||||
``ansible.posix`` 1.6.1.'
|
|
||||||
fragments:
|
|
||||||
- 1.6.2.yml
|
|
||||||
- 580_drop_ansible214.yml
|
|
||||||
release_date: '2024-10-22'
|
|
||||||
2.0.0:
|
|
||||||
changes:
|
|
||||||
breaking_changes:
|
|
||||||
- firewalld - Changed the type of forward and masquerade options from str to
|
|
||||||
bool (https://github.com/ansible-collections/ansible.posix/issues/582).
|
|
||||||
- firewalld - Changed the type of icmp_block_inversion option from str to bool
|
|
||||||
(https://github.com/ansible-collections/ansible.posix/issues/586).
|
|
||||||
bugfixes:
|
|
||||||
- acl - Fixed to set ACLs on paths mounted with NFS version 4 correctly (https://github.com/ansible-collections/ansible.posix/issues/240).
|
|
||||||
- mount - Handle ``boot`` option on Linux, NetBSD and OpenBSD correctly (https://github.com/ansible-collections/ansible.posix/issues/364).
|
|
||||||
- mount - If a comment is appended to a fstab entry, state present creates a
|
|
||||||
double-entry (https://github.com/ansible-collections/ansible.posix/issues/595).
|
|
||||||
minor_changes:
|
|
||||||
- authorized_keys - allow using absolute path to a file as a SSH key(s) source
|
|
||||||
(https://github.com/ansible-collections/ansible.posix/pull/568)
|
|
||||||
- callback plugins - Add recap information to timer, profile_roles and profile_tasks
|
|
||||||
callback outputs (https://github.com/ansible-collections/ansible.posix/pull/387).
|
|
||||||
release_summary: 'This is the major release of the ``ansible.posix`` collection.
|
|
||||||
|
|
||||||
This changelog contains all changes to the modules and plugins
|
|
||||||
|
|
||||||
in this collection that have been added after the release of
|
|
||||||
|
|
||||||
``ansible.posix`` 1.6.2'
|
|
||||||
removed_features:
|
|
||||||
- skippy - Remove skippy pluglin as it is no longer supported(https://github.com/ansible-collections/ansible.posix/issues/350).
|
|
||||||
fragments:
|
|
||||||
- 2.0.0.yml
|
|
||||||
- 365-boot-linux.yml
|
|
||||||
- 387_callback_output_header.yml
|
|
||||||
- 556_remove_skippy_callback.yml
|
|
||||||
- 566_bump_version_161.yml
|
|
||||||
- 567_remove_version_added.yml
|
|
||||||
- 568_update_authorized_key.yml
|
|
||||||
- 570_nfs4_acl.yml
|
|
||||||
- 571_ci_bump_core_version.yml
|
|
||||||
- 576_bump_version_2.yml
|
|
||||||
- 581_ci_selinux.yml
|
|
||||||
- 584_firewalld_opt_type.yml
|
|
||||||
- 587_update_README.yml
|
|
||||||
- 588_ci_enable_devel.yml
|
|
||||||
- 593_replace_freebsd_version.yml
|
|
||||||
- 597_remove_fstab_comment_on_updating.yml
|
|
||||||
- 598_icmp_block_inversion.yml
|
|
||||||
release_date: '2024-12-04'
|
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
trivial:
|
|
||||||
- Bump version to 3.0.0 for the next release (https://github.com/ansible-collections/ansible.posix/issues/603).
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
trivial:
|
|
||||||
- Remove ubuntu20.04 from CI tests (https://github.com/ansible-collections/ansible.posix/issues/612).
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
---
|
|
||||||
minor_changes:
|
|
||||||
- profile_tasks - Add option to provide a different date/time format (https://github.com/ansible-collections/ansible.posix/issues/279).
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
---
|
|
||||||
bugfixes:
|
|
||||||
- ansible.posix.cgroup_perf_recap - fixes json module load path (https://github.com/ansible-collections/ansible.posix/issues/630).
|
|
||||||
trivial:
|
|
||||||
- ansible.posix.seboolean - remove unnecessary condition from seboolean integration tests (https://github.com/ansible-collections/ansible.posix/issues/630).
|
|
||||||
- ansible.posix.selinux - optimize conditions for selinux integration tests (https://github.com/ansible-collections/ansible.posix/issues/630).
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
---
|
|
||||||
bugfixes:
|
|
||||||
- ansible.posix.authorized_key - fixes error on permission denied in authorized_key module (https://github.com/ansible-collections/ansible.posix/issues/462).
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
trivial:
|
|
||||||
- Add Red Hat Enterprise Linux 10.0 to the CI matrix (https://github.com/ansible-collections/ansible.posix/issues/642).
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
minor_changes:
|
|
||||||
- "profile_tasks and profile_roles callback plugins - avoid deleted/deprecated callback functions, instead use modern interface that was introduced a longer time ago (https://github.com/ansible-collections/ansible.posix/issues/650)."
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
---
|
|
||||||
trivial:
|
|
||||||
- Bump ansible-core version to 2.20 of devel branch and add 2.19 to CI
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
trivial:
|
|
||||||
- AZP - fixed syntax error in CI test.
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
---
|
|
||||||
trivial:
|
|
||||||
- README - Update README to reflect Ansible Core 2.19 release.
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
---
|
|
||||||
trivial:
|
|
||||||
- AZP - Update AZP matrix to follow ansible-test changes.
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
bugfixes:
|
|
||||||
- "firewalld_info - stop returning warnings as return values; this has been deprecated by ansible-core (https://github.com/ansible-collections/ansible.posix/pull/670)."
|
|
||||||
- "mount - stop returning warnings as return values; this has been deprecated by ansible-core (https://github.com/ansible-collections/ansible.posix/pull/670)."
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
trivial:
|
|
||||||
- Update AZP CI matrix (https://github.com/ansible-collections/ansible.posix/issues/673).
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
trivial:
|
|
||||||
- Updatng AZP CI matrix to ignore ansible-bad-import-from on six(https://github.com/ansible-collections/ansible.posix/pull/682).
|
|
||||||
- Skipped sanity[cannot-ignore] to keep backward compatibility with Python2.
|
|
||||||
- Consolidate all ansible-lint option locations into .ansible-lint file.
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
---
|
|
||||||
minor_changes:
|
|
||||||
- acl - fix deprecated ``ansible.module_utils._text`` import (https://github.com/ansible-collections/ansible.posix/issues/686).
|
|
||||||
- authorized_key - fix deprecated ``ansible.module_utils._text`` and ``ansible.module_utils.six`` imports (https://github.com/ansible-collections/ansible.posix/issues/686).
|
|
||||||
- cgroup_perf_recap callback - fix deprecated ``ansible.module_utils._text`` and ``ansible.module_utils.six`` imports (https://github.com/ansible-collections/ansible.posix/issues/686).
|
|
||||||
- csh shell plugin - fix deprecated ``ansible.module_utils.six`` imports (https://github.com/ansible-collections/ansible.posix/issues/686).
|
|
||||||
- firewalld_info - fix deprecated ``ansible.module_utils._text`` import (https://github.com/ansible-collections/ansible.posix/issues/686).
|
|
||||||
- fish shell plugin - fix deprecated ``ansible.module_utils.six`` imports (https://github.com/ansible-collections/ansible.posix/issues/686).
|
|
||||||
- json callback - fix deprecated ``ansible.module_utils._text`` import (https://github.com/ansible-collections/ansible.posix/issues/686).
|
|
||||||
- jsonl callback - fix deprecated ``ansible.module_utils._text`` import (https://github.com/ansible-collections/ansible.posix/issues/686).
|
|
||||||
- mount - fix deprecated ``ansible.module_utils._text`` and ``ansible.module_utils.six`` imports (https://github.com/ansible-collections/ansible.posix/issues/686).
|
|
||||||
- patch - fix deprecated ``ansible.module_utils._text`` import (https://github.com/ansible-collections/ansible.posix/issues/686).
|
|
||||||
- profile_roles callback - fix deprecated ``ansible.module_utils.six`` import (https://github.com/ansible-collections/ansible.posix/issues/686).
|
|
||||||
- profile_tasks callback - fix deprecated ``ansible.module_utils.six`` import (https://github.com/ansible-collections/ansible.posix/issues/686).
|
|
||||||
- rhel_rpm_ostree - fix deprecated ``ansible.module_utils._text`` import (https://github.com/ansible-collections/ansible.posix/issues/686).
|
|
||||||
- rpm_ostree_upgrade - fix deprecated ``ansible.module_utils._text`` import (https://github.com/ansible-collections/ansible.posix/issues/686).
|
|
||||||
- seboolean - fix deprecated ``ansible.module_utils._text`` import (https://github.com/ansible-collections/ansible.posix/issues/686).
|
|
||||||
- synchronize - fix deprecated ``ansible.module_utils._text``, ``ansible.module_utils.common._collections_compat``, and ``ansible.module_utils.six`` imports (https://github.com/ansible-collections/ansible.posix/issues/686).
|
|
||||||
- sysctl - fix deprecated ``ansible.module_utils._text`` and ``ansible.module_utils.six`` imports (https://github.com/ansible-collections/ansible.posix/issues/686).
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
trivial:
|
|
||||||
- AZP - Update AZP matrix to follow ansible-test changes.
|
|
||||||
- Add ignore file for Ansible Core 2.21.
|
|
||||||
- Remove ignore lines for ansible-bad-import-from in 2.20 sanity tests.
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
namespace: ansible
|
namespace: ansible
|
||||||
name: posix
|
name: posix
|
||||||
version: 3.0.0
|
version: 1.6.1
|
||||||
readme: README.md
|
readme: README.md
|
||||||
authors:
|
authors:
|
||||||
- Ansible (github.com/ansible)
|
- Ansible (github.com/ansible)
|
||||||
|
|||||||
@@ -1,2 +1,8 @@
|
|||||||
---
|
---
|
||||||
requires_ansible: ">=2.16.0"
|
requires_ansible: ">=2.14.0"
|
||||||
|
plugin_routing:
|
||||||
|
callback:
|
||||||
|
skippy:
|
||||||
|
deprecation:
|
||||||
|
removal_date: "2024-12-05"
|
||||||
|
warning_text: See the plugin documentation for more details
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ __metaclass__ = type
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
from ansible.errors import AnsibleError, AnsibleAction, _AnsibleActionDone, AnsibleActionFail
|
from ansible.errors import AnsibleError, AnsibleAction, _AnsibleActionDone, AnsibleActionFail
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils._text import to_native
|
||||||
from ansible.module_utils.parsing.convert_bool import boolean
|
from ansible.module_utils.parsing.convert_bool import boolean
|
||||||
from ansible.plugins.action import ActionBase
|
from ansible.plugins.action import ActionBase
|
||||||
|
|
||||||
|
|||||||
@@ -18,11 +18,12 @@ from __future__ import (absolute_import, division, print_function)
|
|||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
from collections.abc import MutableSequence
|
|
||||||
from shlex import quote as shlex_quote
|
|
||||||
|
|
||||||
from ansible import constants as C
|
from ansible import constants as C
|
||||||
from ansible.module_utils.common.text.converters import to_text
|
from ansible.module_utils.six import string_types
|
||||||
|
from ansible.module_utils.six.moves import shlex_quote
|
||||||
|
from ansible.module_utils._text import to_text
|
||||||
|
from ansible.module_utils.common._collections_compat import MutableSequence
|
||||||
from ansible.module_utils.parsing.convert_bool import boolean
|
from ansible.module_utils.parsing.convert_bool import boolean
|
||||||
from ansible.plugins.action import ActionBase
|
from ansible.plugins.action import ActionBase
|
||||||
from ansible.plugins.loader import connection_loader
|
from ansible.plugins.loader import connection_loader
|
||||||
@@ -416,7 +417,7 @@ class ActionModule(ActionBase):
|
|||||||
# Replicate what we do in the module argumentspec handling for lists
|
# Replicate what we do in the module argumentspec handling for lists
|
||||||
if not isinstance(_tmp_args.get('rsync_opts'), MutableSequence):
|
if not isinstance(_tmp_args.get('rsync_opts'), MutableSequence):
|
||||||
tmp_rsync_opts = _tmp_args.get('rsync_opts', [])
|
tmp_rsync_opts = _tmp_args.get('rsync_opts', [])
|
||||||
if isinstance(tmp_rsync_opts, str):
|
if isinstance(tmp_rsync_opts, string_types):
|
||||||
tmp_rsync_opts = tmp_rsync_opts.split(',')
|
tmp_rsync_opts = tmp_rsync_opts.split(',')
|
||||||
elif isinstance(tmp_rsync_opts, (int, float)):
|
elif isinstance(tmp_rsync_opts, (int, float)):
|
||||||
tmp_rsync_opts = [to_text(tmp_rsync_opts)]
|
tmp_rsync_opts = [to_text(tmp_rsync_opts)]
|
||||||
|
|||||||
@@ -132,7 +132,6 @@ DOCUMENTATION = '''
|
|||||||
|
|
||||||
import csv
|
import csv
|
||||||
import datetime
|
import datetime
|
||||||
import json
|
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import threading
|
import threading
|
||||||
@@ -141,8 +140,9 @@ from abc import ABCMeta, abstractmethod
|
|||||||
|
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
from ansible.module_utils._text import to_bytes, to_text
|
||||||
from ansible.parsing.ajson import AnsibleJSONEncoder
|
from ansible.module_utils.six import with_metaclass
|
||||||
|
from ansible.parsing.ajson import AnsibleJSONEncoder, json
|
||||||
from ansible.plugins.callback import CallbackBase
|
from ansible.plugins.callback import CallbackBase
|
||||||
|
|
||||||
|
|
||||||
@@ -157,7 +157,7 @@ def dict_fromkeys(keys, default=None):
|
|||||||
return d
|
return d
|
||||||
|
|
||||||
|
|
||||||
class BaseProf(threading.Thread, metaclass=ABCMeta):
|
class BaseProf(with_metaclass(ABCMeta, threading.Thread)):
|
||||||
def __init__(self, path, obj=None, writer=None):
|
def __init__(self, path, obj=None, writer=None):
|
||||||
threading.Thread.__init__(self) # pylint: disable=non-parent-init-called
|
threading.Thread.__init__(self) # pylint: disable=non-parent-init-called
|
||||||
self.obj = obj
|
self.obj = obj
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ import json
|
|||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from ansible.inventory.host import Host
|
from ansible.inventory.host import Host
|
||||||
from ansible.module_utils.common.text.converters import to_text
|
from ansible.module_utils._text import to_text
|
||||||
from ansible.parsing.ajson import AnsibleJSONEncoder
|
from ansible.parsing.ajson import AnsibleJSONEncoder
|
||||||
from ansible.plugins.callback import CallbackBase
|
from ansible.plugins.callback import CallbackBase
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ import copy
|
|||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from ansible.inventory.host import Host
|
from ansible.inventory.host import Host
|
||||||
from ansible.module_utils.common.text.converters import to_text
|
from ansible.module_utils._text import to_text
|
||||||
from ansible.parsing.ajson import AnsibleJSONEncoder
|
from ansible.parsing.ajson import AnsibleJSONEncoder
|
||||||
from ansible.plugins.callback import CallbackBase
|
from ansible.plugins.callback import CallbackBase
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import collections
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
from ansible.plugins.callback import CallbackBase
|
from ansible.plugins.callback import CallbackBase
|
||||||
from functools import reduce
|
from ansible.module_utils.six.moves import reduce
|
||||||
|
|
||||||
# define start time
|
# define start time
|
||||||
t0 = tn = time.time()
|
t0 = tn = time.time()
|
||||||
@@ -124,11 +124,11 @@ class CallbackModule(CallbackBase):
|
|||||||
def v2_playbook_on_handler_task_start(self, task):
|
def v2_playbook_on_handler_task_start(self, task):
|
||||||
self._record_task(task)
|
self._record_task(task)
|
||||||
|
|
||||||
def v2_playbook_on_stats(self, stats):
|
def playbook_on_setup(self):
|
||||||
# Align summary report header with other callback plugin summary
|
self._display_tasktime()
|
||||||
self._display.banner("ROLES RECAP")
|
|
||||||
|
|
||||||
self._display.display(tasktime())
|
def playbook_on_stats(self, stats):
|
||||||
|
self._display_tasktime()
|
||||||
self._display.display(filled("", fchar="="))
|
self._display.display(filled("", fchar="="))
|
||||||
|
|
||||||
timestamp(self)
|
timestamp(self)
|
||||||
|
|||||||
@@ -52,17 +52,6 @@ DOCUMENTATION = '''
|
|||||||
- section: callback_profile_tasks
|
- section: callback_profile_tasks
|
||||||
key: summary_only
|
key: summary_only
|
||||||
version_added: 1.5.0
|
version_added: 1.5.0
|
||||||
datetime_format:
|
|
||||||
description:
|
|
||||||
- Datetime format, as expected by the C(strftime) and C(strptime) methods.
|
|
||||||
An C(iso8601) alias will be translated to C('%Y-%m-%dT%H:%M:%S.%f') if that datetime standard wants to be used.
|
|
||||||
default: '%A %d %B %Y %H:%M:%S %z'
|
|
||||||
env:
|
|
||||||
- name: PROFILE_TASKS_DATETIME_FORMAT
|
|
||||||
ini:
|
|
||||||
- section: callback_profile_tasks
|
|
||||||
key: datetime_format
|
|
||||||
version_added: 3.0.0
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = '''
|
EXAMPLES = '''
|
||||||
@@ -83,15 +72,14 @@ sample output: >
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
|
import time
|
||||||
|
|
||||||
from datetime import datetime
|
from ansible.module_utils.six.moves import reduce
|
||||||
|
|
||||||
from functools import reduce
|
|
||||||
from ansible.plugins.callback import CallbackBase
|
from ansible.plugins.callback import CallbackBase
|
||||||
|
|
||||||
|
|
||||||
# define start time
|
# define start time
|
||||||
dt0 = dtn = datetime.now().astimezone()
|
t0 = tn = time.time()
|
||||||
|
|
||||||
|
|
||||||
def secondsToStr(t):
|
def secondsToStr(t):
|
||||||
@@ -116,18 +104,17 @@ def filled(msg, fchar="*"):
|
|||||||
|
|
||||||
def timestamp(self):
|
def timestamp(self):
|
||||||
if self.current is not None:
|
if self.current is not None:
|
||||||
elapsed = (datetime.now().astimezone() - self.stats[self.current]['started']).total_seconds()
|
elapsed = time.time() - self.stats[self.current]['started']
|
||||||
self.stats[self.current]['elapsed'] += elapsed
|
self.stats[self.current]['elapsed'] += elapsed
|
||||||
|
|
||||||
|
|
||||||
def tasktime(self):
|
def tasktime():
|
||||||
global dtn
|
global tn
|
||||||
cdtn = datetime.now().astimezone()
|
time_current = time.strftime('%A %d %B %Y %H:%M:%S %z')
|
||||||
datetime_current = cdtn.strftime(self.datetime_format)
|
time_elapsed = secondsToStr(time.time() - tn)
|
||||||
time_elapsed = secondsToStr((cdtn - dtn).total_seconds())
|
time_total_elapsed = secondsToStr(time.time() - t0)
|
||||||
time_total_elapsed = secondsToStr((cdtn - dt0).total_seconds())
|
tn = time.time()
|
||||||
dtn = cdtn
|
return filled('%s (%s)%s%s' % (time_current, time_elapsed, ' ' * 7, time_total_elapsed))
|
||||||
return filled('%s (%s)%s%s' % (datetime_current, time_elapsed, ' ' * 7, time_total_elapsed))
|
|
||||||
|
|
||||||
|
|
||||||
class CallbackModule(CallbackBase):
|
class CallbackModule(CallbackBase):
|
||||||
@@ -147,7 +134,6 @@ class CallbackModule(CallbackBase):
|
|||||||
self.sort_order = None
|
self.sort_order = None
|
||||||
self.summary_only = None
|
self.summary_only = None
|
||||||
self.task_output_limit = None
|
self.task_output_limit = None
|
||||||
self.datetime_format = None
|
|
||||||
|
|
||||||
super(CallbackModule, self).__init__()
|
super(CallbackModule, self).__init__()
|
||||||
|
|
||||||
@@ -173,14 +159,9 @@ class CallbackModule(CallbackBase):
|
|||||||
else:
|
else:
|
||||||
self.task_output_limit = int(self.task_output_limit)
|
self.task_output_limit = int(self.task_output_limit)
|
||||||
|
|
||||||
self.datetime_format = self.get_option('datetime_format')
|
|
||||||
if self.datetime_format is not None:
|
|
||||||
if self.datetime_format == 'iso8601':
|
|
||||||
self.datetime_format = '%Y-%m-%dT%H:%M:%S.%f'
|
|
||||||
|
|
||||||
def _display_tasktime(self):
|
def _display_tasktime(self):
|
||||||
if not self.summary_only:
|
if not self.summary_only:
|
||||||
self._display.display(tasktime(self))
|
self._display.display(tasktime())
|
||||||
|
|
||||||
def _record_task(self, task):
|
def _record_task(self, task):
|
||||||
"""
|
"""
|
||||||
@@ -195,11 +176,10 @@ class CallbackModule(CallbackBase):
|
|||||||
# with the same UUID is executed when `serial` is specified in a playbook.
|
# with the same UUID is executed when `serial` is specified in a playbook.
|
||||||
# elapsed: Elapsed time since the first serialized task was started
|
# elapsed: Elapsed time since the first serialized task was started
|
||||||
self.current = task._uuid
|
self.current = task._uuid
|
||||||
dtn = datetime.now().astimezone()
|
|
||||||
if self.current not in self.stats:
|
if self.current not in self.stats:
|
||||||
self.stats[self.current] = {'started': dtn, 'elapsed': 0.0, 'name': task.get_name()}
|
self.stats[self.current] = {'started': time.time(), 'elapsed': 0.0, 'name': task.get_name()}
|
||||||
else:
|
else:
|
||||||
self.stats[self.current]['started'] = dtn
|
self.stats[self.current]['started'] = time.time()
|
||||||
if self._display.verbosity >= 2:
|
if self._display.verbosity >= 2:
|
||||||
self.stats[self.current]['path'] = task.get_path()
|
self.stats[self.current]['path'] = task.get_path()
|
||||||
|
|
||||||
@@ -209,11 +189,11 @@ class CallbackModule(CallbackBase):
|
|||||||
def v2_playbook_on_handler_task_start(self, task):
|
def v2_playbook_on_handler_task_start(self, task):
|
||||||
self._record_task(task)
|
self._record_task(task)
|
||||||
|
|
||||||
def v2_playbook_on_stats(self, stats):
|
def playbook_on_setup(self):
|
||||||
# Align summary report header with other callback plugin summary
|
self._display_tasktime()
|
||||||
self._display.banner("TASKS RECAP")
|
|
||||||
|
|
||||||
self._display.display(tasktime(self))
|
def playbook_on_stats(self, stats):
|
||||||
|
self._display_tasktime()
|
||||||
self._display.display(filled("", fchar="="))
|
self._display.display(filled("", fchar="="))
|
||||||
|
|
||||||
timestamp(self)
|
timestamp(self)
|
||||||
|
|||||||
43
plugins/callback/skippy.py
Normal file
43
plugins/callback/skippy.py
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com>
|
||||||
|
# (c) 2017 Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
# Make coding more python3-ish
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
DOCUMENTATION = '''
|
||||||
|
name: skippy
|
||||||
|
type: stdout
|
||||||
|
requirements:
|
||||||
|
- set as main display callback
|
||||||
|
short_description: Ansible screen output that ignores skipped status
|
||||||
|
deprecated:
|
||||||
|
why: The 'default' callback plugin now supports this functionality
|
||||||
|
removed_at_date: '2024-12-05'
|
||||||
|
alternative: "'default' callback plugin with 'display_skipped_hosts = no' option"
|
||||||
|
extends_documentation_fragment:
|
||||||
|
- default_callback
|
||||||
|
description:
|
||||||
|
- This callback does the same as the default except it does not output skipped host/task/item status
|
||||||
|
'''
|
||||||
|
|
||||||
|
from ansible.plugins.callback.default import CallbackModule as CallbackModule_default
|
||||||
|
|
||||||
|
|
||||||
|
class CallbackModule(CallbackModule_default):
|
||||||
|
|
||||||
|
'''
|
||||||
|
This is the default callback interface, which simply prints messages
|
||||||
|
to stdout when new callback events are received.
|
||||||
|
'''
|
||||||
|
|
||||||
|
CALLBACK_VERSION = 2.0
|
||||||
|
CALLBACK_TYPE = 'stdout'
|
||||||
|
CALLBACK_NAME = 'ansible.posix.skippy'
|
||||||
|
|
||||||
|
def v2_runner_on_skipped(self, result):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def v2_runner_item_on_skipped(self, result):
|
||||||
|
pass
|
||||||
@@ -46,6 +46,4 @@ class CallbackModule(CallbackBase):
|
|||||||
def v2_playbook_on_stats(self, stats):
|
def v2_playbook_on_stats(self, stats):
|
||||||
end_time = datetime.utcnow()
|
end_time = datetime.utcnow()
|
||||||
runtime = end_time - self.start_time
|
runtime = end_time - self.start_time
|
||||||
# Align summary report header with other callback plugin summary
|
self._display.display("Playbook run took %s days, %s hours, %s minutes, %s seconds" % (self.days_hours_minutes_seconds(runtime)))
|
||||||
self._display.banner("PLAYBOOK RECAP")
|
|
||||||
self._display.display("Playbook run took %s days, %s hours, %s minutes, %s seconds\n\r" % (self.days_hours_minutes_seconds(runtime)))
|
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ import os
|
|||||||
import platform
|
import platform
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils._text import to_native
|
||||||
|
|
||||||
|
|
||||||
def split_entry(entry):
|
def split_entry(entry):
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ options:
|
|||||||
key:
|
key:
|
||||||
description:
|
description:
|
||||||
- The SSH public key(s), as a string or (since Ansible 1.9) url (https://github.com/username.keys).
|
- The SSH public key(s), as a string or (since Ansible 1.9) url (https://github.com/username.keys).
|
||||||
- You can also use V(file://) prefix to search remote for a file with SSH key(s).
|
|
||||||
type: str
|
type: str
|
||||||
required: true
|
required: true
|
||||||
path:
|
path:
|
||||||
@@ -97,12 +96,6 @@ EXAMPLES = r'''
|
|||||||
state: present
|
state: present
|
||||||
key: https://github.com/charlie.keys
|
key: https://github.com/charlie.keys
|
||||||
|
|
||||||
- name: Set authorized keys taken from path on controller node
|
|
||||||
ansible.posix.authorized_key:
|
|
||||||
user: charlie
|
|
||||||
state: present
|
|
||||||
key: file:///home/charlie/.ssh/id_rsa.pub
|
|
||||||
|
|
||||||
- name: Set authorized keys taken from url using lookup
|
- name: Set authorized keys taken from url using lookup
|
||||||
ansible.posix.authorized_key:
|
ansible.posix.authorized_key:
|
||||||
user: charlie
|
user: charlie
|
||||||
@@ -225,20 +218,10 @@ import os.path
|
|||||||
import tempfile
|
import tempfile
|
||||||
import re
|
import re
|
||||||
import shlex
|
import shlex
|
||||||
import errno
|
|
||||||
import traceback
|
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
|
|
||||||
# TODO(Python2): urllib.parse is available in Python 3. This module may run on
|
from ansible.module_utils._text import to_native
|
||||||
# target hosts with Python 2.7 (e.g., older RHEL systems in CI integration tests).
|
|
||||||
# Remove the try/except fallback to urlparse when Python 2 support is dropped.
|
|
||||||
try:
|
|
||||||
from urllib.parse import urlparse
|
|
||||||
except ImportError:
|
|
||||||
from urlparse import urlparse
|
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
|
||||||
from ansible.module_utils.urls import fetch_url
|
from ansible.module_utils.urls import fetch_url
|
||||||
|
|
||||||
|
|
||||||
@@ -484,18 +467,16 @@ def parsekey(module, raw_key, rank=None):
|
|||||||
return (key, key_type, options, comment, rank)
|
return (key, key_type, options, comment, rank)
|
||||||
|
|
||||||
|
|
||||||
def readfile(module, filename):
|
def readfile(filename):
|
||||||
|
|
||||||
|
if not os.path.isfile(filename):
|
||||||
|
return ''
|
||||||
|
|
||||||
|
f = open(filename)
|
||||||
try:
|
try:
|
||||||
with open(filename, 'r') as f:
|
return f.read()
|
||||||
return f.read()
|
finally:
|
||||||
except IOError as e:
|
f.close()
|
||||||
if e.errno == errno.EACCES:
|
|
||||||
module.fail_json(msg="Permission denied on file or path for authorized keys file: %s" % filename,
|
|
||||||
exception=traceback.format_exc())
|
|
||||||
elif e.errno == errno.ENOENT:
|
|
||||||
return ''
|
|
||||||
else:
|
|
||||||
raise
|
|
||||||
|
|
||||||
|
|
||||||
def parsekeys(module, lines):
|
def parsekeys(module, lines):
|
||||||
@@ -575,7 +556,7 @@ def enforce_state(module, params):
|
|||||||
follow = params.get('follow', False)
|
follow = params.get('follow', False)
|
||||||
error_msg = "Error getting key from: %s"
|
error_msg = "Error getting key from: %s"
|
||||||
|
|
||||||
# if the key is a url or file, request it and use it as key source
|
# if the key is a url, request it and use it as key source
|
||||||
if key.startswith("http"):
|
if key.startswith("http"):
|
||||||
try:
|
try:
|
||||||
resp, info = fetch_url(module, key)
|
resp, info = fetch_url(module, key)
|
||||||
@@ -589,26 +570,13 @@ def enforce_state(module, params):
|
|||||||
# resp.read gives bytes on python3, convert to native string type
|
# resp.read gives bytes on python3, convert to native string type
|
||||||
key = to_native(key, errors='surrogate_or_strict')
|
key = to_native(key, errors='surrogate_or_strict')
|
||||||
|
|
||||||
if key.startswith("file"):
|
|
||||||
# if the key is an absolute path, check for existense and use it as a key source
|
|
||||||
key_path = urlparse(key).path
|
|
||||||
if not os.path.exists(key_path):
|
|
||||||
module.fail_json(msg="Path to a key file not found: %s" % key_path)
|
|
||||||
if not os.path.isfile(key_path):
|
|
||||||
module.fail_json(msg="Path to a key is a directory and must be a file: %s" % key_path)
|
|
||||||
try:
|
|
||||||
with open(key_path, 'r') as source_fh:
|
|
||||||
key = source_fh.read()
|
|
||||||
except OSError as e:
|
|
||||||
module.fail_json(msg="Failed to read key file %s : %s" % (key_path, to_native(e)))
|
|
||||||
|
|
||||||
# extract individual keys into an array, skipping blank lines and comments
|
# extract individual keys into an array, skipping blank lines and comments
|
||||||
new_keys = [s for s in key.splitlines() if s and not s.startswith('#')]
|
new_keys = [s for s in key.splitlines() if s and not s.startswith('#')]
|
||||||
|
|
||||||
# check current state -- just get the filename, don't create file
|
# check current state -- just get the filename, don't create file
|
||||||
do_write = False
|
do_write = False
|
||||||
params["keyfile"] = keyfile(module, user, do_write, path, manage_dir)
|
params["keyfile"] = keyfile(module, user, do_write, path, manage_dir)
|
||||||
existing_content = readfile(module, params["keyfile"])
|
existing_content = readfile(params["keyfile"])
|
||||||
existing_keys = parsekeys(module, existing_content)
|
existing_keys = parsekeys(module, existing_content)
|
||||||
|
|
||||||
# Add a place holder for keys that should exist in the state=present and
|
# Add a place holder for keys that should exist in the state=present and
|
||||||
|
|||||||
@@ -74,8 +74,7 @@ options:
|
|||||||
icmp_block_inversion:
|
icmp_block_inversion:
|
||||||
description:
|
description:
|
||||||
- Enable/Disable inversion of ICMP blocks for a zone in firewalld.
|
- Enable/Disable inversion of ICMP blocks for a zone in firewalld.
|
||||||
- Note that the option type is changed to bool in ansible.posix version 2.0.0 and later.
|
type: str
|
||||||
type: bool
|
|
||||||
zone:
|
zone:
|
||||||
description:
|
description:
|
||||||
- The firewalld zone to add/remove to/from.
|
- The firewalld zone to add/remove to/from.
|
||||||
@@ -113,13 +112,11 @@ options:
|
|||||||
description:
|
description:
|
||||||
- The forward setting you would like to enable/disable to/from zones within firewalld.
|
- The forward setting you would like to enable/disable to/from zones within firewalld.
|
||||||
- This option only is supported by firewalld v0.9.0 or later.
|
- This option only is supported by firewalld v0.9.0 or later.
|
||||||
- Note that the option type is changed to bool in ansible.posix version 2.0.0 and later.
|
type: str
|
||||||
type: bool
|
|
||||||
masquerade:
|
masquerade:
|
||||||
description:
|
description:
|
||||||
- The masquerade setting you would like to enable/disable to/from zones within firewalld.
|
- The masquerade setting you would like to enable/disable to/from zones within firewalld.
|
||||||
- Note that the option type is changed to bool in ansible.posix version 2.0.0 and later.
|
type: str
|
||||||
type: bool
|
|
||||||
offline:
|
offline:
|
||||||
description:
|
description:
|
||||||
- Ignores O(immediate) if O(permanent=true) and firewalld is not running.
|
- Ignores O(immediate) if O(permanent=true) and firewalld is not running.
|
||||||
@@ -153,7 +150,7 @@ author:
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = r'''
|
EXAMPLES = r'''
|
||||||
- name: Permanently enable https service, also enable it immediately if possible
|
- name: permanently enable https service, also enable it immediately if possible
|
||||||
ansible.posix.firewalld:
|
ansible.posix.firewalld:
|
||||||
service: https
|
service: https
|
||||||
state: enabled
|
state: enabled
|
||||||
@@ -161,92 +158,81 @@ EXAMPLES = r'''
|
|||||||
immediate: true
|
immediate: true
|
||||||
offline: true
|
offline: true
|
||||||
|
|
||||||
- name: Permit traffic in default zone for https service
|
- name: permit traffic in default zone for https service
|
||||||
ansible.posix.firewalld:
|
ansible.posix.firewalld:
|
||||||
service: https
|
service: https
|
||||||
permanent: true
|
permanent: true
|
||||||
state: enabled
|
state: enabled
|
||||||
|
|
||||||
- name: Permit ospf traffic
|
- name: permit ospf traffic
|
||||||
ansible.posix.firewalld:
|
ansible.posix.firewalld:
|
||||||
protocol: ospf
|
protocol: ospf
|
||||||
permanent: true
|
permanent: true
|
||||||
state: enabled
|
state: enabled
|
||||||
|
|
||||||
- name: Do not permit traffic in default zone on port 8081/tcp
|
- name: do not permit traffic in default zone on port 8081/tcp
|
||||||
ansible.posix.firewalld:
|
ansible.posix.firewalld:
|
||||||
port: 8081/tcp
|
port: 8081/tcp
|
||||||
permanent: true
|
permanent: true
|
||||||
state: disabled
|
state: disabled
|
||||||
|
|
||||||
- name: Permit traffic in default zone on port 161-162/ucp
|
- ansible.posix.firewalld:
|
||||||
ansible.posix.firewalld:
|
|
||||||
port: 161-162/udp
|
port: 161-162/udp
|
||||||
permanent: true
|
permanent: true
|
||||||
state: enabled
|
state: enabled
|
||||||
|
|
||||||
- name: Permit traffic in dmz zone on http service
|
- ansible.posix.firewalld:
|
||||||
ansible.posix.firewalld:
|
|
||||||
zone: dmz
|
zone: dmz
|
||||||
service: http
|
service: http
|
||||||
permanent: true
|
permanent: true
|
||||||
state: enabled
|
state: enabled
|
||||||
|
|
||||||
- name: Enable FTP service with rate limiting using firewalld rich rule
|
- ansible.posix.firewalld:
|
||||||
ansible.posix.firewalld:
|
|
||||||
rich_rule: rule service name="ftp" audit limit value="1/m" accept
|
rich_rule: rule service name="ftp" audit limit value="1/m" accept
|
||||||
permanent: true
|
permanent: true
|
||||||
state: enabled
|
state: enabled
|
||||||
|
|
||||||
- name: Allow traffic from 192.0.2.0/24 in internal zone
|
- ansible.posix.firewalld:
|
||||||
ansible.posix.firewalld:
|
|
||||||
source: 192.0.2.0/24
|
source: 192.0.2.0/24
|
||||||
zone: internal
|
zone: internal
|
||||||
state: enabled
|
state: enabled
|
||||||
|
|
||||||
- name: Assign eth2 interface to trusted zone
|
- ansible.posix.firewalld:
|
||||||
ansible.posix.firewalld:
|
|
||||||
zone: trusted
|
zone: trusted
|
||||||
interface: eth2
|
interface: eth2
|
||||||
permanent: true
|
permanent: true
|
||||||
state: enabled
|
state: enabled
|
||||||
|
|
||||||
- name: Enable forwarding in internal zone
|
- ansible.posix.firewalld:
|
||||||
ansible.posix.firewalld:
|
|
||||||
forward: true
|
forward: true
|
||||||
state: enabled
|
state: enabled
|
||||||
permanent: true
|
permanent: true
|
||||||
zone: internal
|
zone: internal
|
||||||
|
|
||||||
- name: Enable masquerade in dmz zone
|
- ansible.posix.firewalld:
|
||||||
ansible.posix.firewalld:
|
|
||||||
masquerade: true
|
masquerade: true
|
||||||
state: enabled
|
state: enabled
|
||||||
permanent: true
|
permanent: true
|
||||||
zone: dmz
|
zone: dmz
|
||||||
|
|
||||||
- name: Create custom zone if not already present
|
- ansible.posix.firewalld:
|
||||||
ansible.posix.firewalld:
|
|
||||||
zone: custom
|
zone: custom
|
||||||
state: present
|
state: present
|
||||||
permanent: true
|
permanent: true
|
||||||
|
|
||||||
- name: Enable ICMP block inversion in drop zone
|
- ansible.posix.firewalld:
|
||||||
ansible.posix.firewalld:
|
|
||||||
zone: drop
|
zone: drop
|
||||||
state: enabled
|
state: enabled
|
||||||
permanent: true
|
permanent: true
|
||||||
icmp_block_inversion: true
|
icmp_block_inversion: true
|
||||||
|
|
||||||
- name: Block ICMP echo requests in drop zone
|
- ansible.posix.firewalld:
|
||||||
ansible.posix.firewalld:
|
|
||||||
zone: drop
|
zone: drop
|
||||||
state: enabled
|
state: enabled
|
||||||
permanent: true
|
permanent: true
|
||||||
icmp_block: echo-request
|
icmp_block: echo-request
|
||||||
|
|
||||||
- name: Set internal zone target to ACCEPT
|
- ansible.posix.firewalld:
|
||||||
ansible.posix.firewalld:
|
|
||||||
zone: internal
|
zone: internal
|
||||||
state: present
|
state: present
|
||||||
permanent: true
|
permanent: true
|
||||||
@@ -262,6 +248,7 @@ EXAMPLES = r'''
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.parsing.convert_bool import boolean
|
||||||
from ansible_collections.ansible.posix.plugins.module_utils.firewalld import FirewallTransaction, fw_offline
|
from ansible_collections.ansible.posix.plugins.module_utils.firewalld import FirewallTransaction, fw_offline
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -875,7 +862,7 @@ def main():
|
|||||||
module = AnsibleModule(
|
module = AnsibleModule(
|
||||||
argument_spec=dict(
|
argument_spec=dict(
|
||||||
icmp_block=dict(type='str'),
|
icmp_block=dict(type='str'),
|
||||||
icmp_block_inversion=dict(type='bool'),
|
icmp_block_inversion=dict(type='str'),
|
||||||
service=dict(type='str'),
|
service=dict(type='str'),
|
||||||
protocol=dict(type='str'),
|
protocol=dict(type='str'),
|
||||||
port=dict(type='str'),
|
port=dict(type='str'),
|
||||||
@@ -888,8 +875,8 @@ def main():
|
|||||||
state=dict(type='str', required=True, choices=['absent', 'disabled', 'enabled', 'present']),
|
state=dict(type='str', required=True, choices=['absent', 'disabled', 'enabled', 'present']),
|
||||||
timeout=dict(type='int', default=0),
|
timeout=dict(type='int', default=0),
|
||||||
interface=dict(type='str'),
|
interface=dict(type='str'),
|
||||||
forward=dict(type='bool'),
|
forward=dict(type='str'),
|
||||||
masquerade=dict(type='bool'),
|
masquerade=dict(type='str'),
|
||||||
offline=dict(type='bool', default=False),
|
offline=dict(type='bool', default=False),
|
||||||
target=dict(type='str', choices=['default', 'ACCEPT', 'DROP', '%%REJECT%%']),
|
target=dict(type='str', choices=['default', 'ACCEPT', 'DROP', '%%REJECT%%']),
|
||||||
),
|
),
|
||||||
@@ -998,7 +985,16 @@ def main():
|
|||||||
msgs.append("Changed icmp-block %s to %s" % (icmp_block, desired_state))
|
msgs.append("Changed icmp-block %s to %s" % (icmp_block, desired_state))
|
||||||
|
|
||||||
if icmp_block_inversion is not None:
|
if icmp_block_inversion is not None:
|
||||||
expected_state = 'enabled' if (desired_state == 'enabled') == icmp_block_inversion else 'disabled'
|
# Type of icmp_block_inversion will be changed to boolean in a future release.
|
||||||
|
icmp_block_inversion_status = True
|
||||||
|
try:
|
||||||
|
icmp_block_inversion_status = boolean(icmp_block_inversion, True)
|
||||||
|
except TypeError:
|
||||||
|
module.warn('The value of the icmp_block_inversion option is "%s". '
|
||||||
|
'The type of the option will be changed from string to boolean in a future release. '
|
||||||
|
'To avoid unexpected behavior, please change the value to boolean.' % icmp_block_inversion)
|
||||||
|
expected_state = 'enabled' if (desired_state == 'enabled') == icmp_block_inversion_status else 'disabled'
|
||||||
|
|
||||||
transaction = IcmpBlockInversionTransaction(
|
transaction = IcmpBlockInversionTransaction(
|
||||||
module,
|
module,
|
||||||
action_args=(),
|
action_args=(),
|
||||||
@@ -1133,7 +1129,16 @@ def main():
|
|||||||
msgs = msgs + transaction_msgs
|
msgs = msgs + transaction_msgs
|
||||||
|
|
||||||
if forward is not None:
|
if forward is not None:
|
||||||
expected_state = 'enabled' if (desired_state == 'enabled') == forward else 'disabled'
|
# Type of forward will be changed to boolean in a future release.
|
||||||
|
forward_status = False
|
||||||
|
try:
|
||||||
|
forward_status = boolean(forward, False)
|
||||||
|
except TypeError:
|
||||||
|
module.warn('The value of the forward option is "%s". '
|
||||||
|
'The type of the option will be changed from string to boolean in a future release. '
|
||||||
|
'To avoid unexpected behavior, please change the value to boolean.' % forward)
|
||||||
|
|
||||||
|
expected_state = 'enabled' if (desired_state == 'enabled') == forward_status else 'disabled'
|
||||||
transaction = ForwardTransaction(
|
transaction = ForwardTransaction(
|
||||||
module,
|
module,
|
||||||
action_args=(),
|
action_args=(),
|
||||||
@@ -1147,7 +1152,16 @@ def main():
|
|||||||
msgs = msgs + transaction_msgs
|
msgs = msgs + transaction_msgs
|
||||||
|
|
||||||
if masquerade is not None:
|
if masquerade is not None:
|
||||||
expected_state = 'enabled' if (desired_state == 'enabled') == masquerade else 'disabled'
|
# Type of masquerade will be changed to boolean in a future release.
|
||||||
|
masquerade_status = True
|
||||||
|
try:
|
||||||
|
masquerade_status = boolean(masquerade, True)
|
||||||
|
except TypeError:
|
||||||
|
module.warn('The value of the masquerade option is "%s". '
|
||||||
|
'The type of the option will be changed from string to boolean in a future release. '
|
||||||
|
'To avoid unexpected behavior, please change the value to boolean.' % masquerade)
|
||||||
|
|
||||||
|
expected_state = 'enabled' if (desired_state == 'enabled') == masquerade_status else 'disabled'
|
||||||
transaction = MasqueradeTransaction(
|
transaction = MasqueradeTransaction(
|
||||||
module,
|
module,
|
||||||
action_args=(),
|
action_args=(),
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ firewalld_info:
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils._text import to_native
|
||||||
from ansible_collections.ansible.posix.plugins.module_utils._respawn import respawn_module, HAS_RESPAWN_UTIL
|
from ansible_collections.ansible.posix.plugins.module_utils._respawn import respawn_module, HAS_RESPAWN_UTIL
|
||||||
from ansible_collections.ansible.posix.plugins.module_utils.version import StrictVersion
|
from ansible_collections.ansible.posix.plugins.module_utils.version import StrictVersion
|
||||||
|
|
||||||
@@ -319,6 +319,7 @@ def main():
|
|||||||
active_zones=module.params['active_zones'],
|
active_zones=module.params['active_zones'],
|
||||||
collected_zones=list(),
|
collected_zones=list(),
|
||||||
undefined_zones=list(),
|
undefined_zones=list(),
|
||||||
|
warnings=list(),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Exit with failure message if requirements modules are not installed.
|
# Exit with failure message if requirements modules are not installed.
|
||||||
|
|||||||
@@ -225,7 +225,8 @@ import platform
|
|||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible_collections.ansible.posix.plugins.module_utils.mount import ismount
|
from ansible_collections.ansible.posix.plugins.module_utils.mount import ismount
|
||||||
from ansible.module_utils.common.text.converters import to_bytes, to_native
|
from ansible.module_utils.six import iteritems
|
||||||
|
from ansible.module_utils._text import to_bytes, to_native
|
||||||
from ansible.module_utils.parsing.convert_bool import boolean
|
from ansible.module_utils.parsing.convert_bool import boolean
|
||||||
|
|
||||||
|
|
||||||
@@ -278,7 +279,7 @@ def _set_mount_save_old(module, args):
|
|||||||
old_lines = []
|
old_lines = []
|
||||||
exists = False
|
exists = False
|
||||||
changed = False
|
changed = False
|
||||||
escaped_args = dict([(k, _escape_fstab(v)) for k, v in args.items()])
|
escaped_args = dict([(k, _escape_fstab(v)) for k, v in iteritems(args) if k != 'warnings'])
|
||||||
new_line = '%(src)s %(name)s %(fstype)s %(opts)s %(dump)s %(passno)s\n'
|
new_line = '%(src)s %(name)s %(fstype)s %(opts)s %(dump)s %(passno)s\n'
|
||||||
|
|
||||||
if platform.system() == 'SunOS':
|
if platform.system() == 'SunOS':
|
||||||
@@ -302,7 +303,7 @@ def _set_mount_save_old(module, args):
|
|||||||
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
fields = line.split('#')[0].split()
|
fields = line.split()
|
||||||
|
|
||||||
# Check if we got a valid line for splitting
|
# Check if we got a valid line for splitting
|
||||||
# (on Linux the 5th and the 6th field is optional)
|
# (on Linux the 5th and the 6th field is optional)
|
||||||
@@ -803,6 +804,7 @@ def main():
|
|||||||
passno='-',
|
passno='-',
|
||||||
fstab=module.params['fstab'],
|
fstab=module.params['fstab'],
|
||||||
boot='yes' if module.params['boot'] else 'no',
|
boot='yes' if module.params['boot'] else 'no',
|
||||||
|
warnings=[]
|
||||||
)
|
)
|
||||||
if args['fstab'] is None:
|
if args['fstab'] is None:
|
||||||
args['fstab'] = '/etc/vfstab'
|
args['fstab'] = '/etc/vfstab'
|
||||||
@@ -814,6 +816,7 @@ def main():
|
|||||||
passno='0',
|
passno='0',
|
||||||
fstab=module.params['fstab'],
|
fstab=module.params['fstab'],
|
||||||
boot='yes',
|
boot='yes',
|
||||||
|
warnings=[]
|
||||||
)
|
)
|
||||||
if args['fstab'] is None:
|
if args['fstab'] is None:
|
||||||
args['fstab'] = '/etc/fstab'
|
args['fstab'] = '/etc/fstab'
|
||||||
@@ -831,7 +834,8 @@ def main():
|
|||||||
linux_mounts = get_linux_mounts(module)
|
linux_mounts = get_linux_mounts(module)
|
||||||
|
|
||||||
if linux_mounts is None:
|
if linux_mounts is None:
|
||||||
module.warn('Cannot open file /proc/self/mountinfo. Bind mounts might be misinterpreted.')
|
args['warnings'].append('Cannot open file /proc/self/mountinfo.'
|
||||||
|
' Bind mounts might be misinterpreted.')
|
||||||
|
|
||||||
# Override defaults with user specified params
|
# Override defaults with user specified params
|
||||||
for key in ('src', 'fstype', 'passno', 'opts', 'dump', 'fstab'):
|
for key in ('src', 'fstype', 'passno', 'opts', 'dump', 'fstab'):
|
||||||
@@ -843,7 +847,7 @@ def main():
|
|||||||
# specified in 'opts', mount module will ignore 'boot'.
|
# specified in 'opts', mount module will ignore 'boot'.
|
||||||
opts = args['opts'].split(',')
|
opts = args['opts'].split(',')
|
||||||
if module.params['boot'] and 'noauto' in opts:
|
if module.params['boot'] and 'noauto' in opts:
|
||||||
module.warn("Ignore the 'boot' due to 'opts' contains 'noauto'.")
|
args['warnings'].append("Ignore the 'boot' due to 'opts' contains 'noauto'.")
|
||||||
elif not module.params['boot']:
|
elif not module.params['boot']:
|
||||||
args['boot'] = 'no'
|
args['boot'] = 'no'
|
||||||
opts.append('noauto')
|
opts.append('noauto')
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ import os
|
|||||||
import platform
|
import platform
|
||||||
from traceback import format_exc
|
from traceback import format_exc
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils._text import to_native
|
||||||
|
|
||||||
|
|
||||||
class PatchError(Exception):
|
class PatchError(Exception):
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ import os
|
|||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.common.text.converters import to_text
|
from ansible.module_utils._text import to_text
|
||||||
|
|
||||||
|
|
||||||
def locally_installed(module, pkgname):
|
def locally_installed(module, pkgname):
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ import os
|
|||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.common.text.converters import to_native, to_text
|
from ansible.module_utils._text import to_native, to_text
|
||||||
|
|
||||||
|
|
||||||
def rpm_ostree_transaction(module):
|
def rpm_ostree_transaction(module):
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ except ImportError:
|
|||||||
HAVE_SEMANAGE = False
|
HAVE_SEMANAGE = False
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||||
from ansible.module_utils.common.text.converters import to_text
|
from ansible.module_utils._text import to_text
|
||||||
from ansible_collections.ansible.posix.plugins.module_utils._respawn import respawn_module, HAS_RESPAWN_UTIL
|
from ansible_collections.ansible.posix.plugins.module_utils._respawn import respawn_module, HAS_RESPAWN_UTIL
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -367,16 +367,9 @@ EXAMPLES = r'''
|
|||||||
import os
|
import os
|
||||||
import errno
|
import errno
|
||||||
|
|
||||||
# TODO(Python2): shlex.quote was added in Python 3.3. This module may run on
|
|
||||||
# target hosts with Python 2.7 (e.g., older RHEL systems in CI integration tests).
|
|
||||||
# Remove the try/except fallback to pipes.quote when Python 2 support is dropped.
|
|
||||||
try:
|
|
||||||
from shlex import quote as shlex_quote
|
|
||||||
except ImportError:
|
|
||||||
from pipes import quote as shlex_quote
|
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.common.text.converters import to_bytes, to_native
|
from ansible.module_utils._text import to_bytes, to_native
|
||||||
|
from ansible.module_utils.six.moves import shlex_quote
|
||||||
|
|
||||||
|
|
||||||
client_addr = None
|
client_addr = None
|
||||||
|
|||||||
@@ -80,13 +80,6 @@ EXAMPLES = r'''
|
|||||||
sysctl_file: /tmp/test_sysctl.conf
|
sysctl_file: /tmp/test_sysctl.conf
|
||||||
reload: false
|
reload: false
|
||||||
|
|
||||||
# Enable resource limits management in FreeBSD
|
|
||||||
- ansible.posix.sysctl:
|
|
||||||
name: kern.racct.enable
|
|
||||||
value: '1'
|
|
||||||
sysctl_file: /boot/loader.conf
|
|
||||||
reload: false
|
|
||||||
|
|
||||||
# Set ip forwarding on in /proc and verify token value with the sysctl command
|
# Set ip forwarding on in /proc and verify token value with the sysctl command
|
||||||
- ansible.posix.sysctl:
|
- ansible.posix.sysctl:
|
||||||
name: net.ipv4.ip_forward
|
name: net.ipv4.ip_forward
|
||||||
@@ -107,20 +100,12 @@ EXAMPLES = r'''
|
|||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
import re
|
import re
|
||||||
import sys
|
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
# TODO(Python2): On Python 2, string_types is basestring (str + unicode).
|
|
||||||
# This module may run on target hosts with Python 2.7.
|
|
||||||
# Remove the Python 2 branch when Python 2 support is dropped.
|
|
||||||
if sys.version_info >= (3, 0):
|
|
||||||
string_types = str
|
|
||||||
else:
|
|
||||||
string_types = basestring # pylint: disable=undefined-variable
|
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils.six import string_types
|
||||||
from ansible.module_utils.parsing.convert_bool import BOOLEANS_FALSE, BOOLEANS_TRUE
|
from ansible.module_utils.parsing.convert_bool import BOOLEANS_FALSE, BOOLEANS_TRUE
|
||||||
|
from ansible.module_utils._text import to_native
|
||||||
|
|
||||||
|
|
||||||
class SysctlModule(object):
|
class SysctlModule(object):
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ DOCUMENTATION = '''
|
|||||||
- shell_common
|
- shell_common
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from shlex import quote as shlex_quote
|
from ansible.module_utils.six import text_type
|
||||||
|
from ansible.module_utils.six.moves import shlex_quote
|
||||||
from ansible.plugins.shell import ShellBase
|
from ansible.plugins.shell import ShellBase
|
||||||
|
|
||||||
|
|
||||||
@@ -42,5 +43,5 @@ class ShellModule(ShellBase):
|
|||||||
ret = []
|
ret = []
|
||||||
# All the -u options must be first, so we process them first
|
# All the -u options must be first, so we process them first
|
||||||
ret += ['-u %s' % k for k, v in kwargs.items() if v is None]
|
ret += ['-u %s' % k for k, v in kwargs.items() if v is None]
|
||||||
ret += ['%s=%s' % (k, shlex_quote(str(v))) for k, v in kwargs.items() if v is not None]
|
ret += ['%s=%s' % (k, shlex_quote(text_type(v))) for k, v in kwargs.items() if v is not None]
|
||||||
return 'env %s' % ' '.join(ret)
|
return 'env %s' % ' '.join(ret)
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ DOCUMENTATION = '''
|
|||||||
- shell_common
|
- shell_common
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from shlex import quote as shlex_quote
|
from ansible.module_utils.six import text_type
|
||||||
|
from ansible.module_utils.six.moves import shlex_quote
|
||||||
from ansible.plugins.shell.sh import ShellModule as ShModule
|
from ansible.plugins.shell.sh import ShellModule as ShModule
|
||||||
|
|
||||||
|
|
||||||
@@ -41,7 +42,7 @@ class ShellModule(ShModule):
|
|||||||
if v is None:
|
if v is None:
|
||||||
ret.append('set -e %s;' % k)
|
ret.append('set -e %s;' % k)
|
||||||
else:
|
else:
|
||||||
ret.append('set -lx %s %s;' % (k, shlex_quote(str(v))))
|
ret.append('set -lx %s %s;' % (k, shlex_quote(text_type(v))))
|
||||||
return ' '.join(ret)
|
return ' '.join(ret)
|
||||||
|
|
||||||
def build_module_command(self, env_string, shebang, cmd, arg_path=None):
|
def build_module_command(self, env_string, shebang, cmd, arg_path=None):
|
||||||
|
|||||||
@@ -46,12 +46,6 @@
|
|||||||
path: "{{ test_dir }}"
|
path: "{{ test_dir }}"
|
||||||
state: directory
|
state: directory
|
||||||
mode: "0755"
|
mode: "0755"
|
||||||
|
|
||||||
- name: Install acl package
|
|
||||||
ansible.builtin.package:
|
|
||||||
name: acl
|
|
||||||
state: present
|
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
- name: Grant ansible user read access to a file
|
- name: Grant ansible user read access to a file
|
||||||
ansible.posix.acl:
|
ansible.posix.acl:
|
||||||
|
|||||||
@@ -35,5 +35,3 @@ multiple_keys_comments: |
|
|||||||
ssh-rsa DATA_BASIC 1@testing
|
ssh-rsa DATA_BASIC 1@testing
|
||||||
# I like adding comments yo-dude-this-is-not-a-key INVALID_DATA 2@testing
|
# I like adding comments yo-dude-this-is-not-a-key INVALID_DATA 2@testing
|
||||||
ecdsa-sha2-nistp521 ECDSA_DATA 4@testing
|
ecdsa-sha2-nistp521 ECDSA_DATA 4@testing
|
||||||
|
|
||||||
key_path: /tmp/id_rsa.pub
|
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Create key file for test
|
|
||||||
ansible.builtin.copy:
|
|
||||||
dest: "{{ key_path }}"
|
|
||||||
content: "{{ rsa_key_basic }}"
|
|
||||||
mode: "0600"
|
|
||||||
|
|
||||||
- name: Add key using path
|
|
||||||
ansible.posix.authorized_key:
|
|
||||||
user: root
|
|
||||||
key: file://{{ key_path }}
|
|
||||||
state: present
|
|
||||||
path: "{{ output_dir | expanduser }}/authorized_keys"
|
|
||||||
register: result
|
|
||||||
|
|
||||||
- name: Assert that the key was added
|
|
||||||
ansible.builtin.assert:
|
|
||||||
that:
|
|
||||||
- result.changed == true
|
|
||||||
|
|
||||||
- name: Add key using path again
|
|
||||||
ansible.posix.authorized_key:
|
|
||||||
user: root
|
|
||||||
key: file://{{ key_path }}
|
|
||||||
state: present
|
|
||||||
path: "{{ output_dir | expanduser }}/authorized_keys"
|
|
||||||
register: result
|
|
||||||
|
|
||||||
- name: Assert that no changes were applied
|
|
||||||
ansible.builtin.assert:
|
|
||||||
that:
|
|
||||||
- result.changed == false
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
---
|
|
||||||
# -------------------------------------------------------------
|
|
||||||
# check permissions
|
|
||||||
|
|
||||||
- name: Create a file that is not accessible
|
|
||||||
ansible.builtin.file:
|
|
||||||
state: touch
|
|
||||||
path: "{{ output_dir | expanduser }}/file_permissions"
|
|
||||||
owner: root
|
|
||||||
mode: '0000'
|
|
||||||
|
|
||||||
- name: Create unprivileged user
|
|
||||||
ansible.builtin.user:
|
|
||||||
name: nopriv
|
|
||||||
create_home: true
|
|
||||||
|
|
||||||
- name: Try to delete a key from an unreadable file
|
|
||||||
become: true
|
|
||||||
become_user: nopriv
|
|
||||||
ansible.posix.authorized_key:
|
|
||||||
user: root
|
|
||||||
key: "{{ dss_key_basic }}"
|
|
||||||
state: absent
|
|
||||||
path: "{{ output_dir | expanduser }}/file_permissions"
|
|
||||||
register: result
|
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
- name: Assert that the key deletion has failed
|
|
||||||
ansible.builtin.assert:
|
|
||||||
that:
|
|
||||||
- result is failed
|
|
||||||
|
|
||||||
- name: Remove the file
|
|
||||||
ansible.builtin.file:
|
|
||||||
state: absent
|
|
||||||
path: "{{ output_dir | expanduser }}/file_permissions"
|
|
||||||
|
|
||||||
- name: Remove the user
|
|
||||||
ansible.builtin.user:
|
|
||||||
name: nopriv
|
|
||||||
state: absent
|
|
||||||
@@ -31,9 +31,3 @@
|
|||||||
|
|
||||||
- name: Test for the management of comments with key
|
- name: Test for the management of comments with key
|
||||||
ansible.builtin.import_tasks: comments.yml
|
ansible.builtin.import_tasks: comments.yml
|
||||||
|
|
||||||
- name: Test for specifying key as a path
|
|
||||||
ansible.builtin.import_tasks: check_path.yml
|
|
||||||
|
|
||||||
- name: Test for permission denied files
|
|
||||||
ansible.builtin.import_tasks: check_permissions.yml
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
needs/privileged
|
|
||||||
needs/root
|
|
||||||
destructive
|
destructive
|
||||||
shippable/posix/group1
|
shippable/posix/group1
|
||||||
skip/aix
|
skip/aix
|
||||||
|
|||||||
@@ -114,3 +114,60 @@
|
|||||||
ansible.builtin.assert:
|
ansible.builtin.assert:
|
||||||
that:
|
that:
|
||||||
- result is not changed
|
- result is not changed
|
||||||
|
|
||||||
|
# Validate backwards compatible behavior until icmp block inversion is switched from string to boolean type
|
||||||
|
- name: Icmp block inversion enabled when icmp block inversion is non-boolean string and state is enabled
|
||||||
|
block:
|
||||||
|
- name: Testing enable icmp block inversion
|
||||||
|
ansible.posix.firewalld:
|
||||||
|
zone: trusted
|
||||||
|
icmp_block_inversion: some string
|
||||||
|
permanent: true
|
||||||
|
state: enabled
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: Assert icmp block inversion is enabled
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
|
||||||
|
- name: Testing enable icmp block inversion (verify not changed)
|
||||||
|
ansible.posix.firewalld:
|
||||||
|
zone: trusted
|
||||||
|
icmp_block_inversion: some string
|
||||||
|
permanent: true
|
||||||
|
state: enabled
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: Assert icmp block inversion is enabled (verify not changed)
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- result is not changed
|
||||||
|
|
||||||
|
- name: Icmp block inversion disabled when icmp block inversion is non-boolean string and state is disabled
|
||||||
|
block:
|
||||||
|
- name: Testing disable icmp block inversion
|
||||||
|
ansible.posix.firewalld:
|
||||||
|
zone: trusted
|
||||||
|
icmp_block_inversion: some string
|
||||||
|
permanent: true
|
||||||
|
state: disabled
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: Assert icmp block inversion is disabled
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
|
||||||
|
- name: Testing disable icmp block inversion (verify not changed)
|
||||||
|
ansible.posix.firewalld:
|
||||||
|
zone: trusted
|
||||||
|
icmp_block_inversion: some string
|
||||||
|
permanent: true
|
||||||
|
state: disabled
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: Assert icmp block inversion is disabled (verify not changed)
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- result is not changed
|
||||||
|
|||||||
@@ -114,3 +114,60 @@
|
|||||||
ansible.builtin.assert:
|
ansible.builtin.assert:
|
||||||
that:
|
that:
|
||||||
- result is not changed
|
- result is not changed
|
||||||
|
|
||||||
|
# Validate backwards compatible behavior until masquerade is switched from string to boolean type
|
||||||
|
- name: Masquerade enabled when masquerade is non-boolean string and state is enabled
|
||||||
|
block:
|
||||||
|
- name: Testing enable masquerade
|
||||||
|
ansible.posix.firewalld:
|
||||||
|
zone: trusted
|
||||||
|
masquerade: some string
|
||||||
|
permanent: true
|
||||||
|
state: enabled
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: Assert masquerade is enabled
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
|
||||||
|
- name: Testing enable masquerade (verify not changed)
|
||||||
|
ansible.posix.firewalld:
|
||||||
|
zone: trusted
|
||||||
|
masquerade: some string
|
||||||
|
permanent: true
|
||||||
|
state: enabled
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: Assert masquerade is enabled (verify not changed)
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- result is not changed
|
||||||
|
|
||||||
|
- name: Masquerade disabled when masquerade is non-boolean string and state is disabled
|
||||||
|
block:
|
||||||
|
- name: Testing disable masquerade
|
||||||
|
ansible.posix.firewalld:
|
||||||
|
zone: trusted
|
||||||
|
masquerade: some string
|
||||||
|
permanent: true
|
||||||
|
state: disabled
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: Assert masquerade is disabled
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
|
||||||
|
- name: Testing disable masquerade (verify not changed)
|
||||||
|
ansible.posix.firewalld:
|
||||||
|
zone: trusted
|
||||||
|
masquerade: some string
|
||||||
|
permanent: true
|
||||||
|
state: disabled
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: Assert masquerade is disabled (verify not changed)
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- result is not changed
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
# SETUP ################################################################################
|
|
||||||
- name: Install dependencies (Linux)
|
- name: Install dependencies (Linux)
|
||||||
ansible.builtin.package:
|
ansible.builtin.package:
|
||||||
name: e2fsprogs
|
name: e2fsprogs
|
||||||
@@ -111,42 +110,6 @@
|
|||||||
mode: '0644'
|
mode: '0644'
|
||||||
register: orig_info
|
register: orig_info
|
||||||
|
|
||||||
# BIND MOUNT ################################################################################
|
|
||||||
# bind mount check mode
|
|
||||||
- name: Bind mount a filesystem (Linux) (check mode)
|
|
||||||
ansible.posix.mount:
|
|
||||||
src: '{{ output_dir }}/mount_source'
|
|
||||||
name: '{{ output_dir }}/mount_dest'
|
|
||||||
state: mounted
|
|
||||||
fstype: None
|
|
||||||
opts: bind
|
|
||||||
when: ansible_system == 'Linux'
|
|
||||||
register: bind_result_linux_dry_run
|
|
||||||
check_mode: true
|
|
||||||
|
|
||||||
- name: Bind mount a filesystem (FreeBSD) (check mode)
|
|
||||||
ansible.posix.mount:
|
|
||||||
src: '{{ output_dir }}/mount_source'
|
|
||||||
name: '{{ output_dir }}/mount_dest'
|
|
||||||
state: mounted
|
|
||||||
fstype: nullfs
|
|
||||||
when: ansible_system == 'FreeBSD'
|
|
||||||
register: bind_result_freebsd_dry_run
|
|
||||||
check_mode: true
|
|
||||||
|
|
||||||
- name: Attempt to stat bind mounted file
|
|
||||||
ansible.builtin.stat:
|
|
||||||
path: '{{ output_dir }}/mount_dest/test_file'
|
|
||||||
when: ansible_system in ('FreeBSD', 'Linux')
|
|
||||||
register: dest_stat
|
|
||||||
|
|
||||||
- name: Assert the bind mount did not take place
|
|
||||||
ansible.builtin.assert:
|
|
||||||
that:
|
|
||||||
- not dest_stat['stat']['exists']
|
|
||||||
when: ansible_system in ('FreeBSD', 'Linux')
|
|
||||||
|
|
||||||
# bind mount
|
|
||||||
- name: Bind mount a filesystem (Linux)
|
- name: Bind mount a filesystem (Linux)
|
||||||
ansible.posix.mount:
|
ansible.posix.mount:
|
||||||
src: '{{ output_dir }}/mount_source'
|
src: '{{ output_dir }}/mount_source'
|
||||||
@@ -205,48 +168,6 @@
|
|||||||
- (ansible_system == 'Linux' and not bind_result_linux['changed']) or (ansible_system == 'FreeBSD' and not bind_result_freebsd['changed'])
|
- (ansible_system == 'Linux' and not bind_result_linux['changed']) or (ansible_system == 'FreeBSD' and not bind_result_freebsd['changed'])
|
||||||
when: ansible_system in ('FreeBSD', 'Linux')
|
when: ansible_system in ('FreeBSD', 'Linux')
|
||||||
|
|
||||||
# remount check mode
|
|
||||||
- name: Remount filesystem with different opts (Linux) (check mode)
|
|
||||||
ansible.posix.mount:
|
|
||||||
src: '{{ output_dir }}/mount_source'
|
|
||||||
name: '{{ output_dir }}/mount_dest'
|
|
||||||
state: mounted
|
|
||||||
fstype: None
|
|
||||||
opts: bind,ro
|
|
||||||
when: ansible_system == 'Linux'
|
|
||||||
register: bind_result_linux
|
|
||||||
check_mode: true
|
|
||||||
|
|
||||||
- name: Remount filesystem with different opts (FreeBSD) (check mode)
|
|
||||||
ansible.posix.mount:
|
|
||||||
src: '{{ output_dir }}/mount_source'
|
|
||||||
name: '{{ output_dir }}/mount_dest'
|
|
||||||
state: mounted
|
|
||||||
fstype: nullfs
|
|
||||||
opts: ro
|
|
||||||
when: ansible_system == 'FreeBSD'
|
|
||||||
register: bind_result_freebsd
|
|
||||||
check_mode: true
|
|
||||||
|
|
||||||
- name: Get mount options
|
|
||||||
ansible.builtin.shell:
|
|
||||||
cmd: set -o pipefail && mount | grep mount_dest | grep -c -E -w '(ro|read-only)'
|
|
||||||
executable: "{{ shell_executable }}"
|
|
||||||
changed_when: false
|
|
||||||
failed_when: false
|
|
||||||
register: new_options_count
|
|
||||||
|
|
||||||
- name: Make sure the filesystem does not have the new opts
|
|
||||||
ansible.builtin.assert:
|
|
||||||
that:
|
|
||||||
- linux_and_changed or freebsd_and_changed
|
|
||||||
- new_options_count.stdout | int == 0
|
|
||||||
vars:
|
|
||||||
linux_and_changed: "{{ ansible_system == 'Linux' and bind_result_linux_dry_run['changed'] }}"
|
|
||||||
freebsd_and_changed: "{{ ansible_system == 'FreeBSD' and bind_result_freebsd['changed'] }}"
|
|
||||||
when: ansible_system in ('FreeBSD', 'Linux')
|
|
||||||
|
|
||||||
# remount
|
|
||||||
- name: Remount filesystem with different opts (Linux)
|
- name: Remount filesystem with different opts (Linux)
|
||||||
ansible.posix.mount:
|
ansible.posix.mount:
|
||||||
src: '{{ output_dir }}/mount_source'
|
src: '{{ output_dir }}/mount_source'
|
||||||
@@ -282,29 +203,6 @@
|
|||||||
- 1 == remount_options.stdout_lines | length
|
- 1 == remount_options.stdout_lines | length
|
||||||
when: ansible_system in ('FreeBSD', 'Linux')
|
when: ansible_system in ('FreeBSD', 'Linux')
|
||||||
|
|
||||||
# unmount check mode
|
|
||||||
- name: Unmount the bind mount (check mode)
|
|
||||||
ansible.posix.mount:
|
|
||||||
name: '{{ output_dir }}/mount_dest'
|
|
||||||
state: absent
|
|
||||||
when: ansible_system in ('Linux', 'FreeBSD')
|
|
||||||
register: unmount_result
|
|
||||||
check_mode: true
|
|
||||||
|
|
||||||
- name: Make sure the file still exists in dest
|
|
||||||
ansible.builtin.stat:
|
|
||||||
path: '{{ output_dir }}/mount_dest/test_file'
|
|
||||||
when: ansible_system in ('FreeBSD', 'Linux')
|
|
||||||
register: dest_stat
|
|
||||||
|
|
||||||
- name: Check that we did not unmount
|
|
||||||
ansible.builtin.assert:
|
|
||||||
that:
|
|
||||||
- unmount_result['changed']
|
|
||||||
- dest_stat['stat']['exists']
|
|
||||||
when: ansible_system in ('FreeBSD', 'Linux')
|
|
||||||
|
|
||||||
# unmount
|
|
||||||
- name: Unmount the bind mount
|
- name: Unmount the bind mount
|
||||||
ansible.posix.mount:
|
ansible.posix.mount:
|
||||||
name: '{{ output_dir }}/mount_dest'
|
name: '{{ output_dir }}/mount_dest'
|
||||||
@@ -325,36 +223,9 @@
|
|||||||
- not dest_stat['stat']['exists']
|
- not dest_stat['stat']['exists']
|
||||||
when: ansible_system in ('FreeBSD', 'Linux')
|
when: ansible_system in ('FreeBSD', 'Linux')
|
||||||
|
|
||||||
# SWAP #############################################################
|
- name: Block to test remounted option
|
||||||
- name: Swap
|
|
||||||
when: ansible_system in ('Linux')
|
when: ansible_system in ('Linux')
|
||||||
block:
|
block:
|
||||||
# mount swap check mode
|
|
||||||
- name: Stat /etc/fstab
|
|
||||||
ansible.builtin.stat:
|
|
||||||
path: /etc/fstab
|
|
||||||
register: stat_fstab_before
|
|
||||||
|
|
||||||
- name: Create fstab record for the first swap file (check mode)
|
|
||||||
ansible.posix.mount:
|
|
||||||
name: none
|
|
||||||
src: /tmp/swap1
|
|
||||||
opts: sw
|
|
||||||
fstype: swap
|
|
||||||
state: present
|
|
||||||
check_mode: true
|
|
||||||
|
|
||||||
- name: Stat /etc/fstab
|
|
||||||
ansible.builtin.stat:
|
|
||||||
path: /etc/fstab
|
|
||||||
register: stat_fstab_after
|
|
||||||
|
|
||||||
- name: Assert that fstab checksum did not change
|
|
||||||
ansible.builtin.assert:
|
|
||||||
that:
|
|
||||||
- stat_fstab_before.stat.checksum == stat_fstab_after.stat.checksum
|
|
||||||
|
|
||||||
# mount swap1
|
|
||||||
- name: Create fstab record for the first swap file
|
- name: Create fstab record for the first swap file
|
||||||
ansible.posix.mount:
|
ansible.posix.mount:
|
||||||
name: none
|
name: none
|
||||||
@@ -379,7 +250,6 @@
|
|||||||
- swap1_created['changed']
|
- swap1_created['changed']
|
||||||
- not swap1_created_again['changed']
|
- not swap1_created_again['changed']
|
||||||
|
|
||||||
# mount swap2
|
|
||||||
- name: Create fstab record for the second swap file
|
- name: Create fstab record for the second swap file
|
||||||
ansible.posix.mount:
|
ansible.posix.mount:
|
||||||
name: none
|
name: none
|
||||||
@@ -404,30 +274,6 @@
|
|||||||
- swap2_created['changed']
|
- swap2_created['changed']
|
||||||
- not swap2_created_again['changed']
|
- not swap2_created_again['changed']
|
||||||
|
|
||||||
# remove swap check mode
|
|
||||||
- name: Stat /etc/fstab
|
|
||||||
ansible.builtin.stat:
|
|
||||||
path: /etc/fstab
|
|
||||||
register: stat_fstab_before
|
|
||||||
|
|
||||||
- name: Remove the fstab record for the first swap file (check mode)
|
|
||||||
ansible.posix.mount:
|
|
||||||
name: none
|
|
||||||
src: /tmp/swap1
|
|
||||||
state: absent
|
|
||||||
check_mode: true
|
|
||||||
|
|
||||||
- name: Stat /etc/fstab
|
|
||||||
ansible.builtin.stat:
|
|
||||||
path: /etc/fstab
|
|
||||||
register: stat_fstab_after
|
|
||||||
|
|
||||||
- name: Assert that fstab checksum did not change
|
|
||||||
ansible.builtin.assert:
|
|
||||||
that:
|
|
||||||
- stat_fstab_before.stat.checksum == stat_fstab_after.stat.checksum
|
|
||||||
|
|
||||||
# remove swap1
|
|
||||||
- name: Remove the fstab record for the first swap file
|
- name: Remove the fstab record for the first swap file
|
||||||
ansible.posix.mount:
|
ansible.posix.mount:
|
||||||
name: none
|
name: none
|
||||||
@@ -448,7 +294,6 @@
|
|||||||
- swap1_removed['changed']
|
- swap1_removed['changed']
|
||||||
- not swap1_removed_again['changed']
|
- not swap1_removed_again['changed']
|
||||||
|
|
||||||
# remove swap2
|
|
||||||
- name: Remove the fstab record for the second swap file
|
- name: Remove the fstab record for the second swap file
|
||||||
ansible.posix.mount:
|
ansible.posix.mount:
|
||||||
name: none
|
name: none
|
||||||
@@ -469,10 +314,6 @@
|
|||||||
- swap2_removed['changed']
|
- swap2_removed['changed']
|
||||||
- not swap2_removed_again['changed']
|
- not swap2_removed_again['changed']
|
||||||
|
|
||||||
# FIXUP #############################################################
|
|
||||||
- name: Fix incomplete entry already present in fstab
|
|
||||||
when: ansible_system == 'Linux'
|
|
||||||
block:
|
|
||||||
- name: Create fstab record with missing last two fields
|
- name: Create fstab record with missing last two fields
|
||||||
ansible.builtin.copy:
|
ansible.builtin.copy:
|
||||||
dest: /etc/fstab
|
dest: /etc/fstab
|
||||||
@@ -502,11 +343,6 @@
|
|||||||
- ''' 0 0'' in optional_fields_content.stdout'
|
- ''' 0 0'' in optional_fields_content.stdout'
|
||||||
- 1 == optional_fields_content.stdout_lines | length
|
- 1 == optional_fields_content.stdout_lines | length
|
||||||
|
|
||||||
# REMOUNTED #############################################################
|
|
||||||
- name: Block to test remounted option
|
|
||||||
when: ansible_system in ('Linux')
|
|
||||||
block:
|
|
||||||
# setup
|
|
||||||
- name: Create empty file
|
- name: Create empty file
|
||||||
community.general.filesize:
|
community.general.filesize:
|
||||||
path: /tmp/myfs.img
|
path: /tmp/myfs.img
|
||||||
@@ -536,26 +372,6 @@
|
|||||||
ansible.builtin.pause:
|
ansible.builtin.pause:
|
||||||
seconds: 2
|
seconds: 2
|
||||||
|
|
||||||
# remount check mode
|
|
||||||
- name: Remount (check mode)
|
|
||||||
ansible.posix.mount:
|
|
||||||
path: /tmp/myfs
|
|
||||||
state: remounted
|
|
||||||
|
|
||||||
- name: Get again the last write time
|
|
||||||
ansible.builtin.shell:
|
|
||||||
cmd: >-
|
|
||||||
set -o pipefail && dumpe2fs /tmp/myfs.img 2>/dev/null | grep -i "last write time:" |cut -d: -f2-
|
|
||||||
executable: "{{ shell_executable }}"
|
|
||||||
changed_when: false
|
|
||||||
register: last_write_time_check
|
|
||||||
|
|
||||||
- name: Fail if they are different
|
|
||||||
ansible.builtin.fail:
|
|
||||||
msg: Filesytem was remounted, testing of the module failed!
|
|
||||||
when: last_write_time.stdout != last_write_time_check.stdout
|
|
||||||
|
|
||||||
# remount
|
|
||||||
- name: Test if the FS is remounted
|
- name: Test if the FS is remounted
|
||||||
ansible.posix.mount:
|
ansible.posix.mount:
|
||||||
path: /tmp/myfs
|
path: /tmp/myfs
|
||||||
@@ -574,29 +390,6 @@
|
|||||||
msg: Filesytem was not remounted, testing of the module failed!
|
msg: Filesytem was not remounted, testing of the module failed!
|
||||||
when: last_write is defined and last_write_time2 is defined and last_write_time.stdout == last_write_time2.stdout
|
when: last_write is defined and last_write_time2 is defined and last_write_time.stdout == last_write_time2.stdout
|
||||||
|
|
||||||
# remount different options check mode
|
|
||||||
- name: Remount filesystem with different opts using remounted option (Linux only)
|
|
||||||
ansible.posix.mount:
|
|
||||||
path: /tmp/myfs
|
|
||||||
state: remounted
|
|
||||||
opts: rw,noexec
|
|
||||||
check_mode: true
|
|
||||||
|
|
||||||
- name: Get remounted options (Linux only)
|
|
||||||
ansible.builtin.shell:
|
|
||||||
cmd: set -o pipefail && mount | grep myfs | grep -E -w 'noexec' | wc -l
|
|
||||||
executable: "{{ shell_executable }}"
|
|
||||||
failed_when: false
|
|
||||||
changed_when: false
|
|
||||||
register: remounted_options
|
|
||||||
|
|
||||||
- name: Make sure the filesystem now has the new opts after using remounted (Linux only)
|
|
||||||
ansible.builtin.assert:
|
|
||||||
that:
|
|
||||||
- "'0' in remounted_options.stdout"
|
|
||||||
- "1 == remounted_options.stdout_lines | length"
|
|
||||||
|
|
||||||
# remount different options
|
|
||||||
- name: Remount filesystem with different opts using remounted option (Linux only)
|
- name: Remount filesystem with different opts using remounted option (Linux only)
|
||||||
ansible.posix.mount:
|
ansible.posix.mount:
|
||||||
path: /tmp/myfs
|
path: /tmp/myfs
|
||||||
@@ -616,7 +409,6 @@
|
|||||||
- "'1' in remounted_options.stdout"
|
- "'1' in remounted_options.stdout"
|
||||||
- "1 == remounted_options.stdout_lines | length"
|
- "1 == remounted_options.stdout_lines | length"
|
||||||
|
|
||||||
# backup
|
|
||||||
- name: Mount the FS again to test backup
|
- name: Mount the FS again to test backup
|
||||||
ansible.posix.mount:
|
ansible.posix.mount:
|
||||||
path: /tmp/myfs
|
path: /tmp/myfs
|
||||||
@@ -647,11 +439,9 @@
|
|||||||
- /tmp/myfs.img
|
- /tmp/myfs.img
|
||||||
- /tmp/myfs
|
- /tmp/myfs
|
||||||
|
|
||||||
# BOOT #############################################################
|
|
||||||
- name: Block to test boot option for Linux
|
- name: Block to test boot option for Linux
|
||||||
when: ansible_system in ('Linux')
|
when: ansible_system in ('Linux')
|
||||||
block:
|
block:
|
||||||
# setup
|
|
||||||
- name: Create empty file
|
- name: Create empty file
|
||||||
community.general.filesize:
|
community.general.filesize:
|
||||||
path: /tmp/myfs.img
|
path: /tmp/myfs.img
|
||||||
@@ -662,7 +452,6 @@
|
|||||||
fstype: ext3
|
fstype: ext3
|
||||||
dev: /tmp/myfs.img
|
dev: /tmp/myfs.img
|
||||||
|
|
||||||
# noauto
|
|
||||||
- name: Mount the FS with noauto option
|
- name: Mount the FS with noauto option
|
||||||
ansible.posix.mount:
|
ansible.posix.mount:
|
||||||
path: /tmp/myfs
|
path: /tmp/myfs
|
||||||
@@ -683,7 +472,6 @@
|
|||||||
path: /tmp/myfs
|
path: /tmp/myfs
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
# noauto + defaults
|
|
||||||
- name: Mount the FS with noauto option and defaults
|
- name: Mount the FS with noauto option and defaults
|
||||||
ansible.posix.mount:
|
ansible.posix.mount:
|
||||||
path: /tmp/myfs
|
path: /tmp/myfs
|
||||||
@@ -711,7 +499,6 @@
|
|||||||
- /tmp/myfs.img
|
- /tmp/myfs.img
|
||||||
- /tmp/myfs
|
- /tmp/myfs
|
||||||
|
|
||||||
# NEWLINE END OF FILE ############################################
|
|
||||||
- name: Block to test missing newline at the EOF of fstab
|
- name: Block to test missing newline at the EOF of fstab
|
||||||
when: ansible_system in ('Linux')
|
when: ansible_system in ('Linux')
|
||||||
block:
|
block:
|
||||||
@@ -750,7 +537,6 @@
|
|||||||
- /tmp/myfs1
|
- /tmp/myfs1
|
||||||
- /tmp/test_fstab
|
- /tmp/test_fstab
|
||||||
|
|
||||||
# EPHEMERAL ################################################
|
|
||||||
- name: Block to test ephemeral option
|
- name: Block to test ephemeral option
|
||||||
environment:
|
environment:
|
||||||
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
@@ -766,7 +552,8 @@
|
|||||||
path: /tmp/myfs_B.img
|
path: /tmp/myfs_B.img
|
||||||
size: 20M
|
size: 20M
|
||||||
|
|
||||||
##### FORMAT FS ON LINUX
|
##### FORMAT FS ON LINUX
|
||||||
|
|
||||||
- name: Block to format FS on Linux
|
- name: Block to format FS on Linux
|
||||||
when: ansible_system == 'Linux'
|
when: ansible_system == 'Linux'
|
||||||
block:
|
block:
|
||||||
@@ -780,7 +567,8 @@
|
|||||||
fstype: ext3
|
fstype: ext3
|
||||||
dev: /tmp/myfs_B.img
|
dev: /tmp/myfs_B.img
|
||||||
|
|
||||||
##### FORMAT FS ON SOLARIS AND BSD
|
##### FORMAT FS ON SOLARIS AND BSD
|
||||||
|
|
||||||
- name: Create loop devices on Solaris and BSD
|
- name: Create loop devices on Solaris and BSD
|
||||||
ansible.builtin.shell:
|
ansible.builtin.shell:
|
||||||
cmd: "set -o pipefail && {{ ephemeral_create_loop_dev_cmd }}"
|
cmd: "set -o pipefail && {{ ephemeral_create_loop_dev_cmd }}"
|
||||||
@@ -795,49 +583,14 @@
|
|||||||
changed_when: true
|
changed_when: true
|
||||||
when: ephemeral_format_fs_cmd is defined
|
when: ephemeral_format_fs_cmd is defined
|
||||||
|
|
||||||
|
##### TESTS
|
||||||
|
|
||||||
- name: Create fstab if it does not exist
|
- name: Create fstab if it does not exist
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
path: "{{ ephemeral_fstab }}"
|
path: "{{ ephemeral_fstab }}"
|
||||||
state: touch
|
state: touch
|
||||||
mode: '0644'
|
mode: '0644'
|
||||||
|
|
||||||
# normal ephemeral mount check mode
|
|
||||||
- name: Get checksum of /etc/fstab before mounting anything
|
|
||||||
ansible.builtin.stat:
|
|
||||||
path: '{{ ephemeral_fstab }}'
|
|
||||||
register: fstab_stat_before_mount
|
|
||||||
|
|
||||||
- name: Mount the FS A with ephemeral state (check mode)
|
|
||||||
ansible.posix.mount:
|
|
||||||
path: /tmp/myfs
|
|
||||||
src: '{{ ephemeral_device_a }}'
|
|
||||||
fstype: '{{ ephemeral_fstype }}'
|
|
||||||
opts: rw
|
|
||||||
state: ephemeral
|
|
||||||
register: ephemeral_mount_info
|
|
||||||
check_mode: true
|
|
||||||
|
|
||||||
- name: Get checksum of /etc/fstab after an ephemeral mount
|
|
||||||
ansible.builtin.stat:
|
|
||||||
path: '{{ ephemeral_fstab }}'
|
|
||||||
register: fstab_stat_after_mount
|
|
||||||
|
|
||||||
- name: Get mountinfo
|
|
||||||
ansible.builtin.shell:
|
|
||||||
cmd: grep -c '/tmp/myfs' <(mount -v)
|
|
||||||
executable: "{{ shell_executable }}"
|
|
||||||
register: check_mountinfo
|
|
||||||
failed_when: false
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Assert the mount occurred and the fstab is unchanged
|
|
||||||
ansible.builtin.assert:
|
|
||||||
that:
|
|
||||||
- check_mountinfo.stdout|int == 0
|
|
||||||
- ephemeral_mount_info['changed']
|
|
||||||
- fstab_stat_before_mount['stat']['checksum'] == fstab_stat_after_mount['stat']['checksum']
|
|
||||||
|
|
||||||
# normal ephemeral mount
|
|
||||||
- name: Get checksum of /etc/fstab before mounting anything
|
- name: Get checksum of /etc/fstab before mounting anything
|
||||||
ansible.builtin.stat:
|
ansible.builtin.stat:
|
||||||
path: '{{ ephemeral_fstab }}'
|
path: '{{ ephemeral_fstab }}'
|
||||||
@@ -878,48 +631,6 @@
|
|||||||
- ephemeral_mount_info['changed']
|
- ephemeral_mount_info['changed']
|
||||||
- fstab_stat_before_mount['stat']['checksum'] == fstab_stat_after_mount['stat']['checksum']
|
- fstab_stat_before_mount['stat']['checksum'] == fstab_stat_after_mount['stat']['checksum']
|
||||||
|
|
||||||
# remount different options check mode
|
|
||||||
- name: Get first mount record
|
|
||||||
ansible.builtin.shell:
|
|
||||||
cmd: grep '/tmp/myfs' <(mount -v)
|
|
||||||
executable: "{{ shell_executable }}"
|
|
||||||
register: ephemeral_mount_record_1
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Try to mount FS A where FS A is already mounted (should trigger remount and changed)
|
|
||||||
ansible.posix.mount:
|
|
||||||
path: /tmp/myfs
|
|
||||||
src: '{{ ephemeral_device_a }}'
|
|
||||||
fstype: '{{ ephemeral_fstype }}'
|
|
||||||
opts: ro
|
|
||||||
state: ephemeral
|
|
||||||
register: ephemeral_mount_info
|
|
||||||
check_mode: true
|
|
||||||
|
|
||||||
- name: Get second mount record (should be different than the first)
|
|
||||||
ansible.builtin.shell:
|
|
||||||
cmd: grep '/tmp/myfs' <(mount -v)
|
|
||||||
executable: "{{ shell_executable }}"
|
|
||||||
register: ephemeral_mount_record_2
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Get mountinfo
|
|
||||||
ansible.builtin.shell:
|
|
||||||
cmd: grep -c '/tmp/myfs' <(mount -v)
|
|
||||||
executable: "{{ shell_executable }}"
|
|
||||||
failed_when: false
|
|
||||||
register: check_mountinfo
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Assert the FS A is still mounted, the options unchanged and the fstab unchanged
|
|
||||||
ansible.builtin.assert:
|
|
||||||
that:
|
|
||||||
- check_mountinfo.stdout|int == 1
|
|
||||||
- ephemeral_mount_record_1.stdout == ephemeral_mount_record_2.stdout
|
|
||||||
- ephemeral_mount_info['changed']
|
|
||||||
- fstab_stat_before_mount['stat']['checksum'] == fstab_stat_after_mount['stat']['checksum']
|
|
||||||
|
|
||||||
# remount different options
|
|
||||||
- name: Get first mount record
|
- name: Get first mount record
|
||||||
ansible.builtin.shell:
|
ansible.builtin.shell:
|
||||||
cmd: grep '/tmp/myfs' <(mount -v)
|
cmd: grep '/tmp/myfs' <(mount -v)
|
||||||
@@ -959,7 +670,6 @@
|
|||||||
- ephemeral_mount_info['changed']
|
- ephemeral_mount_info['changed']
|
||||||
- fstab_stat_before_mount['stat']['checksum'] == fstab_stat_after_mount['stat']['checksum']
|
- fstab_stat_before_mount['stat']['checksum'] == fstab_stat_after_mount['stat']['checksum']
|
||||||
|
|
||||||
# conflicting mount
|
|
||||||
- name: Try to mount file B on file A mountpoint (should fail)
|
- name: Try to mount file B on file A mountpoint (should fail)
|
||||||
ansible.posix.mount:
|
ansible.posix.mount:
|
||||||
path: /tmp/myfs
|
path: /tmp/myfs
|
||||||
@@ -997,39 +707,6 @@
|
|||||||
- test_file_stat['stat']['exists']
|
- test_file_stat['stat']['exists']
|
||||||
- ephemeral_mount_b_info is failed
|
- ephemeral_mount_b_info is failed
|
||||||
|
|
||||||
# unmount check mode
|
|
||||||
- name: Unmount FS with state = unmounted
|
|
||||||
ansible.posix.mount:
|
|
||||||
path: /tmp/myfs
|
|
||||||
state: unmounted
|
|
||||||
check_mode: true
|
|
||||||
|
|
||||||
- name: Get fstab checksum after unmounting an ephemeral mount with state = unmounted
|
|
||||||
ansible.builtin.stat:
|
|
||||||
path: '{{ ephemeral_fstab }}'
|
|
||||||
register: fstab_stat_after_unmount
|
|
||||||
|
|
||||||
- name: Get mountinfo
|
|
||||||
ansible.builtin.shell:
|
|
||||||
cmd: grep -c '/tmp/myfs' <(mount -v)
|
|
||||||
executable: "{{ shell_executable }}"
|
|
||||||
register: check_mountinfo
|
|
||||||
failed_when: false
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Try to stat our test file
|
|
||||||
ansible.builtin.stat:
|
|
||||||
path: /tmp/myfs/test_file
|
|
||||||
register: test_file_stat
|
|
||||||
|
|
||||||
- name: Assert that unmount did not take place and fstab unchanged
|
|
||||||
ansible.builtin.assert:
|
|
||||||
that:
|
|
||||||
- check_mountinfo.stdout|int == 1
|
|
||||||
- test_file_stat['stat']['exists']
|
|
||||||
- fstab_stat_before_mount['stat']['checksum'] == fstab_stat_after_unmount['stat']['checksum']
|
|
||||||
|
|
||||||
# unmount
|
|
||||||
- name: Unmount FS with state = unmounted
|
- name: Unmount FS with state = unmounted
|
||||||
ansible.posix.mount:
|
ansible.posix.mount:
|
||||||
path: /tmp/myfs
|
path: /tmp/myfs
|
||||||
@@ -1082,7 +759,6 @@
|
|||||||
- /tmp/myfs_B.img
|
- /tmp/myfs_B.img
|
||||||
- /tmp/myfs
|
- /tmp/myfs
|
||||||
|
|
||||||
# OPTS_NO_LOG ######################################
|
|
||||||
- name: Block to test opts_no_log option
|
- name: Block to test opts_no_log option
|
||||||
when: ansible_system == 'Linux'
|
when: ansible_system == 'Linux'
|
||||||
block:
|
block:
|
||||||
|
|||||||
@@ -20,4 +20,5 @@
|
|||||||
ansible.builtin.include_tasks: seboolean.yml
|
ansible.builtin.include_tasks: seboolean.yml
|
||||||
when:
|
when:
|
||||||
- ansible_selinux is defined
|
- ansible_selinux is defined
|
||||||
|
- ansible_selinux
|
||||||
- ansible_selinux.status == 'enabled'
|
- ansible_selinux.status == 'enabled'
|
||||||
|
|||||||
@@ -19,21 +19,23 @@
|
|||||||
- name: Debug message for when SELinux is disabled
|
- name: Debug message for when SELinux is disabled
|
||||||
ansible.builtin.debug:
|
ansible.builtin.debug:
|
||||||
msg: SELinux is disabled
|
msg: SELinux is disabled
|
||||||
when: ansible_selinux is defined and ansible_selinux.status == 'disabled'
|
when: ansible_selinux is defined and not ansible_selinux
|
||||||
|
|
||||||
- name: Debug message for when SELinux is enabled and not disabled
|
- name: Debug message for when SELinux is enabled and not disabled
|
||||||
ansible.builtin.debug:
|
ansible.builtin.debug:
|
||||||
msg: SELinux is {{ ansible_selinux.status }}
|
msg: SELinux is {{ ansible_selinux.status }}
|
||||||
when: ansible_selinux is defined
|
when: ansible_selinux is defined and ansible_selinux
|
||||||
|
|
||||||
- name: Include_tasks for when SELinux is enabled
|
- name: Include_tasks for when SELinux is enabled
|
||||||
ansible.builtin.include_tasks: selinux.yml
|
ansible.builtin.include_tasks: selinux.yml
|
||||||
when:
|
when:
|
||||||
- ansible_selinux is defined
|
- ansible_selinux is defined
|
||||||
|
- ansible_selinux
|
||||||
- ansible_selinux.status == 'enabled'
|
- ansible_selinux.status == 'enabled'
|
||||||
|
|
||||||
- name: Include tasks for selogin when SELinux is enabled
|
- name: Include tasks for selogin when SELinux is enabled
|
||||||
ansible.builtin.include_tasks: selogin.yml
|
ansible.builtin.include_tasks: selogin.yml
|
||||||
when:
|
when:
|
||||||
- ansible_selinux is defined
|
- ansible_selinux is defined
|
||||||
|
- ansible_selinux
|
||||||
- ansible_selinux.status == 'enabled'
|
- ansible_selinux.status == 'enabled'
|
||||||
|
|||||||
@@ -128,8 +128,8 @@
|
|||||||
ansible.builtin.assert:
|
ansible.builtin.assert:
|
||||||
that:
|
that:
|
||||||
- selinux_config_original | length == selinux_config_after | length
|
- selinux_config_original | length == selinux_config_after | length
|
||||||
- (selinux_config_after | select("search", "^SELINUX=disabled\s*$") | list | length) > 0
|
- selinux_config_after[selinux_config_after.index('SELINUX=disabled')] is search("^SELINUX=\w+$")
|
||||||
- (selinux_config_after | select("search", "^SELINUXTYPE=targeted\s*$") | list | length) > 0
|
- selinux_config_after[selinux_config_after.index('SELINUXTYPE=targeted')] is search("^SELINUXTYPE=\w+$")
|
||||||
|
|
||||||
- name: TEST 1 | Disable SELinux again, with kernel arguments update
|
- name: TEST 1 | Disable SELinux again, with kernel arguments update
|
||||||
ansible.posix.selinux:
|
ansible.posix.selinux:
|
||||||
|
|||||||
2
tests/sanity/ignore-2.14.txt
Normal file
2
tests/sanity/ignore-2.14.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
tests/utils/shippable/check_matrix.py replace-urlopen
|
||||||
|
tests/utils/shippable/timing.py shebang
|
||||||
2
tests/sanity/ignore-2.15.txt
Normal file
2
tests/sanity/ignore-2.15.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
tests/utils/shippable/check_matrix.py replace-urlopen
|
||||||
|
tests/utils/shippable/timing.py shebang
|
||||||
1
tests/sanity/ignore-2.16.txt
Normal file
1
tests/sanity/ignore-2.16.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
tests/utils/shippable/timing.py shebang
|
||||||
1
tests/sanity/ignore-2.17.txt
Normal file
1
tests/sanity/ignore-2.17.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
tests/utils/shippable/timing.py shebang
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
tests/utils/shippable/timing.py shebang
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
tests/utils/shippable/timing.py shebang
|
||||||
|
|||||||
34
tests/unit/compat/builtins.py
Normal file
34
tests/unit/compat/builtins.py
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# (c) 2014, Toshio Kuratomi <tkuratomi@ansible.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/>.
|
||||||
|
|
||||||
|
# Make coding more python3-ish
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
#
|
||||||
|
# Compat for python2.7
|
||||||
|
#
|
||||||
|
|
||||||
|
# One unittest needs to import builtins via __import__() so we need to have
|
||||||
|
# the string that represents it
|
||||||
|
try:
|
||||||
|
import __builtin__
|
||||||
|
except ImportError:
|
||||||
|
BUILTINS = 'builtins'
|
||||||
|
else:
|
||||||
|
BUILTINS = '__builtin__'
|
||||||
|
__all__ = ['__builtin__']
|
||||||
116
tests/unit/mock/loader.py
Normal file
116
tests/unit/mock/loader.py
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
# (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.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/>.
|
||||||
|
|
||||||
|
# Make coding more python3-ish
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from ansible.errors import AnsibleParserError
|
||||||
|
from ansible.parsing.dataloader import DataLoader
|
||||||
|
from ansible.module_utils._text import to_bytes, to_text
|
||||||
|
|
||||||
|
|
||||||
|
class DictDataLoader(DataLoader):
|
||||||
|
|
||||||
|
def __init__(self, file_mapping=None):
|
||||||
|
file_mapping = {} if file_mapping is None else file_mapping
|
||||||
|
assert isinstance(file_mapping, dict)
|
||||||
|
|
||||||
|
super(DictDataLoader, self).__init__()
|
||||||
|
|
||||||
|
self._file_mapping = file_mapping
|
||||||
|
self._build_known_directories()
|
||||||
|
self._vault_secrets = None
|
||||||
|
|
||||||
|
def load_from_file(self, path, cache=True, unsafe=False):
|
||||||
|
path = to_text(path)
|
||||||
|
if path in self._file_mapping:
|
||||||
|
return self.load(self._file_mapping[path], path)
|
||||||
|
return None
|
||||||
|
|
||||||
|
# TODO: the real _get_file_contents returns a bytestring, so we actually convert the
|
||||||
|
# unicode/text it's created with to utf-8
|
||||||
|
def _get_file_contents(self, file_name):
|
||||||
|
path = to_text(file_name)
|
||||||
|
if path in self._file_mapping:
|
||||||
|
return (to_bytes(self._file_mapping[path]), False)
|
||||||
|
else:
|
||||||
|
raise AnsibleParserError("file not found: %s" % path)
|
||||||
|
|
||||||
|
def path_exists(self, path):
|
||||||
|
path = to_text(path)
|
||||||
|
return path in self._file_mapping or path in self._known_directories
|
||||||
|
|
||||||
|
def is_file(self, path):
|
||||||
|
path = to_text(path)
|
||||||
|
return path in self._file_mapping
|
||||||
|
|
||||||
|
def is_directory(self, path):
|
||||||
|
path = to_text(path)
|
||||||
|
return path in self._known_directories
|
||||||
|
|
||||||
|
def list_directory(self, path):
|
||||||
|
ret = []
|
||||||
|
path = to_text(path)
|
||||||
|
for x in (list(self._file_mapping.keys()) + self._known_directories):
|
||||||
|
if x.startswith(path):
|
||||||
|
if os.path.dirname(x) == path:
|
||||||
|
ret.append(os.path.basename(x))
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def is_executable(self, path):
|
||||||
|
# FIXME: figure out a way to make paths return true for this
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _add_known_directory(self, directory):
|
||||||
|
if directory not in self._known_directories:
|
||||||
|
self._known_directories.append(directory)
|
||||||
|
|
||||||
|
def _build_known_directories(self):
|
||||||
|
self._known_directories = []
|
||||||
|
for path in self._file_mapping:
|
||||||
|
dirname = os.path.dirname(path)
|
||||||
|
while dirname not in ('/', ''):
|
||||||
|
self._add_known_directory(dirname)
|
||||||
|
dirname = os.path.dirname(dirname)
|
||||||
|
|
||||||
|
def push(self, path, content):
|
||||||
|
rebuild_dirs = False
|
||||||
|
if path not in self._file_mapping:
|
||||||
|
rebuild_dirs = True
|
||||||
|
|
||||||
|
self._file_mapping[path] = content
|
||||||
|
|
||||||
|
if rebuild_dirs:
|
||||||
|
self._build_known_directories()
|
||||||
|
|
||||||
|
def pop(self, path):
|
||||||
|
if path in self._file_mapping:
|
||||||
|
del self._file_mapping[path]
|
||||||
|
self._build_known_directories()
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
self._file_mapping = dict()
|
||||||
|
self._known_directories = []
|
||||||
|
|
||||||
|
def get_basedir(self):
|
||||||
|
return os.getcwd()
|
||||||
|
|
||||||
|
def set_vault_secrets(self, vault_secrets):
|
||||||
|
self._vault_secrets = vault_secrets
|
||||||
9
tests/unit/mock/path.py
Normal file
9
tests/unit/mock/path.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
mock_unfrackpath_noop = MagicMock(spec_set=unfrackpath, side_effect=lambda x, *args, **kwargs: x)
|
||||||
90
tests/unit/mock/procenv.py
Normal file
90
tests/unit/mock/procenv.py
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
# (c) 2016, Matt Davis <mdavis@ansible.com>
|
||||||
|
# (c) 2016, Toshio Kuratomi <tkuratomi@ansible.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/>.
|
||||||
|
|
||||||
|
# Make coding more python3-ish
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
|
||||||
|
from contextlib import contextmanager
|
||||||
|
from io import BytesIO, StringIO
|
||||||
|
from ansible_collections.ansible.posix.tests.unit.compat import unittest
|
||||||
|
from ansible.module_utils.six import PY3
|
||||||
|
from ansible.module_utils._text import to_bytes
|
||||||
|
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def swap_stdin_and_argv(stdin_data='', argv_data=tuple()):
|
||||||
|
"""
|
||||||
|
context manager that temporarily masks the test runner's values for stdin and argv
|
||||||
|
"""
|
||||||
|
real_stdin = sys.stdin
|
||||||
|
real_argv = sys.argv
|
||||||
|
|
||||||
|
if PY3:
|
||||||
|
fake_stream = StringIO(stdin_data)
|
||||||
|
fake_stream.buffer = BytesIO(to_bytes(stdin_data))
|
||||||
|
else:
|
||||||
|
fake_stream = BytesIO(to_bytes(stdin_data))
|
||||||
|
|
||||||
|
try:
|
||||||
|
sys.stdin = fake_stream
|
||||||
|
sys.argv = argv_data
|
||||||
|
|
||||||
|
yield
|
||||||
|
finally:
|
||||||
|
sys.stdin = real_stdin
|
||||||
|
sys.argv = real_argv
|
||||||
|
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def swap_stdout():
|
||||||
|
"""
|
||||||
|
context manager that temporarily replaces stdout for tests that need to verify output
|
||||||
|
"""
|
||||||
|
old_stdout = sys.stdout
|
||||||
|
|
||||||
|
if PY3:
|
||||||
|
fake_stream = StringIO()
|
||||||
|
else:
|
||||||
|
fake_stream = BytesIO()
|
||||||
|
|
||||||
|
try:
|
||||||
|
sys.stdout = fake_stream
|
||||||
|
|
||||||
|
yield fake_stream
|
||||||
|
finally:
|
||||||
|
sys.stdout = old_stdout
|
||||||
|
|
||||||
|
|
||||||
|
class ModuleTestCase(unittest.TestCase):
|
||||||
|
def setUp(self, module_args=None):
|
||||||
|
if module_args is None:
|
||||||
|
module_args = {'_ansible_remote_tmp': '/tmp', '_ansible_keep_remote_files': False}
|
||||||
|
|
||||||
|
args = json.dumps(dict(ANSIBLE_MODULE_ARGS=module_args))
|
||||||
|
|
||||||
|
# unittest doesn't have a clean place to use a context manager, so we have to enter/exit manually
|
||||||
|
self.stdin_swap = swap_stdin_and_argv(stdin_data=args)
|
||||||
|
self.stdin_swap.__enter__()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
# unittest doesn't have a clean place to use a context manager, so we have to enter/exit manually
|
||||||
|
self.stdin_swap.__exit__(None, None, None)
|
||||||
39
tests/unit/mock/vault_helper.py
Normal file
39
tests/unit/mock/vault_helper.py
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# 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/>.
|
||||||
|
|
||||||
|
# Make coding more python3-ish
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
from ansible.module_utils._text import to_bytes
|
||||||
|
|
||||||
|
from ansible.parsing.vault import VaultSecret
|
||||||
|
|
||||||
|
|
||||||
|
class TextVaultSecret(VaultSecret):
|
||||||
|
'''A secret piece of text. ie, a password. Tracks text encoding.
|
||||||
|
|
||||||
|
The text encoding of the text may not be the default text encoding so
|
||||||
|
we keep track of the encoding so we encode it to the same bytes.'''
|
||||||
|
|
||||||
|
def __init__(self, text, encoding=None, errors=None, _bytes=None):
|
||||||
|
super(TextVaultSecret, self).__init__()
|
||||||
|
self.text = text
|
||||||
|
self.encoding = encoding or 'utf-8'
|
||||||
|
self._bytes = _bytes
|
||||||
|
self.errors = errors or 'strict'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def bytes(self):
|
||||||
|
'''The text encoded with encoding, unless we specifically set _bytes.'''
|
||||||
|
return self._bytes or to_bytes(self.text, encoding=self.encoding, errors=self.errors)
|
||||||
125
tests/unit/mock/yaml_helper.py
Normal file
125
tests/unit/mock/yaml_helper.py
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
import io
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
from ansible.module_utils.six import PY3
|
||||||
|
from ansible.parsing.yaml.loader import AnsibleLoader
|
||||||
|
from ansible.parsing.yaml.dumper import AnsibleDumper
|
||||||
|
|
||||||
|
|
||||||
|
class YamlTestUtils(object):
|
||||||
|
"""Mixin class to combine with a unittest.TestCase subclass."""
|
||||||
|
def _loader(self, stream):
|
||||||
|
"""Vault related tests will want to override this.
|
||||||
|
|
||||||
|
Vault cases should setup a AnsibleLoader that has the vault password."""
|
||||||
|
return AnsibleLoader(stream)
|
||||||
|
|
||||||
|
def _dump_stream(self, obj, stream, dumper=None):
|
||||||
|
"""Dump to a py2-unicode or py3-string stream."""
|
||||||
|
if PY3:
|
||||||
|
return yaml.dump(obj, stream, Dumper=dumper)
|
||||||
|
else:
|
||||||
|
return yaml.dump(obj, stream, Dumper=dumper, encoding=None)
|
||||||
|
|
||||||
|
def _dump_string(self, obj, dumper=None):
|
||||||
|
"""Dump to a py2-unicode or py3-string"""
|
||||||
|
if PY3:
|
||||||
|
return yaml.dump(obj, Dumper=dumper)
|
||||||
|
else:
|
||||||
|
return yaml.dump(obj, Dumper=dumper, encoding=None)
|
||||||
|
|
||||||
|
def _dump_load_cycle(self, obj):
|
||||||
|
# Each pass though a dump or load revs the 'generation'
|
||||||
|
# obj to yaml string
|
||||||
|
string_from_object_dump = self._dump_string(obj, dumper=AnsibleDumper)
|
||||||
|
|
||||||
|
# wrap a stream/file like StringIO around that yaml
|
||||||
|
stream_from_object_dump = io.StringIO(string_from_object_dump)
|
||||||
|
loader = self._loader(stream_from_object_dump)
|
||||||
|
# load the yaml stream to create a new instance of the object (gen 2)
|
||||||
|
obj_2 = loader.get_data()
|
||||||
|
|
||||||
|
# dump the gen 2 objects directory to strings
|
||||||
|
string_from_object_dump_2 = self._dump_string(obj_2,
|
||||||
|
dumper=AnsibleDumper)
|
||||||
|
|
||||||
|
# The gen 1 and gen 2 yaml strings
|
||||||
|
self.assertEqual(string_from_object_dump, string_from_object_dump_2)
|
||||||
|
# the gen 1 (orig) and gen 2 py object
|
||||||
|
self.assertEqual(obj, obj_2)
|
||||||
|
|
||||||
|
# again! gen 3... load strings into py objects
|
||||||
|
stream_3 = io.StringIO(string_from_object_dump_2)
|
||||||
|
loader_3 = self._loader(stream_3)
|
||||||
|
obj_3 = loader_3.get_data()
|
||||||
|
|
||||||
|
string_from_object_dump_3 = self._dump_string(obj_3, dumper=AnsibleDumper)
|
||||||
|
|
||||||
|
self.assertEqual(obj, obj_3)
|
||||||
|
# should be transitive, but...
|
||||||
|
self.assertEqual(obj_2, obj_3)
|
||||||
|
self.assertEqual(string_from_object_dump, string_from_object_dump_3)
|
||||||
|
|
||||||
|
def _old_dump_load_cycle(self, obj):
|
||||||
|
'''Dump the passed in object to yaml, load it back up, dump again, compare.'''
|
||||||
|
stream = io.StringIO()
|
||||||
|
|
||||||
|
yaml_string = self._dump_string(obj, dumper=AnsibleDumper)
|
||||||
|
self._dump_stream(obj, stream, dumper=AnsibleDumper)
|
||||||
|
|
||||||
|
yaml_string_from_stream = stream.getvalue()
|
||||||
|
|
||||||
|
# reset stream
|
||||||
|
stream.seek(0)
|
||||||
|
|
||||||
|
loader = self._loader(stream)
|
||||||
|
# loader = AnsibleLoader(stream, vault_password=self.vault_password)
|
||||||
|
obj_from_stream = loader.get_data()
|
||||||
|
|
||||||
|
stream_from_string = io.StringIO(yaml_string)
|
||||||
|
loader2 = self._loader(stream_from_string)
|
||||||
|
# loader2 = AnsibleLoader(stream_from_string, vault_password=self.vault_password)
|
||||||
|
obj_from_string = loader2.get_data()
|
||||||
|
|
||||||
|
stream_obj_from_stream = io.StringIO()
|
||||||
|
stream_obj_from_string = io.StringIO()
|
||||||
|
|
||||||
|
if PY3:
|
||||||
|
yaml.dump(obj_from_stream, stream_obj_from_stream, Dumper=AnsibleDumper)
|
||||||
|
yaml.dump(obj_from_stream, stream_obj_from_string, Dumper=AnsibleDumper)
|
||||||
|
else:
|
||||||
|
yaml.dump(obj_from_stream, stream_obj_from_stream, Dumper=AnsibleDumper, encoding=None)
|
||||||
|
yaml.dump(obj_from_stream, stream_obj_from_string, Dumper=AnsibleDumper, encoding=None)
|
||||||
|
|
||||||
|
yaml_string_stream_obj_from_stream = stream_obj_from_stream.getvalue()
|
||||||
|
yaml_string_stream_obj_from_string = stream_obj_from_string.getvalue()
|
||||||
|
|
||||||
|
stream_obj_from_stream.seek(0)
|
||||||
|
stream_obj_from_string.seek(0)
|
||||||
|
|
||||||
|
if PY3:
|
||||||
|
yaml_string_obj_from_stream = yaml.dump(obj_from_stream, Dumper=AnsibleDumper)
|
||||||
|
yaml_string_obj_from_string = yaml.dump(obj_from_string, Dumper=AnsibleDumper)
|
||||||
|
else:
|
||||||
|
yaml_string_obj_from_stream = yaml.dump(obj_from_stream, Dumper=AnsibleDumper, encoding=None)
|
||||||
|
yaml_string_obj_from_string = yaml.dump(obj_from_string, Dumper=AnsibleDumper, encoding=None)
|
||||||
|
|
||||||
|
assert yaml_string == yaml_string_obj_from_stream
|
||||||
|
assert yaml_string == yaml_string_obj_from_stream == yaml_string_obj_from_string
|
||||||
|
assert (yaml_string == yaml_string_obj_from_stream == yaml_string_obj_from_string == yaml_string_stream_obj_from_stream ==
|
||||||
|
yaml_string_stream_obj_from_string)
|
||||||
|
assert obj == obj_from_stream
|
||||||
|
assert obj == obj_from_string
|
||||||
|
assert obj == yaml_string_obj_from_stream
|
||||||
|
assert obj == yaml_string_obj_from_string
|
||||||
|
assert obj == obj_from_stream == obj_from_string == yaml_string_obj_from_stream == yaml_string_obj_from_string
|
||||||
|
return {'obj': obj,
|
||||||
|
'yaml_string': yaml_string,
|
||||||
|
'yaml_string_from_stream': yaml_string_from_stream,
|
||||||
|
'obj_from_stream': obj_from_stream,
|
||||||
|
'obj_from_string': obj_from_string,
|
||||||
|
'yaml_string_obj_from_string': yaml_string_obj_from_string}
|
||||||
32
tests/unit/modules/conftest.py
Normal file
32
tests/unit/modules/conftest.py
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# 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
|
||||||
|
|
||||||
|
from ansible.module_utils.six import string_types
|
||||||
|
from ansible.module_utils._text import to_bytes
|
||||||
|
from ansible.module_utils.common._collections_compat import MutableMapping
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def patch_ansible_module(request, mocker):
|
||||||
|
if isinstance(request.param, string_types):
|
||||||
|
args = request.param
|
||||||
|
elif isinstance(request.param, MutableMapping):
|
||||||
|
if 'ANSIBLE_MODULE_ARGS' not in request.param:
|
||||||
|
request.param = {'ANSIBLE_MODULE_ARGS': request.param}
|
||||||
|
if '_ansible_remote_tmp' not in request.param['ANSIBLE_MODULE_ARGS']:
|
||||||
|
request.param['ANSIBLE_MODULE_ARGS']['_ansible_remote_tmp'] = '/tmp'
|
||||||
|
if '_ansible_keep_remote_files' not in request.param['ANSIBLE_MODULE_ARGS']:
|
||||||
|
request.param['ANSIBLE_MODULE_ARGS']['_ansible_keep_remote_files'] = False
|
||||||
|
args = json.dumps(request.param)
|
||||||
|
else:
|
||||||
|
raise Exception('Malformed data to the patch_ansible_module pytest fixture')
|
||||||
|
|
||||||
|
mocker.patch('ansible.module_utils.basic._ANSIBLE_ARGS', to_bytes(args))
|
||||||
@@ -7,7 +7,7 @@ import tempfile
|
|||||||
|
|
||||||
from ansible_collections.ansible.posix.tests.unit.compat import unittest
|
from ansible_collections.ansible.posix.tests.unit.compat import unittest
|
||||||
from ansible_collections.ansible.posix.tests.unit.compat.mock import MagicMock
|
from ansible_collections.ansible.posix.tests.unit.compat.mock import MagicMock
|
||||||
from ansible.module_utils.common.text.converters import to_bytes
|
from ansible.module_utils._text import to_bytes
|
||||||
|
|
||||||
from ansible_collections.ansible.posix.plugins.modules.mount import (
|
from ansible_collections.ansible.posix.plugins.modules.mount import (
|
||||||
get_linux_mounts,
|
get_linux_mounts,
|
||||||
|
|||||||
51
tests/unit/modules/utils.py
Normal file
51
tests/unit/modules/utils.py
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
|
from ansible_collections.ansible.posix.tests.unit.compat import unittest
|
||||||
|
from ansible_collections.ansible.posix.tests.unit.compat.mock import patch
|
||||||
|
from ansible.module_utils import basic
|
||||||
|
from ansible.module_utils._text import to_bytes
|
||||||
|
|
||||||
|
|
||||||
|
def set_module_args(args):
|
||||||
|
if '_ansible_remote_tmp' not in args:
|
||||||
|
args['_ansible_remote_tmp'] = '/tmp'
|
||||||
|
if '_ansible_keep_remote_files' not in args:
|
||||||
|
args['_ansible_keep_remote_files'] = False
|
||||||
|
|
||||||
|
args = json.dumps({'ANSIBLE_MODULE_ARGS': args})
|
||||||
|
basic._ANSIBLE_ARGS = to_bytes(args)
|
||||||
|
|
||||||
|
|
||||||
|
class AnsibleExitJson(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class AnsibleFailJson(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def exit_json(*args, **kwargs):
|
||||||
|
if 'changed' not in kwargs:
|
||||||
|
kwargs['changed'] = False
|
||||||
|
raise AnsibleExitJson(kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def fail_json(*args, **kwargs):
|
||||||
|
kwargs['failed'] = True
|
||||||
|
raise AnsibleFailJson(kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class ModuleTestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.mock_module = patch.multiple(basic.AnsibleModule, exit_json=exit_json, fail_json=fail_json)
|
||||||
|
self.mock_module.start()
|
||||||
|
self.mock_sleep = patch('time.sleep')
|
||||||
|
self.mock_sleep.start()
|
||||||
|
set_module_args({})
|
||||||
|
self.addCleanup(self.mock_module.stop)
|
||||||
|
self.addCleanup(self.mock_sleep.stop)
|
||||||
@@ -9,5 +9,6 @@ command -v ansible
|
|||||||
pip install --upgrade --user pip
|
pip install --upgrade --user pip
|
||||||
pip install --upgrade --user ansible-lint
|
pip install --upgrade --user ansible-lint
|
||||||
|
|
||||||
# To specify additional options, you can specify them into .ansible-lint file.
|
PATH="${PATH/\~/${HOME}}" ansible-lint \
|
||||||
PATH="${PATH/\~/${HOME}}" ansible-lint
|
--exclude changelogs/ \
|
||||||
|
--profile=production
|
||||||
|
|||||||
@@ -62,15 +62,15 @@ else
|
|||||||
retry pip install "https://github.com/ansible/ansible/archive/stable-${ansible_version}.tar.gz" --disable-pip-version-check
|
retry pip install "https://github.com/ansible/ansible/archive/stable-${ansible_version}.tar.gz" --disable-pip-version-check
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export ANSIBLE_COLLECTIONS_PATH="${PWD}/../../../"
|
export ANSIBLE_COLLECTIONS_PATHS="${PWD}/../../../"
|
||||||
|
|
||||||
# START: HACK install dependencies
|
# START: HACK install dependencies
|
||||||
if [ "${ansible_version}" == "2.9" ] || [ "${ansible_version}" == "2.10" ]; then
|
if [ "${ansible_version}" == "2.9" ] || [ "${ansible_version}" == "2.10" ]; then
|
||||||
# Note: Since community.general 5.x, Ansible Core versions prior to 2.11 are not supported.
|
# Note: Since community.general 5.x, Ansible Core versions prior to 2.11 are not supported.
|
||||||
# So we need to use 4.8.1 for Ansible 2.9 and Ansible Engine 2.10.
|
# So we need to use 4.8.1 for Ansible 2.9 and Ansible Engine 2.10.
|
||||||
retry git clone --depth=1 --single-branch -b 4.8.1 https://github.com/ansible-collections/community.general.git "${ANSIBLE_COLLECTIONS_PATH}/ansible_collections/community/general"
|
retry git clone --depth=1 --single-branch -b 4.8.1 https://github.com/ansible-collections/community.general.git "${ANSIBLE_COLLECTIONS_PATHS}/ansible_collections/community/general"
|
||||||
else
|
else
|
||||||
retry git clone --depth=1 --single-branch https://github.com/ansible-collections/community.general.git "${ANSIBLE_COLLECTIONS_PATH}/ansible_collections/community/general"
|
retry git clone --depth=1 --single-branch https://github.com/ansible-collections/community.general.git "${ANSIBLE_COLLECTIONS_PATHS}/ansible_collections/community/general"
|
||||||
fi
|
fi
|
||||||
# Note: we're installing with git to work around Galaxy being a huge PITA (https://github.com/ansible/galaxy/issues/2429)
|
# Note: we're installing with git to work around Galaxy being a huge PITA (https://github.com/ansible/galaxy/issues/2429)
|
||||||
# END: HACK
|
# END: HACK
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
from __future__ import (absolute_import, division, print_function)
|
from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user