mirror of
https://github.com/freeipa/ansible-freeipa.git
synced 2026-03-28 14:23:06 +00:00
Compare commits
74 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d580431832 | ||
|
|
6c94fe9bd5 | ||
|
|
4fa0621156 | ||
|
|
da775a21b2 | ||
|
|
5a774d2612 | ||
|
|
3e405fd08d | ||
|
|
cb3226910b | ||
|
|
a96611fb3f | ||
|
|
e92f09b920 | ||
|
|
97b0638f30 | ||
|
|
24569b850a | ||
|
|
08a2ba1592 | ||
|
|
3d5ff1f5fd | ||
|
|
2b28626012 | ||
|
|
7c7d98872e | ||
|
|
8956a7a1dd | ||
|
|
25577fa9bc | ||
|
|
f6bd62feb4 | ||
|
|
33c1c00643 | ||
|
|
0f530df092 | ||
|
|
a707d1887d | ||
|
|
e1786c9ddc | ||
|
|
367d30a30c | ||
|
|
77c34aeca2 | ||
|
|
5b33cb5e80 | ||
|
|
c979843b1a | ||
|
|
a8ce235261 | ||
|
|
bdcc8153f8 | ||
|
|
57bc35df80 | ||
|
|
a2f59e1a34 | ||
|
|
16636de681 | ||
|
|
55ec25a759 | ||
|
|
2b10256575 | ||
|
|
907650c746 | ||
|
|
b128a5cb9f | ||
|
|
220c4f0016 | ||
|
|
7f1df9d8f8 | ||
|
|
75d8ea283f | ||
|
|
91a3013513 | ||
|
|
85ef81c842 | ||
|
|
ad44f11887 | ||
|
|
80693c431a | ||
|
|
9ebc365d69 | ||
|
|
50ba326ed8 | ||
|
|
691e5915b9 | ||
|
|
178cf218b9 | ||
|
|
36f26bdf63 | ||
|
|
e2bdbeef6d | ||
|
|
88dc4c6923 | ||
|
|
e05fbce04c | ||
|
|
c2ff12b101 | ||
|
|
7dbe6edbf0 | ||
|
|
02ba890eb4 | ||
|
|
8515c9a48b | ||
|
|
94311f439c | ||
|
|
7aa9483b2c | ||
|
|
68bca84481 | ||
|
|
c9010d52ef | ||
|
|
0c6a7c8a14 | ||
|
|
0d246b1c11 | ||
|
|
785681f100 | ||
|
|
480c83f504 | ||
|
|
928ed30b8b | ||
|
|
fb6fed58cb | ||
|
|
b0e03a032d | ||
|
|
7ac0ec6bd4 | ||
|
|
8153239ef7 | ||
|
|
c2f6a19677 | ||
|
|
0002d4c7f7 | ||
|
|
a95c222ed6 | ||
|
|
d9a20e16c1 | ||
|
|
a4860f7b04 | ||
|
|
e71602be6e | ||
|
|
3dfa026eda |
@@ -7,7 +7,6 @@ exclude_paths:
|
||||
- .tox/
|
||||
- .venv/
|
||||
- .yamllint
|
||||
- molecule/
|
||||
- tests/azure/
|
||||
- meta/runtime.yml
|
||||
- requirements-docker.yml
|
||||
|
||||
17
.github/workflows/lint.yml
vendored
17
.github/workflows/lint.yml
vendored
@@ -34,21 +34,6 @@ jobs:
|
||||
- name: Run yaml-lint
|
||||
uses: ibiqlik/action-yamllint@v3.1.1
|
||||
|
||||
pydocstyle:
|
||||
name: Verify pydocstyle
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.1
|
||||
with:
|
||||
fetch-depth: 1
|
||||
- uses: actions/setup-python@v5.1.0
|
||||
with:
|
||||
python-version: "3.x"
|
||||
- name: Run pydocstyle
|
||||
run: |
|
||||
pip install pydocstyle
|
||||
pydocstyle
|
||||
|
||||
flake8:
|
||||
name: Verify flake8
|
||||
runs-on: ubuntu-latest
|
||||
@@ -88,3 +73,5 @@ jobs:
|
||||
fetch-depth: 1
|
||||
- name: Run ShellCheck
|
||||
uses: ludeeus/action-shellcheck@master
|
||||
env:
|
||||
SHELLCHECK_OPTS: -x
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -12,3 +12,4 @@ importer_result.json
|
||||
/.venv/
|
||||
|
||||
tests/logs/
|
||||
TEST*.xml
|
||||
|
||||
@@ -29,10 +29,6 @@ repos:
|
||||
rev: 7.0.0
|
||||
hooks:
|
||||
- id: flake8
|
||||
- repo: https://github.com/pycqa/pydocstyle
|
||||
rev: 6.3.0
|
||||
hooks:
|
||||
- id: pydocstyle
|
||||
- repo: https://github.com/pycqa/pylint
|
||||
rev: v3.2.2
|
||||
hooks:
|
||||
@@ -54,4 +50,7 @@ repos:
|
||||
name: ShellCheck
|
||||
language: system
|
||||
entry: shellcheck
|
||||
files: \.sh$
|
||||
args: ['-x']
|
||||
files: >
|
||||
\.sh$
|
||||
utils/sh*$
|
||||
|
||||
@@ -44,7 +44,7 @@ Example playbook to make sure HBAC Rule login exists:
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hbacrules
|
||||
hbacsvcs: ipaserver
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
@@ -60,7 +60,7 @@ Example playbook to make sure HBAC Rule login exists with the only HBAC Service
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hbacrules
|
||||
hbacsvcs: ipaserver
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
@@ -77,7 +77,7 @@ Example playbook to make sure HBAC Service sshd is present in HBAC Rule login:
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hbacrules
|
||||
hbacsvcs: ipaserver
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
@@ -95,7 +95,7 @@ Example playbook to make sure HBAC Service sshd is absent in HBAC Rule login:
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hbacrules
|
||||
hbacsvcs: ipaserver
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
@@ -114,7 +114,7 @@ Example playbook to make sure HBAC Rule login is absent:
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hbacrules
|
||||
hbacsvcs: ipaserver
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
|
||||
@@ -44,7 +44,7 @@ Example playbook to make sure HBAC Service Group login exists:
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hbacsvcgroups
|
||||
hbacsvcs: ipaserver
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
@@ -60,7 +60,7 @@ Example playbook to make sure HBAC Service Group login exists with the only HBAC
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hbacsvcgroups
|
||||
hbacsvcs: ipaserver
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
@@ -77,7 +77,7 @@ Example playbook to make sure HBAC Service sshd is present in HBAC Service Group
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hbacsvcgroups
|
||||
hbacsvcs: ipaserver
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
@@ -95,7 +95,7 @@ Example playbook to make sure HBAC Service sshd is absent in HBAC Service Group
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hbacsvcgroups
|
||||
hbacsvcs: ipaserver
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
@@ -114,7 +114,7 @@ Example playbook to make sure HBAC Service Group login is absent:
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle hbacsvcgroups
|
||||
hbacsvcs: ipaserver
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
|
||||
@@ -341,7 +341,7 @@ Variable | Description | Required
|
||||
`password` \| `user_password` \| `userpassword` | Password used in bulk enrollment for absent or not enrolled hosts. | no
|
||||
`random` \| `random_password` | Initiate the generation of a random password to be used in bulk enrollment for absent or not enrolled hosts. | no
|
||||
`certificate` \| `usercertificate` | List of base-64 encoded host certificates | no
|
||||
`managedby` \| `principalname` \| `krbprincipalname` | List of hosts that can manage this host | no
|
||||
`managedby_host` | List of hosts that can manage this host | no
|
||||
`principal` \| `principalname` \| `krbprincipalname` | List of principal aliases for this host | no
|
||||
`allow_create_keytab_user` \| `ipaallowedtoperform_write_keys_user` | Users allowed to create a keytab of this host. | no
|
||||
`allow_create_keytab_group` \| `ipaallowedtoperform_write_keys_group` | Groups allowed to create a keytab of this host. | no
|
||||
|
||||
@@ -129,6 +129,49 @@ Example playbook to make sure Sudo Rule is absent:
|
||||
state: absent
|
||||
```
|
||||
|
||||
Example playbook to ensure multiple Sudo Rule are present using batch mode:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle sudorules
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
- name: Ensure multiple Sudo Rules are present using batch mode.
|
||||
ipasudorule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
sudorules:
|
||||
- name: testrule1
|
||||
hostmask:
|
||||
- 192.168.122.1/24
|
||||
- name: testrule2
|
||||
hostcategory: all
|
||||
```
|
||||
|
||||
Example playbook to ensure multiple Sudo Rule members are present using batch mode:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle sudorules
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
- name: Ensure multiple Sudo Rules are present using batch mode.
|
||||
ipasudorule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
action: member
|
||||
sudorules:
|
||||
- name: testrule1
|
||||
user:
|
||||
- user01
|
||||
- user02
|
||||
group:
|
||||
- group01
|
||||
- name: testrule2
|
||||
hostgroup:
|
||||
- hostgroup01
|
||||
- hostgroup02
|
||||
```
|
||||
|
||||
Variables
|
||||
=========
|
||||
@@ -139,7 +182,9 @@ Variable | Description | Required
|
||||
`ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no
|
||||
`ipaapi_context` | The context in which the module will execute. Executing in a server context is preferred. If not provided context will be determined by the execution environment. Valid values are `server` and `client`. | no
|
||||
`ipaapi_ldap_cache` | Use LDAP cache for IPA connection. The bool setting defaults to yes. (bool) | no
|
||||
`name` \| `cn` | The list of sudorule name strings. | yes
|
||||
`name` \| `cn` | The list of sudorule name strings. | no
|
||||
`sudorules` | The list of sudorule dicts. Each `sudorule` dict entry can contain sudorule variables.<br>There is one required option in the `sudorule` dict:| no
|
||||
| `name` - The sudorule name string of the entry. | yes
|
||||
`description` | The sudorule description string. | no
|
||||
`usercategory` \| `usercat` | User category the rule applies to. Choices: ["all", ""] | no
|
||||
`hostcategory` \| `hostcat` | Host category the rule applies to. Choices: ["all", ""] | no
|
||||
|
||||
73
infra/azure/azure-pipelines.yml
Normal file
73
infra/azure/azure-pipelines.yml
Normal file
@@ -0,0 +1,73 @@
|
||||
---
|
||||
trigger:
|
||||
- master
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-20.04'
|
||||
|
||||
variables:
|
||||
ansible_version: "-core >=2.16,<2.17"
|
||||
ansible_latest: "-core"
|
||||
ansible_minimum: "-core <2.16"
|
||||
distros: "fedora-latest,c9s,fedora-rawhide"
|
||||
|
||||
stages:
|
||||
|
||||
- stage: fedora_latest_ansible_latest
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
distro: fedora-latest
|
||||
ansible_version: ${{ variables.ansible_latest }}
|
||||
skip_git_test: true
|
||||
|
||||
- stage: fedora_latest_ansible_2_15
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
distro: fedora-latest
|
||||
ansible_version: ${{ variables.ansbile_minimum }}
|
||||
skip_git_test: true
|
||||
|
||||
# Supported distros
|
||||
|
||||
- ${{ each distro in split(variables.distros, ',') }}:
|
||||
- stage: ${{ replace(distro, '-', '_') }}_ansible_2_16
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
distro: ${{ distro }}
|
||||
ansible_version: ${{ variables.ansible_version }}
|
||||
skip_git_test: true
|
||||
test_galaxy: false
|
||||
|
||||
# Galaxy on Fedora
|
||||
|
||||
- stage: galaxy_fedora_latest_ansible_2_16
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
distro: fedora-latest
|
||||
ansible_version: ${{ variables.ansible_version }}
|
||||
skip_git_test: true
|
||||
test_galaxy: true
|
||||
|
||||
# CentOS 8 Stream, latest supported Ansible version.
|
||||
|
||||
- stage: c8s_ansible_2_16
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
distro: c8s
|
||||
ansible_version: "-core <2.17"
|
||||
skip_git_test: true
|
||||
35
infra/azure/build-containers.yml
Normal file
35
infra/azure/build-containers.yml
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
schedules:
|
||||
- cron: "0 0 * * 0"
|
||||
displayName: Weekly Sunday midnight build
|
||||
branches:
|
||||
include:
|
||||
- master
|
||||
always: true
|
||||
|
||||
trigger: none
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-24.04'
|
||||
|
||||
variables: { distros: "fedora-latest,fedora-rawhide,c9s" }
|
||||
|
||||
stages:
|
||||
|
||||
- ${{ each distro in split(variables.distros, ',') }}:
|
||||
- stage: build_${{ join('_', split(distro, '-')) }}
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/build_container.yml
|
||||
parameters:
|
||||
distro: ${{ distro }}
|
||||
|
||||
# Special case for CentOS 8 Stream
|
||||
- stage: CentOS_8_Stream
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/build_container.yml
|
||||
parameters:
|
||||
distro: c8s
|
||||
# ansible-core 2.17+ cannot be used to deploy on CentOS 8 Stream.
|
||||
ansible_core_version: "<2.17"
|
||||
79
infra/azure/nightly.yml
Normal file
79
infra/azure/nightly.yml
Normal file
@@ -0,0 +1,79 @@
|
||||
---
|
||||
schedules:
|
||||
- cron: "0 19 * * *"
|
||||
displayName: Nightly Builds
|
||||
branches:
|
||||
include:
|
||||
- master
|
||||
always: true
|
||||
|
||||
trigger: none
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-20.04'
|
||||
|
||||
variables:
|
||||
# We need to have two sets, as c8s is not supported by all ansible versions
|
||||
recent_distros: "fedora-latest,fedora-rawhide,c9s"
|
||||
distros: "fedora-latest,fedora-rawhide,c9s,c8s"
|
||||
ansible_latest: "-core"
|
||||
ansible_minimum: "-core <2.16"
|
||||
ansible_version: "-core >=2.16,<2.17"
|
||||
|
||||
stages:
|
||||
|
||||
# Minimum ansible
|
||||
|
||||
- ${{ each distro in split(variables.distros, ',') }}:
|
||||
- stage: ${{ replace(distro, '-', '_') }}_ansible_2_15
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
distro: fedora-latest
|
||||
ansible_version: ${{ variables.ansible_minimum }}
|
||||
skip_git_test: true
|
||||
test_galaxy: false
|
||||
|
||||
# Latest ansible
|
||||
|
||||
- ${{ each distro in split(variables.recent_distros, ',') }}:
|
||||
- stage: ${{ replace(distro, '-', '_') }}_ansible_latest
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
distro: ${{ distro }}
|
||||
ansible_version: ${{ variables.ansible_latest }}
|
||||
skip_git_test: true
|
||||
test_galaxy: false
|
||||
|
||||
# Selected ansible-core version
|
||||
|
||||
- ${{ each distro in split(variables.distros, ',') }}:
|
||||
- stage: ${{ replace(distro, '-', '_') }}_ansible_2_16
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
distro: ${{ distro }}
|
||||
ansible_version: ${{ variables.ansible_version }}
|
||||
skip_git_test: true
|
||||
test_galaxy: false
|
||||
|
||||
# Galaxy collection with selected ansible-core version
|
||||
|
||||
- ${{ each distro in split(variables.distros, ',') }}:
|
||||
- stage: galaxy_${{ replace(distro, '-', '_') }}_asible_2_16
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
distro: ${{ distro }}
|
||||
ansible_version: ${{ variables.ansible_version }}
|
||||
skip_git_test: true
|
||||
test_galaxy: true
|
||||
39
infra/azure/pr-pipeline.yml
Normal file
39
infra/azure/pr-pipeline.yml
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
trigger:
|
||||
- master
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-20.04'
|
||||
|
||||
variables:
|
||||
distros: "fedora-latest,c9s,c8s,fedora-rawhide"
|
||||
ansible_version: "-core >=2.15,<2.16"
|
||||
|
||||
stages:
|
||||
|
||||
# Test with repository in all distros
|
||||
|
||||
- ${{ each distro in split(variables.distros, ',') }}:
|
||||
- stage: ${{ replace(distro, '-', '_') }}_ansible_2_16
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/run_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
distro: ${{ distro }}
|
||||
ansible_version: ${{ variables.ansible_version }}
|
||||
skip_git_test: false
|
||||
test_galaxy: false
|
||||
|
||||
# Galaxy on Fedora
|
||||
|
||||
- stage: galaxy_fedora_latest_ansible_2_16
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/run_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
distro: fedora-latest
|
||||
ansible_version: ${{ variables.ansible_version }}
|
||||
skip_git_test: false
|
||||
test_galaxy: true
|
||||
@@ -159,7 +159,7 @@ def map_test_module_sources(base):
|
||||
"""Create a map of 'test-modules' to 'plugin-sources', from 'base'."""
|
||||
# Find root directory of playbook tests.
|
||||
script_dir = os.path.dirname(__file__)
|
||||
test_root = os.path.realpath(os.path.join(script_dir, f"../{base}"))
|
||||
test_root = os.path.realpath(os.path.join(script_dir, f"../../../{base}"))
|
||||
# create modules:source_files map
|
||||
_result = {}
|
||||
for test_module in [d for d in os.scandir(test_root) if d.is_dir()]:
|
||||
@@ -170,7 +170,7 @@ def map_test_module_sources(base):
|
||||
|
||||
|
||||
def usage(err=0):
|
||||
print("filter_plugins.py [-h|--help] [-p|--pytest] PY_SRC...")
|
||||
print("get_test_modules.py [-h|--help] [-p|--pytest] PY_SRC...")
|
||||
print(
|
||||
"""
|
||||
Print a comma-separated list of modules that should be tested if
|
||||
67
infra/azure/scripts/set_test_modules
Normal file
67
infra/azure/scripts/set_test_modules
Normal file
@@ -0,0 +1,67 @@
|
||||
#!/bin/bash -eu
|
||||
# This file shoud be source'd (. set_test_modules) rather than executed.
|
||||
#
|
||||
# Set SKIP_GIT_TEST="True" or use -a to prevent git modification comparison.
|
||||
#
|
||||
|
||||
RED="\033[31;1m"
|
||||
RST="\033[0m"
|
||||
|
||||
die() {
|
||||
echo -e "${RED}${*}${RST}" >&2
|
||||
}
|
||||
|
||||
BASEDIR="$(readlink -f "$(dirname "${BASH_SOURCE[0]}")")"
|
||||
TOPDIR="$(readlink -f "${BASEDIR}/../../..")"
|
||||
|
||||
[ -n "$(command -v python3)" ] && python="$(command -v python3)" || python="$(command -v python2)"
|
||||
|
||||
pushd "${TOPDIR}" >/dev/null 2>&1 || die "Failed to change directory."
|
||||
|
||||
SKIP_GIT_TEST=${SKIP_GIT_TEST:-"False"}
|
||||
|
||||
while getopts ":a" opt
|
||||
do
|
||||
case "${opt}" in
|
||||
a) SKIP_GIT_TEST="True" ;;
|
||||
*) ;; # ignore other options
|
||||
esac
|
||||
done
|
||||
|
||||
files_list=$(mktemp)
|
||||
|
||||
enabled_modules="None"
|
||||
enabled_tests="None"
|
||||
|
||||
if [ "${SKIP_GIT_TEST}" != "True" ]
|
||||
then
|
||||
remote="$(basename "$(mktemp -u remote_XXXXXX)")"
|
||||
git remote add "${remote}" https://github.com/freeipa/ansible-freeipa
|
||||
git fetch --prune --no-tags --quiet "${remote}"
|
||||
git diff "${remote}/master" --name-only > "${files_list}"
|
||||
git remote remove "${remote}"
|
||||
|
||||
# shellcheck disable=SC2046
|
||||
enabled_modules="$(${python} "${BASEDIR}/get_test_modules.py" $(cat "${files_list}"))"
|
||||
[ -z "${enabled_modules}" ] && enabled_modules="None"
|
||||
|
||||
# Get individual tests that should be executed
|
||||
mapfile -t tests < <(sed -n 's#.*/\(test_[^/]*\).yml#\1#p' "${files_list}" | tr -d " ")
|
||||
[ ${#tests[@]} -gt 0 ] && enabled_tests=$(IFS=, ; echo "${tests[*]}")
|
||||
[ -z "${enabled_tests}" ] && enabled_tests="None"
|
||||
|
||||
[ -n "${enabled_tests}" ] && IPA_ENABLED_TESTS="${enabled_tests},${IPA_ENABLED_TESTS}"
|
||||
[ -n "${enabled_modules}" ] && IPA_ENABLED_MODULES="${enabled_modules},${IPA_ENABLED_MODULES}"
|
||||
|
||||
rm -f "${files_list}"
|
||||
fi
|
||||
|
||||
# Get all modules that should have tests executed
|
||||
|
||||
export IPA_ENABLED_MODULES
|
||||
export IPA_ENABLED_TESTS
|
||||
|
||||
echo "IPA_ENABLED_MODULES = [${IPA_ENABLED_MODULES}]"
|
||||
echo "IPA_ENABLED_TESTS = [${IPA_ENABLED_TESTS}]"
|
||||
|
||||
popd >/dev/null 2>&1 || die "Failed to change back to original directory."
|
||||
45
infra/azure/templates/build_container.yml
Normal file
45
infra/azure/templates/build_container.yml
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
parameters:
|
||||
- name: distro
|
||||
type: string
|
||||
- name: python_version
|
||||
type: string
|
||||
default: 3.x
|
||||
- name: ansible_core_version
|
||||
default: ""
|
||||
|
||||
jobs:
|
||||
- job: BuildTestImage_${{ join('_', split(parameters.distro, '-')) }}
|
||||
displayName: Build ${{ parameters.distro }} test container
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: '${{ parameters.python_version }}'
|
||||
|
||||
- script: python -m pip install --upgrade pip "ansible-core${{ parameters.ansible_core_version }}"
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Install tools
|
||||
|
||||
- script: ansible-galaxy collection install containers.podman
|
||||
displayName: Install Ansible Galaxy collections
|
||||
|
||||
- script: infra/image/build.sh -p -s ${{ parameters.distro }}
|
||||
displayName: Build ${{ parameters.distro }} base image
|
||||
env:
|
||||
ANSIBLE_ROLES_PATH: "${PWD}/roles"
|
||||
ANSIBLE_LIBRARY: "${PWD}/plugins/modules"
|
||||
ANSIBLE_MODULE_UTILS: "${PWD}/plugins/module_utils"
|
||||
|
||||
- script: podman login -u="$QUAY_ROBOT_USERNAME" -p="$QUAY_ROBOT_TOKEN" quay.io
|
||||
displayName: Registry login
|
||||
env:
|
||||
# Secrets needs to be mapped as env vars to work properly
|
||||
QUAY_ROBOT_TOKEN: $(QUAY_ROBOT_TOKEN)
|
||||
|
||||
- script: |
|
||||
podman push quay.io/ansible-freeipa/upstream-tests:${{parameters.distro}}-base quay.io/ansible-freeipa/upstream-tests:${{ parameters.distro }}-base
|
||||
displayName: Push base image
|
||||
|
||||
- script: |
|
||||
podman push quay.io/ansible-freeipa/upstream-tests:${{ parameters.distro }}-server quay.io/ansible-freeipa/upstream-tests:${{ parameters.distro }}-server
|
||||
displayName: Push server image
|
||||
30
infra/azure/templates/group_tests.yml
Normal file
30
infra/azure/templates/group_tests.yml
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
parameters:
|
||||
- name: distro
|
||||
type: string
|
||||
default: fedora-latest
|
||||
- name: build_number
|
||||
type: string
|
||||
- name: ansible_version
|
||||
type: string
|
||||
default: ""
|
||||
- name: skip_git_test
|
||||
type: boolean
|
||||
default: false
|
||||
- name: test_galaxy
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
jobs:
|
||||
|
||||
- ${{ each group in split('1,2,3', ',') }}:
|
||||
- template: run_tests.yml
|
||||
parameters:
|
||||
group_number: ${{ group }}
|
||||
number_of_groups: 3
|
||||
build_number: ${{ parameters.build_number }}
|
||||
distro: ${{ parameters.distro }}
|
||||
ansible_version: ${{ parameters.ansible_version }}
|
||||
python_version: '< 3.12'
|
||||
skip_git_test: ${{ parameters.skip_git_test }}
|
||||
test_galaxy: ${{ parameters.test_galaxy }}
|
||||
30
infra/azure/templates/prepare_environment.yaml
Normal file
30
infra/azure/templates/prepare_environment.yaml
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
parameters:
|
||||
- name: distro
|
||||
type: string
|
||||
default: fedora-latest
|
||||
- name: ansible_version
|
||||
type: string
|
||||
default: ""
|
||||
- name: python_version
|
||||
type: string
|
||||
default: 3.x
|
||||
- name: build_number
|
||||
type: string
|
||||
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: '${{ parameters.python_version }}'
|
||||
|
||||
- script: |
|
||||
pip install "ansible${{ parameters.ansible_version }}" -r requirements-tests.txt
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Install test dependencies
|
||||
|
||||
- script: ansible-galaxy collection install -r requirements-podman.yml
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Install Ansible collections
|
||||
|
||||
- script: infra/image/start.sh ${{ parameters.distro }}-server
|
||||
displayName: Setup target container for ${{ parameters.distro }}
|
||||
98
infra/azure/templates/run_tests.yml
Normal file
98
infra/azure/templates/run_tests.yml
Normal file
@@ -0,0 +1,98 @@
|
||||
---
|
||||
parameters:
|
||||
- name: group_number
|
||||
type: number
|
||||
default: 1
|
||||
- name: number_of_groups
|
||||
type: number
|
||||
default: 1
|
||||
- name: distro
|
||||
type: string
|
||||
default: fedora-latest
|
||||
- name: ansible_version
|
||||
type: string
|
||||
default: ""
|
||||
- name: python_version
|
||||
type: string
|
||||
default: 3.x
|
||||
- name: build_number
|
||||
type: string
|
||||
- name: skip_git_test
|
||||
type: boolean
|
||||
default: true
|
||||
- name: test_type
|
||||
type: string
|
||||
default: "playbook"
|
||||
- name: test_galaxy
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
jobs:
|
||||
- job: Test_Group${{ parameters.group_number }}
|
||||
displayName: Run playbook tests ${{ parameters.distro }} (${{ parameters.group_number }}/${{ parameters.number_of_groups }})
|
||||
timeoutInMinutes: 360
|
||||
variables:
|
||||
- template: variables.yaml
|
||||
- template: variables_${{ parameters.distro }}.yaml
|
||||
steps:
|
||||
- template: prepare_environment.yaml
|
||||
parameters:
|
||||
build_number: ${{ parameters.build_number }}
|
||||
distro: ${{ parameters.distro }}
|
||||
ansible_version: ${{ parameters.ansible_version }}
|
||||
python_version: ${{ parameters.python_version }}
|
||||
|
||||
- bash: echo "##vso[task.setvariable variable=TOPDIR]${PWD}"
|
||||
displayName: Set repo rootdir
|
||||
|
||||
- script: |
|
||||
. "${TOPDIR}/infra/azure/scripts/set_test_modules"
|
||||
python3 utils/check_test_configuration.py ${{ parameters.distro }}
|
||||
displayName: Check test configuration
|
||||
env:
|
||||
SKIP_GIT_TEST: ${{ parameters.skip_git_test }}
|
||||
|
||||
- script: |
|
||||
git fetch --unshallow
|
||||
utils/build-galaxy-release.sh -i
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Build Galaxy release
|
||||
condition: ${{ parameters.test_galaxy }}
|
||||
|
||||
- script: |
|
||||
echo "PWD: ${PWD}"
|
||||
echo "TOPDIR: ${TOPDIR}"
|
||||
echo "ROLES: ${ANSIBLE_ROLES_PATH}"
|
||||
echo "LIBRARY: ${ANSIBLE_LIBRARY}"
|
||||
echo "MODULE_UTILS: ${ANSIBLE_MODULE_UTILS}"
|
||||
. "${TOPDIR}/infra/azure/scripts/set_test_modules"
|
||||
[ "${{ parameters.test_galaxy }}" == "True" ] && cd ~/.ansible/collections/ansible_collections/freeipa/ansible_freeipa
|
||||
pytest \
|
||||
-m "${{ parameters.test_type }}" \
|
||||
--verbose \
|
||||
--color=yes \
|
||||
--splits=${{ parameters.number_of_groups }} \
|
||||
--group=${{ parameters.group_number }} \
|
||||
--randomly-seed=$(date "+%Y%m%d") \
|
||||
--suppress-no-test-exit-code \
|
||||
--junit-xml=TEST-results-pr-check.xml
|
||||
displayName: Run playbook tests
|
||||
env:
|
||||
SKIP_GIT_TEST: ${{ parameters.skip_git_test }}
|
||||
${{ if not(parameters.test_galaxy) }}:
|
||||
ANSIBLE_ROLES_PATH: "${PWD}/roles"
|
||||
ANSIBLE_LIBRARY: "${PWD}/plugins"
|
||||
ANSIBLE_MODULE_UTILS: "${PWD}/plugins/module_utils"
|
||||
IPA_SERVER_HOST: ansible-freeipa-tests
|
||||
RUN_TESTS_IN_DOCKER: podman
|
||||
IPA_DISABLED_MODULES: ${{ variables.ipa_disabled_modules }}
|
||||
IPA_DISABLED_TESTS: ${{ variables.ipa_disabled_tests }}
|
||||
IPA_ENABLED_MODULES: ${{ variables.ipa_enabled_modules }}
|
||||
IPA_ENABLED_TESTS: ${{ variables.ipa_enabled_tests }}
|
||||
IPA_VERBOSITY: "-vvv"
|
||||
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
mergeTestResults: true
|
||||
testRunTitle: PlaybookTests-Build${{ parameters.build_number }}
|
||||
condition: succeededOrFailed()
|
||||
15
infra/image/build-inventory
Normal file
15
infra/image/build-inventory
Normal file
@@ -0,0 +1,15 @@
|
||||
[ipaserver]
|
||||
ansible-freeipa-image-builder ansible_connection=podman
|
||||
|
||||
[ipaserver:vars]
|
||||
ipaadmin_password=SomeADMINpassword
|
||||
ipadm_password=SomeDMpassword
|
||||
ipaserver_domain=test.local
|
||||
ipaserver_realm=TEST.LOCAL
|
||||
ipaserver_setup_dns=true
|
||||
ipaserver_auto_forwarders=true
|
||||
ipaserver_no_dnssec_validation=true
|
||||
ipaserver_auto_reverse=true
|
||||
ipaserver_setup_kra=true
|
||||
ipaserver_setup_firewalld=false
|
||||
ipaclient_no_ntp=true
|
||||
135
infra/image/build.sh
Executable file
135
infra/image/build.sh
Executable file
@@ -0,0 +1,135 @@
|
||||
#!/bin/bash -eu
|
||||
|
||||
BASEDIR="$(readlink -f "$(dirname "$0")")"
|
||||
TOPDIR="$(readlink -f "${BASEDIR}/../..")"
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
. "${BASEDIR}/shcontainer"
|
||||
# shellcheck disable=SC1091
|
||||
. "${TOPDIR}/utils/shfun"
|
||||
|
||||
valid_distro() {
|
||||
find "${BASEDIR}/dockerfile" -type f -printf "%f\n" | tr "\n" " "
|
||||
}
|
||||
|
||||
usage() {
|
||||
local prog="${0##*/}"
|
||||
cat << EOF
|
||||
usage: ${prog} [-h] [-p] [-n HOSTNAME] [-s] distro
|
||||
${prog} build a container image to test ansible-freeipa.
|
||||
EOF
|
||||
}
|
||||
|
||||
help() {
|
||||
cat << EOF
|
||||
positional arguments:
|
||||
|
||||
distro The base distro to build the test container.
|
||||
Availble distros: $(valid_distro)
|
||||
|
||||
optional arguments:
|
||||
|
||||
-n HOSTNAME Container hostname
|
||||
-p Give extended privileges to the container
|
||||
-s Deploy IPA server
|
||||
EOF
|
||||
}
|
||||
|
||||
name="ansible-freeipa-image-builder"
|
||||
hostname="ipaserver.test.local"
|
||||
cpus="2"
|
||||
memory="3g"
|
||||
quayname="quay.io/ansible-freeipa/upstream-tests"
|
||||
deploy_server="N"
|
||||
privileged=""
|
||||
|
||||
while getopts ":hn:ps" option
|
||||
do
|
||||
case "${option}" in
|
||||
h) help && exit 0 ;;
|
||||
n) hostname="${OPTARG}" ;;
|
||||
p) privileged="privileged" ;;
|
||||
s) deploy_server="Y" ;;
|
||||
*) die -u "Invalid option: ${option}" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift $((OPTIND - 1))
|
||||
distro=${1:-}
|
||||
|
||||
[ -n "${distro}" ] || die "Distro needs to be given.\nUse one of: $(valid_distro)"
|
||||
|
||||
[ -f "${BASEDIR}/dockerfile/${distro}" ] \
|
||||
|| die "${distro} is not a valid distro target.\nUse one of: $(valid_distro)"
|
||||
|
||||
container_check
|
||||
|
||||
if [ "${deploy_server}" == "Y" ]
|
||||
then
|
||||
[ -n "$(command -v "ansible-playbook")" ] || die "ansible-playbook is required to install FreeIPA."
|
||||
|
||||
deploy_playbook="${TOPDIR}/playbooks/install-server.yml"
|
||||
[ -f "${deploy_playbook}" ] || die "Can't find playbook '${deploy_playbook}'"
|
||||
|
||||
inventory_file="${BASEDIR}/build-inventory"
|
||||
[ -f "${inventory_file}" ] || die "Can't find inventory '${inventory_file}'"
|
||||
fi
|
||||
|
||||
container_state=$(container_get_state "${name}")
|
||||
|
||||
tag="${distro}-base"
|
||||
server_tag="${distro}-server"
|
||||
|
||||
container_remove_image_if_exists "${tag}"
|
||||
[ "${deploy_server}" == "Y" ] && \
|
||||
container_remove_image_if_exists "${server_tag}"
|
||||
|
||||
container_build "${tag}" "${BASEDIR}/dockerfile/${distro}" "${BASEDIR}"
|
||||
container_create "${name}" "${tag}" \
|
||||
"hostname=${hostname}" \
|
||||
"memory=${memory}" \
|
||||
"cpus=${cpus}" \
|
||||
"${privileged}"
|
||||
container_commit "${name}" "${quayname}:${tag}"
|
||||
|
||||
if [ "${deploy_server}" == "Y" ]
|
||||
then
|
||||
deployed=false
|
||||
|
||||
# Set path to ansible-freeipa roles
|
||||
[ -z "${ANSIBLE_ROLES_PATH:-""}" ] && export ANSIBLE_ROLES_PATH="${TOPDIR}/roles"
|
||||
|
||||
# Install collection containers.podman if not available
|
||||
if [ -z "$(ansible-galaxy collection list containers.podman)" ]
|
||||
then
|
||||
tmpdir="$(mktemp -d)"
|
||||
export ANSIBLE_COLLECTIONS_PATH="${tmpdir}"
|
||||
ansible-galaxy collection install -p "${tmpdir}" containers.podman
|
||||
fi
|
||||
|
||||
[ "${container_state}" != "running" ] && container_start "${name}"
|
||||
|
||||
container_wait_for_journald "${name}"
|
||||
|
||||
log info "= Deploying IPA ="
|
||||
if ansible-playbook -u root -i "${inventory_file}" "${deploy_playbook}"
|
||||
then
|
||||
deployed=true
|
||||
fi
|
||||
echo
|
||||
|
||||
if $deployed; then
|
||||
log info "= Enabling services ="
|
||||
container_exec "${name}" systemctl enable fixnet
|
||||
container_exec "${name}" systemctl enable fixipaip
|
||||
echo
|
||||
fi
|
||||
|
||||
container_stop "${name}"
|
||||
|
||||
$deployed || die "Deployment failed"
|
||||
|
||||
container_commit "${name}" "${quayname}:${server_tag}"
|
||||
fi
|
||||
|
||||
log info "= DONE: Image created. ="
|
||||
38
infra/image/dockerfile/c10s
Normal file
38
infra/image/dockerfile/c10s
Normal file
@@ -0,0 +1,38 @@
|
||||
FROM quay.io/centos/centos:stream10-development
|
||||
ENV container=podman
|
||||
|
||||
RUN rm -fv /var/cache/dnf/metadata_lock.pid; \
|
||||
dnf makecache; \
|
||||
dnf --assumeyes install \
|
||||
/usr/bin/dnf-3 \
|
||||
sudo \
|
||||
bash \
|
||||
systemd \
|
||||
procps-ng \
|
||||
iproute; \
|
||||
rm -rf /var/cache/dnf/;
|
||||
|
||||
RUN (cd /lib/systemd/system/; \
|
||||
if [ -e dbus-broker.service ] && [ ! -e dbus.service ]; then \
|
||||
ln -s dbus-broker.service dbus.service; \
|
||||
fi \
|
||||
)
|
||||
COPY system-service/container-ipa.target /lib/systemd/system/
|
||||
RUN systemctl set-default container-ipa.target
|
||||
RUN (cd /etc/systemd/system/; \
|
||||
rm -rf multi-user.target.wants \
|
||||
&& mkdir container-ipa.target.wants \
|
||||
&& ln -s container-ipa.target.wants multi-user.target.wants \
|
||||
)
|
||||
|
||||
COPY system-service/fixnet.sh /root/
|
||||
COPY system-service/fixipaip.sh /root/
|
||||
COPY system-service/fixnet.service /etc/systemd/system/
|
||||
COPY system-service/fixipaip.service /etc/systemd/system/
|
||||
RUN chmod +x /root/fixnet.sh /root/fixipaip.sh
|
||||
|
||||
STOPSIGNAL RTMIN+3
|
||||
|
||||
VOLUME ["/sys/fs/cgroup"]
|
||||
|
||||
CMD ["/usr/sbin/init"]
|
||||
43
infra/image/dockerfile/c8s
Normal file
43
infra/image/dockerfile/c8s
Normal file
@@ -0,0 +1,43 @@
|
||||
FROM quay.io/centos/centos:stream8
|
||||
ENV container=podman
|
||||
|
||||
RUN rm -fv /var/cache/dnf/metadata_lock.pid; \
|
||||
sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo; \
|
||||
sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo; \
|
||||
sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo; \
|
||||
dnf makecache; \
|
||||
dnf --assumeyes install \
|
||||
/usr/bin/dnf-3 \
|
||||
sudo \
|
||||
bash \
|
||||
systemd \
|
||||
procps-ng \
|
||||
iproute; \
|
||||
dnf clean all; \
|
||||
rm -rf /var/cache/dnf/;
|
||||
|
||||
RUN (cd /lib/systemd/system/; \
|
||||
if [ -e dbus-broker.service ] && [ ! -e dbus.service ]; then \
|
||||
ln -s dbus-broker.service dbus.service; \
|
||||
fi \
|
||||
)
|
||||
COPY system-service/container-ipa.target /lib/systemd/system/
|
||||
RUN systemctl set-default container-ipa.target
|
||||
RUN (cd /etc/systemd/system/; \
|
||||
rm -rf multi-user.target.wants \
|
||||
&& mkdir container-ipa.target.wants \
|
||||
&& ln -s container-ipa.target.wants multi-user.target.wants \
|
||||
)
|
||||
|
||||
COPY system-service/fixnet.sh /root/
|
||||
COPY system-service/fixipaip.sh /root/
|
||||
COPY system-service/fixnet.service /etc/systemd/system/
|
||||
COPY system-service/fixipaip.service /etc/systemd/system/
|
||||
RUN chmod +x /root/fixnet.sh /root/fixipaip.sh
|
||||
|
||||
STOPSIGNAL RTMIN+3
|
||||
|
||||
VOLUME ["/sys/fs/cgroup"]
|
||||
|
||||
CMD ["/usr/sbin/init"]
|
||||
|
||||
38
infra/image/dockerfile/c9s
Normal file
38
infra/image/dockerfile/c9s
Normal file
@@ -0,0 +1,38 @@
|
||||
FROM quay.io/centos/centos:stream9
|
||||
ENV container=podman
|
||||
|
||||
RUN rm -fv /var/cache/dnf/metadata_lock.pid; \
|
||||
dnf makecache; \
|
||||
dnf --assumeyes install \
|
||||
/usr/bin/dnf-3 \
|
||||
sudo \
|
||||
bash \
|
||||
systemd \
|
||||
procps-ng \
|
||||
iproute; \
|
||||
rm -rf /var/cache/dnf/;
|
||||
|
||||
RUN (cd /lib/systemd/system/; \
|
||||
if [ -e dbus-broker.service ] && [ ! -e dbus.service ]; then \
|
||||
ln -s dbus-broker.service dbus.service; \
|
||||
fi \
|
||||
)
|
||||
COPY system-service/container-ipa.target /lib/systemd/system/
|
||||
RUN systemctl set-default container-ipa.target
|
||||
RUN (cd /etc/systemd/system/; \
|
||||
rm -rf multi-user.target.wants \
|
||||
&& mkdir container-ipa.target.wants \
|
||||
&& ln -s container-ipa.target.wants multi-user.target.wants \
|
||||
)
|
||||
|
||||
COPY system-service/fixnet.sh /root/
|
||||
COPY system-service/fixipaip.sh /root/
|
||||
COPY system-service/fixnet.service /etc/systemd/system/
|
||||
COPY system-service/fixipaip.service /etc/systemd/system/
|
||||
RUN chmod +x /root/fixnet.sh /root/fixipaip.sh
|
||||
|
||||
STOPSIGNAL RTMIN+3
|
||||
|
||||
VOLUME ["/sys/fs/cgroup"]
|
||||
|
||||
CMD ["/usr/sbin/init"]
|
||||
41
infra/image/dockerfile/fedora-latest
Normal file
41
infra/image/dockerfile/fedora-latest
Normal file
@@ -0,0 +1,41 @@
|
||||
FROM fedora:latest
|
||||
ENV container=podman
|
||||
|
||||
RUN rm -fv /var/cache/dnf/metadata_lock.pid; \
|
||||
dnf makecache; \
|
||||
dnf --assumeyes install \
|
||||
/usr/bin/python3 \
|
||||
/usr/bin/python3-config \
|
||||
python3-libdnf5 \
|
||||
sudo \
|
||||
bash \
|
||||
systemd \
|
||||
procps-ng \
|
||||
iproute; \
|
||||
dnf clean all; \
|
||||
rm -rf /var/cache/dnf/;
|
||||
|
||||
RUN (cd /lib/systemd/system/; \
|
||||
if [ -e dbus-broker.service ] && [ ! -e dbus.service ]; then \
|
||||
ln -s dbus-broker.service dbus.service; \
|
||||
fi \
|
||||
)
|
||||
COPY system-service/container-ipa.target /lib/systemd/system/
|
||||
RUN systemctl set-default container-ipa.target
|
||||
RUN (cd /etc/systemd/system/; \
|
||||
rm -rf multi-user.target.wants \
|
||||
&& mkdir container-ipa.target.wants \
|
||||
&& ln -s container-ipa.target.wants multi-user.target.wants \
|
||||
)
|
||||
|
||||
COPY system-service/fixnet.sh /root/
|
||||
COPY system-service/fixipaip.sh /root/
|
||||
COPY system-service/fixnet.service /etc/systemd/system/
|
||||
COPY system-service/fixipaip.service /etc/systemd/system/
|
||||
RUN chmod +x /root/fixnet.sh /root/fixipaip.sh
|
||||
|
||||
STOPSIGNAL RTMIN+3
|
||||
|
||||
VOLUME ["/sys/fs/cgroup"]
|
||||
|
||||
CMD ["/usr/sbin/init"]
|
||||
41
infra/image/dockerfile/fedora-rawhide
Normal file
41
infra/image/dockerfile/fedora-rawhide
Normal file
@@ -0,0 +1,41 @@
|
||||
FROM fedora:rawhide
|
||||
ENV container=podman
|
||||
|
||||
RUN rm -fv /var/cache/dnf/metadata_lock.pid; \
|
||||
dnf makecache; \
|
||||
dnf --assumeyes install \
|
||||
/usr/bin/python3 \
|
||||
/usr/bin/python3-config \
|
||||
python3-libdnf5 \
|
||||
sudo \
|
||||
bash \
|
||||
systemd \
|
||||
procps-ng \
|
||||
iproute; \
|
||||
dnf clean all; \
|
||||
rm -rf /var/cache/dnf/;
|
||||
|
||||
RUN (cd /lib/systemd/system/; \
|
||||
if [ -e dbus-broker.service ] && [ ! -e dbus.service ]; then \
|
||||
ln -s dbus-broker.service dbus.service; \
|
||||
fi \
|
||||
)
|
||||
COPY system-service/container-ipa.target /lib/systemd/system/
|
||||
RUN systemctl set-default container-ipa.target
|
||||
RUN (cd /etc/systemd/system/; \
|
||||
rm -rf multi-user.target.wants \
|
||||
&& mkdir container-ipa.target.wants \
|
||||
&& ln -s container-ipa.target.wants multi-user.target.wants \
|
||||
)
|
||||
|
||||
COPY system-service/fixnet.sh /root/
|
||||
COPY system-service/fixipaip.sh /root/
|
||||
COPY system-service/fixnet.service /etc/systemd/system/
|
||||
COPY system-service/fixipaip.service /etc/systemd/system/
|
||||
RUN chmod +x /root/fixnet.sh /root/fixipaip.sh
|
||||
|
||||
STOPSIGNAL RTMIN+3
|
||||
|
||||
VOLUME ["/sys/fs/cgroup"]
|
||||
|
||||
CMD ["/usr/sbin/init"]
|
||||
6
infra/image/inventory
Normal file
6
infra/image/inventory
Normal file
@@ -0,0 +1,6 @@
|
||||
[ipaserver]
|
||||
ansible-freeipa-tests ansible_connection=podman
|
||||
|
||||
[ipaserver:vars]
|
||||
ipaadmin_password=SomeADMINpassword
|
||||
ipadm_password=SomeDMpassword
|
||||
177
infra/image/shcontainer
Normal file
177
infra/image/shcontainer
Normal file
@@ -0,0 +1,177 @@
|
||||
#!/bin/bash -eu
|
||||
# This file is meant to be source'd by other scripts
|
||||
|
||||
SCRIPTDIR="$(dirname -- "$(readlink -f "${BASH_SOURCE[0]}")")"
|
||||
TOPDIR="$(readlink -f "${SCRIPTDIR}/../..")"
|
||||
|
||||
. "${TOPDIR}/utils/shfun"
|
||||
|
||||
container_create() {
|
||||
local name=${1}
|
||||
local image=${2}
|
||||
shift 2
|
||||
declare -a extra_opts=()
|
||||
for opt in "$@"
|
||||
do
|
||||
[ -z "${opt}" ] && continue
|
||||
case "${opt}" in
|
||||
hostname=*) extra_opts+=("--${opt}") ;;
|
||||
cpus=*) extra_opts+=("--${opt}") ;;
|
||||
memory=*) extra_opts+=("--${opt}") ;;
|
||||
privileged) extra_opts+=("--${opt}") ;;
|
||||
*) log error "container_create: Invalid option: ${opt}" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# ensure default values are set
|
||||
[[ " ${extra_opts[*]} " =~ " --cpus=" ]] || extra_opts+=("--cpus=2")
|
||||
[[ " ${extra_opts[*]} " =~ " --hostname=" ]] \
|
||||
|| extra_opts+=("--hostname=ipaserver.test.local")
|
||||
|
||||
log info "= Creating ${name} ="
|
||||
podman create \
|
||||
--security-opt label=disable \
|
||||
--network bridge:interface_name=eth0 \
|
||||
--systemd true \
|
||||
--name "${name}" \
|
||||
--memory-swap -1 \
|
||||
--no-hosts \
|
||||
--replace \
|
||||
"${extra_opts[@]}" \
|
||||
"${image}"
|
||||
echo
|
||||
}
|
||||
|
||||
container_start() {
|
||||
local name="${1}"
|
||||
|
||||
log info "= Starting ${name} ="
|
||||
podman start "${name}"
|
||||
echo
|
||||
}
|
||||
|
||||
container_stop() {
|
||||
local name="${1}"
|
||||
|
||||
log info "= Stopping ${name} ="
|
||||
podman stop "${name}"
|
||||
echo
|
||||
}
|
||||
|
||||
container_wait_for_journald() {
|
||||
local name=${1}
|
||||
|
||||
log info "= Waiting till systemd-journald is running ="
|
||||
max=20
|
||||
wait=2
|
||||
count=0
|
||||
while ! podman exec "${name}" ps -x | grep -q "systemd-journald"
|
||||
do
|
||||
if [ $count -ge $max ]; then
|
||||
die "Timeout: systemd-journald is not starting up"
|
||||
fi
|
||||
count=$((count+1))
|
||||
log info "Waiting ${wait} seconds .."
|
||||
sleep ${wait}
|
||||
done
|
||||
log info "done"
|
||||
echo
|
||||
}
|
||||
|
||||
container_wait_up() {
|
||||
local name="${1}"
|
||||
|
||||
log info "= Waiting till all services are started ="
|
||||
max=20
|
||||
wait=15
|
||||
count=0
|
||||
while podman exec "${name}" systemctl list-jobs | \
|
||||
grep -qvi "no jobs running"
|
||||
do
|
||||
if [ $count -ge $max ]; then
|
||||
die "Timeout: Services are not starting up"
|
||||
fi
|
||||
count=$((count+1))
|
||||
log info "Waiting ${wait} seconds .."
|
||||
sleep ${wait}
|
||||
done
|
||||
log info "done"
|
||||
echo
|
||||
}
|
||||
|
||||
container_build() {
|
||||
local tag="${1}"
|
||||
local file="${2}"
|
||||
local dir="${3}"
|
||||
|
||||
log info "= Building ${tag} ="
|
||||
podman build -t "${tag}" -f "${file}" "${dir}"
|
||||
echo
|
||||
}
|
||||
|
||||
container_commit() {
|
||||
local name="${1}"
|
||||
local image="${2}"
|
||||
|
||||
log info "= Committing \"${image}\" ="
|
||||
podman commit "${name}" "${image}"
|
||||
echo
|
||||
}
|
||||
|
||||
container_exec() {
|
||||
local name="${1}"
|
||||
shift 1
|
||||
|
||||
# "@Q" is only needed for the log output, the exec command is properly
|
||||
# working without also for args containing spaces.
|
||||
log info "= Executing \"${*@Q}\" ="
|
||||
podman exec -t "${name}" "${@}"
|
||||
echo
|
||||
}
|
||||
|
||||
container_remove_image_if_exists()
|
||||
{
|
||||
# In older (as in Ubuntu 22.04) podman versions,
|
||||
# 'podman image rm --force' fails if the image
|
||||
# does not exist.
|
||||
local tag_to_remove="${1}"
|
||||
|
||||
if podman image exists "${tag_to_remove}"
|
||||
then
|
||||
log info "= Cleanup ${tag_to_remove} ="
|
||||
podman image rm "${tag_to_remove}" --force
|
||||
echo
|
||||
fi
|
||||
}
|
||||
|
||||
container_get_state()
|
||||
{
|
||||
local name="${1}"
|
||||
|
||||
state=$(podman ps -q --all --format "{{.State}}" --filter "name=${name}")
|
||||
echo "${state}"
|
||||
}
|
||||
|
||||
container_pull() {
|
||||
local source="${1}"
|
||||
|
||||
image=$(podman pull "${source}")
|
||||
echo "${image}"
|
||||
}
|
||||
|
||||
container_image_list() {
|
||||
local source="${1}"
|
||||
|
||||
# Append "$" for an exact match if the source does not end with ":" to
|
||||
# search for the repo only.
|
||||
if [[ ${source} != *: ]]; then
|
||||
source="${source}$"
|
||||
fi
|
||||
image=$(podman image list --format "{{ .Repository }}:{{ .Tag }}" | \
|
||||
grep "^${source}")
|
||||
echo "${image}"
|
||||
}
|
||||
|
||||
container_check() {
|
||||
[ -n "$(command -v "podman")" ] || die "podman is required."
|
||||
}
|
||||
95
infra/image/start.sh
Executable file
95
infra/image/start.sh
Executable file
@@ -0,0 +1,95 @@
|
||||
#!/bin/bash -eu
|
||||
|
||||
BASEDIR="$(readlink -f "$(dirname "$0")")"
|
||||
TOPDIR="$(readlink -f "${BASEDIR}/../..")"
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
. "${BASEDIR}/shcontainer"
|
||||
# shellcheck disable=SC1091
|
||||
. "${TOPDIR}/utils/shfun"
|
||||
|
||||
usage() {
|
||||
local prog="${0##*/}"
|
||||
cat << EOF
|
||||
usage: ${prog} [-h] [-l] [-n HOSTNAME ] image
|
||||
${prog} start a prebuilt ansible-freeipa test container image.
|
||||
EOF
|
||||
}
|
||||
|
||||
help() {
|
||||
cat << EOF
|
||||
positional arguments:
|
||||
|
||||
image The image to start, leave empty to get list of images
|
||||
|
||||
optional arguments:
|
||||
|
||||
-h Show this message
|
||||
-l Try to use local image first, if not found download.
|
||||
-n HOSTNAME Set container hostname
|
||||
|
||||
NOTE:
|
||||
- The hostname must be the same as the hostname of the container
|
||||
when FreeIPA was deployed. Use only if you built the image and
|
||||
defined its hostname.
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
list_images() {
|
||||
local quay_api="https://quay.io/api/v1/repository/ansible-freeipa/upstream-tests/tag"
|
||||
log info "Available images on quay:"
|
||||
curl --silent -L "${quay_api}" | jq '.tags[]|.name' | tr -d '"'| sort | uniq | sed "s/.*/ &/"
|
||||
echo
|
||||
log info "Local images (use -l):"
|
||||
local_image=$(container_image_list "${repo}:")
|
||||
echo "${local_image}" | sed -e "s/.*://" | sed "s/.*/ &/"
|
||||
echo
|
||||
}
|
||||
|
||||
repo="quay.io/ansible-freeipa/upstream-tests"
|
||||
name="ansible-freeipa-tests"
|
||||
hostname="ipaserver.test.local"
|
||||
try_local_first="N"
|
||||
|
||||
while getopts ":hln:" option
|
||||
do
|
||||
case "${option}" in
|
||||
h) help && exit 0 ;;
|
||||
l) try_local_first="Y" ;;
|
||||
n) hostname="${OPTARG}" ;;
|
||||
*) die -u "Invalid option: ${option}" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift $((OPTIND - 1))
|
||||
image=${1:-}
|
||||
|
||||
container_check
|
||||
|
||||
if [ -z "${image}" ]; then
|
||||
list_images
|
||||
exit 0
|
||||
fi
|
||||
|
||||
local_image=
|
||||
if [ "${try_local_first}" == "Y" ]; then
|
||||
log info "= Trying to use local image first ="
|
||||
local_image=$(container_image_list "${repo}:${image}")
|
||||
[ -n "${local_image}" ] && log info "Found ${local_image}"
|
||||
echo
|
||||
fi
|
||||
if [ -z "${local_image}" ]; then
|
||||
log info "= Downloading from quay ="
|
||||
local_image=$(container_pull "${repo}:${image}")
|
||||
echo
|
||||
fi
|
||||
|
||||
[ -z "${local_image}" ] && die "Image '${image}' is not valid"
|
||||
|
||||
container_create "${name}" "${local_image}" "hostname=${hostname}"
|
||||
container_start "${name}"
|
||||
container_wait_for_journald "${name}"
|
||||
container_wait_up "${name}"
|
||||
|
||||
log info "Container ${name} is ready to be used."
|
||||
6
infra/image/system-service/container-ipa.target
Normal file
6
infra/image/system-service/container-ipa.target
Normal file
@@ -0,0 +1,6 @@
|
||||
[Unit]
|
||||
Description=Minimal target for containerized FreeIPA server
|
||||
DefaultDependencies=false
|
||||
AllowIsolate=yes
|
||||
Requires=systemd-tmpfiles-setup.service systemd-journald.service dbus.service
|
||||
After=systemd-tmpfiles-setup.service systemd-journald.service dbus.service
|
||||
12
infra/image/system-service/fixipaip.service
Normal file
12
infra/image/system-service/fixipaip.service
Normal file
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=Fix IPA server IP in IPA Server
|
||||
After=ipa.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/root/fixipaip.sh
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
85
infra/image/system-service/fixipaip.sh
Executable file
85
infra/image/system-service/fixipaip.sh
Executable file
@@ -0,0 +1,85 @@
|
||||
#!/bin/bash -eu
|
||||
|
||||
function valid_fqdn()
|
||||
{
|
||||
local name="${1}"
|
||||
|
||||
[[ "${name}" =~ [[:space:]] ]] && return 1
|
||||
[[ "${name}" =~ \. ]] || return 1
|
||||
[[ "${name}" =~ \.\. ]] && return 1
|
||||
for i in ${name//./ }; do
|
||||
[[ "${i}" =~ ^[a-z0-9_/]+$ ]] || return 1
|
||||
done
|
||||
[[ "${name}" == "localhost.localdomain" ]] && return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
function valid_ipv4()
|
||||
{
|
||||
local ip="${1}"
|
||||
local rematch="^([0-9]{1,3}\.){3}[0-9]{1,3}$"
|
||||
|
||||
[[ "${ip}" =~ ${rematch} ]] || return 1
|
||||
for i in ${ip//./ }; do
|
||||
[[ ${i} -le 255 ]] || return 1
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
HOSTNAME=$(hostname)
|
||||
IP=$(hostname -I | cut -d " " -f 1)
|
||||
export KRB5CCNAME=ansible_freeipa_cache
|
||||
|
||||
if [ -z "${HOSTNAME}" ] || ! valid_fqdn "${HOSTNAME}" ; then
|
||||
echo "ERROR: Got invalid hostname: '${HOSTNAME}'"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${IP}" ] || ! valid_ipv4 "${IP}" ; then
|
||||
echo "ERROR: Got invalid IPv4 address: '${IP}'"
|
||||
exit 1
|
||||
fi
|
||||
PTR=$(echo "${IP}" | awk -F"." '{print $4}')
|
||||
if [ -z "${PTR}" ] || [ -n "${PTR//[0-9]}" ]; then
|
||||
echo "ERROR: Failed to get PTR from IPv4 address: '${PTR}'"
|
||||
exit 1
|
||||
fi
|
||||
FORWARDER=$(grep -s -m 1 ^nameserver /etc/resolv.conf.fixnet | cut -d" " -f 2)
|
||||
if [ -z "${FORWARDER}" ] || [ "${FORWARDER}" == "127.0.0.1" ]; then
|
||||
FORWARDER="8.8.8.8"
|
||||
fi
|
||||
|
||||
echo "Fix IPA:"
|
||||
echo " HOSTNAME: '${HOSTNAME}'"
|
||||
echo " IP: '${IP}'"
|
||||
echo " PTR: '${PTR}'"
|
||||
echo " FORWARDER: '${FORWARDER}'"
|
||||
|
||||
ZONES=$(ipa -e in_server=true dnszone-find --name-from-ip="${HOSTNAME}." \
|
||||
--raw --pkey-only | grep "idnsname:" | awk -F": " '{print $2}')
|
||||
for zone in ${ZONES}; do
|
||||
echo
|
||||
if [[ "${zone}" == *".in-addr.arpa."* ]]; then
|
||||
echo "Fixing reverse zone ${zone}:"
|
||||
OLD_PTR=$(ipa -e in_server=true dnsrecord-find "${zone}" \
|
||||
--ptr-rec="${HOSTNAME}." --raw | grep "idnsname:" | \
|
||||
awk -F": " '{print $2}')
|
||||
if [ -z "${OLD_PTR}" ] || [ -n "${OLD_PTR//[0-9]}" ]; then
|
||||
echo "ERROR: Failed to get old PTR from '${zone}': '${OLD_PTR}'"
|
||||
else
|
||||
ipa -e in_server=true dnsrecord-mod "${zone}" "${OLD_PTR}" \
|
||||
--ptr-rec="${HOSTNAME}." --rename="${PTR}" || true
|
||||
fi
|
||||
else
|
||||
echo "Fixing forward zone ${zone}:"
|
||||
ipa -e in_server=true dnsrecord-mod test.local "${HOSTNAME%%.*}" \
|
||||
--a-rec="$IP" || true
|
||||
ipa -e in_server=true dnsrecord-mod test.local ipa-ca \
|
||||
--a-rec="$IP" || true
|
||||
fi
|
||||
done
|
||||
|
||||
ipa -e in_server=true dnsserver-mod "${HOSTNAME}" \
|
||||
--forwarder="${FORWARDER}" || true
|
||||
|
||||
exit 0
|
||||
14
infra/image/system-service/fixnet.service
Normal file
14
infra/image/system-service/fixnet.service
Normal file
@@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Fix server IP in IPA Server
|
||||
Wants=network.target
|
||||
After=network.target
|
||||
Before=ipa.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/root/fixnet.sh
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=ipa.service
|
||||
66
infra/image/system-service/fixnet.sh
Executable file
66
infra/image/system-service/fixnet.sh
Executable file
@@ -0,0 +1,66 @@
|
||||
#!/bin/bash -eu
|
||||
|
||||
function valid_fqdn()
|
||||
{
|
||||
local name="${1}"
|
||||
|
||||
[[ "${name}" =~ [[:space:]] ]] && return 1
|
||||
[[ "${name}" =~ \. ]] || return 1
|
||||
[[ "${name}" =~ \.\. ]] && return 1
|
||||
for i in ${name//./ }; do
|
||||
[[ "${i}" =~ ^[a-z0-9_/]+$ ]] || return 1
|
||||
done
|
||||
[[ "${name}" == "localhost.localdomain" ]] && return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
function valid_ipv4()
|
||||
{
|
||||
local ip="${1}"
|
||||
local rematch="^([0-9]{1,3}\.){3}[0-9]{1,3}$"
|
||||
|
||||
[[ "${ip}" =~ ${rematch} ]] || return 1
|
||||
for i in ${ip//./ }; do
|
||||
[[ ${i} -le 255 ]] || return 1
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
HOSTNAME=$(hostname)
|
||||
IP=$(hostname -I | cut -d " " -f 1)
|
||||
|
||||
if [ -z "${HOSTNAME}" ] || ! valid_fqdn "${HOSTNAME}" ; then
|
||||
echo "ERROR: Failed to retrieve hostname."
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "${IP}" ] || ! valid_ipv4 "${IP}" ; then
|
||||
echo "ERROR: Got invalid IPv4 address: '${IP}'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Fix NET:"
|
||||
echo " HOSTNAME: '${HOSTNAME}'"
|
||||
echo " IP: '${IP}'"
|
||||
echo
|
||||
|
||||
if grep -qE "^[^(#\s*)][0-9\.]+\s$HOSTNAME(\s|$)" /etc/hosts
|
||||
then
|
||||
sed -i.bak -e "s/.*${HOSTNAME}/${IP}\t${HOSTNAME}/" /etc/hosts
|
||||
else
|
||||
echo -e "$IP\t${HOSTNAME} ${HOSTNAME%%.*}" >> /etc/hosts
|
||||
fi
|
||||
|
||||
cp -a /etc/resolv.conf /etc/resolv.conf.fixnet
|
||||
cat > /etc/resolv.conf <<EOF
|
||||
search ${HOSTNAME#*.}
|
||||
nameserver 127.0.0.1
|
||||
EOF
|
||||
|
||||
echo "/etc/hosts:"
|
||||
cat "/etc/hosts"
|
||||
echo
|
||||
echo "/etc/resolv.conf:"
|
||||
cat "/etc/resolv.conf"
|
||||
|
||||
exit 0
|
||||
@@ -1,30 +0,0 @@
|
||||
FROM quay.io/centos/centos:stream8
|
||||
ENV container=docker
|
||||
|
||||
RUN rm -fv /var/cache/dnf/metadata_lock.pid; \
|
||||
dnf makecache; \
|
||||
dnf --assumeyes install \
|
||||
/usr/bin/python3 \
|
||||
/usr/bin/python3-config \
|
||||
/usr/bin/dnf-3 \
|
||||
sudo \
|
||||
bash \
|
||||
systemd \
|
||||
procps-ng \
|
||||
iproute && \
|
||||
dnf clean all; \
|
||||
(cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
|
||||
rm -f /lib/systemd/system/multi-user.target.wants/*;\
|
||||
rm -f /etc/systemd/system/*.wants/*;\
|
||||
rm -f /lib/systemd/system/local-fs.target.wants/*; \
|
||||
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
|
||||
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
|
||||
rm -f /lib/systemd/system/basic.target.wants/*;\
|
||||
rm -f /lib/systemd/system/anaconda.target.wants/*; \
|
||||
rm -rf /var/cache/dnf/;
|
||||
|
||||
STOPSIGNAL RTMIN+3
|
||||
|
||||
VOLUME ["/sys/fs/cgroup"]
|
||||
|
||||
CMD ["/usr/sbin/init"]
|
||||
@@ -1,19 +0,0 @@
|
||||
---
|
||||
driver:
|
||||
name: docker
|
||||
platforms:
|
||||
- name: c8s-build
|
||||
image: "quay.io/centos/centos:stream8"
|
||||
dockerfile: Dockerfile
|
||||
hostname: ipaserver.test.local
|
||||
dns_servers:
|
||||
- 8.8.8.8
|
||||
volumes:
|
||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
||||
command: /usr/sbin/init
|
||||
privileged: true
|
||||
provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
prepare: ../resources/playbooks/prepare-build.yml
|
||||
prerun: false
|
||||
@@ -1,19 +0,0 @@
|
||||
---
|
||||
driver:
|
||||
name: docker
|
||||
platforms:
|
||||
- name: c8s
|
||||
image: quay.io/ansible-freeipa/upstream-tests:c8s
|
||||
pre_build_image: true
|
||||
hostname: ipaserver.test.local
|
||||
dns_servers:
|
||||
- 127.0.0.1
|
||||
volumes:
|
||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
||||
command: /usr/sbin/init
|
||||
privileged: true
|
||||
provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
prepare: ../resources/playbooks/prepare.yml
|
||||
prerun: false
|
||||
@@ -1,29 +0,0 @@
|
||||
FROM quay.io/centos/centos:stream9
|
||||
ENV container=docker
|
||||
|
||||
RUN rm -fv /var/cache/dnf/metadata_lock.pid; \
|
||||
dnf makecache; \
|
||||
dnf --assumeyes install \
|
||||
/usr/bin/python3 \
|
||||
/usr/bin/dnf-3 \
|
||||
sudo \
|
||||
bash \
|
||||
systemd \
|
||||
procps-ng \
|
||||
iproute && \
|
||||
dnf clean all; \
|
||||
(cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
|
||||
rm -f /lib/systemd/system/multi-user.target.wants/*;\
|
||||
rm -f /etc/systemd/system/*.wants/*;\
|
||||
rm -f /lib/systemd/system/local-fs.target.wants/*; \
|
||||
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
|
||||
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
|
||||
rm -f /lib/systemd/system/basic.target.wants/*;\
|
||||
rm -f /lib/systemd/system/anaconda.target.wants/*; \
|
||||
rm -rf /var/cache/dnf/;
|
||||
|
||||
STOPSIGNAL RTMIN+3
|
||||
|
||||
VOLUME ["/sys/fs/cgroup"]
|
||||
|
||||
CMD ["/usr/sbin/init"]
|
||||
@@ -1,19 +0,0 @@
|
||||
---
|
||||
driver:
|
||||
name: docker
|
||||
platforms:
|
||||
- name: c9s-build
|
||||
image: "quay.io/centos/centos:stream9"
|
||||
dockerfile: Dockerfile
|
||||
hostname: ipaserver.test.local
|
||||
dns_servers:
|
||||
- 8.8.8.8
|
||||
volumes:
|
||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
||||
command: /usr/sbin/init
|
||||
privileged: true
|
||||
provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
prepare: ../resources/playbooks/prepare-build.yml
|
||||
prerun: false
|
||||
@@ -1,19 +0,0 @@
|
||||
---
|
||||
driver:
|
||||
name: docker
|
||||
platforms:
|
||||
- name: c9s
|
||||
image: quay.io/ansible-freeipa/upstream-tests:c9s
|
||||
pre_build_image: true
|
||||
hostname: ipaserver.test.local
|
||||
dns_servers:
|
||||
- 127.0.0.1
|
||||
volumes:
|
||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
||||
command: /usr/sbin/init
|
||||
privileged: true
|
||||
provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
prepare: ../resources/playbooks/prepare.yml
|
||||
prerun: false
|
||||
@@ -1,19 +0,0 @@
|
||||
---
|
||||
driver:
|
||||
name: docker
|
||||
platforms:
|
||||
- name: centos-7-build
|
||||
image: centos/systemd
|
||||
pre_build_image: true
|
||||
hostname: ipaserver.test.local
|
||||
dns_servers:
|
||||
- 8.8.8.8
|
||||
volumes:
|
||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
||||
command: /usr/sbin/init
|
||||
privileged: true
|
||||
provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
prepare: ../resources/playbooks/prepare-build.yml
|
||||
prerun: false
|
||||
@@ -1,19 +0,0 @@
|
||||
---
|
||||
driver:
|
||||
name: docker
|
||||
platforms:
|
||||
- name: centos-7
|
||||
image: quay.io/ansible-freeipa/upstream-tests:centos-7
|
||||
pre_build_image: true
|
||||
hostname: ipaserver.test.local
|
||||
dns_servers:
|
||||
- 127.0.0.1
|
||||
volumes:
|
||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
||||
command: /usr/sbin/init
|
||||
privileged: true
|
||||
provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
prepare: ../resources/playbooks/prepare.yml
|
||||
prerun: false
|
||||
@@ -1 +0,0 @@
|
||||
fedora-latest
|
||||
@@ -1,30 +0,0 @@
|
||||
FROM fedora:latest
|
||||
ENV container=docker
|
||||
|
||||
RUN rm -fv /var/cache/dnf/metadata_lock.pid; \
|
||||
dnf makecache; \
|
||||
dnf --assumeyes install \
|
||||
/usr/bin/python3 \
|
||||
/usr/bin/python3-config \
|
||||
/usr/bin/dnf-3 \
|
||||
sudo \
|
||||
bash \
|
||||
systemd \
|
||||
procps-ng \
|
||||
iproute && \
|
||||
dnf clean all; \
|
||||
(cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
|
||||
rm -f /lib/systemd/system/multi-user.target.wants/*;\
|
||||
rm -f /etc/systemd/system/*.wants/*;\
|
||||
rm -f /lib/systemd/system/local-fs.target.wants/*; \
|
||||
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
|
||||
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
|
||||
rm -f /lib/systemd/system/basic.target.wants/*;\
|
||||
rm -f /lib/systemd/system/anaconda.target.wants/*; \
|
||||
rm -rf /var/cache/dnf/;
|
||||
|
||||
STOPSIGNAL RTMIN+3
|
||||
|
||||
VOLUME ["/sys/fs/cgroup"]
|
||||
|
||||
CMD ["/usr/sbin/init"]
|
||||
@@ -1,19 +0,0 @@
|
||||
---
|
||||
driver:
|
||||
name: docker
|
||||
platforms:
|
||||
- name: fedora-latest-build
|
||||
image: "fedora:latest"
|
||||
dockerfile: Dockerfile
|
||||
hostname: ipaserver.test.local
|
||||
dns_servers:
|
||||
- 8.8.8.8
|
||||
volumes:
|
||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
||||
command: /usr/sbin/init
|
||||
privileged: true
|
||||
provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
prepare: ../resources/playbooks/prepare-build.yml
|
||||
prerun: false
|
||||
@@ -1,19 +0,0 @@
|
||||
---
|
||||
driver:
|
||||
name: docker
|
||||
platforms:
|
||||
- name: fedora-latest
|
||||
image: quay.io/ansible-freeipa/upstream-tests:fedora-latest
|
||||
pre_build_image: true
|
||||
hostname: ipaserver.test.local
|
||||
dns_servers:
|
||||
- 127.0.0.1
|
||||
volumes:
|
||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
||||
command: /usr/sbin/init
|
||||
privileged: true
|
||||
provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
prepare: ../resources/playbooks/prepare.yml
|
||||
prerun: false
|
||||
@@ -1,30 +0,0 @@
|
||||
FROM fedora:rawhide
|
||||
ENV container=docker
|
||||
|
||||
RUN rm -fv /var/cache/dnf/metadata_lock.pid; \
|
||||
dnf makecache; \
|
||||
dnf --assumeyes install \
|
||||
/usr/bin/python3 \
|
||||
/usr/bin/python3-config \
|
||||
/usr/bin/dnf-3 \
|
||||
sudo \
|
||||
bash \
|
||||
systemd \
|
||||
procps-ng \
|
||||
iproute && \
|
||||
dnf clean all; \
|
||||
(cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
|
||||
rm -f /lib/systemd/system/multi-user.target.wants/*;\
|
||||
rm -f /etc/systemd/system/*.wants/*;\
|
||||
rm -f /lib/systemd/system/local-fs.target.wants/*; \
|
||||
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
|
||||
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
|
||||
rm -f /lib/systemd/system/basic.target.wants/*;\
|
||||
rm -f /lib/systemd/system/anaconda.target.wants/*; \
|
||||
rm -rf /var/cache/dnf/;
|
||||
|
||||
STOPSIGNAL RTMIN+3
|
||||
|
||||
VOLUME ["/sys/fs/cgroup"]
|
||||
|
||||
CMD ["/usr/sbin/init"]
|
||||
@@ -1,19 +0,0 @@
|
||||
---
|
||||
driver:
|
||||
name: docker
|
||||
platforms:
|
||||
- name: fedora-rawhide-build
|
||||
image: "fedora:rawhide"
|
||||
dockerfile: Dockerfile
|
||||
hostname: ipaserver.test.local
|
||||
dns_servers:
|
||||
- 8.8.8.8
|
||||
volumes:
|
||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
||||
command: /usr/sbin/init
|
||||
privileged: true
|
||||
provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
prepare: ../resources/playbooks/prepare-build.yml
|
||||
prerun: false
|
||||
@@ -1,19 +0,0 @@
|
||||
---
|
||||
driver:
|
||||
name: docker
|
||||
platforms:
|
||||
- name: fedora-rawhide
|
||||
image: quay.io/ansible-freeipa/upstream-tests:fedora-rawhide
|
||||
pre_build_image: true
|
||||
hostname: ipaserver.test.local
|
||||
dns_servers:
|
||||
- 127.0.0.1
|
||||
volumes:
|
||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
||||
command: /usr/sbin/init
|
||||
privileged: true
|
||||
provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
prepare: ../resources/playbooks/prepare.yml
|
||||
prerun: false
|
||||
@@ -1 +0,0 @@
|
||||
../../../plugins/modules/
|
||||
@@ -1 +0,0 @@
|
||||
../../../plugins/module_utils/
|
||||
@@ -1,28 +0,0 @@
|
||||
---
|
||||
- name: Converge
|
||||
hosts: all
|
||||
tasks:
|
||||
- include_tasks: prepare-common.yml
|
||||
|
||||
- name: Ensure sudo package is installed
|
||||
package:
|
||||
name: sudo
|
||||
|
||||
- name: Ensure nss package is updated
|
||||
package:
|
||||
name: nss
|
||||
state: latest # noqa 403
|
||||
|
||||
- include_role:
|
||||
name: ipaserver
|
||||
vars:
|
||||
ipaserver_setup_dns: yes
|
||||
ipaserver_setup_kra: yes
|
||||
ipaserver_auto_forwarders: yes
|
||||
ipaserver_no_dnssec_validation: yes
|
||||
ipaserver_auto_reverse: yes
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipadm_password: SomeDMpassword
|
||||
ipaserver_domain: test.local
|
||||
ipaserver_realm: TEST.LOCAL
|
||||
ipaclient_no_ntp: yes
|
||||
@@ -1,33 +0,0 @@
|
||||
---
|
||||
# IPA depends on IPv6 and without it dirsrv service won't start.
|
||||
- name: Ensure IPv6 is ENABLED
|
||||
ansible.posix.sysctl:
|
||||
name: "{{ item.name }}"
|
||||
value: "{{ item.value }}"
|
||||
sysctl_set: yes
|
||||
state: present
|
||||
reload: yes
|
||||
with_items:
|
||||
- name: net.ipv6.conf.all.disable_ipv6
|
||||
value: 0
|
||||
- name: net.ipv6.conf.lo.disable_ipv6
|
||||
value: 0
|
||||
- name: net.ipv6.conf.eth0.disable_ipv6
|
||||
value: 1
|
||||
|
||||
# Set fs.protected_regular to 0
|
||||
# This is needed in some IPA versions in order to get KRA enabled.
|
||||
# See https://pagure.io/freeipa/issue/7906 for more information.
|
||||
- name: stat protected_regular
|
||||
ansible.builtin.stat:
|
||||
path: /proc/sys/fs/protected_regular
|
||||
register: result
|
||||
|
||||
- name: Ensure fs.protected_regular is disabled
|
||||
ansible.posix.sysctl:
|
||||
name: fs.protected_regular
|
||||
value: 0
|
||||
sysctl_set: yes
|
||||
state: present
|
||||
reload: yes
|
||||
when: result.stat.exists
|
||||
@@ -1,48 +0,0 @@
|
||||
---
|
||||
- name: Converge
|
||||
hosts: all
|
||||
tasks:
|
||||
- include_tasks: prepare-common.yml
|
||||
|
||||
# In some distros DS won't start up after reboot
|
||||
# This is due to a problem in 389-ds. See tickets:
|
||||
# * https://pagure.io/389-ds-base/issue/47429
|
||||
# * https://pagure.io/389-ds-base/issue/51039
|
||||
#
|
||||
# To avoid this problem we create the directories before starting IPA.
|
||||
- name: Ensure lock dirs for DS exists
|
||||
ansible.builtin.file:
|
||||
state: directory
|
||||
owner: dirsrv
|
||||
group: dirsrv
|
||||
path: "{{ item }}"
|
||||
mode: 0770
|
||||
loop:
|
||||
- /var/lock/dirsrv/
|
||||
- /var/lock/dirsrv/slapd-TEST-LOCAL/
|
||||
|
||||
- name: Ensure IPA server is up an running
|
||||
ansible.builtin.service:
|
||||
name: ipa
|
||||
state: started
|
||||
|
||||
- name: Wait for krb5dkc to be running
|
||||
ansible.builtin.service_facts:
|
||||
no_log: True
|
||||
register: result
|
||||
until: "'krb5kdc.service' in result.ansible_facts.services and \
|
||||
result.ansible_facts.services['krb5kdc.service'].state == 'running'"
|
||||
retries: 30
|
||||
delay: 5
|
||||
|
||||
- name: Check if TGT is available for admin.
|
||||
ansible.builtin.shell:
|
||||
cmd: echo SomeADMINpassword | kinit -c ansible_freeipa_cache admin
|
||||
register: result
|
||||
until: not result.failed
|
||||
retries: 30
|
||||
delay: 5
|
||||
|
||||
- name: Cleanup TGT.
|
||||
ansible.builtin.shell:
|
||||
cmd: kdestroy -c ansible_freeipa_cache -A
|
||||
@@ -1 +0,0 @@
|
||||
../../../roles/
|
||||
@@ -353,7 +353,15 @@ def api_check_ipa_version(oper, requested_version):
|
||||
tasks.parse_ipa_version(requested_version))
|
||||
|
||||
|
||||
def date_format(value):
|
||||
def date_string(value):
|
||||
# Convert datetime to gernalized time format string
|
||||
if not isinstance(value, datetime):
|
||||
raise ValueError("Invalid datetime type '%s'" % repr(value))
|
||||
|
||||
return value.strftime(LDAP_GENERALIZED_TIME_FORMAT)
|
||||
|
||||
|
||||
def convert_date(value):
|
||||
accepted_date_formats = [
|
||||
LDAP_GENERALIZED_TIME_FORMAT, # generalized time
|
||||
'%Y-%m-%dT%H:%M:%SZ', # ISO 8601, second precision
|
||||
@@ -365,7 +373,7 @@ def date_format(value):
|
||||
|
||||
for _date_format in accepted_date_formats:
|
||||
try:
|
||||
return datetime.strptime(value, _date_format)
|
||||
return date_string(datetime.strptime(value, _date_format))
|
||||
except ValueError:
|
||||
pass
|
||||
raise ValueError("Invalid date '%s'" % value)
|
||||
@@ -518,6 +526,10 @@ def module_params_get(module, name, allow_empty_list_item=False):
|
||||
|
||||
def module_params_get_lowercase(module, name, allow_empty_list_item=False):
|
||||
value = module_params_get(module, name, allow_empty_list_item)
|
||||
return convert_param_value_to_lowercase(value)
|
||||
|
||||
|
||||
def convert_param_value_to_lowercase(value):
|
||||
if isinstance(value, list):
|
||||
value = [v.lower() for v in value]
|
||||
if isinstance(value, (str, unicode)):
|
||||
@@ -1576,3 +1588,232 @@ class IPAAnsibleModule(AnsibleModule):
|
||||
ts = time.time()
|
||||
# pylint: disable=super-with-arguments
|
||||
super(IPAAnsibleModule, self).warn("%f %s" % (ts, warning))
|
||||
|
||||
|
||||
class EntryFactory:
|
||||
"""
|
||||
Implement an Entry Factory to extract objects from modules.
|
||||
|
||||
When defining an ansible-freeipa module which allows the setting of
|
||||
multiple objects in a single task, the object parameters can be set
|
||||
as a set of parameters, or as a list of dictionaries with multiple
|
||||
objects.
|
||||
|
||||
The EntryFactory abstracts the extraction of the entry values so
|
||||
that the entries set in a module can be treated as a list of objects
|
||||
independent of the way the objects have been defined (as single object
|
||||
defined by its parameters or as a list).
|
||||
|
||||
Parameters
|
||||
----------
|
||||
ansible_module: The ansible module to be processed.
|
||||
invalid_params: The list of invalid parameters for the current
|
||||
state/action combination.
|
||||
multiname: The name of the list of objects parameters.
|
||||
params: a dict of the entry parameters with its configuration as a
|
||||
dict. The 'convert' configuration is a list of functions to be
|
||||
applied, in order, to the provided value for the paarameter. Any
|
||||
other configuration field is ignored in the current implementation.
|
||||
validate_entry: an optional function to validate the entry values.
|
||||
This function is called after the parameters for the current
|
||||
state/action are checked, and can be used to perform further
|
||||
validation or modification to the entry values. If the entry is
|
||||
not valid, 'fail_json' should be called. The function must return
|
||||
the entry, modified or not. The funcion signature is
|
||||
'def fn(module:IPAAnsibleModule, entry: Entry) -> Entry:'
|
||||
**user_vars: any other keyword argument is passed to the
|
||||
validate_entry callback as user data.
|
||||
|
||||
Example
|
||||
-------
|
||||
def validate_entry(module, entry, mydata):
|
||||
if (something_is_wrong(entry)):
|
||||
module.fail_json(msg=f"Something wrong with {entry.name}")
|
||||
entry.some_field = mydata
|
||||
return entry
|
||||
|
||||
def main():
|
||||
# ...
|
||||
# Create param mapping, all moudle parameters must be
|
||||
# present as keys of this dictionary
|
||||
params = {
|
||||
"name": {},
|
||||
"description": {}
|
||||
"user": {
|
||||
"convert": [convert_param_value_to_lowercase]
|
||||
},
|
||||
"group": {"convert": [convert_param_value_to_lowercase]}
|
||||
}
|
||||
entries = EntryFactory(
|
||||
module, invalid_params, "entries", params,
|
||||
validate_entry=validate_entry,
|
||||
mydata=1234
|
||||
)
|
||||
#...
|
||||
with module.ipa_connect(context=context):
|
||||
# ...
|
||||
for entry in entries:
|
||||
# process entry and create commands
|
||||
# ...
|
||||
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
ansible_module,
|
||||
invalid_params,
|
||||
multiname,
|
||||
params,
|
||||
validate_entry=None,
|
||||
**user_vars
|
||||
):
|
||||
"""Initialize the Entry Factory."""
|
||||
self.ansible_module = ansible_module
|
||||
self.invalid_params = set(invalid_params)
|
||||
self.multiname = multiname
|
||||
self.params = params
|
||||
self.convert = {
|
||||
param: (config or {}).get("convert", [])
|
||||
for param, config in params.items()
|
||||
}
|
||||
self.validate_entry = validate_entry
|
||||
self.user_vars = user_vars
|
||||
self.__entries = self._get_entries()
|
||||
|
||||
def __iter__(self):
|
||||
"""Initialize factory iterator."""
|
||||
return iter(self.__entries)
|
||||
|
||||
def __next__(self):
|
||||
"""Retrieve next entry."""
|
||||
return next(self.__entries)
|
||||
|
||||
def check_invalid_parameter_usage(self, entry_dict, fail_on_check=True):
|
||||
"""
|
||||
Check if entry_dict parameters are valid for the current state/action.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
entry_dict: A dictionary representing the module parameters.
|
||||
fail_on_check: If set to True wil make the module execution fail
|
||||
if invalid parameters are used.
|
||||
|
||||
Return
|
||||
------
|
||||
If fail_on_check is not True, returns True if the entry parameters
|
||||
are valid and execution should proceed, False otherwise.
|
||||
|
||||
"""
|
||||
state = self.ansible_module.params_get("state")
|
||||
action = self.ansible_module.params_get("action")
|
||||
|
||||
if action is None:
|
||||
msg = "Arguments '{0}' can not be used with state '{1}'"
|
||||
else:
|
||||
msg = "Arguments '{0}' can not be used with action " \
|
||||
"'{2}' and state '{1}'"
|
||||
|
||||
entry_params = set(k for k, v in entry_dict.items() if v is not None)
|
||||
match_invalid = self.invalid_params & entry_params
|
||||
if match_invalid:
|
||||
if fail_on_check:
|
||||
self.ansible_module.fail_json(
|
||||
msg=msg.format(", ".join(match_invalid), state, action))
|
||||
return False
|
||||
|
||||
if not entry_dict.get("name"):
|
||||
if fail_on_check:
|
||||
self.ansible_module.fail_json(msg="Entry 'name' is not set.")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
class Entry:
|
||||
"""Provide an abstraction to handle module entries."""
|
||||
|
||||
def __init__(self, values):
|
||||
"""Initialize entry to be used as dict or object."""
|
||||
self.values = values
|
||||
for key, value in values.items():
|
||||
setattr(self, key, value)
|
||||
|
||||
def copy(self):
|
||||
"""Make a copy of the entry."""
|
||||
return EntryFactory.Entry(self.values.copy())
|
||||
|
||||
def __setitem__(self, item, value):
|
||||
"""Allow entries to be treated as dictionaries."""
|
||||
self.values[item] = value
|
||||
setattr(self, item, value)
|
||||
|
||||
def __getitem__(self, item):
|
||||
"""Allow entries to be treated as dictionaries."""
|
||||
return self.values[item]
|
||||
|
||||
def __setattr__(self, attrname, value):
|
||||
if attrname != "values" and attrname in self.values:
|
||||
self.values[attrname] = value
|
||||
super().__setattr__(attrname, value)
|
||||
|
||||
def __repr__(self):
|
||||
"""Provide a string representation of the stored values."""
|
||||
return repr(self.values)
|
||||
|
||||
def _get_entries(self):
|
||||
"""Retrieve all entries from the module."""
|
||||
def copy_entry_and_set_name(entry, name):
|
||||
_result = entry.copy()
|
||||
_result.name = name
|
||||
return _result
|
||||
|
||||
names = self.ansible_module.params_get("name")
|
||||
if names is not None:
|
||||
if not isinstance(names, list):
|
||||
names = [names]
|
||||
# Get entrie(s) defined by the 'name' parameter.
|
||||
# For most states and modules, 'name' will represent a single
|
||||
# entry, but for some states, like 'absent', it could be a
|
||||
# list of names.
|
||||
_entry = self._extract_entry(
|
||||
self.ansible_module,
|
||||
IPAAnsibleModule.params_get
|
||||
)
|
||||
# copy attribute values if 'name' returns a list
|
||||
_entries = [
|
||||
copy_entry_and_set_name(_entry, _name)
|
||||
for _name in names
|
||||
]
|
||||
else:
|
||||
_entries = [
|
||||
self._extract_entry(data, dict.get)
|
||||
for data in self.ansible_module.params_get(self.multiname)
|
||||
]
|
||||
|
||||
return _entries
|
||||
|
||||
def _extract_entry(self, data, param_get):
|
||||
"""Extract an entry from the given data, using the given method."""
|
||||
def get_entry_param_value(parameter, conversions):
|
||||
_value = param_get(data, parameter)
|
||||
if _value and conversions:
|
||||
for fn in conversions:
|
||||
_value = fn(_value)
|
||||
return _value
|
||||
|
||||
# Build 'parameter: value' mapping for all module parameters
|
||||
_entry = {
|
||||
parameter: get_entry_param_value(parameter, conversions)
|
||||
for parameter, conversions in self.convert.items()
|
||||
}
|
||||
|
||||
# Check if any invalid parameter is used.
|
||||
self.check_invalid_parameter_usage(_entry)
|
||||
|
||||
# Create Entry object
|
||||
_result = EntryFactory.Entry(_entry)
|
||||
# Call entry validation callback, if provided.
|
||||
if self.validate_entry:
|
||||
_result = self.validate_entry(
|
||||
self.ansible_module, _result, **self.user_vars)
|
||||
|
||||
return _result
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -739,10 +739,10 @@ user:
|
||||
|
||||
|
||||
from ansible.module_utils.ansible_freeipa_module import \
|
||||
IPAAnsibleModule, compare_args_ipa, gen_add_del_lists, date_format, \
|
||||
IPAAnsibleModule, compare_args_ipa, gen_add_del_lists, convert_date, \
|
||||
encode_certificate, load_cert_from_str, DN_x500_text, to_text, \
|
||||
ipalib_errors, gen_add_list, gen_intersection_list, \
|
||||
convert_input_certificates
|
||||
convert_input_certificates, date_string
|
||||
from ansible.module_utils import six
|
||||
if six.PY3:
|
||||
unicode = str
|
||||
@@ -758,6 +758,10 @@ def find_user(module, name):
|
||||
except ipalib_errors.NotFound:
|
||||
return None
|
||||
|
||||
# Convert datetime to proper string representation
|
||||
for _expkey in ["krbpasswordexpiration", "krbprincipalexpiration"]:
|
||||
if _expkey in _result:
|
||||
_result[_expkey] = [date_string(x) for x in _result[_expkey]]
|
||||
# Transform each principal to a string
|
||||
_result["krbprincipalname"] = [
|
||||
to_text(x) for x in (_result.get("krbprincipalname") or [])
|
||||
@@ -1172,12 +1176,12 @@ def main():
|
||||
if principalexpiration is not None:
|
||||
if principalexpiration[:-1] != "Z":
|
||||
principalexpiration = principalexpiration + "Z"
|
||||
principalexpiration = date_format(principalexpiration)
|
||||
principalexpiration = convert_date(principalexpiration)
|
||||
passwordexpiration = ansible_module.params_get("passwordexpiration")
|
||||
if passwordexpiration is not None:
|
||||
if passwordexpiration[:-1] != "Z":
|
||||
passwordexpiration = passwordexpiration + "Z"
|
||||
passwordexpiration = date_format(passwordexpiration)
|
||||
passwordexpiration = convert_date(passwordexpiration)
|
||||
password = ansible_module.params_get("password")
|
||||
random = ansible_module.params_get("random")
|
||||
uid = ansible_module.params_get("uid")
|
||||
@@ -1310,12 +1314,12 @@ def main():
|
||||
if principalexpiration is not None:
|
||||
if principalexpiration[:-1] != "Z":
|
||||
principalexpiration = principalexpiration + "Z"
|
||||
principalexpiration = date_format(principalexpiration)
|
||||
principalexpiration = convert_date(principalexpiration)
|
||||
passwordexpiration = user.get("passwordexpiration")
|
||||
if passwordexpiration is not None:
|
||||
if passwordexpiration[:-1] != "Z":
|
||||
passwordexpiration = passwordexpiration + "Z"
|
||||
passwordexpiration = date_format(passwordexpiration)
|
||||
passwordexpiration = convert_date(passwordexpiration)
|
||||
password = user.get("password")
|
||||
random = user.get("random")
|
||||
uid = user.get("uid")
|
||||
|
||||
@@ -5,6 +5,5 @@ flake8==7.0.0
|
||||
flake8-bugbear
|
||||
pylint>=3.2
|
||||
wrapt==1.14.1
|
||||
pydocstyle==6.3.0
|
||||
yamllint==1.35.1
|
||||
ansible-lint>=24.5.0
|
||||
|
||||
10
setup.cfg
10
setup.cfg
@@ -28,10 +28,6 @@ per-file-ignores =
|
||||
plugins/*:E402
|
||||
roles/*:E402
|
||||
|
||||
[pydocstyle]
|
||||
inherit = false
|
||||
ignore = D1,D212,D203
|
||||
|
||||
[pylint.MASTER]
|
||||
disable =
|
||||
consider-using-f-string, # f-string is not supported on Python2
|
||||
@@ -56,7 +52,8 @@ disable =
|
||||
too-many-branches,
|
||||
too-many-locals,
|
||||
fixme,
|
||||
use-dict-literal
|
||||
use-dict-literal,
|
||||
too-many-positional-arguments
|
||||
|
||||
[pylint.BASIC]
|
||||
good-names =
|
||||
@@ -85,6 +82,9 @@ ignored-modules =
|
||||
os,
|
||||
SSSDConfig
|
||||
|
||||
[pylint.DESIGN]
|
||||
max-attributes=12
|
||||
|
||||
[pylint.REFACTORING]
|
||||
max-nested-blocks = 9
|
||||
|
||||
|
||||
@@ -36,6 +36,12 @@ environment variable. For example:
|
||||
IPA_SSH_PASSWORD=<ipaserver_ssh_password> IPA_SERVER_HOST=<ipaserver_host_or_ip> pytest
|
||||
```
|
||||
|
||||
If you want, or need to to set the Python interpreter to use, you must set `IPA_PYTHON_PATH`
|
||||
environment variable. For example:
|
||||
|
||||
```
|
||||
IPA_PYTHON_PATH=/usr/bin/python3.14 IPA_SERVER_HOST=<ipaserver_host_or_ip> pytest
|
||||
```
|
||||
|
||||
To run a single test use the full path with the following format:
|
||||
|
||||
@@ -96,48 +102,16 @@ The pytests are tests that will execute small playbooks and then will verify the
|
||||
To select only these tests on a test execution use the option `-m "not playbook"`.
|
||||
|
||||
|
||||
## Running tests in a docker container
|
||||
## Running tests in a container
|
||||
|
||||
It's also possible to run the tests in a container.
|
||||
|
||||
### Creating a container to run the tests
|
||||
|
||||
Before setting up a container you will need to install molecule framework:
|
||||
|
||||
```
|
||||
pip install molecule-plugins[docker]
|
||||
```
|
||||
|
||||
Now you can start a test container using the following command:
|
||||
```
|
||||
molecule create -s c8s
|
||||
```
|
||||
|
||||
Note: Currently the containers available for running the tests are:
|
||||
* fedora-latest
|
||||
* centos-7
|
||||
* c8s
|
||||
* c9s
|
||||
|
||||
### Running the tests inside the container
|
||||
It's also possible to run the tests in a container. Use the script `infra/image/start.sh` to start a container.
|
||||
|
||||
To run the tests you will use pytest (works the same as for VMs).
|
||||
|
||||
```
|
||||
RUN_TESTS_IN_DOCKER=1 IPA_SERVER_HOST=c8s pytest
|
||||
RUN_TESTS_IN_DOCKER=podman IPA_SERVER_HOST=ansbile-freeipa-tests pytest -m "playbook"
|
||||
```
|
||||
|
||||
### Cleaning up after tests
|
||||
|
||||
After running the tests you should probably destroy the test container using:
|
||||
|
||||
```
|
||||
molecule destroy -s c8s
|
||||
```
|
||||
|
||||
See [Running the tests](#running-the-tests) section for more information on available options.
|
||||
|
||||
|
||||
## Running local tests with upstream CI images
|
||||
|
||||
To run tests locally using the same images used by upstream CI use `utils/run-tests.sh`.
|
||||
@@ -166,8 +140,6 @@ By default the tests are executed against the latest version of the Fedora image
|
||||
utils/run-tests.sh -i c9s tests/host/test_host.yml
|
||||
```
|
||||
|
||||
|
||||
## Upcoming/desired improvements:
|
||||
|
||||
* A script to pre-config the complete test environment using virsh.
|
||||
* A test matrix to run tests against different distros in parallel (probably using tox).
|
||||
* A test matrix to run tests against different distros in parallel.
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
---
|
||||
trigger:
|
||||
- master
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-20.04'
|
||||
|
||||
stages:
|
||||
|
||||
# Fedora
|
||||
|
||||
- stage: Fedora_Ansible_Latest
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: fedora-latest
|
||||
ansible_version: "-core"
|
||||
|
||||
# Fedora
|
||||
|
||||
- stage: Fedora_Ansible_min_supported
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: fedora-latest
|
||||
ansible_version: "-core <2.14"
|
||||
|
||||
# Fedora
|
||||
|
||||
- stage: Fedora_Latest
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: fedora-latest
|
||||
ansible_version: "-core >=2.14,<2.15"
|
||||
|
||||
# Galaxy on Fedora
|
||||
|
||||
- stage: Galaxy_Fedora_Latest
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/galaxy_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: fedora-latest
|
||||
ansible_version: "-core >=2.14,<2.15"
|
||||
|
||||
# CentOS 9 Stream
|
||||
|
||||
- stage: CentOS_9_Stream
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: c9s
|
||||
ansible_version: "-core >=2.14,<2.15"
|
||||
|
||||
# CentOS 8 Stream
|
||||
|
||||
- stage: CentOS_8_Stream
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: c8s
|
||||
ansible_version: "-core >=2.14,<2.15"
|
||||
|
||||
# CentOS 7
|
||||
|
||||
- stage: CentOS_7
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: centos-7
|
||||
ansible_version: "-core >=2.14,<2.15"
|
||||
@@ -1,61 +0,0 @@
|
||||
---
|
||||
|
||||
schedules:
|
||||
- cron: "0 0 * * 0"
|
||||
displayName: Weekly Sunday midnight build
|
||||
branches:
|
||||
include:
|
||||
- master
|
||||
always: true
|
||||
|
||||
trigger: none
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-20.04'
|
||||
|
||||
stages:
|
||||
|
||||
- stage: CentOS_7
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/build_container.yml
|
||||
parameters:
|
||||
job_name_suffix: Centos7
|
||||
container_name: centos-7
|
||||
build_scenario_name: centos-7-build
|
||||
|
||||
- stage: CentOS_8_Stream
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/build_container.yml
|
||||
parameters:
|
||||
job_name_suffix: C8S
|
||||
container_name: c8s
|
||||
build_scenario_name: c8s-build
|
||||
|
||||
- stage: CentOS_9_Stream
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/build_container.yml
|
||||
parameters:
|
||||
job_name_suffix: C9S
|
||||
container_name: c9s
|
||||
build_scenario_name: c9s-build
|
||||
|
||||
- stage: Fedora_Latest
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/build_container.yml
|
||||
parameters:
|
||||
job_name_suffix: FedoraLatest
|
||||
container_name: fedora-latest
|
||||
build_scenario_name: fedora-latest-build
|
||||
|
||||
- stage: Fedora_Rawhide
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/build_container.yml
|
||||
parameters:
|
||||
job_name_suffix: FedoraRawhide
|
||||
container_name: fedora-rawhide
|
||||
build_scenario_name: fedora-rawhide-build
|
||||
@@ -1,243 +0,0 @@
|
||||
---
|
||||
schedules:
|
||||
- cron: "0 19 * * *"
|
||||
displayName: Nightly Builds
|
||||
branches:
|
||||
include:
|
||||
- master
|
||||
always: true
|
||||
|
||||
trigger: none
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-20.04'
|
||||
|
||||
stages:
|
||||
|
||||
# Fedora
|
||||
|
||||
- stage: FedoraLatest_Ansible_Core_2_13
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: fedora-latest
|
||||
ansible_version: "-core >=2.13,<2.14"
|
||||
|
||||
- stage: FedoraLatest_Ansible_Core_2_14
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: fedora-latest
|
||||
ansible_version: "-core >=2.14,<2.15"
|
||||
|
||||
- stage: FedoraLatest_Ansible_Core_2_15
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: fedora-latest
|
||||
ansible_version: "-core >=2.15,<2.16"
|
||||
|
||||
- stage: FedoraLatest_Ansible_latest
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: fedora-latest
|
||||
ansible_version: ""
|
||||
|
||||
# Galaxy on Fedora
|
||||
|
||||
- stage: Galaxy_FedoraLatest_Ansible_Core_2_13
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/galaxy_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: fedora-latest
|
||||
ansible_version: "-core >=2.13,<2.14"
|
||||
|
||||
- stage: Galaxy_FedoraLatest_Ansible_Core_2_14
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/galaxy_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: fedora-latest
|
||||
ansible_version: "-core >=2.14,<2.15"
|
||||
|
||||
- stage: Galaxy_FedoraLatest_Ansible_Core_2_15
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/galaxy_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: fedora-latest
|
||||
ansible_version: "-core >=2.15,<2.16"
|
||||
|
||||
- stage: Galaxy_FedoraLatest_Ansible_latest
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/galaxy_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: fedora-latest
|
||||
ansible_version: ""
|
||||
|
||||
# Fedora Rawhide
|
||||
|
||||
- stage: FedoraRawhide_Ansible_Core_2_13
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: fedora-rawhide
|
||||
ansible_version: "-core >=2.13,<2.14"
|
||||
|
||||
- stage: FedoraRawhide_Ansible_Core_2_14
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: fedora-rawhide
|
||||
ansible_version: "-core >=2.14,<2.15"
|
||||
|
||||
- stage: FedoraRawhide_Ansible_Core_2_15
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: fedora-rawhide
|
||||
ansible_version: "-core >=2.15,<2.16"
|
||||
|
||||
- stage: FedoraRawhide_Ansible_latest
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: fedora-rawhide
|
||||
ansible_version: ""
|
||||
|
||||
# CentoOS 9 Stream
|
||||
|
||||
- stage: c9s_Ansible_Core_2_13
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: c9s
|
||||
ansible_version: "-core >=2.13,<2.14"
|
||||
|
||||
- stage: c9s_Ansible_Core_2_14
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: c9s
|
||||
ansible_version: "-core >=2.14,<2.15"
|
||||
|
||||
- stage: c9s_Ansible_Core_2_15
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: c9s
|
||||
ansible_version: "-core >=2.15,<2.16"
|
||||
|
||||
- stage: c9s_Ansible_latest
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: c9s
|
||||
ansible_version: ""
|
||||
|
||||
# CentOS 8 Stream
|
||||
|
||||
- stage: c8s_Ansible_Core_2_13
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: c8s
|
||||
ansible_version: "-core >=2.13,<2.14"
|
||||
|
||||
- stage: c8s_Ansible_Core_2_14
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: c8s
|
||||
ansible_version: "-core >=2.14,<2.15"
|
||||
|
||||
- stage: c8s_Ansible_Core_2_15
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: c8s
|
||||
ansible_version: "-core >=2.15,<2.16"
|
||||
|
||||
- stage: c8s_Ansible_latest
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: c8s
|
||||
ansible_version: ""
|
||||
|
||||
# CentOS 7
|
||||
|
||||
- stage: CentOS7_Ansible_Core_2_13
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: centos-7
|
||||
ansible_version: "-core >=2.13,<2.14"
|
||||
|
||||
- stage: CentOS7_Ansible_Core_2_14
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: centos-7
|
||||
ansible_version: "-core >=2.14,<2.15"
|
||||
|
||||
- stage: CentOS7_Ansible_Core_2_15
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: centos-7
|
||||
ansible_version: "-core >=2.15,<2.16"
|
||||
|
||||
- stage: CentOS7_Ansible_latest
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: centos-7
|
||||
ansible_version: ""
|
||||
@@ -1,74 +0,0 @@
|
||||
---
|
||||
trigger:
|
||||
- master
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-20.04'
|
||||
|
||||
stages:
|
||||
|
||||
# Fedora
|
||||
|
||||
- stage: Fedora_Latest
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/fast_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: fedora-latest
|
||||
ansible_version: "-core >=2.14,<2.15"
|
||||
|
||||
# Galaxy on Fedora
|
||||
|
||||
- stage: Galaxy_Fedora_Latest
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/fast_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: fedora-latest
|
||||
ansible_version: "-core >=2.14,<2.15"
|
||||
|
||||
# CentOS 9 Stream
|
||||
|
||||
- stage: CentOS_9_Stream
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/fast_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: c9s
|
||||
ansible_version: "-core >=2.14,<2.15"
|
||||
|
||||
# CentOS 8 Stream
|
||||
|
||||
- stage: CentOS_8_Stream
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/fast_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: c8s
|
||||
ansible_version: "-core >=2.14,<2.15"
|
||||
|
||||
# CentOS 7
|
||||
|
||||
- stage: CentOS_7
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/fast_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: centos-7
|
||||
ansible_version: "-core >=2.14,<2.15"
|
||||
|
||||
# Rawhide
|
||||
|
||||
- stage: Fedora_Rawhide
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/fast_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
scenario: fedora-rawhide
|
||||
ansible_version: "-core >=2.14,<2.15"
|
||||
@@ -1,43 +0,0 @@
|
||||
---
|
||||
parameters:
|
||||
- name: job_name_suffix
|
||||
type: string
|
||||
- name: container_name
|
||||
type: string
|
||||
- name: build_scenario_name
|
||||
type: string
|
||||
- name: python_version
|
||||
type: string
|
||||
default: 3.x
|
||||
|
||||
jobs:
|
||||
- job: BuildTestImage${{ parameters.job_name_suffix }}
|
||||
displayName: Build ${{ parameters.container_name }} test container
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: '${{ parameters.python_version }}'
|
||||
|
||||
- script: python -m pip install --upgrade pip setuptools wheel ansible
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Install tools
|
||||
|
||||
- script: pip install molecule-plugins[docker] "requests<2.29"
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Install molecule
|
||||
|
||||
- script: molecule create -s ${{ parameters.build_scenario_name }}
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Create test container
|
||||
env:
|
||||
ANSIBLE_LIBRARY: ./molecule
|
||||
|
||||
- script: |
|
||||
docker stop ${{ parameters.build_scenario_name }}
|
||||
docker commit ${{ parameters.build_scenario_name }} quay.io/ansible-freeipa/upstream-tests:${{ parameters.container_name }}
|
||||
docker login -u="$QUAY_ROBOT_USERNAME" -p="$QUAY_ROBOT_TOKEN" quay.io
|
||||
docker push quay.io/ansible-freeipa/upstream-tests:${{ parameters.container_name }}
|
||||
displayName: Save image and upload
|
||||
env:
|
||||
# Secrets needs to be mapped as env vars to work properly
|
||||
QUAY_ROBOT_TOKEN: $(QUAY_ROBOT_TOKEN)
|
||||
@@ -1,27 +0,0 @@
|
||||
---
|
||||
parameters:
|
||||
- name: scenario
|
||||
type: string
|
||||
default: fedora-latest
|
||||
- name: build_number
|
||||
type: string
|
||||
- name: ansible_version
|
||||
type: string
|
||||
default: ""
|
||||
|
||||
jobs:
|
||||
- template: playbook_fast.yml
|
||||
parameters:
|
||||
group_number: 1
|
||||
number_of_groups: 1
|
||||
build_number: ${{ parameters.build_number }}
|
||||
scenario: ${{ parameters.scenario }}
|
||||
ansible_version: ${{ parameters.ansible_version }}
|
||||
python_version: '< 3.12'
|
||||
|
||||
# - template: pytest_tests.yml
|
||||
# parameters:
|
||||
# build_number: ${{ parameters.build_number }}
|
||||
# scenario: ${{ parameters.scenario }}
|
||||
# ansible_version: ${{ parameters.ansible_version }}
|
||||
# python_version: '< 3.12'
|
||||
@@ -1,65 +0,0 @@
|
||||
---
|
||||
parameters:
|
||||
- name: build_number
|
||||
type: string
|
||||
- name: scenario
|
||||
type: string
|
||||
default: fedora-latest
|
||||
- name: ansible_version
|
||||
type: string
|
||||
default: ""
|
||||
- name: python_version
|
||||
type: string
|
||||
default: 3.x
|
||||
|
||||
jobs:
|
||||
- job: Test_PyTests
|
||||
displayName: Run pytests on ${{ parameters.scenario }}
|
||||
timeoutInMinutes: 240
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: '${{ parameters.python_version }}'
|
||||
|
||||
- script: |
|
||||
pip install \
|
||||
"molecule-plugins[docker]" \
|
||||
"requests<2.29" \
|
||||
"ansible${{ parameters.ansible_version }}"
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Install molecule and Ansible
|
||||
|
||||
- script: ansible-galaxy collection install community.docker ansible.posix
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Install Ansible collections
|
||||
|
||||
- script: pip install -r requirements-tests.txt
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Install dependencies
|
||||
|
||||
- script: |
|
||||
utils/build-galaxy-release.sh -i
|
||||
molecule create -s ${{ parameters.scenario }}
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Setup test container
|
||||
env:
|
||||
ANSIBLE_LIBRARY: ./molecule
|
||||
|
||||
- script: |
|
||||
cd ~/.ansible/collections/ansible_collections/freeipa/ansible_freeipa
|
||||
pytest \
|
||||
-m "not playbook" \
|
||||
--verbose \
|
||||
--color=yes \
|
||||
--junit-xml=TEST-results-pytests.xml
|
||||
displayName: Run tests
|
||||
env:
|
||||
IPA_SERVER_HOST: ${{ parameters.scenario }}
|
||||
RUN_TESTS_IN_DOCKER: true
|
||||
IPA_VERBOSITY: "-vvv"
|
||||
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
mergeTestResults: true
|
||||
testRunTitle: PlaybookTests-Build${{ parameters.build_number }}
|
||||
condition: succeededOrFailed()
|
||||
@@ -1,86 +0,0 @@
|
||||
---
|
||||
parameters:
|
||||
- name: group_number
|
||||
type: number
|
||||
default: 1
|
||||
- name: number_of_groups
|
||||
type: number
|
||||
default: 1
|
||||
- name: scenario
|
||||
type: string
|
||||
default: fedora-latest
|
||||
- name: ansible_version
|
||||
type: string
|
||||
default: ""
|
||||
- name: python_version
|
||||
type: string
|
||||
default: 3.x
|
||||
- name: build_number
|
||||
type: string
|
||||
|
||||
|
||||
jobs:
|
||||
- job: Test_Group${{ parameters.group_number }}
|
||||
displayName: Run playbook tests ${{ parameters.scenario }} (${{ parameters.group_number }}/${{ parameters.number_of_groups }})
|
||||
timeoutInMinutes: 240
|
||||
variables:
|
||||
- template: variables.yaml
|
||||
- template: variables_${{ parameters.scenario }}.yaml
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: '${{ parameters.python_version }}'
|
||||
|
||||
- script: |
|
||||
pip install \
|
||||
"molecule-plugins[docker]" \
|
||||
"requests<2.29" \
|
||||
"ansible${{ parameters.ansible_version }}"
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Install molecule and Ansible
|
||||
|
||||
- script: ansible-galaxy collection install community.docker ansible.posix
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Install Ansible collections
|
||||
|
||||
- script: pip install -r requirements-tests.txt
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Install dependencies
|
||||
|
||||
- script: |
|
||||
utils/build-galaxy-release.sh -i
|
||||
molecule create -s ${{ parameters.scenario }}
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Setup test container
|
||||
env:
|
||||
ANSIBLE_LIBRARY: ./molecule
|
||||
|
||||
- script: |
|
||||
python utils/check_test_configuration.py ${{ parameters.scenario }}
|
||||
displayName: Check scenario test configuration
|
||||
|
||||
- script: |
|
||||
cd ~/.ansible/collections/ansible_collections/freeipa/ansible_freeipa
|
||||
pytest \
|
||||
-m "playbook" \
|
||||
--verbose \
|
||||
--color=yes \
|
||||
--splits=${{ parameters.number_of_groups }} \
|
||||
--group=${{ parameters.group_number }} \
|
||||
--randomly-seed=$(date "+%Y%m%d") \
|
||||
--junit-xml=TEST-results-group-${{ parameters.group_number }}.xml
|
||||
displayName: Run playbook tests
|
||||
env:
|
||||
IPA_SERVER_HOST: ${{ parameters.scenario }}
|
||||
RUN_TESTS_IN_DOCKER: true
|
||||
IPA_DISABLED_MODULES: ${{ variables.ipa_disabled_modules }}
|
||||
IPA_DISABLED_TESTS: ${{ variables.ipa_disabled_tests }}
|
||||
IPA_ENABLED_MODULES: ${{ variables.ipa_enabled_modules }}
|
||||
IPA_ENABLED_TESTS: ${{ variables.ipa_enabled_tests }}
|
||||
IPA_VERBOSITY: "-vvv"
|
||||
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
mergeTestResults: true
|
||||
testRunTitle: PlaybookTests-Build${{ parameters.build_number }}
|
||||
condition: succeededOrFailed()
|
||||
@@ -1,46 +0,0 @@
|
||||
---
|
||||
parameters:
|
||||
- name: scenario
|
||||
type: string
|
||||
default: fedora-latest
|
||||
- name: build_number
|
||||
type: string
|
||||
- name: ansible_version
|
||||
type: string
|
||||
default: ""
|
||||
|
||||
jobs:
|
||||
- template: galaxy_script.yml
|
||||
parameters:
|
||||
group_number: 1
|
||||
number_of_groups: 3
|
||||
build_number: ${{ parameters.build_number }}
|
||||
scenario: ${{ parameters.scenario }}
|
||||
ansible_version: ${{ parameters.ansible_version }}
|
||||
python_version: '< 3.12'
|
||||
|
||||
- template: galaxy_script.yml
|
||||
parameters:
|
||||
group_number: 2
|
||||
number_of_groups: 3
|
||||
build_number: ${{ parameters.build_number }}
|
||||
scenario: ${{ parameters.scenario }}
|
||||
ansible_version: ${{ parameters.ansible_version }}
|
||||
python_version: '< 3.12'
|
||||
|
||||
- template: galaxy_script.yml
|
||||
parameters:
|
||||
group_number: 3
|
||||
number_of_groups: 3
|
||||
build_number: ${{ parameters.build_number }}
|
||||
scenario: ${{ parameters.scenario }}
|
||||
ansible_version: ${{ parameters.ansible_version }}
|
||||
python_version: '< 3.12'
|
||||
|
||||
# Temporarily disable due to issues with ansible docker plugin.
|
||||
#- template: galaxy_pytest_script.yml
|
||||
# parameters:
|
||||
# build_number: ${{ parameters.build_number }}
|
||||
# scenario: ${{ parameters.scenario }}
|
||||
# ansible_version: ${{ parameters.ansible_version }}
|
||||
# python_version: '< 3.12'
|
||||
@@ -1,46 +0,0 @@
|
||||
---
|
||||
parameters:
|
||||
- name: scenario
|
||||
type: string
|
||||
default: fedora-latest
|
||||
- name: build_number
|
||||
type: string
|
||||
- name: ansible_version
|
||||
type: string
|
||||
default: ""
|
||||
|
||||
jobs:
|
||||
- template: playbook_tests.yml
|
||||
parameters:
|
||||
group_number: 1
|
||||
number_of_groups: 3
|
||||
build_number: ${{ parameters.build_number }}
|
||||
scenario: ${{ parameters.scenario }}
|
||||
ansible_version: ${{ parameters.ansible_version }}
|
||||
python_version: '< 3.12'
|
||||
|
||||
- template: playbook_tests.yml
|
||||
parameters:
|
||||
group_number: 2
|
||||
number_of_groups: 3
|
||||
build_number: ${{ parameters.build_number }}
|
||||
scenario: ${{ parameters.scenario }}
|
||||
ansible_version: ${{ parameters.ansible_version }}
|
||||
python_version: '< 3.12'
|
||||
|
||||
- template: playbook_tests.yml
|
||||
parameters:
|
||||
group_number: 3
|
||||
number_of_groups: 3
|
||||
build_number: ${{ parameters.build_number }}
|
||||
scenario: ${{ parameters.scenario }}
|
||||
ansible_version: ${{ parameters.ansible_version }}
|
||||
python_version: '< 3.12'
|
||||
|
||||
# Temporarily disabled due to ansible docker plugin issue.
|
||||
#- template: pytest_tests.yml
|
||||
# parameters:
|
||||
# build_number: ${{ parameters.build_number }}
|
||||
# scenario: ${{ parameters.scenario }}
|
||||
# ansible_version: ${{ parameters.ansible_version }}
|
||||
# python_version: '< 3.12'
|
||||
@@ -1,92 +0,0 @@
|
||||
---
|
||||
parameters:
|
||||
- name: group_number
|
||||
type: number
|
||||
default: 1
|
||||
- name: number_of_groups
|
||||
type: number
|
||||
default: 1
|
||||
- name: scenario
|
||||
type: string
|
||||
default: fedora-latest
|
||||
- name: ansible_version
|
||||
type: string
|
||||
default: ""
|
||||
- name: python_version
|
||||
type: string
|
||||
default: 3.x
|
||||
- name: build_number
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
- job: Test_Group${{ parameters.group_number }}
|
||||
displayName: Run playbook tests ${{ parameters.scenario }} (${{ parameters.group_number }}/${{ parameters.number_of_groups }})
|
||||
timeoutInMinutes: 360
|
||||
variables:
|
||||
- template: variables.yaml
|
||||
- template: variables_${{ parameters.scenario }}.yaml
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: '${{ parameters.python_version }}'
|
||||
|
||||
- script: |
|
||||
pip install \
|
||||
"molecule-plugins[docker]" \
|
||||
"requests<2.29" \
|
||||
"ansible${{ parameters.ansible_version }}"
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Install molecule and Ansible
|
||||
|
||||
- script: ansible-galaxy collection install community.docker ansible.posix
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Install Ansible collections
|
||||
|
||||
- script: pip install -r requirements-tests.txt
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Install dependencies
|
||||
|
||||
- script: |
|
||||
rm -rf ~/ansible
|
||||
mkdir -p ~/.ansible/roles ~/.ansible/library ~/.ansible/module_utils
|
||||
cp -a roles/* ~/.ansible/roles
|
||||
cp -a plugins/modules/* ~/.ansible/library
|
||||
cp -a plugins/module_utils/* ~/.ansible/module_utils
|
||||
molecule create -s ${{ parameters.scenario }}
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Setup test container
|
||||
env:
|
||||
ANSIBLE_LIBRARY: ./molecule
|
||||
|
||||
- script: |
|
||||
. utils/set_test_modules
|
||||
python utils/check_test_configuration.py ${{ parameters.scenario }}
|
||||
displayName: Check scenario test configuration
|
||||
|
||||
- script: |
|
||||
. utils/set_test_modules
|
||||
if ! pytest \
|
||||
-m "playbook" \
|
||||
--verbose \
|
||||
--color=yes \
|
||||
--suppress-no-test-exit-code \
|
||||
--splits=${{ parameters.number_of_groups }} \
|
||||
--group=${{ parameters.group_number }} \
|
||||
--randomly-seed=$(date "+%Y%m%d") \
|
||||
--junit-xml=TEST-results-group-${{ parameters.group_number }}.xml
|
||||
then
|
||||
[ $? -eq 5 ] && true || false
|
||||
fi
|
||||
displayName: Run playbook tests
|
||||
env:
|
||||
IPA_SERVER_HOST: ${{ parameters.scenario }}
|
||||
RUN_TESTS_IN_DOCKER: true
|
||||
IPA_DISABLED_MODULES: ${{ variables.ipa_disabled_modules }}
|
||||
IPA_DISABLED_TESTS: ${{ variables.ipa_disabled_tests }}
|
||||
IPA_VERBOSITY: "-vvv"
|
||||
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
mergeTestResults: true
|
||||
testRunTitle: PlaybookTests-Build${{ parameters.build_number }}
|
||||
condition: succeededOrFailed()
|
||||
@@ -1,88 +0,0 @@
|
||||
---
|
||||
parameters:
|
||||
- name: group_number
|
||||
type: number
|
||||
default: 1
|
||||
- name: number_of_groups
|
||||
type: number
|
||||
default: 1
|
||||
- name: scenario
|
||||
type: string
|
||||
default: fedora-latest
|
||||
- name: ansible_version
|
||||
type: string
|
||||
default: ""
|
||||
- name: python_version
|
||||
type: string
|
||||
default: 3.x
|
||||
- name: build_number
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
- job: Test_Group${{ parameters.group_number }}
|
||||
displayName: Run playbook tests ${{ parameters.scenario }} (${{ parameters.group_number }}/${{ parameters.number_of_groups }})
|
||||
timeoutInMinutes: 240
|
||||
variables:
|
||||
- template: variables.yaml
|
||||
- template: variables_${{ parameters.scenario }}.yaml
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: '${{ parameters.python_version }}'
|
||||
|
||||
- script: |
|
||||
pip install \
|
||||
"molecule-plugins[docker]" \
|
||||
"requests<2.29" \
|
||||
"ansible${{ parameters.ansible_version }}"
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Install molecule and Ansible
|
||||
|
||||
- script: ansible-galaxy collection install community.docker ansible.posix
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Install Ansible collections
|
||||
|
||||
- script: pip install -r requirements-tests.txt
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Install dependencies
|
||||
|
||||
- script: |
|
||||
rm -rf ~/ansible
|
||||
mkdir -p ~/.ansible/roles ~/.ansible/library ~/.ansible/module_utils
|
||||
cp -a roles/* ~/.ansible/roles
|
||||
cp -a plugins/modules/* ~/.ansible/library
|
||||
cp -a plugins/module_utils/* ~/.ansible/module_utils
|
||||
molecule create -s ${{ parameters.scenario }}
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Setup test container
|
||||
env:
|
||||
ANSIBLE_LIBRARY: ./molecule
|
||||
|
||||
- script: |
|
||||
python utils/check_test_configuration.py ${{ parameters.scenario }}
|
||||
displayName: Check scenario test configuration
|
||||
|
||||
- script: |
|
||||
pytest \
|
||||
-m "playbook" \
|
||||
--verbose \
|
||||
--color=yes \
|
||||
--splits=${{ parameters.number_of_groups }} \
|
||||
--group=${{ parameters.group_number }} \
|
||||
--randomly-seed=$(date "+%Y%m%d") \
|
||||
--junit-xml=TEST-results-group-${{ parameters.group_number }}.xml
|
||||
displayName: Run playbook tests
|
||||
env:
|
||||
IPA_SERVER_HOST: ${{ parameters.scenario }}
|
||||
RUN_TESTS_IN_DOCKER: true
|
||||
IPA_DISABLED_MODULES: ${{ variables.ipa_disabled_modules }}
|
||||
IPA_DISABLED_TESTS: ${{ variables.ipa_disabled_tests }}
|
||||
IPA_ENABLED_MODULES: ${{ variables.ipa_enabled_modules }}
|
||||
IPA_ENABLED_TESTS: ${{ variables.ipa_enabled_tests }}
|
||||
IPA_VERBOSITY: "-vvv"
|
||||
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
mergeTestResults: true
|
||||
testRunTitle: PlaybookTests-Build${{ parameters.build_number }}
|
||||
condition: succeededOrFailed()
|
||||
@@ -1,75 +0,0 @@
|
||||
---
|
||||
parameters:
|
||||
- name: build_number
|
||||
type: string
|
||||
- name: scenario
|
||||
type: string
|
||||
default: fedora-latest
|
||||
- name: ansible_version
|
||||
type: string
|
||||
default: ""
|
||||
- name: python_version
|
||||
type: string
|
||||
default: 3.x
|
||||
|
||||
jobs:
|
||||
- job: Test_PyTests
|
||||
displayName: Run pytests on ${{ parameters.scenario }}
|
||||
timeoutInMinutes: 240
|
||||
variables:
|
||||
- template: variables.yaml
|
||||
- template: variables_${{ parameters.scenario }}.yaml
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: '${{ parameters.python_version }}'
|
||||
|
||||
- script: |
|
||||
pip install \
|
||||
"molecule-plugins[docker]" \
|
||||
"requests<2.29" \
|
||||
"ansible${{ parameters.ansible_version }}"
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Install molecule and Ansible
|
||||
|
||||
- script: ansible-galaxy collection install community.docker ansible.posix
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Install Ansible collections
|
||||
|
||||
- script: pip install -r requirements-tests.txt
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Install dependencies
|
||||
|
||||
- script: |
|
||||
rm -rf ~/.ansible
|
||||
mkdir -p ~/.ansible/roles ~/.ansible/library ~/.ansible/module_utils
|
||||
cp -a roles/* ~/.ansible/roles
|
||||
cp -a plugins/modules/* ~/.ansible/library
|
||||
cp -a plugins/module_utils/* ~/.ansible/module_utils
|
||||
molecule create -s ${{ parameters.scenario }}
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Setup test container
|
||||
env:
|
||||
ANSIBLE_LIBRARY: ./molecule
|
||||
|
||||
- script: |
|
||||
pytest \
|
||||
-m "not playbook" \
|
||||
--verbose \
|
||||
--color=yes \
|
||||
--junit-xml=TEST-results-pytests.xml
|
||||
displayName: Run tests
|
||||
env:
|
||||
IPA_SERVER_HOST: ${{ parameters.scenario }}
|
||||
RUN_TESTS_IN_DOCKER: true
|
||||
IPA_DISABLED_MODULES: ${{ variables.ipa_disabled_modules }}
|
||||
IPA_DISABLED_TESTS: ${{ variables.ipa_disabled_tests }}
|
||||
IPA_ENABLED_MODULES: ${{ variables.ipa_enabled_modules }}
|
||||
IPA_ENABLED_TESTS: ${{ variables.ipa_enabled_tests }}
|
||||
IPA_VERBOSITY: "-vvv"
|
||||
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
mergeTestResults: true
|
||||
testRunTitle: PlaybookTests-Build${{ parameters.build_number }}
|
||||
condition: succeededOrFailed()
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
- name: Create CSR
|
||||
ansible.builtin.shell:
|
||||
cmd: "openssl req -newkey rsa:1024 -keyout /dev/null -nodes -subj /CN=certhost.{{ ipa_domain }}"
|
||||
cmd: "openssl req -newkey rsa:2048 -keyout /dev/null -nodes -subj /CN=certhost.{{ ipa_domain }}"
|
||||
register: host_req
|
||||
|
||||
- name: Create CSR file
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
- name: Create signing request for certificate
|
||||
ansible.builtin.shell:
|
||||
cmd: "openssl req -newkey rsa:1024 -keyout /dev/null -nodes -subj /CN=certservice.{{ ipa_domain }}"
|
||||
cmd: "openssl req -newkey rsa:2048 -keyout /dev/null -nodes -subj /CN=certservice.{{ ipa_domain }}"
|
||||
register: service_req
|
||||
|
||||
- name: Create CSR file
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
- name: Crete CSR
|
||||
ansible.builtin.shell:
|
||||
cmd:
|
||||
'openssl req -newkey rsa:1024 -keyout /dev/null -nodes -subj /CN=certuser -reqexts IECUserRoles
|
||||
'openssl req -newkey rsa:2048 -keyout /dev/null -nodes -subj /CN=certuser -reqexts IECUserRoles
|
||||
-config <(cat /etc/pki/tls/openssl.cnf; printf "[IECUserRoles]\n1.2.840.10070.8.1=ASN1:UTF8String:hello world")'
|
||||
executable: /bin/bash
|
||||
register: user_req
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
---
|
||||
- name: Test services absent
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Include generate_test_data.yml
|
||||
ansible.builtin.include_tasks: generate_test_data.yml
|
||||
|
||||
- name: Services absent len:{{ service_list | length }}
|
||||
ipaservice:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
services: "{{ service_absent_list }}"
|
||||
state: absent
|
||||
@@ -8,6 +8,18 @@
|
||||
- name: Include generate_test_data.yml
|
||||
ansible.builtin.include_tasks: generate_test_data.yml
|
||||
|
||||
- name: Cleanup Services len:{{ service_list | length }}
|
||||
ipaservice:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
services: "{{ service_absent_list }}"
|
||||
state: absent
|
||||
|
||||
- name: Cleanup Hosts len:{{ host_list | length }}
|
||||
ipahost:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
hosts: "{{ host_absent_list }}"
|
||||
state: absent
|
||||
|
||||
- name: Hosts present len:{{ host_list | length }}
|
||||
ipahost:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
|
||||
@@ -3,11 +3,15 @@
|
||||
- name: Test sudorule
|
||||
hosts: "{{ ipa_test_host | default('ipaserver') }}"
|
||||
become: true
|
||||
gather_facts: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
|
||||
# setup
|
||||
- name: Ensure DNS Ansible facts are available
|
||||
ansible.builtin.setup:
|
||||
gather_subset: dns
|
||||
|
||||
- name: Ensure test user is present
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
@@ -1157,7 +1161,7 @@
|
||||
hostmask: 192.168.120.0/24
|
||||
action: member
|
||||
register: result
|
||||
check_mode: yes
|
||||
check_mode: true
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure sudorule hostmask member is present
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
---
|
||||
- name: Test sudorule user category
|
||||
hosts: ipaserver
|
||||
become: yes
|
||||
gather_facts: yes
|
||||
become: false
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Get Domain from the server name
|
||||
ansible.builtin.set_fact:
|
||||
ipaserver_domain: "{{ ansible_facts['fqdn'].split('.')[1:] | join('.') }}"
|
||||
- name: Test sudorule single hostnames
|
||||
block:
|
||||
# setup test environment
|
||||
- name: Ensure ipaserver_domain is set
|
||||
when: ipaserver_domain is not defined
|
||||
block:
|
||||
- name: Retrieve host information
|
||||
ansible.builtin.setup:
|
||||
gather_subset: dns
|
||||
- name: Get Domain from the server name
|
||||
ansible.builtin.set_fact:
|
||||
ipaserver_domain: "{{ ansible_facts['fqdn'].split('.')[1:] | join('.') }}"
|
||||
|
||||
- name: Ensure sudorules are absent
|
||||
ipasudorule:
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
- name: Test sudorule
|
||||
hosts: ipaclients, ipaserver
|
||||
become: no
|
||||
gather_facts: no
|
||||
become: false
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Include FreeIPA facts.
|
||||
@@ -37,3 +37,15 @@
|
||||
when: groups['ipaclients'] is not defined or not groups['ipaclients']
|
||||
vars:
|
||||
ipa_context: client
|
||||
|
||||
- name: Test sudorule using client context, in client host.
|
||||
ansible.builtin.import_playbook: test_sudorules.yml
|
||||
when: groups['ipaclients']
|
||||
vars:
|
||||
ipa_test_host: ipaclients
|
||||
|
||||
- name: Test sudorule using client context, in server host.
|
||||
ansible.builtin.import_playbook: test_sudorules.yml
|
||||
when: groups['ipaclients'] is not defined or not groups['ipaclients']
|
||||
vars:
|
||||
ipa_context: client
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
- name: Test sudorule members should be case insensitive.
|
||||
hosts: "{{ ipa_test_host | default('ipaserver') }}"
|
||||
become: no
|
||||
gather_facts: no
|
||||
become: false
|
||||
gather_facts: false
|
||||
|
||||
vars:
|
||||
groups_present:
|
||||
@@ -37,7 +37,7 @@
|
||||
ipahost:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: "{{ item }}.{{ ipa_domain }}"
|
||||
force: yes
|
||||
force: true
|
||||
loop: "{{ groups_present }}"
|
||||
|
||||
- name: Ensure test users exist.
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
---
|
||||
- name: Test sudorule with single hostnames.
|
||||
hosts: "{{ ipa_test_host | default('ipaserver') }}"
|
||||
become: no
|
||||
gather_facts: no
|
||||
become: false
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Test sudorule single hostnames
|
||||
block:
|
||||
# setup test environment
|
||||
- name: Get Domain from the server name
|
||||
ansible.builtin.set_fact:
|
||||
ipaserver_domain: "{{ ansible_facts['fqdn'].split('.')[1:] | join('.') }}"
|
||||
- name: Ensure ipaserver_domain is set
|
||||
when: ipaserver_domain is not defined
|
||||
block:
|
||||
- name: Retrieve host information
|
||||
ansible.builtin.setup:
|
||||
gather_subset: dns
|
||||
- name: Get Domain from the server name
|
||||
ansible.builtin.set_fact:
|
||||
ipaserver_domain: "{{ ansible_facts['fqdn'].split('.')[1:] | join('.') }}"
|
||||
|
||||
- name: Ensure test sudo rule is absent
|
||||
ipasudorule:
|
||||
@@ -24,9 +29,9 @@
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
hosts:
|
||||
- name: "host01.{{ ipaserver_domain }}"
|
||||
force: yes
|
||||
force: true
|
||||
- name: "host02.{{ ipaserver_domain }}"
|
||||
force: yes
|
||||
force: true
|
||||
|
||||
# start tests
|
||||
- name: Ensure sudorule exist with host member using FQDN.
|
||||
|
||||
382
tests/sudorule/test_sudorules.yml
Normal file
382
tests/sudorule/test_sudorules.yml
Normal file
@@ -0,0 +1,382 @@
|
||||
---
|
||||
- name: Test sudorule
|
||||
hosts: "{{ ipa_test_host | default('ipaserver') }}"
|
||||
become: false
|
||||
gather_facts: false
|
||||
|
||||
module_defaults:
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
ipahostgroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
ipasudocmdgroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
ipasudocmd:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
ipasudorule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
|
||||
tasks:
|
||||
|
||||
# setup
|
||||
- name: Ensure ansible facts for DNS are available
|
||||
ansible.builtin.setup:
|
||||
gather_subset: dns
|
||||
|
||||
- name: Ensure test users are absent
|
||||
ipauser:
|
||||
name:
|
||||
- user01
|
||||
- user02
|
||||
state: absent
|
||||
|
||||
- name: Ensure test groups are absent
|
||||
ipagroup:
|
||||
name:
|
||||
- group01
|
||||
- group02
|
||||
state: absent
|
||||
|
||||
- name: Ensure test hostgroup is absent
|
||||
ipahostgroup:
|
||||
name: cluster
|
||||
state: absent
|
||||
|
||||
- name: Ensure test users are present
|
||||
ipauser:
|
||||
users:
|
||||
- name: user01
|
||||
first: user
|
||||
last: zeroone
|
||||
- name: user02
|
||||
first: user
|
||||
last: zerotwo
|
||||
|
||||
- name: Ensure groups are present
|
||||
ipagroup:
|
||||
groups:
|
||||
- name: group01
|
||||
user: user01
|
||||
- name: group02
|
||||
|
||||
- name: Ensure sudocmdgroup is absent
|
||||
ipasudocmdgroup:
|
||||
name: test_sudorule_cmdgroup
|
||||
state: absent
|
||||
|
||||
- name: Ensure hostgroup is present, with a host.
|
||||
ipahostgroup:
|
||||
name: cluster
|
||||
host: "{{ ansible_facts['fqdn'] }}"
|
||||
|
||||
- name: Ensure some sudocmds are available
|
||||
ipasudocmd:
|
||||
name:
|
||||
- /sbin/ifconfig
|
||||
- /usr/bin/vim
|
||||
- /usr/bin/emacs
|
||||
state: present
|
||||
|
||||
- name: Ensure sudocmdgroup is available
|
||||
ipasudocmdgroup:
|
||||
name: test_sudorule_cmdgroup
|
||||
sudocmd: /usr/bin/vim
|
||||
state: present
|
||||
|
||||
- name: Ensure another sudocmdgroup is available
|
||||
ipasudocmdgroup:
|
||||
name: test_sudorule_cmdgroup_2
|
||||
sudocmd: /usr/bin/emacs
|
||||
state: present
|
||||
|
||||
- name: Ensure sudorules are absent
|
||||
ipasudorule:
|
||||
name:
|
||||
- testrule1
|
||||
- testrule2
|
||||
- allusers
|
||||
- allhosts
|
||||
- allcommands
|
||||
state: absent
|
||||
|
||||
# tests
|
||||
- name: Run sudorules tests.
|
||||
block:
|
||||
- name: Ensure sudorules are present
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: testrule1
|
||||
- name: testrule2
|
||||
- name: allhosts
|
||||
- name: allcommands
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure sudorules are present, again
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: testrule1
|
||||
- name: testrule2
|
||||
- name: allhosts
|
||||
- name: allcommands
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure testrule1 and testrule2 are absent
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: testrule1
|
||||
- name: testrule2
|
||||
state: absent
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure testrule1 and testrule2 are absent, again
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: testrule1
|
||||
- name: testrule2
|
||||
state: absent
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure allhosts and allcommands sudorules are still present
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: allhosts
|
||||
- name: allcomands
|
||||
state: absent
|
||||
check_mode: true
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure sudorules with parameters are present
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: testrule1
|
||||
runasuser:
|
||||
- user01
|
||||
- name: testrule2
|
||||
runasuser_group:
|
||||
- group01
|
||||
state: present
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure sudorules with parameters are present, again
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: testrule1
|
||||
runasuser:
|
||||
- user01
|
||||
- name: testrule2
|
||||
runasuser_group:
|
||||
- group01
|
||||
state: present
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure sudorules with parameters are modified
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: testrule1
|
||||
runasuser:
|
||||
- user02
|
||||
- name: testrule2
|
||||
runasuser_group:
|
||||
- group02
|
||||
state: present
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure sudorules with parameters are modified again
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: testrule1
|
||||
runasuser:
|
||||
- user02
|
||||
- name: testrule2
|
||||
runasuser_group:
|
||||
- group02
|
||||
state: present
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure sudorules members can be modified
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: testrule1
|
||||
runasuser:
|
||||
- user01
|
||||
- name: testrule2
|
||||
runasuser_group:
|
||||
- group01
|
||||
action: member
|
||||
state: present
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure sudorules members can modified, again
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: testrule1
|
||||
runasuser:
|
||||
- user01
|
||||
- user02
|
||||
- name: testrule2
|
||||
runasuser_group:
|
||||
- group01
|
||||
- group02
|
||||
action: member
|
||||
state: present
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure sudorules members are absent
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: testrule1
|
||||
runasuser:
|
||||
- user01
|
||||
- name: testrule2
|
||||
runasuser_group:
|
||||
- group02
|
||||
action: member
|
||||
state: absent
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure sudorules members are absent, again
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: testrule1
|
||||
runasuser:
|
||||
- user01
|
||||
- name: testrule2
|
||||
runasuser_group:
|
||||
- group02
|
||||
action: member
|
||||
state: absent
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure testrule1 and testrule2 are present, with proper attributes
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: testrule1
|
||||
runasuser:
|
||||
- user02
|
||||
- name: testrule2
|
||||
runasuser_group:
|
||||
- group01
|
||||
state: present
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure testrule1 and testrule2 are disabled
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: testrule1
|
||||
- name: testrule2
|
||||
state: disabled
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure testrule1 and testrule2 are disabled, again
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: testrule1
|
||||
- name: testrule2
|
||||
state: disabled
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure testrule1 and testrule2 are enabled
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: testrule1
|
||||
- name: testrule2
|
||||
state: enabled
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure testrule1 and testrule2 are enabled, again
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: testrule1
|
||||
- name: testrule2
|
||||
state: enabled
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure multiple sudorules cannot be enabled with invalid parameters
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: testrule1
|
||||
runasuser: user01
|
||||
- name: testrule2
|
||||
runasuser: user01
|
||||
state: enabled
|
||||
register: result
|
||||
failed_when: not result.failed and "Argument 'runasuser' can not be used with action 'sudorule' and state 'enabled'" not in result.msg
|
||||
|
||||
- name: Ensure multiple sudorules cannot be disabled with invalid parameters
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: testrule1
|
||||
runasuser: user01
|
||||
- name: testrule2
|
||||
runasuser: user01
|
||||
state: disabled
|
||||
register: result
|
||||
failed_when: not result.failed and "Argument 'runasuser' can not be used with action 'sudorule' and state 'disabled'" not in result.msg
|
||||
|
||||
# cleanup
|
||||
always:
|
||||
- name: Cleanup sudorules
|
||||
ipasudorule:
|
||||
name:
|
||||
- testrule1
|
||||
- testrule2
|
||||
- allusers
|
||||
- allhosts
|
||||
- allcommands
|
||||
state: absent
|
||||
|
||||
- name: Ensure sudocmdgroup is absent
|
||||
ipasudocmdgroup:
|
||||
name:
|
||||
- test_sudorule_cmdgroup
|
||||
- test_sudorule_cmdgroup_2
|
||||
state: absent
|
||||
|
||||
- name: Ensure sudocmds are absent
|
||||
ipasudocmd:
|
||||
name:
|
||||
- /sbin/ifconfig
|
||||
- /usr/bin/vim
|
||||
- /usr/bin/emacs
|
||||
state: absent
|
||||
|
||||
- name: Ensure hostgroup is absent.
|
||||
ipahostgroup:
|
||||
name: cluster
|
||||
state: absent
|
||||
|
||||
- name: Ensure groups are absent
|
||||
ipagroup:
|
||||
name: group01,group02
|
||||
state: absent
|
||||
|
||||
- name: Ensure user is absent
|
||||
ipauser:
|
||||
name: user01,user02
|
||||
state: absent
|
||||
311
tests/sudorule/test_sudorules_member_case_insensitive.yml
Normal file
311
tests/sudorule/test_sudorules_member_case_insensitive.yml
Normal file
@@ -0,0 +1,311 @@
|
||||
---
|
||||
- name: Test sudorules members should be case insensitive.
|
||||
hosts: "{{ ipa_test_host | default('ipaserver') }}"
|
||||
become: false
|
||||
gather_facts: false
|
||||
|
||||
module_defaults:
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
ipagroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
ipahost:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
ipahostgroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
ipasudocmdgroup:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
ipasudocmd:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
ipasudorule:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
|
||||
vars:
|
||||
groups_present:
|
||||
- eleMENT1
|
||||
- Element2
|
||||
- eLeMenT3
|
||||
- ElemENT4
|
||||
|
||||
tasks:
|
||||
- name: Test sudorule member case insensitive
|
||||
block:
|
||||
# SETUP
|
||||
- name: Ensure domain name
|
||||
ansible.builtin.set_fact:
|
||||
ipa_domain: ipa.test
|
||||
when: ipa_domain is not defined
|
||||
|
||||
- name: Ensure test groups are absent.
|
||||
ipagroup:
|
||||
name: "{{ groups_present }}"
|
||||
state: absent
|
||||
|
||||
- name: Ensure test hostgroups are absent.
|
||||
ipahostgroup:
|
||||
name: "{{ groups_present }}"
|
||||
state: absent
|
||||
|
||||
- name: Ensure test users are absent.
|
||||
ipauser:
|
||||
name: "{{ groups_present }}"
|
||||
state: absent
|
||||
|
||||
- name: Ensure test groups exist.
|
||||
ipagroup:
|
||||
name: "{{ item }}"
|
||||
loop: "{{ groups_present }}"
|
||||
|
||||
- name: Ensure test hostgroups exist.
|
||||
ipahostgroup:
|
||||
name: "{{ item }}"
|
||||
loop: "{{ groups_present }}"
|
||||
|
||||
- name: Ensure test hosts exist.
|
||||
ipahost:
|
||||
name: "{{ item }}.{{ ipa_domain }}"
|
||||
force: yes
|
||||
loop: "{{ groups_present }}"
|
||||
|
||||
- name: Ensure test users exist.
|
||||
ipauser:
|
||||
name: "user{{ item }}"
|
||||
first: "{{ item }}"
|
||||
last: "{{ item }}"
|
||||
loop: "{{ groups_present }}"
|
||||
|
||||
- name: Ensure sudorule do not exist
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: "{{ item }}"
|
||||
state: absent
|
||||
loop: "{{ groups_present }}"
|
||||
|
||||
# TESTS
|
||||
- name: Ensure sudorule exist with runasusers members
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: "{{ item }}"
|
||||
cmdcategory: all
|
||||
runasuser: "user{{ item }}"
|
||||
loop: "{{ groups_present }}"
|
||||
register: result
|
||||
failed_when: result.failed or not result.changed
|
||||
|
||||
- name: Ensure sudorule exist with lowercase runasusers members
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: "{{ item }}"
|
||||
cmdcategory: all
|
||||
runasuser: "user{{ item | lower }}"
|
||||
loop: "{{ groups_present }}"
|
||||
register: result
|
||||
failed_when: result.failed or result.changed
|
||||
|
||||
- name: Ensure sudorule exist with uppercase runasusers members
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: "{{ item }}"
|
||||
cmdcategory: all
|
||||
runasuser: "user{{ item | upper }}"
|
||||
loop: "{{ groups_present }}"
|
||||
register: result
|
||||
failed_when: result.failed or result.changed
|
||||
|
||||
- name: Ensure sudorule exist with runasgroup members
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: "{{ item }}"
|
||||
cmdcategory: all
|
||||
runasgroup: "{{ item }}"
|
||||
loop: "{{ groups_present }}"
|
||||
register: result
|
||||
failed_when: result.failed or not result.changed
|
||||
|
||||
- name: Ensure sudorule exist with lowercase runasgroup members
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: "{{ item }}"
|
||||
cmdcategory: all
|
||||
runasgroup: "{{ item | lower }}"
|
||||
loop: "{{ groups_present }}"
|
||||
register: result
|
||||
failed_when: result.failed or result.changed
|
||||
|
||||
- name: Ensure sudorule exist with uppercase runasgroup members
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: "{{ item }}"
|
||||
cmdcategory: all
|
||||
runasgroup: "{{ item | upper }}"
|
||||
loop: "{{ groups_present }}"
|
||||
register: result
|
||||
failed_when: result.failed or result.changed
|
||||
|
||||
- name: Ensure sudorule do not exist
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: "{{ item }}"
|
||||
state: absent
|
||||
loop: "{{ groups_present }}"
|
||||
|
||||
#####
|
||||
|
||||
- name: Ensure sudorule exist with members
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: "{{ item }}"
|
||||
cmdcategory: all
|
||||
hostgroup: "{{ item }}"
|
||||
host: "{{ item }}.{{ ipa_domain }}"
|
||||
group: "{{ item }}"
|
||||
user: "user{{ item }}"
|
||||
loop: "{{ groups_present }}"
|
||||
register: result
|
||||
failed_when: result.failed or not result.changed
|
||||
|
||||
- name: Ensure sudorule exist with members, lowercase
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: "{{ item }}"
|
||||
cmdcategory: all
|
||||
hostgroup: "{{ item | lower }}"
|
||||
host: "{{ item | lower }}.{{ ipa_domain }}"
|
||||
group: "{{ item | lower }}"
|
||||
user: "user{{ item | lower }}"
|
||||
loop: "{{ groups_present }}"
|
||||
register: result
|
||||
failed_when: result.failed or result.changed
|
||||
|
||||
- name: Ensure sudorule exist with members, uppercase
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: "{{ item }}"
|
||||
cmdcategory: all
|
||||
hostgroup: "{{ item | upper }}"
|
||||
host: "{{ item | upper }}.{{ ipa_domain }}"
|
||||
group: "{{ item | upper }}"
|
||||
user: "user{{ item | upper }}"
|
||||
loop: "{{ groups_present }}"
|
||||
register: result
|
||||
failed_when: result.failed or result.changed
|
||||
|
||||
- name: Ensure sudorule member is absent
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: "{{ item }}"
|
||||
hostgroup: "{{ item }}"
|
||||
host: "{{ item }}.{{ ipa_domain }}"
|
||||
group: "{{ item }}"
|
||||
user: "user{{ item }}"
|
||||
action: member
|
||||
state: absent
|
||||
loop: "{{ groups_present }}"
|
||||
register: result
|
||||
failed_when: result.failed or not result.changed
|
||||
|
||||
- name: Ensure sudorule member is absent, lowercase
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: "{{ item }}"
|
||||
hostgroup: "{{ item | lower }}"
|
||||
host: "{{ item | lower }}.{{ ipa_domain }}"
|
||||
group: "{{ item | lower }}"
|
||||
user: "user{{ item | lower }}"
|
||||
action: member
|
||||
state: absent
|
||||
loop: "{{ groups_present }}"
|
||||
register: result
|
||||
failed_when: result.failed or result.changed
|
||||
|
||||
- name: Ensure sudorule member is absent, upercase
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: "{{ item }}"
|
||||
hostgroup: "{{ item | upper }}"
|
||||
host: "{{ item | upper }}.{{ ipa_domain }}"
|
||||
group: "{{ item | upper }}"
|
||||
user: "user{{ item | upper }}"
|
||||
action: member
|
||||
state: absent
|
||||
loop: "{{ groups_present }}"
|
||||
register: result
|
||||
failed_when: result.failed or result.changed
|
||||
|
||||
- name: Ensure sudorule member is present, upercase
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: "{{ item }}"
|
||||
hostgroup: "{{ item | upper }}"
|
||||
host: "{{ item | upper }}.{{ ipa_domain }}"
|
||||
group: "{{ item | upper }}"
|
||||
user: "user{{ item | upper }}"
|
||||
action: member
|
||||
loop: "{{ groups_present }}"
|
||||
register: result
|
||||
failed_when: result.failed or not result.changed
|
||||
|
||||
- name: Ensure sudorule member is present, lowercase
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: "{{ item }}"
|
||||
hostgroup: "{{ item | lower }}"
|
||||
host: "{{ item | lower }}.{{ ipa_domain }}"
|
||||
group: "{{ item | lower }}"
|
||||
user: "user{{ item | lower }}"
|
||||
action: member
|
||||
loop: "{{ groups_present }}"
|
||||
register: result
|
||||
failed_when: result.failed or result.changed
|
||||
|
||||
- name: Ensure sudorule member is present, mixed case
|
||||
ipasudorule:
|
||||
sudorules:
|
||||
- name: "{{ item }}"
|
||||
hostgroup: "{{ item }}"
|
||||
host: "{{ item }}.{{ ipa_domain }}"
|
||||
group: "{{ item }}"
|
||||
user: "user{{ item }}"
|
||||
action: member
|
||||
loop: "{{ groups_present }}"
|
||||
register: result
|
||||
failed_when: result.failed or result.changed
|
||||
|
||||
# cleanup
|
||||
always:
|
||||
- name: Ensure sudorule do not exist
|
||||
ipasudorule:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
loop: "{{ groups_present }}"
|
||||
|
||||
- name: Ensure test groups do not exist.
|
||||
ipagroup:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
loop: "{{ groups_present }}"
|
||||
|
||||
- name: Ensure test hostgroups do not exist.
|
||||
ipahostgroup:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
loop: "{{ groups_present }}"
|
||||
|
||||
- name: Ensure test hosts do not exist.
|
||||
ipahost:
|
||||
name: "{{ item }}.{{ ipa_domain }}"
|
||||
state: absent
|
||||
loop: "{{ groups_present }}"
|
||||
|
||||
- name: Ensure test users do not exist.
|
||||
ipauser:
|
||||
name: "user{{ item }}"
|
||||
state: absent
|
||||
loop: "{{ groups_present }}"
|
||||
@@ -1,13 +0,0 @@
|
||||
---
|
||||
- name: Create users.json
|
||||
hosts: localhost
|
||||
|
||||
tasks:
|
||||
- name: Check if users.json exists
|
||||
ansible.builtin.stat:
|
||||
path: users.json
|
||||
register: register_stat_users
|
||||
|
||||
- name: Create users.json
|
||||
ansible.builtin.command: /bin/bash users.sh 500
|
||||
when: not register_stat_users.stat.exists
|
||||
48
tests/user/generate_test_data.yml
Normal file
48
tests/user/generate_test_data.yml
Normal file
@@ -0,0 +1,48 @@
|
||||
# Generate lists for users
|
||||
---
|
||||
- name: Create present services.json data
|
||||
ansible.builtin.shell: |
|
||||
date=$(date --date='+2 years' "+%Y-%m-%d %H:%M:%S")
|
||||
echo "["
|
||||
for i in $(seq -w 1 "{{ NUM }}"); do
|
||||
echo " {"
|
||||
echo " \"name\": \"testuser_${i}\","
|
||||
echo " \"first\": \"First ${i}\","
|
||||
echo " \"last\": \"Last ${i}\","
|
||||
echo " \"password\": \"user${i}PW\","
|
||||
echo " \"passwordexpiration\": \"${date}\""
|
||||
if [ "$i" -lt "{{ NUM }}" ]; then
|
||||
echo " },"
|
||||
else
|
||||
echo " }"
|
||||
fi
|
||||
done
|
||||
echo "]"
|
||||
vars:
|
||||
NUM: 500
|
||||
register: command
|
||||
|
||||
- name: Set user_list
|
||||
ansible.builtin.set_fact:
|
||||
user_list: "{{ command.stdout | from_json }}"
|
||||
|
||||
- name: Create absent user.json data
|
||||
ansible.builtin.shell: |
|
||||
echo "["
|
||||
for i in $(seq -w 1 "{{ NUM }}"); do
|
||||
echo " {"
|
||||
echo " \"name\": \"testuser_${i}\""
|
||||
if [ "$i" -lt "{{ NUM }}" ]; then
|
||||
echo " },"
|
||||
else
|
||||
echo " }"
|
||||
fi
|
||||
done
|
||||
echo "]"
|
||||
vars:
|
||||
NUM: 500
|
||||
register: command
|
||||
|
||||
- name: Set user_absent_list
|
||||
ansible.builtin.set_fact:
|
||||
user_absent_list: "{{ command.stdout | from_json }}"
|
||||
@@ -1,24 +0,0 @@
|
||||
---
|
||||
- name: Include create_users_json.yml
|
||||
ansible.builtin.import_playbook: create_users_json.yml
|
||||
|
||||
- name: Test users absent
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Include users.json
|
||||
ansible.builtin.include_vars:
|
||||
file: users.json # noqa missing-import
|
||||
|
||||
- name: Create dict with user names
|
||||
ansible.builtin.set_fact:
|
||||
user_names: "{{ user_names | default([]) + [{'name': item.name}] }}"
|
||||
loop: "{{ users }}"
|
||||
|
||||
- name: Users absent len:{{ users | length }}
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
users: "{{ user_names }}"
|
||||
state: absent
|
||||
@@ -1,18 +0,0 @@
|
||||
---
|
||||
- name: Include create_users_json.yml
|
||||
ansible.builtin.import_playbook: create_users_json.yml
|
||||
|
||||
- name: Test users present
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Include users.json
|
||||
ansible.builtin.include_vars:
|
||||
file: users.json # noqa missing-import
|
||||
|
||||
- name: Users present len:{{ users | length }}
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
users: "{{ users }}"
|
||||
38
tests/user/test_users_present_absent.yml
Normal file
38
tests/user/test_users_present_absent.yml
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
- name: Test users present and absent
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
tasks:
|
||||
- name: Include generate_test_data.yml
|
||||
ansible.builtin.include_tasks: generate_test_data.yml
|
||||
|
||||
- name: Size of user_list
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ user_list | length }}"
|
||||
|
||||
- name: Size of user_absent_list
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ user_absent_list | length }}"
|
||||
|
||||
- name: Cleanup test users
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
users: "{{ user_absent_list }}"
|
||||
state: absent
|
||||
|
||||
- name: Users present
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
users: "{{ user_list }}"
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Users absent
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
users: "{{ user_absent_list }}"
|
||||
state: absent
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
43
tests/user/test_users_present_absent_slice.yml
Normal file
43
tests/user/test_users_present_absent_slice.yml
Normal file
@@ -0,0 +1,43 @@
|
||||
---
|
||||
- name: Test users present and absent with slice
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
vars:
|
||||
slice_size: 100
|
||||
tasks:
|
||||
- name: Include generate_test_data.yml
|
||||
ansible.builtin.include_tasks: generate_test_data.yml
|
||||
|
||||
- name: Size of user_list
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ user_list | length }}"
|
||||
|
||||
- name: Size of user_absent_list
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ user_absent_list | length }}"
|
||||
|
||||
- name: Cleanup test users
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
users: "{{ user_absent_list[item : item + slice_size] }}"
|
||||
state: absent
|
||||
loop: "{{ range(0, user_absent_list | length, slice_size) | list }}"
|
||||
|
||||
- name: Users present
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
users: "{{ user_list[item : item + slice_size] }}"
|
||||
loop: "{{ range(0, user_list | length, slice_size) | list }}"
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Users absent
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
users: "{{ user_absent_list[item : item + slice_size] }}"
|
||||
state: absent
|
||||
loop: "{{ range(0, user_absent_list | length, slice_size) | list }}"
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
@@ -1,23 +0,0 @@
|
||||
---
|
||||
- name: Include create_users_json.yml
|
||||
ansible.builtin.import_playbook: create_users_json.yml
|
||||
|
||||
- name: Test users present slice
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
vars:
|
||||
slice_size: 500
|
||||
tasks:
|
||||
- name: Include users.json
|
||||
ansible.builtin.include_vars:
|
||||
file: users.json # noqa missing-import
|
||||
- name: Size of users slice.
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ users | length }}"
|
||||
- name: Users present
|
||||
ipauser:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
users: "{{ users[item : item + slice_size] }}"
|
||||
loop: "{{ range(0, users | length, slice_size) | list }}"
|
||||
@@ -1,29 +0,0 @@
|
||||
#!/bin/bash -eu
|
||||
|
||||
NUM=${1-1000}
|
||||
FILE="users.json"
|
||||
date=$(date --date='+2 years' "+%Y-%m-%d %H:%M:%S")
|
||||
|
||||
echo "{" > "$FILE"
|
||||
|
||||
echo " \"users\": [" >> "$FILE"
|
||||
|
||||
for i in $(seq 1 "$NUM"); do
|
||||
{
|
||||
echo " {"
|
||||
echo " \"name\": \"user$i\","
|
||||
echo " \"first\": \"First $i\","
|
||||
echo " \"last\": \"Last $i\","
|
||||
echo " \"password\": \"user${i}PW\","
|
||||
echo " \"passwordexpiration\": \"$date\""
|
||||
} >> "$FILE"
|
||||
if [ "$i" -lt "$NUM" ]; then
|
||||
echo " }," >> "$FILE"
|
||||
else
|
||||
echo " }" >> "$FILE"
|
||||
fi
|
||||
done
|
||||
|
||||
echo " ]" >> "$FILE"
|
||||
|
||||
echo "}" >> "$FILE"
|
||||
@@ -1,22 +0,0 @@
|
||||
#!/bin/bash -eu
|
||||
|
||||
NUM=1000
|
||||
FILE="users_absent.json"
|
||||
|
||||
echo "{" > "$FILE"
|
||||
|
||||
echo " \"users\": [" >> "$FILE"
|
||||
|
||||
for i in $(seq 1 "$NUM"); do
|
||||
echo " {" >> "$FILE"
|
||||
echo " \"name\": \"user$i\"," >> "$FILE"
|
||||
if [ "$i" -lt "$NUM" ]; then
|
||||
echo " }," >> "$FILE"
|
||||
else
|
||||
echo " }" >> "$FILE"
|
||||
fi
|
||||
done
|
||||
|
||||
echo " ]" >> "$FILE"
|
||||
|
||||
echo "}" >> "$FILE"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user