summaryrefslogtreecommitdiffstats
path: root/ansible_collections/community/general/tests/integration
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 12:04:41 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 12:04:41 +0000
commit975f66f2eebe9dadba04f275774d4ab83f74cf25 (patch)
tree89bd26a93aaae6a25749145b7e4bca4a1e75b2be /ansible_collections/community/general/tests/integration
parentInitial commit. (diff)
downloadansible-975f66f2eebe9dadba04f275774d4ab83f74cf25.tar.xz
ansible-975f66f2eebe9dadba04f275774d4ab83f74cf25.zip
Adding upstream version 7.7.0+dfsg.upstream/7.7.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ansible_collections/community/general/tests/integration')
-rw-r--r--ansible_collections/community/general/tests/integration/requirements.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/aix_devices/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/aix_devices/tasks/main.yml81
-rw-r--r--ansible_collections/community/general/tests/integration/targets/aix_filesystem/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/aix_filesystem/tasks/main.yml130
-rw-r--r--ansible_collections/community/general/tests/integration/targets/alerta_customer/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/alerta_customer/defaults/main.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/alerta_customer/tasks/main.yml156
-rw-r--r--ansible_collections/community/general/tests/integration/targets/alternatives/aliases11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/alternatives/tasks/main.yml93
-rw-r--r--ansible_collections/community/general/tests/integration/targets/alternatives/tasks/path_is_checked.yml17
-rw-r--r--ansible_collections/community/general/tests/integration/targets/alternatives/tasks/remove_links.yml13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/alternatives/tasks/setup.yml19
-rw-r--r--ansible_collections/community/general/tests/integration/targets/alternatives/tasks/setup_test.yml16
-rw-r--r--ansible_collections/community/general/tests/integration/targets/alternatives/tasks/subcommands.yml222
-rw-r--r--ansible_collections/community/general/tests/integration/targets/alternatives/tasks/test.yml56
-rw-r--r--ansible_collections/community/general/tests/integration/targets/alternatives/tasks/tests.yml20
-rw-r--r--ansible_collections/community/general/tests/integration/targets/alternatives/tasks/tests_set_priority.yml54
-rw-r--r--ansible_collections/community/general/tests/integration/targets/alternatives/tasks/tests_state.yml120
-rw-r--r--ansible_collections/community/general/tests/integration/targets/alternatives/templates/dummy_alternative17
-rw-r--r--ansible_collections/community/general/tests/integration/targets/alternatives/templates/dummy_command6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/alternatives/vars/Debian.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/alternatives/vars/Suse-42.3.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/alternatives/vars/default.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ansible_galaxy_install/aliases8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ansible_galaxy_install/files/test.yml15
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ansible_galaxy_install/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ansible_galaxy_install/tasks/main.yml88
-rw-r--r--ansible_collections/community/general/tests/integration/targets/apache2_module/aliases7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/apache2_module/tasks/635-apache2-misleading-warning.yml47
-rw-r--r--ansible_collections/community/general/tests/integration/targets/apache2_module/tasks/actualtest.yml207
-rw-r--r--ansible_collections/community/general/tests/integration/targets/apache2_module/tasks/main.yml52
-rw-r--r--ansible_collections/community/general/tests/integration/targets/archive/aliases9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/archive/files/bar.txt5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/archive/files/empty.txt0
-rw-r--r--ansible_collections/community/general/tests/integration/targets/archive/files/foo.txt5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/archive/files/sub/subfile.txt0
-rw-r--r--ansible_collections/community/general/tests/integration/targets/archive/meta/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/archive/tasks/main.yml145
-rw-r--r--ansible_collections/community/general/tests/integration/targets/archive/tests/broken-link.yml35
-rw-r--r--ansible_collections/community/general/tests/integration/targets/archive/tests/core.yml177
-rw-r--r--ansible_collections/community/general/tests/integration/targets/archive/tests/exclusions.yml44
-rw-r--r--ansible_collections/community/general/tests/integration/targets/archive/tests/idempotency.yml144
-rw-r--r--ansible_collections/community/general/tests/integration/targets/archive/tests/remove.yml211
-rw-r--r--ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/aliases12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/defaults/main.yml20
-rw-r--r--ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/main.yml29
-rw-r--r--ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/run_common_tests.yml15
-rw-r--r--ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/run_filesystem_tests.yml32
-rw-r--r--ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/setup.yml37
-rw-r--r--ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_filesystem_matching.yml80
-rw-r--r--ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_snapshot_clobber.yml41
-rw-r--r--ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_snapshot_error.yml42
-rw-r--r--ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_snapshot_skip.yml41
-rw-r--r--ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_subvolume_default.yml99
-rw-r--r--ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_subvolume_nested.yml61
-rw-r--r--ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_subvolume_recursive.yml86
-rw-r--r--ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_subvolume_simple.yml54
-rw-r--r--ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_subvolume_whitespace.yml62
-rw-r--r--ansible_collections/community/general/tests/integration/targets/callback/inventory.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/callback/tasks/main.yml100
-rw-r--r--ansible_collections/community/general/tests/integration/targets/callback_diy/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/callback_diy/tasks/main.yml462
-rw-r--r--ansible_collections/community/general/tests/integration/targets/callback_log_plays/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/callback_log_plays/ping_log.yml9
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/callback_log_plays/runme.sh21
-rw-r--r--ansible_collections/community/general/tests/integration/targets/callback_yaml/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/callback_yaml/tasks/main.yml101
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cargo/aliases7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cargo/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cargo/tasks/main.yml20
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cargo/tasks/setup.yml28
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cargo/tasks/test_general.yml35
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cargo/tasks/test_version.yml50
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cloud_init_data_facts/aliases10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cloud_init_data_facts/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cloud_init_data_facts/tasks/main.yml68
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cmd_runner/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cmd_runner/library/cmd_echo.py55
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cmd_runner/tasks/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cmd_runner/tasks/test_cmd_echo.yml19
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cmd_runner/vars/main.yml123
-rw-r--r--ansible_collections/community/general/tests/integration/targets/connection/aliases5
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/connection/test.sh16
-rw-r--r--ansible_collections/community/general/tests/integration/targets/connection/test_connection.yml48
-rw-r--r--ansible_collections/community/general/tests/integration/targets/connection_chroot/aliases7
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/connection_chroot/runme.sh21
-rw-r--r--ansible_collections/community/general/tests/integration/targets/connection_chroot/test_connection.inventory11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/connection_jail/aliases5
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/connection_jail/runme.sh21
-rw-r--r--ansible_collections/community/general/tests/integration/targets/connection_jail/test_connection.inventory11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/connection_lxc/aliases5
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/connection_lxc/runme.sh21
-rw-r--r--ansible_collections/community/general/tests/integration/targets/connection_lxc/test_connection.inventory21
-rw-r--r--ansible_collections/community/general/tests/integration/targets/connection_lxd/aliases6
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/connection_lxd/runme.sh21
-rw-r--r--ansible_collections/community/general/tests/integration/targets/connection_lxd/test_connection.inventory10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/connection_posix/aliases6
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/connection_posix/test.sh21
-rw-r--r--ansible_collections/community/general/tests/integration/targets/consul/aliases8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/consul/meta/main.yml10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_session.yml177
-rw-r--r--ansible_collections/community/general/tests/integration/targets/consul/tasks/main.yml89
-rw-r--r--ansible_collections/community/general/tests/integration/targets/consul/templates/consul_config.hcl.j214
-rw-r--r--ansible_collections/community/general/tests/integration/targets/copr/aliases9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/copr/tasks/main.yml160
-rw-r--r--ansible_collections/community/general/tests/integration/targets/copr/vars/main.yml15
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cpanm/aliases10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cpanm/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cpanm/tasks/main.yml65
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cronvar/aliases9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cronvar/defaults/main.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cronvar/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/cronvar/tasks/main.yml124
-rw-r--r--ansible_collections/community/general/tests/integration/targets/deploy_helper/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/deploy_helper/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/deploy_helper/tasks/main.yml158
-rw-r--r--ansible_collections/community/general/tests/integration/targets/discord/README.md20
-rw-r--r--ansible_collections/community/general/tests/integration/targets/discord/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/discord/defaults/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/discord/tasks/main.yml69
-rw-r--r--ansible_collections/community/general/tests/integration/targets/django_manage/aliases15
-rw-r--r--ansible_collections/community/general/tests/integration/targets/django_manage/files/base_test/1045-single-app-project/single_app_project/core/settings.py6
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/django_manage/files/base_test/1045-single-app-project/single_app_project/manage.py21
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/django_manage/files/base_test/simple_project/p1/manage.py29
-rw-r--r--ansible_collections/community/general/tests/integration/targets/django_manage/files/base_test/simple_project/p1/p1/settings.py133
-rw-r--r--ansible_collections/community/general/tests/integration/targets/django_manage/files/base_test/simple_project/p1/p1/urls.py28
-rw-r--r--ansible_collections/community/general/tests/integration/targets/django_manage/files/base_test/startproj/.keep0
-rw-r--r--ansible_collections/community/general/tests/integration/targets/django_manage/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/django_manage/tasks/main.yaml84
-rw-r--r--ansible_collections/community/general/tests/integration/targets/dnf_versionlock/aliases9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/dnf_versionlock/tasks/install.yml10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/dnf_versionlock/tasks/lock_bash.yml36
-rw-r--r--ansible_collections/community/general/tests/integration/targets/dnf_versionlock/tasks/lock_updates.yml74
-rw-r--r--ansible_collections/community/general/tests/integration/targets/dnf_versionlock/tasks/main.yml12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/dpkg_divert/aliases10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/dpkg_divert/tasks/main.yml13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/dpkg_divert/tasks/prepare.yml43
-rw-r--r--ansible_collections/community/general/tests/integration/targets/dpkg_divert/tasks/tests/01-basic.yml291
-rw-r--r--ansible_collections/community/general/tests/integration/targets/dpkg_divert/tasks/tests/02-rename.yml384
-rw-r--r--ansible_collections/community/general/tests/integration/targets/etcd3/aliases12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/etcd3/meta/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/etcd3/tasks/main.yml18
-rw-r--r--ansible_collections/community/general/tests/integration/targets/etcd3/tasks/run_tests.yml81
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesize/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesize/defaults/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesize/tasks/basics.yml411
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesize/tasks/errors.yml133
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesize/tasks/floats.yml249
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesize/tasks/main.yml44
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesize/tasks/sparse.yml286
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesize/tasks/symlinks.yml97
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesystem/aliases10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesystem/defaults/main.yml35
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesystem/meta/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesystem/tasks/create_device.yml64
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesystem/tasks/create_fs.yml119
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesystem/tasks/freebsd_setup.yml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesystem/tasks/main.yml107
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesystem/tasks/overwrite_another_fs.yml59
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesystem/tasks/remove_fs.yml102
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesystem/tasks/setup.yml154
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesystem/vars/Ubuntu-14.04.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filesystem/vars/default.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_counter/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_counter/tasks/main.yml41
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_dict/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_dict/tasks/main.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_dict_kv/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_dict_kv/tasks/main.yml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_from_csv/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_from_csv/tasks/main.yml54
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_from_csv/vars/main.yml31
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_groupby_as_dict/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_groupby_as_dict/tasks/main.yml49
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_groupby_as_dict/vars/main.yml35
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_hashids/aliases6
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/filter_hashids/runme.sh15
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_hashids/runme.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_hashids/tasks/main.yml63
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_hashids/vars/main.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_jc/aliases7
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/filter_jc/runme.sh15
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_jc/runme.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_jc/tasks/main.yml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_json_query/aliases7
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/filter_json_query/runme.sh15
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_json_query/runme.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_json_query/tasks/main.yml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_json_query/vars/main.yml16
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_lists_mergeby/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_lists_mergeby/tasks/lists_mergeby_2-10.yml143
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_lists_mergeby/tasks/lists_mergeby_default.yml169
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_lists_mergeby/tasks/main.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_lists_mergeby/vars/main.yml209
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_path_join_shim/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_path_join_shim/tasks/main.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_random_mac/aliases7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_random_mac/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_random_mac/tasks/main.yml62
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_time/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_time/tasks/main.yml115
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_unicode_normalize/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_unicode_normalize/tasks/main.yml44
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_unicode_normalize/vars/main.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_version_sort/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/filter_version_sort/tasks/main.yml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/flatpak/aliases12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/flatpak/files/serve.py69
-rw-r--r--ansible_collections/community/general/tests/integration/targets/flatpak/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/flatpak/tasks/check_mode.yml197
-rw-r--r--ansible_collections/community/general/tests/integration/targets/flatpak/tasks/main.yml64
-rw-r--r--ansible_collections/community/general/tests/integration/targets/flatpak/tasks/setup.yml68
-rw-r--r--ansible_collections/community/general/tests/integration/targets/flatpak/tasks/test.yml289
-rw-r--r--ansible_collections/community/general/tests/integration/targets/flatpak_remote/aliases12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/flatpak_remote/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/flatpak_remote/tasks/check_mode.yml206
-rw-r--r--ansible_collections/community/general/tests/integration/targets/flatpak_remote/tasks/main.yml50
-rw-r--r--ansible_collections/community/general/tests/integration/targets/flatpak_remote/tasks/setup.yml40
-rw-r--r--ansible_collections/community/general/tests/integration/targets/flatpak_remote/tasks/test.yml135
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gandi_livedns/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gandi_livedns/defaults/main.yml37
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/create_record.yml69
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/record.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/remove_record.yml61
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/update_record.yml59
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gem/aliases9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gem/meta/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gem/tasks/main.yml213
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gem/vars/FreeBSD.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gem/vars/RedHat.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gem/vars/default.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config/aliases7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config/files/gitconfig6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config/tasks/exclusion_state_list-all.yml20
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config/tasks/get_set_no_state.yml29
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config/tasks/get_set_state_present.yml31
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config/tasks/get_set_state_present_file.yml32
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config/tasks/main.yml35
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config/tasks/precedence_between_unset_and_value.yml29
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config/tasks/set_value_with_tilde.yml37
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config/tasks/setup.yml15
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config/tasks/setup_no_value.yml16
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config/tasks/setup_value.yml16
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config/tasks/unset_check_mode.yml29
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config/tasks/unset_no_value.yml27
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config/tasks/unset_value.yml28
-rw-r--r--ansible_collections/community/general/tests/integration/targets/git_config/vars/main.yml10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/github_issue/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/github_issue/tasks/main.yml38
-rw-r--r--ansible_collections/community/general/tests/integration/targets/github_issue/vars/main.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_branch/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_branch/defaults/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_branch/tasks/main.yml69
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_deploy_key/aliases7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_deploy_key/defaults/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_deploy_key/tasks/main.yml78
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_group/aliases7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_group/defaults/main.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_group/tasks/main.yml129
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_group_members/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_group_members/tasks/main.yml74
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_group_members/vars/main.yml18
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_group_variable/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_group_variable/tasks/main.yml706
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_hook/aliases7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_hook/defaults/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_hook/tasks/main.yml77
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_project/aliases7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_project/defaults/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_project/tasks/main.yml49
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_project_badge/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_project_badge/defaults/main.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_project_badge/tasks/main.yml214
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_project_members/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_project_members/defaults/main.yml18
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_project_members/tasks/main.yml124
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_project_variable/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_project_variable/tasks/main.yml701
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_runner/aliases7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_runner/defaults/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_runner/tasks/main.yml78
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_user/aliases7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_user/defaults/main.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_user/tasks/main.yml257
-rw-r--r--ansible_collections/community/general/tests/integration/targets/gitlab_user/tasks/sshkey.yml139
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hg/aliases7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hg/meta/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hg/tasks/install.yml88
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hg/tasks/main.yml45
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hg/tasks/run-tests.yml85
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hg/tasks/uninstall.yml53
-rw-r--r--ansible_collections/community/general/tests/integration/targets/homebrew/aliases10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/homebrew/tasks/main.yml99
-rw-r--r--ansible_collections/community/general/tests/integration/targets/homebrew_cask/aliases10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/homebrew_cask/defaults/main.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/homebrew_cask/tasks/main.yml73
-rw-r--r--ansible_collections/community/general/tests/integration/targets/homectl/aliases11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/homectl/tasks/main.yml182
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hwc_ecs_instance/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hwc_ecs_instance/tasks/main.yml319
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hwc_evs_disk/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hwc_evs_disk/tasks/main.yml113
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hwc_network_vpc/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hwc_network_vpc/tasks/main.yml105
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hwc_smn_topic/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hwc_smn_topic/tasks/main.yml86
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hwc_vpc_eip/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hwc_vpc_eip/tasks/main.yml190
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hwc_vpc_peering_connect/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hwc_vpc_peering_connect/tasks/main.yml155
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hwc_vpc_port/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hwc_vpc_port/tasks/main.yml141
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hwc_vpc_private_ip/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hwc_vpc_private_ip/tasks/main.yml142
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hwc_vpc_route/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hwc_vpc_route/tasks/main.yml159
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hwc_vpc_security_group/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hwc_vpc_security_group/tasks/main.yml91
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hwc_vpc_security_group_rule/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hwc_vpc_security_group_rule/tasks/main.yml166
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hwc_vpc_subnet/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/hwc_vpc_subnet/tasks/main.yml152
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ilo_redfish_command/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ilo_redfish_command/tasks/main.yml12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ilo_redfish_config/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ilo_redfish_config/tasks/main.yml53
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ilo_redfish_info/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ilo_redfish_info/tasks/main.yml13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/influxdb_user/aliases11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/influxdb_user/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/influxdb_user/tasks/main.yml12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/influxdb_user/tasks/tests.yml143
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ini_file/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ini_file/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ini_file/tasks/main.yml40
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/00-basic.yml42
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/01-value.yml592
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/02-values.yml1023
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/03-encoding.yml44
-rw-r--r--ansible_collections/community/general/tests/integration/targets/interfaces_file/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/interfaces_file/files/interfaces_ff11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/interfaces_file/files/interfaces_ff_384111
-rw-r--r--ansible_collections/community/general/tests/integration/targets/interfaces_file/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/interfaces_file/tasks/main.yml67
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ipify_facts/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ipify_facts/tasks/main.yml33
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ipify_facts/vars/main.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iptables_state/aliases12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iptables_state/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iptables_state/tasks/main.yml38
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iptables_state/tasks/tests/00-basic.yml320
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iptables_state/tasks/tests/01-tables.yml294
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iptables_state/tasks/tests/10-rollback.yml203
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ipwcli_dns/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ipwcli_dns/tasks/main.yml115
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_create/aliases8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_create/files/test1.cfg61
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_create/files/test_dir/test2.cfg61
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_create/meta/main.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_create/tasks/main.yml163
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_create/tasks/prepare_dest_dir.yml13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_customize/aliases13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_customize/meta/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/iso_customize.yml75
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/iso_customize_add_files.yml34
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/iso_customize_delete_files.yml34
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/iso_customize_exception.yml71
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/iso_mount.yml39
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/main.yml94
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/prepare.yml40
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_extract/aliases13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_extract/files/test.isobin0 -> 374784 bytes
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_extract/files/test.iso.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_extract/meta/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_extract/tasks/7zip.yml54
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_extract/tasks/main.yml43
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_extract/tasks/prepare.yml21
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_extract/tasks/tests.yml40
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_extract/vars/Alpine.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_extract/vars/Archlinux.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_extract/vars/Debian.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_extract/vars/FreeBSD.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_extract/vars/RedHat.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_extract/vars/Suse.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_extract/vars/Ubuntu.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/iso_extract/vars/default.yml4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/java_cert/aliases11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/java_cert/defaults/main.yml19
-rw-r--r--ansible_collections/community/general/tests/integration/targets/java_cert/files/setupSSLServer.py24
-rw-r--r--ansible_collections/community/general/tests/integration/targets/java_cert/files/testpkcs.p12bin0 -> 2532 bytes
-rw-r--r--ansible_collections/community/general/tests/integration/targets/java_cert/files/testpkcs.p12.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/java_cert/meta/main.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/java_cert/tasks/main.yml116
-rw-r--r--ansible_collections/community/general/tests/integration/targets/java_cert/tasks/state_change.yml298
-rw-r--r--ansible_collections/community/general/tests/integration/targets/java_keystore/aliases11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/java_keystore/defaults/main.yml20
-rw-r--r--ansible_collections/community/general/tests/integration/targets/java_keystore/meta/main.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/java_keystore/tasks/main.yml43
-rw-r--r--ansible_collections/community/general/tests/integration/targets/java_keystore/tasks/prepare.yml37
-rw-r--r--ansible_collections/community/general/tests/integration/targets/java_keystore/tasks/tests.yml313
-rw-r--r--ansible_collections/community/general/tests/integration/targets/jboss/aliases12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/jboss/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/jboss/tasks/jboss.yml238
-rw-r--r--ansible_collections/community/general/tests/integration/targets/jboss/tasks/main.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/jira/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/jira/tasks/main.yml111
-rw-r--r--ansible_collections/community/general/tests/integration/targets/jira/vars/main.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/kdeconfig/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/kdeconfig/meta/main.yml7
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/kdeconfig/tasks/files/kwriteconf_fake38
-rw-r--r--ansible_collections/community/general/tests/integration/targets/kdeconfig/tasks/main.yml369
-rw-r--r--ansible_collections/community/general/tests/integration/targets/kernel_blacklist/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/kernel_blacklist/files/blacklist7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/kernel_blacklist/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/kernel_blacklist/tasks/main.yml111
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_authz_authorization_scope/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_authz_authorization_scope/readme.adoc27
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_authz_authorization_scope/tasks/main.yml234
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_authz_authorization_scope/vars/main.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_client/README.md17
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_client/docker-compose.yml31
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_client/tasks/main.yml63
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_client/vars/main.yml61
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_clientscope_type/README.md16
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_clientscope_type/docker-compose.yml16
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_clientscope_type/tasks/main.yml164
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_clientscope_type/vars/main.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_info/README.md17
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_info/docker-compose.yml31
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_info/tasks/main.yml48
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_info/vars/main.yml20
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_regenerate/README.md17
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_regenerate/docker-compose.yml31
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_regenerate/tasks/main.yml49
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_regenerate/vars/main.yml20
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_group/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_group/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_group/readme.adoc27
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_group/tasks/main.yml527
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_group/vars/main.yml10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_identity_provider/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_identity_provider/tasks/main.yml175
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_identity_provider/vars/main.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_role/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_role/tasks/main.yml250
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_role/vars/main.yml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_user_federation/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_user_federation/tasks/main.yml425
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_user_federation/vars/main.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_user_rolemapping/aliases4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_user_rolemapping/tasks/main.yml143
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keycloak_user_rolemapping/vars/main.yml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keyring/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keyring/tasks/main.yml99
-rw-r--r--ansible_collections/community/general/tests/integration/targets/keyring/vars/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/launchd/aliases7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/launchd/files/ansible_test_service.py24
-rw-r--r--ansible_collections/community/general/tests/integration/targets/launchd/tasks/main.yml30
-rw-r--r--ansible_collections/community/general/tests/integration/targets/launchd/tasks/setup.yml23
-rw-r--r--ansible_collections/community/general/tests/integration/targets/launchd/tasks/teardown.yml30
-rw-r--r--ansible_collections/community/general/tests/integration/targets/launchd/tasks/test.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/launchd/tasks/tests/test_reload.yml71
-rw-r--r--ansible_collections/community/general/tests/integration/targets/launchd/tasks/tests/test_restart.yml46
-rw-r--r--ansible_collections/community/general/tests/integration/targets/launchd/tasks/tests/test_runatload.yml36
-rw-r--r--ansible_collections/community/general/tests/integration/targets/launchd/tasks/tests/test_start_stop.yml115
-rw-r--r--ansible_collections/community/general/tests/integration/targets/launchd/tasks/tests/test_unknown.yml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/launchd/tasks/tests/test_unload.yml65
-rw-r--r--ansible_collections/community/general/tests/integration/targets/launchd/templates/launchd.test.service.plist.j218
-rw-r--r--ansible_collections/community/general/tests/integration/targets/launchd/templates/modified.launchd.test.service.plist.j218
-rw-r--r--ansible_collections/community/general/tests/integration/targets/launchd/vars/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ldap_search/aliases11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ldap_search/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ldap_search/tasks/main.yml16
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ldap_search/tasks/tests/basic.yml25
-rw-r--r--ansible_collections/community/general/tests/integration/targets/listen_ports_facts/aliases10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/listen_ports_facts/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/listen_ports_facts/tasks/main.yml112
-rw-r--r--ansible_collections/community/general/tests/integration/targets/locale_gen/aliases8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/locale_gen/tasks/locale_gen.yml99
-rw-r--r--ansible_collections/community/general/tests/integration/targets/locale_gen/tasks/main.yml12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_cartesian/aliases7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_cartesian/tasks/main.yml32
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_collection_version/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll/galaxy.yml12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll/plugins/modules/collection_module.py33
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_mf/FILES.json40
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_mf/FILES.json.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_mf/MANIFEST.json30
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_mf/MANIFEST.json.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_mf/README.md0
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_mf/plugins/modules/collection_module.py33
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_nothing/plugins/modules/collection_module.py33
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_nv/galaxy.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_nv/plugins/modules/collection_module.py33
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_collection_version/library/local_module.py33
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/lookup_collection_version/runme.sh20
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_collection_version/runme.yml40
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_dependent/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_dependent/tasks/main.yml183
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_dig/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_dig/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_dig/tasks/main.yml37
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_etcd3/aliases14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_etcd3/defaults/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_etcd3/dependencies.yml10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_etcd3/meta/main.yml7
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/lookup_etcd3/runme.sh11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_etcd3/tasks/main.yml28
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_etcd3/tasks/tests.yml27
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_etcd3/test_lookup_etcd3.yml10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_flattened/aliases7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_flattened/tasks/main.yml24
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/aliases8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/dependencies.yml16
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/runme.sh11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/test.yml31
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/test_db.py15
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/aliases6
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/lookup_merge_variables/runme.sh13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test.yml174
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test_with_env.yml44
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/vars.yml34
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/aliases11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/tasks/main.yml17
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/tasks/package.yml84
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/tasks/password_tests.yml130
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/tasks/tests.yml239
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/templates/input9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/templates/input.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/templates/security-privacy.repo.j213
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/Alpine.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/Archlinux.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/Debian.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/Fedora.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/FreeBSD.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/default.yml4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/main.yml122
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_random_pet/aliases7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_random_pet/dependencies.yml10
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/lookup_random_pet/runme.sh11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_random_pet/test.yml30
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_random_string/aliases7
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/lookup_random_string/runme.sh8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_random_string/test.yml53
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_random_words/aliases7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_random_words/dependencies.yml10
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/lookup_random_words/runme.sh11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lookup_random_words/test.yml32
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvg/aliases12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvg/meta/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvg/tasks/main.yml27
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvg/tasks/setup.yml27
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvg/tasks/teardown.yml23
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_grow_reduce.yml38
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_indempotency.yml20
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_pvresize.yml81
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lxd_project/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/lxd_project/tasks/main.yml142
-rw-r--r--ansible_collections/community/general/tests/integration/targets/mail/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/mail/files/smtpserver.crt26
-rw-r--r--ansible_collections/community/general/tests/integration/targets/mail/files/smtpserver.key32
-rw-r--r--ansible_collections/community/general/tests/integration/targets/mail/files/smtpserver.py69
-rw-r--r--ansible_collections/community/general/tests/integration/targets/mail/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/mail/tasks/main.yml105
-rw-r--r--ansible_collections/community/general/tests/integration/targets/mas/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/mas/tasks/main.yml158
-rw-r--r--ansible_collections/community/general/tests/integration/targets/memset_dns_reload/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/memset_dns_reload/meta/main.yml4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/memset_dns_reload/tasks/main.yml33
-rw-r--r--ansible_collections/community/general/tests/integration/targets/memset_memstore_info/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/memset_memstore_info/meta/main.yml4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/memset_memstore_info/tasks/main.yml34
-rw-r--r--ansible_collections/community/general/tests/integration/targets/memset_server_info/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/memset_server_info/meta/main.yml4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/memset_server_info/tasks/main.yml34
-rw-r--r--ansible_collections/community/general/tests/integration/targets/memset_zone/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/memset_zone/meta/main.yml4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/memset_zone/tasks/main.yml125
-rw-r--r--ansible_collections/community/general/tests/integration/targets/memset_zone/vars/main.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/memset_zone_domain/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/memset_zone_domain/meta/main.yml4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/memset_zone_domain/tasks/main.yml152
-rw-r--r--ansible_collections/community/general/tests/integration/targets/memset_zone_domain/vars/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/memset_zone_record/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/memset_zone_record/meta/main.yml4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/memset_zone_record/tasks/main.yml235
-rw-r--r--ansible_collections/community/general/tests/integration/targets/memset_zone_record/vars/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/module_helper/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/module_helper/library/mdepfail.py70
-rw-r--r--ansible_collections/community/general/tests/integration/targets/module_helper/library/msimple.py78
-rw-r--r--ansible_collections/community/general/tests/integration/targets/module_helper/library/msimpleda.py66
-rw-r--r--ansible_collections/community/general/tests/integration/targets/module_helper/library/mstate.py78
-rw-r--r--ansible_collections/community/general/tests/integration/targets/module_helper/tasks/main.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/module_helper/tasks/mdepfail.yml18
-rw-r--r--ansible_collections/community/general/tests/integration/targets/module_helper/tasks/msimple.yml85
-rw-r--r--ansible_collections/community/general/tests/integration/targets/module_helper/tasks/msimple_output_conflict.yml54
-rw-r--r--ansible_collections/community/general/tests/integration/targets/module_helper/tasks/msimpleda.yml39
-rw-r--r--ansible_collections/community/general/tests/integration/targets/module_helper/tasks/mstate.yml83
-rw-r--r--ansible_collections/community/general/tests/integration/targets/monit/aliases14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/monit/defaults/main.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/monit/files/httpd_echo.py51
-rw-r--r--ansible_collections/community/general/tests/integration/targets/monit/meta/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/monit/tasks/check_state.yml21
-rw-r--r--ansible_collections/community/general/tests/integration/targets/monit/tasks/main.yml99
-rw-r--r--ansible_collections/community/general/tests/integration/targets/monit/tasks/test.yml33
-rw-r--r--ansible_collections/community/general/tests/integration/targets/monit/tasks/test_errors.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/monit/tasks/test_reload_present.yml65
-rw-r--r--ansible_collections/community/general/tests/integration/targets/monit/tasks/test_state.yml38
-rw-r--r--ansible_collections/community/general/tests/integration/targets/monit/templates/monitrc.j219
-rw-r--r--ansible_collections/community/general/tests/integration/targets/monit/vars/Alpine.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/monit/vars/Archlinux.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/monit/vars/CentOS-6.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/monit/vars/RedHat.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/monit/vars/Suse.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/monit/vars/defaults.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/mqtt/aliases10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/mqtt/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/mqtt/tasks/main.yml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/mqtt/tasks/ubuntu.yml147
-rw-r--r--ansible_collections/community/general/tests/integration/targets/mssql_script/aliases10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/mssql_script/defaults/main.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/mssql_script/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/mssql_script/tasks/main.yml246
-rw-r--r--ansible_collections/community/general/tests/integration/targets/nomad/aliases10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/nomad/files/job.hcl400
-rw-r--r--ansible_collections/community/general/tests/integration/targets/nomad/meta/main.yml10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/nomad/tasks/main.yml111
-rw-r--r--ansible_collections/community/general/tests/integration/targets/nomad/tasks/nomad_job.yml111
-rw-r--r--ansible_collections/community/general/tests/integration/targets/npm/aliases8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/npm/meta/main.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/npm/tasks/main.yml32
-rw-r--r--ansible_collections/community/general/tests/integration/targets/npm/tasks/no_bin_links.yml68
-rw-r--r--ansible_collections/community/general/tests/integration/targets/npm/tasks/run.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/npm/tasks/setup.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/npm/tasks/test.yml74
-rw-r--r--ansible_collections/community/general/tests/integration/targets/odbc/aliases12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/odbc/defaults/main.yml38
-rw-r--r--ansible_collections/community/general/tests/integration/targets/odbc/meta/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/odbc/tasks/install_pyodbc.yml12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/odbc/tasks/main.yml158
-rw-r--r--ansible_collections/community/general/tests/integration/targets/odbc/tasks/negative_tests.yml24
-rw-r--r--ansible_collections/community/general/tests/integration/targets/odbc/tasks/no_pyodbc.yml16
-rw-r--r--ansible_collections/community/general/tests/integration/targets/one_host/aliases7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/one_host/files/testhost/tmp/opennebula-fixtures.json.gzbin0 -> 2950 bytes
-rw-r--r--ansible_collections/community/general/tests/integration/targets/one_host/files/testhost/tmp/opennebula-fixtures.json.gz.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/one_host/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/one_host/tasks/main.yml243
-rw-r--r--ansible_collections/community/general/tests/integration/targets/one_template/aliases7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/one_template/files/testhost/tmp/opennebula-fixtures.json.gzbin0 -> 1069 bytes
-rw-r--r--ansible_collections/community/general/tests/integration/targets/one_template/files/testhost/tmp/opennebula-fixtures.json.gz.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/one_template/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/one_template/tasks/main.yml246
-rw-r--r--ansible_collections/community/general/tests/integration/targets/osx_defaults/aliases9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/osx_defaults/tasks/main.yml255
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pacman/aliases12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pacman/meta/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pacman/tasks/basic.yml86
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pacman/tasks/locally_installed_package.yml85
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pacman/tasks/main.yml19
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pacman/tasks/package_urls.yml219
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pacman/tasks/reason.yml101
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pacman/tasks/remove_nosave.yml74
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pacman/tasks/update_cache.yml27
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pagerduty_user/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pagerduty_user/tasks/main.yml25
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pagerduty_user/vars/main.yml10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pam_limits/aliases9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pam_limits/files/test_pam_limits.conf5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pam_limits/tasks/main.yml92
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pamd/aliases9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pamd/tasks/main.yml74
-rw-r--r--ansible_collections/community/general/tests/integration/targets/parted/aliases13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/parted/handlers/main.yml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/parted/tasks/main.yml86
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pids/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pids/files/sleeper.c13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pids/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pids/tasks/main.yml120
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pids/templates/obtainpid.sh7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pipx/aliases8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pipx/tasks/main.yml316
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pipx_info/aliases8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pipx_info/tasks/main.yml140
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pkgng/aliases9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pkgng/tasks/create-outofdate-pkg.yml52
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pkgng/tasks/freebsd.yml551
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pkgng/tasks/install_single_package.yml58
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pkgng/tasks/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pkgng/tasks/setup-testjail.yml100
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pkgng/templates/MANIFEST.json.j216
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pkgng/templates/MANIFEST.json.j2.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pkgng/vars/main.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pkgutil/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/pkgutil/tasks/main.yml117
-rw-r--r--ansible_collections/community/general/tests/integration/targets/proxmox/aliases9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/proxmox/tasks/main.yml579
-rw-r--r--ansible_collections/community/general/tests/integration/targets/python_requirements_info/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/python_requirements_info/tasks/main.yml45
-rw-r--r--ansible_collections/community/general/tests/integration/targets/read_csv/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/read_csv/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/read_csv/tasks/main.yml176
-rw-r--r--ansible_collections/community/general/tests/integration/targets/redis_info/aliases10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/redis_info/defaults/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/redis_info/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/redis_info/tasks/main.yml48
-rw-r--r--ansible_collections/community/general/tests/integration/targets/rundeck/aliases12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/rundeck/defaults/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/rundeck/files/test_job.yaml28
-rw-r--r--ansible_collections/community/general/tests/integration/targets/rundeck/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/rundeck/tasks/main.yml127
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_compute/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_compute/defaults/main.yml13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_compute/tasks/ip.yml206
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_compute/tasks/main.yml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_compute/tasks/pagination.yml76
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_compute/tasks/security_group.yml152
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_compute/tasks/state.yml392
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_container/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_container/defaults/main.yml18
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_container/tasks/main.yml290
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_container_info/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_container_info/defaults/main.yml16
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_container_info/tasks/main.yml63
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_container_namespace/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_container_namespace/defaults/main.yml15
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_container_namespace/tasks/main.yml255
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_container_namespace_info/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_container_namespace_info/defaults/main.yml13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_container_namespace_info/tasks/main.yml41
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_container_registry/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_container_registry/defaults/main.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_container_registry/tasks/main.yml178
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_container_registry_info/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_container_registry_info/defaults/main.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_container_registry_info/tasks/main.yml41
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_database_backup/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_database_backup/defaults/main.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_database_backup/tasks/main.yml238
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_function/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_function/defaults/main.yml17
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_function/tasks/main.yml284
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_function_info/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_function_info/defaults/main.yml15
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_function_info/tasks/main.yml62
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_function_namespace/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_function_namespace/defaults/main.yml15
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_function_namespace/tasks/main.yml260
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_function_namespace_info/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_function_namespace_info/defaults/main.yml13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_function_namespace_info/tasks/main.yml43
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_image_info/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_image_info/tasks/main.yml37
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_ip/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_ip/defaults/main.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_ip/tasks/main.yml449
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_ip_info/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_ip_info/tasks/main.yml37
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_lb/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_lb/defaults/main.yml12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_lb/tasks/main.yml224
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_organization_info/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_organization_info/tasks/main.yml22
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_security_group/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_security_group/defaults/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_security_group/tasks/main.yml139
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_security_group_info/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_security_group_info/tasks/main.yml37
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_security_group_rule/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_security_group_rule/defaults/main.yml12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_security_group_rule/tasks/main.yml252
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_server_info/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_server_info/tasks/main.yml37
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_snapshot_info/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_snapshot_info/tasks/main.yml37
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_sshkey/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_sshkey/tasks/main.yml49
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_user_data/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_user_data/defaults/main.yml18
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_user_data/tasks/main.yml87
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_volume/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_volume/defaults/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_volume/tasks/main.yml51
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_volume_info/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/scaleway_volume_info/tasks/main.yml37
-rw-r--r--ansible_collections/community/general/tests/integration/targets/sefcontext/aliases7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/sefcontext/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/sefcontext/tasks/main.yml21
-rw-r--r--ansible_collections/community/general/tests/integration/targets/sefcontext/tasks/sefcontext.yml233
-rw-r--r--ansible_collections/community/general/tests/integration/targets/sensu_client/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/sensu_client/tasks/main.yml179
-rw-r--r--ansible_collections/community/general/tests/integration/targets/sensu_handler/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/sensu_handler/tasks/main.yml129
-rw-r--r--ansible_collections/community/general/tests/integration/targets/sensu_handler/tasks/pipe.yml25
-rw-r--r--ansible_collections/community/general/tests/integration/targets/sensu_handler/tasks/set.yml53
-rw-r--r--ansible_collections/community/general/tests/integration/targets/sensu_handler/tasks/tcp.yml56
-rw-r--r--ansible_collections/community/general/tests/integration/targets/sensu_handler/tasks/transport.yml56
-rw-r--r--ansible_collections/community/general/tests/integration/targets/sensu_handler/tasks/udp.yml56
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_cron/defaults/main.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_cron/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_cron/tasks/main.yml75
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_cron/vars/alpine.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_cron/vars/archlinux.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_cron/vars/debian.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_cron/vars/default.yml4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_cron/vars/fedora.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_cron/vars/freebsd.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_cron/vars/redhat.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_cron/vars/suse.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_docker/README.md73
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_docker/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_docker/defaults/main.yml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_docker/handlers/main.yml19
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_docker/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_docker/tasks/D-Fedora.yml33
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_docker/tasks/default.yml21
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_docker/tasks/main.yml55
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_docker/vars/D-Fedora.yml10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_docker/vars/D-Ubuntu.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_epel/tasks/main.yml25
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_etcd3/defaults/main.yml17
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_etcd3/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_etcd3/tasks/main.yml104
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_etcd3/vars/RedHat-7.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_etcd3/vars/Suse-py3.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_etcd3/vars/Suse.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_etcd3/vars/default.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/README.md144
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/create-repo.sh63
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/files/repo.tar.xzbin0 -> 7352 bytes
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/files/repo.tar.xz.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/handlers/main.yaml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/meta/main.yaml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/tasks/main.yaml32
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_gnutar/handlers/main.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_gnutar/tasks/main.yml24
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_influxdb/tasks/main.yml12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_influxdb/tasks/setup.yml29
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_java_keytool/meta/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_java_keytool/tasks/main.yml26
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/Alpine.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/Archlinux.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/Debian.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/RedHat.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/Suse.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_mosquitto/files/mosquitto.conf39
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_mosquitto/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_mosquitto/tasks/main.yml12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_mosquitto/tasks/ubuntu.yml29
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_openldap/files/initial_config.ldif22
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_openldap/files/initial_config.ldif.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_openldap/files/rootpw_cnconfig.ldif4
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_openldap/files/rootpw_cnconfig.ldif.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_openldap/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_openldap/tasks/main.yml72
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_openldap/vars/Debian.yml60
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_openldap/vars/Ubuntu.yml60
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_opennebula/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_opennebula/tasks/main.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_opennebula/vars/main.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_openssl/meta/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_openssl/tasks/main.yml69
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/Alpine.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/Archlinux.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/CentOS-8.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/Darwin.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/Debian.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/FreeBSD.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/RedHat-9.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/RedHat.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/Suse.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_pkg_mgr/tasks/archlinux.yml23
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_pkg_mgr/tasks/main.yml39
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/defaults/main.yml22
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/files/dummy--1.0.sql6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/files/dummy--2.0.sql6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/files/dummy--3.0.sql6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/files/dummy.control3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/files/dummy.control.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/files/pg_hba.conf14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/tasks/main.yml257
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Alpine-py3.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Archlinux-py3.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Debian-11-py3.yml13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Debian-8.yml13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/FreeBSD-11-py3.yml17
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/FreeBSD-11.yml17
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/FreeBSD-12.0-py3.yml17
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/FreeBSD-12.0.yml17
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/FreeBSD-12.1-py3.yml17
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/FreeBSD-12.1.yml17
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/RedHat-py3.yml13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/RedHat.yml12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-12.yml13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-14.yml13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-16-py3.yml13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-16.yml13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-18-py3.yml13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-20-py3.yml13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-22-py3.yml13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/default-py3.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/default.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_redis_replication/defaults/main.yml56
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_redis_replication/handlers/main.yml39
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_redis_replication/meta/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_redis_replication/tasks/main.yml12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_redis_replication/tasks/setup_redis_cluster.yml78
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_remote_constraints/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_remote_constraints/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_remote_constraints/tasks/main.yml18
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir/handlers/main.yml10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir/tasks/default-cleanup.yml10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir/tasks/default.yml16
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir/tasks/main.yml20
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir_outside_tmp/handlers/main.yml10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir_outside_tmp/tasks/default-cleanup.yml10
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir_outside_tmp/tasks/default.yml22
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir_outside_tmp/tasks/main.yml20
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_rundeck/defaults/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_rundeck/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_rundeck/tasks/main.yml41
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_rundeck/vars/Alpine.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_rundeck/vars/Archlinux.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_rundeck/vars/Debian.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_rundeck/vars/RedHat.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_snap/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_snap/defaults/main.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_snap/handlers/main.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_snap/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-Fedora.yml25
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-RedHat-8.2.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-RedHat-8.3.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-RedHat-9.0.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-RedHat-9.1.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-Ubuntu.yml19
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/Debian.yml25
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/RedHat.yml25
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/default.yml25
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/main.yml34
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/nothing.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_tls/files/ca_certificate.pem23
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_tls/files/ca_key.pem32
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_tls/files/client_certificate.pem24
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_tls/files/client_key.pem31
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_tls/files/server_certificate.pem24
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_tls/files/server_key.pem31
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_tls/tasks/main.yml30
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/defaults/main.yml13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/files/wildfly.conf12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/handlers/main.yml18
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/meta/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/tasks/main.yml107
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/templates/launch.sh.j214
-rw-r--r--ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/templates/wildfly.service.j220
-rw-r--r--ansible_collections/community/general/tests/integration/targets/shutdown/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/shutdown/tasks/main.yml93
-rw-r--r--ansible_collections/community/general/tests/integration/targets/snap/aliases13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/snap/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/snap/tasks/main.yml243
-rw-r--r--ansible_collections/community/general/tests/integration/targets/snap_alias/aliases13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/snap_alias/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/snap_alias/tasks/main.yml13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/snap_alias/tasks/test.yml159
-rw-r--r--ansible_collections/community/general/tests/integration/targets/spectrum_model_attrs/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/spectrum_model_attrs/tasks/main.yml78
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ssh_config/aliases9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ssh_config/files/fake_id_rsa0
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ssh_config/files/ssh_config_test0
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ssh_config/meta/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ssh_config/tasks/main.yml245
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ssh_config/tasks/options.yml422
-rw-r--r--ansible_collections/community/general/tests/integration/targets/sudoers/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/sudoers/tasks/main.yml279
-rw-r--r--ansible_collections/community/general/tests/integration/targets/supervisorctl/aliases8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/supervisorctl/files/sendProcessStdin.py31
-rw-r--r--ansible_collections/community/general/tests/integration/targets/supervisorctl/meta/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/install_Darwin.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/install_FreeBSD.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/install_Linux.yml15
-rw-r--r--ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/install_RedHat.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/install_Suse.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/install_pip.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/main.yml57
-rw-r--r--ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/start_supervisord.yml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/stop_supervisord.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/test.yml17
-rw-r--r--ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/test_start.yml140
-rw-r--r--ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/test_stop.yml64
-rw-r--r--ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/uninstall_Darwin.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/uninstall_FreeBSD.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/uninstall_Linux.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/uninstall_RedHat.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/uninstall_Suse.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/uninstall_pip.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/supervisorctl/templates/supervisord.conf48
-rw-r--r--ansible_collections/community/general/tests/integration/targets/supervisorctl/vars/Debian.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/supervisorctl/vars/defaults.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/sysrc/aliases9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/sysrc/tasks/main.yml343
-rw-r--r--ansible_collections/community/general/tests/integration/targets/sysrc/tasks/setup-testjail.yml73
-rw-r--r--ansible_collections/community/general/tests/integration/targets/terraform/.gitignore8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/terraform/aliases11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/terraform/files/complex_variables/main.tf35
-rw-r--r--ansible_collections/community/general/tests/integration/targets/terraform/files/complex_variables/variables.tf62
-rw-r--r--ansible_collections/community/general/tests/integration/targets/terraform/meta/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/terraform/tasks/complex_variables.yml60
-rw-r--r--ansible_collections/community/general/tests/integration/targets/terraform/tasks/main.yml67
-rw-r--r--ansible_collections/community/general/tests/integration/targets/terraform/tasks/test_provider_upgrade.yml35
-rw-r--r--ansible_collections/community/general/tests/integration/targets/terraform/templates/provider_test/main.tf.j213
-rw-r--r--ansible_collections/community/general/tests/integration/targets/terraform/vars/main.yml40
-rw-r--r--ansible_collections/community/general/tests/integration/targets/test_a_module/aliases5
-rw-r--r--ansible_collections/community/general/tests/integration/targets/test_a_module/collections/ansible_collections/testns/testcoll/galaxy.yml12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/test_a_module/collections/ansible_collections/testns/testcoll/plugins/modules/collection_module.py33
-rw-r--r--ansible_collections/community/general/tests/integration/targets/test_a_module/library/local_module.py33
-rwxr-xr-xansible_collections/community/general/tests/integration/targets/test_a_module/runme.sh20
-rw-r--r--ansible_collections/community/general/tests/integration/targets/test_a_module/runme.yml42
-rw-r--r--ansible_collections/community/general/tests/integration/targets/timezone/aliases9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/timezone/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/timezone/tasks/main.yml96
-rw-r--r--ansible_collections/community/general/tests/integration/targets/timezone/tasks/test.yml612
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ufw/aliases17
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ufw/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ufw/tasks/main.yml45
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ufw/tasks/run-test.yml25
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ufw/tasks/tests/basic.yml406
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ufw/tasks/tests/global-state.yml154
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ufw/tasks/tests/insert_relative_to.yml84
-rw-r--r--ansible_collections/community/general/tests/integration/targets/ufw/tasks/tests/interface.yml86
-rw-r--r--ansible_collections/community/general/tests/integration/targets/wakeonlan/aliases6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/wakeonlan/tasks/main.yml58
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xattr/aliases12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xattr/defaults/main.yml6
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xattr/meta/main.yml8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xattr/tasks/main.yml21
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xattr/tasks/setup.yml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xattr/tasks/test.yml72
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xfs_quota/aliases12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xfs_quota/defaults/main.yml46
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xfs_quota/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xfs_quota/tasks/gquota.yml147
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xfs_quota/tasks/main.yml37
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xfs_quota/tasks/pquota.yml184
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xfs_quota/tasks/uquota.yml147
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/aliases7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/fixtures/ansible-xml-beers-unicode.xml13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/fixtures/ansible-xml-beers-unicode.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/fixtures/ansible-xml-beers.xml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/fixtures/ansible-xml-beers.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/fixtures/ansible-xml-namespaced-beers.xml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/fixtures/ansible-xml-namespaced-beers.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-elements-unicode.xml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-elements-unicode.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-elements.xml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-elements.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-from-groupvars.xml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-from-groupvars.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-insertafter.xml17
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-insertafter.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-insertbefore.xml17
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-insertbefore.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-with-attributes-unicode.xml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-with-attributes-unicode.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-with-attributes.xml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-with-attributes.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-add-element-implicitly.xml32
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-add-element-implicitly.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-add-namespaced-children-elements.xml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-add-namespaced-children-elements.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-pretty-print-only.xml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-pretty-print-only.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-pretty-print.xml15
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-pretty-print.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-attribute.xml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-attribute.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-element.xml13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-element.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-namespaced-attribute.xml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-namespaced-attribute.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-namespaced-element.xml13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-namespaced-element.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-set-attribute-value-unicode.xml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-set-attribute-value-unicode.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-set-attribute-value.xml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-set-attribute-value.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements-empty-list.xml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements-empty-list.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements-level.xml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements-level.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements-unicode.xml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements-unicode.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements.xml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-set-element-value-empty.xml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-set-element-value-empty.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-set-element-value-unicode.xml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-set-element-value-unicode.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-set-element-value.xml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-set-element-value.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-set-namespaced-attribute-value.xml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-set-namespaced-attribute-value.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-set-namespaced-element-value.xml14
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/results/test-set-namespaced-element-value.xml.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/main.yml77
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-elements-unicode.yml36
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-elements.yml36
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-from-groupvars.yml35
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-insertafter.yml36
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-insertbefore.yml36
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-with-attributes-unicode.yml38
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-with-attributes.yml42
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-element-implicitly.yml241
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-namespaced-children-elements.yml39
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-children-elements-xml.yml37
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-count-unicode.yml23
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-count.yml23
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-get-element-content-unicode.yml36
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-get-element-content.yml51
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-mutually-exclusive-attributes.yml26
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-pretty-print-only.yml33
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-pretty-print.yml34
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-attribute-nochange.yml32
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-attribute.yml35
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-element-nochange.yml32
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-element.yml35
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-namespaced-attribute-nochange.yml37
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-namespaced-attribute.yml40
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-namespaced-element-nochange.yml37
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-namespaced-element.yml40
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-attribute-value-unicode.yml36
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-attribute-value.yml36
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-children-elements-level.yml81
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-children-elements-unicode.yml53
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-children-elements.yml86
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-element-value-empty.yml35
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-element-value-unicode.yml50
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-element-value.yml50
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-namespaced-attribute-value.yml41
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-namespaced-children-elements.yml61
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-namespaced-element-value.yml53
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/tasks/test-xmlstring.yml85
-rw-r--r--ansible_collections/community/general/tests/integration/targets/xml/vars/main.yml11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/yarn/aliases8
-rw-r--r--ansible_collections/community/general/tests/integration/targets/yarn/meta/main.yml9
-rw-r--r--ansible_collections/community/general/tests/integration/targets/yarn/tasks/main.yml23
-rw-r--r--ansible_collections/community/general/tests/integration/targets/yarn/tasks/run.yml233
-rw-r--r--ansible_collections/community/general/tests/integration/targets/yarn/templates/package.j214
-rw-r--r--ansible_collections/community/general/tests/integration/targets/yum_versionlock/aliases11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/yum_versionlock/tasks/main.yml87
-rw-r--r--ansible_collections/community/general/tests/integration/targets/zypper/aliases11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/zypper/files/empty.spec12
-rw-r--r--ansible_collections/community/general/tests/integration/targets/zypper/files/empty.spec.license3
-rw-r--r--ansible_collections/community/general/tests/integration/targets/zypper/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/zypper/tasks/main.yml15
-rw-r--r--ansible_collections/community/general/tests/integration/targets/zypper/tasks/zypper.yml530
-rw-r--r--ansible_collections/community/general/tests/integration/targets/zypper/templates/duplicate.spec.j224
-rw-r--r--ansible_collections/community/general/tests/integration/targets/zypper_repository/aliases11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/zypper_repository/files/systemsmanagement_Uyuni_Utils.repo11
-rw-r--r--ansible_collections/community/general/tests/integration/targets/zypper_repository/meta/main.yml7
-rw-r--r--ansible_collections/community/general/tests/integration/targets/zypper_repository/tasks/main.yml13
-rw-r--r--ansible_collections/community/general/tests/integration/targets/zypper_repository/tasks/test.yml40
-rw-r--r--ansible_collections/community/general/tests/integration/targets/zypper_repository/tasks/zypper_repository.yml289
1166 files changed, 54855 insertions, 0 deletions
diff --git a/ansible_collections/community/general/tests/integration/requirements.yml b/ansible_collections/community/general/tests/integration/requirements.yml
new file mode 100644
index 000000000..b772fc82d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/requirements.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+collections:
+- ansible.posix
+- community.crypto
+- community.docker
diff --git a/ansible_collections/community/general/tests/integration/targets/aix_devices/aliases b/ansible_collections/community/general/tests/integration/targets/aix_devices/aliases
new file mode 100644
index 000000000..8d841c56b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/aix_devices/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# No AIX LPAR available
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/aix_devices/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/aix_devices/tasks/main.yml
new file mode 100644
index 000000000..284f46c33
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/aix_devices/tasks/main.yml
@@ -0,0 +1,81 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Scan new devices.
+ aix_devices:
+ device: all
+ state: present
+
+- name: Scan new virtual devices (vio0).
+ aix_devices:
+ device: vio0
+ state: present
+
+- name: Removing IP alias to en0
+ aix_devices:
+ device: en0
+ attributes:
+ delalias4: 10.0.0.100,255.255.255.0
+
+- name: Removes ent2.
+ aix_devices:
+ device: ent2
+ state: absent
+
+- name: Put device en2 in Defined
+ aix_devices:
+ device: en2
+ state: defined
+
+- name: Removes ent4 (inexistent).
+ aix_devices:
+ device: ent4
+ state: absent
+
+- name: Put device en4 in Defined (inexistent)
+ aix_devices:
+ device: en4
+ state: defined
+
+- name: Put vscsi1 and children devices in Defined state.
+ aix_devices:
+ device: vscsi1
+ recursive: true
+ state: defined
+
+- name: Removes vscsi1 and children devices.
+ aix_devices:
+ device: vscsi1
+ recursive: true
+ state: absent
+
+- name: Changes en1 mtu to 9000 and disables arp.
+ aix_devices:
+ device: en1
+ attributes:
+ mtu: 900
+ arp: 'off'
+ state: present
+
+- name: Configure IP, netmask and set en1 up.
+ aix_devices:
+ device: en1
+ attributes:
+ netaddr: 192.168.0.100
+ netmask: 255.255.255.0
+ state: up
+ state: present
+
+- name: Adding IP alias to en0
+ aix_devices:
+ device: en0
+ attributes:
+ alias4: 10.0.0.100,255.255.255.0
+ state: present
diff --git a/ansible_collections/community/general/tests/integration/targets/aix_filesystem/aliases b/ansible_collections/community/general/tests/integration/targets/aix_filesystem/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/aix_filesystem/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/aix_filesystem/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/aix_filesystem/tasks/main.yml
new file mode 100644
index 000000000..25146062d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/aix_filesystem/tasks/main.yml
@@ -0,0 +1,130 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Umounting /testfs
+ aix_filesystem:
+ filesystem: /testfs
+ state: unmounted
+
+- name: Removing /testfs
+ aix_filesystem:
+ filesystem: /testfs
+ state: absent
+
+- name: Creating a new file system
+ aix_filesystem:
+ filesystem: /newfs
+ size: 1G
+ state: present
+ vg: datavg
+
+# It requires a host (nfshost) exporting the NFS
+- name: Creating NFS filesystem from nfshost (Linux NFS server)
+ aix_filesystem:
+ device: /home/ftp
+ nfs_server: nfshost
+ filesystem: /nfs/ftp
+ state: present
+
+# It requires a volume group named datavg (next three actions)
+- name: Creating a logical volume testlv (aix_lvol module)
+ aix_lvol:
+ vg: datavg
+ lv: testlv
+ size: 2G
+ state: present
+
+- name: Create filesystem in a previously defined logical volume
+ aix_filesystem:
+ device: testlv
+ filesystem: /testfs
+ state: present
+
+- name: Create an already existing filesystem using existing logical volume.
+ aix_filesystem:
+ vg: datavg
+ device: mksysblv
+ filesystem: /mksysb
+ state: present
+
+- name: Create a filesystem in a non-existing VG
+ aix_filesystem:
+ vg: nonexistvg
+ filesystem: /newlv
+ state: present
+
+- name: Resizing /mksysb to 1G
+ aix_filesystem:
+ filesystem: /mksysb
+ size: 1G
+ state: present
+
+- name: Resizing /mksysb to +512M
+ aix_filesystem:
+ filesystem: /mksysb
+ size: +512M
+ state: present
+
+- name: Resizing /mksysb to 11G
+ aix_filesystem:
+ filesystem: /mksysb
+ size: 11G
+ state: present
+
+- name: Resizing /mksysb to 11G (already done)
+ aix_filesystem:
+ filesystem: /mksysb
+ size: 11G
+ state: present
+
+- name: Resizing /mksysb to -2G
+ aix_filesystem:
+ filesystem: /mksysb
+ size: -2G
+ state: present
+
+- name: Resizing /mksysb to 100G (no enought space)
+ aix_filesystem:
+ filesystem: /mksysb
+ size: +100G
+ state: present
+
+- name: Unmount filesystem /home/ftp
+ aix_filesystem:
+ filesystem: /home/ftp
+ state: unmounted
+
+- name: Remove NFS filesystem /home/ftp
+ aix_filesystem:
+ filesystem: /home/ftp
+ rm_mount_point: true
+ state: absent
+
+- name: Mount filesystem /newfs
+ aix_filesystem:
+ filesystem: /newfs
+ state: mounted
+
+- name: Remove mounted /newfs
+ aix_filesystem:
+ filesystem: /newfs
+ rm_mount_point: true
+ state: absent
+
+- name: Umount /newfs
+ aix_filesystem:
+ filesystem: /newfs
+ state: unmounted
+
+- name: Remove /newfs
+ aix_filesystem:
+ filesystem: /newfs
+ rm_mount_point: true
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/alerta_customer/aliases b/ansible_collections/community/general/tests/integration/targets/alerta_customer/aliases
new file mode 100644
index 000000000..d163e8d9c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/alerta_customer/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+disabled
diff --git a/ansible_collections/community/general/tests/integration/targets/alerta_customer/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/alerta_customer/defaults/main.yml
new file mode 100644
index 000000000..3d4877b41
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/alerta_customer/defaults/main.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+alerta_url: http://localhost:8080/
+alerta_user: admin@example.com
+alerta_password: password
+alerta_key: demo-key
diff --git a/ansible_collections/community/general/tests/integration/targets/alerta_customer/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/alerta_customer/tasks/main.yml
new file mode 100644
index 000000000..b91c24b53
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/alerta_customer/tasks/main.yml
@@ -0,0 +1,156 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create customer (check mode)
+ alerta_customer:
+ alerta_url: "{{ alerta_url }}"
+ api_username: "{{ alerta_user }}"
+ api_password: "{{ alerta_password }}"
+ customer: customer1
+ match: admin@admin.admin
+ check_mode: true
+ register: result
+
+- name: Check result (check mode)
+ assert:
+ that:
+ - result is changed
+
+- name: Create customer
+ alerta_customer:
+ alerta_url: "{{ alerta_url }}"
+ api_username: "{{ alerta_user }}"
+ api_password: "{{ alerta_password }}"
+ customer: customer1
+ match: admin@admin.admin
+ register: result
+
+- name: Check customer creation
+ assert:
+ that:
+ - result is changed
+
+- name: Test customer creation idempotency
+ alerta_customer:
+ alerta_url: "{{ alerta_url }}"
+ api_username: "{{ alerta_user }}"
+ api_password: "{{ alerta_password }}"
+ customer: customer1
+ match: admin@admin.admin
+ register: result
+
+- name: Check customer creation idempotency
+ assert:
+ that:
+ - result is not changed
+
+- name: Delete customer (check mode)
+ alerta_customer:
+ alerta_url: "{{ alerta_url }}"
+ api_username: "{{ alerta_user }}"
+ api_password: "{{ alerta_password }}"
+ customer: customer1
+ match: admin@admin.admin
+ state: absent
+ check_mode: true
+ register: result
+
+- name: Check customer deletion (check mode)
+ assert:
+ that:
+ - result is changed
+
+- name: Delete customer
+ alerta_customer:
+ alerta_url: "{{ alerta_url }}"
+ api_username: "{{ alerta_user }}"
+ api_password: "{{ alerta_password }}"
+ customer: customer1
+ match: admin@admin.admin
+ state: absent
+ register: result
+
+- name: Check customer deletion
+ assert:
+ that:
+ - result is changed
+
+- name: Test customer deletion idempotency
+ alerta_customer:
+ alerta_url: "{{ alerta_url }}"
+ api_username: "{{ alerta_user }}"
+ api_password: "{{ alerta_password }}"
+ customer: customer1
+ match: admin@admin.admin
+ state: absent
+ register: result
+
+- name: Check customer deletion idempotency
+ assert:
+ that:
+ - result is not changed
+
+- name: Delete non-existing customer (check mode)
+ alerta_customer:
+ alerta_url: "{{ alerta_url }}"
+ api_username: "{{ alerta_user }}"
+ api_password: "{{ alerta_password }}"
+ customer: customer1
+ match: admin@admin.admin
+ state: absent
+ check_mode: true
+ register: result
+
+- name: Check non-existing customer deletion (check mode)
+ assert:
+ that:
+ - result is not changed
+
+- name: Create customer with api key
+ alerta_customer:
+ alerta_url: "{{ alerta_url }}"
+ api_key: "{{ alerta_key }}"
+ customer: customer1
+ match: admin@admin.admin
+ register: result
+
+- name: Check customer creation with api key
+ assert:
+ that:
+ - result is changed
+
+- name: Delete customer with api key
+ alerta_customer:
+ alerta_url: "{{ alerta_url }}"
+ api_key: "{{ alerta_key }}"
+ customer: customer1
+ match: admin@admin.admin
+ state: absent
+ register: result
+
+- name: Check customer deletion with api key
+ assert:
+ that:
+ - result is changed
+
+- name: Use wrong api key
+ alerta_customer:
+ alerta_url: "{{ alerta_url }}"
+ api_key: wrong_key
+ customer: customer1
+ match: admin@admin.admin
+ register: result
+ ignore_errors: true
+
+- name: Check customer creation with api key
+ assert:
+ that:
+ - result is not changed
+ - result is failed
diff --git a/ansible_collections/community/general/tests/integration/targets/alternatives/aliases b/ansible_collections/community/general/tests/integration/targets/alternatives/aliases
new file mode 100644
index 000000000..f360ac626
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/alternatives/aliases
@@ -0,0 +1,11 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/3
+destructive
+needs/root
+skip/aix
+skip/freebsd
+skip/osx
+skip/macos
diff --git a/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/main.yml
new file mode 100644
index 000000000..81d6a7b0d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/main.yml
@@ -0,0 +1,93 @@
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2017 Pierre-Louis Bonicoli <pierre-louis.bonicoli@libregerbil.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: 'setup: create a dummy alternative'
+ block:
+ - import_tasks: setup.yml
+
+ ##############
+ # Test parameters:
+ # link parameter present / absent ('with_link' variable)
+ # with / without alternatives defined in alternatives file ('with_alternatives' variable)
+ # auto / manual ('mode' variable)
+
+ - include_tasks: tests.yml
+ with_nested:
+ - [ true, false ] # with_link
+ - [ true, false ] # with_alternatives
+ - [ 'auto', 'manual' ] # mode
+ loop_control:
+ loop_var: test_conf
+
+ ##########
+ # Priority
+ - block:
+ - include_tasks: remove_links.yml
+ - include_tasks: setup_test.yml
+ # at least two iterations again
+ - include_tasks: tests_set_priority.yml
+ with_sequence: start=3 end=4
+ vars:
+ with_alternatives: true
+ mode: auto
+
+ - block:
+ - include_tasks: remove_links.yml
+ - include_tasks: setup_test.yml
+ # at least two iterations again
+ - include_tasks: tests_set_priority.yml
+ with_sequence: start=3 end=4
+ vars:
+ with_alternatives: false
+ mode: auto
+
+ # Test that path is checked: alternatives must fail when path is nonexistent
+ - import_tasks: path_is_checked.yml
+
+ # Test that subcommands commands work
+ - import_tasks: subcommands.yml
+
+ # Test operation of the 'state' parameter
+ - block:
+ - include_tasks: remove_links.yml
+ - include_tasks: tests_state.yml
+
+ # Cleanup
+ always:
+ - include_tasks: remove_links.yml
+
+ - file:
+ path: '{{ item }}'
+ state: absent
+ with_items:
+ - '{{ alternatives_dir }}/dummy'
+ - '{{ alternatives_dir }}/dummymain'
+ - '{{ alternatives_dir }}/dummysubcmd'
+
+ - file:
+ path: '/usr/bin/dummy{{ item }}'
+ state: absent
+ with_sequence: start=1 end=4
+
+ # *Disable tests on Fedora 24*
+ # Shippable Fedora 24 image provides chkconfig-1.7-2.fc24.x86_64 but not the
+ # latest available version (chkconfig-1.8-1.fc24.x86_64). update-alternatives
+ # in chkconfig-1.7-2 fails when /etc/alternatives/dummy link is missing,
+ # error is: 'failed to read link /usr/bin/dummy: No such file or directory'.
+ # Moreover Fedora 24 is no longer maintained.
+ #
+ # *Disable tests on Arch Linux*
+ # TODO: figure out whether there is an alternatives tool for Arch Linux
+ #
+ # *Disable tests on Alpine*
+ # TODO: figure out whether there is an alternatives tool for Alpine
+ when:
+ - ansible_distribution != 'Fedora' or ansible_distribution_major_version|int > 24
+ - ansible_distribution != 'Archlinux'
+ - ansible_distribution != 'Alpine'
diff --git a/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/path_is_checked.yml b/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/path_is_checked.yml
new file mode 100644
index 000000000..0bc435889
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/path_is_checked.yml
@@ -0,0 +1,17 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Try with nonexistent path
+ alternatives:
+ name: dummy
+ path: '/non/existent/path/there'
+ link: '/usr/bin/dummy'
+ ignore_errors: true
+ register: alternative
+
+- name: Check previous task failed
+ assert:
+ that:
+ - 'alternative is failed'
diff --git a/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/remove_links.yml b/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/remove_links.yml
new file mode 100644
index 000000000..de25b02cb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/remove_links.yml
@@ -0,0 +1,13 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: remove links
+ file:
+ path: '{{ item }}'
+ state: absent
+ with_items:
+ - "{{ alternatives_dir }}/dummy"
+ - /etc/alternatives/dummy
+ - /usr/bin/dummy
diff --git a/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/setup.yml b/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/setup.yml
new file mode 100644
index 000000000..ab2c39852
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/setup.yml
@@ -0,0 +1,19 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- include_vars: '{{ item }}'
+ with_first_found:
+ - files:
+ - '{{ ansible_os_family }}-{{ ansible_distribution_version }}.yml'
+ - '{{ ansible_os_family }}.yml'
+ - default.yml
+ paths: ../vars
+- template:
+ src: dummy_command
+ dest: /usr/bin/dummy{{ item }}
+ owner: root
+ group: root
+ mode: '0755'
+ with_sequence: start=1 end=4
diff --git a/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/setup_test.yml b/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/setup_test.yml
new file mode 100644
index 000000000..77279c67f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/setup_test.yml
@@ -0,0 +1,16 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- template:
+ src: dummy_alternative
+ dest: '{{ alternatives_dir }}/dummy'
+ owner: root
+ group: root
+ mode: '0644'
+ when: with_alternatives or ansible_os_family != 'RedHat'
+- file:
+ path: '{{ alternatives_dir }}/dummy'
+ state: absent
+ when: not with_alternatives and ansible_os_family == 'RedHat'
diff --git a/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/subcommands.yml b/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/subcommands.yml
new file mode 100644
index 000000000..678bbe68f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/subcommands.yml
@@ -0,0 +1,222 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Try with subcommands
+ alternatives:
+ name: dummymain
+ path: '/usr/bin/dummy1'
+ link: '/usr/bin/dummymain'
+ subcommands:
+ - name: dummysubcmd
+ path: '/usr/bin/dummy2'
+ link: '/usr/bin/dummysubcmd'
+ register: alternative
+
+- name: Check expected command was executed
+ assert:
+ that:
+ - 'alternative is changed'
+
+- name: Execute the current dummymain command
+ command: dummymain
+ register: cmd
+
+- name: Ensure that the expected command was executed
+ assert:
+ that:
+ - cmd.stdout == "dummy1"
+
+- name: Execute the current dummysubcmd command
+ command: dummysubcmd
+ register: cmd
+
+- name: Ensure that the expected command was executed
+ assert:
+ that:
+ - cmd.stdout == "dummy2"
+
+- name: Get dummymain alternatives output
+ command:
+ cmd: '{{ alternatives_command }} --display dummymain'
+ register: result
+
+- name: Print result
+ debug:
+ var: result.stdout_lines
+
+- name: Subcommands are not removed if not specified
+ alternatives:
+ name: dummymain
+ path: '/usr/bin/dummy1'
+ link: '/usr/bin/dummymain'
+ register: alternative
+
+- name: Check expected command was executed
+ assert:
+ that:
+ - 'alternative is not changed'
+
+- name: Execute the current dummysubcmd command
+ command: dummysubcmd
+ register: cmd
+
+- name: Ensure that the expected command was executed
+ assert:
+ that:
+ - cmd.stdout == "dummy2"
+
+- name: Subcommands are removed if set to an empty list
+ alternatives:
+ name: dummymain
+ path: '/usr/bin/dummy1'
+ link: '/usr/bin/dummymain'
+ subcommands: []
+ register: alternative
+
+- name: Check expected command was executed
+ assert:
+ that:
+ - 'alternative is changed'
+
+- name: Execute the current dummysubcmd command
+ command: dummysubcmd
+ register: cmd
+ ignore_errors: true
+
+- name: Ensure that the subcommand is gone
+ assert:
+ that:
+ - cmd.rc == 2
+ - '"No such file" in cmd.msg'
+
+- name: Get dummymain alternatives output
+ command:
+ cmd: '{{ alternatives_command }} --display dummymain'
+ register: result
+
+- name: Print result
+ debug:
+ var: result.stdout_lines
+
+- name: Install other alternative with subcommands
+ alternatives:
+ name: dummymain
+ path: '/usr/bin/dummy3'
+ link: '/usr/bin/dummymain'
+ subcommands:
+ - name: dummysubcmd
+ path: '/usr/bin/dummy4'
+ link: '/usr/bin/dummysubcmd'
+ register: alternative
+
+- name: Check expected command was executed
+ assert:
+ that:
+ - 'alternative is changed'
+
+- name: Execute the current dummymain command
+ command: dummymain
+ register: cmd
+
+- name: Ensure that the expected command was executed
+ assert:
+ that:
+ - cmd.stdout == "dummy3"
+
+- name: Execute the current dummysubcmd command
+ command: dummysubcmd
+ register: cmd
+
+- name: Ensure that the expected command was executed
+ assert:
+ that:
+ - cmd.stdout == "dummy4"
+
+- name: Get dummymain alternatives output
+ command:
+ cmd: '{{ alternatives_command }} --display dummymain'
+ register: result
+
+- name: Print result
+ debug:
+ var: result.stdout_lines
+
+- name: Switch to first alternative
+ alternatives:
+ name: dummymain
+ path: '/usr/bin/dummy1'
+ register: alternative
+
+- name: Check expected command was executed
+ assert:
+ that:
+ - 'alternative is changed'
+
+- name: Execute the current dummymain command
+ command: dummymain
+ register: cmd
+
+- name: Ensure that the expected command was executed
+ assert:
+ that:
+ - cmd.stdout == "dummy1"
+
+- name: Execute the current dummysubcmd command
+ command: dummysubcmd
+ register: cmd
+ ignore_errors: true
+
+- name: Ensure that the subcommand is gone
+ assert:
+ that:
+ - cmd.rc == 2
+ - '"No such file" in cmd.msg'
+
+- name: Get dummymain alternatives output
+ command:
+ cmd: '{{ alternatives_command }} --display dummymain'
+ register: result
+
+- name: Print result
+ debug:
+ var: result.stdout_lines
+
+- name: Switch to second alternative
+ alternatives:
+ name: dummymain
+ path: '/usr/bin/dummy3'
+ register: alternative
+
+- name: Check expected command was executed
+ assert:
+ that:
+ - 'alternative is changed'
+
+- name: Execute the current dummymain command
+ command: dummymain
+ register: cmd
+
+- name: Ensure that the expected command was executed
+ assert:
+ that:
+ - cmd.stdout == "dummy3"
+
+- name: Execute the current dummysubcmd command
+ command: dummysubcmd
+ register: cmd
+
+- name: Ensure that the expected command was executed
+ assert:
+ that:
+ - cmd.stdout == "dummy4"
+
+- name: Get dummymain alternatives output
+ command:
+ cmd: '{{ alternatives_command }} --display dummymain'
+ register: result
+
+- name: Print result
+ debug:
+ var: result.stdout_lines
diff --git a/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/test.yml b/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/test.yml
new file mode 100644
index 000000000..ca59a4b55
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/test.yml
@@ -0,0 +1,56 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- debug:
+ msg: ' with_alternatives: {{ with_alternatives }}, mode: {{ mode }}'
+
+- block:
+ - name: set alternative (using link parameter)
+ alternatives:
+ name: dummy
+ path: '/usr/bin/dummy{{ item }}'
+ link: '/usr/bin/dummy'
+ register: alternative
+
+ - name: check expected command was executed
+ assert:
+ that:
+ - 'alternative is successful'
+ - 'alternative is changed'
+ when: with_link
+
+- block:
+ - name: set alternative (without link parameter)
+ alternatives:
+ name: dummy
+ path: '/usr/bin/dummy{{ item }}'
+ register: alternative
+
+ - name: check expected command was executed
+ assert:
+ that:
+ - 'alternative is successful'
+ - 'alternative is changed'
+ when: not with_link
+
+- name: execute dummy command
+ shell: dummy
+ register: cmd
+
+- name: check expected command was executed
+ assert:
+ that:
+ - 'cmd.stdout == "dummy" ~ item'
+
+- name: 'check mode (manual: alternatives file existed, it has been updated)'
+ shell: 'head -n1 {{ alternatives_dir }}/dummy | grep "^manual$"'
+ when: ansible_os_family != 'RedHat' or with_alternatives or item != 1
+
+- name: 'check mode (auto: alternatives file didn''t exist, it has been created)'
+ shell: 'head -n1 {{ alternatives_dir }}/dummy | grep "^auto$"'
+ when: ansible_os_family == 'RedHat' and not with_alternatives and item == 1
+
+- name: check that alternative has been updated
+ command: "grep -Pzq '/bin/dummy{{ item }}\\n' '{{ alternatives_dir }}/dummy'"
diff --git a/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/tests.yml b/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/tests.yml
new file mode 100644
index 000000000..75e30cabe
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/tests.yml
@@ -0,0 +1,20 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- block:
+ - include_tasks: remove_links.yml
+ - include_tasks: setup_test.yml
+ # at least two iterations:
+ # - first will use 'link currently absent',
+ # - second will receive 'link currently points to'
+ - include_tasks: test.yml
+ with_sequence: start=1 end=2
+ vars:
+ with_link: '{{ test_conf[0] }}'
+ with_alternatives: '{{ test_conf[1] }}'
+ mode: '{{ test_conf[2] }}'
+ # update-alternatives included in Fedora 26 (1.10) & Red Hat 7.4 (1.8) doesn't provide
+ # '--query' switch, 'link' is mandatory for these distributions.
+ when: ansible_os_family != 'RedHat' or test_conf[0]
diff --git a/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/tests_set_priority.yml b/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/tests_set_priority.yml
new file mode 100644
index 000000000..46cf48e59
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/tests_set_priority.yml
@@ -0,0 +1,54 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: update dummy alternative
+ alternatives:
+ name: dummy
+ path: '/usr/bin/dummy{{ item }}'
+ link: /usr/bin/dummy
+ priority: '{{ 60 + item|int }}'
+ register: alternative
+
+- name: execute dummy command
+ shell: dummy
+ register: cmd
+
+- name: check if link group is in manual mode
+ shell: 'head -n1 {{ alternatives_dir }}/dummy | grep "^manual$"'
+
+- name: check expected command was executed
+ assert:
+ that:
+ - 'alternative is changed'
+ - 'cmd.stdout == "dummy{{ item }}"'
+
+- name: check that alternative has been updated
+ command: "grep -Pzq '/bin/dummy{{ item }}\\n{{ 60 + item|int }}' '{{ alternatives_dir }}/dummy'"
+
+- name: update dummy priority
+ alternatives:
+ name: dummy
+ path: '/usr/bin/dummy{{ item }}'
+ link: /usr/bin/dummy
+ priority: '{{ 70 + item|int }}'
+ register: alternative
+
+- name: check that alternative priority has been updated
+ command: "grep -Pzq '/bin/dummy{{ item }}\\n{{ 70 + item|int }}' '{{ alternatives_dir }}/dummy'"
+
+- name: no change without priority
+ alternatives:
+ name: dummy
+ path: '/usr/bin/dummy{{ item }}'
+ link: /usr/bin/dummy
+ register: alternative
+
+- name: check no change was triggered without priority
+ assert:
+ that:
+ - 'alternative is not changed'
+
+- name: check that alternative priority has not been changed
+ command: "grep -Pzq '/bin/dummy{{ item }}\\n{{ 70 + item|int }}' '{{ alternatives_dir }}/dummy'"
diff --git a/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/tests_state.yml b/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/tests_state.yml
new file mode 100644
index 000000000..92c8078c2
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/alternatives/tasks/tests_state.yml
@@ -0,0 +1,120 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Add a few dummy alternatives with state = present and make sure that the
+# group is in 'auto' mode and the highest priority alternative is selected.
+- name: Add some dummy alternatives with state = present
+ alternatives:
+ name: dummy
+ path: "/usr/bin/dummy{{ item.n }}"
+ link: /usr/bin/dummy
+ priority: "{{ item.priority }}"
+ state: present
+ loop:
+ - { n: 1, priority: 50 }
+ - { n: 2, priority: 70 }
+ - { n: 3, priority: 25 }
+
+- name: Ensure that the link group is in auto mode
+ shell: 'head -n1 {{ alternatives_dir }}/dummy | grep "^auto$"'
+
+# Execute current selected 'dummy' and ensure it's the alternative we expect
+- name: Execute the current dummy command
+ shell: dummy
+ register: cmd
+
+- name: Ensure that the expected command was executed
+ assert:
+ that:
+ - cmd.stdout == "dummy2"
+
+# Add another alternative with state = 'selected' and make sure that
+# this change results in the group being set to manual mode, and the
+# new alternative being the selected one.
+- name: Add another dummy alternative with state = selected
+ alternatives:
+ name: dummy
+ path: /usr/bin/dummy4
+ link: /usr/bin/dummy
+ priority: 10
+ state: selected
+
+- name: Ensure that the link group is in manual mode
+ shell: 'head -n1 {{ alternatives_dir }}/dummy | grep "^manual$"'
+
+- name: Execute the current dummy command
+ shell: dummy
+ register: cmd
+
+- name: Ensure that the expected command was executed
+ assert:
+ that:
+ - cmd.stdout == "dummy4"
+
+# Set the currently selected alternative to state = 'present' (was previously
+# selected), and ensure that this results in the group not being set to 'auto'
+# mode, and the alternative is still selected.
+- name: Set current selected dummy to state = present
+ alternatives:
+ name: dummy
+ path: /usr/bin/dummy4
+ link: /usr/bin/dummy
+ state: present
+
+- name: Ensure that the link group is in auto mode
+ shell: 'head -n1 {{ alternatives_dir }}/dummy | grep "^manual$"'
+
+- name: Execute the current dummy command
+ shell: dummy
+ register: cmd
+
+- name: Ensure that the expected command was executed
+ assert:
+ that:
+ - cmd.stdout == "dummy4"
+
+# Set the currently selected alternative to state = 'auto' (was previously
+# selected), and ensure that this results in the group being set to 'auto'
+# mode, and the highest priority alternative is selected.
+- name: Set current selected dummy to state = present
+ alternatives:
+ name: dummy
+ path: /usr/bin/dummy4
+ link: /usr/bin/dummy
+ state: auto
+
+- name: Ensure that the link group is in auto mode
+ shell: 'head -n1 {{ alternatives_dir }}/dummy | grep "^auto$"'
+
+- name: Execute the current dummy command
+ shell: dummy
+ register: cmd
+
+- name: Ensure that the expected command was executed
+ assert:
+ that:
+ - cmd.stdout == "dummy2"
+
+# Remove an alternative with state = 'absent' and make sure that
+# this change results in the alternative being removed.
+- name: Remove best dummy alternative with state = absent
+ alternatives:
+ name: dummy
+ path: /usr/bin/dummy2
+ state: absent
+
+- name: Ensure that the link group is in auto mode
+ shell: 'grep "/usr/bin/dummy2" {{ alternatives_dir }}/dummy'
+ register: cmd
+ failed_when: cmd.rc == 0
+
+- name: Execute the current dummy command
+ shell: dummy
+ register: cmd
+
+- name: Ensure that the expected command was executed
+ assert:
+ that:
+ - cmd.stdout == "dummy1"
diff --git a/ansible_collections/community/general/tests/integration/targets/alternatives/templates/dummy_alternative b/ansible_collections/community/general/tests/integration/targets/alternatives/templates/dummy_alternative
new file mode 100644
index 000000000..9b7136d56
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/alternatives/templates/dummy_alternative
@@ -0,0 +1,17 @@
+{#
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+#}
+{{ mode }}
+/usr/bin/dummy
+
+{% if with_alternatives %}
+/usr/bin/dummy1
+40
+/usr/bin/dummy2
+30
+
+{% else %}
+
+{% endif %}
diff --git a/ansible_collections/community/general/tests/integration/targets/alternatives/templates/dummy_command b/ansible_collections/community/general/tests/integration/targets/alternatives/templates/dummy_command
new file mode 100644
index 000000000..afd80e673
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/alternatives/templates/dummy_command
@@ -0,0 +1,6 @@
+#!/bin/sh
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+echo dummy{{ item }}
diff --git a/ansible_collections/community/general/tests/integration/targets/alternatives/vars/Debian.yml b/ansible_collections/community/general/tests/integration/targets/alternatives/vars/Debian.yml
new file mode 100644
index 000000000..e7f87c59d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/alternatives/vars/Debian.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+alternatives_dir: /var/lib/dpkg/alternatives/
+alternatives_command: update-alternatives
diff --git a/ansible_collections/community/general/tests/integration/targets/alternatives/vars/Suse-42.3.yml b/ansible_collections/community/general/tests/integration/targets/alternatives/vars/Suse-42.3.yml
new file mode 100644
index 000000000..0d5a9cfec
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/alternatives/vars/Suse-42.3.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+alternatives_dir: /var/lib/rpm/alternatives/
+alternatives_command: update-alternatives
diff --git a/ansible_collections/community/general/tests/integration/targets/alternatives/vars/default.yml b/ansible_collections/community/general/tests/integration/targets/alternatives/vars/default.yml
new file mode 100644
index 000000000..68e1feafa
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/alternatives/vars/default.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+alternatives_dir: /var/lib/alternatives/
+alternatives_command: update-alternatives
diff --git a/ansible_collections/community/general/tests/integration/targets/ansible_galaxy_install/aliases b/ansible_collections/community/general/tests/integration/targets/ansible_galaxy_install/aliases
new file mode 100644
index 000000000..13655b194
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ansible_galaxy_install/aliases
@@ -0,0 +1,8 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/3
+destructive
+skip/python2.6
+context/controller # While this is not really true, this module mainly is run on the controller, *and* needs access to the ansible-galaxy CLI tool
diff --git a/ansible_collections/community/general/tests/integration/targets/ansible_galaxy_install/files/test.yml b/ansible_collections/community/general/tests/integration/targets/ansible_galaxy_install/files/test.yml
new file mode 100644
index 000000000..877b5fca4
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ansible_galaxy_install/files/test.yml
@@ -0,0 +1,15 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+roles:
+ # Install a role from Ansible Galaxy.
+ - name: geerlingguy.java
+ version: 1.9.6
+
+collections:
+ # Install a collection from Ansible Galaxy.
+ - name: geerlingguy.php_roles
+ version: 0.9.3
+ source: https://galaxy.ansible.com
diff --git a/ansible_collections/community/general/tests/integration/targets/ansible_galaxy_install/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/ansible_galaxy_install/meta/main.yml
new file mode 100644
index 000000000..982de6eb0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ansible_galaxy_install/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/ansible_galaxy_install/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/ansible_galaxy_install/tasks/main.yml
new file mode 100644
index 000000000..1ecd9980d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ansible_galaxy_install/tasks/main.yml
@@ -0,0 +1,88 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+###################################################
+- name: Install collection netbox.netbox
+ community.general.ansible_galaxy_install:
+ type: collection
+ name: netbox.netbox
+ register: install_c0
+
+- name: Assert collection netbox.netbox was installed
+ assert:
+ that:
+ - install_c0 is changed
+ - '"netbox.netbox" in install_c0.new_collections'
+
+- name: Install collection netbox.netbox (again)
+ community.general.ansible_galaxy_install:
+ type: collection
+ name: netbox.netbox
+ register: install_c1
+
+- name: Assert collection was not installed
+ assert:
+ that:
+ - install_c1 is not changed
+
+###################################################
+- name: Install role ansistrano.deploy
+ community.general.ansible_galaxy_install:
+ type: role
+ name: ansistrano.deploy
+ register: install_r0
+
+- name: Assert collection ansistrano.deploy was installed
+ assert:
+ that:
+ - install_r0 is changed
+ - '"ansistrano.deploy" in install_r0.new_roles'
+
+- name: Install role ansistrano.deploy (again)
+ community.general.ansible_galaxy_install:
+ type: role
+ name: ansistrano.deploy
+ register: install_r1
+
+- name: Assert role was not installed
+ assert:
+ that:
+ - install_r1 is not changed
+
+###################################################
+- name: Set requirements file path
+ set_fact:
+ reqs_file: '{{ remote_tmp_dir }}/reqs.yaml'
+
+- name: Copy requirements file
+ copy:
+ src: 'files/test.yml'
+ dest: '{{ reqs_file }}'
+
+- name: Install from requirements file
+ community.general.ansible_galaxy_install:
+ type: both
+ requirements_file: "{{ reqs_file }}"
+ register: install_rq0
+ ignore_errors: true
+
+- name: Assert requirements file was installed
+ assert:
+ that:
+ - install_rq0 is changed
+ - '"geerlingguy.java" in install_rq0.new_roles'
+ - '"geerlingguy.php_roles" in install_rq0.new_collections'
+
+- name: Install from requirements file (again)
+ community.general.ansible_galaxy_install:
+ type: both
+ requirements_file: "{{ reqs_file }}"
+ register: install_rq1
+ ignore_errors: true
+
+- name: Assert requirements file was not installed
+ assert:
+ that:
+ - install_rq1 is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/apache2_module/aliases b/ansible_collections/community/general/tests/integration/targets/apache2_module/aliases
new file mode 100644
index 000000000..0d1324b22
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/apache2_module/aliases
@@ -0,0 +1,7 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/3
+destructive
+skip/aix
diff --git a/ansible_collections/community/general/tests/integration/targets/apache2_module/tasks/635-apache2-misleading-warning.yml b/ansible_collections/community/general/tests/integration/targets/apache2_module/tasks/635-apache2-misleading-warning.yml
new file mode 100644
index 000000000..5d93a9d30
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/apache2_module/tasks/635-apache2-misleading-warning.yml
@@ -0,0 +1,47 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+# This test represent the misleading behavior of the following issue: https://github.com/ansible-collections/community.general/issues/635
+- name: Disable MPM event module
+ apache2_module:
+ name: "{{ item.module}}"
+ state: "{{ item.state}}"
+ ignore_configcheck: true
+ register: disable_mpm_modules
+ with_items:
+ - { module: mpm_event, state: absent }
+ - { module: mpm_prefork, state: present }
+
+- assert:
+ that:
+ - "'warnings' in disable_mpm_modules"
+ - disable_mpm_modules["warnings"] == [
+ "No MPM module loaded! apache2 reload AND other module actions will fail if no MPM module is loaded immediately.",
+ "No MPM module loaded! apache2 reload AND other module actions will fail if no MPM module is loaded immediately."
+ ]
+
+- name: Enable MPM event module - Revert previous change
+ apache2_module:
+ name: "{{ item.module}}"
+ state: "{{ item.state}}"
+ ignore_configcheck: true
+ register: disable_mpm_modules
+ with_items:
+ - { module: mpm_prefork, state: absent }
+ - { module: mpm_event, state: present }
+
+- name: Disable MPM event module
+ apache2_module:
+ name: "{{ item.module}}"
+ state: "{{ item.state}}"
+ ignore_configcheck: true
+ warn_mpm_absent: false
+ register: disable_mpm_modules
+ with_items:
+ - { module: mpm_event, state: absent }
+ - { module: mpm_prefork, state: present }
+
+- assert:
+ that:
+ - "'warnings' not in disable_mpm_modules"
diff --git a/ansible_collections/community/general/tests/integration/targets/apache2_module/tasks/actualtest.yml b/ansible_collections/community/general/tests/integration/targets/apache2_module/tasks/actualtest.yml
new file mode 100644
index 000000000..3301a16b1
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/apache2_module/tasks/actualtest.yml
@@ -0,0 +1,207 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: disable userdir module
+ community.general.apache2_module:
+ name: userdir
+ state: absent
+ register: userdir_first_disable
+
+- name: disable userdir module, second run
+ community.general.apache2_module:
+ name: userdir
+ state: absent
+ register: disable
+
+- name: ensure community.general.apache2_module is idempotent
+ assert:
+ that:
+ - disable is not changed
+
+- name: enable userdir module
+ community.general.apache2_module:
+ name: userdir
+ state: present
+ register: enable
+
+- name: ensure changed on successful enable
+ assert:
+ that:
+ - enable is changed
+
+- name: enable userdir module, second run
+ community.general.apache2_module:
+ name: userdir
+ state: present
+ register: enabletwo
+
+- name: ensure community.general.apache2_module is idempotent
+ assert:
+ that:
+ - 'not enabletwo.changed'
+
+- name: disable userdir module, final run
+ community.general.apache2_module:
+ name: userdir
+ state: absent
+ register: disablefinal
+
+- name: ensure changed on successful disable
+ assert:
+ that:
+ - 'disablefinal.changed'
+
+- name: set userdir to original state
+ community.general.apache2_module:
+ name: userdir
+ state: present
+ when: userdir_first_disable is changed
+
+- name: ensure autoindex enabled
+ community.general.apache2_module:
+ name: autoindex
+ state: present
+
+- name: Debian/Ubuntu specific tests
+ when: "ansible_os_family == 'Debian'"
+ block:
+ - name: force disable of autoindex # bug #2499
+ community.general.apache2_module:
+ name: autoindex
+ state: absent
+ force: true
+
+ - name: reenable autoindex
+ community.general.apache2_module:
+ name: autoindex
+ state: present
+
+ # mod_evasive is enabled by default upon the installation, so disable first and enable second, to preserve the config
+ - name: disable evasive module
+ community.general.apache2_module:
+ name: evasive
+ state: absent
+
+ - name: enable evasive module, test https://github.com/ansible/ansible/issues/22635
+ community.general.apache2_module:
+ name: evasive
+ state: present
+
+ - name: use identifier to enable module, fix for https://github.com/ansible/ansible/issues/33669
+ community.general.apache2_module:
+ name: dump_io
+ state: present
+ ignore_errors: true
+ register: enable_dumpio_wrong
+
+ - name: disable dump_io
+ community.general.apache2_module:
+ name: dump_io
+ identifier: dumpio_module
+ state: absent
+
+ - name: use identifier to enable module, fix for https://github.com/ansible/ansible/issues/33669
+ community.general.apache2_module:
+ name: dump_io
+ identifier: dumpio_module
+ state: present
+ register: enable_dumpio_correct_1
+
+ - name: ensure idempotency with identifier
+ community.general.apache2_module:
+ name: dump_io
+ identifier: dumpio_module
+ state: present
+ register: enable_dumpio_correct_2
+
+ - name: disable dump_io
+ community.general.apache2_module:
+ name: dump_io
+ identifier: dumpio_module
+ state: absent
+
+ - assert:
+ that:
+ - enable_dumpio_wrong is failed
+ - enable_dumpio_correct_1 is changed
+ - enable_dumpio_correct_2 is not changed
+
+ - name: disable mpm modules
+ community.general.apache2_module:
+ name: "{{ item }}"
+ state: absent
+ ignore_configcheck: true
+ with_items:
+ - mpm_worker
+ - mpm_event
+ - mpm_prefork
+
+ - name: enabled mpm_event
+ community.general.apache2_module:
+ name: mpm_event
+ state: present
+ ignore_configcheck: true
+ register: enabledmpmevent
+
+ - name: ensure changed mpm_event
+ assert:
+ that:
+ - 'enabledmpmevent.changed'
+
+ - name: switch between mpm_event and mpm_worker
+ community.general.apache2_module:
+ name: "{{ item.name }}"
+ state: "{{ item.state }}"
+ ignore_configcheck: true
+ with_items:
+ - name: mpm_event
+ state: absent
+ - name: mpm_worker
+ state: present
+
+ - name: ensure mpm_worker is already enabled
+ community.general.apache2_module:
+ name: mpm_worker
+ state: present
+ register: enabledmpmworker
+
+ - name: ensure mpm_worker unchanged
+ assert:
+ that:
+ - 'not enabledmpmworker.changed'
+
+ - name: try to disable all mpm modules with configcheck
+ community.general.apache2_module:
+ name: "{{item}}"
+ state: absent
+ with_items:
+ - mpm_worker
+ - mpm_event
+ - mpm_prefork
+ ignore_errors: true
+ register: remove_with_configcheck
+
+ - name: ensure configcheck fails task with when run without mpm modules
+ assert:
+ that:
+ - "{{ item.failed }}"
+ with_items: "{{ remove_with_configcheck.results }}"
+
+ - name: try to disable all mpm modules without configcheck
+ community.general.apache2_module:
+ name: "{{item}}"
+ state: absent
+ ignore_configcheck: true
+ with_items:
+ - mpm_worker
+ - mpm_event
+ - mpm_prefork
+
+ - name: enabled mpm_event to restore previous state
+ community.general.apache2_module:
+ name: mpm_event
+ state: present
+ ignore_configcheck: true
+ register: enabledmpmevent
diff --git a/ansible_collections/community/general/tests/integration/targets/apache2_module/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/apache2_module/tasks/main.yml
new file mode 100644
index 000000000..6f2f718ad
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/apache2_module/tasks/main.yml
@@ -0,0 +1,52 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: install apache via apt
+ apt:
+ name: "{{item}}"
+ state: present
+ when: "ansible_os_family == 'Debian'"
+ with_items:
+ - apache2
+ - libapache2-mod-evasive
+
+- name: install apache via zypper
+ community.general.zypper:
+ name: apache2
+ state: present
+ when: "ansible_os_family == 'Suse'"
+
+- name: test apache2_module
+ block:
+ - name: get list of enabled modules
+ shell: apache2ctl -M | sort
+ register: modules_before
+ - name: include only on supported systems
+ include_tasks: actualtest.yml
+ always:
+ - name: get list of enabled modules
+ shell: apache2ctl -M | sort
+ register: modules_after
+ - name: modules_before
+ debug:
+ var: modules_before
+ - name: modules_after
+ debug:
+ var: modules_after
+ - name: ensure that all test modules are disabled again
+ assert:
+ that: modules_before.stdout == modules_after.stdout
+ when: ansible_os_family in ['Debian', 'Suse']
+ # centos/RHEL does not have a2enmod/a2dismod
+
+- name: include misleading warning test
+ include_tasks: 635-apache2-misleading-warning.yml
+ when: ansible_os_family in ['Debian']
+ # Suse has mpm_event module compiled within the base apache2 \ No newline at end of file
diff --git a/ansible_collections/community/general/tests/integration/targets/archive/aliases b/ansible_collections/community/general/tests/integration/targets/archive/aliases
new file mode 100644
index 000000000..88b15a24f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/archive/aliases
@@ -0,0 +1,9 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+needs/root
+destructive
+skip/aix
+skip/osx # FIXME
diff --git a/ansible_collections/community/general/tests/integration/targets/archive/files/bar.txt b/ansible_collections/community/general/tests/integration/targets/archive/files/bar.txt
new file mode 100644
index 000000000..32276adb8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/archive/files/bar.txt
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+bar.txt
diff --git a/ansible_collections/community/general/tests/integration/targets/archive/files/empty.txt b/ansible_collections/community/general/tests/integration/targets/archive/files/empty.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/archive/files/empty.txt
diff --git a/ansible_collections/community/general/tests/integration/targets/archive/files/foo.txt b/ansible_collections/community/general/tests/integration/targets/archive/files/foo.txt
new file mode 100644
index 000000000..a40d2f008
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/archive/files/foo.txt
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+foo.txt
diff --git a/ansible_collections/community/general/tests/integration/targets/archive/files/sub/subfile.txt b/ansible_collections/community/general/tests/integration/targets/archive/files/sub/subfile.txt
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/archive/files/sub/subfile.txt
diff --git a/ansible_collections/community/general/tests/integration/targets/archive/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/archive/meta/main.yml
new file mode 100644
index 000000000..ca1915e05
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/archive/meta/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/archive/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/archive/tasks/main.yml
new file mode 100644
index 000000000..4ca41e254
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/archive/tasks/main.yml
@@ -0,0 +1,145 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Test code for the archive module.
+# Copyright (c) 2017, Abhijeet Kasurde <akasurde@redhat.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Make sure we start fresh
+
+# Test setup
+- name: prep our files
+ copy: src={{ item }} dest={{remote_tmp_dir}}/{{ item }}
+ with_items:
+ - foo.txt
+ - bar.txt
+ - empty.txt
+ - sub
+ - sub/subfile.txt
+
+# Run twice without lzma backport installed, to make sure it does not crash
+- name: Archive - pre-test - first run
+ archive:
+ path: "{{ remote_tmp_dir }}/*.txt"
+ dest: "{{ remote_tmp_dir }}/archive_pretest_1.tar"
+ format: "tar"
+ register: pretest_1
+
+- name: Archive - pre-test - second run
+ archive:
+ path: "{{ remote_tmp_dir }}/*.txt"
+ dest: "{{ remote_tmp_dir }}/archive_pretest_1.tar"
+ format: "tar"
+ register: pretest_2
+
+- name: Archive - validate pre-test
+ assert:
+ that:
+ - pretest_1 is changed
+ - pretest_2 is not changed
+
+# Install dependencies
+- name: Ensure zip is present to create test archive (yum)
+ yum: name=zip state=latest
+ when: ansible_facts.pkg_mgr == 'yum'
+
+- name: Ensure zip is present to create test archive (apt)
+ apt: name=zip state=latest
+ when: ansible_facts.pkg_mgr == 'apt'
+
+- name: Install prerequisites for backports.lzma when using python2 (non OSX)
+ block:
+ - name: Set liblzma package name depending on the OS
+ set_fact:
+ liblzma_dev_package:
+ Debian: liblzma-dev
+ RedHat: xz-devel
+ Suse: xz-devel
+ - name: Ensure liblzma-dev is present to install backports-lzma
+ package: name={{ liblzma_dev_package[ansible_os_family] }} state=latest
+ when: ansible_os_family in liblzma_dev_package.keys()
+ when:
+ - ansible_python_version.split('.')[0] == '2'
+ - ansible_os_family != 'Darwin'
+
+- name: Install prerequisites for backports.lzma when using python2 (OSX)
+ block:
+ - name: Find brew binary
+ command: which brew
+ register: brew_which
+ - name: Get owner of brew binary
+ stat: path="{{ brew_which.stdout }}"
+ register: brew_stat
+ - name: "Install package"
+ homebrew:
+ name: xz
+ state: present
+ update_homebrew: false
+ become: true
+ become_user: "{{ brew_stat.stat.pw_name }}"
+ # Newer versions of brew want to compile a package which takes a long time. Do not upgrade homebrew until a
+ # proper solution can be found
+ environment:
+ HOMEBREW_NO_AUTO_UPDATE: "True"
+ when:
+ - ansible_python_version.split('.')[0] == '2'
+ - ansible_os_family == 'Darwin'
+
+- name: Ensure backports.lzma is present to create test archive (pip)
+ pip: name=backports.lzma state=latest
+ when: ansible_python_version.split('.')[0] == '2'
+ register: backports_lzma_pip
+
+- name: Define formats to test
+ set_fact:
+ formats:
+ - tar
+ - zip
+ - gz
+ - bz2
+ - xz
+
+# Run tests
+- name: Run core tests
+ include_tasks:
+ file: ../tests/core.yml
+ loop: "{{ formats }}"
+ loop_control:
+ loop_var: format
+
+- name: Run exclusions tests
+ include_tasks:
+ file: ../tests/exclusions.yml
+ loop: "{{ formats }}"
+ loop_control:
+ loop_var: format
+
+- name: Run remove tests
+ include_tasks:
+ file: ../tests/remove.yml
+ loop: "{{ formats }}"
+ loop_control:
+ loop_var: format
+
+- name: Run broken link tests
+ include_tasks:
+ file: ../tests/broken-link.yml
+ loop: "{{ formats }}"
+ loop_control:
+ loop_var: format
+
+- name: Run Idempotency tests
+ include_tasks:
+ file: ../tests/idempotency.yml
+ loop: "{{ formats }}"
+ loop_control:
+ loop_var: format
+
+# Test cleanup
+- name: Remove backports.lzma if previously installed (pip)
+ pip: name=backports.lzma state=absent
+ when: backports_lzma_pip is changed
diff --git a/ansible_collections/community/general/tests/integration/targets/archive/tests/broken-link.yml b/ansible_collections/community/general/tests/integration/targets/archive/tests/broken-link.yml
new file mode 100644
index 000000000..7c6444371
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/archive/tests/broken-link.yml
@@ -0,0 +1,35 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- block:
+ - name: Create link - broken link ({{ format }})
+ file:
+ src: /nowhere
+ dest: "{{ remote_tmp_dir }}/nowhere.txt"
+ state: link
+ force: true
+
+ - name: Archive - broken link ({{ format }})
+ archive:
+ path: "{{ remote_tmp_dir }}/*.txt"
+ dest: "{{ remote_tmp_dir }}/archive_broken_link.{{ format }}"
+ format: "{{ format }}"
+
+ - name: Verify archive exists - broken link ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/archive_broken_link.{{ format }}"
+ state: file
+
+ - name: Remove archive - broken link ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/archive_broken_link.{{ format }}"
+ state: absent
+
+ - name: Remove link - broken link ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/nowhere.txt"
+ state: absent
+ # 'zip' does not support symlink's
+ when: format != 'zip'
diff --git a/ansible_collections/community/general/tests/integration/targets/archive/tests/core.yml b/ansible_collections/community/general/tests/integration/targets/archive/tests/core.yml
new file mode 100644
index 000000000..1c4f4d1aa
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/archive/tests/core.yml
@@ -0,0 +1,177 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Test code for the archive module.
+# Copyright (c) 2017, Abhijeet Kasurde <akasurde@redhat.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Make sure we start fresh
+
+# Core functionality tests
+- name: Archive - no options ({{ format }})
+ archive:
+ path: "{{ remote_tmp_dir }}/*.txt"
+ dest: "{{ remote_tmp_dir }}/archive_no_opts.{{ format }}"
+ format: "{{ format }}"
+ register: archive_no_options
+
+- name: Verify that archive exists - no options ({{ format }})
+ file:
+ path: "{{remote_tmp_dir}}/archive_no_opts.{{ format }}"
+ state: file
+
+- name: Verify that archive result is changed and includes all files - no options ({{ format }})
+ assert:
+ that:
+ - archive_no_options is changed
+ - "archive_no_options.dest_state == 'archive'"
+ - "{{ archive_no_options.archived | length }} == 3"
+
+- name: Remove the archive - no options ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/archive_no_options.{{ format }}"
+ state: absent
+
+- name: Archive - file options ({{ format }})
+ archive:
+ path: "{{ remote_tmp_dir }}/*.txt"
+ dest: "{{ remote_tmp_dir }}/archive_file_options.{{ format }}"
+ format: "{{ format }}"
+ mode: "u+rwX,g-rwx,o-rwx"
+ register: archive_file_options
+
+- name: Retrieve archive file information - file options ({{ format }})
+ stat:
+ path: "{{ remote_tmp_dir }}/archive_file_options.{{ format }}"
+ register: archive_file_options_stat
+
+- name: Test that the file modes were changed
+ assert:
+ that:
+ - archive_file_options_stat is not changed
+ - "archive_file_options.mode == '0600'"
+ - "{{ archive_file_options.archived | length }} == 3"
+
+- name: Remove the archive - file options ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/archive_file_options.{{ format }}"
+ state: absent
+
+- name: Archive - non-ascii ({{ format }})
+ archive:
+ path: "{{ remote_tmp_dir }}/*.txt"
+ dest: "{{ remote_tmp_dir }}/archive_nonascii_くらとみ.{{ format }}"
+ format: "{{ format }}"
+ register: archive_nonascii
+
+- name: Retrieve archive file information - non-ascii ({{ format }})
+ stat:
+ path: "{{ remote_tmp_dir }}/archive_nonascii_くらとみ.{{ format }}"
+ register: archive_nonascii_stat
+
+- name: Test that archive exists - non-ascii ({{ format }})
+ assert:
+ that:
+ - archive_nonascii is changed
+ - archive_nonascii_stat.stat.exists == true
+
+- name: Remove the archive - non-ascii ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/archive_nonascii_くらとみ.{{ format }}"
+ state: absent
+
+- name: Archive - single target ({{ format }})
+ archive:
+ path: "{{ remote_tmp_dir }}/foo.txt"
+ dest: "{{ remote_tmp_dir }}/archive_single_target.{{ format }}"
+ format: "{{ format }}"
+ register: archive_single_target
+
+- name: Assert archive has correct state - single target ({{ format }})
+ assert:
+ that:
+ - archive_single_target.dest_state == state_map[format]
+ vars:
+ state_map:
+ tar: archive
+ zip: archive
+ gz: compress
+ bz2: compress
+ xz: compress
+
+- block:
+ - name: Retrieve contents of archive - single target ({{ format }})
+ ansible.builtin.unarchive:
+ src: "{{ remote_tmp_dir }}/archive_single_target.{{ format }}"
+ dest: .
+ list_files: true
+ check_mode: true
+ ignore_errors: true
+ register: archive_single_target_contents
+
+ - name: Assert that file names are preserved - single target ({{ format }})
+ assert:
+ that:
+ - "'oo.txt' not in archive_single_target_contents.files"
+ - "'foo.txt' in archive_single_target_contents.files"
+ # ``unarchive`` fails for RHEL and FreeBSD on ansible 2.x
+ when: archive_single_target_contents is success and archive_single_target_contents is not skipped
+ when: "format == 'zip'"
+
+- name: Remove archive - single target ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/archive_single_target.{{ format }}"
+ state: absent
+
+- name: Archive - path list ({{ format }})
+ archive:
+ path:
+ - "{{ remote_tmp_dir }}/empty.txt"
+ - "{{ remote_tmp_dir }}/foo.txt"
+ - "{{ remote_tmp_dir }}/bar.txt"
+ dest: "{{ remote_tmp_dir }}/archive_path_list.{{ format }}"
+ format: "{{ format }}"
+ register: archive_path_list
+
+- name: Verify that archive exists - path list ({{ format }})
+ file:
+ path: "{{remote_tmp_dir}}/archive_path_list.{{ format }}"
+ state: file
+
+- name: Assert that archive contains all files - path list ({{ format }})
+ assert:
+ that:
+ - archive_path_list is changed
+ - "{{ archive_path_list.archived | length }} == 3"
+
+- name: Remove archive - path list ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/archive_path_list.{{ format }}"
+ state: absent
+
+- name: Archive - missing paths ({{ format }})
+ archive:
+ path:
+ - "{{ remote_tmp_dir }}/*.txt"
+ - "{{ remote_tmp_dir }}/dne.txt"
+ exclude_path: "{{ remote_tmp_dir }}/foo.txt"
+ dest: "{{ remote_tmp_dir }}/archive_missing_paths.{{ format }}"
+ format: "{{ format }}"
+ register: archive_missing_paths
+
+- name: Assert that incomplete archive has incomplete state - missing paths ({{ format }})
+ assert:
+ that:
+ - archive_missing_paths is changed
+ - "archive_missing_paths.dest_state == 'incomplete'"
+ - "'{{ remote_tmp_dir }}/dne.txt' in archive_missing_paths.missing"
+ - "'{{ remote_tmp_dir }}/foo.txt' not in archive_missing_paths.missing"
+
+- name: Remove archive - missing paths ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/archive_missing_paths.{{ format }}"
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/archive/tests/exclusions.yml b/ansible_collections/community/general/tests/integration/targets/archive/tests/exclusions.yml
new file mode 100644
index 000000000..3c5f1fc5c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/archive/tests/exclusions.yml
@@ -0,0 +1,44 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Archive - exclusion patterns ({{ format }})
+ archive:
+ path: "{{ remote_tmp_dir }}/*.txt"
+ dest: "{{ remote_tmp_dir }}/archive_exclusion_patterns.{{ format }}"
+ format: "{{ format }}"
+ exclusion_patterns: b?r.*
+ register: archive_exclusion_patterns
+
+- name: Assert that only included files are archived - exclusion patterns ({{ format }})
+ assert:
+ that:
+ - archive_exclusion_patterns is changed
+ - "'bar.txt' not in archive_exclusion_patterns.archived"
+
+- name: Remove archive - exclusion patterns ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/archive_exclusion_patterns.{{ format }}"
+ state: absent
+
+- name: Archive - exclude path ({{ format }})
+ archive:
+ path:
+ - "{{ remote_tmp_dir }}/sub/subfile.txt"
+ - "{{ remote_tmp_dir }}"
+ exclude_path:
+ - "{{ remote_tmp_dir }}"
+ dest: "{{ remote_tmp_dir }}/archive_exclude_paths.{{ format }}"
+ format: "{{ format }}"
+ register: archive_excluded_paths
+
+- name: Assert that excluded paths do not influence archive root - exclude path ({{ format }})
+ assert:
+ that:
+ - archive_excluded_paths.arcroot != remote_tmp_dir
+
+- name: Remove archive - exclude path ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/archive_exclude_paths.{{ format }}"
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/archive/tests/idempotency.yml b/ansible_collections/community/general/tests/integration/targets/archive/tests/idempotency.yml
new file mode 100644
index 000000000..32f20a656
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/archive/tests/idempotency.yml
@@ -0,0 +1,144 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Archive - file content idempotency ({{ format }})
+ archive:
+ path: "{{ remote_tmp_dir }}/*.txt"
+ dest: "{{ remote_tmp_dir }}/archive_file_content_idempotency.{{ format }}"
+ format: "{{ format }}"
+ register: file_content_idempotency_before
+
+- name: Modify file - file content idempotency ({{ format }})
+ lineinfile:
+ line: bar.txt
+ regexp: "^foo.txt$"
+ path: "{{ remote_tmp_dir }}/foo.txt"
+
+- name: Archive second time - file content idempotency ({{ format }})
+ archive:
+ path: "{{ remote_tmp_dir }}/*.txt"
+ dest: "{{ remote_tmp_dir }}/archive_file_content_idempotency.{{ format }}"
+ format: "{{ format }}"
+ register: file_content_idempotency_after
+
+- name: Assert task status is changed - file content idempotency ({{ format }})
+ assert:
+ that:
+ - file_content_idempotency_after is changed
+ # Only ``zip`` archives are guaranteed to compare file content checksums rather than header checksums
+ when: "format == 'zip'"
+
+- name: Remove archive - file content idempotency ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/archive_file_content_idempotency.{{ format }}"
+ state: absent
+
+- name: Modify file back - file content idempotency ({{ format }})
+ lineinfile:
+ line: foo.txt
+ regexp: "^bar.txt$"
+ path: "{{ remote_tmp_dir }}/foo.txt"
+
+- name: Archive - file name idempotency ({{ format }})
+ archive:
+ path: "{{ remote_tmp_dir }}/*.txt"
+ dest: "{{ remote_tmp_dir }}/archive_file_name_idempotency.{{ format }}"
+ format: "{{ format }}"
+ register: file_name_idempotency_before
+
+- name: Rename file - file name idempotency ({{ format }})
+ command: "mv {{ remote_tmp_dir }}/foo.txt {{ remote_tmp_dir }}/fii.txt"
+
+- name: Archive again - file name idempotency ({{ format }})
+ archive:
+ path: "{{ remote_tmp_dir }}/*.txt"
+ dest: "{{ remote_tmp_dir }}/archive_file_name_idempotency.{{ format }}"
+ format: "{{ format }}"
+ register: file_name_idempotency_after
+
+- name: Check task status - file name idempotency ({{ format }})
+ assert:
+ that:
+ - file_name_idempotency_after is changed
+
+- name: Remove archive - file name idempotency ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/archive_file_name_idempotency.{{ format }}"
+ state: absent
+
+- name: Rename file back - file name idempotency ({{ format }})
+ command: "mv {{ remote_tmp_dir }}/fii.txt {{ remote_tmp_dir }}/foo.txt"
+
+- name: Archive - single file content idempotency ({{ format }})
+ archive:
+ path: "{{ remote_tmp_dir }}/foo.txt"
+ dest: "{{ remote_tmp_dir }}/archive_single_file_content_idempotency.{{ format }}"
+ format: "{{ format }}"
+ register: single_file_content_idempotency_before
+
+- name: Modify file - single file content idempotency ({{ format }})
+ lineinfile:
+ line: bar.txt
+ regexp: "^foo.txt$"
+ path: "{{ remote_tmp_dir }}/foo.txt"
+
+- name: Archive second time - single file content idempotency ({{ format }})
+ archive:
+ path: "{{ remote_tmp_dir }}/foo.txt"
+ dest: "{{ remote_tmp_dir }}/archive_single_file_content_idempotency.{{ format }}"
+ format: "{{ format }}"
+ register: single_file_content_idempotency_after
+
+- name: Assert task status is changed - single file content idempotency ({{ format }})
+ assert:
+ that:
+ - single_file_content_idempotency_after is changed
+ # ``tar`` archives are not guaranteed to identify changes to file content if the file meta properties are unchanged.
+ when: "format != 'tar'"
+
+- name: Remove archive - single file content idempotency ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/archive_single_file_content_idempotency.{{ format }}"
+ state: absent
+
+- name: Modify file back - single file content idempotency ({{ format }})
+ lineinfile:
+ line: foo.txt
+ regexp: "^bar.txt$"
+ path: "{{ remote_tmp_dir }}/foo.txt"
+
+- name: Archive - single file name idempotency ({{ format }})
+ archive:
+ path: "{{ remote_tmp_dir }}/foo.txt"
+ dest: "{{ remote_tmp_dir }}/archive_single_file_name_idempotency.{{ format }}"
+ format: "{{ format }}"
+ register: single_file_name_idempotency_before
+
+- name: Rename file - single file name idempotency ({{ format }})
+ command: "mv {{ remote_tmp_dir }}/foo.txt {{ remote_tmp_dir }}/fii.txt"
+
+- name: Archive again - single file name idempotency ({{ format }})
+ archive:
+ path: "{{ remote_tmp_dir }}/fii.txt"
+ dest: "{{ remote_tmp_dir }}/archive_single_file_name_idempotency.{{ format }}"
+ format: "{{ format }}"
+ register: single_file_name_idempotency_after
+
+
+# The gz, bz2, and xz formats do not store the original file name
+# so it is not possible to identify a change in this scenario.
+- name: Check task status - single file name idempotency ({{ format }})
+ assert:
+ that:
+ - single_file_name_idempotency_after is changed
+ when: "format in ('tar', 'zip')"
+
+- name: Remove archive - single file name idempotency ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/archive_single_file_name_idempotency.{{ format }}"
+ state: absent
+
+- name: Rename file back - single file name idempotency ({{ format }})
+ command: "mv {{ remote_tmp_dir }}/fii.txt {{ remote_tmp_dir }}/foo.txt"
diff --git a/ansible_collections/community/general/tests/integration/targets/archive/tests/remove.yml b/ansible_collections/community/general/tests/integration/targets/archive/tests/remove.yml
new file mode 100644
index 000000000..8f0b8cff8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/archive/tests/remove.yml
@@ -0,0 +1,211 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Archive - remove source files ({{ format }})
+ archive:
+ path: "{{ remote_tmp_dir }}/*.txt"
+ dest: "{{ remote_tmp_dir }}/archive_remove_source_files.{{ format }}"
+ format: "{{ format }}"
+ remove: true
+ register: archive_remove_source_files
+
+- name: Verify archive exists - remove source files ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/archive_remove_source_files.{{ format }}"
+ state: file
+
+- name: Verify all files were archived - remove source files ({{ format }})
+ assert:
+ that:
+ - archive_remove_source_files is changed
+ - "{{ archive_remove_source_files.archived | length }} == 3"
+
+- name: Remove Archive - remove source files ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/archive_remove_source_files.{{ format }}"
+ state: absent
+
+- name: Assert that source files were removed - remove source files ({{ format }})
+ assert:
+ that:
+ - "'{{ remote_tmp_dir }}/{{ item }}' is not exists"
+ with_items:
+ - foo.txt
+ - bar.txt
+ - empty.txt
+
+- name: Copy source files - remove source directory ({{ format }})
+ copy:
+ src: "{{ item }}"
+ dest: "{{ remote_tmp_dir }}/{{ item }}"
+ with_items:
+ - foo.txt
+ - bar.txt
+ - empty.txt
+
+- name: Create temporary directory - remove source directory ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/tmpdir"
+ state: directory
+
+- name: Copy source files to temporary directory - remove source directory ({{ format }})
+ copy:
+ src: "{{ item }}"
+ dest: "{{ remote_tmp_dir }}/tmpdir/{{ item }}"
+ with_items:
+ - foo.txt
+ - bar.txt
+ - empty.txt
+
+- name: Archive - remove source directory ({{ format }})
+ archive:
+ path: "{{ remote_tmp_dir }}/tmpdir"
+ dest: "{{ remote_tmp_dir }}/archive_remove_source_directory.{{ format }}"
+ format: "{{ format }}"
+ remove: true
+ register: archive_remove_source_directory
+
+- name: Verify archive exists - remove source directory ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/archive_remove_source_directory.{{ format }}"
+ state: file
+
+- name: Verify archive contains all files - remove source directory ({{ format }})
+ assert:
+ that:
+ - archive_remove_source_directory is changed
+ - "{{ archive_remove_source_directory.archived | length }} == 3"
+
+- name: Remove archive - remove source directory ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/archive_remove_source_directory.{{ format }}"
+ state: absent
+
+- name: Verify source directory was removed - remove source directory ({{ format }})
+ assert:
+ that:
+ - "'{{ remote_tmp_dir }}/tmpdir' is not exists"
+
+- name: Create temporary directory - remove source excluding path ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/tmpdir"
+ state: directory
+
+- name: Copy source files to temporary directory - remove source excluding path ({{ format }})
+ copy:
+ src: "{{ item }}"
+ dest: "{{ remote_tmp_dir }}/tmpdir/{{ item }}"
+ with_items:
+ - foo.txt
+ - bar.txt
+ - empty.txt
+
+- name: Archive - remove source excluding path ({{ format }})
+ archive:
+ path: "{{ remote_tmp_dir }}/tmpdir/*"
+ dest: "{{ remote_tmp_dir }}/archive_remove_source_excluding_path.{{ format }}"
+ format: "{{ format }}"
+ remove: true
+ exclude_path: "{{ remote_tmp_dir }}/tmpdir/empty.txt"
+ register: archive_remove_source_excluding_path
+
+- name: Verify archive exists - remove source excluding path ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/archive_remove_source_excluding_path.{{ format }}"
+ state: file
+
+- name: Verify all files except excluded are archived - remove source excluding path ({{ format }})
+ assert:
+ that:
+ - archive_remove_source_excluding_path is changed
+ - "{{ archive_remove_source_excluding_path.archived | length }} == 2"
+
+- name: Remove archive - remove source excluding path ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/archive_remove_source_excluding_path.{{ format }}"
+ state: absent
+
+- name: Verify that excluded file still exists - remove source excluding path ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/tmpdir/empty.txt"
+ state: file
+
+- name: Copy source files to temporary directory - remove source excluding sub path ({{ format }})
+ copy:
+ src: "{{ item }}"
+ dest: "{{ remote_tmp_dir }}/tmpdir/{{ item }}"
+ with_items:
+ - foo.txt
+ - bar.txt
+ - empty.txt
+ - sub
+ - sub/subfile.txt
+
+- name: Archive - remove source excluding sub path ({{ format }})
+ archive:
+ path:
+ - "{{ remote_tmp_dir }}/tmpdir/*.txt"
+ - "{{ remote_tmp_dir }}/tmpdir/sub/*"
+ dest: "{{ remote_tmp_dir }}/archive_remove_source_excluding_sub_path.{{ format }}"
+ format: "{{ format }}"
+ remove: true
+ exclude_path: "{{ remote_tmp_dir }}/tmpdir/sub/subfile.txt"
+ register: archive_remove_source_excluding_sub_path
+
+- name: Verify archive exists - remove source excluding sub path ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/archive_remove_source_excluding_sub_path.{{ format }}"
+ state: file
+
+- name: Remove archive - remove source excluding sub path ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/archive_remove_source_excluding_sub_path.{{ format }}"
+ state: absent
+
+- name: Verify that sub path still exists - remove source excluding sub path ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/tmpdir/sub/subfile.txt"
+ state: file
+
+- name: Copy source files to temporary directory - remove source with nested paths ({{ format }})
+ copy:
+ src: "{{ item }}"
+ dest: "{{ remote_tmp_dir }}/tmpdir/{{ item }}"
+ with_items:
+ - foo.txt
+ - bar.txt
+ - empty.txt
+ - sub
+ - sub/subfile.txt
+
+- name: Archive - remove source with nested paths ({{ format }})
+ archive:
+ path: "{{ remote_tmp_dir }}/tmpdir/"
+ dest: "{{ remote_tmp_dir }}/archive_remove_source_nested_paths.{{ format }}"
+ format: "{{ format }}"
+ remove: true
+ register: archive_remove_nested_paths
+
+- name: Verify archive exists - remove source with nested paths ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/archive_remove_source_nested_paths.{{ format }}"
+ state: file
+
+- name: Verify source files were removed - remove source with nested paths ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/tmpdir"
+ state: absent
+ register: archive_remove_nested_paths_status
+
+- name: Assert tasks status - remove source with nested paths ({{ format }})
+ assert:
+ that:
+ - archive_remove_nested_paths is success
+ - archive_remove_nested_paths_status is not changed
+
+- name: Remove archive - remove source with nested paths ({{ format }})
+ file:
+ path: "{{ remote_tmp_dir }}/archive_remove_source_nested_paths.{{ format }}"
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/aliases b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/aliases
new file mode 100644
index 000000000..914c36ad3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/aliases
@@ -0,0 +1,12 @@
+# Copyright (c) Ansible Projec
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/3
+azp/posix/vm
+destructive
+needs/privileged
+skip/aix
+skip/freebsd
+skip/osx
+skip/macos
diff --git a/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/defaults/main.yml
new file mode 100644
index 000000000..52c88d5de
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/defaults/main.yml
@@ -0,0 +1,20 @@
+---
+# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+btrfs_subvolume_single_configs:
+- file: "/tmp/disks0.img"
+ loop: "/dev/loop95"
+btrfs_subvolume_multiple_configs:
+- file: "/tmp/diskm0.img"
+ loop: "/dev/loop97"
+- file: "/tmp/diskm1.img"
+ loop: "/dev/loop98"
+- file: "/tmp/diskm2.img"
+ loop: "/dev/loop99"
+btrfs_subvolume_configs: "{{ btrfs_subvolume_single_configs + btrfs_subvolume_multiple_configs }}"
+btrfs_subvolume_single_devices: "{{ btrfs_subvolume_single_configs | map(attribute='loop') }}"
+btrfs_subvolume_single_label: "single"
+btrfs_subvolume_multiple_devices: "{{ btrfs_subvolume_multiple_configs | map(attribute='loop') }}"
+btrfs_subvolume_multiple_label: "multiple"
diff --git a/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/main.yml
new file mode 100644
index 000000000..d47270440
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/main.yml
@@ -0,0 +1,29 @@
+---
+# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install required packages
+ ansible.builtin.package:
+ name:
+ - btrfs-progs # btrfs userspace
+ - util-linux # losetup
+ ignore_errors: True
+ register: btrfs_installed
+
+- name: Execute integration tests tests
+ block:
+ - ansible.builtin.include_tasks: 'setup.yml'
+
+ - name: "Execute test scenario for single device filesystem"
+ ansible.builtin.include_tasks: 'run_filesystem_tests.yml'
+ vars:
+ btrfs_subvolume_target_device: "{{ btrfs_subvolume_single_devices | first }}"
+ btrfs_subvolume_target_label: "{{ btrfs_subvolume_single_label }}"
+
+ - name: "Execute test scenario for multiple device configuration"
+ ansible.builtin.include_tasks: 'run_filesystem_tests.yml'
+ vars:
+ btrfs_subvolume_target_device: "{{ btrfs_subvolume_multiple_devices | first }}"
+ btrfs_subvolume_target_label: "{{ btrfs_subvolume_multiple_label }}"
+ when: btrfs_installed is success
diff --git a/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/run_common_tests.yml b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/run_common_tests.yml
new file mode 100644
index 000000000..013ec50bf
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/run_common_tests.yml
@@ -0,0 +1,15 @@
+---
+# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- ansible.builtin.include_tasks: 'test_subvolume_simple.yml'
+- ansible.builtin.include_tasks: 'test_subvolume_nested.yml'
+- ansible.builtin.include_tasks: 'test_subvolume_recursive.yml'
+- ansible.builtin.include_tasks: 'test_subvolume_default.yml'
+
+- ansible.builtin.include_tasks: 'test_snapshot_skip.yml'
+- ansible.builtin.include_tasks: 'test_snapshot_clobber.yml'
+- ansible.builtin.include_tasks: 'test_snapshot_error.yml'
+
+- ansible.builtin.include_tasks: 'test_subvolume_whitespace.yml'
diff --git a/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/run_filesystem_tests.yml b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/run_filesystem_tests.yml
new file mode 100644
index 000000000..0ea3fa666
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/run_filesystem_tests.yml
@@ -0,0 +1,32 @@
+---
+# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- ansible.builtin.include_tasks: 'test_filesystem_matching.yml'
+
+- name: "Execute all test scenario for unmounted filesystem"
+ ansible.builtin.include_tasks: 'run_common_tests.yml'
+
+- name: "Execute test scenarios where non-root subvolume is mounted"
+ block:
+ - name: Create subvolume '/nonroot'
+ community.general.btrfs_subvolume:
+ automount: Yes
+ name: "/nonroot"
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ state: "present"
+ register: nonroot
+ - name: "Mount subvolume '/nonroot'"
+ ansible.posix.mount:
+ src: "{{ nonroot.filesystem.devices | first }}"
+ path: /mnt
+ opts: "subvolid={{ nonroot.target_subvolume_id }}"
+ fstype: btrfs
+ state: mounted
+ - name: "Run tests for explicit, mounted single device configuration"
+ ansible.builtin.include_tasks: 'run_common_tests.yml'
+ - name: "Unmount subvolume /nonroot"
+ ansible.posix.mount:
+ path: /mnt
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/setup.yml b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/setup.yml
new file mode 100644
index 000000000..f5bbdf9c5
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/setup.yml
@@ -0,0 +1,37 @@
+---
+# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: "Create file {{ item.file }} to back loop device {{ item.loop }}"
+ ansible.builtin.command:
+ cmd: "dd if=/dev/zero of={{ item.file }} bs=1M count=200" ## minimum count 109
+ creates: "{{ item.file }}"
+ with_items: "{{ btrfs_subvolume_configs }}"
+
+- name: "Setup loop device {{ item.loop }}"
+ ansible.builtin.command:
+ cmd: "losetup {{ item.loop }} {{ item.file }}"
+ creates: "{{ item.loop }}"
+ with_items: "{{ btrfs_subvolume_configs }}"
+
+- name: Create single device btrfs filesystem
+ ansible.builtin.command:
+ cmd: "mkfs.btrfs --label {{ btrfs_subvolume_single_label }} -f {{ btrfs_subvolume_single_devices | first }}"
+ changed_when: True
+
+- name: Create multiple device btrfs filesystem
+ ansible.builtin.command:
+ cmd: "mkfs.btrfs --label {{ btrfs_subvolume_multiple_label }} -f -d raid0 {{ btrfs_subvolume_multiple_devices | join(' ') }}"
+ changed_when: True
+
+# Typically created by udev, but apparently missing on Alpine
+- name: Create btrfs control device node
+ ansible.builtin.command:
+ cmd: "mknod /dev/btrfs-control c 10 234"
+ creates: "/dev/btrfs-control"
+
+- name: Force rescan to ensure all device are detected
+ ansible.builtin.command:
+ cmd: "btrfs device scan"
+ changed_when: True
diff --git a/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_filesystem_matching.yml b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_filesystem_matching.yml
new file mode 100644
index 000000000..2455eeacf
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_filesystem_matching.yml
@@ -0,0 +1,80 @@
+---
+# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: "Match targeted filesystem by label"
+ block:
+ - name: Match '{{ btrfs_subvolume_target_label }}' filesystem by label
+ community.general.btrfs_subvolume:
+ automount: Yes
+ name: "/match_label"
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ state: "present"
+ register: result
+
+ - name: Validate the '{{ btrfs_subvolume_target_label }}' filesystem was chosen
+ ansible.builtin.assert:
+ that:
+ - result.filesystem.label == btrfs_subvolume_target_label
+
+- name: "Match targeted filesystem by uuid"
+ block:
+ - name: Match '{{ btrfs_subvolume_target_label }}' filesystem by uuid
+ community.general.btrfs_subvolume:
+ automount: Yes
+ name: "/match_uuid"
+ filesystem_uuid: "{{ result.filesystem.uuid }}"
+ state: "present"
+ register: result
+
+ - name: Validate the '{{ btrfs_subvolume_target_label }}' filesystem was chosen
+ ansible.builtin.assert:
+ that:
+ - result.filesystem.label == btrfs_subvolume_target_label
+
+- name: "Match targeted filesystem by devices"
+ block:
+ - name: Match '{{ btrfs_subvolume_target_label }}' filesystem by device
+ community.general.btrfs_subvolume:
+ automount: Yes
+ name: "/match_device"
+ filesystem_device: "{{ result.filesystem.devices | first }}"
+ state: "present"
+ register: result
+
+ - name: Validate the '{{ btrfs_subvolume_target_label }}' filesystem was chosen
+ ansible.builtin.assert:
+ that:
+ - result.filesystem.label == btrfs_subvolume_target_label
+
+- name: "Match only mounted filesystem"
+ block:
+ - name: "Mount filesystem '{{ btrfs_subvolume_target_label }}'"
+ ansible.posix.mount:
+ src: "{{ result.filesystem.devices | first }}"
+ path: /mnt
+ opts: "subvolid={{ 5 }}"
+ fstype: btrfs
+ state: mounted
+
+ - name: Print current status
+ community.general.btrfs_info:
+
+ - name: Match '{{ btrfs_subvolume_target_label }}' filesystem when only mount
+ community.general.btrfs_subvolume:
+ automount: Yes
+ name: "/match_only_mounted"
+ state: "present"
+ register: result
+
+ - name: "Unmount filesystem '{{ btrfs_subvolume_target_label }}'"
+ ansible.posix.mount:
+ path: /mnt
+ state: absent
+
+ - name: Validate the '{{ btrfs_subvolume_target_label }}' filesystem was chosen
+ ansible.builtin.assert:
+ that:
+ - result.filesystem.label == btrfs_subvolume_target_label
+ when: False # TODO don't attempt this if the host already has a pre-existing btrfs filesystem
diff --git a/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_snapshot_clobber.yml b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_snapshot_clobber.yml
new file mode 100644
index 000000000..ce25a999b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_snapshot_clobber.yml
@@ -0,0 +1,41 @@
+---
+# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create a snapshot, overwriting if one already exists at path
+ block:
+ - name: Create a snapshot named 'snapshot_clobber'
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/snapshot_clobber"
+ snapshot_source: "/"
+ snapshot_conflict: "clobber"
+ state: "present"
+ register: result
+ - name: Snapshot 'snapshot_clobber' created
+ ansible.builtin.assert:
+ that:
+ - result is changed
+
+ - name: Create a snapshot named 'snapshot_clobber' (no idempotency)
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/snapshot_clobber"
+ snapshot_source: "/"
+ snapshot_conflict: "clobber"
+ state: "present"
+ register: result
+ - name: Snapshot 'snapshot_clobber' created (no idempotency)
+ ansible.builtin.assert:
+ that:
+ - result is changed
+
+- name: Cleanup created snapshot
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/snapshot_clobber"
+ state: "absent"
diff --git a/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_snapshot_error.yml b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_snapshot_error.yml
new file mode 100644
index 000000000..49d928b74
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_snapshot_error.yml
@@ -0,0 +1,42 @@
+---
+# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create a snapshot, erroring if one already exists at path
+ block:
+ - name: Create a snapshot named 'snapshot_error'
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/snapshot_error"
+ snapshot_source: "/"
+ snapshot_conflict: "error"
+ state: "present"
+ register: result
+ - name: Snapshot 'snapshot_error' created
+ ansible.builtin.assert:
+ that:
+ - result is changed
+
+ - name: Create a snapshot named 'snapshot_error' (no idempotency)
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/snapshot_error"
+ snapshot_source: "/"
+ snapshot_conflict: "error"
+ state: "present"
+ register: result
+ ignore_errors: true
+ - name: Snapshot 'snapshot_error' created (no idempotency)
+ ansible.builtin.assert:
+ that:
+ - result is not changed
+
+- name: Cleanup created snapshot
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/snapshot_error"
+ state: "absent"
diff --git a/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_snapshot_skip.yml b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_snapshot_skip.yml
new file mode 100644
index 000000000..07e65b133
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_snapshot_skip.yml
@@ -0,0 +1,41 @@
+---
+# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create a snapshot if one does not already exist at path
+ block:
+ - name: Create a snapshot named 'snapshot_skip'
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/snapshot_skip"
+ snapshot_source: "/"
+ snapshot_conflict: "skip"
+ state: "present"
+ register: result
+ - name: Snapshot 'snapshot_skip' created
+ ansible.builtin.assert:
+ that:
+ - result is changed
+
+ - name: Create a snapshot named 'snapshot_skip' (idempotency)
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/snapshot_skip"
+ snapshot_source: "/"
+ snapshot_conflict: "skip"
+ state: "present"
+ register: result
+ - name: Snapshot 'snapshot_skip' created (idempotency)
+ ansible.builtin.assert:
+ that:
+ - result is not changed
+
+- name: Cleanup created snapshot
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/snapshot_skip"
+ state: "absent"
diff --git a/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_subvolume_default.yml b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_subvolume_default.yml
new file mode 100644
index 000000000..f6eed9387
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_subvolume_default.yml
@@ -0,0 +1,99 @@
+---
+# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Change the default subvolume
+ block:
+ - name: Update filesystem default subvolume to '@'
+ community.general.btrfs_subvolume:
+ automount: Yes
+ default: True
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/@"
+ state: "present"
+ register: result
+ - name: Subvolume '@' set to default
+ ansible.builtin.assert:
+ that:
+ - result is changed
+ - name: Update filesystem default subvolume to '@' (idempotency)
+ community.general.btrfs_subvolume:
+ automount: Yes
+ default: True
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/@"
+ state: "present"
+ register: result
+ - name: Subvolume '@' set to default (idempotency)
+ ansible.builtin.assert:
+ that:
+ - result is not changed
+
+- name: Revert the default subvolume
+ block:
+ - name: Revert filesystem default subvolume to '/'
+ community.general.btrfs_subvolume:
+ automount: Yes
+ default: True
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/"
+ state: "present"
+ register: result
+ - name: Subvolume '/' set to default
+ ansible.builtin.assert:
+ that:
+ - result is changed
+ - name: Revert filesystem default subvolume to '/' (idempotency)
+ community.general.btrfs_subvolume:
+ automount: Yes
+ default: True
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/"
+ state: "present"
+ register: result
+ - name: Subvolume '/' set to default (idempotency)
+ ansible.builtin.assert:
+ that:
+ - result is not changed
+
+
+- name: Change the default subvolume again
+ block:
+ - name: Update filesystem default subvolume to '@'
+ community.general.btrfs_subvolume:
+ automount: Yes
+ default: True
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/@"
+ state: "present"
+ register: result
+ - name: Subvolume '@' set to default
+ ansible.builtin.assert:
+ that:
+ - result is changed
+
+- name: Revert custom default subvolume to fs_tree root when deleted
+ block:
+ - name: Delete custom default subvolume '@'
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/@"
+ state: "absent"
+ register: result
+ - name: Subvolume '@' deleted
+ ansible.builtin.assert:
+ that:
+ - result is changed
+ - name: Delete custom default subvolume '@' (idempotency)
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/@"
+ state: "absent"
+ register: result
+ - name: Subvolume '@' deleted (idempotency)
+ ansible.builtin.assert:
+ that:
+ - result is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_subvolume_nested.yml b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_subvolume_nested.yml
new file mode 100644
index 000000000..b706bf72a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_subvolume_nested.yml
@@ -0,0 +1,61 @@
+---
+# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create parent subvolume 'container'
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/container"
+ state: "present"
+
+- name: Create a nested subvolume
+ block:
+ - name: Create a subvolume named 'nested' inside 'container'
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/container/nested"
+ state: "present"
+ register: result
+ - name: Subvolume 'container/nested' created
+ ansible.builtin.assert:
+ that:
+ - result is changed
+ - name: Create a subvolume named 'nested' inside 'container' (idempotency)
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/container/nested"
+ state: "present"
+ register: result
+ - name: Subvolume 'container/nested' created (idempotency)
+ ansible.builtin.assert:
+ that:
+ - result is not changed
+
+- name: Remove a nested subvolume
+ block:
+ - name: Remove a subvolume named 'nested' inside 'container'
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/container/nested"
+ state: "absent"
+ register: result
+ - name: Subvolume 'container/nested' removed
+ ansible.builtin.assert:
+ that:
+ - result is changed
+ - name: Remove a subvolume named 'nested' inside 'container' (idempotency)
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/container/nested"
+ state: "absent"
+ register: result
+ - name: Subvolume 'container/nested' removed (idempotency)
+ ansible.builtin.assert:
+ that:
+ - result is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_subvolume_recursive.yml b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_subvolume_recursive.yml
new file mode 100644
index 000000000..7e9f99007
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_subvolume_recursive.yml
@@ -0,0 +1,86 @@
+---
+# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Recursively create subvolumes
+ block:
+ - name: Create a subvolume named '/recursive/son/grandson'
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/recursive/son/grandson"
+ recursive: Yes
+ state: "present"
+ register: result
+ - name: Subvolume named '/recursive/son/grandson' created
+ ansible.builtin.assert:
+ that:
+ - result is changed
+
+ - name: Create a subvolume named '/recursive/son/grandson' (idempotency)
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/recursive/son/grandson"
+ recursive: Yes
+ state: "present"
+ register: result
+ - name: Subvolume named '/recursive/son/grandson' created (idempotency)
+ ansible.builtin.assert:
+ that:
+ - result is not changed
+
+ - name: Create a subvolume named '/recursive/daughter/granddaughter'
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/recursive/daughter/granddaughter"
+ recursive: Yes
+ state: "present"
+ register: result
+ - name: Subvolume named '/recursive/son/grandson' created
+ ansible.builtin.assert:
+ that:
+ - result is changed
+
+ - name: Create a subvolume named '/recursive/daughter/granddaughter' (idempotency)
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/recursive/daughter/granddaughter"
+ recursive: Yes
+ state: "present"
+ register: result
+ - name: Subvolume named '/recursive/son/grandson' created (idempotency)
+ ansible.builtin.assert:
+ that:
+ - result is not changed
+
+- name: Recursively remove subvolumes
+ block:
+ - name: Remove subvolume '/recursive' and all descendents
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/recursive"
+ recursive: Yes
+ state: "absent"
+ register: result
+ - name: Subvolume '/recursive' removed
+ ansible.builtin.assert:
+ that:
+ - result is changed
+
+ - name: Remove subvolume '/recursive' and all descendents (idempotency)
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/recursive"
+ recursive: Yes
+ state: "absent"
+ register: result
+ - name: Subvolume '/recursive' removed (idempotency)
+ ansible.builtin.assert:
+ that:
+ - result is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_subvolume_simple.yml b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_subvolume_simple.yml
new file mode 100644
index 000000000..6cd214e74
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_subvolume_simple.yml
@@ -0,0 +1,54 @@
+---
+# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create a simple subvolume
+ block:
+ - name: Create a subvolume named 'simple'
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/simple"
+ state: "present"
+ register: result
+ - name: Subvolume named 'simple' created
+ ansible.builtin.assert:
+ that:
+ - result is changed
+ - name: Create a subvolume named 'simple' (idempotency)
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/simple"
+ state: "present"
+ register: result
+ - name: Subvolume named 'simple' created (idempotency)
+ ansible.builtin.assert:
+ that:
+ - result is not changed
+
+- name: Remove a simple subvolume
+ block:
+ - name: Remove a subvolume named 'simple'
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/simple"
+ state: "absent"
+ register: result
+ - name: Subvolume named 'simple' removed
+ ansible.builtin.assert:
+ that:
+ - result is changed
+ - name: Remove a subvolume named 'simple' (idempotency)
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/simple"
+ state: "absent"
+ register: result
+ - name: Subvolume named 'simple' removed (idempotency)
+ ansible.builtin.assert:
+ that:
+ - result is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_subvolume_whitespace.yml b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_subvolume_whitespace.yml
new file mode 100644
index 000000000..6a0147af6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/btrfs_subvolume/tasks/test_subvolume_whitespace.yml
@@ -0,0 +1,62 @@
+---
+# Copyright (c) 2022, Gregory Furlong <gnfzdz@fzdz.io>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create a subvolume named 'container'
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/container"
+ state: "present"
+
+- name: Create a subvolume with whitespace in the name
+ block:
+ - name: Create a subvolume named 'container/my data'
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/container/my data"
+ state: "present"
+ register: result
+ - name: Subvolume named 'container/my data' created
+ ansible.builtin.assert:
+ that:
+ - result is changed
+ - name: Create a subvolume named 'container/my data' (idempotency)
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/container/my data"
+ state: "present"
+ register: result
+ - name: Subvolume named 'container/my data' created (idempotency)
+ ansible.builtin.assert:
+ that:
+ - result is not changed
+
+- name: Remove a subvolume with whitespace in the name
+ block:
+ - name: Remove a subvolume named 'container/my data'
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/container/my data"
+ state: "absent"
+ register: result
+ - name: Subvolume named 'container/my data' removed
+ ansible.builtin.assert:
+ that:
+ - result is changed
+
+ - name: Remove a subvolume named 'container/my data' (idempotency)
+ community.general.btrfs_subvolume:
+ automount: Yes
+ filesystem_label: "{{ btrfs_subvolume_target_label }}"
+ name: "/container/my data"
+ state: "absent"
+ register: result
+ - name: Subvolume named 'container/my data' removed (idempotency)
+ ansible.builtin.assert:
+ that:
+ - result is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/callback/inventory.yml b/ansible_collections/community/general/tests/integration/targets/callback/inventory.yml
new file mode 100644
index 000000000..8e1a47e9a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/callback/inventory.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+all:
+ hosts:
+ testhost:
+ ansible_connection: local
diff --git a/ansible_collections/community/general/tests/integration/targets/callback/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/callback/tasks/main.yml
new file mode 100644
index 000000000..827217a53
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/callback/tasks/main.yml
@@ -0,0 +1,100 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- block:
+ - name: Create temporary playbook files
+ tempfile:
+ state: file
+ suffix: temp
+ loop: "{{ tests }}"
+ loop_control:
+ loop_var: test
+ label: "{{ test.name }}"
+ register: temporary_playbook_files
+
+ - name: Set temporary playbook file content
+ copy:
+ content: "{{ test.playbook }}"
+ dest: "{{ temporary_playbook_files.results[test_idx].path }}"
+ loop: "{{ tests }}"
+ loop_control:
+ loop_var: test
+ index_var: test_idx
+ label: "{{ test.name }}"
+
+ - name: Collect outputs
+ command: "ansible-playbook -i {{ inventory }} {{ playbook }}"
+ environment: "{{ test.environment }}"
+ loop: "{{ tests }}"
+ loop_control:
+ loop_var: test
+ label: "{{ test.name }}"
+ register: outputs
+ changed_when: false
+ vars:
+ inventory: "{{ role_path }}/inventory.yml"
+ playbook: "
+ {%- for result in temporary_playbook_files.results -%}
+ {%- if result.test.name == test.name -%}
+ {{- result.path -}}
+ {%- endif -%}
+ {%- endfor -%}"
+
+ - name: Assert test output equals expected output
+ assert:
+ that: result.output.differences | length == 0
+ loop: "{{ results }}"
+ loop_control:
+ loop_var: result
+ label: "{{ result.name }}"
+ register: assertions
+ vars:
+ results: >-
+ {%- set results = [] -%}
+ {%- for result in outputs.results -%}
+ {%- set differences = [] -%}
+ {%- for i in range([result.test.expected_output | count, result.stdout_lines | count] | max) -%}
+ {%- set line = "line_%s" | format(i+1) -%}
+ {%- set test_line = result.stdout_lines[i] | default(none) -%}
+ {%- set expected_lines = result.test.expected_output[i] | default(none) -%}
+ {%- if expected_lines is not string and expected_lines is not none -%}
+ {%- if test_line not in expected_lines -%}
+ {{- differences.append({
+ line: {
+ 'expected_one_of': expected_lines,
+ 'got': test_line }}) -}}
+ {%- endif -%}
+ {%- else -%}
+ {%- if expected_lines != test_line -%}
+ {{- differences.append({
+ line: {
+ 'expected': expected_lines,
+ 'got': test_line }}) -}}
+ {%- endif -%}
+ {%- endif -%}
+ {%- endfor -%}
+ {{- results.append({
+ 'name': result.test.name,
+ 'output': {
+ 'differences': differences,
+ 'expected': result.test.expected_output,
+ 'got': result.stdout_lines }}) -}}
+ {%- endfor -%}
+ {{- results -}}
+
+ always:
+ - name: Remove temporary playbooks
+ file:
+ path: "{{ temporary_file.path }}"
+ state: absent
+ loop: "{{ temporary_playbook_files.results }}"
+ loop_control:
+ loop_var: temporary_file
+ label: "{{ temporary_file.test.name }}: {{ temporary_file.path }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/callback_diy/aliases b/ansible_collections/community/general/tests/integration/targets/callback_diy/aliases
new file mode 100644
index 000000000..3e2dd244c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/callback_diy/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/3
+needs/target/callback
diff --git a/ansible_collections/community/general/tests/integration/targets/callback_diy/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/callback_diy/tasks/main.yml
new file mode 100644
index 000000000..fa468b52b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/callback_diy/tasks/main.yml
@@ -0,0 +1,462 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Run tests
+ include_role:
+ name: callback
+ vars:
+ tests:
+ - name: Not using diy callback options
+ environment:
+ ANSIBLE_NOCOLOR: 'true'
+ ANSIBLE_FORCE_COLOR: 'false'
+ ANSIBLE_STDOUT_CALLBACK: community.general.diy
+ playbook: |
+ - hosts: testhost
+ gather_facts: false
+ tasks:
+ - name: Sample task name
+ debug:
+ msg: sample debug msg
+ expected_output: [
+ "",
+ "PLAY [testhost] ****************************************************************",
+ "",
+ "TASK [Sample task name] ********************************************************",
+ "ok: [testhost] => {",
+ " \"msg\": \"sample debug msg\"",
+ "}",
+ "",
+ "PLAY RECAP *********************************************************************",
+ "testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
+ ]
+
+ - name: Set playbook_on_start_msg callback using environment variable
+ environment:
+ ANSIBLE_NOCOLOR: 'true'
+ ANSIBLE_FORCE_COLOR: 'false'
+ ANSIBLE_STDOUT_CALLBACK: community.general.diy
+ ANSIBLE_CALLBACK_DIY_PLAYBOOK_ON_START_MSG: "Sample output Sample playbook message"
+ playbook: |
+ - hosts: testhost
+ gather_facts: false
+ tasks:
+ - name: Sample task name
+ debug:
+ msg: sample debug msg
+ expected_output: [
+ "Sample output Sample playbook message",
+ "",
+ "PLAY [testhost] ****************************************************************",
+ "",
+ "TASK [Sample task name] ********************************************************",
+ "ok: [testhost] => {",
+ " \"msg\": \"sample debug msg\"",
+ "}",
+ "",
+ "PLAY RECAP *********************************************************************",
+ "testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
+ ]
+
+ - name: Set playbook_on_play_start_msg callback using play variable
+ environment:
+ ANSIBLE_NOCOLOR: 'true'
+ ANSIBLE_FORCE_COLOR: 'false'
+ ANSIBLE_STDOUT_CALLBACK: community.general.diy
+ playbook: !unsafe |
+ - name: Sample play name
+ hosts: testhost
+ gather_facts: false
+ vars:
+ ansible_callback_diy_playbook_on_play_start_msg: Sample output {{ ansible_callback_diy.play.name }}
+ tasks:
+ - name: Sample task name
+ debug:
+ msg: sample debug msg
+ expected_output: [
+ "Sample output Sample play name",
+ "",
+ "TASK [Sample task name] ********************************************************",
+ "ok: [testhost] => {",
+ " \"msg\": \"sample debug msg\"",
+ "}",
+ "",
+ "PLAY RECAP *********************************************************************",
+ "testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
+ ]
+
+ - name: Set playbook_on_task_start_msg callback using play variable
+ environment:
+ ANSIBLE_NOCOLOR: 'true'
+ ANSIBLE_FORCE_COLOR: 'false'
+ ANSIBLE_STDOUT_CALLBACK: community.general.diy
+ playbook: !unsafe |
+ - hosts: testhost
+ gather_facts: false
+ vars:
+ ansible_callback_diy_playbook_on_task_start_msg: Sample output {{ ansible_callback_diy.task.name }}
+ tasks:
+ - name: Sample task name
+ debug:
+ msg: sample debug msg
+ expected_output: [
+ "",
+ "PLAY [testhost] ****************************************************************",
+ "Sample output Sample task name",
+ "ok: [testhost] => {",
+ " \"msg\": \"sample debug msg\"",
+ "}",
+ "",
+ "PLAY RECAP *********************************************************************",
+ "testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
+ ]
+
+ - name: Set playbook_on_task_start_msg callback using task variable
+ environment:
+ ANSIBLE_NOCOLOR: 'true'
+ ANSIBLE_FORCE_COLOR: 'false'
+ ANSIBLE_STDOUT_CALLBACK: community.general.diy
+ playbook: !unsafe |
+ - hosts: testhost
+ gather_facts: false
+ tasks:
+ - name: Sample task name
+ debug:
+ msg: sample debug msg
+ vars:
+ ansible_callback_diy_playbook_on_task_start_msg: Sample output {{ ansible_callback_diy.task.name }}
+ expected_output: [
+ "",
+ "PLAY [testhost] ****************************************************************",
+ "Sample output Sample task name",
+ "ok: [testhost] => {",
+ " \"msg\": \"sample debug msg\"",
+ "}",
+ "",
+ "PLAY RECAP *********************************************************************",
+ "testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
+ ]
+
+ - name: Set runner_on_ok_msg callback using task variable
+ environment:
+ ANSIBLE_NOCOLOR: 'true'
+ ANSIBLE_FORCE_COLOR: 'false'
+ ANSIBLE_STDOUT_CALLBACK: community.general.diy
+ playbook: !unsafe |
+ - hosts: testhost
+ gather_facts: false
+ tasks:
+ - name: Sample task name
+ debug:
+ msg: sample debug msg
+ vars:
+ ansible_callback_diy_runner_on_ok_msg: Sample output {{ ansible_callback_diy.result.output.msg }}
+ expected_output: [
+ "",
+ "PLAY [testhost] ****************************************************************",
+ "",
+ "TASK [Sample task name] ********************************************************",
+ "Sample output sample debug msg",
+ "",
+ "PLAY RECAP *********************************************************************",
+ "testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
+ ]
+
+ - name: Set runner_on_failed_msg callback using task variable
+ environment:
+ ANSIBLE_NOCOLOR: 'true'
+ ANSIBLE_FORCE_COLOR: 'false'
+ ANSIBLE_STDOUT_CALLBACK: community.general.diy
+ playbook: |
+ - hosts: testhost
+ gather_facts: false
+ tasks:
+ - name: Sample task name
+ debug:
+ msg: sample debug msg
+ failed_when: true
+ ignore_errors: true
+ vars:
+ ansible_callback_diy_runner_on_failed_msg: Sample output Sample failure message
+ expected_output: [
+ "",
+ "PLAY [testhost] ****************************************************************",
+ "",
+ "TASK [Sample task name] ********************************************************",
+ "Sample output Sample failure message",
+ "",
+ "PLAY RECAP *********************************************************************",
+ "testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1 "
+ ]
+
+ - name: Set runner_on_skipped_msg callback using task variable
+ environment:
+ ANSIBLE_NOCOLOR: 'true'
+ ANSIBLE_FORCE_COLOR: 'false'
+ ANSIBLE_STDOUT_CALLBACK: community.general.diy
+ playbook: !unsafe |
+ - hosts: testhost
+ gather_facts: false
+ tasks:
+ - name: Sample task name
+ debug:
+ msg: sample debug msg
+ when: false
+ vars:
+ ansible_callback_diy_runner_on_skipped_msg: Sample output Skipped {{ ansible_callback_diy.task.name }}
+ expected_output: [
+ "",
+ "PLAY [testhost] ****************************************************************",
+ "",
+ "TASK [Sample task name] ********************************************************",
+ "Sample output Skipped Sample task name",
+ "",
+ "PLAY RECAP *********************************************************************",
+ "testhost : ok=0 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 "
+ ]
+
+ - name: Set runner_item_on_ok_msg callback using task variable
+ environment:
+ ANSIBLE_NOCOLOR: 'true'
+ ANSIBLE_FORCE_COLOR: 'false'
+ ANSIBLE_STDOUT_CALLBACK: community.general.diy
+ playbook: !unsafe |
+ - hosts: testhost
+ gather_facts: false
+ tasks:
+ - name: Sample task name
+ debug:
+ msg: sample debug msg {{ item }}
+ loop:
+ - sample item 1
+ - sample item 2
+ - sample item 3
+ vars:
+ ansible_callback_diy_runner_item_on_ok_msg: Sample output Looping {{ ansible_callback_diy.result.output.msg }}
+ expected_output: [
+ "",
+ "PLAY [testhost] ****************************************************************",
+ "",
+ "TASK [Sample task name] ********************************************************",
+ "Sample output Looping sample debug msg sample item 1",
+ "Sample output Looping sample debug msg sample item 2",
+ "Sample output Looping sample debug msg sample item 3",
+ "",
+ "PLAY RECAP *********************************************************************",
+ "testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
+ ]
+
+ - name: Set runner_item_on_failed_msg callback using task variable
+ environment:
+ ANSIBLE_NOCOLOR: 'true'
+ ANSIBLE_FORCE_COLOR: 'false'
+ ANSIBLE_STDOUT_CALLBACK: community.general.diy
+ playbook: !unsafe |
+ - hosts: testhost
+ gather_facts: false
+ tasks:
+ - name: Sample task name
+ debug:
+ msg: sample debug msg {{ item }}
+ loop:
+ - sample item 1
+ - sample item 2
+ - sample item 3
+ failed_when: item == 'sample item 2'
+ ignore_errors: true
+ vars:
+ ansible_callback_diy_runner_item_on_failed_msg: Sample output Looping sample failure message
+ expected_output: [
+ "",
+ "PLAY [testhost] ****************************************************************",
+ "",
+ "TASK [Sample task name] ********************************************************",
+ "ok: [testhost] => (item=sample item 1) => {",
+ " \"msg\": \"sample debug msg sample item 1\"",
+ "}",
+ "Sample output Looping sample failure message",
+ "ok: [testhost] => (item=sample item 3) => {",
+ " \"msg\": \"sample debug msg sample item 3\"",
+ "}",
+ [
+ # Apparently a bug was fixed in Ansible, as before it ran through with "All items completed"
+ "fatal: [testhost]: FAILED! => {\"msg\": \"All items completed\"}",
+ "fatal: [testhost]: FAILED! => {\"msg\": \"One or more items failed\"}",
+ ],
+ "...ignoring",
+ "",
+ "PLAY RECAP *********************************************************************",
+ "testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1 "
+ ]
+
+ - name: Set runner_item_on_skipped_msg callback using task variable
+ environment:
+ ANSIBLE_NOCOLOR: 'true'
+ ANSIBLE_FORCE_COLOR: 'false'
+ ANSIBLE_STDOUT_CALLBACK: community.general.diy
+ playbook: !unsafe |
+ - hosts: testhost
+ gather_facts: false
+ tasks:
+ - name: Sample task name
+ debug:
+ msg: sample debug msg {{ item }}
+ loop:
+ - sample item 1
+ - sample item 2
+ - sample item 3
+ when: item != 'sample item 2'
+ vars:
+ ansible_callback_diy_runner_item_on_skipped_msg: Sample output Looping Skipped {{ ansible_callback_diy.result.output.item }}
+ expected_output: [
+ "",
+ "PLAY [testhost] ****************************************************************",
+ "",
+ "TASK [Sample task name] ********************************************************",
+ "ok: [testhost] => (item=sample item 1) => {",
+ " \"msg\": \"sample debug msg sample item 1\"",
+ "}",
+ "Sample output Looping Skipped sample item 2",
+ "ok: [testhost] => (item=sample item 3) => {",
+ " \"msg\": \"sample debug msg sample item 3\"",
+ "}",
+ "",
+ "PLAY RECAP *********************************************************************",
+ "testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
+ ]
+
+ - name: Set playbook_on_stats_msg callback using play variable
+ environment:
+ ANSIBLE_NOCOLOR: 'true'
+ ANSIBLE_FORCE_COLOR: 'false'
+ ANSIBLE_STDOUT_CALLBACK: community.general.diy
+ playbook: !unsafe |
+ - hosts: testhost
+ gather_facts: false
+ vars:
+ ansible_callback_diy_playbook_on_stats_msg: |+2
+ Sample output stats
+ ===============================
+ {% for key in ansible_callback_diy.stats | sort %}
+ {% set color_one = "" %}
+ {% set color_two = "" %}
+ {% if ansible_callback_diy.stats[key] %}
+ {% if key == 'ok' %}
+ {% set prefix = ' ' %}
+ {% set suffix = ' ' %}
+ {% elif key == 'changed' %}
+ {% set prefix = ' ' %}
+ {% set suffix = ' ' %}
+ {% elif key == 'processed' %}
+ {% set prefix = ' ' %}
+ {% set suffix = ' ' %}
+ {% elif key == 'skipped' %}
+ {% set prefix = ' ' %}
+ {% set suffix = ' ' %}
+ {% else %}
+ {% set prefix = "" %}
+ {% set suffix = "" %}
+ {% endif %}
+ {{ color_one }}{{ "%s%s%s" | format(prefix,key,suffix) }}{{ color_two }}: {{ ansible_callback_diy.stats[key] | to_nice_yaml }}
+ {% endif %}
+ {% endfor %}
+ tasks:
+ - name: Sample task name
+ debug:
+ msg: sample debug msg
+ expected_output: [
+ "",
+ "PLAY [testhost] ****************************************************************",
+ "",
+ "TASK [Sample task name] ********************************************************",
+ "ok: [testhost] => {",
+ " \"msg\": \"sample debug msg\"",
+ "}",
+ " Sample output stats",
+ "===============================",
+ " ok : testhost: 1",
+ "",
+ " processed : testhost: 1"
+ ]
+
+ - name: Suppress output on playbook_on_task_start_msg callback using task variable
+ environment:
+ ANSIBLE_NOCOLOR: 'true'
+ ANSIBLE_FORCE_COLOR: 'false'
+ ANSIBLE_STDOUT_CALLBACK: community.general.diy
+ playbook: |
+ - hosts: testhost
+ gather_facts: false
+ tasks:
+ - name: Sample task name
+ debug:
+ msg: sample debug msg
+ vars:
+ ansible_callback_diy_playbook_on_task_start_msg: ''
+ expected_output: [
+ "",
+ "PLAY [testhost] ****************************************************************",
+ "ok: [testhost] => {",
+ " \"msg\": \"sample debug msg\"",
+ "}",
+ "",
+ "PLAY RECAP *********************************************************************",
+ "testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
+ ]
+
+ - name: Suppress output on runner_on_ok_msg callback using task variable
+ environment:
+ ANSIBLE_NOCOLOR: 'true'
+ ANSIBLE_FORCE_COLOR: 'false'
+ ANSIBLE_STDOUT_CALLBACK: community.general.diy
+ playbook: |
+ - hosts: testhost
+ gather_facts: false
+ tasks:
+ - name: Sample task name
+ debug:
+ msg: sample debug msg
+ vars:
+ ansible_callback_diy_runner_on_ok_msg: ''
+ expected_output: [
+ "",
+ "PLAY [testhost] ****************************************************************",
+ "",
+ "TASK [Sample task name] ********************************************************",
+ "",
+ "PLAY RECAP *********************************************************************",
+ "testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
+ ]
+
+ - name: Set runner_on_ok_msg_color using task variable
+ environment:
+ ANSIBLE_NOCOLOR: 'true'
+ ANSIBLE_FORCE_COLOR: 'false'
+ ANSIBLE_STDOUT_CALLBACK: community.general.diy
+ playbook: !unsafe |
+ - hosts: testhost
+ gather_facts: false
+ tasks:
+ - name: Sample task name
+ debug:
+ msg: sample debug msg
+ vars:
+ ansible_callback_diy_runner_on_ok_msg: Sample output {{ ansible_callback_diy.result.output.msg }}
+ ansible_callback_diy_runner_on_ok_msg_color: blue
+ expected_output: [
+ "",
+ "PLAY [testhost] ****************************************************************",
+ "",
+ "TASK [Sample task name] ********************************************************",
+ "Sample output sample debug msg",
+ "",
+ "PLAY RECAP *********************************************************************",
+ "testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
+ ]
diff --git a/ansible_collections/community/general/tests/integration/targets/callback_log_plays/aliases b/ansible_collections/community/general/tests/integration/targets/callback_log_plays/aliases
new file mode 100644
index 000000000..343f119da
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/callback_log_plays/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/3
diff --git a/ansible_collections/community/general/tests/integration/targets/callback_log_plays/ping_log.yml b/ansible_collections/community/general/tests/integration/targets/callback_log_plays/ping_log.yml
new file mode 100644
index 000000000..24f35f899
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/callback_log_plays/ping_log.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- hosts: localhost
+ gather_facts: false
+ tasks:
+ - ping:
diff --git a/ansible_collections/community/general/tests/integration/targets/callback_log_plays/runme.sh b/ansible_collections/community/general/tests/integration/targets/callback_log_plays/runme.sh
new file mode 100755
index 000000000..88eea1626
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/callback_log_plays/runme.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+set -eux
+
+# ANSIBLE_CALLBACK_WHITELIST has been deprecated in ansible-base 2.11, ANSIBLE_CALLBACKS_ENABLED should be used
+export ANSIBLE_CALLBACK_WHITELIST="community.general.log_plays,${ANSIBLE_CALLBACK_WHITELIST:-}"
+export ANSIBLE_CALLBACKS_ENABLED="community.general.log_plays,${ANSIBLE_CALLBACKS_ENABLED:-}"
+
+# run play, should create log and dir if needed
+export ANSIBLE_LOG_FOLDER="logit"
+ansible-playbook ping_log.yml -v "$@"
+[[ -f "${ANSIBLE_LOG_FOLDER}/localhost" ]]
+
+# now force it to fail
+export ANSIBLE_LOG_FOLDER="logit.file"
+touch "${ANSIBLE_LOG_FOLDER}"
+ansible-playbook ping_log.yml -v "$@" 2>&1| grep 'Failure using method (v2_runner_on_ok) in callback plugin'
+[[ ! -f "${ANSIBLE_LOG_FOLDER}/localhost" ]]
diff --git a/ansible_collections/community/general/tests/integration/targets/callback_yaml/aliases b/ansible_collections/community/general/tests/integration/targets/callback_yaml/aliases
new file mode 100644
index 000000000..a27cf0e26
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/callback_yaml/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+needs/target/callback
diff --git a/ansible_collections/community/general/tests/integration/targets/callback_yaml/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/callback_yaml/tasks/main.yml
new file mode 100644
index 000000000..f3c36663d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/callback_yaml/tasks/main.yml
@@ -0,0 +1,101 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Run tests
+ include_role:
+ name: callback
+ vars:
+ tests:
+ - name: Basic run
+ environment:
+ ANSIBLE_NOCOLOR: 'true'
+ ANSIBLE_FORCE_COLOR: 'false'
+ ANSIBLE_STDOUT_CALLBACK: community.general.yaml
+ playbook: |
+ - hosts: testhost
+ gather_facts: false
+ tasks:
+ - name: Sample task name
+ debug:
+ msg: sample debug msg
+ expected_output: [
+ "",
+ "PLAY [testhost] ****************************************************************",
+ "",
+ "TASK [Sample task name] ********************************************************",
+ "ok: [testhost] => ",
+ " msg: sample debug msg",
+ "",
+ "PLAY RECAP *********************************************************************",
+ "testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
+ ]
+ - name: Test umlauts in multiline
+ environment:
+ ANSIBLE_NOCOLOR: 'true'
+ ANSIBLE_FORCE_COLOR: 'false'
+ ANSIBLE_STDOUT_CALLBACK: community.general.yaml
+ playbook: |
+ - hosts: testhost
+ gather_facts: false
+ tasks:
+ - name: Umlaut output
+ debug:
+ msg: "äöü\néêè\nßï☺"
+ expected_output: [
+ "",
+ "PLAY [testhost] ****************************************************************",
+ "",
+ "TASK [Umlaut output] ***********************************************************",
+ "ok: [testhost] => ",
+ " msg: |-",
+ " äöü",
+ " éêè",
+ " ßï☺",
+ "",
+ "PLAY RECAP *********************************************************************",
+ "testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
+ ]
+ - name: Test to_yaml
+ environment:
+ ANSIBLE_NOCOLOR: 'true'
+ ANSIBLE_FORCE_COLOR: 'false'
+ ANSIBLE_STDOUT_CALLBACK: community.general.yaml
+ playbook: |
+ - hosts: testhost
+ gather_facts: false
+ vars:
+ data: |
+ line 1
+ line 2
+ line 3
+ tasks:
+ - name: Test to_yaml
+ debug:
+ msg: "{{ '{{' }}'{{ '{{' }}'{{ '}}' }} data | to_yaml {{ '{{' }}'{{ '}}' }}'{{ '}}' }}"
+ # The above should be: msg: "{{ data | to_yaml }}"
+ # Unfortunately, the way Ansible handles templating, we need to do some funny 'escaping' tricks...
+ expected_output: [
+ "",
+ "PLAY [testhost] ****************************************************************",
+ "",
+ "TASK [Test to_yaml] ************************************************************",
+ "ok: [testhost] => ",
+ " msg: |-",
+ " 'line 1",
+ " ",
+ " line 2",
+ " ",
+ " line 3",
+ " ",
+ " '",
+ "",
+ "PLAY RECAP *********************************************************************",
+ "testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
+ ]
diff --git a/ansible_collections/community/general/tests/integration/targets/cargo/aliases b/ansible_collections/community/general/tests/integration/targets/cargo/aliases
new file mode 100644
index 000000000..9c7febe24
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/cargo/aliases
@@ -0,0 +1,7 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+destructive
+skip/aix
diff --git a/ansible_collections/community/general/tests/integration/targets/cargo/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/cargo/meta/main.yml
new file mode 100644
index 000000000..2fcd152f9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/cargo/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
diff --git a/ansible_collections/community/general/tests/integration/targets/cargo/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/cargo/tasks/main.yml
new file mode 100644
index 000000000..bb22e27c0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/cargo/tasks/main.yml
@@ -0,0 +1,20 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- import_tasks: setup.yml
+- name: Set default environment
+ set_fact:
+ cargo_environment: {}
+- name: Set special environment to work around cargo bugs
+ set_fact:
+ cargo_environment:
+ # See https://github.com/rust-lang/cargo/issues/10230#issuecomment-1201662729:
+ CARGO_NET_GIT_FETCH_WITH_CLI: "true"
+ when: has_cargo | default(false) and ansible_distribution == 'Alpine'
+- block:
+ - import_tasks: test_general.yml
+ - import_tasks: test_version.yml
+ environment: "{{ cargo_environment }}"
+ when: has_cargo | default(false)
diff --git a/ansible_collections/community/general/tests/integration/targets/cargo/tasks/setup.yml b/ansible_collections/community/general/tests/integration/targets/cargo/tasks/setup.yml
new file mode 100644
index 000000000..232658ab4
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/cargo/tasks/setup.yml
@@ -0,0 +1,28 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- block:
+ - name: Install cargo
+ package:
+ name: cargo
+ state: present
+ - set_fact:
+ has_cargo: true
+ when:
+ - ansible_system != 'FreeBSD'
+ - ansible_distribution != 'MacOSX'
+ - ansible_distribution != 'RedHat' or ansible_distribution_version is version('8.0', '>=')
+ - ansible_distribution != 'CentOS' or ansible_distribution_version is version('7.0', '>=')
+ - ansible_distribution != 'Ubuntu' or ansible_distribution_version is version('18', '>=')
+
+- block:
+ - name: Install rust (containing cargo)
+ package:
+ name: rust
+ state: present
+ - set_fact:
+ has_cargo: true
+ when:
+ - ansible_system == 'FreeBSD' and ansible_distribution_version is version('13.0', '>')
diff --git a/ansible_collections/community/general/tests/integration/targets/cargo/tasks/test_general.yml b/ansible_collections/community/general/tests/integration/targets/cargo/tasks/test_general.yml
new file mode 100644
index 000000000..2bffa08f0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/cargo/tasks/test_general.yml
@@ -0,0 +1,35 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Ensure application helloworld is uninstalled
+ community.general.cargo:
+ state: absent
+ name: helloworld
+ register: uninstall_absent_helloworld
+
+- name: Install application helloworld
+ community.general.cargo:
+ name: helloworld
+ register: install_absent_helloworld
+
+- name: Install application helloworld again
+ community.general.cargo:
+ name: helloworld
+ register: install_present_helloworld
+ ignore_errors: true
+
+- name: Uninstall application helloworld
+ community.general.cargo:
+ state: absent
+ name: helloworld
+ register: uninstall_present_helloworld
+
+- name: Check assertions helloworld
+ assert:
+ that:
+ - uninstall_absent_helloworld is not changed
+ - install_absent_helloworld is changed
+ - install_present_helloworld is not changed
+ - uninstall_present_helloworld is changed
diff --git a/ansible_collections/community/general/tests/integration/targets/cargo/tasks/test_version.yml b/ansible_collections/community/general/tests/integration/targets/cargo/tasks/test_version.yml
new file mode 100644
index 000000000..c1ab8e198
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/cargo/tasks/test_version.yml
@@ -0,0 +1,50 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install application helloworld-yliu 0.1.0
+ community.general.cargo:
+ name: helloworld-yliu
+ version: 0.1.0
+ register: install_helloworld_010
+
+- name: Install application helloworld-yliu 0.1.0 (idempotent)
+ community.general.cargo:
+ name: helloworld-yliu
+ version: 0.1.0
+ register: install_helloworld_010_idem
+
+- name: Upgrade helloworld-yliu 0.1.0
+ community.general.cargo:
+ name: helloworld-yliu
+ state: latest
+ register: upgrade_helloworld_010
+
+- name: Upgrade helloworld-yliu 0.1.0 (idempotent)
+ community.general.cargo:
+ name: helloworld-yliu
+ state: latest
+ register: upgrade_helloworld_010_idem
+
+- name: Downgrade helloworld-yliu 0.1.0
+ community.general.cargo:
+ name: helloworld-yliu
+ version: 0.1.0
+ register: downgrade_helloworld_010
+
+- name: Downgrade helloworld-yliu 0.1.0 (idempotent)
+ community.general.cargo:
+ name: helloworld-yliu
+ version: 0.1.0
+ register: downgrade_helloworld_010_idem
+
+- name: Check assertions helloworld-yliu
+ assert:
+ that:
+ - install_helloworld_010 is changed
+ - install_helloworld_010_idem is not changed
+ - upgrade_helloworld_010 is changed
+ - upgrade_helloworld_010_idem is not changed
+ - downgrade_helloworld_010 is changed
+ - downgrade_helloworld_010_idem is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/cloud_init_data_facts/aliases b/ansible_collections/community/general/tests/integration/targets/cloud_init_data_facts/aliases
new file mode 100644
index 000000000..bec4d21af
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/cloud_init_data_facts/aliases
@@ -0,0 +1,10 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+destructive
+skip/aix
+skip/osx
+skip/macos
+skip/freebsd
diff --git a/ansible_collections/community/general/tests/integration/targets/cloud_init_data_facts/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/cloud_init_data_facts/meta/main.yml
new file mode 100644
index 000000000..2fcd152f9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/cloud_init_data_facts/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
diff --git a/ansible_collections/community/general/tests/integration/targets/cloud_init_data_facts/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/cloud_init_data_facts/tasks/main.yml
new file mode 100644
index 000000000..40e762d68
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/cloud_init_data_facts/tasks/main.yml
@@ -0,0 +1,68 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: test cloud-init
+ # TODO: check for a workaround
+ # install 'cloud-init'' failed: dpkg-divert: error: `diversion of /etc/init/ureadahead.conf
+ # to /etc/init/ureadahead.conf.disabled by cloud-init' clashes with `local diversion of
+ # /etc/init/ureadahead.conf to /etc/init/ureadahead.conf.distrib
+ # https://bugs.launchpad.net/ubuntu/+source/ureadahead/+bug/997838
+ # Will also have to skip on OpenSUSE when running on Python 2 on newer Leap versions
+ # (!= 42 and >= 15) ascloud-init will install the Python 3 package, breaking our build on py2.
+ when:
+ - not (ansible_distribution == "Ubuntu" and ansible_distribution_major_version|int == 14)
+ - not (ansible_os_family == "Suse" and ansible_distribution_major_version|int != 42 and ansible_python.version.major != 3)
+ - not (ansible_distribution == "CentOS" and ansible_distribution_major_version|int == 8) # TODO: cannot start service
+ - not (ansible_distribution == 'Archlinux') # TODO: package seems to be broken, cannot be downloaded from mirrors?
+ - not (ansible_distribution == 'Alpine') # TODO: not sure what's wrong here, the module doesn't return what the tests expect
+ block:
+ - name: setup install cloud-init
+ package:
+ name:
+ - cloud-init
+ - udev
+
+ - name: Ensure systemd-network user exists
+ user:
+ name: systemd-network
+ state: present
+ when: ansible_distribution == 'Fedora' and ansible_distribution_major_version|int >= 37
+
+ - name: setup run cloud-init
+ service:
+ name: cloud-init-local
+ state: restarted
+
+ - name: test gather cloud-init facts in check mode
+ cloud_init_data_facts:
+ check_mode: true
+ register: result
+ - name: verify test gather cloud-init facts in check mode
+ assert:
+ that:
+ - result.cloud_init_data_facts.status.v1 is defined
+ - result.cloud_init_data_facts.status.v1.stage is defined
+ - not result.cloud_init_data_facts.status.v1.stage
+ - cloud_init_data_facts.status.v1 is defined
+ - cloud_init_data_facts.status.v1.stage is defined
+ - not cloud_init_data_facts.status.v1.stage
+
+ - name: test gather cloud-init facts
+ cloud_init_data_facts:
+ register: result
+ - name: verify test gather cloud-init facts
+ assert:
+ that:
+ - result.cloud_init_data_facts.status.v1 is defined
+ - result.cloud_init_data_facts.status.v1.stage is defined
+ - not result.cloud_init_data_facts.status.v1.stage
+ - cloud_init_data_facts.status.v1 is defined
+ - cloud_init_data_facts.status.v1.stage is defined
+ - not cloud_init_data_facts.status.v1.stage
diff --git a/ansible_collections/community/general/tests/integration/targets/cmd_runner/aliases b/ansible_collections/community/general/tests/integration/targets/cmd_runner/aliases
new file mode 100644
index 000000000..12d1d6617
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/cmd_runner/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
diff --git a/ansible_collections/community/general/tests/integration/targets/cmd_runner/library/cmd_echo.py b/ansible_collections/community/general/tests/integration/targets/cmd_runner/library/cmd_echo.py
new file mode 100644
index 000000000..cd8766264
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/cmd_runner/library/cmd_echo.py
@@ -0,0 +1,55 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright (c) 2022, Alexei Znamensky <russoz@gmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+DOCUMENTATION = ""
+
+EXAMPLES = ""
+
+RETURN = ""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible_collections.community.general.plugins.module_utils.cmd_runner import CmdRunner, cmd_runner_fmt as fmt
+
+
+def main():
+ module = AnsibleModule(
+ argument_spec=dict(
+ arg_formats=dict(type="dict", default={}),
+ arg_order=dict(type="raw", required=True),
+ arg_values=dict(type="dict", default={}),
+ check_mode_skip=dict(type="bool", default=False),
+ aa=dict(type="raw"),
+ ),
+ supports_check_mode=True,
+ )
+ p = module.params
+
+ info = None
+
+ arg_formats = {}
+ for arg, fmt_spec in p['arg_formats'].items():
+ func = getattr(fmt, fmt_spec['func'])
+ args = fmt_spec.get("args", [])
+
+ arg_formats[arg] = func(*args)
+
+ runner = CmdRunner(module, ['echo', '--'], arg_formats=arg_formats)
+
+ with runner.context(p['arg_order'], check_mode_skip=p['check_mode_skip']) as ctx:
+ result = ctx.run(**p['arg_values'])
+ info = ctx.run_info
+ check = "check"
+ rc, out, err = result if result is not None else (None, None, None)
+
+ module.exit_json(rc=rc, out=out, err=err, info=info)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/general/tests/integration/targets/cmd_runner/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/cmd_runner/tasks/main.yml
new file mode 100644
index 000000000..36ab039f0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/cmd_runner/tasks/main.yml
@@ -0,0 +1,8 @@
+# Copyright (c) 2022, Alexei Znamensky
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: parameterized test cmd_echo
+ ansible.builtin.include_tasks:
+ file: test_cmd_echo.yml
+ loop: "{{ cmd_echo_tests }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/cmd_runner/tasks/test_cmd_echo.yml b/ansible_collections/community/general/tests/integration/targets/cmd_runner/tasks/test_cmd_echo.yml
new file mode 100644
index 000000000..1c2caf2b5
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/cmd_runner/tasks/test_cmd_echo.yml
@@ -0,0 +1,19 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: test cmd_echo [{{ item.name }}]
+ cmd_echo:
+ arg_formats: "{{ item.arg_formats|default(omit) }}"
+ arg_order: "{{ item.arg_order }}"
+ arg_values: "{{ item.arg_values|default(omit) }}"
+ check_mode_skip: "{{ item.check_mode_skip|default(omit) }}"
+ aa: "{{ item.aa|default(omit) }}"
+ register: test_result
+ check_mode: "{{ item.check_mode|default(omit) }}"
+ ignore_errors: "{{ item.expect_error|default(omit) }}"
+
+- name: check results [{{ item.name }}]
+ assert:
+ that: "{{ item.assertions }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/cmd_runner/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/cmd_runner/vars/main.yml
new file mode 100644
index 000000000..7f0027d49
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/cmd_runner/vars/main.yml
@@ -0,0 +1,123 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2022, Alexei Znamensky
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cmd_echo_tests:
+ - name: set aa and bb value
+ arg_formats:
+ aa:
+ func: as_opt_eq_val
+ args: [--answer]
+ bb:
+ func: as_bool
+ args: [--bb-here]
+ arg_order: 'aa bb'
+ arg_values:
+ bb: true
+ aa: 11
+ assertions:
+ - test_result.rc == 0
+ - test_result.out == "-- --answer=11 --bb-here\n"
+ - test_result.err == ""
+
+ - name: default aa value
+ arg_formats:
+ aa:
+ func: as_opt_eq_val
+ args: [--answer]
+ bb:
+ func: as_bool
+ args: [--bb-here]
+ arg_order: ['aa', 'bb']
+ arg_values:
+ aa: 43
+ bb: true
+ assertions:
+ - test_result.rc == 0
+ - test_result.out == "-- --answer=43 --bb-here\n"
+ - test_result.err == ""
+
+ - name: implicit aa format
+ arg_formats:
+ bb:
+ func: as_bool
+ args: [--bb-here]
+ arg_order: ['aa', 'bb']
+ arg_values:
+ bb: true
+ aa: 1984
+ assertions:
+ - test_result.rc == 0
+ - test_result.out == "-- --aa 1984 --bb-here\n"
+ - test_result.err == ""
+
+ - name: missing bb format
+ arg_order: ['aa', 'bb']
+ arg_values:
+ bb: true
+ aa: 1984
+ expect_error: true
+ assertions:
+ - test_result is failed
+ - test_result.rc == 1
+ - '"out" not in test_result'
+ - '"err" not in test_result'
+ - >-
+ "MissingArgumentFormat: Cannot find format for parameter bb"
+ in test_result.module_stderr
+
+ - name: missing bb value
+ arg_formats:
+ bb:
+ func: as_bool
+ args: [--bb-here]
+ arg_order: 'aa bb'
+ aa: 1984
+ expect_error: true
+ assertions:
+ - test_result is failed
+ - test_result.rc == 1
+ - '"out" not in test_result'
+ - '"err" not in test_result'
+ - >-
+ "MissingArgumentValue: Cannot find value for parameter bb"
+ in test_result.module_stderr
+
+ - name: set aa and bb value with check_mode on
+ arg_formats:
+ aa:
+ func: as_opt_eq_val
+ args: [--answer]
+ bb:
+ func: as_bool
+ args: [--bb-here]
+ arg_order: 'aa bb'
+ arg_values:
+ bb: true
+ aa: 11
+ check_mode: true
+ assertions:
+ - test_result.rc == 0
+ - test_result.out == "-- --answer=11 --bb-here\n"
+ - test_result.err == ""
+
+ - name: set aa and bb value with check_mode and check_mode_skip on
+ arg_formats:
+ aa:
+ func: as_opt_eq_val
+ args: [--answer]
+ bb:
+ func: as_bool
+ args: [--bb-here]
+ arg_order: 'aa bb'
+ arg_values:
+ bb: true
+ check_mode_skip: true
+ aa: 11
+ check_mode: true
+ expect_error: true # because if result contains rc != 0, ansible assumes error
+ assertions:
+ - test_result.rc == None
+ - test_result.out == None
+ - test_result.err == None
diff --git a/ansible_collections/community/general/tests/integration/targets/connection/aliases b/ansible_collections/community/general/tests/integration/targets/connection/aliases
new file mode 100644
index 000000000..a02a2d61a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/connection/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+hidden
diff --git a/ansible_collections/community/general/tests/integration/targets/connection/test.sh b/ansible_collections/community/general/tests/integration/targets/connection/test.sh
new file mode 100755
index 000000000..793a85dd3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/connection/test.sh
@@ -0,0 +1,16 @@
+#!/usr/bin/env bash
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+set -eux
+
+[ -f "${INVENTORY}" ]
+
+# Run connection tests with both the default and C locale.
+
+ansible-playbook test_connection.yml -i "${INVENTORY}" "$@"
+
+if ansible --version | grep ansible | grep -E ' 2\.(9|10|11|12|13)\.'; then
+ LC_ALL=C LANG=C ansible-playbook test_connection.yml -i "${INVENTORY}" "$@"
+fi
diff --git a/ansible_collections/community/general/tests/integration/targets/connection/test_connection.yml b/ansible_collections/community/general/tests/integration/targets/connection/test_connection.yml
new file mode 100644
index 000000000..bb0a99399
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/connection/test_connection.yml
@@ -0,0 +1,48 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- hosts: "{{ target_hosts }}"
+ gather_facts: false
+ serial: 1
+ tasks:
+
+ ### raw with unicode arg and output
+
+ - name: raw with unicode arg and output
+ raw: echo 汉语
+ register: command
+ - name: check output of raw with unicode arg and output
+ assert:
+ that:
+ - "'汉语' in command.stdout"
+ - command is changed # as of 2.2, raw should default to changed: true for consistency w/ shell/command/script modules
+
+ ### copy local file with unicode filename and content
+
+ - name: create local file with unicode filename and content
+ local_action: lineinfile dest={{ local_tmp }}-汉语/汉语.txt create=true line=汉语
+ - name: remove remote file with unicode filename and content
+ action: "{{ action_prefix }}file path={{ remote_tmp }}-汉语/汉语.txt state=absent"
+ - name: create remote directory with unicode name
+ action: "{{ action_prefix }}file path={{ remote_tmp }}-汉语 state=directory"
+ - name: copy local file with unicode filename and content
+ action: "{{ action_prefix }}copy src={{ local_tmp }}-汉语/汉语.txt dest={{ remote_tmp }}-汉语/汉语.txt"
+
+ ### fetch remote file with unicode filename and content
+
+ - name: remove local file with unicode filename and content
+ local_action: file path={{ local_tmp }}-汉语/汉语.txt state=absent
+ - name: fetch remote file with unicode filename and content
+ fetch: src={{ remote_tmp }}-汉语/汉语.txt dest={{ local_tmp }}-汉语/汉语.txt fail_on_missing=true validate_checksum=true flat=true
+
+ ### remove local and remote temp files
+
+ - name: remove local temp file
+ local_action: file path={{ local_tmp }}-汉语 state=absent
+ - name: remove remote temp file
+ action: "{{ action_prefix }}file path={{ remote_tmp }}-汉语 state=absent"
+
+ ### test wait_for_connection plugin
+ - ansible.builtin.wait_for_connection:
diff --git a/ansible_collections/community/general/tests/integration/targets/connection_chroot/aliases b/ansible_collections/community/general/tests/integration/targets/connection_chroot/aliases
new file mode 100644
index 000000000..38138ee4d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/connection_chroot/aliases
@@ -0,0 +1,7 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/3
+needs/root
+skip/macos # Skipped due to limitation of macOS 10.15 SIP, please read https://github.com/ansible-collections/community.general/issues/1017#issuecomment-755088895
diff --git a/ansible_collections/community/general/tests/integration/targets/connection_chroot/runme.sh b/ansible_collections/community/general/tests/integration/targets/connection_chroot/runme.sh
new file mode 100755
index 000000000..9f31da64d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/connection_chroot/runme.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+set -eux
+
+# Connection tests for POSIX platforms use this script by linking to it from the appropriate 'connection_' target dir.
+# The name of the inventory group to test is extracted from the directory name following the 'connection_' prefix.
+
+group=$(python -c \
+ "from os import path; print(path.basename(path.abspath(path.dirname('$0'))).replace('connection_', ''))")
+
+cd ../connection
+
+INVENTORY="../connection_${group}/test_connection.inventory" ./test.sh \
+ -e target_hosts="${group}" \
+ -e action_prefix= \
+ -e local_tmp=/tmp/ansible-local \
+ -e remote_tmp=/tmp/ansible-remote \
+ "$@"
diff --git a/ansible_collections/community/general/tests/integration/targets/connection_chroot/test_connection.inventory b/ansible_collections/community/general/tests/integration/targets/connection_chroot/test_connection.inventory
new file mode 100644
index 000000000..126b29c8a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/connection_chroot/test_connection.inventory
@@ -0,0 +1,11 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+[chroot]
+chroot-pipelining ansible_ssh_pipelining=true
+chroot-no-pipelining ansible_ssh_pipelining=false
+[chroot:vars]
+ansible_host=/
+ansible_connection=community.general.chroot
+ansible_python_interpreter="{{ ansible_playbook_python }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/connection_jail/aliases b/ansible_collections/community/general/tests/integration/targets/connection_jail/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/connection_jail/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/connection_jail/runme.sh b/ansible_collections/community/general/tests/integration/targets/connection_jail/runme.sh
new file mode 100755
index 000000000..9f31da64d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/connection_jail/runme.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+set -eux
+
+# Connection tests for POSIX platforms use this script by linking to it from the appropriate 'connection_' target dir.
+# The name of the inventory group to test is extracted from the directory name following the 'connection_' prefix.
+
+group=$(python -c \
+ "from os import path; print(path.basename(path.abspath(path.dirname('$0'))).replace('connection_', ''))")
+
+cd ../connection
+
+INVENTORY="../connection_${group}/test_connection.inventory" ./test.sh \
+ -e target_hosts="${group}" \
+ -e action_prefix= \
+ -e local_tmp=/tmp/ansible-local \
+ -e remote_tmp=/tmp/ansible-remote \
+ "$@"
diff --git a/ansible_collections/community/general/tests/integration/targets/connection_jail/test_connection.inventory b/ansible_collections/community/general/tests/integration/targets/connection_jail/test_connection.inventory
new file mode 100644
index 000000000..995c32444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/connection_jail/test_connection.inventory
@@ -0,0 +1,11 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+[jail]
+jail-pipelining ansible_ssh_pipelining=true
+jail-no-pipelining ansible_ssh_pipelining=false
+[jail:vars]
+ansible_host=freebsd_10_2
+ansible_connection=community.general.jail
+ansible_python_interpreter=/usr/local/bin/python
diff --git a/ansible_collections/community/general/tests/integration/targets/connection_lxc/aliases b/ansible_collections/community/general/tests/integration/targets/connection_lxc/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/connection_lxc/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/connection_lxc/runme.sh b/ansible_collections/community/general/tests/integration/targets/connection_lxc/runme.sh
new file mode 100755
index 000000000..9f31da64d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/connection_lxc/runme.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+set -eux
+
+# Connection tests for POSIX platforms use this script by linking to it from the appropriate 'connection_' target dir.
+# The name of the inventory group to test is extracted from the directory name following the 'connection_' prefix.
+
+group=$(python -c \
+ "from os import path; print(path.basename(path.abspath(path.dirname('$0'))).replace('connection_', ''))")
+
+cd ../connection
+
+INVENTORY="../connection_${group}/test_connection.inventory" ./test.sh \
+ -e target_hosts="${group}" \
+ -e action_prefix= \
+ -e local_tmp=/tmp/ansible-local \
+ -e remote_tmp=/tmp/ansible-remote \
+ "$@"
diff --git a/ansible_collections/community/general/tests/integration/targets/connection_lxc/test_connection.inventory b/ansible_collections/community/general/tests/integration/targets/connection_lxc/test_connection.inventory
new file mode 100644
index 000000000..cfcd7a32f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/connection_lxc/test_connection.inventory
@@ -0,0 +1,21 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+[lxc]
+lxc-pipelining ansible_ssh_pipelining=true
+lxc-no-pipelining ansible_ssh_pipelining=false
+[lxc:vars]
+# 1. install lxc
+# 2. install python2-lxc
+# $ pip install git+https://github.com/lxc/python2-lxc.git
+# 3. create container:
+# $ sudo lxc-create -t download -n centos-7-amd64 -- -d centos -r 7 -a amd64
+# 4. start container:
+# $ sudo lxc-start -n centos-7-amd64 -d
+# 5. run test:
+# $ sudo -E make test_connection_lxc
+# 6. stop container
+# $ sudo lxc-stop -n centos-7-amd64
+ansible_host=centos-7-amd64
+ansible_connection=community.general.lxc
diff --git a/ansible_collections/community/general/tests/integration/targets/connection_lxd/aliases b/ansible_collections/community/general/tests/integration/targets/connection_lxd/aliases
new file mode 100644
index 000000000..5a0c47032
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/connection_lxd/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+non_local
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/connection_lxd/runme.sh b/ansible_collections/community/general/tests/integration/targets/connection_lxd/runme.sh
new file mode 100755
index 000000000..9f31da64d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/connection_lxd/runme.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+set -eux
+
+# Connection tests for POSIX platforms use this script by linking to it from the appropriate 'connection_' target dir.
+# The name of the inventory group to test is extracted from the directory name following the 'connection_' prefix.
+
+group=$(python -c \
+ "from os import path; print(path.basename(path.abspath(path.dirname('$0'))).replace('connection_', ''))")
+
+cd ../connection
+
+INVENTORY="../connection_${group}/test_connection.inventory" ./test.sh \
+ -e target_hosts="${group}" \
+ -e action_prefix= \
+ -e local_tmp=/tmp/ansible-local \
+ -e remote_tmp=/tmp/ansible-remote \
+ "$@"
diff --git a/ansible_collections/community/general/tests/integration/targets/connection_lxd/test_connection.inventory b/ansible_collections/community/general/tests/integration/targets/connection_lxd/test_connection.inventory
new file mode 100644
index 000000000..d2d2c10e3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/connection_lxd/test_connection.inventory
@@ -0,0 +1,10 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+[lxd]
+lxd-pipelining ansible_ssh_pipelining=true
+lxd-no-pipelining ansible_ssh_pipelining=false
+[lxd:vars]
+ansible_host=centos-7-amd64
+ansible_connection=community.general.lxd
diff --git a/ansible_collections/community/general/tests/integration/targets/connection_posix/aliases b/ansible_collections/community/general/tests/integration/targets/connection_posix/aliases
new file mode 100644
index 000000000..44561e2ff
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/connection_posix/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+needs/target/connection
+hidden
diff --git a/ansible_collections/community/general/tests/integration/targets/connection_posix/test.sh b/ansible_collections/community/general/tests/integration/targets/connection_posix/test.sh
new file mode 100755
index 000000000..9f31da64d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/connection_posix/test.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+set -eux
+
+# Connection tests for POSIX platforms use this script by linking to it from the appropriate 'connection_' target dir.
+# The name of the inventory group to test is extracted from the directory name following the 'connection_' prefix.
+
+group=$(python -c \
+ "from os import path; print(path.basename(path.abspath(path.dirname('$0'))).replace('connection_', ''))")
+
+cd ../connection
+
+INVENTORY="../connection_${group}/test_connection.inventory" ./test.sh \
+ -e target_hosts="${group}" \
+ -e action_prefix= \
+ -e local_tmp=/tmp/ansible-local \
+ -e remote_tmp=/tmp/ansible-remote \
+ "$@"
diff --git a/ansible_collections/community/general/tests/integration/targets/consul/aliases b/ansible_collections/community/general/tests/integration/targets/consul/aliases
new file mode 100644
index 000000000..d9cf1eb9c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/consul/aliases
@@ -0,0 +1,8 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+destructive
+skip/aix
+skip/macos # cannot simply create binaries in system locations on newer macOS versions
diff --git a/ansible_collections/community/general/tests/integration/targets/consul/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/consul/meta/main.yml
new file mode 100644
index 000000000..0909be206
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/consul/meta/main.yml
@@ -0,0 +1,10 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
+ - setup_openssl
+ - setup_remote_tmp_dir
+ - setup_remote_constraints
diff --git a/ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_session.yml b/ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_session.yml
new file mode 100644
index 000000000..543668964
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/consul/tasks/consul_session.yml
@@ -0,0 +1,177 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: list sessions
+ consul_session:
+ state: list
+ register: result
+
+- assert:
+ that:
+ - result is changed
+ - "'sessions' in result"
+
+- name: create a session
+ consul_session:
+ state: present
+ name: testsession
+ register: result
+
+- assert:
+ that:
+ - result is changed
+ - result['name'] == 'testsession'
+ - "'session_id' in result"
+
+- set_fact:
+ session_id: "{{ result['session_id'] }}"
+
+- name: list sessions after creation
+ consul_session:
+ state: list
+ register: result
+
+- set_fact:
+ session_count: "{{ result['sessions'] | length }}"
+
+- assert:
+ that:
+ - result is changed
+ # selectattr not available on Jinja 2.2 provided by CentOS 6
+ # hence the two following tasks (set_fact/assert) are used
+ # - (result['sessions'] | selectattr('ID', 'match', '^' ~ session_id ~ '$') | first)['Name'] == 'testsession'
+
+- name: search created session
+ set_fact:
+ test_session_found: true
+ loop: "{{ result['sessions'] }}"
+ when: "item.get('ID') == session_id and item.get('Name') == 'testsession'"
+
+- name: ensure session was created
+ assert:
+ that:
+ - test_session_found|default(False)
+
+- name: fetch info about a session
+ consul_session:
+ state: info
+ id: '{{ session_id }}'
+ register: result
+
+- assert:
+ that:
+ - result is changed
+
+- name: ensure 'id' parameter is required when state=info
+ consul_session:
+ state: info
+ name: test
+ register: result
+ ignore_errors: true
+
+- assert:
+ that:
+ - result is failed
+
+- name: ensure unknown scheme fails
+ consul_session:
+ state: info
+ id: '{{ session_id }}'
+ scheme: non_existent
+ register: result
+ ignore_errors: true
+
+- assert:
+ that:
+ - result is failed
+
+- name: ensure SSL certificate is checked
+ consul_session:
+ state: info
+ id: '{{ session_id }}'
+ port: 8501
+ scheme: https
+ register: result
+ ignore_errors: true
+
+- name: previous task should fail since certificate is not known
+ assert:
+ that:
+ - result is failed
+ - "'certificate verify failed' in result.msg"
+
+- name: ensure SSL certificate isn't checked when validate_certs is disabled
+ consul_session:
+ state: info
+ id: '{{ session_id }}'
+ port: 8501
+ scheme: https
+ validate_certs: false
+ register: result
+
+- name: previous task should succeed since certificate isn't checked
+ assert:
+ that:
+ - result is changed
+
+- name: ensure a secure connection is possible
+ consul_session:
+ state: info
+ id: '{{ session_id }}'
+ port: 8501
+ scheme: https
+ environment:
+ REQUESTS_CA_BUNDLE: '{{ remote_dir }}/cert.pem'
+ register: result
+
+- assert:
+ that:
+ - result is changed
+
+- name: delete a session
+ consul_session:
+ state: absent
+ id: '{{ session_id }}'
+ register: result
+
+- assert:
+ that:
+ - result is changed
+
+- name: list sessions after deletion
+ consul_session:
+ state: list
+ register: result
+
+- assert:
+ that:
+ - result is changed
+ # selectattr and equalto not available on Jinja 2.2 provided by CentOS 6
+ # hence the two following tasks (command/assert) are used
+ # - (result['sessions'] | selectattr('ID', 'equalto', session_id) | list | length) == 0
+
+- name: search deleted session
+ command: echo 'session found'
+ loop: "{{ result['sessions'] }}"
+ when: "item.get('ID') == session_id and item.get('Name') == 'testsession'"
+ register: search_deleted
+
+- name: ensure session was deleted
+ assert:
+ that:
+ - search_deleted is skipped # each iteration is skipped
+ - search_deleted is not changed # and then unchanged
+
+- name: ensure session can be created with a ttl
+ consul_session:
+ state: present
+ name: session-with-ttl
+ ttl: 180 # sec
+ register: result
+
+- assert:
+ that:
+ - result is changed
+ - result['ttl'] == 180
diff --git a/ansible_collections/community/general/tests/integration/targets/consul/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/consul/tasks/main.yml
new file mode 100644
index 000000000..a2b63ac95
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/consul/tasks/main.yml
@@ -0,0 +1,89 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install Consul and test
+ vars:
+ consul_version: 1.5.0
+ consul_uri: https://s3.amazonaws.com/ansible-ci-files/test/integration/targets/consul/consul_{{ consul_version }}_{{ ansible_system | lower }}_{{ consul_arch }}.zip
+ consul_cmd: '{{ remote_tmp_dir }}/consul'
+ block:
+ - name: Install requests<2.20 (CentOS/RHEL 6)
+ pip:
+ name: requests<2.20
+ extra_args: "-c {{ remote_constraints }}"
+ register: result
+ until: result is success
+ when: ansible_distribution_file_variety|default() == 'RedHat' and ansible_distribution_major_version is version('6', '<=')
+ - name: Install python-consul
+ pip:
+ name: python-consul
+ extra_args: "-c {{ remote_constraints }}"
+ register: result
+ until: result is success
+ - name: Generate privatekey
+ community.crypto.openssl_privatekey:
+ path: '{{ remote_tmp_dir }}/privatekey.pem'
+ - name: Generate CSR
+ community.crypto.openssl_csr:
+ path: '{{ remote_tmp_dir }}/csr.csr'
+ privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
+ subject:
+ commonName: localhost
+ - name: Generate selfsigned certificate
+ register: selfsigned_certificate
+ community.crypto.x509_certificate:
+ path: '{{ remote_tmp_dir }}/cert.pem'
+ csr_path: '{{ remote_tmp_dir }}/csr.csr'
+ privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
+ provider: selfsigned
+ selfsigned_digest: sha256
+ - name: Install unzip
+ package:
+ name: unzip
+ register: result
+ until: result is success
+ when: ansible_distribution != "MacOSX"
+ - assert:
+ that: ansible_architecture in ['i386', 'x86_64', 'amd64']
+ - set_fact:
+ consul_arch: '386'
+ when: ansible_architecture == 'i386'
+ - set_fact:
+ consul_arch: amd64
+ when: ansible_architecture in ['x86_64', 'amd64']
+ - name: Download consul binary
+ unarchive:
+ src: '{{ consul_uri }}'
+ dest: '{{ remote_tmp_dir }}'
+ remote_src: true
+ register: result
+ until: result is success
+ - vars:
+ remote_dir: '{{ echo_remote_tmp_dir.stdout }}'
+ block:
+ - command: echo {{ remote_tmp_dir }}
+ register: echo_remote_tmp_dir
+ - name: Create configuration file
+ template:
+ src: consul_config.hcl.j2
+ dest: '{{ remote_tmp_dir }}/consul_config.hcl'
+ - name: Start Consul (dev mode enabled)
+ shell: nohup {{ consul_cmd }} agent -dev -config-file {{ remote_tmp_dir }}/consul_config.hcl </dev/null >/dev/null 2>&1 &
+ - name: Create some data
+ command: '{{ consul_cmd }} kv put data/value{{ item }} foo{{ item }}'
+ loop:
+ - 1
+ - 2
+ - 3
+ - import_tasks: consul_session.yml
+ always:
+ - name: Kill consul process
+ shell: kill $(cat {{ remote_tmp_dir }}/consul.pid)
+ ignore_errors: true
diff --git a/ansible_collections/community/general/tests/integration/targets/consul/templates/consul_config.hcl.j2 b/ansible_collections/community/general/tests/integration/targets/consul/templates/consul_config.hcl.j2
new file mode 100644
index 000000000..96da5d664
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/consul/templates/consul_config.hcl.j2
@@ -0,0 +1,14 @@
+{#
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+#}
+# {{ ansible_managed }}
+server = true
+pid_file = "{{ remote_dir }}/consul.pid"
+ports {
+ http = 8500
+ https = 8501
+}
+key_file = "{{ remote_dir }}/privatekey.pem"
+cert_file = "{{ remote_dir }}/cert.pem"
diff --git a/ansible_collections/community/general/tests/integration/targets/copr/aliases b/ansible_collections/community/general/tests/integration/targets/copr/aliases
new file mode 100644
index 000000000..ed3c1af00
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/copr/aliases
@@ -0,0 +1,9 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+needs/root
+skip/macos
+skip/osx
+skip/freebsd
diff --git a/ansible_collections/community/general/tests/integration/targets/copr/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/copr/tasks/main.yml
new file mode 100644
index 000000000..0e4651724
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/copr/tasks/main.yml
@@ -0,0 +1,160 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- when:
+ # Fedora or RHEL >= 8
+ # This module requires the dnf module which is not available on RHEL 7.
+ - >
+ ansible_distribution == 'Fedora'
+ or (ansible_os_family == 'RedHat' and ansible_distribution != 'Fedora'
+ and ansible_distribution_major_version | int >= 8)
+ # The copr module imports dnf which is only available for the system Python
+ # interpreter.
+ - >
+ not (ansible_distribution == 'CentOS' and
+ ansible_distribution_major_version | int == 8 and not
+ ansible_python_version.startswith('3.6'))
+ block:
+ - debug: var=copr_chroot
+ - name: enable copr project
+ copr:
+ host: copr.fedorainfracloud.org
+ state: enabled
+ name: '{{ copr_fullname }}'
+ chroot: "{{ copr_chroot }}"
+ register: result
+
+ - name: assert that the copr project was enabled
+ assert:
+ that:
+ - 'result is changed'
+ - result.msg == 'enabled'
+ - result.info == 'Please note that this repository is not part of the main distribution'
+
+ - name: enable copr project
+ check_mode: true
+ copr:
+ state: enabled
+ name: '{{ copr_fullname }}'
+ chroot: '{{ copr_chroot }}'
+ register: result
+
+ - name: assert that the copr project was enabled
+ assert:
+ that:
+ - result is not changed
+ - result.msg == 'enabled'
+
+ - name: Ensure the repo is installed and enabled | slurp
+ register: result
+ ansible.builtin.slurp:
+ src: "{{ copr_repofile }}"
+
+ - name: Ensure the repo is installed and enabled
+ vars:
+ content: "{{ result.content | b64decode }}"
+ _baseurl: "{{ 'https://download.copr.fedorainfracloud.org/results/gotmax23/community.general.copr_integration_tests' | regex_escape }}"
+ baseurl: "{{ content | regex_search('baseurl=' ~ _baseurl) }}"
+ block:
+ - ansible.builtin.debug:
+ var: content
+ - ansible.builtin.debug:
+ var: baseurl
+ - name: Ensure the repo is installed and enabled
+ ansible.builtin.assert:
+ that:
+ - "'enabled=1' in content"
+ - baseurl | length > 0
+
+ - name: Install test package from Copr
+ when:
+ # Copr does not build new packages for EOL Fedoras.
+ - >
+ not (ansible_distribution == 'Fedora' and
+ ansible_distribution_major_version | int < 35)
+ block:
+ - name: install test package from the copr
+ ansible.builtin.package:
+ update_cache: true
+ name: copr-module-integration-dummy-package
+
+ - name: uninstall test package
+ register: result
+ ansible.builtin.package:
+ name: copr-module-integration-dummy-package
+ state: absent
+
+ - name: check uninstall test package
+ ansible.builtin.assert:
+ that: result.changed | bool
+
+ - name: remove copr project
+ copr:
+ state: absent
+ name: '{{ copr_fullname }}'
+ register: result
+
+ - name: assert that the copr project was removed
+ assert:
+ that:
+ - 'result is changed'
+ - result.msg == 'absent'
+
+ - name: Ensure the repo file was removed | stat
+ register: result
+ ansible.builtin.stat:
+ dest: "{{ copr_repofile }}"
+
+ - name: Ensure the repo file was removed
+ ansible.builtin.assert:
+ that: not result.stat.exists | bool
+
+ - name: disable copr project
+ copr:
+ state: disabled
+ name: '{{ copr_fullname }}'
+ chroot: '{{ copr_chroot }}'
+ register: result
+
+ - name: assert that the copr project was disabled
+ assert:
+ that:
+ - 'result is changed'
+ - result.msg == 'disabled'
+
+ - name: Ensure the repo is installed but disabled | slurp
+ register: result
+ ansible.builtin.slurp:
+ src: "{{ copr_repofile }}"
+
+ - name: Ensure the repo is installed but disabled
+ vars:
+ content: "{{ result.content | b64decode }}"
+ _baseurl: "{{ 'https://download.copr.fedorainfracloud.org/results/gotmax23/community.general.copr_integration_tests' | regex_escape }}"
+ baseurl: "{{ content | regex_search('baseurl=' ~ _baseurl) }}"
+ block:
+ - ansible.builtin.debug:
+ var: content
+ - ansible.builtin.debug:
+ var: baseurl
+ - name: Ensure the repo is installed but disabled
+ ansible.builtin.assert:
+ that:
+ - "'enabled=0' in content"
+ - baseurl | length > 0
+
+ always:
+ - name: clean up
+ ignore_errors: true
+ copr:
+ host: copr.fedorainfracloud.org
+ state: absent
+ name: '{{ copr_fullname }}'
+ chroot: '{{ copr_chroot }}'
+
+ - name: cleanup test package
+ ansible.builtin.package:
+ name: copr-module-integration-dummy-package
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/copr/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/copr/vars/main.yml
new file mode 100644
index 000000000..a37a44d47
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/copr/vars/main.yml
@@ -0,0 +1,15 @@
+# Copyright (c) 2022 Maxwell G <gotmax@e.email>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or
+# https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+---
+copr_host: copr.fedorainfracloud.org
+copr_namespace: gotmax23
+copr_name: community.general.copr_integration_tests
+copr_fullname: '{{ copr_namespace }}/{{ copr_name }}'
+copr_repofile: '/etc/yum.repos.d/_copr:{{ copr_host }}:{{ copr_namespace }}:{{ copr_name }}.repo'
+
+# TODO: Fix chroot autodetection so this isn't necessary
+_copr_chroot_fedora: "fedora-rawhide-x86_64"
+_copr_chroot_rhelish: "epel-{{ ansible_distribution_major_version }}-x86_64"
+copr_chroot: "{{ _copr_chroot_fedora if ansible_distribution == 'Fedora' else _copr_chroot_rhelish }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/cpanm/aliases b/ansible_collections/community/general/tests/integration/targets/cpanm/aliases
new file mode 100644
index 000000000..d30ba06b6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/cpanm/aliases
@@ -0,0 +1,10 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/3
+destructive
+skip/macos
+skip/osx
+skip/freebsd
+skip/aix
diff --git a/ansible_collections/community/general/tests/integration/targets/cpanm/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/cpanm/meta/main.yml
new file mode 100644
index 000000000..2fcd152f9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/cpanm/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
diff --git a/ansible_collections/community/general/tests/integration/targets/cpanm/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/cpanm/tasks/main.yml
new file mode 100644
index 000000000..c9adc1ca6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/cpanm/tasks/main.yml
@@ -0,0 +1,65 @@
+# Copyright (c) 2020, Berkhan Berkdemir
+# Copyright (c) 2021, Alexei Znamensky
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: bail out for non-supported platforms
+ meta: end_play
+ when:
+ - (ansible_os_family != "RedHat" or ansible_distribution_major_version|int < 7)
+ - ansible_os_family != "Debian"
+
+- name: install perl development package for Red Hat family
+ package:
+ name:
+ - perl-devel
+ - perl-App-cpanminus
+ state: present
+ become: true
+ when: ansible_os_family == "RedHat"
+
+- name: install perl development package for Debian family
+ package:
+ name:
+ - cpanminus
+ state: present
+ become: true
+ when: ansible_os_family == "Debian"
+
+- name: install a Perl package
+ cpanm:
+ name: JSON
+ notest: true
+ register: install_perl_package_result
+
+- name: assert package is installed
+ assert:
+ that:
+ - install_perl_package_result is changed
+ - install_perl_package_result is not failed
+
+- name: install same Perl package
+ cpanm:
+ name: JSON
+ notest: true
+ register: install_same_perl_package_result
+
+- name: assert same package is installed
+ assert:
+ that:
+ - install_same_perl_package_result is not changed
+ - install_same_perl_package_result is not failed
+
+- name: install a Perl package with version operator
+ cpanm:
+ name: JSON
+ version: "@4.01"
+ notest: true
+ mode: new
+ register: install_perl_package_with_version_op_result
+
+- name: assert package with version operator is installed
+ assert:
+ that:
+ - install_perl_package_with_version_op_result is changed
+ - install_perl_package_with_version_op_result is not failed
diff --git a/ansible_collections/community/general/tests/integration/targets/cronvar/aliases b/ansible_collections/community/general/tests/integration/targets/cronvar/aliases
new file mode 100644
index 000000000..e9ef7265d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/cronvar/aliases
@@ -0,0 +1,9 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/3
+destructive
+skip/aix
+skip/osx
+skip/macos
diff --git a/ansible_collections/community/general/tests/integration/targets/cronvar/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/cronvar/defaults/main.yml
new file mode 100644
index 000000000..11ef47d9d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/cronvar/defaults/main.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cron_config_path: /etc/cron.d
diff --git a/ansible_collections/community/general/tests/integration/targets/cronvar/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/cronvar/meta/main.yml
new file mode 100644
index 000000000..92d116f2a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/cronvar/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_cron
diff --git a/ansible_collections/community/general/tests/integration/targets/cronvar/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/cronvar/tasks/main.yml
new file mode 100644
index 000000000..73ec41abc
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/cronvar/tasks/main.yml
@@ -0,0 +1,124 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Ensure /etc/cron.d directory exists
+ file:
+ path: /etc/cron.d
+ state: directory
+
+- name: Create EMAIL cron var
+ cronvar:
+ name: EMAIL
+ value: doug@ansibmod.con.com
+ register: create_cronvar1
+
+- name: Create EMAIL cron var again
+ cronvar:
+ name: EMAIL
+ value: doug@ansibmod.con.com
+ register: create_cronvar2
+
+- name: Check cron var value
+ shell: crontab -l -u root | grep -c EMAIL=doug@ansibmod.con.com
+ register: varcheck1
+
+- name: Modify EMAIL cron var
+ cronvar:
+ name: EMAIL
+ value: jane@ansibmod.con.com
+ register: create_cronvar3
+
+- name: Check cron var value again
+ shell: crontab -l -u root | grep -c EMAIL=jane@ansibmod.con.com
+ register: varcheck2
+
+- name: Remove EMAIL cron var
+ cronvar:
+ name: EMAIL
+ state: absent
+ register: remove_cronvar1
+
+- name: Remove EMAIL cron var again
+ cronvar:
+ name: EMAIL
+ state: absent
+ register: remove_cronvar2
+
+- name: Check cron var value again
+ shell: crontab -l -u root | grep -c EMAIL
+ register: varcheck3
+ failed_when: varcheck3.rc == 0
+
+- name: Add cron var to custom file
+ cronvar:
+ name: TESTVAR
+ value: somevalue
+ cron_file: cronvar_test
+ register: custom_cronfile1
+
+- name: Add cron var to custom file again
+ cronvar:
+ name: TESTVAR
+ value: somevalue
+ cron_file: cronvar_test
+ register: custom_cronfile2
+
+- name: Check cron var value in custom file
+ command: grep -c TESTVAR=somevalue {{ cron_config_path }}/cronvar_test
+ register: custom_varcheck1
+
+- name: Change cron var in custom file
+ cronvar:
+ name: TESTVAR
+ value: newvalue
+ cron_file: cronvar_test
+ register: custom_cronfile3
+
+- name: Check cron var value in custom file
+ command: grep -c TESTVAR=newvalue {{ cron_config_path }}/cronvar_test
+ register: custom_varcheck2
+
+- name: Remove cron var from custom file
+ cronvar:
+ name: TESTVAR
+ value: newvalue
+ cron_file: cronvar_test
+ state: absent
+ register: custom_remove_cronvar1
+
+- name: Remove cron var from custom file again
+ cronvar:
+ name: TESTVAR
+ value: newvalue
+ cron_file: cronvar_test
+ state: absent
+ register: custom_remove_cronvar2
+
+- name: Check cron var value
+ command: grep -c TESTVAR=newvalue {{ cron_config_path }}/cronvar_test
+ register: custom_varcheck3
+ failed_when: custom_varcheck3.rc == 0
+
+- name: Ensure cronvar tasks did the right thing
+ assert:
+ that:
+ - create_cronvar1 is changed
+ - create_cronvar2 is not changed
+ - create_cronvar3 is changed
+ - remove_cronvar1 is changed
+ - remove_cronvar2 is not changed
+ - varcheck1.stdout == '1'
+ - varcheck2.stdout == '1'
+ - varcheck3.stdout == '0'
+ - custom_remove_cronvar1 is changed
+ - custom_remove_cronvar2 is not changed
+ - custom_varcheck1.stdout == '1'
+ - custom_varcheck2.stdout == '1'
+ - custom_varcheck3.stdout == '0'
diff --git a/ansible_collections/community/general/tests/integration/targets/deploy_helper/aliases b/ansible_collections/community/general/tests/integration/targets/deploy_helper/aliases
new file mode 100644
index 000000000..afda346c4
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/deploy_helper/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
diff --git a/ansible_collections/community/general/tests/integration/targets/deploy_helper/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/deploy_helper/meta/main.yml
new file mode 100644
index 000000000..982de6eb0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/deploy_helper/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/deploy_helper/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/deploy_helper/tasks/main.yml
new file mode 100644
index 000000000..fdd8bd87b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/deploy_helper/tasks/main.yml
@@ -0,0 +1,158 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: record the output directory
+ set_fact: deploy_helper_test_root={{remote_tmp_dir}}/deploy_helper_test_root
+
+- name: State=query with default parameters
+ deploy_helper: path={{ deploy_helper_test_root }} state=query
+- name: Assert State=query with default parameters
+ assert:
+ that:
+ - "'project_path' in deploy_helper"
+ - "deploy_helper.current_path == '{{ deploy_helper.project_path }}/current'"
+ - "deploy_helper.releases_path == '{{ deploy_helper.project_path }}/releases'"
+ - "deploy_helper.shared_path == '{{ deploy_helper.project_path }}/shared'"
+ - "deploy_helper.unfinished_filename == 'DEPLOY_UNFINISHED'"
+ - "'previous_release' in deploy_helper"
+ - "'previous_release_path' in deploy_helper"
+ - "'new_release' in deploy_helper"
+ - "'new_release_path' in deploy_helper"
+ - "deploy_helper.new_release_path == '{{ deploy_helper.releases_path }}/{{ deploy_helper.new_release }}'"
+
+- name: State=query with relative overridden paths
+ deploy_helper: path={{ deploy_helper_test_root }} current_path=CURRENT_PATH releases_path=RELEASES_PATH shared_path=SHARED_PATH state=query
+- name: Assert State=query with relative overridden paths
+ assert:
+ that:
+ - "deploy_helper.current_path == '{{ deploy_helper.project_path }}/CURRENT_PATH'"
+ - "deploy_helper.releases_path == '{{ deploy_helper.project_path }}/RELEASES_PATH'"
+ - "deploy_helper.shared_path == '{{ deploy_helper.project_path }}/SHARED_PATH'"
+ - "deploy_helper.new_release_path == '{{ deploy_helper.releases_path }}/{{ deploy_helper.new_release}}'"
+
+- name: State=query with absolute overridden paths
+ deploy_helper: path={{ deploy_helper_test_root }} current_path=/CURRENT_PATH releases_path=/RELEASES_PATH shared_path=/SHARED_PATH state=query
+- name: Assert State=query with absolute overridden paths
+ assert:
+ that:
+ - "deploy_helper.current_path == '/CURRENT_PATH'"
+ - "deploy_helper.releases_path == '/RELEASES_PATH'"
+ - "deploy_helper.shared_path == '/SHARED_PATH'"
+ - "deploy_helper.new_release_path == '{{ deploy_helper.releases_path }}/{{ deploy_helper.new_release}}'"
+
+- name: State=query with overridden unfinished_filename
+ deploy_helper: path={{ deploy_helper_test_root }} unfinished_filename=UNFINISHED_DEPLOY state=query
+- name: Assert State=query with overridden unfinished_filename
+ assert:
+ that:
+ - "'UNFINISHED_DEPLOY' == deploy_helper.unfinished_filename"
+
+# Remove the root folder just in case it exists
+- file: path={{ deploy_helper_test_root }} state=absent
+
+- name: State=present with default parameters
+ deploy_helper: path={{ deploy_helper_test_root }} state=present
+- stat: path={{ deploy_helper.releases_path }}
+ register: releases_path
+- stat: path={{ deploy_helper.shared_path }}
+ register: shared_path
+- name: Assert State=present with default parameters
+ assert:
+ that:
+ - "releases_path.stat.exists"
+ - "shared_path.stat.exists"
+
+# Setup older releases for tests
+- file: path={{ deploy_helper.releases_path }}/{{ item }} state=directory
+ with_items: ['first', 'second', 'third', 'fourth', 'fifth', 'sixth', 'seventh']
+# Setup the new release
+- file: path={{ deploy_helper.new_release_path }} state=directory
+# Add a buildfile, just like in a real deploy
+- copy: content='' dest={{ deploy_helper.new_release_path }}/{{ deploy_helper.unfinished_filename }}
+# Add a buildfile, to an older deploy
+- copy: content='' dest={{ deploy_helper.releases_path }}/third/{{ deploy_helper.unfinished_filename }}
+
+- name: State=finalize with default parameters
+ deploy_helper: path={{ deploy_helper_test_root }} release={{ deploy_helper.new_release }} state=finalize
+- stat: path={{ deploy_helper.current_path }}
+ register: current_path
+- stat: path={{ deploy_helper.current_path }}/DEPLOY_UNFINISHED
+ register: current_path_unfinished_filename
+- name: Assert State=finalize with default parameters
+ assert:
+ that:
+ - "current_path.stat.islnk"
+ - "deploy_helper.new_release_path in current_path.stat.lnk_source"
+ - "not current_path_unfinished_filename.stat.exists"
+- stat: path={{ deploy_helper.releases_path }}/third
+ register: third_release_path
+- shell: "ls {{ deploy_helper.releases_path }} | wc -l"
+ register: releases_count
+- name: Assert State=finalize with default parameters (clean=true checks)
+ assert:
+ that:
+ - "not third_release_path.stat.exists"
+ - "releases_count.stdout|trim == '6'"
+- deploy_helper: path={{ deploy_helper_test_root }} release={{ deploy_helper.new_release }} state=query
+- name: Assert State=finalize with default parameters (previous_release checks)
+ assert:
+ that:
+ - "deploy_helper.new_release == deploy_helper.previous_release"
+
+- name: State=absent with default parameters
+ deploy_helper: path={{ deploy_helper_test_root }} state=absent
+- stat: path={{ deploy_helper_test_root }}
+ register: project_path
+- name: Assert State=absent with default parameters
+ assert:
+ that:
+ - "not project_path.stat.exists"
+
+- debug: msg="Clearing all release data and facts ---------"
+
+- name: State=present with shared_path set to False
+ deploy_helper: path={{ deploy_helper_test_root }} state=present shared_path=''
+- stat: path={{ deploy_helper.releases_path }}
+ register: releases_path
+- stat: path={{ deploy_helper.shared_path }}
+ register: shared_path
+- name: Assert State=present with shared_path set to False
+ assert:
+ that:
+ - "releases_path.stat.exists"
+ - "not shared_path.stat.exists"
+
+# Setup older releases for tests
+- file: path={{ deploy_helper.releases_path }}/{{ item }} state=directory
+ with_items: ['first', 'second', 'third', 'fourth', 'fifth']
+# Setup the new release
+- file: path={{ deploy_helper.new_release_path }} state=directory
+# Add a buildfile, just like in a real deploy
+- copy: content='' dest={{ deploy_helper.new_release_path }}/{{ deploy_helper.unfinished_filename }}
+# Add a buildfile, to an older deploy
+- copy: content='' dest={{ deploy_helper.releases_path }}/third/{{ deploy_helper.unfinished_filename }}
+
+- shell: "ls {{ deploy_helper_test_root }}/releases | wc -l"
+ register: before_releases_count
+- name: State=clean with keep_releases=3
+ deploy_helper: path={{ deploy_helper_test_root }} release={{ deploy_helper.new_release }} state=clean keep_releases=3
+- stat: path={{ deploy_helper.releases_path }}/third
+ register: third_release_path
+- shell: "ls {{ deploy_helper.releases_path }} | wc -l"
+ register: releases_count
+- name: Assert State=finalize with default parameters (clean=true checks)
+ assert:
+ that:
+ - "not third_release_path.stat.exists"
+ - "before_releases_count.stdout|trim == '6'"
+ - "releases_count.stdout|trim == '3'"
+
+# Remove the root folder
+- file: path={{ deploy_helper_test_root }} state=absent
diff --git a/ansible_collections/community/general/tests/integration/targets/discord/README.md b/ansible_collections/community/general/tests/integration/targets/discord/README.md
new file mode 100644
index 000000000..528ea0643
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/discord/README.md
@@ -0,0 +1,20 @@
+<!--
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+-->
+
+The integration tests can be executed locally:
+
+1. Create or use an existing discord server
+2. Open `Server Settings` and navigate to `Integrations` tab
+3. Click `Create Webhook` to create a new webhook
+4. Click `Copy Webhook URL` and extract the webhook_id + webhook_token
+
+ Example: https://discord.com/api/webhooks/`webhook_id`/`webhook_token`
+
+5. Replace the variables `discord_id` and `discord_token` in the var file
+6. Run the integration test
+````
+ansible-test integration -v --color yes discord --allow-unsupported
+````
diff --git a/ansible_collections/community/general/tests/integration/targets/discord/aliases b/ansible_collections/community/general/tests/integration/targets/discord/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/discord/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/discord/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/discord/defaults/main.yml
new file mode 100644
index 000000000..ef01141ca
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/discord/defaults/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+discord_id: 000
+discord_token: xxx
diff --git a/ansible_collections/community/general/tests/integration/targets/discord/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/discord/tasks/main.yml
new file mode 100644
index 000000000..29314ba23
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/discord/tasks/main.yml
@@ -0,0 +1,69 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Send basic message
+ community.general.discord:
+ webhook_id: "{{ discord_id }}"
+ webhook_token: "{{ discord_token }}"
+ content: "Messages from ansible-test"
+ register: result
+
+- name: Check result
+ assert:
+ that:
+ - result is changed
+ - result.http_code == 204
+
+- name: Send embeds
+ community.general.discord:
+ webhook_id: "{{ discord_id }}"
+ webhook_token: "{{ discord_token }}"
+ embeds:
+ - title: "Title of embed message 1"
+ description: "Description embed message 1"
+ footer:
+ text: "author ansible-test"
+ image:
+ url: "https://avatars.githubusercontent.com/u/44586252?s=200&v=4"
+ - title: "Title of embed message 2"
+ description: "Description embed message 2"
+ footer:
+ text: "author ansible-test"
+ icon_url: "https://avatars.githubusercontent.com/u/44586252?s=200&v=4"
+ fields:
+ - name: "Field 1"
+ value: 1
+ - name: "Field 2"
+ value: "Text"
+ timestamp: "{{ ansible_date_time.iso8601 }}"
+ username: Ansible Test
+ avatar_url: "https://avatars.githubusercontent.com/u/44586252?s=200&v=4"
+ register: result
+
+- name: Check result
+ assert:
+ that:
+ - result is changed
+ - result.http_code == 204
+
+- name: Use a wrong token
+ community.general.discord:
+ webhook_id: "{{ discord_id }}"
+ webhook_token: "wrong_token"
+ content: "Messages from ansible-test"
+ register: result
+ ignore_errors: true
+
+- name: Check result
+ assert:
+ that:
+ - result is not changed
+ - result.http_code == 401
+ - result.response.message == "Invalid Webhook Token"
diff --git a/ansible_collections/community/general/tests/integration/targets/django_manage/aliases b/ansible_collections/community/general/tests/integration/targets/django_manage/aliases
new file mode 100644
index 000000000..98aed9e9d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/django_manage/aliases
@@ -0,0 +1,15 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+skip/python2
+skip/freebsd
+skip/macos
+skip/osx
+skip/rhel8.2
+skip/rhel8.3
+skip/rhel8.4
+skip/rhel8.5
+skip/rhel9.0
+skip/rhel9.1
diff --git a/ansible_collections/community/general/tests/integration/targets/django_manage/files/base_test/1045-single-app-project/single_app_project/core/settings.py b/ansible_collections/community/general/tests/integration/targets/django_manage/files/base_test/1045-single-app-project/single_app_project/core/settings.py
new file mode 100644
index 000000000..881221c06
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/django_manage/files/base_test/1045-single-app-project/single_app_project/core/settings.py
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# single_app_project/core/settings.py
+SECRET_KEY = 'testtesttesttesttest'
diff --git a/ansible_collections/community/general/tests/integration/targets/django_manage/files/base_test/1045-single-app-project/single_app_project/manage.py b/ansible_collections/community/general/tests/integration/targets/django_manage/files/base_test/1045-single-app-project/single_app_project/manage.py
new file mode 100755
index 000000000..4b4eddcb6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/django_manage/files/base_test/1045-single-app-project/single_app_project/manage.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+# single_app_project/manage.py
+import os
+import sys
+
+
+def main():
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'single_app_project.core.settings')
+ from django.core.management import execute_from_command_line
+ execute_from_command_line(sys.argv)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/general/tests/integration/targets/django_manage/files/base_test/simple_project/p1/manage.py b/ansible_collections/community/general/tests/integration/targets/django_manage/files/base_test/simple_project/p1/manage.py
new file mode 100755
index 000000000..be3140f44
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/django_manage/files/base_test/simple_project/p1/manage.py
@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+"""Django's command-line utility for administrative tasks."""
+import os
+import sys
+
+
+def main():
+ """Run administrative tasks."""
+ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'p1.settings')
+ try:
+ from django.core.management import execute_from_command_line
+ except ImportError as exc:
+ raise ImportError(
+ "Couldn't import Django. Are you sure it's installed and "
+ "available on your PYTHONPATH environment variable? Did you "
+ "forget to activate a virtual environment?"
+ ) from exc
+ execute_from_command_line(sys.argv)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/general/tests/integration/targets/django_manage/files/base_test/simple_project/p1/p1/settings.py b/ansible_collections/community/general/tests/integration/targets/django_manage/files/base_test/simple_project/p1/p1/settings.py
new file mode 100644
index 000000000..86b3ae64c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/django_manage/files/base_test/simple_project/p1/p1/settings.py
@@ -0,0 +1,133 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+"""
+Django settings for p1 project.
+
+Generated by 'django-admin startproj' using Django 3.1.5.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/3.1/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/3.1/ref/settings/
+"""
+
+import os
+from pathlib import Path
+
+# Build paths inside the project like this: BASE_DIR / 'subdir'.
+BASE_DIR = Path(__file__).resolve().parent.parent
+
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = '%g@gyhl*q@@g(_ab@t^76dao^#b9-v8mw^50)x_bv6wpl+mukj'
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+
+ALLOWED_HOSTS = []
+
+
+# Application definition
+
+INSTALLED_APPS = [
+ 'django.contrib.admin',
+ 'django.contrib.auth',
+ 'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'django.contrib.messages',
+ 'django.contrib.staticfiles',
+]
+
+MIDDLEWARE = [
+ 'django.middleware.security.SecurityMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.middleware.common.CommonMiddleware',
+ 'django.middleware.csrf.CsrfViewMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware',
+ 'django.middleware.clickjacking.XFrameOptionsMiddleware',
+]
+
+ROOT_URLCONF = 'p1.urls'
+
+TEMPLATES = [
+ {
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'DIRS': [],
+ 'APP_DIRS': True,
+ 'OPTIONS': {
+ 'context_processors': [
+ 'django.template.context_processors.debug',
+ 'django.template.context_processors.request',
+ 'django.contrib.auth.context_processors.auth',
+ 'django.contrib.messages.context_processors.messages',
+ ],
+ },
+ },
+]
+
+WSGI_APPLICATION = 'p1.wsgi.application'
+
+
+# Database
+# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
+
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'NAME': BASE_DIR / 'db.sqlite3',
+ }
+}
+
+
+# Password validation
+# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
+
+AUTH_PASSWORD_VALIDATORS = [
+ {
+ 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+ },
+]
+
+
+# Internationalization
+# https://docs.djangoproject.com/en/3.1/topics/i18n/
+
+LANGUAGE_CODE = 'en-us'
+
+TIME_ZONE = 'UTC'
+
+USE_I18N = True
+
+USE_L10N = True
+
+USE_TZ = True
+
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/3.1/howto/static-files/
+
+STATIC_URL = '/static/'
+STATIC_ROOT = '/tmp/django-static'
+
+if "DJANGO_ANSIBLE_RAISE" in os.environ:
+ raise ValueError("DJANGO_ANSIBLE_RAISE={0}".format(os.environ["DJANGO_ANSIBLE_RAISE"]))
diff --git a/ansible_collections/community/general/tests/integration/targets/django_manage/files/base_test/simple_project/p1/p1/urls.py b/ansible_collections/community/general/tests/integration/targets/django_manage/files/base_test/simple_project/p1/p1/urls.py
new file mode 100644
index 000000000..36cb59275
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/django_manage/files/base_test/simple_project/p1/p1/urls.py
@@ -0,0 +1,28 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+"""p1 URL Configuration
+
+The `urlpatterns` list routes URLs to views. For more information please see:
+ https://docs.djangoproject.com/en/2.2/topics/http/urls/
+Examples:
+Function views
+ 1. Add an import: from my_app import views
+ 2. Add a URL to urlpatterns: path('', views.home, name='home')
+Class-based views
+ 1. Add an import: from other_app.views import Home
+ 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
+Including another URLconf
+ 1. Import the include() function: from django.urls import include, path
+ 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
+"""
+from django.contrib import admin
+from django.urls import path
+
+urlpatterns = [
+ path('admin/', admin.site.urls),
+]
diff --git a/ansible_collections/community/general/tests/integration/targets/django_manage/files/base_test/startproj/.keep b/ansible_collections/community/general/tests/integration/targets/django_manage/files/base_test/startproj/.keep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/django_manage/files/base_test/startproj/.keep
diff --git a/ansible_collections/community/general/tests/integration/targets/django_manage/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/django_manage/meta/main.yml
new file mode 100644
index 000000000..2fcd152f9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/django_manage/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
diff --git a/ansible_collections/community/general/tests/integration/targets/django_manage/tasks/main.yaml b/ansible_collections/community/general/tests/integration/targets/django_manage/tasks/main.yaml
new file mode 100644
index 000000000..c07b53893
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/django_manage/tasks/main.yaml
@@ -0,0 +1,84 @@
+# Test code for django_manage module
+#
+# Copyright (c) 2020, Alexei Znamensky <russoz@gmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+- name: Create temporary test directory
+ tempfile:
+ state: directory
+ suffix: .django_manage
+ register: tmp_django_root
+
+- name: Install virtualenv on CentOS 8
+ package:
+ name: virtualenv
+ state: present
+ when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '8'
+
+- name: Install virtualenv on Arch Linux
+ pip:
+ name: virtualenv
+ state: present
+ when: ansible_os_family == 'Archlinux'
+
+- name: Install required library
+ pip:
+ name: django
+ state: present
+ virtualenv: "{{ tmp_django_root.path }}/venv"
+
+- name: Copy files
+ copy:
+ src: base_test/
+ dest: "{{ tmp_django_root.path }}"
+ mode: preserve
+
+- name: Create project
+ command:
+ chdir: "{{ tmp_django_root.path }}/startproj"
+ cmd: "{{ tmp_django_root.path }}/venv/bin/django-admin startproject test_django_manage_1"
+
+- name: Create app
+ command:
+ chdir: "{{ tmp_django_root.path }}/startproj"
+ cmd: "{{ tmp_django_root.path }}/venv/bin/django-admin startapp app1"
+
+- name: Check
+ community.general.django_manage:
+ project_path: "{{ tmp_django_root.path }}/startproj/test_django_manage_1"
+ command: check
+ virtualenv: "{{ tmp_django_root.path }}/venv"
+
+- name: Check simple_project
+ community.general.django_manage:
+ project_path: "{{ tmp_django_root.path }}/simple_project/p1"
+ command: check
+ virtualenv: "{{ tmp_django_root.path }}/venv"
+
+- name: Check custom project
+ community.general.django_manage:
+ project_path: "{{ tmp_django_root.path }}/1045-single-app-project/single_app_project"
+ pythonpath: "{{ tmp_django_root.path }}/1045-single-app-project/"
+ command: check
+ virtualenv: "{{ tmp_django_root.path }}/venv"
+
+- name: Run collectstatic --noinput on simple project
+ community.general.django_manage:
+ project_path: "{{ tmp_django_root.path }}/simple_project/p1"
+ command: collectstatic --noinput
+ virtualenv: "{{ tmp_django_root.path }}/venv"
+
+- name: Trigger exception with environment variable
+ community.general.django_manage:
+ project_path: "{{ tmp_django_root.path }}/simple_project/p1"
+ command: collectstatic --noinput
+ virtualenv: "{{ tmp_django_root.path }}/venv"
+ environment:
+ DJANGO_ANSIBLE_RAISE: blah
+ ignore_errors: true
+ register: env_raise
+
+- name: Check env variable reached manage.py
+ ansible.builtin.assert:
+ that:
+ - "'ValueError: DJANGO_ANSIBLE_RAISE=blah' in env_raise.msg"
diff --git a/ansible_collections/community/general/tests/integration/targets/dnf_versionlock/aliases b/ansible_collections/community/general/tests/integration/targets/dnf_versionlock/aliases
new file mode 100644
index 000000000..b85ae6419
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/dnf_versionlock/aliases
@@ -0,0 +1,9 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+skip/aix
+skip/freebsd
+skip/osx
+skip/macos
diff --git a/ansible_collections/community/general/tests/integration/targets/dnf_versionlock/tasks/install.yml b/ansible_collections/community/general/tests/integration/targets/dnf_versionlock/tasks/install.yml
new file mode 100644
index 000000000..9773d87dc
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/dnf_versionlock/tasks/install.yml
@@ -0,0 +1,10 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install dnf versionlock plugin
+ dnf:
+ name: dnf-plugin-versionlock
+ state: present
+...
diff --git a/ansible_collections/community/general/tests/integration/targets/dnf_versionlock/tasks/lock_bash.yml b/ansible_collections/community/general/tests/integration/targets/dnf_versionlock/tasks/lock_bash.yml
new file mode 100644
index 000000000..56357e01c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/dnf_versionlock/tasks/lock_bash.yml
@@ -0,0 +1,36 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Clear locklist
+ community.general.dnf_versionlock:
+ state: clean
+ register: clear_locklist
+
+- assert:
+ that:
+ - clear_locklist.locklist_post | length == 0
+
+- name: Lock installed package bash
+ community.general.dnf_versionlock:
+ name: bash
+ state: present
+ register: lock_bash
+
+- assert:
+ that:
+ - lock_bash is changed
+ - lock_bash.locklist_post | length == 1
+
+- name: Unlock installed package bash
+ community.general.dnf_versionlock:
+ name: bash
+ state: absent
+ register: unlock_bash
+
+- assert:
+ that:
+ - unlock_bash is changed
+ - unlock_bash.locklist_post | length == 0
+...
diff --git a/ansible_collections/community/general/tests/integration/targets/dnf_versionlock/tasks/lock_updates.yml b/ansible_collections/community/general/tests/integration/targets/dnf_versionlock/tasks/lock_updates.yml
new file mode 100644
index 000000000..b3fceb26f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/dnf_versionlock/tasks/lock_updates.yml
@@ -0,0 +1,74 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Check packages with updates
+ dnf:
+ list: updates
+ register: updates
+
+- name: Set local facts
+ set_fact:
+ _packages: "{{ (updates.results | map(attribute='name') | list)[:5] }}"
+
+- debug:
+ msg:
+ - "The packages to be locked and unlocked are: {{ _packages}}"
+
+- block:
+ - name: Clear locklist
+ community.general.dnf_versionlock:
+ state: clean
+ register: clear_locklist
+
+ - assert:
+ that:
+ - clear_locklist.locklist_post | length == 0
+
+ - name: Lock packages with updates
+ dnf_versionlock:
+ name: "{{ _packages }}"
+ state: present
+ register: lock_packages
+
+ - assert:
+ that:
+ - lock_packages is changed
+ - (lock_packages.locklist_post | length) <= (_packages | length)
+
+ - name: Update packages with updates while locked
+ command: >-
+ dnf update -y
+ --setopt=obsoletes=0 {{ _packages | join(' ') }}
+ register: update_locked_packages
+ changed_when: '"Nothing to do" not in update_locked_packages.stdout'
+
+ - assert:
+ that:
+ - update_locked_packages is not changed
+
+ - name: Unlock packages with updates
+ dnf_versionlock:
+ name: "{{ _packages }}"
+ state: absent
+ register: unlock_packages
+
+ - assert:
+ that:
+ - unlock_packages is changed
+ - unlock_packages.locklist_post | length == 0
+
+ - name: Update packages
+ dnf:
+ name: "{{ _packages }}"
+ state: latest
+ check_mode: true
+ register: update_packages
+
+ - assert:
+ that:
+ - update_packages is changed
+
+ when: updates.results | length > 0
+...
diff --git a/ansible_collections/community/general/tests/integration/targets/dnf_versionlock/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/dnf_versionlock/tasks/main.yml
new file mode 100644
index 000000000..51e823ffd
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/dnf_versionlock/tasks/main.yml
@@ -0,0 +1,12 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- block:
+ - include_tasks: install.yml
+ - include_tasks: lock_bash.yml
+ - include_tasks: lock_updates.yml
+ when: (ansible_distribution == 'Fedora' and ansible_distribution_major_version is version('23', '>=')) or
+ (ansible_distribution in ['RedHat', 'CentOS'] and ansible_distribution_major_version is version('8', '>='))
+...
diff --git a/ansible_collections/community/general/tests/integration/targets/dpkg_divert/aliases b/ansible_collections/community/general/tests/integration/targets/dpkg_divert/aliases
new file mode 100644
index 000000000..050bf89b4
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/dpkg_divert/aliases
@@ -0,0 +1,10 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+skip/aix
+skip/osx
+skip/macos
+skip/rhel
+skip/freebsd
diff --git a/ansible_collections/community/general/tests/integration/targets/dpkg_divert/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/dpkg_divert/tasks/main.yml
new file mode 100644
index 000000000..910f174e1
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/dpkg_divert/tasks/main.yml
@@ -0,0 +1,13 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: "include tasks for Debian family"
+ include_tasks: prepare.yml
+ when: ansible_pkg_mgr == "apt"
diff --git a/ansible_collections/community/general/tests/integration/targets/dpkg_divert/tasks/prepare.yml b/ansible_collections/community/general/tests/integration/targets/dpkg_divert/tasks/prepare.yml
new file mode 100644
index 000000000..94566b41e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/dpkg_divert/tasks/prepare.yml
@@ -0,0 +1,43 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: "set variables for the entire playbook"
+ set_fact:
+ foobarrc: "{{ foobarrc }}"
+ foobarrc_ansible: "{{ foobarrc }}.ansible"
+ foobarrc_distrib: "{{ foobarrc }}.distrib"
+ foobarrc_oldtext: "# foobar configuration file\n# Please refer to the documentation for details\n"
+ foobarrc_oldsha1: "e1c54c36d2fd1b8d67d1826e49b95ac8c0f24c0a"
+ foobarrc_newtext: "# Custom foobar configuration file\nFOO=bar\nBAR=foo"
+ foobarrc_newsha1: "3fe6c890519fb48e27c1b0e3e37afb11357d5cac"
+ vars:
+ foobarrc: "/etc/foobarrc"
+
+- name: "remove foobarrc diversion"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ state: absent
+ become: true
+
+- name: "remove test files"
+ file:
+ path: "{{ dpkg_divert_item }}"
+ state: absent
+ loop:
+ - "{{ foobarrc_ansible }}"
+ - "{{ foobarrc_distrib }}"
+ loop_control:
+ loop_var: dpkg_divert_item
+ become: true
+
+
+- block:
+ - name: "include tasks to perform basic tests (create, remove, update)"
+ include_tasks: tests/01-basic.yml
+
+ - name: "include tasks to perform other tests (rename)"
+ include_tasks: tests/02-rename.yml
+ become: true
+ diff: true
diff --git a/ansible_collections/community/general/tests/integration/targets/dpkg_divert/tasks/tests/01-basic.yml b/ansible_collections/community/general/tests/integration/targets/dpkg_divert/tasks/tests/01-basic.yml
new file mode 100644
index 000000000..78863d1db
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/dpkg_divert/tasks/tests/01-basic.yml
@@ -0,0 +1,291 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+################################################################################
+# TEST 01: state=present
+
+- name: "create foobarrc for tests"
+ copy:
+ dest: "{{ foobarrc }}"
+ content: "{{ foobarrc_oldtext }}"
+
+
+- name: "divert foobarrc (check mode, must report a change)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ state: present
+ register: diversion_0
+ check_mode: true
+
+- name: "divert foobarrc (must report a change)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ state: present
+ register: diversion_1
+
+
+- name: "divert foobarrc (must NOT report a change, idempotency)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ state: present
+ register: diversion_2
+
+- name: "divert foobarrc (check mode, must NOT report a change, idempotency)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ state: present
+ register: diversion_3
+ check_mode: true
+
+
+# Ensure that 'rename' has no effect when state is not changed
+
+- name: "divert foobarrc (rename, must NOT report a change, idempotency)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ state: present
+ rename: true
+ register: diversion_4
+
+- name: "divert foobarrc (check mode, rename, must NOT report a change, idempotency)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ state: present
+ rename: true
+ register: diversion_5
+ check_mode: true
+
+
+# Check results
+
+- name: "stat foobarrc (must still be there)"
+ stat:
+ path: "{{ foobarrc }}"
+ register: diversion_6
+
+- name: "stat foobarrc.distrib (must not exist)"
+ stat:
+ path: "{{ foobarrc_distrib }}"
+ register: diversion_7
+
+- name: "assert that results of test 01 are as expected"
+ assert:
+ that:
+ - diversion_0 is changed
+ - diversion_1 is changed
+ - diversion_2 is not changed
+ - diversion_3 is not changed
+ - diversion_4 is not changed
+ - diversion_5 is not changed
+ - diversion_6.stat.exists
+ - diversion_6.stat.checksum == foobarrc_oldsha1
+ - not diversion_7.stat.exists
+ - diversion_0.diversion == diversion_1.diversion
+ - diversion_2.diversion == diversion_3.diversion
+ - diversion_4.diversion == diversion_5.diversion
+ - diversion_0.commands == diversion_1.commands
+ - diversion_2.commands == diversion_3.commands
+ - diversion_4.commands == diversion_5.commands
+ quiet: true
+
+
+################################################################################
+# TEST 02: state=absent
+
+- name: "remove diversion for foobarrc (check mode, must report a change)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ state: absent
+ register: diversion_0
+ check_mode: true
+
+- name: "remove diversion for foobarrc (must report a change)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ state: absent
+ register: diversion_1
+
+
+- name: "remove diversion for foobarrc (must NOT report a change, idempotency)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ state: absent
+ register: diversion_2
+
+- name: "remove diversion for foobarrc (check mode, must NOT report a change, idempotency)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ state: absent
+ register: diversion_3
+ check_mode: true
+
+
+# Check results
+
+- name: "stat foobarrc (must still be there)"
+ stat:
+ path: "{{ foobarrc }}"
+ register: diversion_4
+
+- name: "stat foobarrc.distrib (must not exist)"
+ stat:
+ path: "{{ foobarrc_distrib }}"
+ register: diversion_5
+
+- name: "assert that results of test 02 are as expected"
+ assert:
+ that:
+ - diversion_0 is changed
+ - diversion_1 is changed
+ - diversion_2 is not changed
+ - diversion_3 is not changed
+ - diversion_4.stat.exists
+ - diversion_4.stat.checksum == foobarrc_oldsha1
+ - not diversion_5.stat.exists
+ - diversion_0.diversion == diversion_1.diversion
+ - diversion_2.diversion == diversion_3.diversion
+ - diversion_0.commands == diversion_1.commands
+ - diversion_2.commands == diversion_3.commands
+ quiet: true
+
+
+################################################################################
+# TEST 03: holder=ansible
+
+- name: "create foobarrc diversion with defaults"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+
+
+- name: "update foobarrc diversion holder (check mode, must report a change)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ holder: "ansible"
+ register: diversion_0
+ check_mode: true
+
+- name: "update foobarrc diversion holder (must report a change)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ holder: "ansible"
+ register: diversion_1
+
+
+- name: "update foobarrc diversion holder (must NOT report a change, idempotency)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ holder: "ansible"
+ register: diversion_2
+
+- name: "update foobarrc diversion holder (check mode, must NOT report a change, idempotency)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ holder: "ansible"
+ register: diversion_3
+ check_mode: true
+
+
+# Check results
+
+- name: "stat foobarrc (must still be there)"
+ stat:
+ path: "{{ foobarrc }}"
+ register: diversion_4
+
+- name: "stat foobarrc.distrib (must not exist)"
+ stat:
+ path: "{{ foobarrc_distrib }}"
+ register: diversion_5
+
+- name: "assert that results of test 03 are as expected"
+ assert:
+ that:
+ - diversion_0 is changed
+ - diversion_1 is changed
+ - diversion_2 is not changed
+ - diversion_3 is not changed
+ - diversion_4.stat.exists
+ - diversion_4.stat.checksum == foobarrc_oldsha1
+ - not diversion_5.stat.exists
+ - diversion_0.diversion == diversion_1.diversion
+ - diversion_2.diversion == diversion_3.diversion
+ - diversion_0.commands == diversion_1.commands
+ - diversion_2.commands == diversion_3.commands
+ quiet: true
+
+- name: "remove foobarrc diversion"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ state: absent
+
+
+################################################################################
+# TEST 04: divert=/etc/foobarrc.ansible
+
+- name: "create foobarrc diversion with defaults"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+
+
+- name: "update foobarrc divert path (check mode, must report a change)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ divert: "{{ foobarrc_ansible }}"
+ register: diversion_0
+ check_mode: true
+
+- name: "update foobarrc divert path (must report a change)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ divert: "{{ foobarrc_ansible }}"
+ register: diversion_1
+
+
+- name: "update foobarrc divert path (must NOT report a change, idempotency)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ divert: "{{ foobarrc_ansible }}"
+ register: diversion_2
+
+- name: "update foobarrc divert path (check mode, must NOT report a change, idempotency)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ divert: "{{ foobarrc_ansible }}"
+ register: diversion_3
+ check_mode: true
+
+
+# Check results
+
+- name: "stat foobarrc (must still be there)"
+ stat:
+ path: "{{ foobarrc }}"
+ register: diversion_4
+
+- name: "stat foobarrc.ansible (must not exist)"
+ stat:
+ path: "{{ foobarrc_ansible }}"
+ register: diversion_5
+
+- name: "assert that results of test 04 are as expected"
+ assert:
+ that:
+ - diversion_0 is changed
+ - diversion_1 is changed
+ - diversion_2 is not changed
+ - diversion_3 is not changed
+ - diversion_4.stat.exists
+ - diversion_4.stat.checksum == foobarrc_oldsha1
+ - not diversion_5.stat.exists
+ - diversion_0.diversion == diversion_1.diversion
+ - diversion_2.diversion == diversion_3.diversion
+ - diversion_0.commands == diversion_1.commands
+ - diversion_2.commands == diversion_3.commands
+ quiet: true
+
+- name: "remove foobarrc diversion"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/dpkg_divert/tasks/tests/02-rename.yml b/ansible_collections/community/general/tests/integration/targets/dpkg_divert/tasks/tests/02-rename.yml
new file mode 100644
index 000000000..6c95a7291
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/dpkg_divert/tasks/tests/02-rename.yml
@@ -0,0 +1,384 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+################################################################################
+# TEST 05: rename=yes, state=present
+
+- name: "create diversion for foobarrc (check mode, rename, must report a change)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ rename: true
+ register: diversion_0
+ check_mode: true
+
+- name: "create diversion for foobarrc (rename, must report a change)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ rename: true
+ register: diversion_1
+
+
+- name: "create diversion for foobarrc (rename, must NOT report a change, idempotency)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ rename: true
+ register: diversion_2
+
+- name: "create diversion for foobarrc (check mode, rename, must NOT report a change, idempotency)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ rename: true
+ register: diversion_3
+ check_mode: true
+
+
+# Get results
+
+- name: "stat foobarrc (must not exist)"
+ stat:
+ path: "{{ foobarrc }}"
+ register: diversion_4
+
+- name: "stat foobarrc.distrib (must exist)"
+ stat:
+ path: "{{ foobarrc_distrib }}"
+ register: diversion_5
+
+- name: "assert that results of test 05 are as expected"
+ assert:
+ that:
+ - diversion_0 is changed
+ - diversion_1 is changed
+ - diversion_2 is not changed
+ - diversion_3 is not changed
+ - not diversion_4.stat.exists
+ - diversion_5.stat.exists
+ - diversion_5.stat.checksum == foobarrc_oldsha1
+ - diversion_0.diversion == diversion_1.diversion
+ - diversion_2.diversion == diversion_3.diversion
+ - diversion_0.commands == diversion_1.commands
+ - diversion_2.commands == diversion_3.commands
+ quiet: true
+
+
+################################################################################
+# TEST 06: rename=yes, state=absent
+
+- name: "remove diversion for foobarrc (check mode, rename, must report a change)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ rename: true
+ state: absent
+ register: diversion_0
+ check_mode: true
+
+- name: "remove diversion for foobarrc (rename, must report a change)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ rename: true
+ state: absent
+ register: diversion_1
+
+
+- name: "remove diversion for foobarrc (rename, must NOT report a change, idempotency)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ rename: true
+ state: absent
+ register: diversion_2
+
+- name: "remove diversion for foobarrc (check mode, rename, must NOT report a change, idempotency)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ rename: true
+ state: absent
+ register: diversion_3
+ check_mode: true
+
+
+# Check results
+
+- name: "stat foobarrc (must exist)"
+ stat:
+ path: "{{ foobarrc }}"
+ register: diversion_4
+
+- name: "stat foobarrc.distrib (must not exist)"
+ stat:
+ path: "{{ foobarrc_distrib }}"
+ register: diversion_5
+
+- name: "assert that results of test 06 are as expected"
+ assert:
+ that:
+ - diversion_0 is changed
+ - diversion_1 is changed
+ - diversion_2 is not changed
+ - diversion_3 is not changed
+ - diversion_4.stat.exists
+ - diversion_4.stat.checksum == foobarrc_oldsha1
+ - not diversion_5.stat.exists
+ - diversion_0.diversion == diversion_1.diversion
+ - diversion_2.diversion == diversion_3.diversion
+ - diversion_0.commands == diversion_1.commands
+ - diversion_2.commands == diversion_3.commands
+ quiet: true
+
+
+################################################################################
+# TEST 07: rename=yes, force=yes, state=present
+
+- name: "create foobarrc.distrib for tests"
+ copy:
+ dest: "{{ foobarrc_distrib }}"
+ content: "{{ foobarrc_oldtext }}"
+
+
+- name: "create diversion for foobarrc (check mode, rename, must fail)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ rename: true
+ register: diversion_0
+ ignore_errors: true
+ check_mode: true
+
+- name: "create diversion for foobarrc (rename, must fail)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ rename: true
+ register: diversion_1
+ ignore_errors: true
+
+
+- name: "create diversion for foobarrc (check mode, force rename, must report a change)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ rename: true
+ force: true
+ register: diversion_2
+ check_mode: true
+
+- name: "create diversion for foobarrc (force rename, must report a change)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ rename: true
+ force: true
+ register: diversion_3
+
+
+- name: "create diversion for foobarrc (force rename, must NOT report a change, idempotency)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ rename: true
+ force: true
+ register: diversion_4
+
+- name: "create diversion for foobarrc (check mode, force rename, must NOT report a change, idempotency)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ rename: true
+ force: true
+ register: diversion_5
+ check_mode: true
+
+
+# Check results
+
+- name: "stat foobarrc (must not exist)"
+ stat:
+ path: "{{ foobarrc }}"
+ register: diversion_6
+
+- name: "stat foobarrc.distrib (must exist)"
+ stat:
+ path: "{{ foobarrc_distrib }}"
+ register: diversion_7
+
+- name: "assert that results of test 07 are as expected"
+ assert:
+ that:
+ - diversion_0 is failed
+ - diversion_1 is failed
+ - diversion_2 is changed
+ - diversion_3 is changed
+ - diversion_4 is not changed
+ - diversion_5 is not changed
+ - not diversion_6.stat.exists
+ - diversion_7.stat.exists
+ - diversion_7.stat.checksum == foobarrc_oldsha1
+ - diversion_0 == diversion_1
+ - diversion_2.diversion == diversion_3.diversion
+ - diversion_4.diversion == diversion_5.diversion
+ - diversion_2.commands == diversion_3.commands
+ - diversion_4.commands == diversion_5.commands
+ quiet: true
+
+
+################################################################################
+# TEST 08: state=present, update an existing divert path
+
+- name: "create foobarrc with new contents for tests"
+ copy:
+ dest: "{{ foobarrc }}"
+ content: "{{ foobarrc_newtext }}"
+
+
+- name: "create diversion for foobarrc (check mode, update divert path, must report a change)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ divert: "{{ foobarrc_ansible }}"
+ register: diversion_0
+ check_mode: true
+
+- name: "create diversion for foobarrc (update divert path, must report a change)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ divert: "{{ foobarrc_ansible }}"
+ register: diversion_1
+
+
+- name: "create diversion for foobarrc (update divert path, must NOT report a change, idempotency)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ divert: "{{ foobarrc_ansible }}"
+ register: diversion_2
+
+- name: "create diversion for foobarrc (check mode, update divert path, must NOT report a change, idempotency)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ divert: "{{ foobarrc_ansible }}"
+ register: diversion_3
+ check_mode: true
+
+
+# Check results
+
+- name: "stat foobarrc (must exist)"
+ stat:
+ path: "{{ foobarrc }}"
+ register: diversion_4
+
+- name: "stat foobarrc.ansible (must exist)"
+ stat:
+ path: "{{ foobarrc_ansible }}"
+ register: diversion_5
+
+- name: "stat foobarrc.distrib (must not exist)"
+ stat:
+ path: "{{ foobarrc_distrib }}"
+ register: diversion_6
+
+- name: "assert that results of test 08 are as expected"
+ assert:
+ that:
+ - diversion_0 is changed
+ - diversion_1 is changed
+ - diversion_2 is not changed
+ - diversion_3 is not changed
+ - diversion_4.stat.exists
+ - diversion_4.stat.checksum == foobarrc_newsha1
+ - diversion_5.stat.exists
+ - diversion_5.stat.checksum == foobarrc_oldsha1
+ - not diversion_6.stat.exists
+ - diversion_0.diversion == diversion_1.diversion
+ - diversion_2.diversion == diversion_3.diversion
+ - diversion_0.commands == diversion_1.commands
+ - diversion_2.commands == diversion_3.commands
+ quiet: true
+
+
+################################################################################
+# TEST 09: rename=yes, force=yes, state=absent
+
+- name: "remove diversion for foobarrc (check mode, rename, must fail)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ state: absent
+ rename: true
+ register: diversion_0
+ ignore_errors: true
+ check_mode: true
+
+- name: "remove diversion for foobarrc (rename, must fail)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ state: absent
+ rename: true
+ register: diversion_1
+ ignore_errors: true
+
+
+- name: "remove diversion for foobarrc (check mode, force rename, must report a change)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ state: absent
+ rename: true
+ force: true
+ register: diversion_2
+ check_mode: true
+
+- name: "remove diversion for foobarrc (force rename, must report a change)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ state: absent
+ rename: true
+ force: true
+ register: diversion_3
+
+
+- name: "remove diversion for foobarrc (force rename, must NOT report a change, idempotency)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ state: absent
+ rename: true
+ force: true
+ register: diversion_4
+
+- name: "remove diversion for foobarrc (check mode, force rename, must NOT report a change, idempotency)"
+ dpkg_divert:
+ path: "{{ foobarrc }}"
+ state: absent
+ rename: true
+ force: true
+ register: diversion_5
+ check_mode: true
+
+
+# Check results
+
+- name: "stat foobarrc (must exist)"
+ stat:
+ path: "{{ foobarrc }}"
+ register: diversion_6
+
+- name: "stat foobarrc.distrib (must not exist)"
+ stat:
+ path: "{{ foobarrc_distrib }}"
+ register: diversion_7
+
+- name: "stat foobarrc.ansible (must not exist)"
+ stat:
+ path: "{{ foobarrc_ansible }}"
+ register: diversion_8
+
+- name: "assert that results of test 09 are as expected"
+ assert:
+ that:
+ - diversion_0 is failed
+ - diversion_1 is failed
+ - diversion_2 is changed
+ - diversion_3 is changed
+ - diversion_4 is not changed
+ - diversion_5 is not changed
+ - diversion_6.stat.exists
+ - diversion_6.stat.checksum == foobarrc_oldsha1
+ - not diversion_7.stat.exists
+ - not diversion_8.stat.exists
+ - diversion_0 == diversion_1
+ - diversion_2.diversion == diversion_3.diversion
+ - diversion_4.diversion == diversion_5.diversion
+ - diversion_2.commands == diversion_3.commands
+ - diversion_4.commands == diversion_5.commands
+ quiet: true
diff --git a/ansible_collections/community/general/tests/integration/targets/etcd3/aliases b/ansible_collections/community/general/tests/integration/targets/etcd3/aliases
new file mode 100644
index 000000000..264446580
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/etcd3/aliases
@@ -0,0 +1,12 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+destructive
+skip/aix
+skip/osx
+skip/macos
+skip/freebsd
+skip/python2.6 # installing etcd3 python module will fail on python < 2.7
+disabled # see https://github.com/ansible-collections/community.general/issues/322
diff --git a/ansible_collections/community/general/tests/integration/targets/etcd3/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/etcd3/meta/main.yml
new file mode 100644
index 000000000..f922f5506
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/etcd3/meta/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
+ - setup_etcd3
diff --git a/ansible_collections/community/general/tests/integration/targets/etcd3/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/etcd3/tasks/main.yml
new file mode 100644
index 000000000..2fe7435dc
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/etcd3/tasks/main.yml
@@ -0,0 +1,18 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# test code for the etcd3 module
+# Copyright (c) 2017, Jean-Philippe Evrard <jean-philippe@evrard.me>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# ============================================================
+
+
+- name: run_tests for supported distros
+ include_tasks: run_tests.yml
+ when:
+ - ansible_distribution | lower ~ "-" ~ ansible_distribution_major_version | lower != 'centos-6'
diff --git a/ansible_collections/community/general/tests/integration/targets/etcd3/tasks/run_tests.yml b/ansible_collections/community/general/tests/integration/targets/etcd3/tasks/run_tests.yml
new file mode 100644
index 000000000..4bd8fa4ec
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/etcd3/tasks/run_tests.yml
@@ -0,0 +1,81 @@
+---
+# test code for the etcd3 module
+# Copyright (c) 2017, Jean-Philippe Evrard <jean-philippe@evrard.me>
+# Copyright 2020, SCC France, Eric Belhomme <ebelhomme@fr.scc.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# ============================================================
+
+# Integration tests
+- name: Check mode, show need change
+ etcd3:
+ key: "foo"
+ value: "bar"
+ state: "present"
+ register: _etcd3_prst_chktst
+ check_mode: true
+
+- name: Change to new value
+ etcd3:
+ key: "foo"
+ value: "bar"
+ state: "present"
+ register: _etcd3_prst_chgtst
+
+- name: Idempotency test, show unchanged.
+ etcd3:
+ key: "foo"
+ value: "bar"
+ state: "present"
+ register: _etcd3_prst_idmptnttst
+
+- name: Idempotency test in check mode, show unchanged
+ etcd3:
+ key: "foo"
+ value: "bar"
+ state: "present"
+ register: _etcd3_prst_idmptntchktst
+ check_mode: true
+
+- name: Check mode, show need removal of key
+ etcd3:
+ key: "foo"
+ value: "baz"
+ state: "absent"
+ register: _etcd3_absnt_chktst
+ check_mode: true
+
+- name: Remove foo key
+ etcd3:
+ key: "foo"
+ value: "baz"
+ state: "absent"
+ register: _etcd3_absnt_chgtst
+
+- name: Idempotency test in check mode, show unchanged
+ etcd3:
+ key: "foo"
+ value: "baz"
+ state: "absent"
+ register: _etcd3_absnt_idmptnttst
+ check_mode: true
+
+- name: Idempotency test, show unchanged
+ etcd3:
+ key: "foo"
+ value: "baz"
+ state: "absent"
+ register: _etcd3_absnt_idmptntchktst
+
+- name: Checking the status are expected
+ assert:
+ that:
+ - _etcd3_prst_chktst is changed
+ - _etcd3_prst_chgtst is changed
+ - _etcd3_prst_idmptnttst is not changed
+ - _etcd3_prst_idmptntchktst is not changed
+ - _etcd3_absnt_chktst is changed
+ - _etcd3_absnt_chgtst is changed
+ - _etcd3_absnt_idmptnttst is not changed
+ - _etcd3_absnt_idmptntchktst is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/filesize/aliases b/ansible_collections/community/general/tests/integration/targets/filesize/aliases
new file mode 100644
index 000000000..7642e70da
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filesize/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+azp/posix/vm
diff --git a/ansible_collections/community/general/tests/integration/targets/filesize/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/filesize/defaults/main.yml
new file mode 100644
index 000000000..d51108276
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filesize/defaults/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+filesize_testdir: "/tmp/testdir"
+filesize_testfile: "{{ filesize_testdir }}/testfile"
+filesize_testlink: "{{ filesize_testdir }}/testlink"
diff --git a/ansible_collections/community/general/tests/integration/targets/filesize/tasks/basics.yml b/ansible_collections/community/general/tests/integration/targets/filesize/tasks/basics.yml
new file mode 100644
index 000000000..3c0673189
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filesize/tasks/basics.yml
@@ -0,0 +1,411 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Test module with basic parameters.
+# Create a file, grow it, reduce it to its initial size and check the match
+# between initial and final checksums. Also check size formats consistency
+# (as 57001B == 57001 B == 57.001 kB, for example, or 0 block or 0 unit is
+# zero, etc).
+
+- name: Create an empty file (check mode)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 0
+ register: filesize_test_basic_01
+ check_mode: true
+
+- name: Stat the file (should not exist)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ register: filesize_stat_basic_01
+
+
+- name: Create an empty file
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 0
+ register: filesize_test_basic_02
+
+- name: Stat the file (should exist now)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ register: filesize_stat_basic_02
+
+
+- name: Create an empty file (check mode, idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 0G
+ register: filesize_test_basic_03
+ check_mode: true
+
+- name: Create an empty file (idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 0G
+ register: filesize_test_basic_04
+
+- name: Stat the file (should still exist, unchanged)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ register: filesize_stat_basic_04
+
+
+- name: Assert that results are as expected
+ ansible.builtin.assert:
+ that:
+ # check_mode & idempotency are in good shape.
+ - filesize_test_basic_01 is changed
+ - filesize_test_basic_02 is changed
+ - filesize_test_basic_03 is not changed
+ - filesize_test_basic_04 is not changed
+
+ # check_mode returns the same command than actual mode.
+ - filesize_test_basic_02.cmd == filesize_test_basic_01.cmd
+ - filesize_test_basic_03.cmd is undefined
+ - filesize_test_basic_04.cmd is undefined
+
+ # Module's specific return results are consistent with user input, that
+ # means: with *expected* results.
+ - filesize_test_basic_01.filesize.bytes == 0
+ - filesize_test_basic_02.filesize.bytes == 0
+ - filesize_test_basic_03.filesize.bytes == 0
+ - filesize_test_basic_04.filesize.bytes == 0
+
+ - filesize_test_basic_01.size_diff == 0
+ - filesize_test_basic_02.size_diff == 0
+ - filesize_test_basic_03.size_diff == 0
+ - filesize_test_basic_04.size_diff == 0
+
+ # Results populated by module.set_fs_attributes_if_different() are still
+ # consistent with current state of the file.
+ - filesize_test_basic_01.state is undefined
+ - filesize_test_basic_02.state in ["file"]
+ - filesize_test_basic_01.size is undefined
+ - filesize_test_basic_02.size == 0
+ - filesize_test_basic_03.size == 0
+ - filesize_test_basic_04.size == 0
+
+ # Cross results with those retrieved by another module.
+ - not filesize_stat_basic_01.stat.exists
+ - filesize_stat_basic_02.stat.exists
+ - filesize_stat_basic_02.stat.isreg
+ - filesize_stat_basic_02.stat.size == 0
+ - filesize_stat_basic_04.stat.size == 0
+
+
+- name: Fill the file up to 57kB (57000B) with random data (check mode)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 57kB
+ source: /dev/urandom
+ register: filesize_test_basic_11
+ check_mode: true
+
+- name: Stat the file (should still be unchanged)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ register: filesize_stat_basic_11
+
+
+- name: Fill the file up to 57kB (57000B) with random data
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 57kB
+ source: /dev/urandom
+ register: filesize_test_basic_12
+
+- name: Stat the resulting file (and get its checksum)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ register: filesize_stat_basic_12
+
+- name: Store checksum as fact
+ ansible.builtin.set_fact:
+ filesize_test_checksum: "{{ filesize_stat_basic_12.stat.checksum }}"
+
+
+- name: Fill the file up to 57000B (57kB) with random data (check mode, idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 57000B
+ source: /dev/urandom
+ register: filesize_test_basic_13
+ check_mode: true
+
+- name: Fill the file up to 57000B (57kB) with random data (idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 57000B
+ source: /dev/urandom
+ register: filesize_test_basic_14
+
+- name: Stat the file again (should remain the same)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ register: filesize_stat_basic_14
+
+
+- name: Assert that results are as expected
+ ansible.builtin.assert:
+ that:
+ - filesize_test_basic_11 is changed
+ - filesize_test_basic_12 is changed
+ - filesize_test_basic_13 is not changed
+ - filesize_test_basic_14 is not changed
+
+ - filesize_test_basic_12.cmd == filesize_test_basic_11.cmd
+ - filesize_test_basic_13.cmd is undefined
+ - filesize_test_basic_14.cmd is undefined
+
+ - filesize_test_basic_11.filesize.bytes == 57000
+ - filesize_test_basic_12.filesize.bytes == 57000
+ - filesize_test_basic_13.filesize.bytes == 57000
+ - filesize_test_basic_14.filesize.bytes == 57000
+
+ - filesize_test_basic_11.size_diff == 57000
+ - filesize_test_basic_12.size_diff == 57000
+ - filesize_test_basic_13.size_diff == 0
+ - filesize_test_basic_14.size_diff == 0
+
+ - filesize_stat_basic_11.stat.size == 0
+ - filesize_stat_basic_12.stat.size == 57000
+ - filesize_stat_basic_14.stat.size == 57000
+
+ - filesize_stat_basic_14.stat.checksum == filesize_test_checksum
+
+
+
+- name: Expand the file with 1 byte (57001B) (check mode)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 57001B
+ register: filesize_test_basic_21
+ check_mode: true
+
+- name: Stat the file again (should remain the same)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ register: filesize_stat_basic_21
+
+
+- name: Expand the file with 1 byte (57001B)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 57001B
+ register: filesize_test_basic_22
+
+- name: Stat the file (should have grown of 1 byte)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ register: filesize_stat_basic_22
+
+
+- name: Expand the file with 1 byte (57.001 kB) (check mode, idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 57.001 kB
+ register: filesize_test_basic_23
+ check_mode: true
+
+- name: Expand the file with 1 byte (57.001 kB) (idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 57.001 kB
+ register: filesize_test_basic_24
+
+- name: Stat the file again (should remain the same)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ register: filesize_stat_basic_24
+
+
+- name: Assert that results are as expected
+ ansible.builtin.assert:
+ that:
+ - filesize_test_basic_21 is changed
+ - filesize_test_basic_22 is changed
+ - filesize_test_basic_23 is not changed
+ - filesize_test_basic_24 is not changed
+
+ - filesize_test_basic_22.cmd == filesize_test_basic_21.cmd
+ - filesize_test_basic_23.cmd is undefined
+ - filesize_test_basic_24.cmd is undefined
+
+ - filesize_test_basic_21.filesize.bytes == 57001
+ - filesize_test_basic_22.filesize.bytes == 57001
+ - filesize_test_basic_23.filesize.bytes == 57001
+ - filesize_test_basic_24.filesize.bytes == 57001
+
+ - filesize_test_basic_21.size_diff == 1
+ - filesize_test_basic_22.size_diff == 1
+ - filesize_test_basic_23.size_diff == 0
+ - filesize_test_basic_24.size_diff == 0
+
+ - filesize_stat_basic_21.stat.size == 57000
+ - filesize_stat_basic_22.stat.size == 57001
+ - filesize_stat_basic_24.stat.size == 57001
+
+ - filesize_stat_basic_21.stat.checksum == filesize_test_checksum
+ - filesize_stat_basic_22.stat.checksum != filesize_test_checksum
+ - filesize_stat_basic_24.stat.checksum != filesize_test_checksum
+
+
+
+- name: Expand the file up to 2 MiB (2*1024*1024 bytes) (check mode)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 2 MiB
+ register: filesize_test_basic_31
+ check_mode: true
+
+- name: Stat the file again (should remain the same)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ register: filesize_stat_basic_31
+
+
+- name: Expand the file up to 2 MiB (2*1024*1024 bytes)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 2 MiB
+ register: filesize_test_basic_32
+
+- name: Stat the file again (should have grown to 2MiB)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ register: filesize_stat_basic_32
+
+
+- name: Expand the file up to 2×1M (2*1024*1024 bytes) (check mode, idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 2
+ blocksize: 1M
+ register: filesize_test_basic_33
+ check_mode: true
+
+- name: Expand the file up to 2×1M (2*1024*1024 bytes) (idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 2
+ blocksize: 1M
+ register: filesize_test_basic_34
+
+- name: Stat the file again (should remain the same)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ register: filesize_stat_basic_34
+
+
+- name: Assert that results are as expected
+ ansible.builtin.assert:
+ that:
+ - filesize_test_basic_31 is changed
+ - filesize_test_basic_32 is changed
+ - filesize_test_basic_33 is not changed
+ - filesize_test_basic_34 is not changed
+
+ - filesize_test_basic_32.cmd == filesize_test_basic_31.cmd
+ - filesize_test_basic_33.cmd is undefined
+ - filesize_test_basic_34.cmd is undefined
+
+ - filesize_test_basic_31.filesize.bytes == 2*1024**2
+ - filesize_test_basic_32.filesize.bytes == 2*1024**2
+ - filesize_test_basic_33.filesize.bytes == 2*1024**2
+ - filesize_test_basic_34.filesize.bytes == 2*1024**2
+
+ - filesize_test_basic_31.size_diff == 2*1024**2 - 57001
+ - filesize_test_basic_32.size_diff == 2*1024**2 - 57001
+ - filesize_test_basic_33.size_diff == 0
+ - filesize_test_basic_34.size_diff == 0
+
+ - filesize_stat_basic_31.stat.size == 57001
+ - filesize_stat_basic_32.stat.size == 2*1024**2
+ - filesize_stat_basic_34.stat.size == 2*1024**2
+
+
+
+- name: Truncate the file to 57kB (57000B) (check mode)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 57kB
+ register: filesize_test_basic_41
+ check_mode: true
+
+- name: Stat the resulting file (should be unchanged)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ register: filesize_stat_basic_41
+
+
+- name: Truncate the file to 57kB (57000B)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 57kB
+ register: filesize_test_basic_42
+
+- name: Stat the resulting file (and get its checksum)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ register: filesize_stat_basic_42
+
+
+- name: Truncate the file to 57000 B (57kB) (check mode, idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 57000 B
+ register: filesize_test_basic_43
+ check_mode: true
+
+- name: Truncate the file to 57000 B (57kB) (idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 57000 B
+ register: filesize_test_basic_44
+
+- name: Stat the file again (should remain the same)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ register: filesize_stat_basic_44
+
+
+- name: Assert that results are as expected
+ ansible.builtin.assert:
+ that:
+ - filesize_test_basic_41 is changed
+ - filesize_test_basic_42 is changed
+ - filesize_test_basic_43 is not changed
+ - filesize_test_basic_44 is not changed
+
+ - filesize_test_basic_42.cmd == filesize_test_basic_41.cmd
+ - filesize_test_basic_43.cmd is undefined
+ - filesize_test_basic_44.cmd is undefined
+
+ - filesize_test_basic_41.filesize.bytes == 57000
+ - filesize_test_basic_42.filesize.bytes == 57000
+ - filesize_test_basic_43.filesize.bytes == 57000
+ - filesize_test_basic_44.filesize.bytes == 57000
+
+ - filesize_test_basic_41.size_diff == 57000 - 2*1024**2
+ - filesize_test_basic_42.size_diff == 57000 - 2*1024**2
+ - filesize_test_basic_43.size_diff == 0
+ - filesize_test_basic_44.size_diff == 0
+
+ - filesize_stat_basic_41.stat.size == 2*1024**2
+ - filesize_stat_basic_42.stat.size == 57000
+ - filesize_stat_basic_44.stat.size == 57000
+
+ # The original random file is back.
+ - filesize_stat_basic_41.stat.checksum != filesize_test_checksum
+ - filesize_stat_basic_42.stat.checksum == filesize_test_checksum
+ - filesize_stat_basic_44.stat.checksum == filesize_test_checksum
+
+
+
+- name: Remove test file
+ ansible.builtin.file:
+ path: "{{ filesize_testfile }}"
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/filesize/tasks/errors.yml b/ansible_collections/community/general/tests/integration/targets/filesize/tasks/errors.yml
new file mode 100644
index 000000000..351a90ac6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filesize/tasks/errors.yml
@@ -0,0 +1,133 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Check error handling of the module.
+# 1. Missing or unknown parameters
+# 2. Wrong values (missing source device, invalid size...)
+
+- name: Trigger an error due to missing parameter (path)
+ community.general.filesize:
+ size: 1kB
+ register: filesize_test_error_01
+ ignore_errors: true
+
+
+- name: Trigger an error due to missing parameter (size)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ register: filesize_test_error_02
+ ignore_errors: true
+
+
+- name: Trigger an error due to conflicting parameters (force|sparse)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 1MB
+ force: true
+ sparse: true
+ register: filesize_test_error_03
+ ignore_errors: true
+
+
+- name: Trigger an error due to invalid file path (not a file)
+ community.general.filesize:
+ path: "{{ filesize_testdir }}"
+ size: 4096B
+ register: filesize_test_error_04
+ ignore_errors: true
+
+
+- name: Trigger an error due to invalid file path (unexisting parent dir)
+ community.general.filesize:
+ path: "/unexistent/{{ filesize_testfile }}"
+ size: 4096B
+ register: filesize_test_error_05
+ ignore_errors: true
+
+
+- name: Trigger an error due to invalid size unit (b)"
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 4096b
+ register: filesize_test_error_06
+ ignore_errors: true
+
+
+- name: Trigger an error due to invalid size value (bytes require integer)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 1000.5B
+ register: filesize_test_error_07
+ ignore_errors: true
+
+
+- name: Trigger an error due to invalid blocksize value (not an integer)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 1M
+ blocksize: "12.5"
+ register: filesize_test_error_08
+ ignore_errors: true
+
+
+- name: Trigger an error due to invalid blocksize value type (dict)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 1M
+ blocksize:
+ bytes: 512
+ register: filesize_test_error_09
+ ignore_errors: true
+
+
+- name: Trigger an error due to invalid source device (/dev/unexistent)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 1M
+ source: /dev/unexistent
+ register: filesize_test_error_10
+ ignore_errors: true
+
+
+- name: Trigger an error due to invalid source device (/dev/null)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 1M
+ source: /dev/null
+ register: filesize_test_error_11
+ ignore_errors: true
+
+
+- name: Assert that expected errors have been triggered
+ ansible.builtin.assert:
+ that:
+ - "filesize_test_error_01 is failed"
+ - "filesize_test_error_01.msg == 'missing required arguments: path'"
+ - "filesize_test_error_02 is failed"
+ - "filesize_test_error_02.msg == 'missing required arguments: size'"
+ - "filesize_test_error_03 is failed"
+ - "filesize_test_error_03.msg == 'parameters values are mutually exclusive: force=true|sparse=true'"
+ - "filesize_test_error_04 is failed"
+ - "filesize_test_error_04.msg == '%s exists but is not a regular file' % filesize_testdir"
+ - "filesize_test_error_05 is failed"
+ - "filesize_test_error_05.msg == 'parent directory of the file must exist prior to run this module'"
+ - "filesize_test_error_06 is failed"
+ - "filesize_test_error_06.msg is match('invalid size unit')"
+ - "filesize_test_error_07 is failed"
+ - "filesize_test_error_07.msg == 'byte is the smallest unit and requires an integer value'"
+ - "filesize_test_error_08 is failed"
+ - "filesize_test_error_08.msg == 'invalid blocksize value: bytes require an integer value'"
+ - "filesize_test_error_09 is failed"
+ - "filesize_test_error_09.msg is match('invalid value type')"
+ - "filesize_test_error_10 is failed"
+ - "filesize_test_error_10.msg == 'dd error while creating file %s with size 1M from source /dev/unexistent: see stderr for details' % filesize_testfile"
+ - "filesize_test_error_11 is failed"
+ - "filesize_test_error_11.msg == 'module error while creating file %s with size 1M from source /dev/null: file is 0 bytes long' % filesize_testfile"
+
+
+- name: Remove test file
+ ansible.builtin.file:
+ path: "{{ filesize_testfile }}"
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/filesize/tasks/floats.yml b/ansible_collections/community/general/tests/integration/targets/filesize/tasks/floats.yml
new file mode 100644
index 000000000..6d1bde22c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filesize/tasks/floats.yml
@@ -0,0 +1,249 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Test module with floating point numbers (ensure they're not rounded too
+# wrongly), since in python floats are tricky:
+# 256.256 * 1000 == 256255.9999999997
+# 512.512 * 1000 == 512511.9999999994
+# 512.513 * 1000 == 512513.0000000006 != .512513 * 1000000
+
+- name: Create a file with a size of 512.512kB (check mode)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 512.512kB
+ register: filesize_test_float_01
+ check_mode: true
+
+- name: Stat the file (should not exist)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ register: filesize_stat_float_01
+
+
+- name: Create a file with a size of 512.512kB
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 512.512kB
+ register: filesize_test_float_02
+
+- name: Stat the file (should exist now)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ register: filesize_stat_float_02
+
+
+- name: Create a file with a size of 0.512512MB (check mode, idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 0.512512MB
+ register: filesize_test_float_03
+ check_mode: true
+
+- name: Create a file with a size of 0.512512MB (idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 0.512512MB
+ register: filesize_test_float_04
+
+- name: Stat the file (should still exist, unchanged)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ register: filesize_stat_float_04
+
+
+- name: Assert that results are as expected
+ ansible.builtin.assert:
+ that:
+ - filesize_test_float_01 is changed
+ - filesize_test_float_02 is changed
+ - filesize_test_float_03 is not changed
+ - filesize_test_float_04 is not changed
+
+ - filesize_test_float_02.cmd == filesize_test_float_01.cmd
+ - filesize_test_float_03.cmd is undefined
+ - filesize_test_float_04.cmd is undefined
+
+ - filesize_test_float_01.filesize.bytes == 512512
+ - filesize_test_float_02.filesize.bytes == 512512
+ - filesize_test_float_03.filesize.bytes == 512512
+ - filesize_test_float_04.filesize.bytes == 512512
+
+ - filesize_test_float_01.size_diff == 512512
+ - filesize_test_float_02.size_diff == 512512
+ - filesize_test_float_03.size_diff == 0
+ - filesize_test_float_04.size_diff == 0
+
+ - filesize_test_float_01.state is undefined
+ - filesize_test_float_02.state in ["file"]
+ - filesize_test_float_01.size is undefined
+ - filesize_test_float_02.size == 512512
+ - filesize_test_float_03.size == 512512
+ - filesize_test_float_04.size == 512512
+
+ - not filesize_stat_float_01.stat.exists
+ - filesize_stat_float_02.stat.exists
+ - filesize_stat_float_02.stat.isreg
+ - filesize_stat_float_02.stat.size == 512512
+ - filesize_stat_float_04.stat.size == 512512
+
+
+
+- name: Create a file with a size of 512.513kB (check mode)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 512.513kB
+ register: filesize_test_float_11
+ check_mode: true
+
+- name: Stat the file again (should remain the same)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ register: filesize_stat_float_11
+
+
+- name: Create a file with a size of 512.513kB
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 512.513kB
+ register: filesize_test_float_12
+
+- name: Stat the file (should have grown of 1 byte)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ register: filesize_stat_float_12
+
+
+- name: Create a file with a size of 0.512513MB (check mode, idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 0.512513MB
+ register: filesize_test_float_13
+ check_mode: true
+
+- name: Create a file with a size of 0.512513MB (idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 0.512513MB
+ register: filesize_test_float_14
+
+- name: Stat the file again (should remain the same)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ register: filesize_stat_float_14
+
+
+- name: Assert that results are as expected
+ ansible.builtin.assert:
+ that:
+ - filesize_test_float_11 is changed
+ - filesize_test_float_12 is changed
+ - filesize_test_float_13 is not changed
+ - filesize_test_float_14 is not changed
+
+ - filesize_test_float_12.cmd == filesize_test_float_11.cmd
+ - filesize_test_float_13.cmd is undefined
+ - filesize_test_float_14.cmd is undefined
+
+ - filesize_test_float_11.filesize.bytes == 512513
+ - filesize_test_float_12.filesize.bytes == 512513
+ - filesize_test_float_13.filesize.bytes == 512513
+ - filesize_test_float_14.filesize.bytes == 512513
+
+ - filesize_test_float_11.size_diff == 1
+ - filesize_test_float_12.size_diff == 1
+ - filesize_test_float_13.size_diff == 0
+ - filesize_test_float_14.size_diff == 0
+
+ - filesize_test_float_11.size == 512512
+ - filesize_test_float_12.size == 512513
+ - filesize_test_float_13.size == 512513
+ - filesize_test_float_14.size == 512513
+
+ - filesize_stat_float_11.stat.size == 512512
+ - filesize_stat_float_12.stat.size == 512513
+ - filesize_stat_float_14.stat.size == 512513
+
+
+
+- name: Create a file with a size of 4.004MB (check mode)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 4.004MB
+ register: filesize_test_float_21
+ check_mode: true
+
+- name: Stat the file again (should remain the same)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ register: filesize_stat_float_21
+
+
+- name: Create a file with a size of 4.004MB
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 4.004MB
+ register: filesize_test_float_22
+
+- name: Stat the file (should have grown to 4.004MB)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ register: filesize_stat_float_22
+
+
+- name: Create a file with a size of 4.004MB (check mode, idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 4.004MB
+ register: filesize_test_float_23
+ check_mode: true
+
+- name: Create a file with a size of 4.004MB (idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 4.004MB
+ register: filesize_test_float_24
+
+- name: Stat the file again (should remain the same)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ register: filesize_stat_float_24
+
+
+- name: Assert that results are as expected
+ ansible.builtin.assert:
+ that:
+ - filesize_test_float_21 is changed
+ - filesize_test_float_22 is changed
+ - filesize_test_float_23 is not changed
+ - filesize_test_float_24 is not changed
+
+ - filesize_test_float_22.cmd == filesize_test_float_21.cmd
+ - filesize_test_float_23.cmd is undefined
+ - filesize_test_float_24.cmd is undefined
+
+ - filesize_test_float_21.filesize.bytes == 4004000
+ - filesize_test_float_22.filesize.bytes == 4004000
+ - filesize_test_float_23.filesize.bytes == 4004000
+ - filesize_test_float_24.filesize.bytes == 4004000
+
+ - filesize_test_float_21.size_diff == 4004000 - 512513
+ - filesize_test_float_22.size_diff == 4004000 - 512513
+ - filesize_test_float_23.size_diff == 0
+ - filesize_test_float_24.size_diff == 0
+
+ - filesize_test_float_21.size == 512513
+ - filesize_test_float_22.size == 4004000
+ - filesize_test_float_23.size == 4004000
+ - filesize_test_float_24.size == 4004000
+
+ - filesize_stat_float_21.stat.size == 512513
+ - filesize_stat_float_22.stat.size == 4004000
+ - filesize_stat_float_24.stat.size == 4004000
+
+
+- name: Remove test file
+ ansible.builtin.file:
+ path: "{{ filesize_testfile }}"
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/filesize/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/filesize/tasks/main.yml
new file mode 100644
index 000000000..68cd8934c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filesize/tasks/main.yml
@@ -0,0 +1,44 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Ensure the test dir is present
+ ansible.builtin.file:
+ path: "{{ filesize_testdir }}"
+ state: directory
+
+- name: Ensure the test file is absent
+ ansible.builtin.file:
+ path: "{{ filesize_testfile }}"
+ state: absent
+
+- name: Run all tests and remove the workspace anyway
+ block:
+ - name: Include tasks to test error handling
+ include_tasks: errors.yml
+
+ - name: Include tasks to test basic behaviours
+ include_tasks: basics.yml
+
+ - name: Include tasks to test playing with floating point numbers
+ include_tasks: floats.yml
+
+ - name: Include tasks to test playing with sparse files
+ include_tasks: sparse.yml
+ when:
+ - not (ansible_os_family == 'Darwin' and ansible_distribution_version is version('11', '<'))
+
+ - name: Include tasks to test playing with symlinks
+ include_tasks: symlinks.yml
+
+ always:
+ - name: Remove test dir
+ ansible.builtin.file:
+ path: "{{ filesize_testdir }}"
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/filesize/tasks/sparse.yml b/ansible_collections/community/general/tests/integration/targets/filesize/tasks/sparse.yml
new file mode 100644
index 000000000..79145b6e2
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filesize/tasks/sparse.yml
@@ -0,0 +1,286 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Test module with sparse files
+
+- name: Create a huge sparse file of 4TB (check mode)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 4TB
+ sparse: true
+ register: filesize_test_sparse_01
+ check_mode: true
+
+- name: Stat the file (should not exist)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ get_checksum: false
+ register: filesize_stat_sparse_01
+
+
+- name: Create a huge sparse file of 4TB
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 4TB
+ sparse: true
+ register: filesize_test_sparse_02
+
+- name: Stat the resulting file (should exist now)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ get_checksum: false
+ register: filesize_stat_sparse_02
+
+
+- name: Create a huge sparse file of 4TB (4000GB) (check mode, idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 4000GB
+ sparse: true
+ register: filesize_test_sparse_03
+ check_mode: true
+
+- name: Create a huge sparse file of 4TB (4000GB) (idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 4000GB
+ sparse: true
+ register: filesize_test_sparse_04
+
+- name: Create a huge sparse file of 4TB (4000000 × 1MB) (check mode, idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 4000000
+ blocksize: 1MB
+ sparse: true
+ register: filesize_test_sparse_05
+ check_mode: true
+
+- name: Create a huge sparse file of 4TB (4000000 × 1MB) (idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 4000000
+ blocksize: 1MB
+ sparse: true
+ register: filesize_test_sparse_06
+
+- name: Stat the file again (should remain the same)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ get_checksum: false
+ register: filesize_stat_sparse_06
+
+
+- name: Assert that results are as expected
+ ansible.builtin.assert:
+ that:
+ - filesize_test_sparse_01 is changed
+ - filesize_test_sparse_02 is changed
+ - filesize_test_sparse_03 is not changed
+ - filesize_test_sparse_04 is not changed
+ - filesize_test_sparse_05 is not changed
+ - filesize_test_sparse_06 is not changed
+
+ - filesize_test_sparse_02.cmd == filesize_test_sparse_01.cmd
+ - filesize_test_sparse_03.cmd is undefined
+ - filesize_test_sparse_04.cmd is undefined
+ - filesize_test_sparse_05.cmd is undefined
+ - filesize_test_sparse_06.cmd is undefined
+
+ - filesize_test_sparse_01.filesize.bytes == 4*1000**4
+ - filesize_test_sparse_02.filesize.bytes == 4*1000**4
+ - filesize_test_sparse_03.filesize.bytes == 4*1000**4
+ - filesize_test_sparse_04.filesize.bytes == 4*1000**4
+ - filesize_test_sparse_05.filesize.bytes == 4*1000**4
+ - filesize_test_sparse_06.filesize.bytes == 4*1000**4
+
+ - filesize_test_sparse_01.size_diff == 4*1000**4
+ - filesize_test_sparse_02.size_diff == 4*1000**4
+ - filesize_test_sparse_03.size_diff == 0
+ - filesize_test_sparse_04.size_diff == 0
+ - filesize_test_sparse_05.size_diff == 0
+ - filesize_test_sparse_06.size_diff == 0
+
+ - filesize_test_sparse_01.state is undefined
+ - filesize_test_sparse_02.state in ["file"]
+ - filesize_test_sparse_01.size is undefined
+ - filesize_test_sparse_02.size == 4*1000**4
+ - filesize_test_sparse_03.size == 4*1000**4
+ - filesize_test_sparse_04.size == 4*1000**4
+ - filesize_test_sparse_05.size == 4*1000**4
+ - filesize_test_sparse_06.size == 4*1000**4
+
+ - not filesize_stat_sparse_01.stat.exists
+ - filesize_stat_sparse_02.stat.exists
+ - filesize_stat_sparse_02.stat.isreg
+ - filesize_stat_sparse_02.stat.size == 4*1000**4
+ - filesize_stat_sparse_06.stat.size == 4*1000**4
+
+
+
+- name: Change sparse file size to 4TiB (check mode)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 4TiB
+ sparse: true
+ register: filesize_test_sparse_11
+ check_mode: true
+
+- name: Stat the file again (should remain the same)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ get_checksum: false
+ register: filesize_stat_sparse_11
+
+
+- name: Change sparse file size to 4TiB
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 4TiB
+ sparse: true
+ register: filesize_test_sparse_12
+
+- name: Stat the file again (should have grown)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ get_checksum: false
+ register: filesize_stat_sparse_12
+
+
+- name: Change sparse file size to 4TiB (4096GiB) (check mode, idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 4096GiB
+ sparse: true
+ register: filesize_test_sparse_13
+ check_mode: true
+
+- name: Change sparse file size to 4TiB (4096GiB) (idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 4096GiB
+ sparse: true
+ register: filesize_test_sparse_14
+
+- name: Stat the file again (should remain the same)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ get_checksum: false
+ register: filesize_stat_sparse_14
+
+
+- name: Assert that results are as expected
+ ansible.builtin.assert:
+ that:
+ - filesize_test_sparse_11 is changed
+ - filesize_test_sparse_12 is changed
+ - filesize_test_sparse_13 is not changed
+ - filesize_test_sparse_14 is not changed
+
+ - filesize_test_sparse_12.cmd == filesize_test_sparse_11.cmd
+ - filesize_test_sparse_13.cmd is undefined
+ - filesize_test_sparse_14.cmd is undefined
+
+ - filesize_test_sparse_11.size_diff == 398046511104
+ - filesize_test_sparse_12.size_diff == 398046511104
+ - filesize_test_sparse_13.size_diff == 0
+ - filesize_test_sparse_14.size_diff == 0
+
+ - filesize_test_sparse_11.size == 4000000000000
+ - filesize_test_sparse_12.size == 4398046511104
+ - filesize_test_sparse_13.size == 4398046511104
+ - filesize_test_sparse_14.size == 4398046511104
+
+ - filesize_stat_sparse_11.stat.size == 4000000000000
+ - filesize_stat_sparse_12.stat.size == 4398046511104
+ - filesize_stat_sparse_14.stat.size == 4398046511104
+
+
+
+- name: Change sparse file size to 4.321TB (check mode)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 4.321TB
+ sparse: true
+ register: filesize_test_sparse_21
+ check_mode: true
+
+- name: Stat the file again (should remain the same)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ get_checksum: false
+ register: filesize_stat_sparse_21
+
+
+- name: Change sparse file size to 4.321TB
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 4.321TB
+ sparse: true
+ register: filesize_test_sparse_22
+
+- name: Stat the file again (should have been reduced)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ get_checksum: false
+ register: filesize_stat_sparse_22
+
+
+- name: Change sparse file size to 4321×1GB (check mode, idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 4321
+ blocksize: 1GB
+ sparse: true
+ register: filesize_test_sparse_23
+ check_mode: true
+
+- name: Change sparse file size to 4321×1GB (idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testfile }}"
+ size: 4321
+ blocksize: 1GB
+ sparse: true
+ register: filesize_test_sparse_24
+
+- name: Stat the file again (should remain the same)
+ ansible.builtin.stat:
+ path: "{{ filesize_testfile }}"
+ get_checksum: false
+ register: filesize_stat_sparse_24
+
+
+- name: Assert that results are as expected
+ ansible.builtin.assert:
+ that:
+ - filesize_test_sparse_21 is changed
+ - filesize_test_sparse_22 is changed
+ - filesize_test_sparse_23 is not changed
+ - filesize_test_sparse_24 is not changed
+
+ - filesize_test_sparse_22.cmd == filesize_test_sparse_21.cmd
+ - filesize_test_sparse_23.cmd is undefined
+ - filesize_test_sparse_24.cmd is undefined
+
+ - filesize_test_sparse_21.size_diff == 4321*1000**3 - 4*1024**4
+ - filesize_test_sparse_22.size_diff == 4321*1000**3 - 4*1024**4
+ - filesize_test_sparse_23.size_diff == 0
+ - filesize_test_sparse_24.size_diff == 0
+
+ - filesize_test_sparse_21.size == 4398046511104
+ - filesize_test_sparse_22.size == 4321000000000
+ - filesize_test_sparse_23.size == 4321000000000
+ - filesize_test_sparse_24.size == 4321000000000
+
+ - filesize_stat_sparse_21.stat.size == 4398046511104
+ - filesize_stat_sparse_22.stat.size == 4321000000000
+ - filesize_stat_sparse_24.stat.size == 4321000000000
+
+
+
+- name: Remove test file
+ ansible.builtin.file:
+ path: "{{ filesize_testfile }}"
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/filesize/tasks/symlinks.yml b/ansible_collections/community/general/tests/integration/targets/filesize/tasks/symlinks.yml
new file mode 100644
index 000000000..011889656
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filesize/tasks/symlinks.yml
@@ -0,0 +1,97 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Check that the module works with symlinks, as expected, i.e. as dd does:
+# follow symlinks.
+
+- name: Ensure the test file is absent
+ ansible.builtin.file:
+ path: "{{ filesize_testfile }}"
+ state: absent
+
+- name: Create a broken symlink in the same directory
+ ansible.builtin.file:
+ src: "{{ filesize_testfile | basename }}"
+ dest: "{{ filesize_testlink }}"
+ state: link
+ force: true
+ follow: false
+
+
+
+- name: Create a file with a size of 512 kB (512000 bytes) (check mode)
+ community.general.filesize:
+ path: "{{ filesize_testlink }}"
+ size: "512 kB"
+ register: filesize_test_symlink_01
+ check_mode: true
+
+- name: Create a file with a size of 512 kB (512000 bytes)
+ community.general.filesize:
+ path: "{{ filesize_testlink }}"
+ size: "512 kB"
+ register: filesize_test_symlink_02
+
+- name: Stat the resulting file (not the symlink)
+ ansible.builtin.stat:
+ path: "{{ filesize_test_symlink_02.path }}"
+ register: filesize_stat_symlink_02
+
+
+- name: Create a file with a size of 500 KiB (512000 bytes) (check mode, idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testlink }}"
+ size: "500 KiB"
+ register: filesize_test_symlink_03
+ check_mode: true
+
+- name: Create a file with a size of 500 KiB (512000 bytes) (idempotency)
+ community.general.filesize:
+ path: "{{ filesize_testlink }}"
+ size: "500 KiB"
+ register: filesize_test_symlink_04
+
+- name: Stat the file again (should remain the same)
+ ansible.builtin.stat:
+ path: "{{ filesize_test_symlink_04.path }}"
+ register: filesize_stat_symlink_04
+
+
+- name: Assert that results are as expected
+ ansible.builtin.assert:
+ that:
+ - filesize_test_symlink_01 is changed
+ - filesize_test_symlink_02 is changed
+ - filesize_test_symlink_03 is not changed
+ - filesize_test_symlink_04 is not changed
+
+ - filesize_test_symlink_02.cmd == filesize_test_symlink_01.cmd
+ - filesize_test_symlink_03.cmd is undefined
+ - filesize_test_symlink_04.cmd is undefined
+
+ - filesize_test_symlink_01.state is undefined
+ - filesize_test_symlink_02.state in ["file"]
+ - filesize_test_symlink_01.size is undefined
+ - filesize_test_symlink_02.size == 512000
+ - filesize_test_symlink_03.size == 512000
+ - filesize_test_symlink_04.size == 512000
+
+ - filesize_stat_symlink_02.stat.size == 512000
+ - filesize_stat_symlink_04.stat.size == 512000
+
+ - filesize_test_symlink_04.path == filesize_test_symlink_02.path
+ - filesize_test_symlink_04.path != filesize_testlink
+
+
+
+- name: Remove test file
+ ansible.builtin.file:
+ path: "{{ filesize_testfile }}"
+ state: absent
+
+- name: Remove test link
+ ansible.builtin.file:
+ path: "{{ filesize_testlink }}"
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/filesystem/aliases b/ansible_collections/community/general/tests/integration/targets/filesystem/aliases
new file mode 100644
index 000000000..a666f7a14
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filesystem/aliases
@@ -0,0 +1,10 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+azp/posix/vm
+destructive
+skip/aix
+skip/osx
+skip/macos
diff --git a/ansible_collections/community/general/tests/integration/targets/filesystem/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/filesystem/defaults/main.yml
new file mode 100644
index 000000000..0448d8602
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filesystem/defaults/main.yml
@@ -0,0 +1,35 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+tested_filesystems:
+ # key: fstype
+ # fssize: size (Mo)
+ # grow: true if resizefs is supported
+ # Other minimal sizes:
+ # - XFS: 20Mo
+ # - Btrfs: 150Mo (50Mo when "--metadata single" is used and 100Mb when on newer Fedora versions)
+ # - f2fs:
+ # - 1.2.0 requires at leat 116Mo
+ # - 1.7.0 requires at least 30Mo
+ # - 1.10.0 requires at least 38Mo
+ # - resizefs asserts when initial fs is smaller than 60Mo and seems to require 1.10.0
+ ext4: {fssize: 10, grow: true}
+ ext4dev: {fssize: 10, grow: true}
+ ext3: {fssize: 10, grow: true}
+ ext2: {fssize: 10, grow: true}
+ xfs: {fssize: 300, grow: false} # grow requires a mounted filesystem
+ btrfs: {fssize: 150, grow: false} # grow requires a mounted filesystem
+ reiserfs: {fssize: 33, grow: false} # grow not implemented
+ vfat: {fssize: 20, grow: true}
+ ocfs2: {fssize: '{{ ocfs2_fssize }}', grow: false} # grow not implemented
+ f2fs: {fssize: '{{ f2fs_fssize|default(60) }}', grow: 'f2fs_version is version("1.10.0", ">=")'}
+ lvm: {fssize: 20, grow: true}
+ swap: {fssize: 10, grow: false} # grow not implemented
+ ufs: {fssize: 10, grow: true}
+
+
+get_uuid_any: "blkid -c /dev/null -o value -s UUID {{ dev }}"
+get_uuid_ufs: "dumpfs {{ dev }} | awk -v sb=superblock -v id=id '$1 == sb && $4 == id {print $6$7}'"
+get_uuid_cmd: "{{ get_uuid_ufs if fstype == 'ufs' else get_uuid_any }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/filesystem/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/filesystem/meta/main.yml
new file mode 100644
index 000000000..d3facee4f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filesystem/meta/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
+ - setup_remote_tmp_dir_outside_tmp
diff --git a/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/create_device.yml b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/create_device.yml
new file mode 100644
index 000000000..8966ec2e6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/create_device.yml
@@ -0,0 +1,64 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: 'Create a "disk" file'
+ community.general.filesize:
+ path: '{{ image_file }}'
+ size: '{{ fssize }}M'
+ force: true
+
+- vars:
+ dev: '{{ image_file }}'
+ block:
+ - when: fstype == 'lvm'
+ block:
+ - name: 'Show next free loop device'
+ ansible.builtin.command:
+ cmd: 'losetup -f'
+ register: loop_device_cmd
+
+ - name: 'Create a loop device for LVM'
+ ansible.builtin.command:
+ cmd: 'losetup -f {{ dev }}'
+
+ - name: 'Switch to loop device target for further tasks'
+ ansible.builtin.set_fact:
+ dev: "{{ loop_device_cmd.stdout }}"
+
+ - when: fstype == 'ufs'
+ block:
+ - name: 'Create a memory disk for UFS'
+ ansible.builtin.command:
+ cmd: 'mdconfig -a -f {{ dev }}'
+ register: memory_disk_cmd
+
+ - name: 'Switch to memory disk target for further tasks'
+ ansible.builtin.set_fact:
+ dev: "/dev/{{ memory_disk_cmd.stdout }}"
+
+ - include_tasks: '{{ action }}.yml'
+
+ always:
+ - name: 'Detach loop device used for LVM'
+ ansible.builtin.command:
+ cmd: 'losetup -d {{ dev }}'
+ removes: '{{ dev }}'
+ when: fstype == 'lvm'
+
+ - name: 'Detach memory disk used for UFS'
+ ansible.builtin.command:
+ cmd: 'mdconfig -d -u {{ dev }}'
+ removes: '{{ dev }}'
+ when: fstype == 'ufs'
+
+ - name: 'Clean correct device for LVM and UFS'
+ ansible.builtin.set_fact:
+ dev: '{{ image_file }}'
+ when: fstype in ['lvm', 'ufs']
+
+ - name: 'Remove disk image file'
+ ansible.builtin.file:
+ name: '{{ image_file }}'
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/create_fs.yml b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/create_fs.yml
new file mode 100644
index 000000000..d5470fa56
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/create_fs.yml
@@ -0,0 +1,119 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: "Create filesystem ({{ fstype }})"
+ community.general.filesystem:
+ dev: '{{ dev }}'
+ fstype: '{{ fstype }}'
+ register: fs_result
+
+- name: "Assert that results are as expected"
+ ansible.builtin.assert:
+ that:
+ - 'fs_result is changed'
+ - 'fs_result is success'
+
+- name: "Get UUID of created filesystem"
+ ansible.builtin.shell:
+ cmd: "{{ get_uuid_cmd }}"
+ changed_when: false
+ register: uuid
+
+- name: "Check that filesystem isn't created if force isn't used"
+ community.general.filesystem:
+ dev: '{{ dev }}'
+ fstype: '{{ fstype }}'
+ register: fs2_result
+
+- name: "Get UUID of the filesystem"
+ ansible.builtin.shell:
+ cmd: "{{ get_uuid_cmd }}"
+ changed_when: false
+ register: uuid2
+
+- name: "Assert that filesystem UUID is not changed"
+ ansible.builtin.assert:
+ that:
+ - 'fs2_result is not changed'
+ - 'fs2_result is success'
+ - 'uuid.stdout == uuid2.stdout'
+
+- name: "Check that filesystem is recreated if force is used"
+ community.general.filesystem:
+ dev: '{{ dev }}'
+ fstype: '{{ fstype }}'
+ force: true
+ register: fs3_result
+
+- name: "Get UUID of the new filesystem"
+ ansible.builtin.shell:
+ cmd: "{{ get_uuid_cmd }}"
+ changed_when: false
+ register: uuid3
+
+- name: "Assert that filesystem UUID is changed"
+ # libblkid gets no UUID at all for this fstype on FreeBSD
+ when: not (ansible_system == 'FreeBSD' and fstype == 'reiserfs')
+ ansible.builtin.assert:
+ that:
+ - 'fs3_result is changed'
+ - 'fs3_result is success'
+ - 'uuid.stdout != uuid3.stdout'
+
+
+- when: 'grow|bool and (fstype != "vfat" or resize_vfat)'
+ block:
+ - name: "Increase fake device"
+ community.general.filesize:
+ path: '{{ image_file }}'
+ size: '{{ fssize | int + 1 }}M'
+
+ - name: "Resize loop device for LVM"
+ ansible.builtin.command:
+ cmd: 'losetup -c {{ dev }}'
+ when: fstype == 'lvm'
+
+ - name: "Resize memory disk for UFS"
+ ansible.builtin.command:
+ cmd: 'mdconfig -r -u {{ dev }} -s {{ fssize | int + 1 }}M'
+ when: fstype == 'ufs'
+
+ - name: "Expand filesystem"
+ community.general.filesystem:
+ dev: '{{ dev }}'
+ fstype: '{{ fstype }}'
+ resizefs: true
+ register: fs4_result
+
+ - name: "Get UUID of the filesystem"
+ ansible.builtin.shell:
+ cmd: "{{ get_uuid_cmd }}"
+ changed_when: false
+ register: uuid4
+
+ - name: "Assert that filesystem UUID is not changed"
+ ansible.builtin.assert:
+ that:
+ - 'fs4_result is changed'
+ - 'fs4_result is success'
+ - 'uuid3.stdout == uuid4.stdout' # unchanged
+
+- when:
+ - (grow | bool and (fstype != "vfat" or resize_vfat)) or
+ (fstype == "xfs" and ansible_system == "Linux" and
+ ansible_distribution not in ["CentOS", "Ubuntu"])
+ block:
+ - name: "Check that resizefs does nothing if device size is not changed"
+ community.general.filesystem:
+ dev: '{{ dev }}'
+ fstype: '{{ fstype }}'
+ resizefs: true
+ register: fs5_result
+
+ - name: "Assert that the state did not change"
+ ansible.builtin.assert:
+ that:
+ - 'fs5_result is not changed'
+ - 'fs5_result is succeeded'
diff --git a/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/freebsd_setup.yml b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/freebsd_setup.yml
new file mode 100644
index 000000000..03fef66e6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/freebsd_setup.yml
@@ -0,0 +1,14 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: "Uninstall e2fsprogs"
+ ansible.builtin.package:
+ name: e2fsprogs
+ state: absent
+
+- name: "Install util-linux"
+ ansible.builtin.package:
+ name: util-linux
+ state: present
diff --git a/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/main.yml
new file mode 100644
index 000000000..0ff0f2309
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/main.yml
@@ -0,0 +1,107 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- ansible.builtin.debug:
+ msg: '{{ role_name }}'
+- ansible.builtin.debug:
+ msg: '{{ role_path|basename }}'
+- import_tasks: setup.yml
+
+- include_vars: "{{ lookup('first_found', search) }}"
+ vars:
+ search:
+ files:
+ - '{{ ansible_distribution }}-{{ ansible_distribution_version }}.yml'
+ - 'default.yml'
+ paths:
+ - '../vars/'
+
+- include_tasks: create_device.yml
+ vars:
+ image_file: '{{ remote_tmp_dir }}/img'
+ fstype: '{{ item.0.key }}'
+ fssize: '{{ item.0.value.fssize }}'
+ grow: '{{ item.0.value.grow }}'
+ action: '{{ item.1 }}'
+ when:
+ # FreeBSD limited support
+ # Not available: btrfs, lvm, f2fs, ocfs2
+ # All BSD systems use swap fs, but only Linux needs mkswap
+ # Supported: ext2/3/4 (e2fsprogs), xfs (xfsprogs), reiserfs (progsreiserfs), vfat
+ - 'not (ansible_system == "FreeBSD" and item.0.key in ["btrfs", "f2fs", "swap", "lvm", "ocfs2"])'
+ # Available on FreeBSD but not on testbed (util-linux conflicts with e2fsprogs): wipefs, mkfs.minix
+ - 'not (ansible_system == "FreeBSD" and item.1 in ["overwrite_another_fs", "remove_fs"])'
+
+ # Linux limited support
+ # Not available: ufs (this is FreeBSD's native fs)
+ - 'not (ansible_system == "Linux" and item.0.key == "ufs")'
+
+ # Other limitations and corner cases
+
+ # f2fs-tools and reiserfs-utils packages not available with RHEL/CentOS on CI
+ - 'not (ansible_distribution in ["CentOS", "RedHat"] and item.0.key in ["f2fs", "reiserfs"])'
+ - 'not (ansible_os_family == "RedHat" and ansible_distribution_major_version is version("8", ">=") and
+ item.0.key == "btrfs")'
+ # reiserfs-utils package not available with Fedora 35 on CI
+ - 'not (ansible_distribution == "Fedora" and (ansible_facts.distribution_major_version | int >= 35) and
+ item.0.key == "reiserfs")'
+ # reiserfs packages apparently not available with Alpine
+ - 'not (ansible_distribution == "Alpine" and item.0.key == "reiserfs")'
+ # ocfs2 only available on Debian based distributions
+ - 'not (item.0.key == "ocfs2" and ansible_os_family != "Debian")'
+ # Tests use losetup which can not be used inside unprivileged container
+ - 'not (item.0.key == "lvm" and ansible_virtualization_type in ["docker", "container", "containerd"])'
+ # vfat resizing fails on Debian (but not Ubuntu)
+ - 'not (item.0.key == "vfat" and ansible_distribution == "Debian")' # TODO: figure out why it fails, fix it!
+ # vfat resizing fails on ArchLinux
+ - 'not (item.0.key == "vfat" and ansible_distribution == "Archlinux")' # TODO: figure out why it fails, fix it!
+ # vfat resizing fails on Ubuntu 22.04
+ - 'not (item.0.key == "vfat" and ansible_distribution == "Ubuntu" and (ansible_facts.distribution_major_version | int == 22))'
+ # TODO: figure out why it fails, fix it!
+ # btrfs-progs cannot be installed on ArchLinux
+ - 'not (item.0.key == "btrfs" and ansible_distribution == "Archlinux")' # TODO: figure out why it fails, fix it!
+
+ # On CentOS 6 shippable containers, wipefs seems unable to remove vfat signatures
+ - 'not (ansible_distribution == "CentOS" and ansible_distribution_version is version("7.0", "<") and
+ item.1 == "remove_fs" and item.0.key == "vfat")'
+ # On same systems, mkfs.minix (unhandled by the module) can't find the device/file
+ - 'not (ansible_distribution == "CentOS" and ansible_distribution_version is version("7.0", "<") and
+ item.1 == "overwrite_another_fs")'
+
+ # The xfsprogs package on newer versions of OpenSUSE (15+) require Python 3, we skip this on our Python 2 container
+ # OpenSUSE 42.3 Python2 and the other py3 containers are not affected so we will continue to run that
+ - 'not (ansible_os_family == "Suse" and ansible_distribution_major_version|int != 42 and
+ item.0.key == "xfs" and ansible_python.version.major == 2)'
+
+ # TODO: something seems to be broken on Alpine
+ - 'not (ansible_distribution == "Alpine")'
+
+ loop: "{{ query('dict', tested_filesystems)|product(['create_fs', 'overwrite_another_fs', 'remove_fs'])|list }}"
+
+
+# With FreeBSD extended support (util-linux is not available before 12.2)
+
+- include_tasks: freebsd_setup.yml
+ when:
+ - 'ansible_system == "FreeBSD"'
+ - 'ansible_distribution_version is version("12.2", ">=")'
+
+- include_tasks: create_device.yml
+ vars:
+ image_file: '{{ remote_tmp_dir }}/img'
+ fstype: '{{ item.0.key }}'
+ fssize: '{{ item.0.value.fssize }}'
+ grow: '{{ item.0.value.grow }}'
+ action: '{{ item.1 }}'
+ when:
+ - 'ansible_system == "FreeBSD"'
+ - 'ansible_distribution_version is version("12.2", ">=")'
+ - 'item.0.key in ["xfs", "vfat"]'
+ loop: "{{ query('dict', tested_filesystems)|product(['create_fs', 'overwrite_another_fs', 'remove_fs'])|list }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/overwrite_another_fs.yml b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/overwrite_another_fs.yml
new file mode 100644
index 000000000..69418b22f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/overwrite_another_fs.yml
@@ -0,0 +1,59 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: 'Recreate "disk" file'
+ community.general.filesize:
+ path: '{{ image_file }}'
+ size: '{{ fssize }}M'
+ force: true
+
+- name: 'Create a minix filesystem'
+ ansible.builtin.command:
+ cmd: 'mkfs.minix {{ dev }}'
+
+- name: 'Get UUID of the new filesystem'
+ ansible.builtin.shell:
+ cmd: "{{ get_uuid_cmd }}"
+ changed_when: false
+ register: uuid
+
+- name: "Check that an existing filesystem (not handled by this module) isn't overwritten when force isn't used"
+ community.general.filesystem:
+ dev: '{{ dev }}'
+ fstype: '{{ fstype }}'
+ register: fs_result
+ ignore_errors: true
+
+- name: 'Get UUID of the filesystem'
+ ansible.builtin.shell:
+ cmd: "{{ get_uuid_cmd }}"
+ changed_when: false
+ register: uuid2
+
+- name: 'Assert that module failed and filesystem UUID is not changed'
+ ansible.builtin.assert:
+ that:
+ - 'fs_result is failed'
+ - 'uuid.stdout == uuid2.stdout'
+
+- name: "Check that an existing filesystem (not handled by this module) is overwritten when force is used"
+ community.general.filesystem:
+ dev: '{{ dev }}'
+ fstype: '{{ fstype }}'
+ force: true
+ register: fs_result2
+
+- name: 'Get UUID of the new filesystem'
+ ansible.builtin.shell:
+ cmd: "{{ get_uuid_cmd }}"
+ changed_when: false
+ register: uuid3
+
+- name: 'Assert that module succeeded and filesystem UUID is changed'
+ ansible.builtin.assert:
+ that:
+ - 'fs_result2 is success'
+ - 'fs_result2 is changed'
+ - 'uuid2.stdout != uuid3.stdout'
diff --git a/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/remove_fs.yml b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/remove_fs.yml
new file mode 100644
index 000000000..c5428b309
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/remove_fs.yml
@@ -0,0 +1,102 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# We assume 'create_fs' tests have passed.
+
+- name: "Create filesystem"
+ community.general.filesystem:
+ dev: '{{ dev }}'
+ fstype: '{{ fstype }}'
+
+- name: "Get filesystem UUID with 'blkid'"
+ ansible.builtin.shell:
+ cmd: "{{ get_uuid_cmd }}"
+ changed_when: false
+ register: blkid_ref
+
+- name: "Assert that a filesystem exists on top of the device"
+ ansible.builtin.assert:
+ that:
+ - blkid_ref.stdout | length > 0
+
+
+# Test check_mode first
+- name: "Remove filesystem (check mode)"
+ community.general.filesystem:
+ dev: '{{ dev }}'
+ state: absent
+ register: wipefs
+ check_mode: true
+
+- name: "Get filesystem UUID with 'blkid' (should remain the same)"
+ ansible.builtin.shell:
+ cmd: "{{ get_uuid_cmd }}"
+ changed_when: false
+ register: blkid
+
+- name: "Assert that the state changed but the filesystem still exists"
+ ansible.builtin.assert:
+ that:
+ - wipefs is changed
+ - blkid.stdout == blkid_ref.stdout
+
+# Do it
+- name: "Remove filesystem"
+ community.general.filesystem:
+ dev: '{{ dev }}'
+ state: absent
+ register: wipefs
+
+- name: "Get filesystem UUID with 'blkid' (should be empty)"
+ ansible.builtin.shell:
+ cmd: "{{ get_uuid_cmd }}"
+ changed_when: false
+ failed_when: false
+ register: blkid
+
+- name: "Assert that the state changed and the device has no filesystem"
+ ansible.builtin.assert:
+ that:
+ - wipefs is changed
+ - blkid.stdout | length == 0
+ - blkid.rc == 2
+
+# Do it again
+- name: "Remove filesystem (idempotency)"
+ community.general.filesystem:
+ dev: '{{ dev }}'
+ state: absent
+ register: wipefs
+
+- name: "Assert that the state did not change"
+ ansible.builtin.assert:
+ that:
+ - wipefs is not changed
+
+# and again
+- name: "Remove filesystem (idempotency, check mode)"
+ community.general.filesystem:
+ dev: '{{ dev }}'
+ state: absent
+ register: wipefs
+ check_mode: true
+
+- name: "Assert that the state did not change"
+ ansible.builtin.assert:
+ that:
+ - wipefs is not changed
+
+
+# By the way, test removal of a filesystem on unexistent device
+- name: "Remove filesystem (unexistent device)"
+ community.general.filesystem:
+ dev: '/dev/unexistent_device'
+ state: absent
+ register: wipefs
+
+- name: "Assert that the state did not change"
+ ansible.builtin.assert:
+ that:
+ - wipefs is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/setup.yml b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/setup.yml
new file mode 100644
index 000000000..97dafaeee
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filesystem/tasks/setup.yml
@@ -0,0 +1,154 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# By installing e2fsprogs on FreeBSD, we get a usable blkid command, but this
+# package conflicts with util-linux, that provides blkid too, but also wipefs
+# (required for filesystem state=absent).
+- name: "Install filesystem tools"
+ ansible.builtin.package:
+ name: '{{ item }}'
+ state: present
+ # xfsprogs on OpenSUSE requires Python 3, skip this for our newer Py2 OpenSUSE builds
+ when: not (item == 'xfsprogs' and ansible_os_family == 'Suse' and ansible_python.version.major == 2 and ansible_distribution_major_version|int != 42)
+ loop:
+ - e2fsprogs
+ - xfsprogs
+
+- name: "Install btrfs progs"
+ ansible.builtin.package:
+ name: btrfs-progs
+ state: present
+ when:
+ - ansible_os_family != 'Suse'
+ - not (ansible_distribution == 'Ubuntu' and ansible_distribution_version is version('16.04', '<='))
+ - ansible_system != "FreeBSD"
+ - not (ansible_facts.os_family == "RedHat" and ansible_facts.distribution_major_version is version('8', '>='))
+ - ansible_os_family != 'Archlinux' # TODO
+
+- name: "Install btrfs tools (Ubuntu <= 16.04)"
+ ansible.builtin.package:
+ name: btrfs-tools
+ state: present
+ when:
+ - ansible_distribution == 'Ubuntu'
+ - ansible_distribution_version is version('16.04', '<=')
+
+- name: "Install btrfs progs (OpenSuse)"
+ ansible.builtin.package:
+ name:
+ - python{{ ansible_python.version.major }}-xml
+ - btrfsprogs
+ state: present
+ when: ansible_os_family == 'Suse'
+
+- name: "Install reiserfs utils (Fedora)"
+ ansible.builtin.package:
+ name: reiserfs-utils
+ state: present
+ when:
+ - ansible_distribution == 'Fedora' and (ansible_facts.distribution_major_version | int < 35)
+
+- name: "Install reiserfs and util-linux-systemd (for findmnt) (OpenSuse)"
+ ansible.builtin.package:
+ name:
+ - reiserfs
+ - util-linux-systemd
+ state: present
+ when:
+ - ansible_os_family == 'Suse'
+
+- name: "Install reiserfs progs (Debian and more)"
+ ansible.builtin.package:
+ name: reiserfsprogs
+ state: present
+ when:
+ - ansible_system == 'Linux'
+ - ansible_os_family not in ['Suse', 'RedHat', 'Alpine']
+
+- name: "Install reiserfs progs (FreeBSD)"
+ ansible.builtin.package:
+ name: progsreiserfs
+ state: present
+ when:
+ - ansible_system == 'FreeBSD'
+
+- name: "Install ocfs2 (Debian)"
+ ansible.builtin.package:
+ name: ocfs2-tools
+ state: present
+ when: ansible_os_family == 'Debian'
+
+- name: "Install f2fs tools and get version"
+ when:
+ - ansible_os_family != 'RedHat' or ansible_distribution == 'Fedora'
+ - ansible_distribution != 'Ubuntu' or ansible_distribution_version is version('16.04', '>=')
+ - ansible_system != "FreeBSD"
+ block:
+ - name: "Install f2fs tools"
+ ansible.builtin.package:
+ name: f2fs-tools
+ state: present
+
+ - name: "Fetch f2fs version"
+ ansible.builtin.command:
+ cmd: mkfs.f2fs /dev/null
+ changed_when: false
+ ignore_errors: true
+ register: mkfs_f2fs
+
+ - name: "Record f2fs_version"
+ ansible.builtin.set_fact:
+ f2fs_version: '{{ mkfs_f2fs.stdout
+ | regex_search("F2FS-tools: mkfs.f2fs Ver:.*")
+ | regex_replace("F2FS-tools: mkfs.f2fs Ver: ([0-9.]+) .*", "\1") }}'
+
+- name: "Install dosfstools and lvm2 (Linux)"
+ ansible.builtin.package:
+ name:
+ - dosfstools
+ - lvm2
+ when: ansible_system == 'Linux'
+
+- name: "Install fatresize and get version"
+ when:
+ - ansible_system == 'Linux'
+ - ansible_os_family != 'Suse'
+ - ansible_os_family != 'RedHat' or (ansible_distribution == 'CentOS' and ansible_distribution_version is version('7.0', '=='))
+ - ansible_os_family != 'Alpine'
+ block:
+ - name: "Install fatresize"
+ ansible.builtin.package:
+ name: fatresize
+ state: present
+
+ - name: "Fetch fatresize version"
+ ansible.builtin.command:
+ cmd: fatresize --help
+ changed_when: false
+ register: fatresize
+
+ - name: "Record fatresize_version"
+ ansible.builtin.set_fact:
+ fatresize_version: '{{ fatresize.stdout_lines[0] | regex_search("[0-9]+\.[0-9]+\.[0-9]+") }}'
+
+- name: "Fetch e2fsprogs version"
+ ansible.builtin.command:
+ cmd: mke2fs -V
+ changed_when: false
+ register: mke2fs
+
+- name: "Record e2fsprogs_version"
+ ansible.builtin.set_fact:
+ # mke2fs 1.43.6 (29-Aug-2017)
+ e2fsprogs_version: '{{ mke2fs.stderr_lines[0] | regex_search("[0-9]{1,2}\.[0-9]{1,2}(\.[0-9]{1,2})?") }}'
+
+- name: "Set version-related facts to skip further tasks"
+ ansible.builtin.set_fact:
+ # http://e2fsprogs.sourceforge.net/e2fsprogs-release.html#1.43
+ # Mke2fs no longer complains if the user tries to create a file system
+ # using the entire block device.
+ force_creation: "{{ e2fsprogs_version is version('1.43', '<') }}"
+ # Earlier versions have a segfault bug
+ resize_vfat: "{{ fatresize_version|default('0.0') is version('1.0.4', '>=') }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/filesystem/vars/Ubuntu-14.04.yml b/ansible_collections/community/general/tests/integration/targets/filesystem/vars/Ubuntu-14.04.yml
new file mode 100644
index 000000000..d0cc5f229
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filesystem/vars/Ubuntu-14.04.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ocfs2_fssize: 108
+f2fs_fssize: 116
diff --git a/ansible_collections/community/general/tests/integration/targets/filesystem/vars/default.yml b/ansible_collections/community/general/tests/integration/targets/filesystem/vars/default.yml
new file mode 100644
index 000000000..80151e40e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filesystem/vars/default.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ocfs2_fssize: 20
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_counter/aliases b/ansible_collections/community/general/tests/integration/targets/filter_counter/aliases
new file mode 100644
index 000000000..bc9b4bc99
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_counter/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+skip/python2.6 # filters are controller only, and we no longer support Python 2.6 on the controller
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_counter/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_counter/tasks/main.yml
new file mode 100644
index 000000000..77d6b1b02
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_counter/tasks/main.yml
@@ -0,0 +1,41 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: test counter filter
+ assert:
+ that:
+ - "('abca' | community.general.counter) == {'a': 2, 'b': 1, 'c': 1}"
+ - "(['apple', 'pear', 'pear'] | community.general.counter) == {'apple': 1, 'pear': 2}"
+ - "([1, 2, 2, 3] | community.general.counter) == {1: 1, 2: 2, 3: 1}"
+ - "([1.11, 1.11, 1.12] | community.general.counter) == {1.11: 2, 1.12: 1}"
+
+- name: test fail argument not a sequence
+ debug:
+ msg: "{{ {'a': 'b'} | community.general.counter }}"
+ ignore_errors: true
+ register: res
+
+- name: verify test fail argument not a sequence
+ assert:
+ that:
+ - res is failed
+ - res.msg is match('Argument for community.general.counter must be a sequence')
+
+- name: test fail element not hashable
+ debug:
+ msg: "{{ [{'a': 'b'}] | community.general.counter }}"
+ ignore_errors: true
+ register: res
+
+- name: verify test fail element not hashable
+ assert:
+ that:
+ - res is failed
+ - res.msg is match('community.general.counter needs a sequence with hashable elements')
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_dict/aliases b/ansible_collections/community/general/tests/integration/targets/filter_dict/aliases
new file mode 100644
index 000000000..e8051e042
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_dict/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/3
+skip/python2.6 # filters are controller only, and we no longer support Python 2.6 on the controller
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_dict/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_dict/tasks/main.yml
new file mode 100644
index 000000000..7b4cefde9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_dict/tasks/main.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: "Test dict filter"
+ assert:
+ that:
+ - "[['a', 'b']] | community.general.dict == dict([['a', 'b']])"
+ - "[['a', 'b'], [1, 2]] | community.general.dict == dict([['a', 'b'], [1, 2]])"
+ - "[] | community.general.dict == dict([])"
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_dict_kv/aliases b/ansible_collections/community/general/tests/integration/targets/filter_dict_kv/aliases
new file mode 100644
index 000000000..bc9b4bc99
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_dict_kv/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+skip/python2.6 # filters are controller only, and we no longer support Python 2.6 on the controller
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_dict_kv/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_dict_kv/tasks/main.yml
new file mode 100644
index 000000000..47dc8e25d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_dict_kv/tasks/main.yml
@@ -0,0 +1,14 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: test dict_kv filter
+ assert:
+ that:
+ - "('value' | community.general.dict_kv('key')) == {'key': 'value'}"
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_from_csv/aliases b/ansible_collections/community/general/tests/integration/targets/filter_from_csv/aliases
new file mode 100644
index 000000000..bc9b4bc99
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_from_csv/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+skip/python2.6 # filters are controller only, and we no longer support Python 2.6 on the controller
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_from_csv/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_from_csv/tasks/main.yml
new file mode 100644
index 000000000..5c58f85d4
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_from_csv/tasks/main.yml
@@ -0,0 +1,54 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Parse valid csv input
+ assert:
+ that:
+ - "valid_comma_separated | community.general.from_csv == expected_result"
+
+- name: Parse valid csv input containing spaces with/without skipinitialspace=True
+ assert:
+ that:
+ - "valid_comma_separated_spaces | community.general.from_csv(skipinitialspace=True) == expected_result"
+ - "valid_comma_separated_spaces | community.general.from_csv != expected_result"
+
+- name: Parse valid csv input with no headers with/without specifying fieldnames
+ assert:
+ that:
+ - "valid_comma_separated_no_headers | community.general.from_csv(fieldnames=['id','name','role']) == expected_result"
+ - "valid_comma_separated_no_headers | community.general.from_csv != expected_result"
+
+- name: Parse valid pipe-delimited csv input with/without delimiter=|
+ assert:
+ that:
+ - "valid_pipe_separated | community.general.from_csv(delimiter='|') == expected_result"
+ - "valid_pipe_separated | community.general.from_csv != expected_result"
+
+- name: Register result of invalid csv input when strict=False
+ debug:
+ var: "invalid_comma_separated | community.general.from_csv"
+ register: _invalid_csv_strict_false
+
+- name: Test invalid csv input when strict=False is successful
+ assert:
+ that:
+ - _invalid_csv_strict_false is success
+
+- name: Register result of invalid csv input when strict=True
+ debug:
+ var: "invalid_comma_separated | community.general.from_csv(strict=True)"
+ register: _invalid_csv_strict_true
+ ignore_errors: true
+
+- name: Test invalid csv input when strict=True is failed
+ assert:
+ that:
+ - _invalid_csv_strict_true is failed
+ - _invalid_csv_strict_true.msg is match('Unable to process file:.*')
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_from_csv/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_from_csv/vars/main.yml
new file mode 100644
index 000000000..7212c5aee
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_from_csv/vars/main.yml
@@ -0,0 +1,31 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+valid_comma_separated: |
+ id,name,role
+ 1,foo,bar
+ 2,bar,baz
+valid_comma_separated_spaces: |
+ id,name,role
+ 1, foo, bar
+ 2, bar, baz
+valid_comma_separated_no_headers: |
+ 1,foo,bar
+ 2,bar,baz
+valid_pipe_separated: |
+ id|name|role
+ 1|foo|bar
+ 2|bar|baz
+invalid_comma_separated: |
+ id,name,role
+ 1,foo,bar
+ 2,"b"ar",baz
+expected_result:
+ - id: '1'
+ name: foo
+ role: bar
+ - id: '2'
+ name: bar
+ role: baz
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_groupby_as_dict/aliases b/ansible_collections/community/general/tests/integration/targets/filter_groupby_as_dict/aliases
new file mode 100644
index 000000000..e8051e042
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_groupby_as_dict/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/3
+skip/python2.6 # filters are controller only, and we no longer support Python 2.6 on the controller
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_groupby_as_dict/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_groupby_as_dict/tasks/main.yml
new file mode 100644
index 000000000..f4047f4ac
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_groupby_as_dict/tasks/main.yml
@@ -0,0 +1,49 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Test functionality
+ assert:
+ that:
+ - list1 | community.general.groupby_as_dict('name') == dict1
+
+- name: 'Test error: not a list'
+ set_fact:
+ test: "{{ list_no_list | community.general.groupby_as_dict('name') }}"
+ ignore_errors: true
+ register: result
+
+- assert:
+ that:
+ - result.msg == 'Input is not a sequence'
+
+- name: 'Test error: list element not a mapping'
+ set_fact:
+ test: "{{ list_no_dict | community.general.groupby_as_dict('name') }}"
+ ignore_errors: true
+ register: result
+
+- assert:
+ that:
+ - "result.msg == 'Sequence element #0 is not a mapping'"
+
+- name: 'Test error: list element does not have attribute'
+ set_fact:
+ test: "{{ list_no_attribute | community.general.groupby_as_dict('name') }}"
+ ignore_errors: true
+ register: result
+
+- assert:
+ that:
+ - "result.msg == 'Attribute not contained in element #1 of sequence'"
+
+- name: 'Test error: attribute collision'
+ set_fact:
+ test: "{{ list_collision | community.general.groupby_as_dict('name') }}"
+ ignore_errors: true
+ register: result
+
+- assert:
+ that:
+ - result.msg == "Multiple sequence entries have attribute value 'a'" or result.msg == "Multiple sequence entries have attribute value u'a'"
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_groupby_as_dict/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_groupby_as_dict/vars/main.yml
new file mode 100644
index 000000000..74e24dd3c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_groupby_as_dict/vars/main.yml
@@ -0,0 +1,35 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+list1:
+ - name: a
+ x: y
+ - name: b
+ z: 1
+
+dict1:
+ a:
+ name: a
+ x: y
+ b:
+ name: b
+ z: 1
+
+list_no_list:
+ a:
+ name: a
+
+list_no_dict:
+ - []
+ - 1
+
+list_no_attribute:
+ - name: a
+ foo: baz
+ - foo: bar
+
+list_collision:
+ - name: a
+ - name: a
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_hashids/aliases b/ansible_collections/community/general/tests/integration/targets/filter_hashids/aliases
new file mode 100644
index 000000000..bc9b4bc99
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_hashids/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+skip/python2.6 # filters are controller only, and we no longer support Python 2.6 on the controller
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_hashids/runme.sh b/ansible_collections/community/general/tests/integration/targets/filter_hashids/runme.sh
new file mode 100755
index 000000000..c7a215a06
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_hashids/runme.sh
@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+set -eux
+
+source virtualenv.sh
+
+# Requirements have to be installed prior to running ansible-playbook
+# because plugins and requirements are loaded before the task runs
+
+pip install hashids
+
+ANSIBLE_ROLES_PATH=../ ansible-playbook runme.yml "$@"
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_hashids/runme.yml b/ansible_collections/community/general/tests/integration/targets/filter_hashids/runme.yml
new file mode 100644
index 000000000..3ac0e388f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_hashids/runme.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- hosts: localhost
+ roles:
+ - { role: filter_hashids }
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_hashids/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_hashids/tasks/main.yml
new file mode 100644
index 000000000..4a76540f6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_hashids/tasks/main.yml
@@ -0,0 +1,63 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Test valid hashable inputs
+ assert:
+ that:
+ - "single_int | community.general.hashids_encode | community.general.hashids_decode == [single_int]"
+ - "int_list | community.general.hashids_encode | community.general.hashids_decode | list == int_list"
+ - "(1,2,3) | community.general.hashids_encode | community.general.hashids_decode == [1,2,3]"
+
+- name: Test valid parameters
+ assert:
+ that:
+ - "single_int | community.general.hashids_encode(salt='test') | community.general.hashids_decode(salt='test') == [single_int]"
+ - "single_int | community.general.hashids_encode(alphabet='1234567890abcdef') | community.general.hashids_decode(alphabet='1234567890abcdef') == [single_int]"
+ - "single_int | community.general.hashids_encode(min_length=20) | community.general.hashids_decode(min_length=20) == [single_int]"
+ - "single_int | community.general.hashids_encode(min_length=20) | length == 20"
+
+- name: Test valid unhashable inputs
+ assert:
+ that:
+ - "single_float | community.general.hashids_encode | community.general.hashids_decode == []"
+ - "arbitrary_string | community.general.hashids_encode | community.general.hashids_decode == []"
+
+- name: Register result of invalid salt
+ debug:
+ var: "invalid_input | community.general.hashids_encode(salt=10)"
+ register: invalid_salt_message
+ ignore_errors: true
+
+- name: Test invalid salt fails
+ assert:
+ that:
+ - invalid_salt_message is failed
+
+- name: Register result of invalid alphabet
+ debug:
+ var: "invalid_input | community.general.hashids_encode(alphabet='abc')"
+ register: invalid_alphabet_message
+ ignore_errors: true
+
+- name: Test invalid alphabet fails
+ assert:
+ that:
+ - invalid_alphabet_message is failed
+
+- name: Register result of invalid min_length
+ debug:
+ var: "invalid_input | community.general.hashids_encode(min_length='foo')"
+ register: invalid_min_length_message
+ ignore_errors: true
+
+- name: Test invalid min_length fails
+ assert:
+ that:
+ - invalid_min_length_message is failed
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_hashids/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_hashids/vars/main.yml
new file mode 100644
index 000000000..db65ef562
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_hashids/vars/main.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+single_int: 1
+int_list: [1, 2, 3]
+single_float: [2.718]
+arbitrary_string: "will not hash"
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_jc/aliases b/ansible_collections/community/general/tests/integration/targets/filter_jc/aliases
new file mode 100644
index 000000000..0e799090e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_jc/aliases
@@ -0,0 +1,7 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+skip/python2.6 # filters are controller only, and we no longer support Python 2.6 on the controller
+skip/python2.7 # jc only supports python3.x
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_jc/runme.sh b/ansible_collections/community/general/tests/integration/targets/filter_jc/runme.sh
new file mode 100755
index 000000000..c427b8b35
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_jc/runme.sh
@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+set -eux
+
+source virtualenv.sh
+
+# Requirements have to be installed prior to running ansible-playbook
+# because plugins and requirements are loaded before the task runs
+
+pip install jc
+
+ANSIBLE_ROLES_PATH=../ ansible-playbook runme.yml "$@"
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_jc/runme.yml b/ansible_collections/community/general/tests/integration/targets/filter_jc/runme.yml
new file mode 100644
index 000000000..6d6a89c00
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_jc/runme.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- hosts: localhost
+ roles:
+ - { role: filter_jc }
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_jc/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_jc/tasks/main.yml
new file mode 100644
index 000000000..a06a0bfa4
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_jc/tasks/main.yml
@@ -0,0 +1,14 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: test jc key/value parser
+ assert:
+ that:
+ - "('key1=value1\nkey2=value2' | community.general.jc('kv')) == {'key1': 'value1', 'key2': 'value2'}"
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_json_query/aliases b/ansible_collections/community/general/tests/integration/targets/filter_json_query/aliases
new file mode 100644
index 000000000..cee9abd2c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_json_query/aliases
@@ -0,0 +1,7 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+skip/python2.6 # filters are controller only, and we no longer support Python 2.6 on the controller
+skip/aix
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_json_query/runme.sh b/ansible_collections/community/general/tests/integration/targets/filter_json_query/runme.sh
new file mode 100755
index 000000000..b1fa994b3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_json_query/runme.sh
@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+set -eux
+
+source virtualenv.sh
+
+# Requirements have to be installed prior to running ansible-playbook
+# because plugins and requirements are loaded before the task runs
+
+pip install jmespath
+
+ANSIBLE_ROLES_PATH=../ ansible-playbook runme.yml "$@"
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_json_query/runme.yml b/ansible_collections/community/general/tests/integration/targets/filter_json_query/runme.yml
new file mode 100644
index 000000000..28281cffb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_json_query/runme.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- hosts: localhost
+ roles:
+ - { role: filter_json_query }
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_json_query/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_json_query/tasks/main.yml
new file mode 100644
index 000000000..92db6d876
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_json_query/tasks/main.yml
@@ -0,0 +1,14 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Test json_query filter
+ assert:
+ that:
+ - "users | community.general.json_query('[*].hosts[].host') == ['host_a', 'host_b', 'host_c', 'host_d']"
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_json_query/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_json_query/vars/main.yml
new file mode 100644
index 000000000..1edd723be
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_json_query/vars/main.yml
@@ -0,0 +1,16 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+users:
+ - name: steve
+ hosts:
+ - host: host_a
+ password: abc
+ - host: host_b
+ - name: bill
+ hosts:
+ - host: host_c
+ password: default
+ - host: host_d
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_lists_mergeby/aliases b/ansible_collections/community/general/tests/integration/targets/filter_lists_mergeby/aliases
new file mode 100644
index 000000000..bc9b4bc99
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_lists_mergeby/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+skip/python2.6 # filters are controller only, and we no longer support Python 2.6 on the controller
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_lists_mergeby/tasks/lists_mergeby_2-10.yml b/ansible_collections/community/general/tests/integration/targets/filter_lists_mergeby/tasks/lists_mergeby_2-10.yml
new file mode 100644
index 000000000..62896e1b0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_lists_mergeby/tasks/lists_mergeby_2-10.yml
@@ -0,0 +1,143 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: 101.Merge 2 lists by attribute name. list_merge='keep'
+ block:
+ - name: Merge 2 lists by attribute name. list_merge='keep'. set
+ set_fact:
+ my_list: "{{ [list100, list101]|
+ community.general.lists_mergeby('name', list_merge='keep') }}"
+ - name: Merge 2 lists by attribute name. list_merge='keep'. debug
+ debug:
+ msg: |-
+ my_list:
+ {{ my_list|to_nice_yaml|indent(2) }}
+ my_list|difference(result101):
+ {{ my_list|difference(result101)|to_nice_yaml|indent(2) }}
+ when: debug_test|d(false)|bool
+ - name: Merge 2 lists by attribute name. list_merge='keep'. assert
+ assert:
+ that: my_list | difference(result101) | length == 0
+ tags: t101
+
+- name: 102.Merge 2 lists by attribute name. list_merge='append'
+ block:
+ - name: Merge 2 lists by attribute name. list_merge='append'. set
+ set_fact:
+ my_list: "{{ [list100, list101]|
+ community.general.lists_mergeby('name', list_merge='append') }}"
+ - name: Merge 2 lists by attribute name. list_merge='append'. debug
+ debug:
+ msg: |-
+ my_list:
+ {{ my_list|to_nice_yaml|indent(2) }}
+ my_list|difference(result102):
+ {{ my_list|difference(result102)|to_nice_yaml|indent(2) }}
+ when: debug_test|d(false)|bool
+ - name: Merge 2 lists by attribute name. list_merge='append'. assert
+ assert:
+ that: my_list | difference(result102) | length == 0
+ tags: t102
+
+- name: 103.Merge 2 lists by attribute name. list_merge='prepend'
+ block:
+ - name: Merge 2 lists by attribute name. list_merge='prepend'. set
+ set_fact:
+ my_list: "{{ [list100, list101]|
+ community.general.lists_mergeby('name', list_merge='prepend') }}"
+ - name: Merge 2 lists by attribute name. list_merge='prepend'. debug
+ debug:
+ msg: |-
+ my_list:
+ {{ my_list|to_nice_yaml|indent(2) }}
+ my_list|difference(result103):
+ {{ my_list|difference(result103)|to_nice_yaml|indent(2) }}
+ when: debug_test|d(false)|bool
+ - name: Merge 2 lists by attribute name. list_merge='prepend'. assert
+ assert:
+ that: my_list | difference(result103) | length == 0
+ tags: t103
+
+- name: 104.Merge 2 lists by attribute name. list_merge='append_rp'
+ block:
+ - name: Merge 2 lists by attribute name. list_merge='append_rp'. set
+ set_fact:
+ my_list: "{{ [list102, list103]|
+ community.general.lists_mergeby('name', list_merge='append_rp') }}"
+ - name: Merge 2 lists by attribute name. list_merge='append_rp'. debug
+ debug:
+ msg: |-
+ my_list:
+ {{ my_list|to_nice_yaml|indent(2) }}
+ my_list|difference(result104):
+ {{ my_list|difference(result104)|to_nice_yaml|indent(2) }}
+ when: debug_test|d(false)|bool
+ - name: Merge 2 lists by attribute name. list_merge='append_rp'. assert
+ assert:
+ that: my_list | difference(result104) | length == 0
+ tags: t104
+
+- name: 105.Merge 2 lists by attribute name. list_merge='prepend_rp'
+ block:
+ - name: Merge 2 lists by attribute name. list_merge='prepend_rp'. set
+ set_fact:
+ my_list: "{{ [list102, list103]|
+ community.general.lists_mergeby('name', list_merge='prepend_rp') }}"
+ - name: Merge 2 lists by attribute name. list_merge='prepend_rp'. debug
+ debug:
+ msg: |-
+ my_list:
+ {{ my_list|to_nice_yaml|indent(2) }}
+ my_list|difference(result105):
+ {{ my_list|difference(result105)|to_nice_yaml|indent(2) }}
+ when: debug_test|d(false)|bool
+ - name: Merge 2 lists by attribute name. list_merge='prepend_rp'. assert
+ assert:
+ that: my_list | difference(result105) | length == 0
+ tags: t105
+
+# Test recursive
+
+- name: 200.Merge by name. recursive=True list_merge='append_rp'
+ block:
+ - name: Merge by name. recursive=True list_merge='append_rp'. set
+ set_fact:
+ my_list: "{{ [list200, list201]|
+ community.general.lists_mergeby('name',
+ recursive=True,
+ list_merge='append_rp') }}"
+ - name: Merge by name. recursive=True list_merge='append_rp'. debug
+ debug:
+ msg: |-
+ my_list:
+ {{ my_list|to_nice_yaml|indent(2) }}
+ my_list|difference(result200):
+ {{ my_list|difference(result200)|to_nice_yaml|indent(2) }}
+ when: debug_test|d(false)|bool
+ - name: Merge by name. recursive=True list_merge='append_rp'. assert
+ assert:
+ that: my_list | difference(result200) | length == 0
+ tags: t200
+
+- name: 201.Merge by name. recursive=False list_merge='append_rp'
+ block:
+ - name: Merge by name. recursive=False list_merge='append_rp'. set
+ set_fact:
+ my_list: "{{ [list200, list201]|
+ community.general.lists_mergeby('name',
+ recursive=False,
+ list_merge='append_rp') }}"
+ - name: Merge by name. recursive=False list_merge='append_rp'. debug
+ debug:
+ msg: |-
+ my_list:
+ {{ my_list|to_nice_yaml|indent(2) }}
+ my_list|difference(result201):
+ {{ my_list|difference(result201)|to_nice_yaml|indent(2) }}
+ when: debug_test|d(false)|bool
+ - name: Merge by name. recursive=False list_merge='append_rp'. assert
+ assert:
+ that: my_list | difference(result201) | length == 0
+ tags: t201
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_lists_mergeby/tasks/lists_mergeby_default.yml b/ansible_collections/community/general/tests/integration/targets/filter_lists_mergeby/tasks/lists_mergeby_default.yml
new file mode 100644
index 000000000..93917c97c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_lists_mergeby/tasks/lists_mergeby_default.yml
@@ -0,0 +1,169 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Debug ansible_version
+ debug:
+ var: ansible_version
+ when: debug_test|d(false)|bool
+ tags: t0
+
+- name: 1. Test lists merged by attribute name
+ block:
+ - name: Test lists merged by attribute name debug
+ debug:
+ msg: "{{ list1 | community.general.lists_mergeby(list2, 'name') }}"
+ when: debug_test|d(false)|bool
+ - name: Test lists merged by attribute name assert
+ assert:
+ that:
+ - "(list1 | community.general.lists_mergeby(list2, 'name') | list |
+ difference(list3) | length) == 0"
+ tags: t1
+
+- name: 2.Test list1 empty
+ block:
+ - name: Test list1 empty debug
+ debug:
+ msg: "{{ [] | community.general.lists_mergeby(list2, 'name') }}"
+ when: debug_test|d(false)|bool
+ - name: Test list1 empty assert
+ assert:
+ that:
+ - "([] | community.general.lists_mergeby(list2, 'name') | list |
+ difference(list2) | length) == 0"
+ tags: t2
+
+- name: 3.Test all lists empty
+ block:
+ - name: Test all lists empty debug
+ debug:
+ msg: "{{ [] | community.general.lists_mergeby([], 'name') }}"
+ when: debug_test|d(false)|bool
+ - name: Test all lists empty assert
+ assert:
+ that:
+ - "([] | community.general.lists_mergeby([], 'name') | list |
+ length) == 0"
+ tags: t3
+
+- name: 4.First argument must be list
+ block:
+ - name: First argument must be list set
+ set_fact:
+ my_list: "{{ {'x': 'y'} | community.general.lists_mergeby(list2, 'name') }}"
+ register: result
+ ignore_errors: true
+ - name: First argument must be list debug
+ debug:
+ var: my_list
+ when: debug_test|d(false)|bool
+ - name: First argument must be list assert
+ assert:
+ that:
+ - result is failed
+ - '"All arguments before the argument index for community.general.lists_mergeby must be lists." in result.msg'
+ tags: t4
+
+- name: 5.Second argument must be list
+ block:
+ - name: Second argument must be list set
+ set_fact:
+ my_list: "{{ list1 | community.general.lists_mergeby({'x': 'y'}, 'name') }}"
+ register: result
+ ignore_errors: true
+ - name: Second argument must be list set debug
+ debug:
+ var: my_list
+ when: debug_test|d(false)|bool
+ - name: Second argument must be list set assert
+ assert:
+ that:
+ - result is failed
+ - '"All arguments before the argument index for community.general.lists_mergeby must be lists." in result.msg'
+ tags: t5
+
+- name: 6.First arguments after the lists must be string
+ block:
+ - name: First arguments after the lists must be string set
+ set_fact:
+ my_list: "{{ list1 | community.general.lists_mergeby(list2, {'x': 'y'}) }}"
+ register: result
+ ignore_errors: true
+ - name: First arguments after the lists must be string debug
+ debug:
+ var: my_list
+ when: debug_test|d(false)|bool
+ - name: First arguments after the lists must be string assert
+ assert:
+ that:
+ - result is failed
+ - '"First argument after the lists for community.general.lists_mergeby must be string." in result.msg'
+ tags: t6
+
+- name: 7.Elements of list must be dictionaries
+ block:
+ - name: Elements of list must be dictionaries set
+ set_fact:
+ my_list: "{{ list4 | community.general.lists_mergeby(list2, 'name') }}"
+ register: result
+ ignore_errors: true
+ - name: Elements of list must be dictionaries debug
+ debug:
+ var: my_list
+ when: debug_test|d(false)|bool
+ - name: Elements of list must be dictionaries assert
+ assert:
+ that:
+ - result is failed
+ - '"Elements of list arguments for lists_mergeby must be dictionaries." in result.msg'
+ tags: t7
+
+- name: 8.Merge 3 lists by attribute name. 1 list in params.
+ block:
+ - name: Merge 3 lists by attribute name. 1 list in params. set
+ set_fact:
+ my_list: "{{ [list1, list2] | community.general.lists_mergeby(list5, 'name') }}"
+ - name: Merge 3 lists by attribute name. 1 list in params. debug
+ debug:
+ var: my_list
+ when: debug_test|d(false)|bool
+ - name: Merge 3 lists by attribute name. 1 list in params. assert
+ assert:
+ that: my_list | difference(result1) | length == 0
+ tags: t8
+
+- name: 9.Merge 3 lists by attribute name. No list in the params.
+ block:
+ - name: Merge 3 lists by attribute name. No list in the params. set
+ set_fact:
+ my_list: "{{ [list1, list2, list5] | community.general.lists_mergeby('name') }}"
+ - name: Merge 3 lists by attribute name. No list in the params. debug
+ debug:
+ var: my_list
+ when: debug_test|d(false)|bool
+ - name: Merge 3 lists by attribute name. No list in the params. asset
+ assert:
+ that: my_list | difference(result1) | length == 0
+ tags: t9
+
+# Test list_merge default options
+
+- name: 100.Merge 2 lists by attribute name. list_merge='replace'
+ block:
+ - name: Merge 2 lists by attribute name. list_merge='replace'. set
+ set_fact:
+ my_list: "{{ [list100, list101] | community.general.lists_mergeby('name') }}"
+ - name: Merge 2 lists by attribute name. list_merge='replace'. debug
+ debug:
+ msg: |-
+ my_list:
+ {{ my_list|to_nice_yaml|indent(2) }}
+ my_list|difference(result100):
+ {{ my_list|difference(result100)|to_nice_yaml|indent(2) }}
+ when: debug_test|d(false)|bool
+ - name: Merge 2 lists by attribute name. list_merge='replace'. assert
+ assert:
+ that: my_list | difference(result100) | length == 0
+ tags: t100
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_lists_mergeby/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_lists_mergeby/tasks/main.yml
new file mode 100644
index 000000000..d0bda368c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_lists_mergeby/tasks/main.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Test list_merge default options
+ import_tasks: lists_mergeby_default.yml
+
+- name: Test list_merge non-default options in Ansible 2.10 and higher
+ import_tasks: lists_mergeby_2-10.yml
+ when: ansible_version.full is version('2.10', '>=')
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_lists_mergeby/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_lists_mergeby/vars/main.yml
new file mode 100644
index 000000000..f3b492878
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_lists_mergeby/vars/main.yml
@@ -0,0 +1,209 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+list1:
+ - name: myname01
+ param01: myparam01
+ - name: myname02
+ param01: myparam02
+
+list2:
+ - name: myname01
+ param01: myparam03
+ - name: myname02
+ param02: myparam04
+ - name: myname03
+ param03: myparam03
+
+list3:
+ - name: myname01
+ param01: myparam03
+ - name: myname02
+ param01: myparam02
+ param02: myparam04
+ - name: myname03
+ param03: myparam03
+
+list4:
+ - name: myname01
+ param01: myparam01
+ - myname02
+
+list5:
+ - name: myname01
+ param01: myparam05
+ - name: myname02
+ param01: myparam06
+
+result1:
+ - name: myname01
+ param01: myparam05
+ - name: myname02
+ param01: myparam06
+ param02: myparam04
+ - name: myname03
+ param03: myparam03
+
+# Test list_merge
+
+list100:
+ - name: myname01
+ param01:
+ - default1
+ - name: myname02
+ param01:
+ - default2
+
+list101:
+ - name: myname01
+ param01:
+ - patch1
+ - name: myname02
+ param01:
+ - patch2
+
+list102:
+ - name: myname01
+ param01:
+ - patch1a
+ - patch1b
+ - patch1c
+ - name: myname02
+ param01:
+ - patch2a
+ - patch2b
+ - patch2d
+
+list103:
+ - name: myname01
+ param01:
+ - patch1c
+ - patch1d
+ - name: myname02
+ param01:
+ - patch2c
+ - patch2d
+
+result100:
+ - name: myname01
+ param01:
+ - patch1
+ - name: myname02
+ param01:
+ - patch2
+
+result101:
+ - name: myname01
+ param01:
+ - default1
+ - name: myname02
+ param01:
+ - default2
+
+result102:
+ - name: myname01
+ param01:
+ - default1
+ - patch1
+ - name: myname02
+ param01:
+ - default2
+ - patch2
+
+result103:
+ - name: myname01
+ param01:
+ - patch1
+ - default1
+ - name: myname02
+ param01:
+ - patch2
+ - default2
+
+result104:
+ - name: myname01
+ param01:
+ - patch1a
+ - patch1b
+ - patch1c
+ - patch1d
+ - name: myname02
+ param01:
+ - patch2a
+ - patch2b
+ - patch2c
+ - patch2d
+
+result105:
+ - name: myname01
+ param01:
+ - patch1c
+ - patch1d
+ - patch1a
+ - patch1b
+ - name: myname02
+ param01:
+ - patch2c
+ - patch2d
+ - patch2a
+ - patch2b
+
+# Test recursive
+
+list200:
+ - name: myname01
+ param01:
+ x: default_value
+ y: default_value
+ list:
+ - default_value
+ - name: myname02
+ param01: [1, 1, 2, 3]
+
+list201:
+ - name: myname01
+ param01:
+ y: patch_value
+ z: patch_value
+ list:
+ - patch_value
+ - name: myname02
+ param01: [3, 4, 4, {key: value}]
+
+result200:
+ - name: myname01
+ param01:
+ list:
+ - default_value
+ - patch_value
+ x: default_value
+ y: patch_value
+ z: patch_value
+ - name: myname02
+ param01:
+ - 1
+ - 1
+ - 2
+ - 3
+ - 4
+ - 4
+ - key: value
+
+result201:
+ - name: myname01
+ param01:
+ list:
+ - patch_value
+ y: patch_value
+ z: patch_value
+ - name: myname02
+ param01:
+ - 1
+ - 1
+ - 2
+ - 3
+ - 4
+ - 4
+ - key: value
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_path_join_shim/aliases b/ansible_collections/community/general/tests/integration/targets/filter_path_join_shim/aliases
new file mode 100644
index 000000000..51baa3d7a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_path_join_shim/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+skip/python2.6 # filters are controller only, and we no longer support Python 2.6 on the controller
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_path_join_shim/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_path_join_shim/tasks/main.yml
new file mode 100644
index 000000000..1462656fb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_path_join_shim/tasks/main.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: "Test path_join filter"
+ assert:
+ that:
+ - "['a', 'b'] | community.general.path_join == 'a/b'"
+ - "['a', '/b'] | community.general.path_join == '/b'"
+ - "[''] | community.general.path_join == ''"
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_random_mac/aliases b/ansible_collections/community/general/tests/integration/targets/filter_random_mac/aliases
new file mode 100644
index 000000000..cee9abd2c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_random_mac/aliases
@@ -0,0 +1,7 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+skip/python2.6 # filters are controller only, and we no longer support Python 2.6 on the controller
+skip/aix
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_random_mac/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_random_mac/meta/main.yml
new file mode 100644
index 000000000..982de6eb0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_random_mac/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_random_mac/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_random_mac/tasks/main.yml
new file mode 100644
index 000000000..230f9776d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_random_mac/tasks/main.yml
@@ -0,0 +1,62 @@
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# test code for filters
+# Copyright (c) 2014, Michael DeHaan <michael.dehaan@gmail.com>
+# Copyright (c) 2019, Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Test random_mac filter bad argument type
+ debug:
+ var: "0 | community.general.random_mac"
+ register: _bad_random_mac_filter
+ ignore_errors: true
+
+- name: Verify random_mac filter showed a bad argument type error message
+ assert:
+ that:
+ - _bad_random_mac_filter is failed
+ - "_bad_random_mac_filter.msg is match('Invalid value type (.*int.*) for random_mac .*')"
+
+- name: Test random_mac filter bad argument value
+ debug:
+ var: "'dummy' | community.general.random_mac"
+ register: _bad_random_mac_filter
+ ignore_errors: true
+
+- name: Verify random_mac filter showed a bad argument value error message
+ assert:
+ that:
+ - _bad_random_mac_filter is failed
+ - "_bad_random_mac_filter.msg is match('Invalid value (.*) for random_mac: .* not hexa byte')"
+
+- name: Test random_mac filter prefix too big
+ debug:
+ var: "'00:00:00:00:00:00' | community.general.random_mac"
+ register: _bad_random_mac_filter
+ ignore_errors: true
+
+- name: Verify random_mac filter showed a prefix too big error message
+ assert:
+ that:
+ - _bad_random_mac_filter is failed
+ - "_bad_random_mac_filter.msg is match('Invalid value (.*) for random_mac: 5 colon.* separated items max')"
+
+- name: Verify random_mac filter
+ assert:
+ that:
+ - "'00' | community.general.random_mac is match('^00:[a-f0-9][a-f0-9]:[a-f0-9][a-f0-9]:[a-f0-9][a-f0-9]:[a-f0-9][a-f0-9]:[a-f0-9][a-f0-9]$')"
+ - "'00:00' | community.general.random_mac is match('^00:00:[a-f0-9][a-f0-9]:[a-f0-9][a-f0-9]:[a-f0-9][a-f0-9]:[a-f0-9][a-f0-9]$')"
+ - "'00:00:00' | community.general.random_mac is match('^00:00:00:[a-f0-9][a-f0-9]:[a-f0-9][a-f0-9]:[a-f0-9][a-f0-9]$')"
+ - "'00:00:00:00' | community.general.random_mac is match('^00:00:00:[a-f0-9][a-f0-9]:[a-f0-9][a-f0-9]:[a-f0-9][a-f0-9]$')"
+ - "'00:00:00:00:00' | community.general.random_mac is match('^00:00:00:00:00:[a-f0-9][a-f0-9]$')"
+ - "'00:00:00' | community.general.random_mac != '00:00:00' | community.general.random_mac"
+
+- name: Verify random_mac filter with seed
+ assert:
+ that:
+ - "'00:00:00' | community.general.random_mac(seed='test') == '00:00:00' | community.general.random_mac(seed='test')"
+ - "'00:00:00' | community.general.random_mac(seed='test') != '00:00:00' | community.general.random_mac(seed='another_test')"
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_time/aliases b/ansible_collections/community/general/tests/integration/targets/filter_time/aliases
new file mode 100644
index 000000000..bc9b4bc99
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_time/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+skip/python2.6 # filters are controller only, and we no longer support Python 2.6 on the controller
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_time/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_time/tasks/main.yml
new file mode 100644
index 000000000..3b6539499
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_time/tasks/main.yml
@@ -0,0 +1,115 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: test zero is 0
+ assert:
+ that:
+ - "('0' | community.general.to_milliseconds) == 0"
+ - "('0' | community.general.to_seconds) == 0"
+ - "('0' | community.general.to_minutes) == 0"
+
+- name: test to_milliseconds filter
+ assert:
+ that:
+ - "('1000ms' | community.general.to_milliseconds) == 1000"
+ - "('1s' | community.general.to_milliseconds) == 1000"
+ - "('1m' | community.general.to_milliseconds) == 60000"
+
+- name: test to_seconds filter
+ assert:
+ that:
+ - "('1000msecs' | community.general.to_seconds) == 1"
+ - "('1ms' | community.general.to_seconds) == 0.001"
+ - "('12m' | community.general.to_seconds) == 720"
+ - "('300minutes' | community.general.to_seconds) == 18000"
+ - "('3h 12m' | community.general.to_seconds) == 11520"
+ - "('2days 3hours 12mins 15secs' | community.general.to_seconds) == 184335"
+ - "('2d -2d -12s' | community.general.to_seconds) == -12"
+
+- name: test to_minutes filter
+ assert:
+ that:
+ - "('30s' | community.general.to_minutes) == 0.5"
+ - "('12m' | community.general.to_minutes) == 12"
+ - "('3h 72m' | community.general.to_minutes) == 252"
+ - "('300s' | community.general.to_minutes) == 5"
+
+- name: test to_hours filter
+ assert:
+ that:
+ - "('30m' | community.general.to_hours) == 0.5"
+ - "('3h 119m 61s' | community.general.to_hours) > 5"
+
+- name: test to_days filter
+ assert:
+ that:
+ - "('1year' | community.general.to_days) == 365"
+ - "('1week' | community.general.to_days) == 7"
+ - "('2weeks' | community.general.to_days) == 14"
+ - "('1mo' | community.general.to_days) == 30"
+ - "('1mo' | community.general.to_days(month=28)) == 28"
+
+- name: test to_weeks filter
+ assert:
+ that:
+ - "('1y' | community.general.to_weeks | int) == 52"
+ - "('7d' | community.general.to_weeks) == 1"
+ - "('1mo' | community.general.to_weeks(month=28)) == 4"
+
+- name: test to_months filter
+ assert:
+ that:
+ - "('30d' | community.general.to_months) == 1"
+ - "('1year' | community.general.to_months | int) == 12"
+ - "('5years' | community.general.to_months(month=30, year=360)) == 60"
+ - "('1years' | community.general.to_months(month=2, year=34)) == 17"
+
+- name: test to_years filter
+ assert:
+ that:
+ - "('365d' | community.general.to_years | int) == 1"
+ - "('12mo' | community.general.to_years | round(0, 'ceil')) == 1"
+ - "('24mo' | community.general.to_years(month=30, year=360)) == 2"
+
+- name: test fail unknown unit
+ debug:
+ msg: "{{ '1s' | community.general.to_time_unit('lightyears') }}"
+ ignore_errors: true
+ register: res
+
+- name: verify test fail unknown unit
+ assert:
+ that:
+ - res is failed
+ - "'to_time_unit() can not convert to the following unit: lightyears' in res.msg"
+
+- name: test fail unknown string
+ debug:
+ msg: "{{ '1 s' | community.general.to_time_unit('s') }}"
+ ignore_errors: true
+ register: res
+
+- name: test fail unknown string
+ assert:
+ that:
+ - res is failed
+ - "'to_time_unit() can not interpret following string' in res.msg"
+
+- name: test fail unknown kwarg
+ debug:
+ msg: "{{ '1s' | community.general.to_time_unit('s', second=23) }}"
+ ignore_errors: true
+ register: res
+
+- name: test fail unknown kwarg
+ assert:
+ that:
+ - res is failed
+ - "'to_time_unit() got unknown keyword arguments' in res.msg"
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_unicode_normalize/aliases b/ansible_collections/community/general/tests/integration/targets/filter_unicode_normalize/aliases
new file mode 100644
index 000000000..bc9b4bc99
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_unicode_normalize/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+skip/python2.6 # filters are controller only, and we no longer support Python 2.6 on the controller
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_unicode_normalize/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_unicode_normalize/tasks/main.yml
new file mode 100644
index 000000000..13902706e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_unicode_normalize/tasks/main.yml
@@ -0,0 +1,44 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Test 'NFC' normalization
+ assert:
+ that:
+ - u_umlaut != u_umlaut_combining
+ - u_umlaut_combining != (u_umlaut_combining | community.general.unicode_normalize)
+ - u_umlaut == (u_umlaut_combining | community.general.unicode_normalize)
+
+- name: Test 'NFKC' normalization
+ assert:
+ that:
+ - latin_capital_i != roman_numeral_one
+ - latin_capital_i == (roman_numeral_one | community.general.unicode_normalize(form='NFKC'))
+
+- name: Register invalid input type
+ debug:
+ msg: "{{ 1 | community.general.unicode_normalize }}"
+ ignore_errors: true
+ register: invalid_input_type
+
+- name: Assert an invalid input type causes failure
+ assert:
+ that:
+ - invalid_input_type is failed
+
+- name: Register invalid form selection
+ debug:
+ msg: "{{ 'arbitrary text' | community.general.unicode_normalize(form='invalid') }}"
+ ignore_errors: true
+ register: invalid_form_selection
+
+- name: Assert invalid form selection causes failure
+ assert:
+ that:
+ - invalid_form_selection is failed
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_unicode_normalize/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_unicode_normalize/vars/main.yml
new file mode 100644
index 000000000..ed4e2968b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_unicode_normalize/vars/main.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+u_umlaut: "{{ '\u00fc' }}"
+u_umlaut_combining: "{{ 'u' + '\u0308' }}"
+roman_numeral_one: "{{ '\u2160' }}"
+latin_capital_i: "{{ '\u0049' }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_version_sort/aliases b/ansible_collections/community/general/tests/integration/targets/filter_version_sort/aliases
new file mode 100644
index 000000000..bc9b4bc99
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_version_sort/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+skip/python2.6 # filters are controller only, and we no longer support Python 2.6 on the controller
diff --git a/ansible_collections/community/general/tests/integration/targets/filter_version_sort/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/filter_version_sort/tasks/main.yml
new file mode 100644
index 000000000..08985d1ba
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/filter_version_sort/tasks/main.yml
@@ -0,0 +1,14 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: validate that versions are properly sorted in a stable way
+ assert:
+ that:
+ - "['a-1.9.rpm', 'a-1.10-1.rpm', 'a-1.09.rpm', 'b-1.01.rpm', 'a-2.1-0.rpm', 'a-1.10-0.rpm'] | community.general.version_sort == ['a-1.9.rpm', 'a-1.09.rpm', 'a-1.10-0.rpm', 'a-1.10-1.rpm', 'a-2.1-0.rpm', 'b-1.01.rpm']"
diff --git a/ansible_collections/community/general/tests/integration/targets/flatpak/aliases b/ansible_collections/community/general/tests/integration/targets/flatpak/aliases
new file mode 100644
index 000000000..e462ed8cb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/flatpak/aliases
@@ -0,0 +1,12 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/3
+destructive
+skip/aix
+skip/freebsd
+skip/osx
+skip/macos
+skip/rhel
+needs/root
diff --git a/ansible_collections/community/general/tests/integration/targets/flatpak/files/serve.py b/ansible_collections/community/general/tests/integration/targets/flatpak/files/serve.py
new file mode 100644
index 000000000..93df1036e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/flatpak/files/serve.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# -*- coding: utf-8 -*-
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+import os
+import posixpath
+import sys
+
+try:
+ from http.server import SimpleHTTPRequestHandler, HTTPServer
+ from urllib.parse import unquote
+except ImportError:
+ from SimpleHTTPServer import SimpleHTTPRequestHandler
+ from BaseHTTPServer import HTTPServer
+ from urllib import unquote
+
+
+# Argument parsing
+if len(sys.argv) != 4:
+ print('Syntax: {0} <bind> <port> <path>'.format(sys.argv[0]))
+ sys.exit(-1)
+
+HOST, PORT, PATH = sys.argv[1:4]
+PORT = int(PORT)
+
+
+# The HTTP request handler
+class Handler(SimpleHTTPRequestHandler):
+ def translate_path(self, path):
+ # Modified from Python 3.6's version of SimpleHTTPRequestHandler
+ # to support using another base directory than CWD.
+
+ # abandon query parameters
+ path = path.split('?', 1)[0]
+ path = path.split('#', 1)[0]
+ # Don't forget explicit trailing slash when normalizing. Issue17324
+ trailing_slash = path.rstrip().endswith('/')
+ try:
+ path = unquote(path, errors='surrogatepass')
+ except (UnicodeDecodeError, TypeError) as exc:
+ path = unquote(path)
+ path = posixpath.normpath(path)
+ words = path.split('/')
+ words = filter(None, words)
+ path = PATH
+ for word in words:
+ if os.path.dirname(word) or word in (os.curdir, os.pardir):
+ # Ignore components that are not a simple file/directory name
+ continue
+ path = os.path.join(path, word)
+ if trailing_slash:
+ path += '/'
+ return path
+
+
+# Run simple HTTP server
+httpd = HTTPServer((HOST, PORT), Handler)
+
+try:
+ httpd.serve_forever()
+except KeyboardInterrupt:
+ pass
+
+httpd.server_close()
diff --git a/ansible_collections/community/general/tests/integration/targets/flatpak/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/flatpak/meta/main.yml
new file mode 100644
index 000000000..0ac87654d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/flatpak/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_flatpak_remote
diff --git a/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/check_mode.yml b/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/check_mode.yml
new file mode 100644
index 000000000..9f52dc122
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/check_mode.yml
@@ -0,0 +1,197 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# - Tests with absent flatpak --------------------------------------------------
+
+# state=present on absent flatpak
+
+- name: Test addition of absent flatpak (check mode)
+ flatpak:
+ name: com.dummy.App1
+ remote: dummy-remote
+ state: present
+ register: addition_result
+ check_mode: true
+
+- name: Verify addition of absent flatpak test result (check mode)
+ assert:
+ that:
+ - addition_result is changed
+ msg: "Adding an absent flatpak shall mark module execution as changed"
+
+- name: Test non-existent idempotency of addition of absent flatpak (check mode)
+ flatpak:
+ name: com.dummy.App1
+ remote: dummy-remote
+ state: present
+ register: double_addition_result
+ check_mode: true
+
+- name: Verify non-existent idempotency of addition of absent flatpak test result (check mode)
+ assert:
+ that:
+ - double_addition_result is changed
+ msg: |
+ Adding an absent flatpak a second time shall still mark module execution
+ as changed in check mode
+
+# state=absent on absent flatpak
+
+- name: Test removal of absent flatpak check mode
+ flatpak:
+ name: com.dummy.App1
+ state: absent
+ register: removal_result
+ check_mode: true
+
+- name: Verify removal of absent flatpak test result (check mode)
+ assert:
+ that:
+ - removal_result is not changed
+ msg: "Removing an absent flatpak shall mark module execution as not changed"
+
+# state=present with url on absent flatpak
+
+- name: Test addition of absent flatpak with url (check mode)
+ flatpak:
+ name: http://127.0.0.1:8000/repo/com.dummy.App1.flatpakref
+ remote: dummy-remote
+ state: present
+ register: url_addition_result
+ check_mode: true
+
+- name: Verify addition of absent flatpak with url test result (check mode)
+ assert:
+ that:
+ - url_addition_result is changed
+ msg: "Adding an absent flatpak from URL shall mark module execution as changed"
+
+- name: Test non-existent idempotency of addition of absent flatpak with url (check mode)
+ flatpak:
+ name: http://127.0.0.1:8000/repo/com.dummy.App1.flatpakref
+ remote: dummy-remote
+ state: present
+ register: double_url_addition_result
+ check_mode: true
+
+- name: >
+ Verify non-existent idempotency of additionof absent flatpak with url test
+ result (check mode)
+ assert:
+ that:
+ - double_url_addition_result is changed
+ msg: |
+ Adding an absent flatpak from URL a second time shall still mark module execution
+ as changed in check mode
+
+# state=absent with url on absent flatpak
+
+- name: Test removal of absent flatpak with url not doing anything (check mode)
+ flatpak:
+ name: http://127.0.0.1:8000/repo/com.dummy.App1.flatpakref
+ state: absent
+ register: url_removal_result
+ check_mode: true
+
+- name: Verify removal of absent flatpak with url test result (check mode)
+ assert:
+ that:
+ - url_removal_result is not changed
+ msg: "Removing an absent flatpak shall mark module execution as not changed"
+
+# - Tests with present flatpak -------------------------------------------------
+
+# state=present on present flatpak
+
+- name: Test addition of present flatpak (check mode)
+ flatpak:
+ name: com.dummy.App2
+ remote: dummy-remote
+ state: present
+ register: addition_present_result
+ check_mode: true
+
+- name: Verify addition test result of present flatpak (check mode)
+ assert:
+ that:
+ - addition_present_result is not changed
+ msg: "Adding an present flatpak shall mark module execution as not changed"
+
+# state=absent on present flatpak
+
+- name: Test removal of present flatpak (check mode)
+ flatpak:
+ name: com.dummy.App2
+ state: absent
+ register: removal_present_result
+ check_mode: true
+
+- name: Verify removal of present flatpak test result (check mode)
+ assert:
+ that:
+ - removal_present_result is changed
+ msg: "Removing a present flatpak shall mark module execution as changed"
+
+- name: Test non-existent idempotency of removal (check mode)
+ flatpak:
+ name: com.dummy.App2
+ state: absent
+ register: double_removal_present_result
+ check_mode: true
+
+- name: Verify non-existent idempotency of removal (check mode)
+ assert:
+ that:
+ - double_removal_present_result is changed
+ msg: |
+ Removing a present flatpak a second time shall still mark module execution
+ as changed in check mode
+
+# state=present with url on present flatpak
+
+- name: Test addition with url of present flatpak (check mode)
+ flatpak:
+ name: http://127.0.0.1:8000/repo/com.dummy.App2.flatpakref
+ remote: dummy-remote
+ state: present
+ register: url_addition_present_result
+ check_mode: true
+
+- name: Verify addition with url of present flatpak test result (check mode)
+ assert:
+ that:
+ - url_addition_present_result is not changed
+ msg: "Adding a present flatpak from URL shall mark module execution as not changed"
+
+# state=absent with url on present flatpak
+
+- name: Test removal with url of present flatpak (check mode)
+ flatpak:
+ name: http://127.0.0.1:8000/repo/com.dummy.App2.flatpakref
+ state: absent
+ register: url_removal_present_result
+ check_mode: true
+
+- name: Verify removal with url of present flatpak test result (check mode)
+ assert:
+ that:
+ - url_removal_present_result is changed
+ msg: "Removing an absent flatpak shall mark module execution as not changed"
+
+- name: Test non-existent idempotency of removal with url of present flatpak (check mode)
+ flatpak:
+ name: http://127.0.0.1:8000/repo/com.dummy.App2.flatpakref
+ remote: dummy-remote
+ state: absent
+ register: double_url_removal_present_result
+ check_mode: true
+
+- name: >
+ Verify non-existent idempotency of installation with url of present
+ flatpak test result (check mode)
+ assert:
+ that:
+ - double_url_removal_present_result is changed
+ msg: Removing an absent flatpak a second time shall still mark module execution as changed
diff --git a/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/main.yml
new file mode 100644
index 000000000..deaf354e8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/main.yml
@@ -0,0 +1,64 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2018, Alexander Bethke <oolongbrothers@gmx.net>
+# Copyright (c) 2018, Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- block:
+
+ - import_tasks: setup.yml
+ become: true
+
+ # executable override
+
+ - name: Test executable override
+ flatpak:
+ name: com.dummy.App1
+ remote: dummy-remote
+ state: present
+ executable: nothing-that-exists
+ ignore_errors: true
+ register: executable_override_result
+
+ - name: Verify executable override test result
+ assert:
+ that:
+ - executable_override_result is failed
+ - executable_override_result is not changed
+ msg: "Specifying non-existing executable shall fail module execution"
+
+ - import_tasks: check_mode.yml
+ become: false
+
+ - import_tasks: test.yml
+ become: false
+ vars:
+ method: user
+
+ - import_tasks: test.yml
+ become: true
+ vars:
+ method: system
+
+ always:
+
+ - name: Check HTTP server status
+ async_status:
+ jid: "{{ webserver_status.ansible_job_id }}"
+ ignore_errors: true
+
+ - name: List processes
+ command: ps aux
+
+ - name: Stop HTTP server
+ command: >-
+ pkill -f -- '{{ remote_tmp_dir }}/serve.py'
+
+ when: |
+ ansible_distribution == 'Fedora' or
+ ansible_distribution == 'Ubuntu' and not ansible_distribution_major_version | int < 16
diff --git a/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/setup.yml b/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/setup.yml
new file mode 100644
index 000000000..4dfdd68cb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/setup.yml
@@ -0,0 +1,68 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install flatpak on Fedora
+ dnf:
+ name: flatpak
+ state: present
+ become: true
+ when: ansible_distribution == 'Fedora'
+
+- block:
+ - name: Activate flatpak ppa on Ubuntu
+ apt_repository:
+ repo: ppa:alexlarsson/flatpak
+ state: present
+ mode: '0644'
+ when: ansible_lsb.major_release | int < 18
+
+ - name: Install flatpak package on Ubuntu
+ apt:
+ name: flatpak
+ state: present
+
+ when: ansible_distribution == 'Ubuntu'
+
+- name: Install dummy remote for user
+ flatpak_remote:
+ name: dummy-remote
+ state: present
+ flatpakrepo_url: /tmp/flatpak/repo/dummy-repo.flatpakrepo
+ method: user
+
+- name: Install dummy remote for system
+ flatpak_remote:
+ name: dummy-remote
+ state: present
+ flatpakrepo_url: /tmp/flatpak/repo/dummy-repo.flatpakrepo
+ method: system
+
+- name: Remove (if necessary) flatpak for testing check mode on absent flatpak
+ flatpak:
+ name:
+ - com.dummy.App1
+ - com.dummy.App3
+ remote: dummy-remote
+ state: absent
+ no_dependencies: true
+
+- name: Add flatpak for testing check mode on present flatpak
+ flatpak:
+ name: com.dummy.App2
+ remote: dummy-remote
+ state: present
+ no_dependencies: true
+
+- name: Copy HTTP server
+ copy:
+ src: serve.py
+ dest: '{{ remote_tmp_dir }}/serve.py'
+ mode: '0755'
+
+- name: Start HTTP server
+ command: '{{ ansible_python.executable }} {{ remote_tmp_dir }}/serve.py 127.0.0.1 8000 /tmp/flatpak/'
+ async: 120
+ poll: 0
+ register: webserver_status
diff --git a/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/test.yml b/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/test.yml
new file mode 100644
index 000000000..29c4efbe9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/flatpak/tasks/test.yml
@@ -0,0 +1,289 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# state=present
+
+- name: Test addition - {{ method }}
+ flatpak:
+ name: com.dummy.App1
+ remote: dummy-remote
+ state: present
+ method: "{{ method }}"
+ no_dependencies: true
+ register: addition_result
+
+- name: Verify addition test result - {{ method }}
+ assert:
+ that:
+ - addition_result is changed
+ msg: "state=present shall add flatpak when absent"
+
+- name: Test idempotency of addition - {{ method }}
+ flatpak:
+ name: com.dummy.App1
+ remote: dummy-remote
+ state: present
+ method: "{{ method }}"
+ no_dependencies: true
+ register: double_addition_result
+
+- name: Verify idempotency of addition test result - {{ method }}
+ assert:
+ that:
+ - double_addition_result is not changed
+ msg: "state=present shall not do anything when flatpak is already present"
+
+# state=absent
+
+- name: Test removal - {{ method }}
+ flatpak:
+ name: com.dummy.App1
+ state: absent
+ method: "{{ method }}"
+ no_dependencies: true
+ register: removal_result
+
+- name: Verify removal test result - {{ method }}
+ assert:
+ that:
+ - removal_result is changed
+ msg: "state=absent shall remove flatpak when present"
+
+- name: Test idempotency of removal - {{ method }}
+ flatpak:
+ name: com.dummy.App1
+ state: absent
+ method: "{{ method }}"
+ no_dependencies: true
+ register: double_removal_result
+
+- name: Verify idempotency of removal test result - {{ method }}
+ assert:
+ that:
+ - double_removal_result is not changed
+ msg: "state=absent shall not do anything when flatpak is not present"
+
+# state=present with url as name
+
+- name: Test addition with url - {{ method }}
+ flatpak:
+ name: http://127.0.0.1:8000/repo/com.dummy.App1.flatpakref
+ remote: dummy-remote
+ state: present
+ method: "{{ method }}"
+ no_dependencies: true
+ register: url_addition_result
+
+- name: Verify addition test result - {{ method }}
+ assert:
+ that:
+ - url_addition_result is changed
+ msg: "state=present with url as name shall add flatpak when absent"
+
+- name: Test idempotency of addition with url - {{ method }}
+ flatpak:
+ name: http://127.0.0.1:8000/repo/com.dummy.App1.flatpakref
+ remote: dummy-remote
+ state: present
+ method: "{{ method }}"
+ no_dependencies: true
+ register: double_url_addition_result
+
+- name: Verify idempotency of addition with url test result - {{ method }}
+ assert:
+ that:
+ - double_url_addition_result is not changed
+ msg: "state=present with url as name shall not do anything when flatpak is already present"
+
+# state=absent with url as name
+
+- name: Test removal with url - {{ method }}
+ flatpak:
+ name: http://127.0.0.1:8000/repo/com.dummy.App1.flatpakref
+ state: absent
+ method: "{{ method }}"
+ no_dependencies: true
+ register: url_removal_result
+ ignore_errors: true
+
+- name: Verify removal test result failed - {{ method }}
+ # It looks like flatpak has a bug when the hostname contains a port. If this is the case, it emits
+ # the following message, which we check for. If another error happens, we fail.
+ # Upstream issue: https://github.com/flatpak/flatpak/issues/4307
+ # (The second message happens with Ubuntu 18.04.)
+ assert:
+ that:
+ - >-
+ url_removal_result.msg in [
+ "error: Invalid branch 127.0.0.1:8000: Branch can't contain :",
+ "error: Invalid id http:: Name can't contain :",
+ ]
+ when: url_removal_result is failed
+
+- when: url_removal_result is not failed
+ block:
+
+ - name: Verify removal test result - {{ method }}
+ assert:
+ that:
+ - url_removal_result is changed
+ msg: "state=absent with url as name shall remove flatpak when present"
+
+ - name: Test idempotency of removal with url - {{ method }}
+ flatpak:
+ name: http://127.0.0.1:8000/repo/com.dummy.App1.flatpakref
+ state: absent
+ method: "{{ method }}"
+ no_dependencies: true
+ register: double_url_removal_result
+
+ - name: Verify idempotency of removal with url test result - {{ method }}
+ assert:
+ that:
+ - double_url_removal_result is not changed
+ msg: "state=absent with url as name shall not do anything when flatpak is not present"
+
+- name: Make sure flatpak is really gone - {{ method }}
+ flatpak:
+ name: com.dummy.App1
+ state: absent
+ method: "{{ method }}"
+ no_dependencies: true
+
+# state=present with list of packages
+
+- name: Test addition with list - {{ method }}
+ flatpak:
+ name:
+ - com.dummy.App1
+ - http://127.0.0.1:8000/repo/com.dummy.App2.flatpakref
+ remote: dummy-remote
+ state: present
+ method: "{{ method }}"
+ no_dependencies: true
+ register: addition_result
+
+- name: Verify addition with list test result - {{ method }}
+ assert:
+ that:
+ - addition_result is changed
+ msg: "state=present shall add flatpak when absent"
+
+- name: Test idempotency of addition with list - {{ method }}
+ flatpak:
+ name:
+ - com.dummy.App1
+ - http://127.0.0.1:8000/repo/com.dummy.App2.flatpakref
+ remote: dummy-remote
+ state: present
+ method: "{{ method }}"
+ no_dependencies: true
+ register: double_addition_result
+
+- name: Verify idempotency of addition with list test result - {{ method }}
+ assert:
+ that:
+ - double_addition_result is not changed
+ msg: "state=present shall not do anything when flatpak is already present"
+
+- name: Test addition with list partially installed - {{ method }}
+ flatpak:
+ name:
+ - com.dummy.App1
+ - http://127.0.0.1:8000/repo/com.dummy.App2.flatpakref
+ - com.dummy.App3
+ remote: dummy-remote
+ state: present
+ method: "{{ method }}"
+ no_dependencies: true
+ register: addition_result
+
+- name: Verify addition with list partially installed test result - {{ method }}
+ assert:
+ that:
+ - addition_result is changed
+ msg: "state=present shall add flatpak when absent"
+
+- name: Test idempotency of addition with list partially installed - {{ method }}
+ flatpak:
+ name:
+ - com.dummy.App1
+ - http://127.0.0.1:8000/repo/com.dummy.App2.flatpakref
+ - com.dummy.App3
+ remote: dummy-remote
+ state: present
+ method: "{{ method }}"
+ no_dependencies: true
+ register: double_addition_result
+
+- name: Verify idempotency of addition with list partially installed test result - {{ method }}
+ assert:
+ that:
+ - double_addition_result is not changed
+ msg: "state=present shall not do anything when flatpak is already present"
+
+# state=absent with list of packages
+
+- name: Test removal with list - {{ method }}
+ flatpak:
+ name:
+ - com.dummy.App1
+ - com.dummy.App2
+ state: absent
+ method: "{{ method }}"
+ register: removal_result
+
+- name: Verify removal with list test result - {{ method }}
+ assert:
+ that:
+ - removal_result is changed
+ msg: "state=absent shall remove flatpak when present"
+
+- name: Test idempotency of removal with list - {{ method }}
+ flatpak:
+ name:
+ - com.dummy.App1
+ - com.dummy.App2
+ state: absent
+ method: "{{ method }}"
+ register: double_removal_result
+
+- name: Verify idempotency of removal with list test result - {{ method }}
+ assert:
+ that:
+ - double_removal_result is not changed
+ msg: "state=absent shall not do anything when flatpak is not present"
+
+- name: Test removal with list partially removed - {{ method }}
+ flatpak:
+ name:
+ - com.dummy.App1
+ - com.dummy.App2
+ - com.dummy.App3
+ state: absent
+ method: "{{ method }}"
+ register: removal_result
+
+- name: Verify removal with list partially removed test result - {{ method }}
+ assert:
+ that:
+ - removal_result is changed
+ msg: "state=absent shall remove flatpak when present"
+
+- name: Test idempotency of removal with list partially removed - {{ method }}
+ flatpak:
+ name:
+ - com.dummy.App1
+ - com.dummy.App2
+ - com.dummy.App3
+ state: absent
+ method: "{{ method }}"
+ register: double_removal_result
+
+- name: Verify idempotency of removal with list partially removed test result - {{ method }}
+ assert:
+ that:
+ - double_removal_result is not changed
+ msg: "state=absent shall not do anything when flatpak is not present"
diff --git a/ansible_collections/community/general/tests/integration/targets/flatpak_remote/aliases b/ansible_collections/community/general/tests/integration/targets/flatpak_remote/aliases
new file mode 100644
index 000000000..e462ed8cb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/flatpak_remote/aliases
@@ -0,0 +1,12 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/3
+destructive
+skip/aix
+skip/freebsd
+skip/osx
+skip/macos
+skip/rhel
+needs/root
diff --git a/ansible_collections/community/general/tests/integration/targets/flatpak_remote/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/flatpak_remote/meta/main.yml
new file mode 100644
index 000000000..0ac87654d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/flatpak_remote/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_flatpak_remote
diff --git a/ansible_collections/community/general/tests/integration/targets/flatpak_remote/tasks/check_mode.yml b/ansible_collections/community/general/tests/integration/targets/flatpak_remote/tasks/check_mode.yml
new file mode 100644
index 000000000..86db5bf56
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/flatpak_remote/tasks/check_mode.yml
@@ -0,0 +1,206 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# - Tests with absent flatpak remote -------------------------------------------
+
+# state=present
+
+- name: Test addition of absent flatpak remote (check mode)
+ flatpak_remote:
+ name: flatpak-test
+ flatpakrepo_url: /tmp/flatpak/repo/dummy-repo.flatpakrepo
+ state: present
+ register: addition_result
+ check_mode: true
+
+- name: Verify addition of absent flatpak remote test result (check mode)
+ assert:
+ that:
+ - addition_result is changed
+ msg: "Adding an absent flatpak remote shall mark module execution as changed"
+
+- name: Test non-existent idempotency of addition of absent flatpak remote (check mode)
+ flatpak_remote:
+ name: flatpak-test
+ flatpakrepo_url: /tmp/flatpak/repo/dummy-repo.flatpakrepo
+ state: present
+ register: double_addition_result
+ check_mode: true
+
+- name: >
+ Verify non-existent idempotency of addition of absent flatpak remote
+ test result (check mode)
+ assert:
+ that:
+ - double_addition_result is changed
+ msg: |
+ Adding an absent flatpak remote a second time shall still mark module execution
+ as changed in check mode
+
+# state=absent
+
+- name: Test removal of absent flatpak remote not doing anything in check mode
+ flatpak_remote:
+ name: flatpak-test
+ state: absent
+ register: removal_result
+ check_mode: true
+
+- name: Verify removal of absent flatpak remote test result (check mode)
+ assert:
+ that:
+ - removal_result is not changed
+ msg: "Removing an absent flatpak remote shall mark module execution as not changed"
+
+
+# - Tests with present flatpak remote -------------------------------------------
+
+# state=present
+
+- name: Test addition of present flatpak remote (check mode)
+ flatpak_remote:
+ name: check-mode-test-remote
+ flatpakrepo_url: /tmp/flatpak/repo/dummy-repo.flatpakrepo
+ state: present
+ register: addition_result
+ check_mode: true
+
+- name: Verify addition of present flatpak remote test result (check mode)
+ assert:
+ that:
+ - addition_result is not changed
+ msg: "Adding a present flatpak remote shall mark module execution as not changed"
+
+# state=absent
+
+- name: Test removal of present flatpak remote not doing anything in check mode
+ flatpak_remote:
+ name: check-mode-test-remote
+ state: absent
+ register: removal_result
+ check_mode: true
+
+- name: Verify removal of present flatpak remote test result (check mode)
+ assert:
+ that:
+ - removal_result is changed
+ msg: "Removing a present flatpak remote shall mark module execution as changed"
+
+- name: Test non-existent idempotency of removal of present flatpak remote (check mode)
+ flatpak_remote:
+ name: check-mode-test-remote
+ state: absent
+ register: double_removal_result
+ check_mode: true
+
+- name: >
+ Verify non-existent idempotency of removal of present flatpak remote
+ test result (check mode)
+ assert:
+ that:
+ - double_removal_result is changed
+ msg: |
+ Removing a present flatpak remote a second time shall still mark module execution
+ as changed in check mode
+
+
+# - Tests with disabled flatpak remote ------------------------------------------
+
+# enabled=true
+
+- name: Test activation of disabled flatpak remote (check mode)
+ flatpak_remote:
+ name: check-mode-disabled-test-remote
+ enabled: true
+ register: activation_result
+ check_mode: true
+
+- name: Verify activation of disabled flatpak remote test result (check mode)
+ assert:
+ that:
+ - activation_result is changed
+ msg: "Enabling an disabled flatpak remote shall mark module execution as changed"
+
+- name: Test non-existent idempotency of activation of disabled flatpak remote (check mode)
+ flatpak_remote:
+ name: check-mode-disabled-test-remote
+ enabled: true
+ register: double_activation_result
+ check_mode: true
+
+- name: >
+ Verify non-existent idempotency of activation of disabled flatpak remote
+ test result (check mode)
+ assert:
+ that:
+ - double_activation_result is changed
+ msg: |
+ Enabling an disabled flatpak remote a second time shall still mark module execution
+ as changed in check mode
+
+# enabled=false
+
+- name: Test deactivation of disabled flatpak remote not doing anything in check mode
+ flatpak_remote:
+ name: check-mode-disabled-test-remote
+ enabled: false
+ register: deactivation_result
+ check_mode: true
+
+- name: Verify deactivation of disabled flatpak remote test result (check mode)
+ assert:
+ that:
+ - deactivation_result is not changed
+ msg: "Disabling an disabled flatpak remote shall mark module execution as not changed"
+
+
+# - Tests with enabled flatpak remote ------------------------------------------
+
+# enabled=true
+
+- name: Test activation of enabled flatpak remote (check mode)
+ flatpak_remote:
+ name: check-mode-enabled-test-remote
+ enabled: true
+ register: activation_result
+ check_mode: true
+
+- name: Verify activation of enabled flatpak remote test result (check mode)
+ assert:
+ that:
+ - activation_result is not changed
+ msg: "Enabling a enabled flatpak remote shall mark module execution as not changed"
+
+# enabled=false
+
+- name: Test deactivation of enabled flatpak remote not doing anything in check mode
+ flatpak_remote:
+ name: check-mode-enabled-test-remote
+ enabled: false
+ register: deactivation_result
+ check_mode: true
+
+- name: Verify deactivation of enabled flatpak remote test result (check mode)
+ assert:
+ that:
+ - deactivation_result is changed
+ msg: "Disabling a enabled flatpak remote shall mark module execution as changed"
+
+- name: Test non-existent idempotency of deactivation of enabled flatpak remote (check mode)
+ flatpak_remote:
+ name: check-mode-enabled-test-remote
+ enabled: false
+ register: double_deactivation_result
+ check_mode: true
+
+- name: >
+ Verify non-existent idempotency of deactivation of enabled flatpak remote
+ test result (check mode)
+ assert:
+ that:
+ - double_deactivation_result is changed
+ msg: |
+ "Disabling a enabled flatpak remote a second time shall still mark module execution
+ as changed in check mode
diff --git a/ansible_collections/community/general/tests/integration/targets/flatpak_remote/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/flatpak_remote/tasks/main.yml
new file mode 100644
index 000000000..1c5091232
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/flatpak_remote/tasks/main.yml
@@ -0,0 +1,50 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2018, Alexander Bethke <oolongbrothers@gmx.net>
+# Copyright (c) 2018, Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- block:
+
+ - import_tasks: setup.yml
+ become: true
+
+ # executable override
+
+ - name: Test executable override
+ flatpak_remote:
+ name: irrelevant
+ remote: irrelevant
+ state: present
+ executable: nothing-that-exists
+ ignore_errors: true
+ register: executable_override_result
+
+ - name: Verify executable override test result
+ assert:
+ that:
+ - executable_override_result is failed
+ - executable_override_result is not changed
+ msg: "Specifying non-existing executable shall fail module execution"
+
+ - import_tasks: check_mode.yml
+ become: false
+
+ - import_tasks: test.yml
+ become: false
+ vars:
+ method: user
+
+ - import_tasks: test.yml
+ become: true
+ vars:
+ method: system
+
+ when: |
+ ansible_distribution == 'Fedora' or
+ ansible_distribution == 'Ubuntu' and not ansible_distribution_major_version | int < 16
diff --git a/ansible_collections/community/general/tests/integration/targets/flatpak_remote/tasks/setup.yml b/ansible_collections/community/general/tests/integration/targets/flatpak_remote/tasks/setup.yml
new file mode 100644
index 000000000..55a14c972
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/flatpak_remote/tasks/setup.yml
@@ -0,0 +1,40 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install flatpak on Fedora
+ dnf:
+ name: flatpak
+ state: present
+ when: ansible_distribution == 'Fedora'
+- block:
+ - name: Activate flatpak ppa on Ubuntu versions older than 18.04/bionic
+ apt_repository:
+ repo: ppa:alexlarsson/flatpak
+ state: present
+ mode: '0644'
+ when: ansible_lsb.major_release | int < 18
+ - name: Install flatpak package on Ubuntu
+ apt:
+ name: flatpak
+ state: present
+ when: ansible_distribution == 'Ubuntu'
+- name: Install flatpak remote for testing check mode
+ flatpak_remote:
+ name: check-mode-test-remote
+ flatpakrepo_url: /tmp/flatpak/repo/dummy-repo.flatpakrepo
+ state: present
+ enabled: true
+- name: Install disabled flatpak remote for testing check mode
+ flatpak_remote:
+ name: check-mode-disabled-test-remote
+ flatpakrepo_url: /tmp/flatpak/repo/dummy-repo.flatpakrepo
+ state: present
+ enabled: false
+- name: Install enabled flatpak remote for testing check mode
+ flatpak_remote:
+ name: check-mode-enabled-test-remote
+ flatpakrepo_url: /tmp/flatpak/repo/dummy-repo.flatpakrepo
+ state: present
+ enabled: true
diff --git a/ansible_collections/community/general/tests/integration/targets/flatpak_remote/tasks/test.yml b/ansible_collections/community/general/tests/integration/targets/flatpak_remote/tasks/test.yml
new file mode 100644
index 000000000..e847205ff
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/flatpak_remote/tasks/test.yml
@@ -0,0 +1,135 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# state=present
+
+- name: Test addition - {{ method }}
+ flatpak_remote:
+ name: flatpak-test
+ flatpakrepo_url: /tmp/flatpak/repo/dummy-repo.flatpakrepo
+ state: present
+ method: "{{ method }}"
+ register: addition_result
+
+- name: Verify addition test result - {{ method }}
+ assert:
+ that:
+ - addition_result is changed
+ msg: "state=present shall add flatpak when absent"
+
+- name: Test idempotency of addition - {{ method }}
+ flatpak_remote:
+ name: flatpak-test
+ flatpakrepo_url: /tmp/flatpak/repo/dummy-repo.flatpakrepo
+ state: present
+ method: "{{ method }}"
+ register: double_addition_result
+
+- name: Verify idempotency of addition test result - {{ method }}
+ assert:
+ that:
+ - double_addition_result is not changed
+ msg: "state=present shall not do anything when flatpak is already present"
+
+- name: Test updating remote url does not do anything - {{ method }}
+ flatpak_remote:
+ name: flatpak-test
+ flatpakrepo_url: https://a.different/repo.flatpakrepo
+ state: present
+ method: "{{ method }}"
+ register: url_update_result
+
+- name: Verify updating remote url does not do anything - {{ method }}
+ assert:
+ that:
+ - url_update_result is not changed
+ msg: "Trying to update the URL of an existing flatpak remote shall not do anything"
+
+
+# enabled=false
+
+- name: Test deactivation - {{ method }}
+ flatpak_remote:
+ name: flatpak-test
+ enabled: false
+ method: "{{ method }}"
+ register: deactivation_result
+
+- name: Verify deactivation test result - {{ method }}
+ assert:
+ that:
+ - deactivation_result is changed
+ msg: "enable=false shall disable flatpak remote when enabled"
+
+- name: Test idempotency of deactivation - {{ method }}
+ flatpak_remote:
+ name: flatpak-test
+ enabled: false
+ method: "{{ method }}"
+ register: double_deactivation_result
+
+- name: Verify idempotency of deactivation test result - {{ method }}
+ assert:
+ that:
+ - double_deactivation_result is not changed
+ msg: "enabled=false shall not do anything when flatpak remote is already disabled"
+
+
+# enabled=false
+
+- name: Test activation - {{ method }}
+ flatpak_remote:
+ name: flatpak-test
+ enabled: true
+ method: "{{ method }}"
+ register: activation_result
+
+- name: Verify activation test result - {{ method }}
+ assert:
+ that:
+ - activation_result is changed
+ msg: "enable=true shall enable flatpak remote when disabled"
+
+- name: Test idempotency of activation - {{ method }}
+ flatpak_remote:
+ name: flatpak-test
+ enabled: true
+ method: "{{ method }}"
+ register: double_activation_result
+
+- name: Verify idempotency of activation test result - {{ method }}
+ assert:
+ that:
+ - double_activation_result is not changed
+ msg: "enabled=true shall not do anything when flatpak remote is already enabled"
+
+
+# state=absent
+
+- name: Test removal - {{ method }}
+ flatpak_remote:
+ name: flatpak-test
+ state: absent
+ method: "{{ method }}"
+ register: removal_result
+
+- name: Verify removal test result - {{ method }}
+ assert:
+ that:
+ - removal_result is changed
+ msg: "state=absent shall remove flatpak when present"
+
+- name: Test idempotency of removal - {{ method }}
+ flatpak_remote:
+ name: flatpak-test
+ state: absent
+ method: "{{ method }}"
+ register: double_removal_result
+
+- name: Verify idempotency of removal test result - {{ method }}
+ assert:
+ that:
+ - double_removal_result is not changed
+ msg: "state=absent shall not do anything when flatpak is not present"
diff --git a/ansible_collections/community/general/tests/integration/targets/gandi_livedns/aliases b/ansible_collections/community/general/tests/integration/targets/gandi_livedns/aliases
new file mode 100644
index 000000000..f69a127f4
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gandi_livedns/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/gandi
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/gandi_livedns/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/gandi_livedns/defaults/main.yml
new file mode 100644
index 000000000..ec1808d8b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gandi_livedns/defaults/main.yml
@@ -0,0 +1,37 @@
+---
+# Copyright (c) 2020 Gregory Thiemonge <gregory.thiemonge@gmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+gandi_livedns_domain_name: "ansible-tests.org"
+gandi_livedns_record_items:
+
+# Single A record
+- record: test-www
+ type: A
+ values:
+ - 10.10.10.10
+ ttl: 400
+ update_values:
+ - 10.10.10.11
+ update_ttl: 800
+
+# Multiple A records
+- record: test-www-multiple
+ type: A
+ ttl: 3600
+ values:
+ - 10.10.11.10
+ - 10.10.11.10
+ update_values:
+ - 10.10.11.11
+ - 10.10.11.13
+
+# CNAME
+- record: test-cname
+ type: CNAME
+ ttl: 10800
+ values:
+ - test-www2
+ update_values:
+ - test-www
diff --git a/ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/create_record.yml b/ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/create_record.yml
new file mode 100644
index 000000000..c3f1c1798
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/create_record.yml
@@ -0,0 +1,69 @@
+---
+# Copyright (c) 2020 Gregory Thiemonge <gregory.thiemonge@gmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: test absent dns record
+ community.general.gandi_livedns:
+ api_key: "{{ gandi_api_key }}"
+ record: "{{ item.record }}"
+ domain: "{{ gandi_livedns_domain_name }}"
+ type: "{{ item.type }}"
+ ttl: "{{ item.ttl }}"
+ state: absent
+ register: result
+- name: verify test absent dns record
+ assert:
+ that:
+ - result is successful
+
+- name: test create a dns record in check mode
+ community.general.gandi_livedns:
+ api_key: "{{ gandi_api_key }}"
+ record: "{{ item.record }}"
+ domain: "{{ gandi_livedns_domain_name }}"
+ values: "{{ item['values'] }}"
+ ttl: "{{ item.ttl }}"
+ type: "{{ item.type }}"
+ check_mode: true
+ register: result
+- name: verify test create a dns record in check mode
+ assert:
+ that:
+ - result is changed
+
+- name: test create a dns record
+ community.general.gandi_livedns:
+ api_key: "{{ gandi_api_key }}"
+ record: "{{ item.record }}"
+ domain: "{{ gandi_livedns_domain_name }}"
+ values: "{{ item['values'] }}"
+ ttl: "{{ item.ttl }}"
+ type: "{{ item.type }}"
+ register: result
+- name: verify test create a dns record
+ assert:
+ that:
+ - result is changed
+ - result.record['values'] == {{ item['values'] }}
+ - result.record.record == "{{ item.record }}"
+ - result.record.type == "{{ item.type }}"
+ - result.record.ttl == {{ item.ttl }}
+
+- name: test create a dns record idempotence
+ community.general.gandi_livedns:
+ api_key: "{{ gandi_api_key }}"
+ record: "{{ item.record }}"
+ domain: "{{ gandi_livedns_domain_name }}"
+ values: "{{ item['values'] }}"
+ ttl: "{{ item.ttl }}"
+ type: "{{ item.type }}"
+ register: result
+- name: verify test create a dns record idempotence
+ assert:
+ that:
+ - result is not changed
+ - result.record['values'] == {{ item['values'] }}
+ - result.record.record == "{{ item.record }}"
+ - result.record.type == "{{ item.type }}"
+ - result.record.ttl == {{ item.ttl }}
diff --git a/ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/main.yml
new file mode 100644
index 000000000..19ba4d8fb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) 2020 Gregory Thiemonge <gregory.thiemonge@gmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- include_tasks: record.yml
+ with_items: "{{ gandi_livedns_record_items }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/record.yml b/ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/record.yml
new file mode 100644
index 000000000..d36e2e857
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/record.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) 2020 Gregory Thiemonge <gregory.thiemonge@gmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- include_tasks: create_record.yml
+- include_tasks: update_record.yml
+- include_tasks: remove_record.yml
diff --git a/ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/remove_record.yml b/ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/remove_record.yml
new file mode 100644
index 000000000..c4b937fd5
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/remove_record.yml
@@ -0,0 +1,61 @@
+---
+# Copyright (c) 2020 Gregory Thiemonge <gregory.thiemonge@gmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: test remove a dns record in check mode
+ community.general.gandi_livedns:
+ api_key: "{{ gandi_api_key }}"
+ record: "{{ item.record }}"
+ domain: "{{ gandi_livedns_domain_name }}"
+ values: "{{ item.update_values | default(item['values']) }}"
+ type: "{{ item.type }}"
+ state: absent
+ check_mode: true
+ register: result
+- name: verify test remove a dns record in check mode
+ assert:
+ that:
+ - result is changed
+
+- name: test remove a dns record
+ community.general.gandi_livedns:
+ api_key: "{{ gandi_api_key }}"
+ record: "{{ item.record }}"
+ domain: "{{ gandi_livedns_domain_name }}"
+ values: "{{ item.update_values | default(item['values']) }}"
+ type: "{{ item.type }}"
+ state: absent
+ register: result
+- name: verify test remove a dns record
+ assert:
+ that:
+ - result is changed
+
+- name: test remove a dns record idempotence
+ community.general.gandi_livedns:
+ api_key: "{{ gandi_api_key }}"
+ record: "{{ item.record }}"
+ domain: "{{ gandi_livedns_domain_name }}"
+ values: "{{ item.update_values | default(item['values']) }}"
+ type: "{{ item.type }}"
+ state: absent
+ register: result
+- name: verify test remove a dns record idempotence
+ assert:
+ that:
+ - result is not changed
+
+- name: test remove second dns record idempotence
+ community.general.gandi_livedns:
+ api_key: "{{ gandi_api_key }}"
+ record: "{{ item.record }}"
+ domain: "{{ gandi_livedns_domain_name }}"
+ values: "{{ item['values'] }}"
+ type: "{{ item.type }}"
+ state: absent
+ register: result
+- name: verify test remove a dns record idempotence
+ assert:
+ that:
+ - result is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/update_record.yml b/ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/update_record.yml
new file mode 100644
index 000000000..a080560a7
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gandi_livedns/tasks/update_record.yml
@@ -0,0 +1,59 @@
+---
+# Copyright (c) 2020 Gregory Thiemonge <gregory.thiemonge@gmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: test update or add another dns record in check mode
+ community.general.gandi_livedns:
+ api_key: "{{ gandi_api_key }}"
+ record: "{{ item.record }}"
+ domain: "{{ gandi_livedns_domain_name }}"
+ values: "{{ item.update_values | default(item['values']) }}"
+ ttl: "{{ item.update_ttl | default(item.ttl) }}"
+ type: "{{ item.type }}"
+ check_mode: true
+ register: result
+- name: verify test update in check mode
+ assert:
+ that:
+ - result is changed
+ - result.record['values'] == {{ item.update_values | default(item['values']) }}
+ - result.record.record == "{{ item.record }}"
+ - result.record.type == "{{ item.type }}"
+ - result.record.ttl == {{ item.update_ttl | default(item.ttl) }}
+
+- name: test update or add another dns record
+ community.general.gandi_livedns:
+ api_key: "{{ gandi_api_key }}"
+ record: "{{ item.record }}"
+ domain: "{{ gandi_livedns_domain_name }}"
+ values: "{{ item.update_values | default(item['values']) }}"
+ ttl: "{{ item.update_ttl | default(item.ttl) }}"
+ type: "{{ item.type }}"
+ register: result
+- name: verify test update a dns record
+ assert:
+ that:
+ - result is changed
+ - result.record['values'] == {{ item.update_values | default(item['values']) }}
+ - result.record.record == "{{ item.record }}"
+ - result.record.ttl == {{ item.update_ttl | default(item.ttl) }}
+ - result.record.type == "{{ item.type }}"
+
+- name: test update or add another dns record idempotence
+ community.general.gandi_livedns:
+ api_key: "{{ gandi_api_key }}"
+ record: "{{ item.record }}"
+ domain: "{{ gandi_livedns_domain_name }}"
+ values: "{{ item.update_values | default(item['values']) }}"
+ ttl: "{{ item.update_ttl | default(item.ttl) }}"
+ type: "{{ item.type }}"
+ register: result
+- name: verify test update a dns record idempotence
+ assert:
+ that:
+ - result is not changed
+ - result.record['values'] == {{ item.update_values | default(item['values']) }}
+ - result.record.record == "{{ item.record }}"
+ - result.record.ttl == {{ item.update_ttl | default(item.ttl) }}
+ - result.record.type == "{{ item.type }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/gem/aliases b/ansible_collections/community/general/tests/integration/targets/gem/aliases
new file mode 100644
index 000000000..007bed538
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gem/aliases
@@ -0,0 +1,9 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+destructive
+skip/aix
+skip/osx
+skip/macos
diff --git a/ansible_collections/community/general/tests/integration/targets/gem/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/gem/meta/main.yml
new file mode 100644
index 000000000..ca1915e05
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gem/meta/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/gem/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/gem/tasks/main.yml
new file mode 100644
index 000000000..362c126bf
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gem/tasks/main.yml
@@ -0,0 +1,213 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# test code for the gem module
+# Copyright (c) 2014, James Tanner <tanner.jc@gmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- when:
+ - not (ansible_os_family == 'Alpine') # TODO
+ block:
+
+ - include_vars: '{{ item }}'
+ with_first_found:
+ - files:
+ - '{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml'
+ - '{{ ansible_distribution }}-{{ ansible_distribution_version }}.yml'
+ - '{{ ansible_os_family }}.yml'
+ - 'default.yml'
+ paths: '../vars'
+
+ - name: Install dependencies for test
+ package:
+ name: "{{ item }}"
+ state: present
+ loop: "{{ test_packages }}"
+ when: ansible_distribution != "MacOSX"
+
+ - name: Install a gem
+ gem:
+ name: gist
+ state: present
+ register: install_gem_result
+ ignore_errors: true
+
+ # when running as root on Fedora, '--install-dir' is set in the os defaults which is
+ # incompatible with '--user-install', we ignore this error for this case only
+ - name: fail if failed to install gem
+ fail:
+ msg: "failed to install gem: {{ install_gem_result.msg }}"
+ when:
+ - install_gem_result is failed
+ - not (ansible_user_uid == 0 and "User --install-dir or --user-install but not both" not in install_gem_result.msg)
+
+ - block:
+ - name: List gems
+ command: gem list
+ register: current_gems
+
+ - name: Ensure gem was installed
+ assert:
+ that:
+ - install_gem_result is changed
+ - current_gems.stdout is search('gist\s+\([0-9.]+\)')
+
+ - name: Remove a gem
+ gem:
+ name: gist
+ state: absent
+ register: remove_gem_results
+
+ - name: List gems
+ command: gem list
+ register: current_gems
+
+ - name: Verify gem is not installed
+ assert:
+ that:
+ - remove_gem_results is changed
+ - current_gems.stdout is not search('gist\s+\([0-9.]+\)')
+ when: not install_gem_result is failed
+
+ # install gem in --no-user-install
+ - block:
+ - name: Install a gem with --no-user-install
+ gem:
+ name: gist
+ state: present
+ user_install: false
+ register: install_gem_result
+
+ - name: List gems
+ command: gem list
+ register: current_gems
+
+ - name: Ensure gem was installed
+ assert:
+ that:
+ - install_gem_result is changed
+ - current_gems.stdout is search('gist\s+\([0-9.]+\)')
+
+ - name: Remove a gem
+ gem:
+ name: gist
+ state: absent
+ register: remove_gem_results
+
+ - name: List gems
+ command: gem list
+ register: current_gems
+
+ - name: Verify gem is not installed
+ assert:
+ that:
+ - remove_gem_results is changed
+ - current_gems.stdout is not search('gist\s+\([0-9.]+\)')
+ when: ansible_user_uid == 0
+
+ # Check cutom gem directory
+ - name: Install gem in a custom directory with incorrect options
+ gem:
+ name: gist
+ state: present
+ install_dir: "{{ remote_tmp_dir }}/gems"
+ ignore_errors: true
+ register: install_gem_fail_result
+
+ - debug:
+ var: install_gem_fail_result
+ tags: debug
+
+ - name: Ensure previous task failed
+ assert:
+ that:
+ - install_gem_fail_result is failed
+ - install_gem_fail_result.msg == 'install_dir requires user_install=false'
+
+ - name: Install a gem in a custom directory
+ gem:
+ name: gist
+ state: present
+ user_install: false
+ install_dir: "{{ remote_tmp_dir }}/gems"
+ register: install_gem_result
+
+ - name: Find gems in custom directory
+ find:
+ paths: "{{ remote_tmp_dir }}/gems/gems"
+ file_type: directory
+ contains: gist
+ register: gem_search
+
+ - name: Ensure gem was installed in custom directory
+ assert:
+ that:
+ - install_gem_result is changed
+ - gem_search.files[0].path is search('gist-[0-9.]+')
+ ignore_errors: true
+
+ - name: Remove a gem in a custom directory
+ gem:
+ name: gist
+ state: absent
+ user_install: false
+ install_dir: "{{ remote_tmp_dir }}/gems"
+ register: install_gem_result
+
+ - name: Find gems in custom directory
+ find:
+ paths: "{{ remote_tmp_dir }}/gems/gems"
+ file_type: directory
+ contains: gist
+ register: gem_search
+
+ - name: Ensure gem was removed in custom directory
+ assert:
+ that:
+ - install_gem_result is changed
+ - gem_search.files | length == 0
+
+ # Custom directory for executables (--bindir)
+ - name: Install gem with custom bindir
+ gem:
+ name: gist
+ state: present
+ bindir: "{{ remote_tmp_dir }}/custom_bindir"
+ norc: true
+ user_install: false # Avoid conflicts between --install-dir and --user-install when running as root on CentOS / Fedora / RHEL
+ register: install_gem_result
+
+ - name: Get stats of gem executable
+ stat:
+ path: "{{ remote_tmp_dir }}/custom_bindir/gist"
+ register: gem_bindir_stat
+
+ - name: Ensure gem executable was installed in custom directory
+ assert:
+ that:
+ - install_gem_result is changed
+ - gem_bindir_stat.stat.exists and gem_bindir_stat.stat.isreg
+
+ - name: Remove gem with custom bindir
+ gem:
+ name: gist
+ state: absent
+ bindir: "{{ remote_tmp_dir }}/custom_bindir"
+ norc: true
+ user_install: false # Avoid conflicts between --install-dir and --user-install when running as root on CentOS / Fedora / RHEL
+ register: install_gem_result
+
+ - name: Get stats of gem executable
+ stat:
+ path: "{{ remote_tmp_dir }}/custom_bindir/gist"
+ register: gem_bindir_stat
+
+ - name: Ensure gem executable was removed from custom directory
+ assert:
+ that:
+ - install_gem_result is changed
+ - not gem_bindir_stat.stat.exists
diff --git a/ansible_collections/community/general/tests/integration/targets/gem/vars/FreeBSD.yml b/ansible_collections/community/general/tests/integration/targets/gem/vars/FreeBSD.yml
new file mode 100644
index 000000000..b9d9cc2c2
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gem/vars/FreeBSD.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+test_packages:
+ - "devel/ruby-gems"
+ - "ruby"
diff --git a/ansible_collections/community/general/tests/integration/targets/gem/vars/RedHat.yml b/ansible_collections/community/general/tests/integration/targets/gem/vars/RedHat.yml
new file mode 100644
index 000000000..2bb724bfe
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gem/vars/RedHat.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+test_packages:
+ - "rubygems"
diff --git a/ansible_collections/community/general/tests/integration/targets/gem/vars/default.yml b/ansible_collections/community/general/tests/integration/targets/gem/vars/default.yml
new file mode 100644
index 000000000..b7496e12c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gem/vars/default.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+test_packages: []
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config/aliases b/ansible_collections/community/general/tests/integration/targets/git_config/aliases
new file mode 100644
index 000000000..7b8c653de
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config/aliases
@@ -0,0 +1,7 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/3
+skip/aix
+destructive
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config/files/gitconfig b/ansible_collections/community/general/tests/integration/targets/git_config/files/gitconfig
new file mode 100644
index 000000000..92eeb7eb9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config/files/gitconfig
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+[http]
+ proxy = foo
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/git_config/meta/main.yml
new file mode 100644
index 000000000..982de6eb0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config/tasks/exclusion_state_list-all.yml b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/exclusion_state_list-all.yml
new file mode 100644
index 000000000..e294a83fb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/exclusion_state_list-all.yml
@@ -0,0 +1,20 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- import_tasks: setup_no_value.yml
+
+- name: testing exclusion between state and list_all parameters
+ git_config:
+ list_all: true
+ state: absent
+ register: result
+ ignore_errors: true
+
+- name: assert git_config failed
+ assert:
+ that:
+ - result is failed
+ - "result.msg == 'parameters are mutually exclusive: list_all|state'"
+...
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config/tasks/get_set_no_state.yml b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/get_set_no_state.yml
new file mode 100644
index 000000000..4e41bf4e9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/get_set_no_state.yml
@@ -0,0 +1,29 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- import_tasks: setup_no_value.yml
+
+- name: setting value without state
+ git_config:
+ name: "{{ option_name }}"
+ value: "{{ option_value }}"
+ scope: "{{ option_scope }}"
+ register: set_result
+
+- name: getting value without state
+ git_config:
+ name: "{{ option_name }}"
+ scope: "{{ option_scope }}"
+ register: get_result
+
+- name: assert set changed and value is correct
+ assert:
+ that:
+ - set_result is changed
+ - set_result.diff.before == "\n"
+ - set_result.diff.after == option_value + "\n"
+ - get_result is not changed
+ - get_result.config_value == option_value
+...
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config/tasks/get_set_state_present.yml b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/get_set_state_present.yml
new file mode 100644
index 000000000..cfc3bbe78
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/get_set_state_present.yml
@@ -0,0 +1,31 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- import_tasks: setup_no_value.yml
+
+- name: setting value with state=present
+ git_config:
+ name: "{{ option_name }}"
+ value: "{{ option_value }}"
+ scope: "{{ option_scope }}"
+ state: present
+ register: result
+
+- name: getting value with state=present
+ git_config:
+ name: "{{ option_name }}"
+ scope: "{{ option_scope }}"
+ state: present
+ register: get_result
+
+- name: assert set changed and value is correct with state=present
+ assert:
+ that:
+ - set_result is changed
+ - set_result.diff.before == "\n"
+ - set_result.diff.after == option_value + "\n"
+ - get_result is not changed
+ - get_result.config_value == option_value
+...
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config/tasks/get_set_state_present_file.yml b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/get_set_state_present_file.yml
new file mode 100644
index 000000000..a61ffcc68
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/get_set_state_present_file.yml
@@ -0,0 +1,32 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- import_tasks: setup_no_value.yml
+
+- name: setting value with state=present
+ git_config:
+ name: "{{ option_name }}"
+ value: "{{ option_value }}"
+ scope: "file"
+ file: "{{ remote_tmp_dir }}/gitconfig_file"
+ state: present
+ register: result
+
+- name: getting value with state=present
+ git_config:
+ name: "{{ option_name }}"
+ scope: "file"
+ file: "{{ remote_tmp_dir }}/gitconfig_file"
+ state: present
+ register: get_result
+
+- name: assert set changed and value is correct with state=present
+ assert:
+ that:
+ - set_result is changed
+ - set_result.diff.before == "\n"
+ - set_result.diff.after == option_value + "\n"
+ - get_result is not changed
+ - get_result.config_value == option_value
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/main.yml
new file mode 100644
index 000000000..4dc72824c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/main.yml
@@ -0,0 +1,35 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# test code for the git_config module
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: setup
+ import_tasks: setup.yml
+
+- block:
+ # testing parameters exclusion: state and list_all
+ - import_tasks: exclusion_state_list-all.yml
+ # testing get/set option without state
+ - import_tasks: get_set_no_state.yml
+ # testing get/set option with state=present
+ - import_tasks: get_set_state_present.yml
+ # testing get/set option with state=present and scope=file
+ - import_tasks: get_set_state_present_file.yml
+ # testing state=absent without value to delete
+ - import_tasks: unset_no_value.yml
+ # testing state=absent with value to delete
+ - import_tasks: unset_value.yml
+ # testing state=absent with value to delete and a defined value parameter
+ - import_tasks: precedence_between_unset_and_value.yml
+ # testing state=absent with check mode
+ - import_tasks: unset_check_mode.yml
+ # testing for case in issue #1776
+ - import_tasks: set_value_with_tilde.yml
+ when: git_installed is succeeded and git_version.stdout is version(git_version_supporting_includes, ">=")
+...
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config/tasks/precedence_between_unset_and_value.yml b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/precedence_between_unset_and_value.yml
new file mode 100644
index 000000000..a76fbab9c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/precedence_between_unset_and_value.yml
@@ -0,0 +1,29 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- import_tasks: setup_value.yml
+
+- name: unsetting value
+ git_config:
+ name: "{{ option_name }}"
+ scope: "{{ option_scope }}"
+ state: absent
+ value: bar
+ register: unset_result
+
+- name: getting value
+ git_config:
+ name: "{{ option_name }}"
+ scope: "{{ option_scope }}"
+ register: get_result
+
+- name: assert unset changed and deleted value
+ assert:
+ that:
+ - unset_result is changed
+ - unset_result.diff.before == option_value + "\n"
+ - unset_result.diff.after == "\n"
+ - get_result.config_value == ''
+...
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config/tasks/set_value_with_tilde.yml b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/set_value_with_tilde.yml
new file mode 100644
index 000000000..f78e709bd
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/set_value_with_tilde.yml
@@ -0,0 +1,37 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+#- import_tasks: setup_no_value.yml
+
+- name: setting value
+ git_config:
+ name: core.hooksPath
+ value: '~/foo/bar'
+ state: present
+ scope: global
+ register: set_result
+
+- name: setting value again
+ git_config:
+ name: core.hooksPath
+ value: '~/foo/bar'
+ state: present
+ scope: global
+ register: set_result2
+
+- name: getting value
+ git_config:
+ name: core.hooksPath
+ scope: global
+ register: get_result
+
+- name: assert set changed and value is correct
+ assert:
+ that:
+ - set_result is changed
+ - set_result2 is not changed
+ - get_result is not changed
+ - get_result.config_value == '~/foo/bar'
+...
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config/tasks/setup.yml b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/setup.yml
new file mode 100644
index 000000000..6e5516da5
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/setup.yml
@@ -0,0 +1,15 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: verify that git is installed so this test can continue
+ command: which git
+ register: git_installed
+ ignore_errors: true
+
+- name: get git version, only newer than {{git_version_supporting_includes}} has includes option
+ shell: "git --version | grep 'git version' | sed 's/git version //'"
+ register: git_version
+ ignore_errors: true
+...
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config/tasks/setup_no_value.yml b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/setup_no_value.yml
new file mode 100644
index 000000000..8e12c350c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/setup_no_value.yml
@@ -0,0 +1,16 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# ------
+# set up : deleting gitconfig file
+- name: set up without value
+ file:
+ path: ~/.gitconfig
+ state: absent
+
+- name: set up without value (file)
+ file:
+ path: "{{ remote_tmp_dir }}/gitconfig_file"
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config/tasks/setup_value.yml b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/setup_value.yml
new file mode 100644
index 000000000..126b1ae4b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/setup_value.yml
@@ -0,0 +1,16 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# ------
+# set up : set gitconfig with value
+- name: set up with value
+ copy:
+ src: gitconfig
+ dest: ~/.gitconfig
+
+- name: set up with value (file)
+ copy:
+ src: gitconfig
+ dest: "{{ remote_tmp_dir }}/gitconfig_file"
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config/tasks/unset_check_mode.yml b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/unset_check_mode.yml
new file mode 100644
index 000000000..39bce3379
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/unset_check_mode.yml
@@ -0,0 +1,29 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- import_tasks: setup_value.yml
+
+- name: unsetting value with check mode
+ git_config:
+ name: "{{ option_name }}"
+ scope: "{{ option_scope }}"
+ state: absent
+ check_mode: true
+ register: unset_result
+
+- name: getting value
+ git_config:
+ name: "{{ option_name }}"
+ scope: "{{ option_scope }}"
+ register: get_result
+
+- name: assert unset changed but dit not delete value
+ assert:
+ that:
+ - unset_result is changed
+ - unset_result.diff.before == option_value + "\n"
+ - unset_result.diff.after == "\n"
+ - get_result.config_value == option_value
+...
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config/tasks/unset_no_value.yml b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/unset_no_value.yml
new file mode 100644
index 000000000..394276cad
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/unset_no_value.yml
@@ -0,0 +1,27 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- import_tasks: setup_no_value.yml
+
+- name: unsetting value
+ git_config:
+ name: "{{ option_name }}"
+ scope: "{{ option_scope }}"
+ state: absent
+ register: unset_result
+
+- name: getting value
+ git_config:
+ name: "{{ option_name }}"
+ scope: "{{ option_scope }}"
+ register: get_result
+
+- name: assert unsetting didn't change
+ assert:
+ that:
+ - unset_result is not changed
+ - unset_result.msg == 'no setting to unset'
+ - get_result.config_value == ''
+...
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config/tasks/unset_value.yml b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/unset_value.yml
new file mode 100644
index 000000000..dfa535a2d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config/tasks/unset_value.yml
@@ -0,0 +1,28 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- import_tasks: setup_value.yml
+
+- name: unsetting value
+ git_config:
+ name: "{{ option_name }}"
+ scope: "{{ option_scope }}"
+ state: absent
+ register: unset_result
+
+- name: getting value
+ git_config:
+ name: "{{ option_name }}"
+ scope: "{{ option_scope }}"
+ register: get_result
+
+- name: assert unset changed and deleted value
+ assert:
+ that:
+ - unset_result is changed
+ - unset_result.diff.before == option_value + "\n"
+ - unset_result.diff.after == "\n"
+ - get_result.config_value == ''
+...
diff --git a/ansible_collections/community/general/tests/integration/targets/git_config/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/git_config/vars/main.yml
new file mode 100644
index 000000000..3cca3ef6e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/git_config/vars/main.yml
@@ -0,0 +1,10 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+git_version_supporting_includes: 1.7.10
+option_name: http.proxy
+option_value: 'foo'
+option_scope: global
+...
diff --git a/ansible_collections/community/general/tests/integration/targets/github_issue/aliases b/ansible_collections/community/general/tests/integration/targets/github_issue/aliases
new file mode 100644
index 000000000..428e8289d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/github_issue/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+destructive
diff --git a/ansible_collections/community/general/tests/integration/targets/github_issue/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/github_issue/tasks/main.yml
new file mode 100644
index 000000000..a7e43c171
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/github_issue/tasks/main.yml
@@ -0,0 +1,38 @@
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Test code for the github_issue module.
+#
+# Copyright (c) 2017-2018, Abhijeet Kasurde <akasurde@redhat.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Check if GitHub issue is closed or not
+ github_issue:
+ organization: "{{ organization }}"
+ repo: "{{ repo }}"
+ issue: "{{ issue }}"
+ action: get_status
+ register: get_status_0002
+
+- assert:
+ that:
+ - get_status_0002 is changed
+ - get_status_0002.issue_status == 'closed'
+
+- name: Check if GitHub issue is closed or not
+ github_issue:
+ organization: "{{ organization }}"
+ repo: "{{ repo }}"
+ issue: "{{ non_existent_issue }}"
+ action: get_status
+ register: get_status_0003
+ ignore_errors: true
+
+- assert:
+ that:
+ - get_status_0003 is not changed
+ - get_status_0003 is failed
+ - "'Failed' in get_status_0003.msg"
diff --git a/ansible_collections/community/general/tests/integration/targets/github_issue/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/github_issue/vars/main.yml
new file mode 100644
index 000000000..8b2a2de6e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/github_issue/vars/main.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+issue: 23642
+non_existent_issue: 1111111
+organization: ansible
+repo: ansible
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_branch/aliases b/ansible_collections/community/general/tests/integration/targets/gitlab_branch/aliases
new file mode 100644
index 000000000..d163e8d9c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_branch/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+disabled
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_branch/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_branch/defaults/main.yml
new file mode 100644
index 000000000..a5f0a0751
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_branch/defaults/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+gitlab_branch: ansible_test_branch
+gitlab_project_name: ansible_test_project
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_branch/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_branch/tasks/main.yml
new file mode 100644
index 000000000..19d90e15c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_branch/tasks/main.yml
@@ -0,0 +1,69 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install required libs
+ pip:
+ name: python-gitlab
+ state: present
+
+- name: Create {{ gitlab_project_name }}
+ gitlab_project:
+ server_url: "{{ gitlab_host }}"
+ validate_certs: false
+ login_token: "{{ gitlab_login_token }}"
+ name: "{{ gitlab_project_name }}"
+ initialize_with_readme: true
+ state: present
+
+- name: Create branch {{ gitlab_branch }}
+ community.general.gitlab_branch:
+ api_url: https://gitlab.com
+ api_token: secret_access_token
+ project: "{{ gitlab_project_name }}"
+ branch: "{{ gitlab_branch }}"
+ ref_branch: main
+ state: present
+
+- name: Create branch {{ gitlab_branch }} ( Idempotency test )
+ community.general.gitlab_branch:
+ api_url: https://gitlab.com
+ api_token: secret_access_token
+ project: "{{ gitlab_project_name }}"
+ branch: "{{ gitlab_branch }}"
+ ref_branch: main
+ state: present
+ register: create_branch
+
+- name: Test module is idempotent
+ assert:
+ that:
+ - create_branch is not changed
+
+- name: Cleanup branch {{ gitlab_branch }}
+ community.general.gitlab_branch:
+ api_url: https://gitlab.com
+ api_token: secret_access_token
+ project: "{{ gitlab_project_name }}"
+ branch: "{{ gitlab_branch }}"
+ state: absent
+ register: delete_branch
+
+- name: Test module is idempotent
+ assert:
+ that:
+ - delete_branch is changed
+
+- name: Clean up {{ gitlab_project_name }}
+ gitlab_project:
+ server_url: "{{ gitlab_host }}"
+ validate_certs: false
+ login_token: "{{ gitlab_login_token }}"
+ name: "{{ gitlab_project_name }}"
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_deploy_key/aliases b/ansible_collections/community/general/tests/integration/targets/gitlab_deploy_key/aliases
new file mode 100644
index 000000000..fc0e157c9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_deploy_key/aliases
@@ -0,0 +1,7 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+gitlab/ci
+disabled
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_deploy_key/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_deploy_key/defaults/main.yml
new file mode 100644
index 000000000..8225571b6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_deploy_key/defaults/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+gitlab_project_name: ansible_test_project
+gitlab_deploy_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJnTYY7CYk1F/wBklpdRxudxN6KeXgfhutkiCigSfPhe ansible_test"
+gitlab_deploy_key_new: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDL1TDkIY2uu6NYRD0G5qGeHTd/AoqQpCw1XENXDnTLDN5DNZVCO1+7xfA5DR5V2tcR691Q005BKxoCo+uUBd1aAM7JWyuXl050rZCXBj4oaUF7urjDANQ7FzYuvqp9h8NGkvzfBYz5YBfu4vh43ajnF0daSyZy4RlxeG9G44vnHElXTQ0igaOCSta/23FdERIYzKxuX4Ul42AwtSmCRwbkN4fC86o0UwW2q0zkgFOUoojtS/Avh0aX8UQyeagaPJFXCc/ldG1mMK020GQAEa8aQcUpysnEzZdq6no5Zyn/WQSobpnJ9CraHhdb1QQytg/+c+CgjSN0cERhTvLn0WsQ043jo5g1kSHNu+OiYXmVwTxe95nXCsoYmCNF/DmezjYVxe9BGlKRAEuHsNi87Il84nBnzKVHGlkq8eJNTR8ASjNkjI7pGS0zxCDB55c3LHh4Aa1xU+nwINRurn/TEDpDZc43/XOnt+aqbxkeWbMtOD/r2gfMj8lNZJ/IyamWy7HcFgGpTZJln4WxVLF+Cz56qa8Hf9WzJL+8Lq7eE3sJKOagn/zPgqeybXbTIPSr3fshq3yE8FYHpFKS4aLvQC/XSLCywrhr25DKBn9UHIZmgC9hxMnVJCKux+ltwGJOKIaoj+5n3+DvM+E3fK3fkADo5+Frzay6/rLTwKWUrzfjQQ== ansible_test_new"
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_deploy_key/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_deploy_key/tasks/main.yml
new file mode 100644
index 000000000..c345c2467
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_deploy_key/tasks/main.yml
@@ -0,0 +1,78 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install required libs
+ pip:
+ name: python-gitlab
+ state: present
+
+- name: Create {{ gitlab_project_name }}
+ gitlab_project:
+ server_url: "{{ gitlab_host }}"
+ validate_certs: false
+ login_token: "{{ gitlab_login_token }}"
+ name: "{{ gitlab_project_name }}"
+ state: present
+
+- name: Cleanup deploy key to {{ gitlab_project_name }}
+ gitlab_deploy_key:
+ login_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ server_url: "{{ gitlab_host }}"
+ title: "{{ gitlab_project_name }}"
+ key: "{{ gitlab_deploy_key }}"
+ state: absent
+
+
+- name: Add deploy key to {{ gitlab_project_name }}
+ gitlab_deploy_key:
+ login_token: "{{ gitlab_login_token }}"
+ project: "root/{{ gitlab_project_name }}"
+ server_url: "{{ gitlab_host }}"
+ title: "{{ gitlab_project_name }}"
+ key: "{{ gitlab_deploy_key }}"
+ state: present
+ register: deploy_key_status
+
+- assert:
+ that:
+ - deploy_key_status is changed
+ - deploy_key_status.deploy_key.key == gitlab_deploy_key
+
+
+- name: Update public key {{ gitlab_project_name }} (change expected)
+ gitlab_deploy_key:
+ login_token: "{{ gitlab_login_token }}"
+ project: "root/{{ gitlab_project_name }}"
+ server_url: "{{ gitlab_host }}"
+ title: "{{ gitlab_project_name }}"
+ key: "{{ gitlab_deploy_key_new }}"
+ state: present
+ register: deploy_key_status
+
+- assert:
+ that:
+ - deploy_key_status is changed
+ - deploy_key_status.deploy_key.key == gitlab_deploy_key_new
+
+- name: Update public key {{ gitlab_project_name }} (no change expected)
+ gitlab_deploy_key:
+ login_token: "{{ gitlab_login_token }}"
+ project: "root/{{ gitlab_project_name }}"
+ server_url: "{{ gitlab_host }}"
+ title: "{{ gitlab_project_name }}"
+ key: "{{ gitlab_deploy_key_new }}"
+ state: present
+ register: deploy_key_status
+
+- assert:
+ that:
+ - not deploy_key_status.changed
+ - deploy_key_status.deploy_key.key == gitlab_deploy_key_new
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_group/aliases b/ansible_collections/community/general/tests/integration/targets/gitlab_group/aliases
new file mode 100644
index 000000000..fc0e157c9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_group/aliases
@@ -0,0 +1,7 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+gitlab/ci
+disabled
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_group/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_group/defaults/main.yml
new file mode 100644
index 000000000..01863abe3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_group/defaults/main.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+gitlab_group: ansible_test_project
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_group/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_group/tasks/main.yml
new file mode 100644
index 000000000..a0355094f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_group/tasks/main.yml
@@ -0,0 +1,129 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install required libs
+ pip:
+ name: python-gitlab
+ state: present
+
+- name: Cleanup GitLab Group
+ gitlab_group:
+ api_url: "{{ gitlab_host }}"
+ validate_certs: false
+ api_token: "{{ gitlab_login_token }}"
+ name: ansible_test_group
+ path: ansible_test_group
+ state: absent
+
+- name: Create GitLab Group
+ gitlab_group:
+ api_url: "{{ gitlab_host }}"
+ validate_certs: false
+ api_token: "{{ gitlab_login_token }}"
+ name: ansible_test_group
+ path: ansible_test_group
+ state: present
+ register: gitlab_group_state
+
+- name: Test group created
+ assert:
+ that:
+ - gitlab_group_state is changed
+
+
+- name: Create GitLab Group ( Idempotency test )
+ gitlab_group:
+ api_url: "{{ gitlab_host }}"
+ validate_certs: false
+ api_token: "{{ gitlab_login_token }}"
+ name: ansible_test_group
+ path: ansible_test_group
+ state: present
+ register: gitlab_group_state_again
+
+- name: Test module is idempotent
+ assert:
+ that:
+ - gitlab_group_state_again is not changed
+
+- name: Cleanup GitLab Group for Description Test
+ gitlab_group:
+ api_url: "{{ gitlab_host }}"
+ validate_certs: false
+ api_token: "{{ gitlab_login_token }}"
+ name: ansible_test_group
+ path: ansible_test_group
+ state: absent
+
+- name: Create GitLab Group for Description Test
+ gitlab_group:
+ api_url: "{{ gitlab_host }}"
+ validate_certs: false
+ api_token: "{{ gitlab_login_token }}"
+ name: ansible_test_group
+ path: ansible_test_group
+ description: My Test Group
+ state: present
+ register: gitlab_group_state_desc
+
+- name: Test group created with Description
+ assert:
+ that:
+ - gitlab_group_state_desc.group.description == "My Test Group"
+
+- name: Cleanup GitLab Group for project_creation_level Test
+ gitlab_group:
+ api_url: "{{ gitlab_host }}"
+ validate_certs: false
+ api_token: "{{ gitlab_login_token }}"
+ name: ansible_test_group
+ path: ansible_test_group
+ state: absent
+
+- name: Create GitLab Group for project_creation_level Test
+ gitlab_group:
+ api_url: "{{ gitlab_host }}"
+ validate_certs: false
+ api_token: "{{ gitlab_login_token }}"
+ name: ansible_test_group
+ path: ansible_test_group
+ project_creation_level: noone
+ state: present
+ register: gitlab_group_state_pcl
+
+- name: Test group created with project_creation_level
+ assert:
+ that:
+ - gitlab_group_state_pcl.group.project_creation_level == "noone"
+
+- name: Cleanup GitLab Group for require_two_factor_authentication Test
+ gitlab_group:
+ api_url: "{{ gitlab_host }}"
+ validate_certs: false
+ api_token: "{{ gitlab_login_token }}"
+ name: ansible_test_group
+ path: ansible_test_group
+ state: absent
+
+- name: Create GitLab Group for project_creation_level Test
+ gitlab_group:
+ api_url: "{{ gitlab_host }}"
+ validate_certs: false
+ api_token: "{{ gitlab_login_token }}"
+ name: ansible_test_group
+ path: ansible_test_group
+ require_two_factor_authentication: true
+ state: present
+ register: gitlab_group_state_rtfa
+
+- name: Test group created with project_creation_level
+ assert:
+ that:
+ - gitlab_group_state_rtfa.group.require_two_factor_authentication == true
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_group_members/aliases b/ansible_collections/community/general/tests/integration/targets/gitlab_group_members/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_group_members/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_group_members/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_group_members/tasks/main.yml
new file mode 100644
index 000000000..aa75096da
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_group_members/tasks/main.yml
@@ -0,0 +1,74 @@
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Test code for gitlab_group_members module
+#
+# Copyright (c) 2020, Zainab Alsaffar <Zainab.Alsaffar@mail.rit.edu>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+- name: Install required library
+ pip:
+ name: python-gitlab
+ state: present
+
+- name: Add a User to A GitLab Group
+ gitlab_group_members:
+ api_url: '{{ gitlab_server_url }}'
+ api_token: '{{ gitlab_api_access_token }}'
+ gitlab_group: '{{ gitlab_group_name }}'
+ gitlab_user: '{{ username }}'
+ access_level: '{{ gitlab_access_level }}'
+ state: present
+
+- name: Remove a User from A GitLab Group
+ gitlab_group_members:
+ api_url: '{{ gitlab_server_url }}'
+ api_token: '{{ gitlab_api_access_token }}'
+ gitlab_group: '{{ gitlab_group_name }}'
+ gitlab_user: '{{ username }}'
+ state: absent
+
+- name: Add a list of Users to A GitLab Group
+ gitlab_group_members:
+ api_url: '{{ gitlab_server_url }}'
+ api_token: '{{ gitlab_api_access_token }}'
+ gitlab_group: '{{ gitlab_group_name }}'
+ gitlab_user: '{{ userlist }}'
+ access_level: '{{ gitlab_access_level }}'
+ state: present
+
+- name: Remove a list of Users to A GitLab Group
+ gitlab_group_members:
+ api_url: '{{ gitlab_server_url }}'
+ api_token: '{{ gitlab_api_access_token }}'
+ gitlab_group: '{{ gitlab_group_name }}'
+ gitlab_user: '{{ userlist }}'
+ state: absent
+
+- name: Add a list of Users with Dedicated Access Levels to A GitLab Group
+ gitlab_group_members:
+ api_url: '{{ gitlab_server_url }}'
+ api_token: '{{ gitlab_api_access_token }}'
+ gitlab_group: '{{ gitlab_group_name }}'
+ gitlab_users_access: '{{ dedicated_access_users }}'
+ state: present
+
+- name: Remove a list of Users with Dedicated Access Levels to A GitLab Group
+ gitlab_group_members:
+ api_url: '{{ gitlab_server_url }}'
+ api_token: '{{ gitlab_api_access_token }}'
+ gitlab_group: '{{ gitlab_group_name }}'
+ gitlab_users_access: '{{ dedicated_access_users }}'
+ state: absent
+
+- name: Add a user, remove all others which might be on this access level
+ gitlab_group_members:
+ api_url: '{{ gitlab_server_url }}'
+ api_token: '{{ gitlab_api_access_token }}'
+ gitlab_group: '{{ gitlab_group_name }}'
+ gitlab_user: '{{ username }}'
+ access_level: '{{ gitlab_access_level }}'
+ pruge_users: '{{ gitlab_access_level }}'
+ state: present
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_group_members/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_group_members/vars/main.yml
new file mode 100644
index 000000000..908260418
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_group_members/vars/main.yml
@@ -0,0 +1,18 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+gitlab_server_url: https://gitlabserver.example.com
+gitlab_api_access_token: 126hngbscx890cv09b
+gitlab_group_name: groupname1
+username: username1
+gitlab_access_level: developer
+userlist:
+ - username1
+ - username2
+dedicated_access_users:
+ - name: username1
+ access_level: "developer"
+ - name: username2
+ access_level: "maintainer"
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_group_variable/aliases b/ansible_collections/community/general/tests/integration/targets/gitlab_group_variable/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_group_variable/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_group_variable/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_group_variable/tasks/main.yml
new file mode 100644
index 000000000..39a3a5df8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_group_variable/tasks/main.yml
@@ -0,0 +1,706 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install required libs
+ pip:
+ name: python-gitlab
+ state: present
+
+- name: purge all variables for check_mode test
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ purge: true
+
+- name: add a variable value in check_mode
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ ACCESS_KEY_ID: checkmode
+ check_mode: true
+ register: gitlab_group_variable_state
+
+- name: check_mode state must be changed
+ assert:
+ that:
+ - gitlab_group_variable_state is changed
+
+- name: apply add value from check_mode test
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ variables:
+ - name: ACCESS_KEY_ID
+ value: checkmode
+ register: gitlab_group_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_group_variable_state is changed
+
+- name: test new format
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ ACCESS_KEY_ID:
+ value: checkmode
+ register: gitlab_group_variable_state
+
+- name: state must be not changed
+ assert:
+ that:
+ - gitlab_group_variable_state is not changed
+
+- name: change protected attribute
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ ACCESS_KEY_ID:
+ value: checkmode
+ protected: true
+ register: gitlab_group_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_group_variable_state is changed
+
+- name: revert protected attribute
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ ACCESS_KEY_ID:
+ value: checkmode
+ protected: false
+ register: gitlab_group_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_group_variable_state is changed
+
+- name: change masked attribute
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ ACCESS_KEY_ID:
+ value: checkmode
+ masked: true
+ register: gitlab_group_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_group_variable_state is changed
+
+- name: revert masked attribute by not mention it
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ ACCESS_KEY_ID:
+ value: checkmode
+ register: gitlab_group_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_group_variable_state is changed
+
+- name: revert again masked attribute by not mention it (idempotent)
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ ACCESS_KEY_ID:
+ value: checkmode
+ register: gitlab_group_variable_state
+
+- name: state must be not changed
+ assert:
+ that:
+ - gitlab_group_variable_state is not changed
+
+- name: set both (masked and protected) attribute
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ ACCESS_KEY_ID:
+ value: checkmode
+ masked: true
+ protected: true
+ variable_type: env_var
+ register: gitlab_group_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_group_variable_state is changed
+
+- name: set again both (masked and protected) attribute (idempotent)
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ ACCESS_KEY_ID:
+ value: checkmode
+ masked: true
+ protected: true
+ variable_type: env_var
+ register: gitlab_group_variable_state
+
+- name: state must not be changed
+ assert:
+ that:
+ - gitlab_group_variable_state is not changed
+
+- name: revert both (masked and protected) attribute
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ ACCESS_KEY_ID:
+ value: checkmode
+ protected: false
+ register: gitlab_group_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_group_variable_state is changed
+
+- name: change a variable value in check_mode again
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ ACCESS_KEY_ID: checkmode
+ check_mode: true
+ register: gitlab_group_variable_state
+
+- name: check_mode state must not be changed
+ assert:
+ that:
+ - gitlab_group_variable_state is not changed
+
+- name: apply again the value change from check_mode test
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ ACCESS_KEY_ID: checkmode
+ register: gitlab_group_variable_state
+
+- name: state must not be changed
+ assert:
+ that:
+ - gitlab_group_variable_state is not changed
+
+- name: change environment scope
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ ACCESS_KEY_ID:
+ environment_scope: testing
+ value: checkmode
+ register: gitlab_group_variable_state
+ when: gitlab_premium_tests is defined
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_group_variable_state is changed
+ when: gitlab_premium_tests is defined
+
+- name: apply again the environment scope change
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ ACCESS_KEY_ID:
+ environment_scope: testing
+ value: checkmode
+ register: gitlab_group_variable_state
+ when: gitlab_premium_tests is defined
+
+- name: state must not be changed
+ assert:
+ that:
+ - gitlab_group_variable_state is not changed
+ when: gitlab_premium_tests is defined
+
+- name: purge all variables at the beginning
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ purge: true
+
+- name: set two test variables
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ ACCESS_KEY_ID: abc123
+ SECRET_ACCESS_KEY: 321cba
+ register: gitlab_group_variable_state
+
+- name: set two test variables state must be changed
+ assert:
+ that:
+ - gitlab_group_variable_state is changed
+ - gitlab_group_variable_state.group_variable.added|length == 2
+ - gitlab_group_variable_state.group_variable.untouched|length == 0
+ - gitlab_group_variable_state.group_variable.removed|length == 0
+ - gitlab_group_variable_state.group_variable.updated|length == 0
+
+- name: re-set two test variables
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ ACCESS_KEY_ID: abc123
+ SECRET_ACCESS_KEY: 321cba
+ register: gitlab_group_variable_state
+
+- name: re-set two test variables state must not be changed
+ assert:
+ that:
+ - gitlab_group_variable_state is not changed
+ - gitlab_group_variable_state.group_variable.added|length == 0
+ - gitlab_group_variable_state.group_variable.untouched|length == 2
+ - gitlab_group_variable_state.group_variable.removed|length == 0
+ - gitlab_group_variable_state.group_variable.updated|length == 0
+
+- name: edit one variable
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ ACCESS_KEY_ID: changed
+ purge: false
+ register: gitlab_group_variable_state
+
+- name: edit one variable state must be changed
+ assert:
+ that:
+ - gitlab_group_variable_state.changed
+ - gitlab_group_variable_state.group_variable.added|length == 0
+ - gitlab_group_variable_state.group_variable.untouched|length == 1
+ - gitlab_group_variable_state.group_variable.removed|length == 0
+ - gitlab_group_variable_state.group_variable.updated|length == 1
+ - gitlab_group_variable_state.group_variable.updated[0] == "ACCESS_KEY_ID"
+
+- name: append one variable
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ some: value
+ purge: false
+ register: gitlab_group_variable_state
+
+- name: append one variable state must be changed
+ assert:
+ that:
+ - gitlab_group_variable_state.changed
+ - gitlab_group_variable_state.group_variable.added|length == 1
+ - gitlab_group_variable_state.group_variable.untouched|length == 2
+ - gitlab_group_variable_state.group_variable.removed|length == 0
+ - gitlab_group_variable_state.group_variable.updated|length == 0
+ - gitlab_group_variable_state.group_variable.added[0] == "some"
+
+- name: re-set all variables
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ ACCESS_KEY_ID: changed
+ SECRET_ACCESS_KEY: 321cba
+ some: value
+ register: gitlab_group_variable_state
+
+- name: re-set all variables state must not be changed
+ assert:
+ that:
+ - not gitlab_group_variable_state.changed
+ - gitlab_group_variable_state.group_variable.added|length == 0
+ - gitlab_group_variable_state.group_variable.untouched|length == 3
+ - gitlab_group_variable_state.group_variable.removed|length == 0
+ - gitlab_group_variable_state.group_variable.updated|length == 0
+
+- name: set one variables and purge all others
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ some: value
+ purge: true
+ register: gitlab_group_variable_state
+
+- name: set one variables and purge all others state must be changed
+ assert:
+ that:
+ - gitlab_group_variable_state.changed
+ - gitlab_group_variable_state.group_variable.added|length == 0
+ - gitlab_group_variable_state.group_variable.untouched|length == 1
+ - gitlab_group_variable_state.group_variable.removed|length == 2
+ - gitlab_group_variable_state.group_variable.updated|length == 0
+
+- name: only one variable is left
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ some: value
+ purge: false
+ register: gitlab_group_variable_state
+
+- name: only one variable is left state must not be changed
+ assert:
+ that:
+ - not gitlab_group_variable_state.changed
+ - gitlab_group_variable_state.group_variable.added|length == 0
+ - gitlab_group_variable_state.group_variable.untouched|length == 1
+ - gitlab_group_variable_state.group_variable.removed|length == 0
+ - gitlab_group_variable_state.group_variable.updated|length == 0
+ - gitlab_group_variable_state.group_variable.untouched[0] == "some"
+
+- name: test integer values
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ some: 42
+ purge: false
+ register: gitlab_group_variable_state
+
+- name: only one variable is left state must be changed
+ assert:
+ that:
+ - gitlab_group_variable_state.changed
+ - gitlab_group_variable_state.group_variable.added|length == 0
+ - gitlab_group_variable_state.group_variable.untouched|length == 0
+ - gitlab_group_variable_state.group_variable.removed|length == 0
+ - gitlab_group_variable_state.group_variable.updated|length == 1
+
+- name: test float values
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ some: 42.23
+ purge: false
+ register: gitlab_group_variable_state
+
+- name: only one variable is left state must be changed
+ assert:
+ that:
+ - gitlab_group_variable_state.changed
+ - gitlab_group_variable_state.group_variable.added|length == 0
+ - gitlab_group_variable_state.group_variable.untouched|length == 0
+ - gitlab_group_variable_state.group_variable.removed|length == 0
+ - gitlab_group_variable_state.group_variable.updated|length == 1
+
+- name: delete the last left variable
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ state: absent
+ vars:
+ some: value
+ register: gitlab_group_variable_state
+
+- name: no variable is left state must be changed
+ assert:
+ that:
+ - gitlab_group_variable_state.changed
+ - gitlab_group_variable_state.group_variable.added|length == 0
+ - gitlab_group_variable_state.group_variable.untouched|length == 0
+ - gitlab_group_variable_state.group_variable.removed|length == 1
+ - gitlab_group_variable_state.group_variable.updated|length == 0
+ - gitlab_group_variable_state.group_variable.removed[0] == "some"
+
+- name: add one variable with variable_type file
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ variables:
+ - name: my_test_var
+ value: my_test_value
+ variable_type: file
+ purge: false
+ register: gitlab_group_variable_state
+
+- name: append one variable state must be changed
+ assert:
+ that:
+ - gitlab_group_variable_state.changed
+ - gitlab_group_variable_state.group_variable.added|length == 1
+ - gitlab_group_variable_state.group_variable.untouched|length == 0
+ - gitlab_group_variable_state.group_variable.removed|length == 0
+ - gitlab_group_variable_state.group_variable.updated|length == 0
+ - gitlab_group_variable_state.group_variable.added[0] == "my_test_var"
+
+- name: change variable_type attribute
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ my_test_var:
+ value: my_test_value
+ variable_type: env_var
+ register: gitlab_group_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_group_variable_state is changed
+
+- name: revert variable_type attribute
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ my_test_var:
+ value: my_test_value
+ variable_type: file
+ register: gitlab_group_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_group_variable_state is changed
+
+- name: delete the variable_type file variable
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ state: absent
+ vars:
+ my_test_var: my_test_value
+ register: gitlab_group_variable_state
+
+- name: no variable is left state must be changed
+ assert:
+ that:
+ - gitlab_group_variable_state.changed
+ - gitlab_group_variable_state.group_variable.added|length == 0
+ - gitlab_group_variable_state.group_variable.untouched|length == 0
+ - gitlab_group_variable_state.group_variable.removed|length == 1
+ - gitlab_group_variable_state.group_variable.updated|length == 0
+ - gitlab_group_variable_state.group_variable.removed[0] == "my_test_var"
+
+- name: set complete page and purge existing ones
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ page1_var01: value
+ page1_var02: value
+ page1_var03: value
+ page1_var04: value
+ page1_var05: value
+ page1_var06: value
+ page1_var07: value
+ page1_var08: value
+ page1_var09: value
+ page1_var10: value
+ page1_var11: value
+ page1_var12: value
+ page1_var13: value
+ page1_var14: value
+ page1_var15: value
+ page1_var16: value
+ page1_var17: value
+ page1_var18: value
+ page1_var19: value
+ page1_var20: value
+ purge: true
+ register: gitlab_group_variable_state
+
+- name: complete page added state must be changed
+ assert:
+ that:
+ - gitlab_group_variable_state is changed
+ - gitlab_group_variable_state.group_variable.added|length == 20
+ - gitlab_group_variable_state.group_variable.untouched|length == 0
+
+- name: set complete page and keep existing ones
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ vars:
+ page2_var01: value
+ page2_var02: value
+ page2_var03: value
+ page2_var04: value
+ page2_var05: value
+ page2_var06: value
+ page2_var07: value
+ page2_var08: value
+ page2_var09: value
+ page2_var10: value
+ page2_var11: value
+ page2_var12: value
+ page2_var13: value
+ page2_var14: value
+ page2_var15: value
+ page2_var16: value
+ page2_var17: value
+ page2_var18: value
+ page2_var19: value
+ page2_var20: value
+ purge: false
+ register: gitlab_group_variable_state
+
+- name: existing page untouched state must be changed
+ assert:
+ that:
+ - gitlab_group_variable_state is changed
+ - gitlab_group_variable_state.group_variable.added|length == 20
+ - gitlab_group_variable_state.group_variable.untouched|length == 20
+
+- name: check that no variables are left
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ purge: true
+ register: gitlab_group_variable_state
+
+- name: check that no variables are untouched state must be changed
+ assert:
+ that:
+ - gitlab_group_variable_state.changed
+ - gitlab_group_variable_state.group_variable.added|length == 0
+ - gitlab_group_variable_state.group_variable.untouched|length == 0
+ - gitlab_group_variable_state.group_variable.removed|length == 40
+ - gitlab_group_variable_state.group_variable.updated|length == 0
+
+- name: same vars, diff scope
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ purge: true
+ variables:
+ - name: SECRET_ACCESS_KEY
+ value: 3214cbad
+ masked: true
+ protected: true
+ variable_type: env_var
+ environment_scope: production
+ - name: SECRET_ACCESS_KEY
+ value: hello_world
+ masked: true
+ protected: true
+ variable_type: env_var
+ environment_scope: development
+ register: gitlab_group_variable_state
+ when: gitlab_premium_tests is defined
+
+- name: verify two vars
+ assert:
+ that:
+ - gitlab_group_variable_state.changed
+ - gitlab_group_variable_state.group_variable.added|length == 2
+ - gitlab_group_variable_state.group_variable.untouched|length == 0
+ - gitlab_group_variable_state.group_variable.removed|length == 0
+ - gitlab_group_variable_state.group_variable.updated|length == 0
+ when: gitlab_premium_tests is defined
+
+- name: throw error when state is present but no value is given
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ variables:
+ - name: delete_me
+ register: gitlab_group_variable_state
+ ignore_errors: true
+
+- name: verify fail
+ assert:
+ that:
+ - gitlab_group_variable_state.failed
+ - gitlab_group_variable_state is not changed
+
+- name: set a new variable to delete it later
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ purge: true
+ variables:
+ - name: delete_me
+ value: ansible
+ register: gitlab_group_variable_state
+
+- name: verify the change
+ assert:
+ that:
+ - gitlab_group_variable_state.changed
+
+- name: delete variable without referencing its value
+ gitlab_group_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ group: "{{ gitlab_group_name }}"
+ state: absent
+ variables:
+ - name: delete_me
+ register: gitlab_group_variable_state
+
+- name: verify deletion
+ assert:
+ that:
+ - gitlab_group_variable_state.changed
+ - gitlab_group_variable_state.group_variable.removed|length == 1
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_hook/aliases b/ansible_collections/community/general/tests/integration/targets/gitlab_hook/aliases
new file mode 100644
index 000000000..fc0e157c9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_hook/aliases
@@ -0,0 +1,7 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+gitlab/ci
+disabled
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_hook/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_hook/defaults/main.yml
new file mode 100644
index 000000000..69cec7d33
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_hook/defaults/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+gitlab_project_name: ansible_test_project
+gitlab_hook_url: http://gitlab.example.com/hook
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_hook/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_hook/tasks/main.yml
new file mode 100644
index 000000000..aa06f6c81
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_hook/tasks/main.yml
@@ -0,0 +1,77 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install required libs
+ pip:
+ name: python-gitlab
+ state: present
+
+- name: Create {{ gitlab_project_name }}
+ gitlab_project:
+ server_url: "{{ gitlab_host }}"
+ validate_certs: false
+ login_token: "{{ gitlab_login_token }}"
+ name: "{{ gitlab_project_name }}"
+ state: present
+
+- name: Cleanup GitLab hook
+ gitlab_hook:
+ server_url: "{{ gitlab_host }}"
+ validate_certs: false
+ login_token: "{{ gitlab_login_token }}"
+ hook_url: "{{ gitlab_hook_url }}"
+ project: "{{ gitlab_project_name }}"
+ state: absent
+
+- name: Create GitLab Hook
+ gitlab_hook:
+ server_url: "{{ gitlab_host }}"
+ validate_certs: false
+ login_token: "{{ gitlab_login_token }}"
+ hook_url: "{{ gitlab_hook_url }}"
+ project: "{{ gitlab_project_name }}"
+ state: present
+ register: gitlab_hook_state
+
+- name: Test group created
+ assert:
+ that:
+ - gitlab_hook_state is changed
+
+
+- name: Create GitLab Hook ( Idempotency test )
+ gitlab_hook:
+ server_url: "{{ gitlab_host }}"
+ validate_certs: false
+ login_token: "{{ gitlab_login_token }}"
+ hook_url: "{{ gitlab_hook_url }}"
+ project: "{{ gitlab_project_name }}"
+ state: present
+ register: gitlab_hook_state_again
+
+- name: Test module is idempotent
+ assert:
+ that:
+ - gitlab_hook_state_again is not changed
+
+- name: Remove GitLab hook
+ gitlab_hook:
+ server_url: "{{ gitlab_host }}"
+ validate_certs: false
+ login_token: "{{ gitlab_login_token }}"
+ hook_url: "{{ gitlab_hook_url }}"
+ project: "{{ gitlab_project_name }}"
+ state: absent
+ register: gitlab_hook_state_absent
+
+- name: Assert hook has been removed
+ assert:
+ that:
+ - gitlab_hook_state_absent is changed
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_project/aliases b/ansible_collections/community/general/tests/integration/targets/gitlab_project/aliases
new file mode 100644
index 000000000..fc0e157c9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_project/aliases
@@ -0,0 +1,7 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+gitlab/ci
+disabled
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_project/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_project/defaults/main.yml
new file mode 100644
index 000000000..457129c22
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_project/defaults/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+gitlab_project_name: ansible_test_project
+gitlab_deploy_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJnTYY7CYk1F/wBklpdRxudxN6KeXgfhutkiCigSfPhe ansible_test"
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_project/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_project/tasks/main.yml
new file mode 100644
index 000000000..0a9e47188
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_project/tasks/main.yml
@@ -0,0 +1,49 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install required libs
+ pip:
+ name: python-gitlab
+ state: present
+
+- name: Clean up {{ gitlab_project_name }}
+ gitlab_project:
+ server_url: "{{ gitlab_host }}"
+ validate_certs: false
+ login_token: "{{ gitlab_login_token }}"
+ name: "{{ gitlab_project_name }}"
+ state: absent
+
+- name: Create {{ gitlab_project_name }}
+ gitlab_project:
+ server_url: "{{ gitlab_host }}"
+ validate_certs: false
+ login_token: "{{ gitlab_login_token }}"
+ name: "{{ gitlab_project_name }}"
+ initialize_with_readme: true
+ state: present
+ register: gitlab_project_state
+
+- assert:
+ that:
+ - gitlab_project_state is changed
+
+- name: Create {{ gitlab_project_name }} (Test idempotency)
+ gitlab_project:
+ server_url: "{{ gitlab_host }}"
+ validate_certs: false
+ login_token: "{{ gitlab_login_token }}"
+ name: "{{ gitlab_project_name }}"
+ state: present
+ register: gitlab_project_state_again
+
+- assert:
+ that:
+ - gitlab_project_state_again is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_project_badge/aliases b/ansible_collections/community/general/tests/integration/targets/gitlab_project_badge/aliases
new file mode 100644
index 000000000..9f72f3711
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_project_badge/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) 2022, Guillaume MARTINEZ (lunik@tiwabbit.fr)
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+gitlab/ci
+disabled
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_project_badge/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_project_badge/defaults/main.yml
new file mode 100644
index 000000000..bf84a4751
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_project_badge/defaults/main.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+gitlab_api_token: glpat-XXXXXXXXXXXXXXXXXXXX
+gitlab_api_url: https://gitlab.com
+gitlab_project_name: ansible_test_project
+gitlab_badge_link_url: 'https://example.gitlab.com/%{project_path}'
+updated_gitlab_badge_link_url: 'https://test.gitlab.com/%{project_path}'
+gitlab_badge_image_url: 'https://example.gitlab.com/%{project_path}/badges/%{default_branch}/pipeline.svg' \ No newline at end of file
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_project_badge/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_project_badge/tasks/main.yml
new file mode 100644
index 000000000..efc090ef7
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_project_badge/tasks/main.yml
@@ -0,0 +1,214 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install required libs
+ pip:
+ name: python-gitlab
+ state: present
+
+- name: Create {{ gitlab_project_name }}
+ gitlab_project:
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: false
+ api_token: "{{ gitlab_api_token }}"
+ name: "{{ gitlab_project_name }}"
+ initialize_with_readme: true
+ state: present
+
+- name: Create Badge (check)
+ check_mode: true
+ gitlab_project_badge:
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: false
+ api_token: "{{ gitlab_api_token }}"
+ project: "{{ gitlab_project_name }}"
+ state: present
+ link_url: "{{ gitlab_badge_link_url }}"
+ image_url: "{{ gitlab_badge_image_url }}"
+ register: gitlab_badge_create_check_task
+
+- ansible.builtin.debug:
+ var: gitlab_badge_create_check_task
+
+- name: Check module call result
+ assert:
+ that:
+ - gitlab_badge_create_check_task.changed
+ - not gitlab_badge_create_check_task.failed
+
+- name: Create Badge
+ gitlab_project_badge:
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: false
+ api_token: "{{ gitlab_api_token }}"
+ project: "{{ gitlab_project_name }}"
+ state: present
+ link_url: "{{ gitlab_badge_link_url }}"
+ image_url: "{{ gitlab_badge_image_url }}"
+ register: gitlab_badge_create_task
+
+- ansible.builtin.debug:
+ var: gitlab_badge_create_task
+
+- name: Check module call result
+ assert:
+ that:
+ - gitlab_badge_create_task.changed
+ - not gitlab_badge_create_task.failed
+
+- name: Create Badge (confirmation)
+ gitlab_project_badge:
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: false
+ api_token: "{{ gitlab_api_token }}"
+ project: "{{ gitlab_project_name }}"
+ state: present
+ link_url: "{{ gitlab_badge_link_url }}"
+ image_url: "{{ gitlab_badge_image_url }}"
+ register: gitlab_badge_create_confirmation_task
+
+- ansible.builtin.debug:
+ var: gitlab_badge_create_confirmation_task
+
+- name: Check module call result
+ assert:
+ that:
+ - not gitlab_badge_create_confirmation_task.changed
+ - not gitlab_badge_create_confirmation_task.failed
+
+- name: Update Badge (check)
+ check_mode: true
+ gitlab_project_badge:
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: false
+ api_token: "{{ gitlab_api_token }}"
+ project: "{{ gitlab_project_name }}"
+ state: present
+ link_url: "{{ updated_gitlab_badge_link_url }}"
+ image_url: "{{ gitlab_badge_image_url }}"
+ register: gitlab_badge_update_check_task
+
+- ansible.builtin.debug:
+ var: gitlab_badge_update_check_task
+
+- name: Check module call result
+ assert:
+ that:
+ - gitlab_badge_update_check_task.changed
+ - not gitlab_badge_update_check_task.failed
+
+- name: Update Badge
+ gitlab_project_badge:
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: false
+ api_token: "{{ gitlab_api_token }}"
+ project: "{{ gitlab_project_name }}"
+ state: present
+ link_url: "{{ updated_gitlab_badge_link_url }}"
+ image_url: "{{ gitlab_badge_image_url }}"
+ register: gitlab_badge_update_task
+
+- ansible.builtin.debug:
+ var: gitlab_badge_update_task
+
+- name: Check module call result
+ assert:
+ that:
+ - gitlab_badge_update_task.changed
+ - not gitlab_badge_update_task.failed
+
+- name: Update Badge (confirmation)
+ gitlab_project_badge:
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: false
+ api_token: "{{ gitlab_api_token }}"
+ project: "{{ gitlab_project_name }}"
+ state: present
+ link_url: "{{ updated_gitlab_badge_link_url }}"
+ image_url: "{{ gitlab_badge_image_url }}"
+ register: gitlab_badge_update_confirmation_task
+
+- ansible.builtin.debug:
+ var: gitlab_badge_update_confirmation_task
+
+- name: Check module call result
+ assert:
+ that:
+ - not gitlab_badge_update_confirmation_task.changed
+ - not gitlab_badge_update_confirmation_task.failed
+
+- name: Delete Badge (check)
+ check_mode: true
+ gitlab_project_badge:
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: false
+ api_token: "{{ gitlab_api_token }}"
+ project: "{{ gitlab_project_name }}"
+ state: absent
+ link_url: "{{ updated_gitlab_badge_link_url }}"
+ image_url: "{{ gitlab_badge_image_url }}"
+ register: gitlab_badge_delete_check_task
+
+- ansible.builtin.debug:
+ var: gitlab_badge_delete_check_task
+
+- name: Check module call result
+ assert:
+ that:
+ - gitlab_badge_delete_check_task.changed
+ - not gitlab_badge_delete_check_task.failed
+
+- name: Delete Badge
+ gitlab_project_badge:
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: false
+ api_token: "{{ gitlab_api_token }}"
+ project: "{{ gitlab_project_name }}"
+ state: absent
+ link_url: "{{ updated_gitlab_badge_link_url }}"
+ image_url: "{{ gitlab_badge_image_url }}"
+ register: gitlab_badge_delete_task
+
+- ansible.builtin.debug:
+ var: gitlab_badge_delete_task
+
+- name: Check module call result
+ assert:
+ that:
+ - gitlab_badge_delete_task.changed
+ - not gitlab_badge_delete_task.failed
+
+- name: Delete Badge (confirmation)
+ gitlab_project_badge:
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: false
+ api_token: "{{ gitlab_api_token }}"
+ project: "{{ gitlab_project_name }}"
+ state: absent
+ link_url: "{{ updated_gitlab_badge_link_url }}"
+ image_url: "{{ gitlab_badge_image_url }}"
+ register: gitlab_badge_delete_confirmation_task
+
+- ansible.builtin.debug:
+ var: gitlab_badge_delete_confirmation_task
+
+- name: Check module call result
+ assert:
+ that:
+ - not gitlab_badge_delete_confirmation_task.changed
+ - not gitlab_badge_delete_confirmation_task.failed
+
+- name: Clean up {{ gitlab_project_name }}
+ gitlab_project:
+ api_url: "{{ gitlab_api_url }}"
+ validate_certs: false
+ api_token: "{{ gitlab_api_token }}"
+ name: "{{ gitlab_project_name }}"
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_project_members/aliases b/ansible_collections/community/general/tests/integration/targets/gitlab_project_members/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_project_members/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_project_members/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_project_members/defaults/main.yml
new file mode 100644
index 000000000..72d5a68f1
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_project_members/defaults/main.yml
@@ -0,0 +1,18 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+gitlab_server_url: https://gitlab.com
+gitlab_api_access_token: "token"
+gitlab_project: some_project
+username: some_user
+gitlab_access_level: developer
+userlist:
+ - username1
+ - username2
+dedicated_access_users:
+ - name: username1
+ access_level: "developer"
+ - name: username2
+ access_level: "maintainer"
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_project_members/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_project_members/tasks/main.yml
new file mode 100644
index 000000000..215abad44
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_project_members/tasks/main.yml
@@ -0,0 +1,124 @@
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Test code for gitlab_project_members module
+#
+# Copyright (c) 2021, Sergey Mikhaltsov <metanovii@gmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install required library
+ pip:
+ name: python-gitlab
+ state: present
+
+- name: Clean UP before tests
+ community.general.gitlab_project_members:
+ api_url: "{{ gitlab_server_url }}"
+ api_token: "{{ gitlab_api_access_token }}"
+ project: "{{ gitlab_project }}"
+ gitlab_user: "{{ username }}"
+ state: absent
+
+- name: Add a User to A GitLab Project
+ community.general.gitlab_project_members:
+ api_url: "{{ gitlab_server_url }}"
+ api_token: "{{ gitlab_api_access_token }}"
+ project: "{{ gitlab_project }}"
+ gitlab_user: "{{ username }}"
+ access_level: "{{ gitlab_access_level }}"
+ state: present
+ register: gitlab_project_members_state
+
+- name: Test member added to project
+ assert:
+ that:
+ - gitlab_project_members_state is changed
+
+- name: Add a User to A GitLab Project ( Idempotency test )
+ community.general.gitlab_project_members:
+ api_url: "{{ gitlab_server_url }}"
+ api_token: "{{ gitlab_api_access_token }}"
+ project: "{{ gitlab_project }}"
+ gitlab_user: "{{ username }}"
+ access_level: "{{ gitlab_access_level }}"
+ state: present
+ register: gitlab_project_members_state_again
+
+- name: Test module is idempotent
+ assert:
+ that:
+ - gitlab_project_members_state_again is not changed
+
+- name: Remove a User from A GitLab Project
+ community.general.gitlab_project_members:
+ api_url: "{{ gitlab_server_url }}"
+ api_token: "{{ gitlab_api_access_token }}"
+ project: "{{ gitlab_project }}"
+ gitlab_user: "{{ username }}"
+ state: absent
+ register: remove_gitlab_project_members_state
+
+- name: Test member removed from project
+ assert:
+ that:
+ - remove_gitlab_project_members_state is changed
+
+- name: Remove a User from A GitLab Project ( Idempotency test )
+ community.general.gitlab_project_members:
+ api_url: "{{ gitlab_server_url }}"
+ api_token: "{{ gitlab_api_access_token }}"
+ project: "{{ gitlab_project }}"
+ gitlab_user: "{{ username }}"
+ state: absent
+ register: remove_gitlab_project_members_state_again
+
+- name: Test module is idempotent
+ assert:
+ that:
+ - remove_gitlab_project_members_state_again is not changed
+
+- name: Add a list of Users to A GitLab Project
+ community.general.gitlab_project_members:
+ api_url: "{{ gitlab_server_url }}"
+ api_token: "{{ gitlab_api_access_token }}"
+ project: "{{ gitlab_project }}"
+ gitlab_user: "{{ userlist }}"
+ access_level: "{{ gitlab_access_level }}"
+ state: present
+
+- name: Remove a list of Users to A GitLab Project
+ community.general.gitlab_project_members::
+ api_url: "{{ gitlab_server_url }}"
+ api_token: "{{ gitlab_api_access_token }}"
+ project: "{{ gitlab_project }}"
+ gitlab_user: "{{ userlist }}"
+ state: absent
+
+- name: Add a list of Users with Dedicated Access Levels to A GitLab Project
+ community.general.gitlab_project_members::
+ api_url: "{{ gitlab_server_url }}"
+ api_token: "{{ gitlab_api_access_token }}"
+ project: "{{ gitlab_project }}"
+ gitlab_users_access: "{{ dedicated_access_users }}"
+ state: present
+
+- name: Remove a list of Users with Dedicated Access Levels to A GitLab Project
+ community.general.gitlab_project_members::
+ api_url: "{{ gitlab_server_url }}"
+ api_token: "{{ gitlab_api_access_token }}"
+ project: "{{ gitlab_project }}"
+ gitlab_users_access: "{{ dedicated_access_users }}"
+ state: absent
+
+- name: Add a user, remove all others which might be on this access level
+ community.general.gitlab_project_members::
+ api_url: "{{ gitlab_server_url }}"
+ api_token: "{{ gitlab_api_access_token }}"
+ project: "{{ gitlab_project }}"
+ gitlab_user: "{{ username }}"
+ access_level: "{{ gitlab_access_level }}"
+ pruge_users: "{{ gitlab_access_level }}"
+ state: present
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_project_variable/aliases b/ansible_collections/community/general/tests/integration/targets/gitlab_project_variable/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_project_variable/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_project_variable/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_project_variable/tasks/main.yml
new file mode 100644
index 000000000..0645da0fd
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_project_variable/tasks/main.yml
@@ -0,0 +1,701 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install required libs
+ pip:
+ name: python-gitlab
+ state: present
+
+- name: purge all variables for check_mode test
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ purge: true
+
+- name: add a variable value in check_mode
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ ACCESS_KEY_ID: checkmode
+ check_mode: true
+ register: gitlab_project_variable_state
+
+- name: check_mode state must be changed
+ assert:
+ that:
+ - gitlab_project_variable_state is changed
+
+- name: apply add value from check_mode test
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ variables:
+ - name: ACCESS_KEY_ID
+ value: checkmode
+ register: gitlab_project_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_project_variable_state is changed
+
+- name: test new format
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ ACCESS_KEY_ID:
+ value: checkmode
+ register: gitlab_project_variable_state
+
+- name: state must be not changed
+ assert:
+ that:
+ - gitlab_project_variable_state is not changed
+
+- name: change protected attribute
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ ACCESS_KEY_ID:
+ value: checkmode
+ protected: true
+ register: gitlab_project_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_project_variable_state is changed
+
+- name: revert protected attribute
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ ACCESS_KEY_ID:
+ value: checkmode
+ protected: false
+ register: gitlab_project_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_project_variable_state is changed
+
+- name: change masked attribute
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ ACCESS_KEY_ID:
+ value: checkmode
+ masked: true
+ register: gitlab_project_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_project_variable_state is changed
+
+- name: revert masked attribute by not mention it
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ ACCESS_KEY_ID:
+ value: checkmode
+ register: gitlab_project_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_project_variable_state is changed
+
+- name: revert again masked attribute by not mention it (idempotent)
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ ACCESS_KEY_ID:
+ value: checkmode
+ register: gitlab_project_variable_state
+
+- name: state must be not changed
+ assert:
+ that:
+ - gitlab_project_variable_state is not changed
+
+- name: set both (masked and protected) attribute
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ ACCESS_KEY_ID:
+ value: checkmode
+ masked: true
+ protected: true
+ variable_type: env_var
+ register: gitlab_project_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_project_variable_state is changed
+
+- name: set again both (masked and protected) attribute (idempotent)
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ ACCESS_KEY_ID:
+ value: checkmode
+ masked: true
+ protected: true
+ variable_type: env_var
+ register: gitlab_project_variable_state
+
+- name: state must not be changed
+ assert:
+ that:
+ - gitlab_project_variable_state is not changed
+
+- name: revert both (masked and protected) attribute
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ ACCESS_KEY_ID:
+ value: checkmode
+ protected: false
+ register: gitlab_project_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_project_variable_state is changed
+
+- name: change a variable value in check_mode again
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ ACCESS_KEY_ID: checkmode
+ check_mode: true
+ register: gitlab_project_variable_state
+
+- name: check_mode state must not be changed
+ assert:
+ that:
+ - gitlab_project_variable_state is not changed
+
+- name: apply again the value change from check_mode test
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ ACCESS_KEY_ID: checkmode
+ register: gitlab_project_variable_state
+
+- name: state must not be changed
+ assert:
+ that:
+ - gitlab_project_variable_state is not changed
+
+- name: change environment scope
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ ACCESS_KEY_ID:
+ environment_scope: testing
+ value: checkmode
+ register: gitlab_project_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_project_variable_state is changed
+
+- name: apply again the environment scope change
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ ACCESS_KEY_ID:
+ environment_scope: testing
+ value: checkmode
+ register: gitlab_project_variable_state
+
+- name: state must not be changed
+ assert:
+ that:
+ - gitlab_project_variable_state is not changed
+
+- name: purge all variables at the beginning
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ purge: true
+
+- name: set two test variables
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ ACCESS_KEY_ID: abc123
+ SECRET_ACCESS_KEY: 321cba
+ register: gitlab_project_variable_state
+
+- name: set two test variables state must be changed
+ assert:
+ that:
+ - gitlab_project_variable_state is changed
+ - gitlab_project_variable_state.project_variable.added|length == 2
+ - gitlab_project_variable_state.project_variable.untouched|length == 0
+ - gitlab_project_variable_state.project_variable.removed|length == 0
+ - gitlab_project_variable_state.project_variable.updated|length == 0
+
+- name: re-set two test variables
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ ACCESS_KEY_ID: abc123
+ SECRET_ACCESS_KEY: 321cba
+ register: gitlab_project_variable_state
+
+- name: re-set two test variables state must not be changed
+ assert:
+ that:
+ - gitlab_project_variable_state is not changed
+ - gitlab_project_variable_state.project_variable.added|length == 0
+ - gitlab_project_variable_state.project_variable.untouched|length == 2
+ - gitlab_project_variable_state.project_variable.removed|length == 0
+ - gitlab_project_variable_state.project_variable.updated|length == 0
+
+- name: edit one variable
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ ACCESS_KEY_ID: changed
+ purge: false
+ register: gitlab_project_variable_state
+
+- name: edit one variable state must be changed
+ assert:
+ that:
+ - gitlab_project_variable_state.changed
+ - gitlab_project_variable_state.project_variable.added|length == 0
+ - gitlab_project_variable_state.project_variable.untouched|length == 1
+ - gitlab_project_variable_state.project_variable.removed|length == 0
+ - gitlab_project_variable_state.project_variable.updated|length == 1
+ - gitlab_project_variable_state.project_variable.updated[0] == "ACCESS_KEY_ID"
+
+- name: append one variable
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ some: value
+ purge: false
+ register: gitlab_project_variable_state
+
+- name: append one variable state must be changed
+ assert:
+ that:
+ - gitlab_project_variable_state.changed
+ - gitlab_project_variable_state.project_variable.added|length == 1
+ - gitlab_project_variable_state.project_variable.untouched|length == 2
+ - gitlab_project_variable_state.project_variable.removed|length == 0
+ - gitlab_project_variable_state.project_variable.updated|length == 0
+ - gitlab_project_variable_state.project_variable.added[0] == "some"
+
+- name: re-set all variables
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ ACCESS_KEY_ID: changed
+ SECRET_ACCESS_KEY: 321cba
+ some: value
+ register: gitlab_project_variable_state
+
+- name: re-set all variables state must not be changed
+ assert:
+ that:
+ - not gitlab_project_variable_state.changed
+ - gitlab_project_variable_state.project_variable.added|length == 0
+ - gitlab_project_variable_state.project_variable.untouched|length == 3
+ - gitlab_project_variable_state.project_variable.removed|length == 0
+ - gitlab_project_variable_state.project_variable.updated|length == 0
+
+- name: set one variables and purge all others
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ some: value
+ purge: true
+ register: gitlab_project_variable_state
+
+- name: set one variables and purge all others state must be changed
+ assert:
+ that:
+ - gitlab_project_variable_state.changed
+ - gitlab_project_variable_state.project_variable.added|length == 0
+ - gitlab_project_variable_state.project_variable.untouched|length == 1
+ - gitlab_project_variable_state.project_variable.removed|length == 2
+ - gitlab_project_variable_state.project_variable.updated|length == 0
+
+- name: only one variable is left
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ some: value
+ purge: false
+ register: gitlab_project_variable_state
+
+- name: only one variable is left state must not be changed
+ assert:
+ that:
+ - not gitlab_project_variable_state.changed
+ - gitlab_project_variable_state.project_variable.added|length == 0
+ - gitlab_project_variable_state.project_variable.untouched|length == 1
+ - gitlab_project_variable_state.project_variable.removed|length == 0
+ - gitlab_project_variable_state.project_variable.updated|length == 0
+ - gitlab_project_variable_state.project_variable.untouched[0] == "some"
+
+- name: test integer values
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ some: 42
+ purge: false
+ register: gitlab_project_variable_state
+
+- name: only one variable is left state must be changed
+ assert:
+ that:
+ - gitlab_project_variable_state.changed
+ - gitlab_project_variable_state.project_variable.added|length == 0
+ - gitlab_project_variable_state.project_variable.untouched|length == 0
+ - gitlab_project_variable_state.project_variable.removed|length == 0
+ - gitlab_project_variable_state.project_variable.updated|length == 1
+
+- name: test float values
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ some: 42.23
+ purge: false
+ register: gitlab_project_variable_state
+
+- name: only one variable is left state must be changed
+ assert:
+ that:
+ - gitlab_project_variable_state.changed
+ - gitlab_project_variable_state.project_variable.added|length == 0
+ - gitlab_project_variable_state.project_variable.untouched|length == 0
+ - gitlab_project_variable_state.project_variable.removed|length == 0
+ - gitlab_project_variable_state.project_variable.updated|length == 1
+
+- name: delete the last left variable
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ state: absent
+ vars:
+ some: value
+ register: gitlab_project_variable_state
+
+- name: no variable is left state must be changed
+ assert:
+ that:
+ - gitlab_project_variable_state.changed
+ - gitlab_project_variable_state.project_variable.added|length == 0
+ - gitlab_project_variable_state.project_variable.untouched|length == 0
+ - gitlab_project_variable_state.project_variable.removed|length == 1
+ - gitlab_project_variable_state.project_variable.updated|length == 0
+ - gitlab_project_variable_state.project_variable.removed[0] == "some"
+
+- name: add one variable with variable_type file
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ variables:
+ - name: my_test_var
+ value: my_test_value
+ variable_type: file
+ purge: false
+ register: gitlab_project_variable_state
+
+- name: append one variable state must be changed
+ assert:
+ that:
+ - gitlab_project_variable_state.changed
+ - gitlab_project_variable_state.project_variable.added|length == 1
+ - gitlab_project_variable_state.project_variable.untouched|length == 0
+ - gitlab_project_variable_state.project_variable.removed|length == 0
+ - gitlab_project_variable_state.project_variable.updated|length == 0
+ # VALUE_SPECIFIED_IN_NO_LOG_PARAMETER
+ #- gitlab_project_variable_state.project_variable.added[0] == "my_test_var"
+
+- name: change variable_type attribute
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ my_test_var:
+ value: my_test_value
+ variable_type: env_var
+ register: gitlab_project_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_project_variable_state is changed
+
+- name: revert variable_type attribute
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ my_test_var:
+ value: my_test_value
+ variable_type: file
+ register: gitlab_project_variable_state
+
+- name: state must be changed
+ assert:
+ that:
+ - gitlab_project_variable_state is changed
+
+- name: delete the variable_type file variable
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ state: absent
+ vars:
+ my_test_var: my_test_value
+ register: gitlab_project_variable_state
+
+- name: no variable is left state must be changed
+ assert:
+ that:
+ - gitlab_project_variable_state.changed
+ - gitlab_project_variable_state.project_variable.added|length == 0
+ - gitlab_project_variable_state.project_variable.untouched|length == 0
+ - gitlab_project_variable_state.project_variable.removed|length == 1
+ - gitlab_project_variable_state.project_variable.updated|length == 0
+ - gitlab_project_variable_state.project_variable.removed[0] == "my_test_var"
+
+- name: set complete page and purge existing ones
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ page1_var01: value
+ page1_var02: value
+ page1_var03: value
+ page1_var04: value
+ page1_var05: value
+ page1_var06: value
+ page1_var07: value
+ page1_var08: value
+ page1_var09: value
+ page1_var10: value
+ page1_var11: value
+ page1_var12: value
+ page1_var13: value
+ page1_var14: value
+ page1_var15: value
+ page1_var16: value
+ page1_var17: value
+ page1_var18: value
+ page1_var19: value
+ page1_var20: value
+ purge: true
+ register: gitlab_project_variable_state
+
+- name: complete page added state must be changed
+ assert:
+ that:
+ - gitlab_project_variable_state is changed
+ - gitlab_project_variable_state.project_variable.added|length == 20
+ - gitlab_project_variable_state.project_variable.untouched|length == 0
+
+- name: set complete page and keep existing ones
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ vars:
+ page2_var01: value
+ page2_var02: value
+ page2_var03: value
+ page2_var04: value
+ page2_var05: value
+ page2_var06: value
+ page2_var07: value
+ page2_var08: value
+ page2_var09: value
+ page2_var10: value
+ page2_var11: value
+ page2_var12: value
+ page2_var13: value
+ page2_var14: value
+ page2_var15: value
+ page2_var16: value
+ page2_var17: value
+ page2_var18: value
+ page2_var19: value
+ page2_var20: value
+ purge: false
+ register: gitlab_project_variable_state
+
+- name: existing page untouched state must be changed
+ assert:
+ that:
+ - gitlab_project_variable_state is changed
+ - gitlab_project_variable_state.project_variable.added|length == 20
+ - gitlab_project_variable_state.project_variable.untouched|length == 20
+
+- name: check that no variables are left
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ purge: true
+ register: gitlab_project_variable_state
+
+- name: check that no variables are untouched state must be changed
+ assert:
+ that:
+ - gitlab_project_variable_state.changed
+ - gitlab_project_variable_state.project_variable.added|length == 0
+ - gitlab_project_variable_state.project_variable.untouched|length == 0
+ - gitlab_project_variable_state.project_variable.removed|length == 40
+ - gitlab_project_variable_state.project_variable.updated|length == 0
+
+- name: same vars, diff scope
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ purge: true
+ variables:
+ - name: SECRET_ACCESS_KEY
+ value: 3214cbad
+ masked: true
+ protected: true
+ variable_type: env_var
+ environment_scope: production
+ - name: SECRET_ACCESS_KEY
+ value: hello_world
+ masked: true
+ protected: true
+ variable_type: env_var
+ environment_scope: development
+ register: gitlab_project_variable_state
+
+- name: verify two vars
+ assert:
+ that:
+ - gitlab_project_variable_state.changed
+ - gitlab_project_variable_state.project_variable.added|length == 2
+ - gitlab_project_variable_state.project_variable.untouched|length == 0
+ - gitlab_project_variable_state.project_variable.removed|length == 0
+ - gitlab_project_variable_state.project_variable.updated|length == 0
+
+- name: throw error when state is present but no value is given
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ variables:
+ - name: delete_me
+ register: gitlab_project_variable_state
+ ignore_errors: true
+
+- name: verify fail
+ assert:
+ that:
+ - gitlab_project_variable_state.failed
+ - gitlab_project_variable_state is not changed
+
+- name: set a new variable to delete it later
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ purge: true
+ variables:
+ - name: delete_me
+ value: ansible
+ register: gitlab_project_variable_state
+
+- name: verify the change
+ assert:
+ that:
+ - gitlab_project_variable_state.changed
+
+- name: delete variable without referencing its value
+ gitlab_project_variable:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ project: "{{ gitlab_project_name }}"
+ state: absent
+ variables:
+ - name: delete_me
+ register: gitlab_project_variable_state
+
+- name: verify deletion
+ assert:
+ that:
+ - gitlab_project_variable_state.changed
+ - gitlab_project_variable_state.project_variable.removed|length == 1
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_runner/aliases b/ansible_collections/community/general/tests/integration/targets/gitlab_runner/aliases
new file mode 100644
index 000000000..fc0e157c9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_runner/aliases
@@ -0,0 +1,7 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+gitlab/ci
+disabled
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_runner/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_runner/defaults/main.yml
new file mode 100644
index 000000000..ec7c0cfe1
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_runner/defaults/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+gitlab_project_name: ansible_test_project
+gitlab_hook_url: http://gitlab.example.com/hook
+gitlab_runner_name: ansible_test_runner
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_runner/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_runner/tasks/main.yml
new file mode 100644
index 000000000..467e918c2
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_runner/tasks/main.yml
@@ -0,0 +1,78 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install required libs
+ pip:
+ name: python-gitlab
+ state: present
+
+- name: Create {{ gitlab_project_name }}
+ gitlab_project:
+ server_url: "{{ gitlab_host }}"
+ validate_certs: false
+ login_token: "{{ gitlab_login_token }}"
+ name: "{{ gitlab_project_name }}"
+ state: present
+
+- name: Cleanup GitLab runner
+ gitlab_runner:
+ server_url: "{{ gitlab_host }}"
+ validate_certs: false
+ login_token: "{{ gitlab_login_token }}"
+ description: "{{ gitlab_runner_name }}"
+ registration_token: "{{ gitlab_runner_registration_token }}"
+ state: absent
+
+- name: Create GitLab Runner
+ gitlab_runner:
+ server_url: "{{ gitlab_host }}"
+ validate_certs: false
+ login_token: "{{ gitlab_login_token }}"
+ description: "{{ gitlab_runner_name }}"
+ registration_token: "{{ gitlab_runner_registration_token }}"
+ state: present
+ register: gitlab_runner_state
+
+- name: Test group created
+ assert:
+ that:
+ - gitlab_runner_state is changed
+
+
+#### COMMENTED AS MODULE WILL UPDATE THE RUNNER IF EXISTS. TO BE DISCUSSED ####
+# - name: Create GitLab Runner ( Idempotency test )
+# gitlab_runner:
+# server_url: "{{ gitlab_host }}"
+# validate_certs: false
+# login_token: "{{ gitlab_login_token }}"
+# description: "{{ gitlab_runner_name }}"
+# registration_token: "{{ gitlab_runner_registration_token }}"
+# state: present
+# register: gitlab_runner_state_again
+
+# - name: Test module is idempotent
+# assert:
+# that:
+# - gitlab_runner_state_again is not changed
+
+- name: Remove GitLab Runner
+ gitlab_runner:
+ server_url: "{{ gitlab_host }}"
+ validate_certs: false
+ login_token: "{{ gitlab_login_token }}"
+ description: "{{ gitlab_runner_name }}"
+ registration_token: "{{ gitlab_runner_registration_token }}"
+ state: absent
+ register: gitlab_runner_state_absent
+
+- name: Assert runner has been removed
+ assert:
+ that:
+ - gitlab_runner_state_absent is changed
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_user/aliases b/ansible_collections/community/general/tests/integration/targets/gitlab_user/aliases
new file mode 100644
index 000000000..fc0e157c9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_user/aliases
@@ -0,0 +1,7 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+gitlab/ci
+disabled
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_user/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_user/defaults/main.yml
new file mode 100644
index 000000000..c7a4a5dd3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_user/defaults/main.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+gitlab_user: ansible_test_user
+gitlab_user_pass: Secr3tPassw00rd
+gitlab_user_email: root@localhost
+gitlab_sshkey_name: ansibletest
+gitlab_sshkey_file: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDI8GIMlrirf+zsvBpxnF0daykP6YEJ5wytZXhDGD2dZXg9Tln0KUSDgreT3FDgoabjlOmG1L/nhu6ML76WCsmc/wnVMlXlDlQpVJSQ2PCxGNs9WRW7Y/Pk6t9KtV/VSYr0LaPgLEU8VkffSUBJezbKa1cssjb4CmRRqcePRNYpgCXdK05TEgFvmXl9qIM8Domf1ak1PlbyMmi/MytzHmnVFzxgUKv5c0Mr+vguCi131gPdh3QSf5AHPLEoO9LcMfu2IO1zvl61wYfsJ0Wn2Fncw+tJQfUin0ffTFgUIsGqki04/YjXyWynjSwQf5Jym4BYM0i2zlDUyRxs4/Tfp4yvJFik42ambzjLK6poq+iCpQReeYih9WZUaZwUQe7zYWhTOuoV7ydsk8+kDRMPidF9K5zWkQnglGrOzdbTqnhxNpwHCg2eSRJ49kPYLOH76g8P7IQvl+zluG0o8Nndir1WcYil4D4CCBskM8WbmrElZH1CRyP/NQMNIf4hFMItTjk= ansible@ansible
+gitlab_sshkey_expires_at: 2030-01-01T00:00:00.000Z
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_user/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_user/tasks/main.yml
new file mode 100644
index 000000000..e8c1ec360
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_user/tasks/main.yml
@@ -0,0 +1,257 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install required libs
+ pip:
+ name: python-gitlab
+ state: present
+
+- name: Clean up gitlab user
+ gitlab_user:
+ api_url: "{{ gitlab_host }}"
+ name: ansible_test_user
+ username: ansible_test_user
+ password: Secr3tPassw00rd
+ email: root@localhost
+ validate_certs: false
+ api_token: "{{ gitlab_login_token }}"
+ state: absent
+
+
+- name: Create gitlab user
+ gitlab_user:
+ api_url: "{{ gitlab_host }}"
+ email: "{{ gitlab_user_email }}"
+ name: "{{ gitlab_user }}"
+ username: "{{ gitlab_user }}"
+ password: "{{ gitlab_user_pass }}"
+ validate_certs: false
+ api_token: "{{ gitlab_login_token }}"
+ state: present
+ register: gitlab_user_state
+
+- name: Check user has been created correctly
+ assert:
+ that:
+ - gitlab_user_state is changed
+
+- name: Create gitlab user again
+ gitlab_user:
+ api_url: "{{ gitlab_host }}"
+ email: root@localhost
+ name: ansible_test_user
+ username: ansible_test_user
+ password: Secr3tPassw00rd
+ validate_certs: false
+ api_token: "{{ gitlab_login_token }}"
+ state: present
+ register: gitlab_user_state_again
+
+- name: Check state is not changed
+ assert:
+ that:
+ - gitlab_user_state_again is not changed
+ - gitlab_user_state_again.user.is_admin == False
+
+
+- name: Update User Test => Make User Admin
+ gitlab_user:
+ api_url: "{{ gitlab_host }}"
+ email: "{{ gitlab_user_email }}"
+ name: "{{ gitlab_user }}"
+ username: "{{ gitlab_user }}"
+ isadmin: true
+ validate_certs: false
+ api_token: "{{ gitlab_login_token }}"
+ state: present
+ register: gitlab_user_state
+
+- name: Check if user is admin now
+ assert:
+ that:
+ - gitlab_user_state is changed
+ - gitlab_user_state.user.is_admin == True
+
+- name: Update User Test => Make User Admin (Again)
+ gitlab_user:
+ api_url: "{{ gitlab_host }}"
+ email: "{{ gitlab_user_email }}"
+ name: "{{ gitlab_user }}"
+ username: "{{ gitlab_user }}"
+ isadmin: true
+ validate_certs: false
+ api_token: "{{ gitlab_login_token }}"
+ state: present
+ register: gitlab_user_state
+
+- name: Check state is not changed
+ assert:
+ that:
+ - gitlab_user_state is not changed
+ - gitlab_user_state.user.is_admin == True
+
+- name: Update User Test => Remove Admin Rights
+ gitlab_user:
+ api_url: "{{ gitlab_host }}"
+ email: "{{ gitlab_user_email }}"
+ name: "{{ gitlab_user }}"
+ username: "{{ gitlab_user }}"
+ isadmin: false
+ validate_certs: false
+ api_token: "{{ gitlab_login_token }}"
+ state: present
+ register: gitlab_user_state
+
+- name: Check if user is not admin anymore
+ assert:
+ that:
+ - gitlab_user_state is changed
+ - gitlab_user_state.user.is_admin == False
+
+
+- name: Update User Test => Try Changing Mail without Confirmation Skipping
+ gitlab_user:
+ api_url: "{{ gitlab_host }}"
+ email: foo@bar.baz
+ name: "{{ gitlab_user }}"
+ username: "{{ gitlab_user }}"
+ confirm: true
+ validate_certs: false
+ api_token: "{{ gitlab_login_token }}"
+ state: present
+ register: gitlab_user_state
+
+- name: Check that eMail is unchanged (Only works with confirmation skipping)
+ assert:
+ that:
+ - gitlab_user_state is changed
+ - gitlab_user_state.user.email == gitlab_user_email
+
+- name: Update User Test => Change Mail with Confirmation Skip
+ gitlab_user:
+ api_url: "{{ gitlab_host }}"
+ email: foo@bar.baz
+ name: "{{ gitlab_user }}"
+ username: "{{ gitlab_user }}"
+ confirm: false
+ validate_certs: false
+ api_token: "{{ gitlab_login_token }}"
+ state: present
+ register: gitlab_user_state
+
+- name: Check that mail has changed now
+ assert:
+ that:
+ - gitlab_user_state is changed
+ - gitlab_user_state.user.email == 'foo@bar.baz'
+
+- name: Update User Test => Change Mail with Confirmation Skip (Again)
+ gitlab_user:
+ api_url: "{{ gitlab_host }}"
+ email: foo@bar.baz
+ name: "{{ gitlab_user }}"
+ username: "{{ gitlab_user }}"
+ confirm: false
+ validate_certs: false
+ api_token: "{{ gitlab_login_token }}"
+ state: present
+ register: gitlab_user_state
+
+- name: Check state is not changed
+ assert:
+ that:
+ - gitlab_user_state is not changed
+ - gitlab_user_state.user.email == 'foo@bar.baz'
+
+- name: Update User Test => Revert to original Mail Address
+ gitlab_user:
+ api_url: "{{ gitlab_host }}"
+ email: "{{ gitlab_user_email }}"
+ name: "{{ gitlab_user }}"
+ username: "{{ gitlab_user }}"
+ confirm: false
+ validate_certs: false
+ api_token: "{{ gitlab_login_token }}"
+ state: present
+ register: gitlab_user_state
+
+- name: Check that reverting mail back to original has worked
+ assert:
+ that:
+ - gitlab_user_state is changed
+ - gitlab_user_state.user.email == gitlab_user_email
+
+
+- name: Update User Test => Change User Password
+ gitlab_user:
+ api_url: "{{ gitlab_host }}"
+ validate_certs: false
+
+ # note: the only way to check if a password really is what it is expected
+ # to be is to use it for login, so we use it here instead of the
+ # default token assuming that a user can always change its own password
+ api_username: "{{ gitlab_user }}"
+ api_password: "{{ gitlab_user_pass }}"
+
+ email: "{{ gitlab_user_email }}"
+ name: "{{ gitlab_user }}"
+ username: "{{ gitlab_user }}"
+ password: new-super-password
+ state: present
+ register: gitlab_user_state
+
+- name: Check PW setting return state
+ assert:
+ that:
+ # note: there is no way to determine if a password has changed or
+ # not, so it can only be always yellow or always green, we
+ # decided for always green for now
+ - gitlab_user_state is not changed
+
+- name: Update User Test => Reset User Password
+ gitlab_user:
+ api_url: "{{ gitlab_host }}"
+ validate_certs: false
+
+ api_username: "{{ gitlab_user }}"
+ api_password: new-super-password
+
+ email: "{{ gitlab_user_email }}"
+ name: "{{ gitlab_user }}"
+ username: "{{ gitlab_user }}"
+ password: "{{ gitlab_user_pass }}"
+ state: present
+ register: gitlab_user_state
+
+- name: Check PW setting return state (Again)
+ assert:
+ that:
+ - gitlab_user_state is not changed
+
+- name: Update User Test => Check that password was reset
+ gitlab_user:
+ api_url: "{{ gitlab_host }}"
+ validate_certs: false
+
+ api_username: "{{ gitlab_user }}"
+ api_password: "{{ gitlab_user_pass }}"
+
+ email: "{{ gitlab_user_email }}"
+ name: "{{ gitlab_user }}"
+ username: "{{ gitlab_user }}"
+ state: present
+ register: gitlab_user_state
+
+- name: Check PW setting return state (Reset)
+ assert:
+ that:
+ - gitlab_user_state is not changed
+
+- include_tasks: sshkey.yml
diff --git a/ansible_collections/community/general/tests/integration/targets/gitlab_user/tasks/sshkey.yml b/ansible_collections/community/general/tests/integration/targets/gitlab_user/tasks/sshkey.yml
new file mode 100644
index 000000000..bba724d5e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/gitlab_user/tasks/sshkey.yml
@@ -0,0 +1,139 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create gitlab user with sshkey credentials
+ gitlab_user:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ email: "{{ gitlab_user_email }}"
+ name: "{{ gitlab_user }}"
+ username: "{{ gitlab_user }}"
+ password: "{{ gitlab_user_pass }}"
+ validate_certs: false
+ sshkey_name: "{{ gitlab_sshkey_name }}"
+ sshkey_file: "{{ gitlab_sshkey_file }}"
+ state: present
+ register: gitlab_user_sshkey
+
+- name: Check user has been created correctly
+ assert:
+ that:
+ - gitlab_user_sshkey is changed
+
+- name: Create gitlab user again
+ gitlab_user:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ email: "{{ gitlab_user_email }}"
+ name: "{{ gitlab_user }}"
+ username: "{{ gitlab_user }}"
+ password: "{{ gitlab_user_pass }}"
+ validate_certs: false
+ sshkey_name: "{{ gitlab_sshkey_name }}"
+ sshkey_file: "{{ gitlab_sshkey_file }}"
+ state: present
+ register: gitlab_user_sshkey_again
+
+- name: Check state is not changed
+ assert:
+ that:
+ - gitlab_user_sshkey_again is not changed
+
+- name: Add expires_at to an already created gitlab user with ssh key
+ gitlab_user:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ email: "{{ gitlab_user_email }}"
+ name: "{{ gitlab_user }}"
+ username: "{{ gitlab_user }}"
+ password: "{{ gitlab_user_pass }}"
+ validate_certs: false
+ sshkey_name: "{{ gitlab_sshkey_name }}"
+ sshkey_file: "{{ gitlab_sshkey_file }}"
+ sshkey_expires_at: "{{ gitlab_sshkey_expires_at }}"
+ state: present
+ register: gitlab_user_created_user_sshkey_expires_at
+
+- name: Check expires_at will not be added to a present ssh key
+ assert:
+ that:
+ - gitlab_user_created_user_sshkey_expires_at is not changed
+
+- name: Remove created gitlab user
+ gitlab_user:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ email: "{{ gitlab_user_email }}"
+ name: "{{ gitlab_user }}"
+ username: "{{ gitlab_user }}"
+ validate_certs: false
+ state: absent
+ register: gitlab_user_sshkey_remove
+
+- name: Check user has been removed correctly
+ assert:
+ that:
+ - gitlab_user_sshkey_remove is changed
+
+- name: Create gitlab user with sshkey and expires_at
+ gitlab_user:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ email: "{{ gitlab_user_email }}"
+ name: "{{ gitlab_user }}"
+ username: "{{ gitlab_user }}"
+ password: "{{ gitlab_user_pass }}"
+ validate_certs: false
+ sshkey_name: "{{ gitlab_sshkey_name }}"
+ sshkey_file: "{{ gitlab_sshkey_file }}"
+ sshkey_expires_at: "{{ gitlab_sshkey_expires_at }}"
+ state: present
+ register: gitlab_user_sshkey_expires_at
+
+- name: Check user has been created correctly
+ assert:
+ that:
+ - gitlab_user_sshkey_expires_at is changed
+
+- name: Create gitlab user with sshkey and expires_at again
+ gitlab_user:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ email: "{{ gitlab_user_email }}"
+ name: "{{ gitlab_user }}"
+ username: "{{ gitlab_user }}"
+ password: "{{ gitlab_user_pass }}"
+ validate_certs: false
+ sshkey_name: "{{ gitlab_sshkey_name }}"
+ sshkey_file: "{{ gitlab_sshkey_file }}"
+ sshkey_expires_at: "{{ gitlab_sshkey_expires_at }}"
+ state: present
+ register: gitlab_user_sshkey_expires_at_again
+
+- name: Check state is not changed
+ assert:
+ that:
+ - gitlab_user_sshkey_expires_at_again is not changed
+
+- name: Remove created gitlab user
+ gitlab_user:
+ api_url: "{{ gitlab_host }}"
+ api_token: "{{ gitlab_login_token }}"
+ email: "{{ gitlab_user_email }}"
+ name: "{{ gitlab_user }}"
+ username: "{{ gitlab_user }}"
+ validate_certs: false
+ state: absent
+ register: gitlab_user_sshkey_expires_at_remove
+
+- name: Check user has been removed correctly
+ assert:
+ that:
+ - gitlab_user_sshkey_expires_at_remove is changed
diff --git a/ansible_collections/community/general/tests/integration/targets/hg/aliases b/ansible_collections/community/general/tests/integration/targets/hg/aliases
new file mode 100644
index 000000000..e1d7ab2a2
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hg/aliases
@@ -0,0 +1,7 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+skip/python3
+skip/aix
diff --git a/ansible_collections/community/general/tests/integration/targets/hg/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/hg/meta/main.yml
new file mode 100644
index 000000000..ca1915e05
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hg/meta/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/hg/tasks/install.yml b/ansible_collections/community/general/tests/integration/targets/hg/tasks/install.yml
new file mode 100644
index 000000000..1b8916880
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hg/tasks/install.yml
@@ -0,0 +1,88 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: get the default python version
+ command: "{{ ansible_python_interpreter }} -V"
+ register: default_python_version
+
+- name: find the default python
+ command: which python
+ register: which_python
+
+- name: find the default pip
+ command: which pip
+ register: which_pip
+
+- name: preserve the default python
+ command: cp -av "{{ which_python.stdout }}" "{{ which_python.stdout }}.default"
+
+- name: preserve the default pip
+ command: cp -av "{{ which_pip.stdout }}" "{{ which_pip.stdout }}.default"
+
+# using the apt module prevents autoremove from working, so call apt-get via shell instead
+- name: install mercurial (apt)
+ shell: apt-get -y update && apt-get -y install mercurial
+ when: ansible_facts.pkg_mgr == 'apt'
+
+- name: install mercurial (dnf)
+ dnf:
+ name: mercurial
+ when: ansible_facts.pkg_mgr == 'dnf'
+
+- name: install mercurial (yum)
+ yum:
+ name: mercurial
+ when: ansible_facts.pkg_mgr == 'yum'
+
+- name: install mercurial (pkgng)
+ package:
+ name: mercurial
+ when: ansible_facts.pkg_mgr in ['pkgng', 'community.general.pkgng']
+
+- name: install mercurial (zypper)
+ package:
+ name: mercurial
+ when: ansible_facts.pkg_mgr in ['zypper', 'community.general.zypper']
+
+- name: preserve the updated python
+ command: cp -av "{{ which_python.stdout }}" "{{ which_python.stdout }}.updated"
+
+- name: preserve the updated pip
+ command: cp -av "{{ which_pip.stdout }}" "{{ which_pip.stdout }}.updated"
+
+- name: locate mercurial
+ command: which hg
+ register: which_hg
+
+- name: get the mercurial interpreter
+ command: head -n 1 "{{ which_hg.stdout }}"
+ register: hg_interpreter
+
+- name: stat the mercurial interpreter
+ stat:
+ path: "{{ hg_interpreter.stdout[2:] }}"
+ register: stat_hg_interpreter
+
+- name: bypass the mercurial python interpreter symlink (if needed)
+ lineinfile:
+ path: "{{ which_hg.stdout }}"
+ regexp: "^#!.*$"
+ line: "#!{{ stat_hg_interpreter.stat.lnk_source }}"
+ when: stat_hg_interpreter.stat.islnk
+
+- name: restore the default python
+ command: cp -av "{{ which_python.stdout }}.default" "{{ which_python.stdout }}"
+
+- name: restore the default pip
+ command: cp -av "{{ which_pip.stdout }}.default" "{{ which_pip.stdout }}"
+
+- name: get the current python version
+ command: "{{ ansible_python_interpreter }} -V"
+ register: current_python_version
+
+- name: verify the python version has not changed
+ assert:
+ that:
+ - default_python_version.stdout == current_python_version.stdout
diff --git a/ansible_collections/community/general/tests/integration/targets/hg/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/hg/tasks/main.yml
new file mode 100644
index 000000000..1ca30459c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hg/tasks/main.yml
@@ -0,0 +1,45 @@
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# test code for the hg module
+# Copyright (c) 2014, James Tanner <tanner.jc@gmail.com>
+#
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: determine if mercurial is already installed
+ command: which hg
+ register: has_hg
+ ignore_errors: true
+
+- name: warn if the underlying system is not capable of running these tests
+ debug:
+ msg: >-
+ The mercurial client is not able to check out Bitbucket repositories as per the changes mentioned here:
+ https://bitbucket.org/blog/deprecating-tlsv1-tlsv1-1-2018-12-01 . Therefore these tests are skipped.
+ when: (ansible_distribution == "Ubuntu" and ansible_distribution_version == "14.04") or ansible_python_version is version("2.7.9", "<")
+
+- block:
+ - name: install mercurial
+ include_tasks: install.yml
+ when: has_hg is failed
+
+ - name: test mercurial
+ include_tasks: run-tests.yml
+
+ - name: uninstall mercurial
+ include_tasks: uninstall.yml
+ when: has_hg is failed
+
+ # As per the bitbucket changes in https://bitbucket.org/blog/deprecating-tlsv1-tlsv1-1-2018-12-01 , this
+ # test will fail under certain circumstances, to avoid false positives, we skip these tests under the following
+ # circumstances:
+ #
+ # - The ubuntu 14.04 image used on shippable runs python 2.7.6, so we skip explicitly for this image.
+ # - When ansible_python_version is not 2.7.9 or higher, mercurial is likely to also run using this same (old)
+ # python version, which causes issues as per the link above.
+ when:
+ - not (ansible_distribution == "Ubuntu" and ansible_distribution_version == "14.04")
+ - ansible_python_version is version("2.7.9", ">=")
diff --git a/ansible_collections/community/general/tests/integration/targets/hg/tasks/run-tests.yml b/ansible_collections/community/general/tests/integration/targets/hg/tasks/run-tests.yml
new file mode 100644
index 000000000..928b7cb68
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hg/tasks/run-tests.yml
@@ -0,0 +1,85 @@
+# test code for the hg module
+# Copyright (c) 2018, Ansible Project
+#
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+
+- name: set where to extract the repo
+ set_fact:
+ checkout_dir: "{{ remote_tmp_dir }}/hg_project_test"
+
+- name: set what repo to use
+ set_fact:
+ repo: "http://hg.pf.osdn.net/view/a/ak/akasurde/hg_project_test"
+
+- name: clean out the remote_tmp_dir
+ shell: rm -rf {{ remote_tmp_dir }}/*
+
+- name: verify that mercurial is installed so this test can continue
+ shell: which hg
+
+- name: initial checkout
+ hg:
+ repo: "{{ repo }}"
+ dest: "{{ checkout_dir }}"
+ register: hg_result
+
+- debug: var=hg_result
+
+- shell: ls {{ checkout_dir }}
+
+- name: verify information about the initial clone
+ assert:
+ that:
+ - "'before' in hg_result"
+ - "'after' in hg_result"
+ - "not hg_result.before"
+ - "hg_result.changed"
+
+- name: repeated checkout
+ hg:
+ repo: "{{ repo }}"
+ dest: "{{ checkout_dir }}"
+ register: hg_result2
+
+- debug: var=hg_result2
+
+- name: check for tags
+ stat:
+ path: "{{ checkout_dir }}/.hgtags"
+ register: tags
+
+- name: check for remotes
+ stat:
+ path: "{{ checkout_dir }}/.hg/branch"
+ register: branches
+
+- debug: var=tags
+- debug: var=branches
+
+- name: assert presence of tags/trunk/branches
+ assert:
+ that:
+ - "tags.stat.isreg"
+ - "branches.stat.isreg"
+
+- name: verify on a re-clone things are marked unchanged
+ assert:
+ that:
+ - "not hg_result2.changed"
+
+- name: Checkout non-existent repo clone
+ hg:
+ repo: "http://hg.pf.osdn.net/view/a/ak/akasurde/hg_project_test_1"
+ clone: false
+ update: false
+ register: hg_result3
+ ignore_errors: true
+
+- name: Verify result of non-existent repo clone
+ assert:
+ that:
+ - hg_result3.msg
+ - "'abort: HTTP Error 404: Not Found' in hg_result3.msg"
+ - "not hg_result3.changed"
diff --git a/ansible_collections/community/general/tests/integration/targets/hg/tasks/uninstall.yml b/ansible_collections/community/general/tests/integration/targets/hg/tasks/uninstall.yml
new file mode 100644
index 000000000..4a26995ef
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hg/tasks/uninstall.yml
@@ -0,0 +1,53 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: restore the updated python
+ command: mv "{{ which_python.stdout }}.updated" "{{ which_python.stdout }}"
+
+- name: restore the updated pip
+ command: mv "{{ which_pip.stdout }}.updated" "{{ which_pip.stdout }}"
+
+- name: restore the mercurial python interpreter symlink (if needed)
+ lineinfile:
+ path: "{{ which_hg.stdout }}"
+ regexp: "^#!.*$"
+ line: "#!{{ stat_hg_interpreter.stat.path }}"
+ when: stat_hg_interpreter.stat.islnk
+
+# using the apt module prevents autoremove from working, so call apt-get via shell instead
+- name: uninstall packages which were not originally installed (apt)
+ shell: apt-get -y remove mercurial && apt-get -y autoremove
+ when: ansible_facts.pkg_mgr == 'apt'
+
+- name: uninstall packages which were not originally installed (dnf)
+ dnf:
+ name: mercurial
+ state: absent
+ autoremove: true
+ when: ansible_facts.pkg_mgr == 'dnf'
+
+# the yum module does not have an autoremove parameter
+- name: uninstall packages which were not originally installed (yum)
+ shell: yum -y autoremove mercurial
+ when: ansible_facts.pkg_mgr == 'yum'
+
+- name: uninstall packages which were not originally installed (pkgng)
+ package:
+ name: mercurial
+ state: absent
+ autoremove: true
+ when: ansible_facts.pkg_mgr in ['pkgng', 'community.general.pkgng']
+
+- name: uninstall packages which were not originally installed (zypper)
+ package:
+ name: mercurial
+ state: absent
+ when: ansible_facts.pkg_mgr in ['zypper', 'community.general.zypper']
+
+- name: restore the default python
+ raw: mv "{{ which_python.stdout }}.default" "{{ which_python.stdout }}"
+
+- name: restore the default pip
+ raw: mv "{{ which_pip.stdout }}.default" "{{ which_pip.stdout }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/homebrew/aliases b/ansible_collections/community/general/tests/integration/targets/homebrew/aliases
new file mode 100644
index 000000000..11bb9a086
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/homebrew/aliases
@@ -0,0 +1,10 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+skip/aix
+skip/freebsd
+skip/rhel
+skip/docker
+skip/python2.6
diff --git a/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/main.yml
new file mode 100644
index 000000000..1db3ef1a6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/homebrew/tasks/main.yml
@@ -0,0 +1,99 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Test code for the homebrew module.
+# Copyright (c) 2020, Abhijeet Kasurde <akasurde@redhat.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Find brew binary
+ command: which brew
+ register: brew_which
+ when: ansible_distribution in ['MacOSX']
+
+- name: Get owner of brew binary
+ stat:
+ path: "{{ brew_which.stdout }}"
+ register: brew_stat
+ when: ansible_distribution in ['MacOSX']
+
+#- name: Use ignored-pinned option while upgrading all
+# homebrew:
+# upgrade_all: true
+# upgrade_options: ignore-pinned
+# become: true
+# become_user: "{{ brew_stat.stat.pw_name }}"
+# register: upgrade_option_result
+# environment:
+# HOMEBREW_NO_AUTO_UPDATE: True
+
+#- assert:
+# that:
+# - upgrade_option_result.changed
+
+- vars:
+ package_name: gnu-tar
+
+ block:
+ - name: Make sure {{ package_name }} package is not installed
+ homebrew:
+ name: "{{ package_name }}"
+ state: absent
+ update_homebrew: false
+ become: true
+ become_user: "{{ brew_stat.stat.pw_name }}"
+
+ - name: Install {{ package_name }} package using homebrew
+ homebrew:
+ name: "{{ package_name }}"
+ state: present
+ update_homebrew: false
+ become: true
+ become_user: "{{ brew_stat.stat.pw_name }}"
+ register: package_result
+
+ - assert:
+ that:
+ - package_result.changed
+
+ - name: Again install {{ package_name }} package using homebrew
+ homebrew:
+ name: "{{ package_name }}"
+ state: present
+ update_homebrew: false
+ become: true
+ become_user: "{{ brew_stat.stat.pw_name }}"
+ register: package_result
+
+ - assert:
+ that:
+ - not package_result.changed
+
+ - name: Uninstall {{ package_name }} package using homebrew
+ homebrew:
+ name: "{{ package_name }}"
+ state: absent
+ update_homebrew: false
+ become: true
+ become_user: "{{ brew_stat.stat.pw_name }}"
+ register: package_result
+
+ - assert:
+ that:
+ - package_result.changed
+
+ - name: Again uninstall {{ package_name }} package using homebrew
+ homebrew:
+ name: "{{ package_name }}"
+ state: absent
+ update_homebrew: false
+ become: true
+ become_user: "{{ brew_stat.stat.pw_name }}"
+ register: package_result
+
+ - assert:
+ that:
+ - not package_result.changed
diff --git a/ansible_collections/community/general/tests/integration/targets/homebrew_cask/aliases b/ansible_collections/community/general/tests/integration/targets/homebrew_cask/aliases
new file mode 100644
index 000000000..11bb9a086
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/homebrew_cask/aliases
@@ -0,0 +1,10 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+skip/aix
+skip/freebsd
+skip/rhel
+skip/docker
+skip/python2.6
diff --git a/ansible_collections/community/general/tests/integration/targets/homebrew_cask/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/homebrew_cask/defaults/main.yml
new file mode 100644
index 000000000..18ebd7b10
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/homebrew_cask/defaults/main.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cask: brooklyn
diff --git a/ansible_collections/community/general/tests/integration/targets/homebrew_cask/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/homebrew_cask/tasks/main.yml
new file mode 100644
index 000000000..85f257266
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/homebrew_cask/tasks/main.yml
@@ -0,0 +1,73 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Test code for the homebrew_cask module.
+# Copyright (c) 2022, Joseph Torcasso <jtorcass@redhat.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Find brew binary
+ command: which brew
+ register: brew_which
+ when: ansible_distribution in ['MacOSX']
+
+ - name: Get owner of brew binary
+ stat:
+ path: "{{ brew_which.stdout }}"
+ register: brew_stat
+ when: ansible_distribution in ['MacOSX']
+
+ - block:
+ - name: Install cask
+ homebrew_cask:
+ name: "{{ cask }}"
+ state: present
+ become: true
+ become_user: "{{ brew_stat.stat.pw_name }}"
+ register: cask_install_result
+
+ - assert:
+ that:
+ - cask_install_result is changed
+ - "'Cask installed' in cask_install_result.msg"
+
+ - name: Install cask (idempotence)
+ homebrew_cask:
+ name: "{{ cask }}"
+ state: present
+ become: true
+ become_user: "{{ brew_stat.stat.pw_name }}"
+ register: cask_install_result
+
+ - assert:
+ that:
+ - cask_install_result is not changed
+ - "'Cask installed' not in cask_install_result.msg"
+ - "'Cask already installed' in cask_install_result.msg"
+
+ - name: Install cask with force install option
+ homebrew_cask:
+ name: "{{ cask }}"
+ state: present
+ install_options: force
+ become: true
+ become_user: "{{ brew_stat.stat.pw_name }}"
+ register: cask_install_result
+
+ - assert:
+ that:
+ - cask_install_result is changed
+ - "'Cask installed' in cask_install_result.msg"
+
+ always:
+ - name: Delete cask
+ homebrew_cask:
+ name: "{{ cask }}"
+ state: absent
+ install_options: force
+ become: true
+ become_user: "{{ brew_stat.stat.pw_name }}"
+ ignore_errors: true
diff --git a/ansible_collections/community/general/tests/integration/targets/homectl/aliases b/ansible_collections/community/general/tests/integration/targets/homectl/aliases
new file mode 100644
index 000000000..b87db2e43
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/homectl/aliases
@@ -0,0 +1,11 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+skip/aix
+skip/freebsd
+skip/osx
+skip/macos
+skip/rhel9.0 # See https://www.reddit.com/r/Fedora/comments/si7nzk/homectl/
+skip/rhel9.1 # See https://www.reddit.com/r/Fedora/comments/si7nzk/homectl/
diff --git a/ansible_collections/community/general/tests/integration/targets/homectl/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/homectl/tasks/main.yml
new file mode 100644
index 000000000..93c1089b4
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/homectl/tasks/main.yml
@@ -0,0 +1,182 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Get systemd version and if it doesn't exist don't run these tests.
+- name: check systemd version
+ command: "systemctl --version"
+ register: systemd_version
+ ignore_errors: true
+
+- name: check homectl version
+ command: homectl --version
+ register: homectl_version
+ ignore_errors: true
+
+- block:
+ - name: Check and start systemd-homed service
+ service:
+ name: systemd-homed.service
+ state: started
+ enabled: true
+
+ - name: Add a user 'james'
+ community.general.homectl:
+ name: james
+ password: myreallysecurepassword1!
+ state: present
+
+ - name: verify user added
+ command: homectl inspect james
+ register: james_info
+
+ - name: Add the user 'tom' with a zsh shell, uid of 1000, and gid of 1000
+ community.general.homectl:
+ name: tom
+ password: myreallysecurepassword1!
+ state: present
+ shell: /bin/zsh
+ uid: 1000
+ gid: 1000
+ disksize: 10G
+ register: tom_userinfo
+
+ - name: Try to add user 'james' that already exists
+ community.general.homectl:
+ name: james
+ password: myreallysecurepassword1!
+ state: present
+ shell: /bin/ksh
+ register: user_exists
+
+ - name: Try to use 'resize=yes' option without 'disksize' option (not allowed)
+ community.general.homectl:
+ name: foo
+ password: uq4895738!@#$%dfd
+ state: present
+ resize: true
+ register: resize_out
+ ignore_errors: true
+
+ - name: Use option 'disksize=1G' without option resize (allowed)
+ community.general.homectl:
+ name: foobar
+ password: "uq4895738!@#$%dfd"
+ state: present
+ disksize: 1G
+ register: disk_out
+ ignore_errors: true
+
+ - name: Try to Create user without giving password
+ community.general.homectl:
+ name: danielle
+ register: danielle_out
+ ignore_errors: true
+
+ - name: remove user 'foobar' without requiring password
+ community.general.homectl:
+ name: foobar
+ state: absent
+ register: delete_foobar_out
+
+ - name: modify user 'james' to have zsh shell and timezone 'America/New_York'
+ community.general.homectl:
+ name: james
+ password: myreallysecurepassword1!
+ state: present
+ shell: /bin/zsh
+ timezone: America/New_York
+ register: lukuser_modify_out
+
+ - name: create user 'jake' with all mount options
+ community.general.homectl:
+ name: jake
+ password: myreallysecurepassword12!
+ mountopts: noexec,nosuid,nodev
+ sshkeys: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDUSW/q2qFZPr2vS0qrmAs+1iQI1jLIBdJ4CVIhE3KnIwxkkiInS8mJ+t0FBTeK3ks3GZLPVYC1v9o2P+oqyUk1CiBnCsMXGJud+L/t8b5r8MiJMyP7Jzd6yhmcvenjvz+vY06jQ9chWAtThEknuaOMongIpQQzSLGbdMy0yMsz4GEjicwdcj1PDwItPvUt4TL4K7V9NE672idADlRt6qng4UwpziqlYgsyIG46ettDras8hGAPricrhFWUS2rLDsCD0thkPFdR8HL1ZWTZ6LtolhO4MYtgntzXn708TTmFC2oIDluzyxVoUYmsfVotVdXFZcOWffnwbCgU+tn75JXTLozgTbV3VWmkxpJFErCWPerxcZv3+7b0f36/Y0gRNjM9HERLDSE1c8yz29NOLY0qH5306aByjOaerxNq9+ZOU/Fmf5/VfGIUp/FdLxDw+V0AzejFG580VAcstEMsOHSdwTbi3gf6LoGSiRyWKKDod0TZCMC6RzfdsfdsfI9CClGl0s= test@router.home"
+ register: jake_out
+
+ - name: Try to remove user 'janet' that doesn't exist
+ community.general.homectl:
+ name: janet
+ state: absent
+ register: user_not_exist
+ ignore_errors: true
+
+ - name: Use check_mode to try and create user 'diana'
+ community.general.homectl:
+ name: diana
+ password: helloworld123!@
+ state: present
+ check_mode: true
+ register: diana_create_checkmode_out
+
+ - name: Verify user 'diana' was not created with check_mode
+ command: homectl inspect diana
+ register: user_diana_exists
+ ignore_errors: true
+
+ - name: Try to modify user 'jake' with only noexec mount option in check_mode
+ community.general.homectl:
+ name: jake
+ password: myreallysecurepassword12!
+ state: present
+ mountopts: noexec
+ check_mode: true
+ register: jake_checkmode_out
+
+ - name: Verify user 'jake' was not modified and still has all mount options
+ command: homectl inspect jake
+ register: user_jake_details_out
+
+ - name: Modify user 'jake' with only noexec mount option
+ community.general.homectl:
+ name: jake
+ password: myreallysecurepassword12!
+ state: present
+ mountopts: noexec
+ register: jake_modify_out
+
+ - name: modify user 'jake' again with only noexec mount option to make sure changed is false as nothing has changed.
+ community.general.homectl:
+ name: jake
+ password: myreallysecurepassword12!
+ state: present
+ mountopts: noexec
+ register: jake_modify_again_out
+
+ - name: Try to modify user 'jake' with an incorrect password
+ community.general.homectl:
+ name: jake
+ password: incorrectPassword!
+ state: present
+ mountopts: noexec
+ locked: true
+ ignore_errors: true
+ register: jake_incorrect_pass_out
+
+ - assert:
+ that:
+ - james_info.rc == 0
+ - tom_userinfo.data['gid'] == 1000 and tom_userinfo.data['uid'] == 1000
+ - user_exists is changed and user_exists.data['shell'] == '/bin/ksh'
+ - resize_out is not changed
+ - disk_out is changed
+ - delete_foobar_out is changed
+ - danielle_out is not changed
+ - lukuser_modify_out.data['timeZone'] == "America/New_York" and lukuser_modify_out.data['shell'] == "/bin/zsh"
+ - user_not_exist is not changed and user_not_exist.msg == "User does not exist!"
+ - jake_out is changed and jake_out.data['mountNoDevices'] == True and jake_out.data['mountNoSuid'] == True and jake_out.data['mountNoExecute'] == True
+ - diana_create_checkmode_out is changed and 'No home for user diana known' in user_diana_exists.stderr
+ - "jake_checkmode_out is changed and 'Mount Flags: nosuid nodev noexec' in user_jake_details_out.stdout"
+ - jake_modify_out is changed and jake_modify_out.data['privileged']['sshAuthorizedKeys'] is not none
+ - jake_modify_out.data['mountNoDevices'] == False and jake_modify_out.data['mountNoExecute'] == True and jake_modify_out.data['mountNoSuid'] == False
+ - jake_modify_again_out is not changed
+ - jake_incorrect_pass_out is not changed and jake_incorrect_pass_out is failed and jake_incorrect_pass_out.msg == 'User exists but password is incorrect!'
+
+ # homectl was first introduced in systemd 245 so check version >= 245 and make sure system has systemd and homectl command
+ when:
+ - systemd_version.rc == 0 and (systemd_version.stdout | regex_search('[0-9][0-9][0-9]') | int >= 245) and homectl_version.rc == 0
+ - ansible_distribution != 'Archlinux' # TODO!
+ - ansible_distribution != 'Fedora' or ansible_distribution_major_version|int < 36 # TODO!
diff --git a/ansible_collections/community/general/tests/integration/targets/hwc_ecs_instance/aliases b/ansible_collections/community/general/tests/integration/targets/hwc_ecs_instance/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hwc_ecs_instance/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/hwc_ecs_instance/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/hwc_ecs_instance/tasks/main.yml
new file mode 100644
index 000000000..dd7086152
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hwc_ecs_instance/tasks/main.yml
@@ -0,0 +1,319 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Pre-test setup
+- name: create a vpc
+ hwc_network_vpc:
+ cidr: "192.168.100.0/24"
+ name: "ansible_network_vpc_test"
+ state: present
+ register: vpc
+- name: create a subnet
+ hwc_vpc_subnet:
+ gateway_ip: "192.168.100.32"
+ name: "ansible_network_subnet_test"
+ dhcp_enable: true
+ vpc_id: "{{ vpc.id }}"
+ cidr: "192.168.100.0/26"
+ state: present
+ register: subnet
+- name: create a eip
+ hwc_vpc_eip:
+ dedicated_bandwidth:
+ charge_mode: "traffic"
+ name: "ansible_test_dedicated_bandwidth"
+ size: 1
+ type: "5_bgp"
+ state: present
+ register: eip
+- name: create a disk
+ hwc_evs_disk:
+ availability_zone: "cn-north-1a"
+ name: "ansible_evs_disk_test"
+ volume_type: "SATA"
+ size: 10
+ state: present
+ register: disk
+- name: delete a instance
+ hwc_ecs_instance:
+ data_volumes:
+ - volume_id: "{{ disk.id }}"
+ enable_auto_recovery: false
+ eip_id: "{{ eip.id }}"
+ name: "ansible_ecs_instance_test"
+ availability_zone: "cn-north-1a"
+ nics:
+ - subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ - subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.34"
+ server_tags:
+ my_server: "my_server"
+ image_id: "8da46d6d-6079-4e31-ad6d-a7167efff892"
+ flavor_name: "s3.small.1"
+ vpc_id: "{{ vpc.id }}"
+ root_volume:
+ volume_type: "SAS"
+ state: absent
+#----------------------------------------------------------
+- name: create a instance (check mode)
+ hwc_ecs_instance:
+ data_volumes:
+ - volume_id: "{{ disk.id }}"
+ enable_auto_recovery: false
+ eip_id: "{{ eip.id }}"
+ name: "ansible_ecs_instance_test"
+ availability_zone: "cn-north-1a"
+ nics:
+ - subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ - subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.34"
+ server_tags:
+ my_server: "my_server"
+ image_id: "8da46d6d-6079-4e31-ad6d-a7167efff892"
+ flavor_name: "s3.small.1"
+ vpc_id: "{{ vpc.id }}"
+ root_volume:
+ volume_type: "SAS"
+ state: present
+ check_mode: true
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - result is changed
+#----------------------------------------------------------
+- name: create a instance
+ hwc_ecs_instance:
+ data_volumes:
+ - volume_id: "{{ disk.id }}"
+ enable_auto_recovery: false
+ eip_id: "{{ eip.id }}"
+ name: "ansible_ecs_instance_test"
+ availability_zone: "cn-north-1a"
+ nics:
+ - subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ - subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.34"
+ server_tags:
+ my_server: "my_server"
+ image_id: "8da46d6d-6079-4e31-ad6d-a7167efff892"
+ flavor_name: "s3.small.1"
+ vpc_id: "{{ vpc.id }}"
+ root_volume:
+ volume_type: "SAS"
+ state: present
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ result is changed
+#----------------------------------------------------------
+- name: create a instance (idemponent)
+ hwc_ecs_instance:
+ data_volumes:
+ - volume_id: "{{ disk.id }}"
+ enable_auto_recovery: false
+ eip_id: "{{ eip.id }}"
+ name: "ansible_ecs_instance_test"
+ availability_zone: "cn-north-1a"
+ nics:
+ - subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ - subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.34"
+ server_tags:
+ my_server: "my_server"
+ image_id: "8da46d6d-6079-4e31-ad6d-a7167efff892"
+ flavor_name: "s3.small.1"
+ vpc_id: "{{ vpc.id }}"
+ root_volume:
+ volume_type: "SAS"
+ state: present
+ check_mode: true
+ register: result
+- name: idemponent
+ assert:
+ that:
+ - not result.changed
+# ----------------------------------------------------------------------------
+- name: create a instance that already exists
+ hwc_ecs_instance:
+ data_volumes:
+ - volume_id: "{{ disk.id }}"
+ enable_auto_recovery: false
+ eip_id: "{{ eip.id }}"
+ name: "ansible_ecs_instance_test"
+ availability_zone: "cn-north-1a"
+ nics:
+ - subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ - subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.34"
+ server_tags:
+ my_server: "my_server"
+ image_id: "8da46d6d-6079-4e31-ad6d-a7167efff892"
+ flavor_name: "s3.small.1"
+ vpc_id: "{{ vpc.id }}"
+ root_volume:
+ volume_type: "SAS"
+ state: present
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - result is not failed
+ - result is not changed
+#----------------------------------------------------------
+- name: delete a instance (check mode)
+ hwc_ecs_instance:
+ data_volumes:
+ - volume_id: "{{ disk.id }}"
+ enable_auto_recovery: false
+ eip_id: "{{ eip.id }}"
+ name: "ansible_ecs_instance_test"
+ availability_zone: "cn-north-1a"
+ nics:
+ - subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ - subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.34"
+ server_tags:
+ my_server: "my_server"
+ image_id: "8da46d6d-6079-4e31-ad6d-a7167efff892"
+ flavor_name: "s3.small.1"
+ vpc_id: "{{ vpc.id }}"
+ root_volume:
+ volume_type: "SAS"
+ state: absent
+ check_mode: true
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - result is changed
+#----------------------------------------------------------
+- name: delete a instance
+ hwc_ecs_instance:
+ data_volumes:
+ - volume_id: "{{ disk.id }}"
+ enable_auto_recovery: false
+ eip_id: "{{ eip.id }}"
+ name: "ansible_ecs_instance_test"
+ availability_zone: "cn-north-1a"
+ nics:
+ - subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ - subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.34"
+ server_tags:
+ my_server: "my_server"
+ image_id: "8da46d6d-6079-4e31-ad6d-a7167efff892"
+ flavor_name: "s3.small.1"
+ vpc_id: "{{ vpc.id }}"
+ root_volume:
+ volume_type: "SAS"
+ state: absent
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ result is changed
+#----------------------------------------------------------
+- name: delete a instance (idemponent)
+ hwc_ecs_instance:
+ data_volumes:
+ - volume_id: "{{ disk.id }}"
+ enable_auto_recovery: false
+ eip_id: "{{ eip.id }}"
+ name: "ansible_ecs_instance_test"
+ availability_zone: "cn-north-1a"
+ nics:
+ - subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ - subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.34"
+ server_tags:
+ my_server: "my_server"
+ image_id: "8da46d6d-6079-4e31-ad6d-a7167efff892"
+ flavor_name: "s3.small.1"
+ vpc_id: "{{ vpc.id }}"
+ root_volume:
+ volume_type: "SAS"
+ state: absent
+ register: result
+- name: idemponent
+ assert:
+ that:
+ - not result.changed
+# ----------------------------------------------------------------------------
+- name: delete a instance that does not exist
+ hwc_ecs_instance:
+ data_volumes:
+ - volume_id: "{{ disk.id }}"
+ enable_auto_recovery: false
+ eip_id: "{{ eip.id }}"
+ name: "ansible_ecs_instance_test"
+ availability_zone: "cn-north-1a"
+ nics:
+ - subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ - subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.34"
+ server_tags:
+ my_server: "my_server"
+ image_id: "8da46d6d-6079-4e31-ad6d-a7167efff892"
+ flavor_name: "s3.small.1"
+ vpc_id: "{{ vpc.id }}"
+ root_volume:
+ volume_type: "SAS"
+ state: absent
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - result is not failed
+ - result is not changed
+#---------------------------------------------------------
+# Post-test teardown
+- name: delete a disk
+ hwc_evs_disk:
+ availability_zone: "cn-north-1a"
+ name: "ansible_evs_disk_test"
+ volume_type: "SATA"
+ size: 10
+ state: absent
+ register: disk
+- name: delete a eip
+ hwc_vpc_eip:
+ dedicated_bandwidth:
+ charge_mode: "traffic"
+ name: "ansible_test_dedicated_bandwidth"
+ size: 1
+ type: "5_bgp"
+ state: absent
+ register: eip
+- name: delete a subnet
+ hwc_vpc_subnet:
+ gateway_ip: "192.168.100.32"
+ name: "ansible_network_subnet_test"
+ dhcp_enable: true
+ vpc_id: "{{ vpc.id }}"
+ cidr: "192.168.100.0/26"
+ state: absent
+ register: subnet
+- name: delete a vpc
+ hwc_network_vpc:
+ cidr: "192.168.100.0/24"
+ name: "ansible_network_vpc_test"
+ state: absent
+ register: vpc
diff --git a/ansible_collections/community/general/tests/integration/targets/hwc_evs_disk/aliases b/ansible_collections/community/general/tests/integration/targets/hwc_evs_disk/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hwc_evs_disk/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/hwc_evs_disk/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/hwc_evs_disk/tasks/main.yml
new file mode 100644
index 000000000..63b7d03f9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hwc_evs_disk/tasks/main.yml
@@ -0,0 +1,113 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: delete a disk
+ hwc_evs_disk:
+ availability_zone: "cn-north-1a"
+ name: "ansible_evs_disk_test"
+ volume_type: "SATA"
+ size: 10
+ state: absent
+#----------------------------------------------------------
+- name: create a disk
+ hwc_evs_disk:
+ availability_zone: "cn-north-1a"
+ name: "ansible_evs_disk_test"
+ volume_type: "SATA"
+ size: 10
+ state: present
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ result is changed
+# ------------------------------------------------------------
+- name: test create a disk in check mode
+ hwc_evs_disk:
+ availability_zone: "cn-north-1a"
+ name: "ansible_evs_disk_test"
+ volume_type: "SATA"
+ size: 10
+ state: present
+ register: result
+ check_mode: true
+- name: verify results of test create a disk in check mode
+ assert:
+ that:
+ result is changed
+# ----------------------------------------------------------------------------
+- name: create a disk that already exists
+ hwc_evs_disk:
+ availability_zone: "cn-north-1a"
+ name: "ansible_evs_disk_test"
+ volume_type: "SATA"
+ size: 10
+ state: present
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - result is not failed
+ - result is not changed
+#----------------------------------------------------------
+- name: delete a disk (check mode)
+ hwc_evs_disk:
+ availability_zone: "cn-north-1a"
+ name: "ansible_evs_disk_test"
+ volume_type: "SATA"
+ size: 10
+ state: absent
+ check_mode: true
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ result is changed
+#----------------------------------------------------------
+- name: delete a disk
+ hwc_evs_disk:
+ availability_zone: "cn-north-1a"
+ name: "ansible_evs_disk_test"
+ volume_type: "SATA"
+ size: 10
+ state: absent
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ result is changed
+# ----------------------------------------------------------------------------
+- name: delete a disk that does not exist (check mode)
+ hwc_evs_disk:
+ availability_zone: "cn-north-1a"
+ name: "ansible_evs_disk_test"
+ volume_type: "SATA"
+ size: 10
+ state: absent
+ check_mode: true
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - result is not changed
+# ----------------------------------------------------------------------------
+- name: delete a disk that does not exist
+ hwc_evs_disk:
+ availability_zone: "cn-north-1a"
+ name: "ansible_evs_disk_test"
+ volume_type: "SATA"
+ size: 10
+ state: absent
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - result is not failed
+ - result is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/hwc_network_vpc/aliases b/ansible_collections/community/general/tests/integration/targets/hwc_network_vpc/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hwc_network_vpc/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/hwc_network_vpc/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/hwc_network_vpc/tasks/main.yml
new file mode 100644
index 000000000..3695fd210
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hwc_network_vpc/tasks/main.yml
@@ -0,0 +1,105 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# ----------------------------------------------------------------------------
+#
+# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
+#
+# ----------------------------------------------------------------------------
+#
+# This file is automatically generated by Magic Modules and manual
+# changes will be clobbered when the file is regenerated.
+#
+# Please read more about how to change this file at
+# https://www.github.com/huaweicloud/magic-modules
+#
+# ----------------------------------------------------------------------------
+# Pre-test setup
+- name: delete a vpc
+ hwc_network_vpc:
+ identity_endpoint: "{{ identity_endpoint }}"
+ user: "{{ user }}"
+ password: "{{ password }}"
+ domain: "{{ domain }}"
+ project: "{{ project }}"
+ region: "{{ region }}"
+ name: "vpc_1"
+ cidr: "192.168.100.0/24"
+ state: absent
+#----------------------------------------------------------
+- name: create a vpc
+ hwc_network_vpc:
+ identity_endpoint: "{{ identity_endpoint }}"
+ user: "{{ user }}"
+ password: "{{ password }}"
+ domain: "{{ domain }}"
+ project: "{{ project }}"
+ region: "{{ region }}"
+ name: "vpc_1"
+ cidr: "192.168.100.0/24"
+ state: present
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - result is changed
+# ----------------------------------------------------------------------------
+- name: create a vpc that already exists
+ hwc_network_vpc:
+ identity_endpoint: "{{ identity_endpoint }}"
+ user: "{{ user }}"
+ password: "{{ password }}"
+ domain: "{{ domain }}"
+ project: "{{ project }}"
+ region: "{{ region }}"
+ name: "vpc_1"
+ cidr: "192.168.100.0/24"
+ state: present
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - result is not failed
+ - result is not changed
+#----------------------------------------------------------
+- name: delete a vpc
+ hwc_network_vpc:
+ identity_endpoint: "{{ identity_endpoint }}"
+ user: "{{ user }}"
+ password: "{{ password }}"
+ domain: "{{ domain }}"
+ project: "{{ project }}"
+ region: "{{ region }}"
+ name: "vpc_1"
+ cidr: "192.168.100.0/24"
+ state: absent
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - result is changed
+# ----------------------------------------------------------------------------
+- name: delete a vpc that does not exist
+ hwc_network_vpc:
+ identity_endpoint: "{{ identity_endpoint }}"
+ user: "{{ user }}"
+ password: "{{ password }}"
+ domain: "{{ domain }}"
+ project: "{{ project }}"
+ region: "{{ region }}"
+ name: "vpc_1"
+ cidr: "192.168.100.0/24"
+ state: absent
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - result is not failed
+ - result is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/hwc_smn_topic/aliases b/ansible_collections/community/general/tests/integration/targets/hwc_smn_topic/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hwc_smn_topic/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/hwc_smn_topic/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/hwc_smn_topic/tasks/main.yml
new file mode 100644
index 000000000..323904773
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hwc_smn_topic/tasks/main.yml
@@ -0,0 +1,86 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: delete a smn topic
+ hwc_smn_topic:
+ identity_endpoint: "{{ identity_endpoint }}"
+ user: "{{ user }}"
+ password: "{{ password }}"
+ domain: "{{ domain }}"
+ project: "{{ project }}"
+ region: "{{ region }}"
+ name: "ansible_smn_topic_test"
+ state: absent
+#----------------------------------------------------------
+- name: create a smn topic
+ hwc_smn_topic:
+ identity_endpoint: "{{ identity_endpoint }}"
+ user: "{{ user }}"
+ password: "{{ password }}"
+ domain: "{{ domain }}"
+ project: "{{ project }}"
+ region: "{{ region }}"
+ name: "ansible_smn_topic_test"
+ state: present
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - result is changed
+# ----------------------------------------------------------------------------
+- name: create a smn topic that already exists
+ hwc_smn_topic:
+ identity_endpoint: "{{ identity_endpoint }}"
+ user: "{{ user }}"
+ password: "{{ password }}"
+ domain: "{{ domain }}"
+ project: "{{ project }}"
+ region: "{{ region }}"
+ name: "ansible_smn_topic_test"
+ state: present
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - result is not failed
+ - result is not changed
+#----------------------------------------------------------
+- name: delete a smn topic
+ hwc_smn_topic:
+ identity_endpoint: "{{ identity_endpoint }}"
+ user: "{{ user }}"
+ password: "{{ password }}"
+ domain: "{{ domain }}"
+ project: "{{ project }}"
+ region: "{{ region }}"
+ name: "ansible_smn_topic_test"
+ state: absent
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - result is changed
+# ----------------------------------------------------------------------------
+- name: delete a smn topic that does not exist
+ hwc_smn_topic:
+ identity_endpoint: "{{ identity_endpoint }}"
+ user: "{{ user }}"
+ password: "{{ password }}"
+ domain: "{{ domain }}"
+ project: "{{ project }}"
+ region: "{{ region }}"
+ name: "ansible_smn_topic_test"
+ state: absent
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - result is not failed
+ - result is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/hwc_vpc_eip/aliases b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_eip/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_eip/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/hwc_vpc_eip/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_eip/tasks/main.yml
new file mode 100644
index 000000000..f830f951f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_eip/tasks/main.yml
@@ -0,0 +1,190 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Pre-test setup
+- name: create a vpc
+ hwc_network_vpc:
+ cidr: "192.168.100.0/24"
+ name: "ansible_network_vpc_test"
+ state: present
+ register: vpc
+- name: create a subnet
+ hwc_vpc_subnet:
+ gateway_ip: "192.168.100.32"
+ name: "ansible_network_subnet_test"
+ dhcp_enable: true
+ vpc_id: "{{ vpc.id }}"
+ cidr: "192.168.100.0/26"
+ state: present
+ register: subnet
+- name: create a port
+ hwc_vpc_port:
+ subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ state: present
+ register: port
+- name: delete a eip
+ hwc_vpc_eip:
+ type: "5_bgp"
+ dedicated_bandwidth:
+ charge_mode: "traffic"
+ name: "ansible_test_dedicated_bandwidth"
+ size: 1
+ port_id: "{{ port.id }}"
+ state: absent
+#----------------------------------------------------------
+- name: create a eip (check mode)
+ hwc_vpc_eip:
+ type: "5_bgp"
+ dedicated_bandwidth:
+ charge_mode: "traffic"
+ name: "ansible_test_dedicated_bandwidth"
+ size: 1
+ port_id: "{{ port.id }}"
+ state: present
+ check_mode: true
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - result is changed
+#----------------------------------------------------------
+- name: create a eip
+ hwc_vpc_eip:
+ type: "5_bgp"
+ dedicated_bandwidth:
+ charge_mode: "traffic"
+ name: "ansible_test_dedicated_bandwidth"
+ size: 1
+ port_id: "{{ port.id }}"
+ state: present
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ result is changed
+#----------------------------------------------------------
+- name: create a eip (idemponent)
+ hwc_vpc_eip:
+ type: "5_bgp"
+ dedicated_bandwidth:
+ charge_mode: "traffic"
+ name: "ansible_test_dedicated_bandwidth"
+ size: 1
+ port_id: "{{ port.id }}"
+ state: present
+ check_mode: true
+ register: result
+- name: idemponent
+ assert:
+ that:
+ - not result.changed
+# ----------------------------------------------------------------------------
+- name: create a eip that already exists
+ hwc_vpc_eip:
+ type: "5_bgp"
+ dedicated_bandwidth:
+ charge_mode: "traffic"
+ name: "ansible_test_dedicated_bandwidth"
+ size: 1
+ port_id: "{{ port.id }}"
+ state: present
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - result is not failed
+ - result is not changed
+#----------------------------------------------------------
+- name: delete a eip (check mode)
+ hwc_vpc_eip:
+ type: "5_bgp"
+ dedicated_bandwidth:
+ charge_mode: "traffic"
+ name: "ansible_test_dedicated_bandwidth"
+ size: 1
+ port_id: "{{ port.id }}"
+ state: absent
+ check_mode: true
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - result is changed
+#----------------------------------------------------------
+- name: delete a eip
+ hwc_vpc_eip:
+ type: "5_bgp"
+ dedicated_bandwidth:
+ charge_mode: "traffic"
+ name: "ansible_test_dedicated_bandwidth"
+ size: 1
+ port_id: "{{ port.id }}"
+ state: absent
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - result is changed
+#----------------------------------------------------------
+- name: delete a eip (idemponent)
+ hwc_vpc_eip:
+ type: "5_bgp"
+ dedicated_bandwidth:
+ charge_mode: "traffic"
+ name: "ansible_test_dedicated_bandwidth"
+ size: 1
+ port_id: "{{ port.id }}"
+ state: absent
+ check_mode: true
+ register: result
+- name: idemponent
+ assert:
+ that:
+ - not result.changed
+# ----------------------------------------------------------------------------
+- name: delete a eip that does not exist
+ hwc_vpc_eip:
+ type: "5_bgp"
+ dedicated_bandwidth:
+ charge_mode: "traffic"
+ name: "ansible_test_dedicated_bandwidth"
+ size: 1
+ port_id: "{{ port.id }}"
+ state: absent
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - result is not failed
+ - result is not changed
+#---------------------------------------------------------
+# Post-test teardown
+- name: delete a port
+ hwc_vpc_port:
+ subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ state: absent
+ register: port
+- name: delete a subnet
+ hwc_vpc_subnet:
+ gateway_ip: "192.168.100.32"
+ name: "ansible_network_subnet_test"
+ dhcp_enable: true
+ vpc_id: "{{ vpc.id }}"
+ cidr: "192.168.100.0/26"
+ state: absent
+ register: subnet
+- name: delete a vpc
+ hwc_network_vpc:
+ cidr: "192.168.100.0/24"
+ name: "ansible_network_vpc_test"
+ state: absent
+ register: vpc
diff --git a/ansible_collections/community/general/tests/integration/targets/hwc_vpc_peering_connect/aliases b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_peering_connect/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_peering_connect/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/hwc_vpc_peering_connect/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_peering_connect/tasks/main.yml
new file mode 100644
index 000000000..b8e02a539
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_peering_connect/tasks/main.yml
@@ -0,0 +1,155 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Pre-test setup
+- name: create a vpc
+ hwc_network_vpc:
+ cidr: "192.168.0.0/16"
+ name: "ansible_network_vpc_test_local"
+ state: present
+ register: vpc1
+- name: create a vpc
+ hwc_network_vpc:
+ cidr: "192.168.0.0/16"
+ name: "ansible_network_vpc_test_peering"
+ state: present
+ register: vpc2
+- name: delete a peering connect
+ hwc_vpc_peering_connect:
+ local_vpc_id: "{{ vpc1.id }}"
+ name: "ansible_network_peering_test"
+ peering_vpc:
+ vpc_id: "{{ vpc2.id }}"
+ state: absent
+#----------------------------------------------------------
+- name: create a peering connect (check mode)
+ hwc_vpc_peering_connect:
+ local_vpc_id: "{{ vpc1.id }}"
+ name: "ansible_network_peering_test"
+ peering_vpc:
+ vpc_id: "{{ vpc2.id }}"
+ state: present
+ check_mode: true
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - not result.id
+ - result.changed
+#----------------------------------------------------------
+- name: create a peering connect
+ hwc_vpc_peering_connect:
+ local_vpc_id: "{{ vpc1.id }}"
+ name: "ansible_network_peering_test"
+ peering_vpc:
+ vpc_id: "{{ vpc2.id }}"
+ state: present
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ result is changed
+#----------------------------------------------------------
+- name: create a peering connect (idemponent)
+ hwc_vpc_peering_connect:
+ local_vpc_id: "{{ vpc1.id }}"
+ name: "ansible_network_peering_test"
+ peering_vpc:
+ vpc_id: "{{ vpc2.id }}"
+ state: present
+ check_mode: true
+ register: result
+- name: idemponent
+ assert:
+ that:
+ - not result.changed
+# ----------------------------------------------------------------------------
+- name: create a peering connect that already exists
+ hwc_vpc_peering_connect:
+ local_vpc_id: "{{ vpc1.id }}"
+ name: "ansible_network_peering_test"
+ peering_vpc:
+ vpc_id: "{{ vpc2.id }}"
+ state: present
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - result is not failed
+ - result is not changed
+#----------------------------------------------------------
+- name: delete a peering connect (check mode)
+ hwc_vpc_peering_connect:
+ local_vpc_id: "{{ vpc1.id }}"
+ name: "ansible_network_peering_test"
+ peering_vpc:
+ vpc_id: "{{ vpc2.id }}"
+ state: absent
+ check_mode: true
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ result is changed
+#----------------------------------------------------------
+- name: delete a peering connect
+ hwc_vpc_peering_connect:
+ local_vpc_id: "{{ vpc1.id }}"
+ name: "ansible_network_peering_test"
+ peering_vpc:
+ vpc_id: "{{ vpc2.id }}"
+ state: absent
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ result is changed
+#----------------------------------------------------------
+- name: delete a peering connect (idemponent)
+ hwc_vpc_peering_connect:
+ local_vpc_id: "{{ vpc1.id }}"
+ name: "ansible_network_peering_test"
+ peering_vpc:
+ vpc_id: "{{ vpc2.id }}"
+ state: absent
+ check_mode: true
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - not result.changed
+# ----------------------------------------------------------------------------
+- name: delete a peering connect that does not exist
+ hwc_vpc_peering_connect:
+ local_vpc_id: "{{ vpc1.id }}"
+ name: "ansible_network_peering_test"
+ peering_vpc:
+ vpc_id: "{{ vpc2.id }}"
+ state: absent
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - result is not failed
+ - result is not changed
+#---------------------------------------------------------
+# Post-test teardown
+- name: delete a vpc
+ hwc_network_vpc:
+ cidr: "192.168.0.0/16"
+ name: "ansible_network_vpc_test_peering"
+ state: absent
+ register: vpc2
+- name: delete a vpc
+ hwc_network_vpc:
+ cidr: "192.168.0.0/16"
+ name: "ansible_network_vpc_test_local"
+ state: absent
+ register: vpc1
diff --git a/ansible_collections/community/general/tests/integration/targets/hwc_vpc_port/aliases b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_port/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_port/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/hwc_vpc_port/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_port/tasks/main.yml
new file mode 100644
index 000000000..93b17398f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_port/tasks/main.yml
@@ -0,0 +1,141 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Pre-test setup
+- name: create a vpc
+ hwc_network_vpc:
+ cidr: "192.168.100.0/24"
+ name: "ansible_network_vpc_test"
+ state: present
+ register: vpc
+- name: create a subnet
+ hwc_vpc_subnet:
+ gateway_ip: "192.168.100.32"
+ name: "ansible_network_subnet_test"
+ dhcp_enable: true
+ vpc_id: "{{ vpc.id }}"
+ cidr: "192.168.100.0/26"
+ state: present
+ register: subnet
+- name: delete a port
+ hwc_vpc_port:
+ subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ state: absent
+#----------------------------------------------------------
+- name: create a port (check mode)
+ hwc_vpc_port:
+ subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ state: present
+ check_mode: true
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - result is changed
+#----------------------------------------------------------
+- name: create a port
+ hwc_vpc_port:
+ subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ state: present
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - result is changed
+#----------------------------------------------------------
+- name: create a port (idemponent)
+ hwc_vpc_port:
+ subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ state: present
+ register: result
+- name: idemponent
+ assert:
+ that:
+ - not result.changed
+# ----------------------------------------------------------------------------
+- name: create a port that already exists
+ hwc_vpc_port:
+ subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ state: present
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - result is not failed
+ - result is not changed
+#----------------------------------------------------------
+- name: delete a port (check mode)
+ hwc_vpc_port:
+ subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ state: absent
+ check_mode: true
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - result is changed
+#----------------------------------------------------------
+- name: delete a port
+ hwc_vpc_port:
+ subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ state: absent
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - result is changed
+#----------------------------------------------------------
+- name: delete a port (idemponent)
+ hwc_vpc_port:
+ subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ state: absent
+ check_mode: true
+ register: result
+- name: idemponent
+ assert:
+ that:
+ - not result.changed
+# ----------------------------------------------------------------------------
+- name: delete a port that does not exist
+ hwc_vpc_port:
+ subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ state: absent
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - result is not failed
+ - result is not changed
+#---------------------------------------------------------
+# Post-test teardown
+- name: delete a subnet
+ hwc_vpc_subnet:
+ gateway_ip: "192.168.100.32"
+ name: "ansible_network_subnet_test"
+ dhcp_enable: true
+ vpc_id: "{{ vpc.id }}"
+ cidr: "192.168.100.0/26"
+ state: absent
+ register: subnet
+- name: delete a vpc
+ hwc_network_vpc:
+ cidr: "192.168.100.0/24"
+ name: "ansible_network_vpc_test"
+ state: absent
+ register: vpc
diff --git a/ansible_collections/community/general/tests/integration/targets/hwc_vpc_private_ip/aliases b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_private_ip/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_private_ip/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/hwc_vpc_private_ip/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_private_ip/tasks/main.yml
new file mode 100644
index 000000000..6accdb855
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_private_ip/tasks/main.yml
@@ -0,0 +1,142 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Pre-test setup
+- name: create a vpc
+ hwc_network_vpc:
+ cidr: "192.168.100.0/24"
+ name: "ansible_network_vpc_test"
+ state: present
+ register: vpc
+- name: create a subnet
+ hwc_vpc_subnet:
+ gateway_ip: "192.168.100.32"
+ name: "ansible_network_subnet_test"
+ dhcp_enable: true
+ vpc_id: "{{ vpc.id }}"
+ cidr: "192.168.100.0/26"
+ state: present
+ register: subnet
+- name: delete a private ip
+ hwc_vpc_private_ip:
+ subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ state: absent
+#----------------------------------------------------------
+- name: create a private ip (check mode)
+ hwc_vpc_private_ip:
+ subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ state: present
+ check_mode: true
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - result is changed
+#----------------------------------------------------------
+- name: create a private ip
+ hwc_vpc_private_ip:
+ subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ state: present
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - result is changed
+#----------------------------------------------------------
+- name: create a private ip (idemponent)
+ hwc_vpc_private_ip:
+ subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ state: present
+ check_mode: true
+ register: result
+- name: idemponent
+ assert:
+ that:
+ - not result.changed
+# ----------------------------------------------------------------------------
+- name: create a private ip that already exists
+ hwc_vpc_private_ip:
+ subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ state: present
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - result is not failed
+ - result is not changed
+#----------------------------------------------------------
+- name: delete a private ip (check mode)
+ hwc_vpc_private_ip:
+ subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ state: absent
+ check_mode: true
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - result is changed
+#----------------------------------------------------------
+- name: delete a private ip
+ hwc_vpc_private_ip:
+ subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ state: absent
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - result is changed
+#----------------------------------------------------------
+- name: delete a private ip (idemponent)
+ hwc_vpc_private_ip:
+ subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ state: absent
+ check_mode: true
+ register: result
+- name: idemponent
+ assert:
+ that:
+ - not result.changed
+# ----------------------------------------------------------------------------
+- name: delete a private ip that does not exist
+ hwc_vpc_private_ip:
+ subnet_id: "{{ subnet.id }}"
+ ip_address: "192.168.100.33"
+ state: absent
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - result is not failed
+ - result is not changed
+#---------------------------------------------------------
+# Post-test teardown
+- name: delete a subnet
+ hwc_vpc_subnet:
+ gateway_ip: "192.168.100.32"
+ name: "ansible_network_subnet_test"
+ dhcp_enable: true
+ vpc_id: "{{ vpc.id }}"
+ cidr: "192.168.100.0/26"
+ state: absent
+ register: subnet
+- name: delete a vpc
+ hwc_network_vpc:
+ cidr: "192.168.100.0/24"
+ name: "ansible_network_vpc_test"
+ state: absent
+ register: vpc
diff --git a/ansible_collections/community/general/tests/integration/targets/hwc_vpc_route/aliases b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_route/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_route/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/hwc_vpc_route/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_route/tasks/main.yml
new file mode 100644
index 000000000..8e2e2ca82
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_route/tasks/main.yml
@@ -0,0 +1,159 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Pre-test setup
+- name: create a vpc
+ hwc_network_vpc:
+ cidr: "192.168.0.0/16"
+ name: "ansible_network_vpc_test_local"
+ state: present
+ register: vpc1
+- name: create a vpc
+ hwc_network_vpc:
+ cidr: "192.168.0.0/16"
+ name: "ansible_network_vpc_test_peering"
+ state: present
+ register: vpc2
+- name: create a peering connect
+ hwc_vpc_peering_connect:
+ local_vpc_id: "{{ vpc1.id }}"
+ name: "ansible_network_peering_test"
+ filters:
+ - "name"
+ peering_vpc:
+ vpc_id: "{{ vpc2.id }}"
+ state: present
+ register: connect
+- name: delete a route
+ hwc_vpc_route:
+ vpc_id: "{{ vpc1.id }}"
+ destination: "192.168.0.0/16"
+ next_hop: "{{ connect.id }}"
+ state: absent
+#----------------------------------------------------------
+- name: create a route (check mode)
+ hwc_vpc_route:
+ vpc_id: "{{ vpc1.id }}"
+ destination: "192.168.0.0/16"
+ next_hop: "{{ connect.id }}"
+ check_mode: true
+ register: result
+- assert:
+ that:
+ - not result.id
+ - result.changed
+#----------------------------------------------------------
+- name: create a route
+ hwc_vpc_route:
+ vpc_id: "{{ vpc1.id }}"
+ destination: "192.168.0.0/16"
+ next_hop: "{{ connect.id }}"
+ state: present
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ result is changed
+# ----------------------------------------------------------
+- name: create a route (idemponent)
+ hwc_vpc_route:
+ vpc_id: "{{ vpc1.id }}"
+ destination: "192.168.0.0/16"
+ next_hop: "{{ connect.id }}"
+ state: present
+ check_mode: true
+ register: result
+- name: idemponent
+ assert:
+ that:
+ - not result.changed
+# -----------------------------------------------------------
+- name: create a route that already exists
+ hwc_vpc_route:
+ vpc_id: "{{ vpc1.id }}"
+ destination: "192.168.0.0/16"
+ next_hop: "{{ connect.id }}"
+ state: present
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - result is not failed
+ - result is not changed
+#----------------------------------------------------------
+- name: delete a route (check mode)
+ hwc_vpc_route:
+ vpc_id: "{{ vpc1.id }}"
+ destination: "192.168.0.0/16"
+ next_hop: "{{ connect.id }}"
+ state: absent
+ check_mode: true
+#----------------------------------------------------------
+- name: delete a route
+ hwc_vpc_route:
+ vpc_id: "{{ vpc1.id }}"
+ destination: "192.168.0.0/16"
+ next_hop: "{{ connect.id }}"
+ state: absent
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ result is changed
+#----------------------------------------------------------
+- name: delete a (idemponent)
+ hwc_vpc_route:
+ vpc_id: "{{ vpc1.id }}"
+ destination: "192.168.0.0/16"
+ next_hop: "{{ connect.id }}"
+ state: absent
+ check_mode: true
+ register: result
+- name: not changed
+ assert:
+ that:
+ not result.changed
+# ----------------------------------------------------------------------------
+- name: delete a route that does not exist
+ hwc_vpc_route:
+ vpc_id: "{{ vpc1.id }}"
+ destination: "192.168.0.0/16"
+ next_hop: "{{ connect.id }}"
+ state: absent
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - result is not failed
+ - result is not changed
+#---------------------------------------------------------
+# Post-test teardown
+- name: delete a peering connect
+ hwc_vpc_peering_connect:
+ local_vpc_id: "{{ vpc1.id }}"
+ name: "ansible_network_peering_test"
+ filters:
+ - "name"
+ peering_vpc:
+ vpc_id: "{{ vpc2.id }}"
+ state: absent
+ register: connect
+- name: delete a vpc
+ hwc_network_vpc:
+ cidr: "192.168.0.0/16"
+ name: "ansible_network_vpc_test_peering"
+ state: absent
+ register: vpc2
+- name: delete a vpc
+ hwc_network_vpc:
+ cidr: "192.168.0.0/16"
+ name: "ansible_network_vpc_test_local"
+ state: absent
+ register: vpc1
diff --git a/ansible_collections/community/general/tests/integration/targets/hwc_vpc_security_group/aliases b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_security_group/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_security_group/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/hwc_vpc_security_group/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_security_group/tasks/main.yml
new file mode 100644
index 000000000..b6ee25e25
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_security_group/tasks/main.yml
@@ -0,0 +1,91 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Pre-test setup
+- name: delete a security group
+ hwc_vpc_security_group:
+ name: "ansible_network_security_group_test"
+ state: absent
+#----------------------------------------------------------
+- name: create a security group (check mode)
+ hwc_vpc_security_group:
+ name: "ansible_network_security_group_test"
+ state: present
+ check_mode: true
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - not result.id
+ - result.changed
+#----------------------------------------------------------
+- name: create a security group
+ hwc_vpc_security_group:
+ name: "ansible_network_security_group_test"
+ state: present
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ result is changed
+#----------------------------------------------------------
+- name: create a security group (idemponent)
+ hwc_vpc_security_group:
+ name: "ansible_network_security_group_test"
+ state: present
+ check_mode: true
+ register: idemponent
+- name: idemponent
+ assert:
+ that:
+ - not result.changed
+# ----------------------------------------------------------------------------
+- name: create a security group that already exists
+ hwc_vpc_security_group:
+ name: "ansible_network_security_group_test"
+ state: present
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - result is not failed
+ - result is not changed
+#----------------------------------------------------------
+- name: delete a security group (check mode)
+ hwc_vpc_security_group:
+ name: "ansible_network_security_group_test"
+ state: absent
+ check_mode: true
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ result is changed
+#----------------------------------------------------------
+- name: delete a security group
+ hwc_vpc_security_group:
+ name: "ansible_network_security_group_test"
+ state: absent
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ result is changed
+# ----------------------------------------------------------------------------
+- name: delete a security group that does not exist
+ hwc_vpc_security_group:
+ name: "ansible_network_security_group_test"
+ state: absent
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - result is not failed
+ - result is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/hwc_vpc_security_group_rule/aliases b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_security_group_rule/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_security_group_rule/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/hwc_vpc_security_group_rule/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_security_group_rule/tasks/main.yml
new file mode 100644
index 000000000..4ce4bafdc
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_security_group_rule/tasks/main.yml
@@ -0,0 +1,166 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Pre-test setup
+- name: create a security group
+ hwc_vpc_security_group:
+ name: "ansible_network_security_group_test"
+ state: present
+ register: sg
+- name: delete a security group rule
+ hwc_vpc_security_group_rule:
+ direction: "ingress"
+ protocol: "tcp"
+ ethertype: "IPv4"
+ port_range_max: 55
+ security_group_id: "{{ sg.id }}"
+ port_range_min: 22
+ remote_ip_prefix: "0.0.0.0/0"
+ state: absent
+#----------------------------------------------------------
+- name: create a security group rule (check mode)
+ hwc_vpc_security_group_rule:
+ direction: "ingress"
+ protocol: "tcp"
+ ethertype: "IPv4"
+ port_range_max: 55
+ security_group_id: "{{ sg.id }}"
+ port_range_min: 22
+ remote_ip_prefix: "0.0.0.0/0"
+ state: present
+ check_mode: true
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - not result.id
+ - result.changed
+#----------------------------------------------------------
+- name: create a security group rule
+ hwc_vpc_security_group_rule:
+ direction: "ingress"
+ protocol: "tcp"
+ ethertype: "IPv4"
+ port_range_max: 55
+ security_group_id: "{{ sg.id }}"
+ port_range_min: 22
+ remote_ip_prefix: "0.0.0.0/0"
+ state: present
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - result is changed
+#----------------------------------------------------------
+- name: create a security group rule (idemponent)
+ hwc_vpc_security_group_rule:
+ direction: "ingress"
+ protocol: "tcp"
+ ethertype: "IPv4"
+ port_range_max: 55
+ security_group_id: "{{ sg.id }}"
+ port_range_min: 22
+ remote_ip_prefix: "0.0.0.0/0"
+ state: present
+ register: result
+- name: idemponent
+ assert:
+ that:
+ - not result.changed
+# ----------------------------------------------------------------------------
+- name: create a security group rule that already exists
+ hwc_vpc_security_group_rule:
+ direction: "ingress"
+ protocol: "tcp"
+ ethertype: "IPv4"
+ port_range_max: 55
+ security_group_id: "{{ sg.id }}"
+ port_range_min: 22
+ remote_ip_prefix: "0.0.0.0/0"
+ state: present
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - result is not failed
+ - result is not changed
+#----------------------------------------------------------
+- name: delete a security group rule (check mode)
+ hwc_vpc_security_group_rule:
+ direction: "ingress"
+ protocol: "tcp"
+ ethertype: "IPv4"
+ port_range_max: 55
+ security_group_id: "{{ sg.id }}"
+ port_range_min: 22
+ remote_ip_prefix: "0.0.0.0/0"
+ state: absent
+ check_mode: true
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - result is changed
+#----------------------------------------------------------
+- name: delete a security group rule
+ hwc_vpc_security_group_rule:
+ direction: "ingress"
+ protocol: "tcp"
+ ethertype: "IPv4"
+ port_range_max: 55
+ security_group_id: "{{ sg.id }}"
+ port_range_min: 22
+ remote_ip_prefix: "0.0.0.0/0"
+ state: absent
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - result is changed
+#----------------------------------------------------------
+- name: delete a security group rule (idemponent)
+ hwc_vpc_security_group_rule:
+ direction: "ingress"
+ protocol: "tcp"
+ ethertype: "IPv4"
+ port_range_max: 55
+ security_group_id: "{{ sg.id }}"
+ port_range_min: 22
+ remote_ip_prefix: "0.0.0.0/0"
+ state: absent
+ register: result
+- name: idemponent
+ assert:
+ that:
+ - not result.changed
+# ----------------------------------------------------------------------------
+- name: delete a security group rule that does not exist
+ hwc_vpc_security_group_rule:
+ direction: "ingress"
+ protocol: "tcp"
+ ethertype: "IPv4"
+ port_range_max: 55
+ security_group_id: "{{ sg.id }}"
+ port_range_min: 22
+ remote_ip_prefix: "0.0.0.0/0"
+ state: absent
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - result is not failed
+ - result is not changed
+#---------------------------------------------------------
+# Post-test teardown
+- name: delete a security group
+ hwc_vpc_security_group:
+ name: "ansible_network_security_group_test"
+ state: absent
+ register: sg
diff --git a/ansible_collections/community/general/tests/integration/targets/hwc_vpc_subnet/aliases b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_subnet/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_subnet/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/hwc_vpc_subnet/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_subnet/tasks/main.yml
new file mode 100644
index 000000000..522ffb601
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/hwc_vpc_subnet/tasks/main.yml
@@ -0,0 +1,152 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Pre-test setup
+- name: create a vpc
+ hwc_network_vpc:
+ cidr: "192.168.100.0/24"
+ name: "ansible_network_vpc_test"
+ state: present
+ register: vpc
+- name: delete a subnet
+ hwc_vpc_subnet:
+ vpc_id: "{{ vpc.id }}"
+ cidr: "192.168.100.0/26"
+ gateway_ip: "192.168.100.32"
+ name: "ansible_network_subnet_test"
+ dhcp_enable: true
+ state: absent
+#----------------------------------------------------------
+- name: create a subnet (check mode)
+ hwc_vpc_subnet:
+ vpc_id: "{{ vpc.id }}"
+ cidr: "192.168.100.0/26"
+ gateway_ip: "192.168.100.32"
+ name: "ansible_network_subnet_test"
+ dhcp_enable: true
+ state: present
+ check_mode: true
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - not result.id
+ - result.changed
+#----------------------------------------------------------
+- name: create a subnet
+ hwc_vpc_subnet:
+ vpc_id: "{{ vpc.id }}"
+ cidr: "192.168.100.0/26"
+ gateway_ip: "192.168.100.32"
+ name: "ansible_network_subnet_test"
+ dhcp_enable: true
+ state: present
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ result is changed
+#----------------------------------------------------------
+- name: create a subnet (idemponent)
+ hwc_vpc_subnet:
+ vpc_id: "{{ vpc.id }}"
+ cidr: "192.168.100.0/26"
+ gateway_ip: "192.168.100.32"
+ name: "ansible_network_subnet_test"
+ dhcp_enable: true
+ state: present
+ check_mode: true
+ register: result
+- name: idemponent
+ assert:
+ that:
+ - not result.changed
+# ----------------------------------------------------------------------------
+- name: create a subnet that already exists
+ hwc_vpc_subnet:
+ vpc_id: "{{ vpc.id }}"
+ cidr: "192.168.100.0/26"
+ gateway_ip: "192.168.100.32"
+ name: "ansible_network_subnet_test"
+ dhcp_enable: true
+ state: present
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - result is not failed
+ - result is not changed
+#----------------------------------------------------------
+- name: delete a subnet (check mode)
+ hwc_vpc_subnet:
+ vpc_id: "{{ vpc.id }}"
+ cidr: "192.168.100.0/26"
+ gateway_ip: "192.168.100.32"
+ name: "ansible_network_subnet_test"
+ dhcp_enable: true
+ state: absent
+ check_mode: true
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - result is changed
+#----------------------------------------------------------
+- name: delete a subnet
+ hwc_vpc_subnet:
+ vpc_id: "{{ vpc.id }}"
+ cidr: "192.168.100.0/26"
+ gateway_ip: "192.168.100.32"
+ name: "ansible_network_subnet_test"
+ dhcp_enable: true
+ state: absent
+ register: result
+- name: assert changed is true
+ assert:
+ that:
+ - result is changed
+#----------------------------------------------------------
+- name: delete a subnet (idemponent)
+ hwc_vpc_subnet:
+ vpc_id: "{{ vpc.id }}"
+ cidr: "192.168.100.0/26"
+ gateway_ip: "192.168.100.32"
+ name: "ansible_network_subnet_test"
+ dhcp_enable: true
+ state: absent
+ check_mode: true
+ register: result
+- name: idemponent
+ assert:
+ that:
+ - not result.changed
+# ----------------------------------------------------------------------------
+- name: delete a subnet that does not exist
+ hwc_vpc_subnet:
+ vpc_id: "{{ vpc.id }}"
+ cidr: "192.168.100.0/26"
+ gateway_ip: "192.168.100.32"
+ name: "ansible_network_subnet_test"
+ dhcp_enable: true
+ state: absent
+ register: result
+- name: assert changed is false
+ assert:
+ that:
+ - result is not failed
+ - result is not changed
+#---------------------------------------------------------
+# Post-test teardown
+- name: delete a vpc
+ hwc_network_vpc:
+ cidr: "192.168.100.0/24"
+ name: "ansible_network_vpc_test"
+ state: absent
+ register: vpc
diff --git a/ansible_collections/community/general/tests/integration/targets/ilo_redfish_command/aliases b/ansible_collections/community/general/tests/integration/targets/ilo_redfish_command/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ilo_redfish_command/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/ilo_redfish_command/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/ilo_redfish_command/tasks/main.yml
new file mode 100644
index 000000000..cc1fce748
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ilo_redfish_command/tasks/main.yml
@@ -0,0 +1,12 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Wait for iLO Reboot Completion
+ community.general.ilo_redfish_command:
+ category: Systems
+ command: WaitforiLORebootCompletion
+ baseuri: "{{ baseuri }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/ilo_redfish_config/aliases b/ansible_collections/community/general/tests/integration/targets/ilo_redfish_config/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ilo_redfish_config/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/ilo_redfish_config/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/ilo_redfish_config/tasks/main.yml
new file mode 100644
index 000000000..30bfb4edd
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ilo_redfish_config/tasks/main.yml
@@ -0,0 +1,53 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Set NTP Servers
+ ilo_redfish_config:
+ category: Manager
+ command: SetNTPServers
+ baseuri: "{{ baseuri }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+ attribute_name: StaticNTPServers
+ attribute_value: 1.2.3.4
+
+- name: Set DNS Server
+ ilo_redfish_config:
+ category: Manager
+ command: SetDNSserver
+ baseuri: "{{ baseuri }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+ attribute_name: DNSServers
+ attribute_value: 192.168.1.1
+
+- name: Set Domain name
+ ilo_redfish_config:
+ category: Manager
+ command: SetDomainName
+ baseuri: "{{ baseuri }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+ attribute_name: DomainName
+ attribute_value: tst.sgp.hp.mfg
+
+- name: Disable WINS Reg
+ ilo_redfish_config:
+ category: Manager
+ command: SetWINSReg
+ baseuri: "{{ baseuri }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+ attribute_name: WINSRegistration
+
+- name: Set TimeZone
+ ilo_redfish_config:
+ category: Manager
+ command: SetTimeZone
+ baseuri: "{{ baseuri }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+ attribute_name: TimeZone
+ attribute_value: Chennai
diff --git a/ansible_collections/community/general/tests/integration/targets/ilo_redfish_info/aliases b/ansible_collections/community/general/tests/integration/targets/ilo_redfish_info/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ilo_redfish_info/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/ilo_redfish_info/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/ilo_redfish_info/tasks/main.yml
new file mode 100644
index 000000000..0f80207ac
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ilo_redfish_info/tasks/main.yml
@@ -0,0 +1,13 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Get sessions
+ ilo_redfish_info:
+ category: Sessions
+ command: GetiLOSessions
+ baseuri: "{{ baseuri }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+ register: result_sessions
diff --git a/ansible_collections/community/general/tests/integration/targets/influxdb_user/aliases b/ansible_collections/community/general/tests/integration/targets/influxdb_user/aliases
new file mode 100644
index 000000000..8c1a7b329
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/influxdb_user/aliases
@@ -0,0 +1,11 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+destructive
+disabled
+skip/osx
+skip/macos
+skip/freebsd
+skip/rhel
diff --git a/ansible_collections/community/general/tests/integration/targets/influxdb_user/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/influxdb_user/meta/main.yml
new file mode 100644
index 000000000..34b3a3a6c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/influxdb_user/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_influxdb
diff --git a/ansible_collections/community/general/tests/integration/targets/influxdb_user/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/influxdb_user/tasks/main.yml
new file mode 100644
index 000000000..7da2f85e5
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/influxdb_user/tasks/main.yml
@@ -0,0 +1,12 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- include_tasks: tests.yml
+ when: ansible_distribution == 'Ubuntu' and ansible_distribution_release == 'trusty'
diff --git a/ansible_collections/community/general/tests/integration/targets/influxdb_user/tasks/tests.yml b/ansible_collections/community/general/tests/integration/targets/influxdb_user/tasks/tests.yml
new file mode 100644
index 000000000..be36ee691
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/influxdb_user/tasks/tests.yml
@@ -0,0 +1,143 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install influxdb python module
+ pip: name=influxdb
+
+- name: Test add admin user in check mode
+ block:
+ - name: Add admin user
+ influxdb_user: user_name=admin user_password=admin admin=yes
+ check_mode: true
+ register: add_admin_user
+
+ - name: Check that admin user adding succeeds with a change
+ assert:
+ that:
+ - add_admin_user is changed
+
+- name: Test add admin user
+ block:
+ - name: Add admin user
+ influxdb_user: user_name=admin user_password=admin admin=yes
+ register: add_admin_user
+
+ - name: Check that admin user adding succeeds with a change
+ assert:
+ that:
+ - add_admin_user is changed
+
+- name: Test add admin user idempotence
+ block:
+ - name: Add admin user
+ influxdb_user: user_name=admin user_password=admin admin=yes
+ register: add_admin_user
+
+ - name: Check that admin user adding succeeds without a change
+ assert:
+ that:
+ - add_admin_user is not changed
+
+- name: Enable authentication and restart service
+ block:
+ - name: Enable authentication
+ lineinfile:
+ path: /etc/influxdb/influxdb.conf
+ regexp: 'auth-enabled ='
+ line: ' auth-enabled = true'
+
+ - name: Restart InfluxDB service
+ service: name=influxdb state=restarted
+
+- name: Test add user in check mode when authentication enabled
+ block:
+ - name: Add user
+ influxdb_user: user_name=user user_password=user login_username=admin login_password=admin
+ check_mode: true
+ register: add_user_with_auth_enabled
+
+ - name: Check that adding user with enabled authentication succeeds with a change
+ assert:
+ that:
+ - add_user_with_auth_enabled is changed
+
+- name: Test add user when authentication enabled
+ block:
+ - name: Add user
+ influxdb_user: user_name=user user_password=user login_username=admin login_password=admin
+ register: add_user_with_auth_enabled
+
+ - name: Check that adding user with enabled authentication succeeds with a change
+ assert:
+ that:
+ - add_user_with_auth_enabled is changed
+
+- name: Test add user when authentication enabled idempotence
+ block:
+ - name: Add the same user
+ influxdb_user: user_name=user user_password=user login_username=admin login_password=admin
+ register: same_user
+
+ - name: Check that adding same user succeeds without a change
+ assert:
+ that:
+ - same_user is not changed
+
+- name: Test change user password in check mode
+ block:
+ - name: Change user password
+ influxdb_user: user_name=user user_password=user2 login_username=admin login_password=admin
+ check_mode: true
+ register: change_password
+
+ - name: Check that password changing succeeds with a change
+ assert:
+ that:
+ - change_password is changed
+
+- name: Test change user password
+ block:
+ - name: Change user password
+ influxdb_user: user_name=user user_password=user2 login_username=admin login_password=admin
+ register: change_password
+
+ - name: Check that password changing succeeds with a change
+ assert:
+ that:
+ - change_password is changed
+
+- name: Test remove user in check mode
+ block:
+ - name: Remove user
+ influxdb_user: user_name=user state=absent login_username=admin login_password=admin
+ check_mode: true
+ register: remove_user
+
+ - name: Check that removing user succeeds with a change
+ assert:
+ that:
+ - remove_user is changed
+
+- name: Test remove user
+ block:
+ - name: Remove user
+ influxdb_user: user_name=user state=absent login_username=admin login_password=admin
+ register: remove_user
+
+ - name: Check that removing user succeeds with a change
+ assert:
+ that:
+ - remove_user is changed
+
+- name: Test remove user idempotence
+ block:
+ - name: Remove user
+ influxdb_user: user_name=user state=absent login_username=admin login_password=admin
+ register: remove_user
+
+ - name: Check that removing user succeeds without a change
+ assert:
+ that:
+ - remove_user is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/ini_file/aliases b/ansible_collections/community/general/tests/integration/targets/ini_file/aliases
new file mode 100644
index 000000000..12d1d6617
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ini_file/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
diff --git a/ansible_collections/community/general/tests/integration/targets/ini_file/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/ini_file/meta/main.yml
new file mode 100644
index 000000000..982de6eb0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ini_file/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/main.yml
new file mode 100644
index 000000000..11c5bf3b2
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/main.yml
@@ -0,0 +1,40 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# test code for ini_file plugins
+# Copyright (c) 2017 Red Hat Inc.
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: record the output directory
+ set_fact:
+ output_file: "{{ remote_tmp_dir }}/foo.ini"
+ non_existing_file: "{{ remote_tmp_dir }}/bar.ini"
+
+- name: include tasks
+ block:
+
+ - name: include tasks to perform basic tests
+ include_tasks: tests/00-basic.yml
+
+ - name: reset output file
+ file:
+ path: "{{ output_file }}"
+ state: absent
+
+ - name: include tasks to perform tests with parameter "value"
+ include_tasks: tests/01-value.yml
+
+ - name: reset output file
+ file:
+ path: "{{ output_file }}"
+ state: absent
+
+ - name: include tasks to perform tests with parameter "values"
+ include_tasks: tests/02-values.yml
+
+ - name: include tasks to test regressions
+ include_tasks: tests/03-encoding.yml
diff --git a/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/00-basic.yml b/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/00-basic.yml
new file mode 100644
index 000000000..c619e937a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/00-basic.yml
@@ -0,0 +1,42 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+## basiscs
+
+- name: test-basic 1 - specify both "value" and "values" and fail
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: fav
+ value: lemonade
+ values:
+ - coke
+ - sprite
+ register: result_basic_1
+ ignore_errors: true
+
+- name: test-basic 1 - verify error message
+ assert:
+ that:
+ - result_basic_1 is not changed
+ - result_basic_1 is failed
+ - "result_basic_1.msg == 'parameters are mutually exclusive: value|values'"
+
+
+- name: test-basic 2 - set "create=no" on non-existing file and fail
+ ini_file:
+ path: "{{ non_existing_file }}"
+ section: food
+ create: false
+ value: banana
+ register: result_basic_2
+ ignore_errors: true
+
+- name: test-basic 2 - verify error message
+ assert:
+ that:
+ - result_basic_2 is not changed
+ - result_basic_2 is failed
+ - result_basic_2.msg == "Destination {{ non_existing_file }} does not exist!"
diff --git a/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/01-value.yml b/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/01-value.yml
new file mode 100644
index 000000000..f95f166fe
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/01-value.yml
@@ -0,0 +1,592 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+## testing value
+
+- name: test-value 1 - set "state=present" and "value=null" and "allow_no_value=false" and fail
+ ini_file:
+ path: "{{ output_file }}"
+ section: cars
+ option: audi
+ value: null
+ allow_no_value: false
+ register: result_value_1
+ ignore_errors: true
+
+- name: test-value 1 - verify error message
+ assert:
+ that:
+ - result_value_1 is not changed
+ - result_value_1 is failed
+ - result_value_1.msg == "Parameter 'value(s)' must be defined if state=present and allow_no_value=False."
+
+
+- name: test-value 2 - set "state=present" and omit "value" and "allow_no_value=false" and fail
+ ini_file:
+ path: "{{ output_file }}"
+ section: cars
+ option: audi
+ allow_no_value: false
+ register: result_value_2
+ ignore_errors: true
+
+- name: test-value 2 - verify error message
+ assert:
+ that:
+ - result_value_2 is not changed
+ - result_value_2 is failed
+ - result_value_2.msg == "Parameter 'value(s)' must be defined if state=present and allow_no_value=False."
+
+
+- name: test-value 3 - add "fav=lemonade" in section "[drinks]" in specified file
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: fav
+ value: lemonade
+ register: result3
+
+- name: test-value 3 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-value 3 - set expected content and get current ini file content
+ set_fact:
+ expected3: |
+
+ [drinks]
+ fav = lemonade
+ content3: "{{ output_content.content | b64decode }}"
+
+- name: test-value 3 - Verify content of ini file is as expected and ini_file 'changed' is true
+ assert:
+ that:
+ - result3 is changed
+ - result3.msg == 'section and option added'
+ - content3 == expected3
+
+
+- name: test-value 4 - add "fav=lemonade" is in section "[drinks]" again
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: fav
+ value: lemonade
+ register: result4
+
+- name: test-value 4 - Ensure unchanged
+ assert:
+ that:
+ - result4 is not changed
+ - result4.msg == 'OK'
+
+
+- name: test-value 5 - Ensure "beverage=coke" is in section "[drinks]"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: beverage
+ value: coke
+ register: result5
+
+- name: test-value 5 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-value 5 - set expected content and get current ini file content
+ set_fact:
+ expected5: |
+
+ [drinks]
+ fav = lemonade
+ beverage = coke
+ content5: "{{ output_content.content | b64decode }}"
+
+- name: test-value 5 - assert 'changed' is true and content is OK
+ assert:
+ that:
+ - result5 is changed
+ - result5.msg == 'option added'
+ - content5 == expected5
+
+
+- name: test-value 6 - Remove option "beverage=coke"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: beverage
+ state: absent
+ register: result6
+
+- name: test-value 6 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-value 6 - set expected content and get current ini file content
+ set_fact:
+ expected6: |
+
+ [drinks]
+ fav = lemonade
+ content6: "{{ output_content.content | b64decode }}"
+
+- name: test-value 6 - assert 'changed' is true and content is as expected
+ assert:
+ that:
+ - result6 is changed
+ - result6.msg == 'option changed'
+ - content6 == expected6
+
+
+- name: test-value 7 - remove section 'drinks'
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ state: absent
+ register: result7
+
+- name: test-value 7 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-value 7 - get current ini file content
+ set_fact:
+ content7: "{{ output_content.content | b64decode }}"
+
+- name: test-value 7 - assert 'changed' is true and content is empty
+ assert:
+ that:
+ - result7 is changed
+ - result7.msg == 'section removed'
+ - content7 == "\n"
+
+
+# allow_no_value
+
+- name: test-value 8 - test allow_no_value
+ ini_file:
+ path: "{{ output_file }}"
+ section: mysqld
+ option: skip-name
+ allow_no_value: true
+ register: result8
+
+- name: test-value 8 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-value 8 - set expected content and get current ini file content
+ set_fact:
+ content8: "{{ output_content.content | b64decode }}"
+ expected8: |
+
+ [mysqld]
+ skip-name
+
+- name: test-value 8 - assert 'changed' is true and section and option added
+ assert:
+ that:
+ - result8 is changed
+ - result8.msg == 'section and option added'
+ - content8 == expected8
+
+
+- name: test-value 9 - test allow_no_value idempotency
+ ini_file:
+ path: "{{ output_file }}"
+ section: mysqld
+ option: skip-name
+ allow_no_value: true
+ register: result9
+
+- name: test-value 9 - assert 'changed' is false
+ assert:
+ that:
+ - result9 is not changed
+ - result9.msg == 'OK'
+
+
+- name: test-value 10 - test create empty section
+ ini_file:
+ path: "{{ output_file }}"
+ section: new_empty_section
+ allow_no_value: true
+ register: result10
+
+- name: test-value 10 - assert 'changed' is true and section added
+ assert:
+ that:
+ - result10 is changed
+ - result10.msg == 'only section added'
+
+
+- name: test-value 11 - test create empty section idempotency
+ ini_file:
+ path: "{{ output_file }}"
+ section: new_empty_section
+ allow_no_value: true
+ register: result11
+
+- name: test-value 11 - assert 'changed' is false
+ assert:
+ that:
+ - result11 is not changed
+ - result11.msg == 'OK'
+
+
+- name: test-value 12 - test remove empty section
+ ini_file:
+ state: absent
+ path: "{{ output_file }}"
+ section: new_empty_section
+ allow_no_value: true
+
+- name: test-value 12 - test allow_no_value with loop
+ ini_file:
+ path: "{{ output_file }}"
+ section: mysqld
+ option: "{{ item.o }}"
+ value: "{{ item.v | d(omit) }}"
+ allow_no_value: true
+ loop:
+ - { o: "skip-name-resolve" }
+ - { o: "max_connections", v: "500" }
+
+- name: test-value 12 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-value 12 - set expected content and get current ini file content
+ set_fact:
+ content12: "{{ output_content.content | b64decode }}"
+ expected12: |
+
+ [mysqld]
+ skip-name
+ skip-name-resolve
+ max_connections = 500
+
+- name: test-value 12 - Verify content of ini file is as expected
+ assert:
+ that:
+ - content12 == expected12
+
+
+- name: test-value 13 - change option with no value to option with value
+ ini_file:
+ path: "{{ output_file }}"
+ section: mysqld
+ option: skip-name
+ value: myvalue
+ register: result13
+
+- name: test-value 13 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-value 13 - set expected content and get current ini file content
+ set_fact:
+ content13: "{{ output_content.content | b64decode }}"
+ expected13: |
+
+ [mysqld]
+ skip-name = myvalue
+ skip-name-resolve
+ max_connections = 500
+
+- name: test-value 13 - assert 'changed' and msg 'option changed' and content is as expected
+ assert:
+ that:
+ - result13 is changed
+ - result13.msg == 'option changed'
+ - content13 == expected13
+
+
+- name: test-value 14 - change option with value to option with no value
+ ini_file:
+ path: "{{ output_file }}"
+ section: mysqld
+ option: skip-name
+ allow_no_value: true
+ register: result14
+
+- name: test-value 14 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-value 14 - set expected content and get current ini file content
+ set_fact:
+ content14: "{{ output_content.content | b64decode }}"
+ expected14: |
+
+ [mysqld]
+ skip-name
+ skip-name-resolve
+ max_connections = 500
+
+- name: test-value 14 - assert 'changed' is true and msg 'option changed' and content is as expected
+ assert:
+ that:
+ - result14 is changed
+ - result14.msg == 'option changed'
+ - content14 == expected14
+
+
+- name: test-value 15 - Remove option with no value
+ ini_file:
+ path: "{{ output_file }}"
+ section: mysqld
+ option: skip-name-resolve
+ state: absent
+ register: result15
+
+- name: test-value 15 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-value 15 - set expected content and get current ini file content
+ set_fact:
+ content15: "{{ output_content.content | b64decode }}"
+ expected15: |
+
+ [mysqld]
+ skip-name
+ max_connections = 500
+
+- name: test-value 15 - assert 'changed' is true and msg 'option changed' and content is as expected
+ assert:
+ that:
+ - result15 is changed
+ - result15.msg == 'option changed'
+ - content15 == expected15
+
+
+- name: test-value 16 - Clean test file
+ copy:
+ content: ""
+ dest: "{{ output_file }}"
+ force: true
+
+- name: test-value 16 - Ensure "beverage=coke" is created within no section
+ ini_file:
+ section:
+ path: "{{ output_file }}"
+ option: beverage
+ value: coke
+ register: result16
+
+- name: test-value 16 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-value 16 - set expected content and get current ini file content
+ set_fact:
+ expected16: |+
+ beverage = coke
+
+ content16: "{{ output_content.content | b64decode }}"
+
+- name: test-value 16 - assert 'changed' is true and content is OK (no section)
+ assert:
+ that:
+ - result16 is changed
+ - result16.msg == 'option added'
+ - content16 == expected16
+
+
+- name: test-value 17 - Ensure "beverage=coke" is modified as "beverage=water" within no section
+ ini_file:
+ path: "{{ output_file }}"
+ option: beverage
+ value: water
+ section:
+ register: result17
+
+- name: test-value 17 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-value 17 - set expected content and get current ini file content
+ set_fact:
+ expected17: |+
+ beverage = water
+
+ content17: "{{ output_content.content | b64decode }}"
+
+- name: test-value 17 - assert 'changed' is true and content is OK (no section)
+ assert:
+ that:
+ - result17 is changed
+ - result17.msg == 'option changed'
+ - content17 == expected17
+
+
+- name: test-value 18 - remove option 'beverage' within no section
+ ini_file:
+ section:
+ path: "{{ output_file }}"
+ option: beverage
+ state: absent
+ register: result18
+
+- name: test-value 18 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-value 18 - get current ini file content
+ set_fact:
+ content18: "{{ output_content.content | b64decode }}"
+
+- name: test-value 18 - assert 'changed' is true and option is removed (no section)
+ assert:
+ that:
+ - result18 is changed
+ - result18.msg == 'option changed'
+ - content18 == "\n"
+
+
+- name: test-value 19 - Check add option without section before existing section
+ block:
+ - name: test-value 19 - Add option with section
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: beverage
+ value: water
+ - name: test-value 19 - Add option without section
+ ini_file:
+ path: "{{ output_file }}"
+ section:
+ option: like
+ value: tea
+
+- name: test-value 19 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-value 19 - set expected content and get current ini file content
+ set_fact:
+ expected19: |
+ like = tea
+
+ [drinks]
+ beverage = water
+ content19: "{{ output_content.content | b64decode }}"
+
+- name: test-value 19 - Verify content of ini file is as expected
+ assert:
+ that:
+ - content19 == expected19
+
+
+- name: test-value 20 - Check add option with empty string value
+ block:
+ - name: test-value 20 - Remove drinks
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ state: absent
+ - name: test-value 20 - Remove tea
+ ini_file:
+ path: "{{ output_file }}"
+ section:
+ option: like
+ value: tea
+ state: absent
+ # See https://github.com/ansible-collections/community.general/issues/3031
+ - name: test-value 20 - Tests with empty strings
+ ini_file:
+ path: "{{ output_file }}"
+ section: "{{ item.section | d('extensions') }}"
+ option: "{{ item.option }}"
+ value: ""
+ allow_no_value: "{{ item.no_value | d(omit) }}"
+ loop:
+ - option: evolve
+ - option: regress
+ - section: foobar
+ option: foo
+ no_value: true
+ - option: improve
+ no_value: true
+
+- name: test-value 20 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-value 20 - set expected content and get current ini file content
+ set_fact:
+ expected20: |+
+
+ [extensions]
+ evolve =
+ regress =
+ improve =
+ [foobar]
+ foo =
+ content20: "{{ output_content.content | b64decode }}"
+
+- name: test-value 20 - Verify content of ini file is as expected
+ assert:
+ that:
+ - content20 == expected20
+
+
+- name: test-value 21 - Create starting ini file
+ copy:
+ # The content below is the following text file with BOM:
+ # [section1]
+ # var1=aaa
+ # var2=bbb
+ # [section2]
+ # var3=ccc
+ content: !!binary |
+ 77u/W3NlY3Rpb24xXQp2YXIxPWFhYQp2YXIyPWJiYgpbc2VjdGlvbjJdCnZhcjM9Y2NjCg==
+ dest: "{{ output_file }}"
+
+- name: test-value 21 - Test ini breakage
+ ini_file:
+ path: "{{ output_file }}"
+ section: section1
+ option: var4
+ value: 0
+ register: result21
+
+- name: test-value 21 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-value 21 - set expected content and get current ini file content
+ set_fact:
+ expected21: |
+ [section1]
+ var1=aaa
+ var2=bbb
+ var4 = 0
+ [section2]
+ var3=ccc
+ content21: "{{ output_content.content | b64decode }}"
+
+- name: test-value 21 - Verify content of ini file is as expected
+ assert:
+ that:
+ - result21 is changed
+ - result21.msg == 'option added'
+ - content21 == expected21
diff --git a/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/02-values.yml b/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/02-values.yml
new file mode 100644
index 000000000..edfc93e42
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/02-values.yml
@@ -0,0 +1,1023 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+## testing values
+
+- name: "test-values 1 - set 'state=present' and 'values=[]' and 'allow_no_value=false' and fail"
+ ini_file:
+ path: "{{ output_file }}"
+ section: cars
+ option: audi
+ values: []
+ allow_no_value: false
+ register: result1
+ ignore_errors: true
+
+- name: test-values 1 - verify error message
+ assert:
+ that:
+ - result1 is not changed
+ - result1 is failed
+ - result1.msg == "Parameter 'value(s)' must be defined if state=present and allow_no_value=False."
+
+
+- name: "test-values 2 - set 'state=present' and omit 'values' and 'allow_no_value=false' and fail"
+ ini_file:
+ path: "{{ output_file }}"
+ section: cars
+ option: audi
+ allow_no_value: false
+ register: result2
+ ignore_errors: true
+
+- name: test-values 2 - verify error message
+ assert:
+ that:
+ - result2 is not changed
+ - result2 is failed
+ - result2.msg == "Parameter 'value(s)' must be defined if state=present and allow_no_value=False."
+
+
+- name: "test-values 3 - ensure 'fav=lemonade' and 'fav=cocktail' is 'present' in section '[drinks]' in specified file"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: fav
+ values:
+ - lemonade
+ - cocktail
+ state: present
+ register: result3
+
+- name: test-values 3 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-values 3 - set expected content and get current ini file content
+ set_fact:
+ expected3: |
+
+ [drinks]
+ fav = lemonade
+ fav = cocktail
+ content3: "{{ output_content.content | b64decode }}"
+
+- name: test-values 3 - Verify content of ini file is as expected and ini_file 'changed' is true
+ assert:
+ that:
+ - result3 is changed
+ - result3.msg == 'section and option added'
+ - content3 == expected3
+
+
+- name: "test-values 4 - remove option 'fav=lemonade' from section '[drinks]' in specified file"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: fav
+ values:
+ - lemonade
+ state: absent
+ exclusive: false
+ register: result4
+
+- name: test-values 4 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-values 4 - set expected content and get current ini file content
+ set_fact:
+ expected4: |
+
+ [drinks]
+ fav = cocktail
+ content4: "{{ output_content.content | b64decode }}"
+
+- name: test-values 4 - Verify content of ini file is as expected and ini_file 'changed' is true
+ assert:
+ that:
+ - result4 is changed
+ - result4.msg == 'option changed'
+ - content4 == expected4
+
+
+- name: "test-values 5 - add option 'fav=lemonade' in section '[drinks]' in specified file"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: fav
+ values:
+ - lemonade
+ state: present
+ exclusive: false
+ register: result5
+
+- name: test-values 5 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-values 5 - set expected content and get current ini file content
+ set_fact:
+ expected5: |
+
+ [drinks]
+ fav = cocktail
+ fav = lemonade
+ content5: "{{ output_content.content | b64decode }}"
+
+- name: test-values 5 - Verify content of ini file is as expected and ini_file 'changed' is true
+ assert:
+ that:
+ - result5 is changed
+ - result5.msg == 'option added'
+ - content5 == expected5
+
+
+- name: "test-values 6 - ensure 'fav=lemonade' and 'fav=cocktail' is 'present' in section '[drinks]' and check for idempotency"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: fav
+ values:
+ - lemonade
+ - cocktail
+ state: present
+ register: result6
+
+- name: test-values 6 - Ensure unchanged
+ assert:
+ that:
+ - result6 is not changed
+ - result6.msg == 'OK'
+
+
+- name: "test-values 7 - ensure 'fav=cocktail' and 'fav=lemonade' (list reverse order) is 'present' in section '[drinks]' and check for idempotency"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: fav
+ values:
+ - cocktail
+ - lemonade
+ state: present
+ register: result7
+
+- name: test-values 7 - Ensure unchanged
+ assert:
+ that:
+ - result7 is not changed
+ - result7.msg == 'OK'
+
+
+- name: "test-values 8 - add option 'fav=lemonade' in section '[drinks]' again and ensure idempotency"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: fav
+ values:
+ - lemonade
+ state: present
+ exclusive: false
+ register: result8
+
+- name: test-values 8 - Ensure unchanged
+ assert:
+ that:
+ - result8 is not changed
+ - result8.msg == 'OK'
+
+
+- name: "test-values 9 - ensure only 'fav=lemonade' is 'present' in section '[drinks]' in specified file"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: fav
+ values:
+ - lemonade
+ state: present
+ register: result9
+
+- name: test-values 9 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-values 9 - set expected content and get current ini file content
+ set_fact:
+ expected9: |
+
+ [drinks]
+ fav = lemonade
+ content9: "{{ output_content.content | b64decode }}"
+
+- name: test-values 9 - Verify content of ini file is as expected and ini_file 'changed' is true
+ assert:
+ that:
+ - result9 is changed
+ - result9.msg == 'option changed'
+ - content9 == expected9
+
+
+- name: "test-values 10 - remove non-existent 'fav=cocktail' from section '[drinks]' in specified file"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: fav
+ values:
+ - cocktail
+ state: absent
+ register: result10
+
+- name: test-values 10 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-values 10 - set expected content and get current ini file content
+ set_fact:
+ expected10: |
+
+ [drinks]
+ content10: "{{ output_content.content | b64decode }}"
+
+
+- name: test-values 10 - Ensure unchanged
+ assert:
+ that:
+ - result10 is changed
+ - result10.msg == 'option changed'
+ - content10 == expected10
+
+
+- name: "test-values 11 - Ensure 'fav=lemonade' and 'beverage=coke' is 'present' in section '[drinks]'"
+ block:
+ - name: "test-values 11 - resetting ini_fie: Ensure 'fav=lemonade' is 'present' in section '[drinks]'"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: fav
+ values:
+ - lemonade
+ state: present
+ - name: "test-values 11 - Ensure 'beverage=coke' is 'present' in section '[drinks]'"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: beverage
+ values:
+ - coke
+ state: present
+ register: result11
+
+- name: test-values 11 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-values 11 - set expected content and get current ini file content
+ set_fact:
+ expected11: |
+
+ [drinks]
+ fav = lemonade
+ beverage = coke
+ content11: "{{ output_content.content | b64decode }}"
+
+- name: test-values 11 - assert 'changed' is true and content is OK
+ assert:
+ that:
+ - result11 is changed
+ - result11.msg == 'option added'
+ - content11 == expected11
+
+
+- name: "test-values 12 - add option 'fav=lemonade' in section '[drinks]' again and ensure idempotency"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: fav
+ values:
+ - lemonade
+ state: present
+ exclusive: false
+ register: result12
+
+- name: test-values 12 - Ensure unchanged
+ assert:
+ that:
+ - result12 is not changed
+ - result12.msg == 'OK'
+
+
+- name: "test-values 13 - add option 'fav=cocktail' in section '[drinks]' in specified file"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: fav
+ values:
+ - cocktail
+ state: present
+ exclusive: false
+ register: result13
+
+- name: test-values 13 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-values 13 - set expected content and get current ini file content
+ set_fact:
+ expected13: |
+
+ [drinks]
+ fav = lemonade
+ beverage = coke
+ fav = cocktail
+ content13: "{{ output_content.content | b64decode }}"
+
+- name: test-values 13 - Verify content of ini file is as expected and ini_file 'changed' is true
+ assert:
+ that:
+ - result13 is changed
+ - result13.msg == 'option added'
+ - content13 == expected13
+
+
+- name: "test-values 14 - Ensure 'refreshment=[water, juice, soft drink]' is 'present' in section '[drinks]'"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: refreshment
+ values:
+ - water
+ - juice
+ - soft drink
+ state: present
+ register: result14
+
+- name: test-values 14 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-values 14 - set expected content and get current ini file content
+ set_fact:
+ expected14: |
+
+ [drinks]
+ fav = lemonade
+ beverage = coke
+ fav = cocktail
+ refreshment = water
+ refreshment = juice
+ refreshment = soft drink
+ content14: "{{ output_content.content | b64decode }}"
+
+- name: test-values 14 - assert 'changed' is true and content is OK
+ assert:
+ that:
+ - result14 is changed
+ - result14.msg == 'option added'
+ - content14 == expected14
+
+
+- name: "test-values 15 - ensure 'fav=lemonade' and 'fav=cocktail' is 'present' in section '[drinks]' and check for idempotency"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: fav
+ values:
+ - lemonade
+ - cocktail
+ state: present
+ register: result15
+
+- name: test-values 15 - Ensure unchanged
+ assert:
+ that:
+ - result15 is not changed
+ - result15.msg == 'OK'
+
+
+- name: "test-values 16 - ensure 'fav=cocktail' and 'fav=lemonade' (list reverse order) is 'present' in section '[drinks]' and check for idempotency"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: fav
+ values:
+ - cocktail
+ - lemonade
+ state: present
+ register: result16
+
+- name: test-values 16 - Ensure unchanged
+ assert:
+ that:
+ - result16 is not changed
+ - result16.msg == 'OK'
+
+
+- name: "test-values 17 - Ensure option 'refreshment' is 'absent' in section '[drinks]'"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: refreshment
+ state: absent
+ register: result17
+
+- name: test-values 17 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-values 17 - set expected content and get current ini file content
+ set_fact:
+ expected17: |
+
+ [drinks]
+ fav = lemonade
+ beverage = coke
+ fav = cocktail
+ content17: "{{ output_content.content | b64decode }}"
+
+- name: test-values 17 - assert 'changed' is true and content is as expected
+ assert:
+ that:
+ - result17 is changed
+ - result17.msg == 'option changed'
+ - content17 == expected17
+
+
+- name: "test-values 18 - Ensure 'beverage=coke' is 'absent' in section '[drinks]'"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: beverage
+ state: absent
+ register: result18
+
+- name: test-values 18 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-values 18 - set expected content and get current ini file content
+ set_fact:
+ expected18: |
+
+ [drinks]
+ fav = lemonade
+ fav = cocktail
+ content18: "{{ output_content.content | b64decode }}"
+
+- name: test-values 18 - assert 'changed' is true and content is as expected
+ assert:
+ that:
+ - result18 is changed
+ - result18.msg == 'option changed'
+ - content18 == expected18
+
+
+- name: "test-values 19 - Ensure non-existent 'beverage=coke' is 'absent' in section '[drinks]'"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: beverage
+ values:
+ - coke
+ state: absent
+ register: result19
+
+- name: test-values 19 - Ensure unchanged
+ assert:
+ that:
+ - result19 is not changed
+ - result19.msg == 'OK'
+
+
+- name: test-values 20 - remove section 'drinks'
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ state: absent
+ register: result20
+
+- name: test-values 20 - remove section 'drinks' again to ensure idempotency"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ state: absent
+ register: result20_remove_again
+
+- name: test-values 20 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-values 20 - get current ini file content
+ set_fact:
+ content20: "{{ output_content.content | b64decode }}"
+
+- name: test-values 20 - assert 'changed' is true and content is empty
+ assert:
+ that:
+ - result20 is changed
+ - result20_remove_again is not changed
+ - result20.msg == 'section removed'
+ - content20 == "\n"
+
+
+- name: "test-values 21 - Ensure 'refreshment=[water, juice, soft drink, juice]' (duplicates removed) is 'present' in section '[drinks]'"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: refreshment
+ values:
+ - water
+ - juice
+ - soft drink
+ - juice
+ state: present
+ register: result21
+
+- name: test-values 21 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-values 21 - set expected content and get current ini file content
+ set_fact:
+ expected21: |
+
+ [drinks]
+ refreshment = water
+ refreshment = juice
+ refreshment = soft drink
+ content21: "{{ output_content.content | b64decode }}"
+
+- name: test-values 21 - assert 'changed' is true and content is OK
+ assert:
+ that:
+ - result21 is changed
+ - result21.msg == 'section and option added'
+ - content21 == expected21
+
+
+- name: test-values 22 - Create starting ini file
+ copy:
+ content: |
+
+ # Some comment to test
+ [mysqld]
+ connect_timeout = 300
+ max_connections = 1000
+ [section1]
+ var1 = aaa
+ # comment in section
+ # var2 = some value
+ # comment after section
+
+ [section2]
+ var3 = ccc
+ # comment after section
+ dest: "{{ output_file }}"
+
+- name: "test-values 22 - Ensure 'skip-name' with 'allow_no_value' is 'present' in section '[mysqld]' test allow_no_value"
+ ini_file:
+ path: "{{ output_file }}"
+ section: mysqld
+ option: skip-name
+ allow_no_value: true
+ state: present
+ register: result22
+
+- name: test-values 22 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-values 22 - set expected content and get current ini file content
+ set_fact:
+ expected22: |
+
+ # Some comment to test
+ [mysqld]
+ connect_timeout = 300
+ max_connections = 1000
+ skip-name
+ [section1]
+ var1 = aaa
+ # comment in section
+ # var2 = some value
+ # comment after section
+
+ [section2]
+ var3 = ccc
+ # comment after section
+ content22: "{{ output_content.content | b64decode }}"
+
+- name: test-values 22 - assert 'changed' is true and content is OK and option added
+ assert:
+ that:
+ - result22 is changed
+ - result22.msg == 'option added'
+ - content22 == expected22
+
+
+- name: "test-values 23 - Ensure 'var2=foo' is 'present' in section '[section1]', replacing commented option 'var2=some value'"
+ ini_file:
+ path: "{{ output_file }}"
+ section: section1
+ option: var2
+ values:
+ - foo
+ state: present
+ register: result23
+
+- name: test-values 23 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-values 23 - set expected content and get current ini file content
+ set_fact:
+ expected23: |
+
+ # Some comment to test
+ [mysqld]
+ connect_timeout = 300
+ max_connections = 1000
+ skip-name
+ [section1]
+ var1 = aaa
+ # comment in section
+ var2 = foo
+ # comment after section
+
+ [section2]
+ var3 = ccc
+ # comment after section
+ content23: "{{ output_content.content | b64decode }}"
+
+- name: test-values 23 - assert 'changed' and msg 'option changed' and content is as expected
+ assert:
+ that:
+ - result23 is changed
+ - result23.msg == 'option changed'
+ - content23 == expected23
+
+
+- name: "test-values 24 - Ensure 'var2=[foo, foobar]' is 'present' in section '[section1]'"
+ ini_file:
+ path: "{{ output_file }}"
+ section: section1
+ option: var2
+ values:
+ - foo
+ - foobar
+ state: present
+ register: result24
+
+- name: test-values 24 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-values 24 - set expected content and get current ini file content
+ set_fact:
+ expected24: |
+
+ # Some comment to test
+ [mysqld]
+ connect_timeout = 300
+ max_connections = 1000
+ skip-name
+ [section1]
+ var1 = aaa
+ # comment in section
+ var2 = foo
+ var2 = foobar
+ # comment after section
+
+ [section2]
+ var3 = ccc
+ # comment after section
+ content24: "{{ output_content.content | b64decode }}"
+
+- name: test-values 24 - assert 'changed' and msg 'option added' and content is as expected
+ assert:
+ that:
+ - result24 is changed
+ - result24.msg == 'option added'
+ - content24 == expected24
+
+
+- name: test-values 25 - Clean test file
+ copy:
+ content: ""
+ dest: "{{ output_file }}"
+ force: true
+
+- name: "test-values 25 - Ensure 'beverage=[coke, pepsi]' is created within no section"
+ ini_file:
+ section:
+ path: "{{ output_file }}"
+ option: beverage
+ values:
+ - coke
+ - pepsi
+ state: present
+ register: result25
+
+- name: test-values 25 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-values 25 - set expected content and get current ini file content
+ set_fact:
+ expected25: |+
+ beverage = coke
+ beverage = pepsi
+
+ content25: "{{ output_content.content | b64decode }}"
+
+- name: test-values 25 - assert 'changed' is true and content is OK (no section)
+ assert:
+ that:
+ - result25 is changed
+ - result25.msg == 'option added'
+ - content25 == expected25
+
+
+- name: "test-values 26 - Ensure 'beverage=coke' and 'beverage=pepsi' are modified within no section"
+ ini_file:
+ path: "{{ output_file }}"
+ option: beverage
+ values:
+ - water
+ - orange juice
+ section:
+ state: present
+ exclusive: true
+ register: result26
+
+- name: test-values 26 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-values 26 - set expected content and get current ini file content
+ set_fact:
+ expected26: |+
+ beverage = water
+ beverage = orange juice
+
+ content26: "{{ output_content.content | b64decode }}"
+
+- name: test-values 26 - assert 'changed' is true and content is OK (no section)
+ assert:
+ that:
+ - result26 is changed
+ - result26.msg == 'option changed'
+ - content26 == expected26
+
+
+- name: "test-values 27 - ensure option 'beverage' is 'absent' within no section"
+ ini_file:
+ section:
+ path: "{{ output_file }}"
+ option: beverage
+ state: absent
+ register: result27
+
+- name: test-values 27 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-values 27 - get current ini file content
+ set_fact:
+ content27: "{{ output_content.content | b64decode }}"
+
+- name: test-values 27 - assert changed (no section)
+ assert:
+ that:
+ - result27 is changed
+ - result27.msg == 'option changed'
+ - content27 == "\n"
+
+
+- name: "test-values 28 - Ensure option 'present' without section before existing section"
+ block:
+ - name: test-values 28 - ensure option present within section
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: beverage
+ values:
+ - water
+ - orange juice
+ state: present
+
+ - name: test-values 28 - ensure option present without section
+ ini_file:
+ path: "{{ output_file }}"
+ section:
+ option: like
+ values:
+ - tea
+ - coffee
+ state: present
+
+- name: test-values 28 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-values 28 - set expected content and get current ini file content
+ set_fact:
+ expected28: |
+ like = tea
+ like = coffee
+
+ [drinks]
+ beverage = water
+ beverage = orange juice
+ content28: "{{ output_content.content | b64decode }}"
+
+- name: test-values 28 - Verify content of ini file is as expected
+ assert:
+ that:
+ - content28 == expected28
+
+
+- name: test-value 29 - Create starting ini file
+ copy:
+ content: |
+ [drinks]
+ fav = cocktail
+ beverage = water
+ fav = lemonade
+ beverage = orange juice
+ dest: "{{ output_file }}"
+
+- name: "test-value 29 - Test 'state=absent' with 'exclusive=true' with multiple options in ini_file"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: fav
+ values:
+ - cocktail
+ state: absent
+ register: result29
+
+- name: test-value 29 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-value 29 - set expected content and get current ini file content
+ set_fact:
+ expected29: |
+ [drinks]
+ beverage = water
+ beverage = orange juice
+ content29: "{{ output_content.content | b64decode }}"
+
+- name: test-value 29 - Verify content of ini file is as expected
+ assert:
+ that:
+ - result29 is changed
+ - result29.msg == 'option changed'
+ - content29 == expected29
+
+
+- name: test-value 30 - Create starting ini file
+ copy:
+ content: |
+ [drinks]
+ fav = cocktail
+ beverage = water
+ fav = lemonade
+ beverage = orange juice
+ dest: "{{ output_file }}"
+
+- name: "test-value 30 - Test 'state=absent' with 'exclusive=false' with multiple options in ini_file"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: fav
+ values:
+ - cocktail
+ state: absent
+ exclusive: false
+ register: result30
+
+- name: test-value 30 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-value 30 - set expected content and get current ini file content
+ set_fact:
+ expected30: |
+ [drinks]
+ beverage = water
+ fav = lemonade
+ beverage = orange juice
+ content30: "{{ output_content.content | b64decode }}"
+
+- name: test-value 30 - Verify content of ini file is as expected
+ assert:
+ that:
+ - result30 is changed
+ - result30.msg == 'option changed'
+ - content30 == expected30
+
+
+- name: test-value 31 - Create starting ini file
+ copy:
+ content: |
+ [drinks]
+ fav = cocktail
+ beverage = water
+ fav = lemonade
+ beverage = orange juice
+ dest: "{{ output_file }}"
+
+- name: "test-value 31 - Test 'state=absent' with 'exclusive=true' and no value given with multiple options in ini_file"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: fav
+ state: absent
+ register: result31
+
+- name: test-value 31 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-value 31 - set expected content and get current ini file content
+ set_fact:
+ expected31: |
+ [drinks]
+ beverage = water
+ beverage = orange juice
+ content31: "{{ output_content.content | b64decode }}"
+
+- name: test-value 31 - Verify content of ini file is as expected
+ assert:
+ that:
+ - result31 is changed
+ - result31.msg == 'option changed'
+ - content31 == expected31
+
+
+- name: test-value 32 - Create starting ini file
+ copy:
+ content: |
+ [drinks]
+ fav = cocktail
+ beverage = water
+ fav = lemonade
+ beverage = orange juice
+ dest: "{{ output_file }}"
+
+- name: "test-value 32 - Test 'state=absent' with 'exclusive=false' and no value given with multiple options in ini_file"
+ ini_file:
+ path: "{{ output_file }}"
+ section: drinks
+ option: fav
+ state: absent
+ exclusive: false
+ register: result32
+ diff: true
+
+- name: test-value 32 - read content from output file
+ slurp:
+ src: "{{ output_file }}"
+ register: output_content
+
+- name: test-value 32 - set expected content and get current ini file content
+ set_fact:
+ expected32: |
+ [drinks]
+ fav = cocktail
+ beverage = water
+ fav = lemonade
+ beverage = orange juice
+ content32: "{{ output_content.content | b64decode }}"
+
+- name: test-value 32 - Verify content of ini file is as expected
+ assert:
+ that:
+ - result32 is not changed
+ - result32.msg == 'OK'
+ - content32 == expected32
diff --git a/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/03-encoding.yml b/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/03-encoding.yml
new file mode 100644
index 000000000..555dd576c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ini_file/tasks/tests/03-encoding.yml
@@ -0,0 +1,44 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Regression test for https://github.com/ansible-collections/community.general/pull/2578#issuecomment-868092282
+- name: Create UTF-8 test file
+ copy:
+ content: !!binary |
+ W2FwcDptYWluXQphdmFpbGFibGVfbGFuZ3VhZ2VzID0gZW4gZnIgZXMgZGUgcHQgamEgbHQgemhf
+ VFcgaWQgZGEgcHRfQlIgcnUgc2wgaXQgbmxfTkwgdWsgdGEgc2kgY3MgbmIgaHUKIyBGdWxsIGxh
+ bmd1YWdlIG5hbWVzIGluIG5hdGl2ZSBsYW5ndWFnZSAoY29tbWEgc2VwYXJhdGVkKQphdmFpbGFi
+ bGVfbGFuZ3VhZ2VzX2Z1bGwgPSBFbmdsaXNoLCBGcmFuw6dhaXMsIEVzcGHDsW9sLCBEZXV0c2No
+ LCBQb3J0dWd1w6pzLCDml6XmnKzoqp4sIExpZXR1dm9zLCDkuK3mlocsIEluZG9uZXNpYSwgRGFu
+ c2ssIFBvcnR1Z3XDqnMgKEJyYXNpbCksINCg0YPRgdGB0LrQuNC5LCBTbG92ZW7FocSNaW5hLCBJ
+ dGFsaWFubywgTmVkZXJsYW5kcywg0KPQutGA0LDRl9C90YHRjNC60LAsIOCupOCuruCuv+CutOCv
+ jSwg4LeD4LeS4LaC4LeE4La9LCDEjGVza3ksIEJva23DpWwsIE1hZ3lhcgo=
+ dest: '{{ output_file }}'
+- name: Add entries
+ ini_file:
+ section: "{{ item.section }}"
+ option: "{{ item.option }}"
+ value: "{{ item.value }}"
+ path: '{{ output_file }}'
+ create: true
+ loop:
+ - section: app:main
+ option: sqlalchemy.url
+ value: postgresql://app:secret@database/app
+ - section: handler_filelog
+ option: args
+ value: (sys.stderr,)
+ - section: handler_filelog
+ option: class
+ value: StreamHandler
+ - section: handler_exc_handler
+ option: args
+ value: (sys.stderr,)
+ - section: båz
+ option: fföø
+ value: ḃâŗ
+ - section: båz
+ option: fföø
+ value: bar
diff --git a/ansible_collections/community/general/tests/integration/targets/interfaces_file/aliases b/ansible_collections/community/general/tests/integration/targets/interfaces_file/aliases
new file mode 100644
index 000000000..12d1d6617
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/interfaces_file/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
diff --git a/ansible_collections/community/general/tests/integration/targets/interfaces_file/files/interfaces_ff b/ansible_collections/community/general/tests/integration/targets/interfaces_file/files/interfaces_ff
new file mode 100644
index 000000000..c7f0452df
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/interfaces_file/files/interfaces_ff
@@ -0,0 +1,11 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+iface eno1 inet static
+ address 1.2.3.4
+ netmask 255.255.255.0
+ gateway 1.2.3.1
+ up route add -net 1.2.3.4 netmask 255.255.255.0 gw 1.2.3.1 eno1
+ up ip addr add 4.3.2.1/32 dev eno1
+ down ip addr add 4.3.2.1/32 dev eno1
diff --git a/ansible_collections/community/general/tests/integration/targets/interfaces_file/files/interfaces_ff_3841 b/ansible_collections/community/general/tests/integration/targets/interfaces_file/files/interfaces_ff_3841
new file mode 100644
index 000000000..9f47879c5
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/interfaces_file/files/interfaces_ff_3841
@@ -0,0 +1,11 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+iface eth0 inet static
+ address 1.2.3.4
+ netmask 255.255.255.0
+ gateway 1.2.3.1
+ up route add -net 1.2.3.4 netmask 255.255.255.0 gw 1.2.3.1 eth0
+ up ip addr add 4.3.2.1/32 dev eth0
+ down ip addr add 4.3.2.1/32 dev eth0
diff --git a/ansible_collections/community/general/tests/integration/targets/interfaces_file/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/interfaces_file/meta/main.yml
new file mode 100644
index 000000000..982de6eb0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/interfaces_file/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/interfaces_file/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/interfaces_file/tasks/main.yml
new file mode 100644
index 000000000..918a32331
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/interfaces_file/tasks/main.yml
@@ -0,0 +1,67 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name:
+ set_fact:
+ interfaces_testfile: '{{ remote_tmp_dir }}/interfaces'
+ interfaces_testfile_3841: '{{ remote_tmp_dir }}/interfaces_3841'
+
+- name: Copy interfaces file
+ copy:
+ src: 'files/interfaces_ff'
+ dest: '{{ interfaces_testfile }}'
+
+- name: Change IP address to 1.2.3.5
+ community.general.interfaces_file:
+ dest: "{{ interfaces_testfile }}"
+ iface: eno1
+ option: address
+ value: 1.2.3.5
+ register: ifile_1
+
+- assert:
+ that:
+ - ifile_1 is changed
+
+- name: Change IP address to 1.2.3.5 again
+ community.general.interfaces_file:
+ dest: "{{ interfaces_testfile }}"
+ iface: eno1
+ option: address
+ value: 1.2.3.5
+ register: ifile_2
+
+- assert:
+ that:
+ - ifile_2 is not changed
+
+- name: 3841 - copy interfaces file
+ copy:
+ src: 'files/interfaces_ff_3841'
+ dest: '{{ interfaces_testfile_3841 }}'
+
+- name: 3841 - floating_ip_interface_up_ip 2a01:a:b:c::1/64 dev eth0
+ interfaces_file:
+ option: up
+ iface: eth0
+ dest: "{{ interfaces_testfile_3841 }}"
+ value: 'ip addr add 2a01:a:b:c::1/64 dev eth0'
+ state: present
+ register: ifile_3841_a
+
+- name: 3841 - floating_ip_interface_up_ip 2a01:a:b:c::1/64 dev eth0 (again)
+ interfaces_file:
+ option: up
+ iface: eth0
+ dest: "{{ interfaces_testfile_3841 }}"
+ value: 'ip addr add 2a01:a:b:c::1/64 dev eth0'
+ state: present
+ register: ifile_3841_b
+
+- name: 3841 - check assertions
+ assert:
+ that:
+ - ifile_3841_a is changed
+ - ifile_3841_b is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/ipify_facts/aliases b/ansible_collections/community/general/tests/integration/targets/ipify_facts/aliases
new file mode 100644
index 000000000..12d1d6617
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ipify_facts/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
diff --git a/ansible_collections/community/general/tests/integration/targets/ipify_facts/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/ipify_facts/tasks/main.yml
new file mode 100644
index 000000000..78e44e946
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ipify_facts/tasks/main.yml
@@ -0,0 +1,33 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Test code for the ipify_facts
+# Copyright (c) 2017, Abhijeet Kasurde <akasurde@redhat.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- debug: var=ansible_distribution
+- debug: var=ansible_distribution_version
+
+- set_fact:
+ validate_certs: false
+ when: (ansible_distribution == "MacOSX" and ansible_distribution_version == "10.11.1")
+
+- name: get information about current IP using ipify facts
+ ipify_facts:
+ timeout: 30
+ validate_certs: "{{ validate_certs }}"
+ register: external_ip
+ until: external_ip is successful
+ retries: 5
+ delay: 10
+
+- name: check if task was successful
+ assert:
+ that:
+ - external_ip is not changed
+ - external_ip.ansible_facts is defined
+ - external_ip.ansible_facts.ipify_public_ip is defined
diff --git a/ansible_collections/community/general/tests/integration/targets/ipify_facts/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/ipify_facts/vars/main.yml
new file mode 100644
index 000000000..3a47dfea8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ipify_facts/vars/main.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+validate_certs: true
diff --git a/ansible_collections/community/general/tests/integration/targets/iptables_state/aliases b/ansible_collections/community/general/tests/integration/targets/iptables_state/aliases
new file mode 100644
index 000000000..5a02a630b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iptables_state/aliases
@@ -0,0 +1,12 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+azp/posix/vm
+destructive
+skip/docker # kernel modules not loadable
+skip/freebsd # no iptables/netfilter (Linux specific)
+skip/osx # no iptables/netfilter (Linux specific)
+skip/macos # no iptables/netfilter (Linux specific)
+skip/aix # no iptables/netfilter (Linux specific)
diff --git a/ansible_collections/community/general/tests/integration/targets/iptables_state/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/iptables_state/meta/main.yml
new file mode 100644
index 000000000..2fcd152f9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iptables_state/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
diff --git a/ansible_collections/community/general/tests/integration/targets/iptables_state/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/iptables_state/tasks/main.yml
new file mode 100644
index 000000000..a74e74df4
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iptables_state/tasks/main.yml
@@ -0,0 +1,38 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: ensure iptables package is installed
+ package:
+ name:
+ - iptables
+ become: true
+
+
+- name: include tasks
+ vars:
+ iptables_saved: "/tmp/test_iptables_state.saved"
+ iptables_tests: "/tmp/test_iptables_state.tests"
+
+ block:
+ - name: include tasks to perform basic tests (check_mode, async, idempotency)
+ include_tasks: tests/00-basic.yml
+
+ - name: include tasks to test tables handling
+ include_tasks: tests/01-tables.yml
+ when:
+ - xtables_lock is undefined
+
+ - name: include tasks to test rollbacks
+ include_tasks: tests/10-rollback.yml
+ when:
+ - xtables_lock is undefined
+ - ansible_connection in ['ssh', 'paramiko', 'smart']
+
+ become: true
diff --git a/ansible_collections/community/general/tests/integration/targets/iptables_state/tasks/tests/00-basic.yml b/ansible_collections/community/general/tests/integration/targets/iptables_state/tasks/tests/00-basic.yml
new file mode 100644
index 000000000..7b366edce
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iptables_state/tasks/tests/00-basic.yml
@@ -0,0 +1,320 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: "ensure our next backup is not there (file)"
+ file:
+ path: "{{ iptables_saved }}"
+ state: absent
+
+- name: "ensure our next rule is not there (iptables)"
+ iptables:
+ chain: OUTPUT
+ jump: ACCEPT
+ state: absent
+
+
+#
+# Basic checks about invalid param/value handling.
+#
+- name: "trigger error about invalid param"
+ iptables_state:
+ name: foobar
+ register: iptables_state
+ ignore_errors: true
+
+- name: "assert that results are as expected"
+ assert:
+ that:
+ - iptables_state is failed
+ - iptables_state.msg is match("Invalid options")
+ quiet: true
+
+
+
+- name: "trigger error about missing param 'state'"
+ iptables_state:
+ path: foobar
+ register: iptables_state
+ ignore_errors: true
+
+- name: "assert that results are as expected"
+ assert:
+ that:
+ - iptables_state is failed
+ - iptables_state.msg is match("missing required arguments")
+ quiet: true
+
+
+
+- name: "trigger error about missing param 'path'"
+ iptables_state:
+ state: saved
+ register: iptables_state
+ ignore_errors: true
+
+- name: "assert that results are as expected"
+ assert:
+ that:
+ - iptables_state is failed
+ - iptables_state.msg is match("missing required arguments")
+ quiet: true
+
+
+
+- name: "trigger error about invalid value for param 'state'"
+ iptables_state:
+ path: foobar
+ state: present
+ register: iptables_state
+ ignore_errors: true
+
+- name: "assert that results are as expected"
+ assert:
+ that:
+ - iptables_state is failed
+ - iptables_state.msg is match("value of state must be one of")
+ quiet: true
+
+
+#
+# Play with the current state first. We will create a file to store it in, but
+# no more. These tests are for:
+# - idempotency
+# - check_mode
+#
+- name: "save state (check_mode, must report a change)"
+ iptables_state:
+ path: "{{ iptables_saved }}"
+ state: saved
+ register: iptables_state
+ check_mode: true
+
+- name: "assert that results are as expected"
+ assert:
+ that:
+ - iptables_state is changed
+ - iptables_state.initial_state == iptables_state.saved
+ quiet: true
+
+
+
+- name: "save state (must report a change)"
+ iptables_state:
+ path: "{{ iptables_saved }}"
+ state: saved
+ register: iptables_state
+
+- name: "assert that results are as expected"
+ assert:
+ that:
+ - iptables_state is changed
+ - iptables_state.initial_state == iptables_state.saved
+ quiet: true
+
+
+
+- name: "save state (idempotency, must NOT report a change)"
+ iptables_state:
+ path: "{{ iptables_saved }}"
+ state: saved
+ register: iptables_state
+
+- name: "assert that results are as expected"
+ assert:
+ that:
+ - iptables_state is not changed
+ - iptables_state.initial_state == iptables_state.saved
+ quiet: true
+
+
+
+- name: "save state (check_mode, must NOT report a change)"
+ iptables_state:
+ path: "{{ iptables_saved }}"
+ state: saved
+ register: iptables_state
+ check_mode: true
+
+- name: "assert that results are as expected"
+ assert:
+ that:
+ - iptables_state is not changed
+ - iptables_state.initial_state == iptables_state.saved
+ quiet: true
+
+
+
+# We begin with 'state=restored' by restoring the current state on itself.
+# This at least ensures the file produced with state=saved is suitable for
+# state=restored.
+
+- name: "state=restored check_mode=true changed=false"
+ block:
+ - name: "restore state (check_mode, must NOT report a change, no warning)"
+ iptables_state:
+ path: "{{ iptables_saved }}"
+ state: restored
+ register: iptables_state
+ check_mode: true
+
+ - name: "assert that results are as expected"
+ assert:
+ that:
+ - iptables_state is not changed
+ - iptables_state.initial_state == iptables_state.restored
+ quiet: true
+
+ rescue:
+ - name: "assert that results are not as expected for only one reason (xtables lock)"
+ assert:
+ that:
+ - iptables_state is failed
+ - iptables_state.stderr is search('xtables lock')
+ quiet: true
+ register: xtables_lock
+
+
+
+- name: "state=restored changed=false"
+ block:
+ - name: "restore state (must NOT report a change, warning about rollback & async)"
+ iptables_state:
+ path: "{{ iptables_saved }}"
+ state: restored
+ register: iptables_state
+
+ - name: "assert that results are as expected"
+ assert:
+ that:
+ - iptables_state is not changed
+ - iptables_state.initial_state == iptables_state.restored
+ quiet: true
+
+ rescue:
+ - name: "assert that results are not as expected for only one reason (xtables lock)"
+ assert:
+ that:
+ - iptables_state is failed
+ - iptables_state.stderr is search('xtables lock')
+ quiet: true
+ register: xtables_lock
+
+
+
+- name: "change iptables state (iptables)"
+ iptables:
+ chain: OUTPUT
+ jump: ACCEPT
+
+
+
+- name: "state=restored changed=true"
+ block:
+ - name: "restore state (check_mode, must report a change)"
+ iptables_state:
+ path: "{{ iptables_saved }}"
+ state: restored
+ register: iptables_state
+ check_mode: true
+
+ - name: "assert that results are as expected"
+ assert:
+ that:
+ - iptables_state is changed
+ - iptables_state.initial_state != iptables_state.restored
+ quiet: true
+
+ rescue:
+ - name: "assert that results are not as expected for only one reason (xtables lock)"
+ assert:
+ that:
+ - iptables_state is failed
+ - iptables_state.stderr is search('xtables lock')
+ quiet: true
+ register: xtables_lock
+
+
+
+- name: "state=restored changed=true"
+ block:
+ - name: "restore state (must report a change, async, no warning)"
+ iptables_state:
+ path: "{{ iptables_saved }}"
+ state: restored
+ register: iptables_state
+ async: "{{ ansible_timeout }}"
+ poll: 0
+
+ - name: "assert that results are as expected"
+ assert:
+ that:
+ - iptables_state is changed
+ - iptables_state.initial_state != iptables_state.restored
+ - iptables_state.applied
+ quiet: true
+
+ rescue:
+ - name: "assert that results are not as expected for only one reason (xtables lock)"
+ assert:
+ that:
+ - iptables_state is failed
+ - iptables_state.stderr is search('xtables lock')
+ quiet: true
+ register: xtables_lock
+
+
+
+- name: "state=restored changed=false"
+ block:
+ - name: "restore state (must NOT report a change, async, no warning)"
+ iptables_state:
+ path: "{{ iptables_saved }}"
+ state: restored
+ register: iptables_state
+ async: "{{ ansible_timeout }}"
+ poll: 0
+
+ - name: "assert that results are as expected"
+ assert:
+ that:
+ - iptables_state is not changed
+ - iptables_state.initial_state == iptables_state.restored
+ quiet: true
+
+ rescue:
+ - name: "assert that results are not as expected for only one reason (xtables lock)"
+ assert:
+ that:
+ - iptables_state is failed
+ - iptables_state.stderr is search('xtables lock')
+ quiet: true
+ register: xtables_lock
+
+
+
+- name: "state=restored changed=false"
+ block:
+ - name: "restore state (check_mode=yes, must NOT report a change, no warning)"
+ iptables_state:
+ path: "{{ iptables_saved }}"
+ state: restored
+ register: iptables_state
+ check_mode: true
+
+ - name: "assert that results are as expected"
+ assert:
+ that:
+ - iptables_state is not changed
+ - iptables_state.initial_state == iptables_state.restored
+ quiet: true
+
+ rescue:
+ - name: "assert that results are not as expected for only one reason (xtables lock)"
+ assert:
+ that:
+ - iptables_state is failed
+ - iptables_state.stderr is search('xtables lock')
+ quiet: true
+ register: xtables_lock
diff --git a/ansible_collections/community/general/tests/integration/targets/iptables_state/tasks/tests/01-tables.yml b/ansible_collections/community/general/tests/integration/targets/iptables_state/tasks/tests/01-tables.yml
new file mode 100644
index 000000000..8a9869c43
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iptables_state/tasks/tests/01-tables.yml
@@ -0,0 +1,294 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: "ensure our next rule is not there (iptables)"
+ iptables:
+ table: nat
+ chain: INPUT
+ jump: ACCEPT
+ state: absent
+
+- name: "get state (table filter)"
+ iptables_state:
+ table: filter
+ state: saved
+ path: "{{ iptables_saved }}"
+ register: iptables_state
+ changed_when: false
+ check_mode: true
+
+- name: "assert that results are as expected"
+ assert:
+ that:
+ - "'*filter' in iptables_state.initial_state"
+ - iptables_state.tables.filter is defined
+ - iptables_state.tables.nat is undefined
+ quiet: true
+
+
+
+- name: "get state (table nat)"
+ iptables_state:
+ table: nat
+ state: saved
+ path: "{{ iptables_saved }}"
+ register: iptables_state
+ changed_when: false
+ check_mode: true
+
+- name: "assert that results are as expected"
+ assert:
+ that:
+ - "'*nat' in iptables_state.initial_state"
+ - "'*filter' in iptables_state.initial_state"
+ - iptables_state.tables.nat is defined
+ - iptables_state.tables.filter is undefined
+ quiet: true
+
+
+
+- name: "save state (table filter)"
+ iptables_state:
+ path: "{{ iptables_saved }}"
+ state: saved
+ table: filter
+ register: iptables_state
+
+- name: "assert that results are as expected"
+ assert:
+ that:
+ - "'*filter' in iptables_state.initial_state"
+ - "'*filter' in iptables_state.saved"
+ - "'*nat' in iptables_state.initial_state"
+ - "'*nat' not in iptables_state.saved"
+ - iptables_state.tables.filter is defined
+ - iptables_state.tables.nat is undefined
+ quiet: true
+
+
+
+- name: "save state (table nat)"
+ iptables_state:
+ path: "{{ iptables_saved }}"
+ state: saved
+ table: nat
+ register: iptables_state
+
+- name: "assert that results are as expected"
+ assert:
+ that:
+ - iptables_state is changed
+ - "'*nat' in iptables_state.initial_state"
+ - "'*nat' in iptables_state.saved"
+ - "'*filter' in iptables_state.initial_state"
+ - "'*filter' not in iptables_state.saved"
+ - iptables_state.tables.nat is defined
+ - iptables_state.tables.filter is undefined
+ quiet: true
+
+
+
+- name: "save state (any table)"
+ iptables_state:
+ path: "{{ iptables_saved }}"
+ state: saved
+ register: iptables_state
+
+- name: "assert that results are as expected"
+ assert:
+ that:
+ - iptables_state is changed
+ - "'*filter' in iptables_state.initial_state"
+ - "'*filter' in iptables_state.saved"
+ - "'*nat' in iptables_state.initial_state"
+ - "'*nat' in iptables_state.saved"
+ - iptables_state.tables.filter is defined
+ - iptables_state.tables.nat is defined
+ quiet: true
+
+
+
+- name: "restore state (table nat, must NOT report a change, no warning)"
+ iptables_state:
+ path: "{{ iptables_saved }}"
+ state: restored
+ table: nat
+ register: iptables_state
+ async: "{{ ansible_timeout }}"
+ poll: 0
+
+- name: "assert that results are as expected"
+ assert:
+ that:
+ - "'*nat' in iptables_state.initial_state"
+ - "'*nat' in iptables_state.restored"
+ - "'*filter' in iptables_state.initial_state"
+ - "'*filter' not in iptables_state.restored"
+ - iptables_state.tables.nat is defined
+ - iptables_state.tables.filter is undefined
+ - iptables_state is not changed
+ quiet: true
+
+
+
+- name: "change NAT table (iptables)"
+ iptables:
+ table: nat
+ chain: INPUT
+ jump: ACCEPT
+ state: present
+
+
+
+- name: "restore state (table nat, must report a change, no warning)"
+ iptables_state:
+ path: "{{ iptables_saved }}"
+ state: restored
+ table: nat
+ register: iptables_state
+ async: "{{ ansible_timeout }}"
+ poll: 0
+
+- name: "assert that results are as expected"
+ assert:
+ that:
+ - "'*nat' in iptables_state.initial_state"
+ - "'*nat' in iptables_state.restored"
+ - "'*filter' in iptables_state.initial_state"
+ - "'*filter' not in iptables_state.restored"
+ - iptables_state.tables.nat is defined
+ - "'-A INPUT -j ACCEPT' in iptables_state.tables.nat"
+ - "'-A INPUT -j ACCEPT' not in iptables_state.restored"
+ - iptables_state.tables.filter is undefined
+ - iptables_state is changed
+ quiet: true
+
+
+
+- name: "get raw and mangle tables states"
+ iptables_state:
+ path: "{{ iptables_saved }}"
+ state: saved
+ table: "{{ item }}"
+ loop:
+ - raw
+ - mangle
+ changed_when: false
+ check_mode: true
+
+
+
+- name: "save state (any table)"
+ iptables_state:
+ path: "{{ iptables_saved }}"
+ state: saved
+ register: iptables_state
+
+- name: "assert that results are as expected"
+ assert:
+ that:
+ - "'filter' in iptables_state.tables"
+ - "'*filter' in iptables_state.saved"
+ - "'mangle' in iptables_state.tables"
+ - "'*mangle' in iptables_state.saved"
+ - "'nat' in iptables_state.tables"
+ - "'*nat' in iptables_state.saved"
+ - "'raw' in iptables_state.tables"
+ - "'*raw' in iptables_state.saved"
+ quiet: true
+
+
+
+- name: "save filter table into a test file"
+ iptables_state:
+ path: "{{ iptables_tests }}"
+ table: filter
+ state: saved
+
+- name: "add a table header in comments (# *mangle)"
+ lineinfile:
+ path: "{{ iptables_tests }}"
+ line: "# *mangle"
+
+
+
+- name: "restore state (table filter, must NOT report a change, no warning)"
+ iptables_state:
+ path: "{{ iptables_tests }}"
+ table: filter
+ state: restored
+ register: iptables_state
+ async: "{{ ansible_timeout }}"
+ poll: 0
+
+- name: "assert that results are as expected"
+ assert:
+ that:
+ - "'*filter' in iptables_state.initial_state"
+ - "'*mangle' in iptables_state.initial_state"
+ - "'*nat' in iptables_state.initial_state"
+ - "'*raw' in iptables_state.initial_state"
+ - "'filter' in iptables_state.tables"
+ - "'mangle' not in iptables_state.tables"
+ - "'nat' not in iptables_state.tables"
+ - "'raw' not in iptables_state.tables"
+ - "'*filter' in iptables_state.restored"
+ - "'*mangle' not in iptables_state.restored"
+ - "'*nat' not in iptables_state.restored"
+ - "'*raw' not in iptables_state.restored"
+ - iptables_state is not changed
+ quiet: true
+
+
+
+- name: "restore state (any table, must NOT report a change, no warning)"
+ iptables_state:
+ path: "{{ iptables_tests }}"
+ state: restored
+ register: iptables_state
+ async: "{{ ansible_timeout }}"
+ poll: 0
+
+- name: "assert that results are as expected"
+ assert:
+ that:
+ - "'*filter' in iptables_state.initial_state"
+ - "'*mangle' in iptables_state.initial_state"
+ - "'*nat' in iptables_state.initial_state"
+ - "'*raw' in iptables_state.initial_state"
+ - "'filter' in iptables_state.tables"
+ - "'mangle' in iptables_state.tables"
+ - "'nat' in iptables_state.tables"
+ - "'raw' in iptables_state.tables"
+ - "'*filter' in iptables_state.restored"
+ - "'*mangle' in iptables_state.restored"
+ - "'*nat' in iptables_state.restored"
+ - "'*raw' in iptables_state.restored"
+ - iptables_state is not changed
+ quiet: true
+
+
+
+- name: "restore state (table mangle, must fail, no warning)"
+ iptables_state:
+ path: "{{ iptables_tests }}"
+ table: mangle
+ state: restored
+ register: iptables_state
+ async: "{{ ansible_timeout }}"
+ poll: 0
+ ignore_errors: true
+
+- name: "explain expected failure"
+ assert:
+ that:
+ - iptables_state is failed
+ - "iptables_state.msg == 'Table mangle to restore not defined in {{ iptables_tests }}'"
+ success_msg: >-
+ The previous error has been triggered by trying to restore a table
+ that is missing in the file provided to iptables-restore.
+ fail_msg: >-
+ The previous task should have failed due to a missing table (mangle)
+ in the file to restore iptables state from.
diff --git a/ansible_collections/community/general/tests/integration/targets/iptables_state/tasks/tests/10-rollback.yml b/ansible_collections/community/general/tests/integration/targets/iptables_state/tasks/tests/10-rollback.yml
new file mode 100644
index 000000000..53fdd3ca0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iptables_state/tasks/tests/10-rollback.yml
@@ -0,0 +1,203 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: "create a blocking ruleset with a DROP policy"
+ copy:
+ dest: "{{ iptables_tests }}"
+ content: |
+ *filter
+ :INPUT DROP
+ COMMIT
+
+
+
+- name: "restore state from the test file (check_mode, must report a change)"
+ iptables_state:
+ path: "{{ iptables_tests }}"
+ state: restored
+ register: iptables_state
+ check_mode: true
+
+- name: "assert that results are as expected"
+ assert:
+ that:
+ - iptables_state is changed
+
+
+
+- name: "fail to restore state from the test file"
+ block:
+ - name: "restore state from the test file (bad policies, expected error -> rollback)"
+ iptables_state:
+ path: "{{ iptables_tests }}"
+ state: restored
+ register: iptables_state
+ async: "{{ ansible_timeout }}"
+ poll: 0
+
+ rescue:
+ - name: "explain expected failure"
+ assert:
+ that:
+ - iptables_state is not changed
+ - not iptables_state.applied
+ success_msg: >-
+ The previous error has been triggered to test the rollback. If you
+ are there, it means that 1) connection has been lost right after the
+ bad rules have been restored; 2) a rollback happened, so the bad
+ rules are not applied, finally; 3) module failed because it didn't
+ reach the wanted state, but at least host is not lost !!!
+ fail_msg: >-
+ The previous error has been triggered but its results are not as
+ expected.
+
+- name: "check that the expected failure happened"
+ assert:
+ that:
+ - iptables_state is failed
+
+
+
+- name: "fail to restore state from the test file (again)"
+ block:
+ - name: "try again, with a higher timeout (bad policies, same expected error)"
+ iptables_state:
+ path: "{{ iptables_tests }}"
+ state: restored
+ register: iptables_state
+ async: "{{ ansible_timeout }}"
+ poll: 0
+ vars:
+ ansible_timeout: "{{ max_delay | d(300) }}"
+
+ rescue:
+ - name: "explain expected failure"
+ assert:
+ that:
+ - iptables_state is not changed
+ - not iptables_state.applied
+ success_msg: >-
+ The previous error has been triggered to test the rollback. If you
+ are there, it means that 1) connection has been lost right after the
+ bad rules have been restored; 2) a rollback happened, so the bad
+ rules are not applied, finally; 3) module failed because it didn't
+ reach the wanted state, but at least host is not lost !!!
+ fail_msg: >-
+ The previous error has been triggered but its results are not as
+ expected.
+
+- name: "check that the expected failure happened"
+ assert:
+ that:
+ - iptables_state is failed
+
+
+
+- name: "restore state from backup (must NOT report a change)"
+ iptables_state:
+ path: "{{ iptables_saved }}"
+ state: restored
+ register: iptables_state
+ async: "{{ ansible_timeout }}"
+ poll: 0
+
+- name: "assert that results are as expected"
+ assert:
+ that:
+ - iptables_state is not changed
+
+
+
+- name: "restore state from backup (mangle, must NOT report a change)"
+ iptables_state:
+ path: "{{ iptables_saved }}"
+ table: mangle
+ state: restored
+ register: iptables_state
+ async: "{{ ansible_timeout }}"
+ poll: 0
+
+- name: "assert that results are as expected"
+ assert:
+ that:
+ - iptables_state is not changed
+
+
+
+- name: "create a blocking ruleset with a REJECT rule"
+ copy:
+ dest: "{{ iptables_tests }}"
+ content: |
+ *filter
+ -A INPUT -j REJECT
+ COMMIT
+
+
+
+- name: "fail to restore state from the test file (again)"
+ block:
+ - name: "restore state from the test file (bad rules, expected error -> rollback)"
+ iptables_state:
+ path: "{{ iptables_tests }}"
+ state: restored
+ register: iptables_state
+ async: "{{ ansible_timeout }}"
+ poll: 0
+
+ rescue:
+ - name: "explain expected failure"
+ assert:
+ that:
+ - iptables_state is not changed
+ - not iptables_state.applied
+ success_msg: >-
+ The previous error has been triggered to test the rollback. If you
+ are there, it means that 1) connection has been lost right after the
+ bad rules have been restored; 2) a rollback happened, so the bad
+ rules are not applied, finally; 3) module failed because it didn't
+ reach the wanted state, but at least host is not lost !!!
+ fail_msg: >-
+ The previous error has been triggered but its results are not as
+ expected.
+
+- name: "check that the expected failure happened"
+ assert:
+ that:
+ - iptables_state is failed
+
+
+
+- name: "fail to restore state from the test file (again)"
+ block:
+ - name: "try again, with a higher timeout (bad rules, same expected error)"
+ iptables_state:
+ path: "{{ iptables_tests }}"
+ state: restored
+ register: iptables_state
+ async: "{{ ansible_timeout }}"
+ poll: 0
+ vars:
+ ansible_timeout: "{{ max_delay | d(300) }}"
+
+ rescue:
+ - name: "explain expected failure"
+ assert:
+ that:
+ - iptables_state is not changed
+ - not iptables_state.applied
+ success_msg: >-
+ The previous error has been triggered to test the rollback. If you
+ are there, it means that 1) connection has been lost right after the
+ bad rules have been restored; 2) a rollback happened, so the bad
+ rules are not applied, finally; 3) module failed because it didn't
+ reach the wanted state, but at least host is not lost !!!
+ fail_msg: >-
+ The previous error has been triggered but its results are not as
+ expected.
+
+- name: "check that the expected failure happened"
+ assert:
+ that:
+ - iptables_state is failed
diff --git a/ansible_collections/community/general/tests/integration/targets/ipwcli_dns/aliases b/ansible_collections/community/general/tests/integration/targets/ipwcli_dns/aliases
new file mode 100644
index 000000000..b469f71b0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ipwcli_dns/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# There is no Ericsson IPWorks
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/ipwcli_dns/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/ipwcli_dns/tasks/main.yml
new file mode 100644
index 000000000..9cbb4edc2
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ipwcli_dns/tasks/main.yml
@@ -0,0 +1,115 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Test code for ipwcli_dns
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: variables username, password, container, tld must be set
+ fail:
+ msg: 'Please set the variables: username, password, container and tld.'
+ when: username is not defined or password is not defined or container is not defined or tld is not defined
+
+- name: add a new A record
+ ipwcli_dns:
+ dnsname: example.{{ tld }}
+ type: A
+ container: '{{ container }}'
+ address: 127.0.0.1
+ ttl: 100
+ username: '{{ username }}'
+ password: '{{ password }}'
+ register: result
+
+- name: assert the new A record is added
+ assert:
+ that:
+ - result is not failed
+ - result is changed
+ - result.record == 'arecord example.{{ tld }} 127.0.0.1 -set ttl=100;container={{ container }}'
+
+- name: delete the A record
+ ipwcli_dns:
+ dnsname: example.{{ tld }}
+ type: A
+ container: '{{ container }}'
+ address: 127.0.0.1
+ ttl: 100
+ username: '{{ username }}'
+ password: '{{ password }}'
+ state: absent
+ register: result
+
+- name: assert the new A record is deleted
+ assert:
+ that:
+ - result is not failed
+ - result is changed
+ - result.record == 'arecord example.{{ tld }} 127.0.0.1 -set ttl=100;container={{ container }}'
+
+- name: delete not existing SRV record
+ ipwcli_dns:
+ dnsname: _sip._tcp.test.example.{{ tld }}
+ type: SRV
+ container: '{{ container }}'
+ target: example.{{ tld }}
+ port: 5060
+ username: '{{ username }}'
+ password: '{{ password }}'
+ state: absent
+ register: result
+
+- name: assert the new a record
+ assert:
+ that:
+ - result is not failed
+ - result is not changed
+ - result.record ==
+ 'srvrecord _sip._tcp.test.example.{{ tld }} -set ttl=3600;container={{ container }};priority=10;weight=10;port=5060;target=example.{{ tld }}'
+
+- name: add a SRV record with weight > 65535 against RFC 2782
+ ipwcli_dns:
+ dnsname: _sip._tcp.test.example.{{ tld }}
+ type: SRV
+ container: '{{ container }}'
+ ttl: 100
+ target: example.{{ tld }}
+ port: 5060
+ weight: 65536
+ username: '{{ username }}'
+ password: '{{ password }}'
+ register: result
+ ignore_errors: true
+
+- name: assert the failure of the new SRV record
+ assert:
+ that:
+ - result is failed
+ - result is not changed
+ - "'Out of UINT16 range' in result.stderr"
+
+- name: add NAPTR record (check_mode)
+ ipwcli_dns:
+ dnsname: test.example.{{ tld }}
+ type: NAPTR
+ preference: 10
+ container: '{{ container }}'
+ ttl: 100
+ order: 10
+ service: 'SIP+D2T'
+ replacement: '_sip._tcp.test.example.{{ tld }}.'
+ flags: S
+ username: '{{ username }}'
+ password: '{{ password }}'
+ check_mode: true
+ register: result
+
+- name: assert the NAPTR check_mode
+ assert:
+ that:
+ - result is not failed
+ - result is changed
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_create/aliases b/ansible_collections/community/general/tests/integration/targets/iso_create/aliases
new file mode 100644
index 000000000..4fb0bec81
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_create/aliases
@@ -0,0 +1,8 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+destructive
+skip/aix
+skip/python2.6
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_create/files/test1.cfg b/ansible_collections/community/general/tests/integration/targets/iso_create/files/test1.cfg
new file mode 100644
index 000000000..8cd712916
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_create/files/test1.cfg
@@ -0,0 +1,61 @@
+#version=DEVEL
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# System authorization information
+auth --enableshadow --passalgo=sha512
+# Use CDROM installation media
+cdrom
+# Use graphical install
+graphical
+# Run the Setup Agent on first boot
+firstboot --enable
+ignoredisk --only-use=sda
+# Keyboard layouts
+keyboard --vckeymap=us --xlayouts='us'
+# System language
+lang en_US.UTF-8
+# Network information
+network --bootproto=dhcp --device=ens192 --ipv6=auto --no-activate
+network --hostname=localhost.localdomain
+# System services
+services --enabled="chronyd"
+# System timezone
+timezone America/New_York --isUtc
+# X Window System configuration information
+xconfig --startxonboot
+# System bootloader configuration
+bootloader --append=" crashkernel=auto" --location=mbr --boot-drive=sda
+autopart --type=lvm
+# Partition clearing information
+clearpart --none --initlabel
+#firewall --disable
+services --disabled=firewalld
+eula --agreed
+# Reboot when the install is finished.
+reboot
+
+%packages
+@^graphical-server-environment
+@base
+@core
+@desktop-debugging
+@dial-up
+@fonts
+@gnome-desktop
+@guest-agents
+@guest-desktop-agents
+@hardware-monitoring
+@input-methods
+@internet-browser
+@multimedia
+@print-client
+@x11
+chrony
+kexec-tools
+open-vm-tools-desktop
+%end
+%addon com_redhat_kdump --enable --reserve-mb='auto'
+%end
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_create/files/test_dir/test2.cfg b/ansible_collections/community/general/tests/integration/targets/iso_create/files/test_dir/test2.cfg
new file mode 100644
index 000000000..8cd712916
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_create/files/test_dir/test2.cfg
@@ -0,0 +1,61 @@
+#version=DEVEL
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# System authorization information
+auth --enableshadow --passalgo=sha512
+# Use CDROM installation media
+cdrom
+# Use graphical install
+graphical
+# Run the Setup Agent on first boot
+firstboot --enable
+ignoredisk --only-use=sda
+# Keyboard layouts
+keyboard --vckeymap=us --xlayouts='us'
+# System language
+lang en_US.UTF-8
+# Network information
+network --bootproto=dhcp --device=ens192 --ipv6=auto --no-activate
+network --hostname=localhost.localdomain
+# System services
+services --enabled="chronyd"
+# System timezone
+timezone America/New_York --isUtc
+# X Window System configuration information
+xconfig --startxonboot
+# System bootloader configuration
+bootloader --append=" crashkernel=auto" --location=mbr --boot-drive=sda
+autopart --type=lvm
+# Partition clearing information
+clearpart --none --initlabel
+#firewall --disable
+services --disabled=firewalld
+eula --agreed
+# Reboot when the install is finished.
+reboot
+
+%packages
+@^graphical-server-environment
+@base
+@core
+@desktop-debugging
+@dial-up
+@fonts
+@gnome-desktop
+@guest-agents
+@guest-desktop-agents
+@hardware-monitoring
+@input-methods
+@internet-browser
+@multimedia
+@print-client
+@x11
+chrony
+kexec-tools
+open-vm-tools-desktop
+%end
+%addon com_redhat_kdump --enable --reserve-mb='auto'
+%end
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_create/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/iso_create/meta/main.yml
new file mode 100644
index 000000000..e7127a2d6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_create/meta/main.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
+ - setup_remote_tmp_dir
+ - setup_remote_constraints
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_create/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/iso_create/tasks/main.yml
new file mode 100644
index 000000000..d53217bd3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_create/tasks/main.yml
@@ -0,0 +1,163 @@
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Test code for iso_create module
+# Copyright (c) 2020, Diane Wang (Tomorrow9) <dianew@vmware.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+- name: install pycdlib
+ pip:
+ name: pycdlib
+ extra_args: "-c {{ remote_constraints }}"
+ register: install_pycdlib
+- debug: var=install_pycdlib
+
+- set_fact:
+ output_test_dir: '{{ remote_tmp_dir }}/test_iso_create'
+
+# - include_tasks: prepare_dest_dir.yml
+
+- name: Copy files and directories
+ copy:
+ src: '{{ item }}'
+ dest: '{{ remote_tmp_dir }}/{{ item }}'
+ loop:
+ - test1.cfg
+ - test_dir
+
+- name: Test check mode
+ iso_create:
+ src_files:
+ - "{{ remote_tmp_dir }}/test1.cfg"
+ dest_iso: "{{ output_test_dir }}/test.iso"
+ interchange_level: 3
+ register: iso_result
+ check_mode: true
+- debug: var=iso_result
+
+- name: Check if iso file created
+ stat:
+ path: "{{ output_test_dir }}/test.iso"
+ register: iso_file
+- debug: var=iso_file
+- assert:
+ that:
+ - iso_result is changed
+ - iso_file.stat.exists == False
+
+- name: Create iso file with a specified file
+ iso_create:
+ src_files:
+ - "{{ remote_tmp_dir }}/test1.cfg"
+ dest_iso: "{{ output_test_dir }}/test.iso"
+ interchange_level: 3
+ register: iso_result
+- debug: var=iso_result
+
+- name: Check if iso file created
+ stat:
+ path: "{{ output_test_dir }}/test.iso"
+ register: iso_file
+
+- assert:
+ that:
+ - iso_result is changed
+ - iso_file.stat.exists == True
+
+- name: Create iso file with a specified file and folder
+ iso_create:
+ src_files:
+ - "{{ remote_tmp_dir }}/test1.cfg"
+ - "{{ remote_tmp_dir }}/test_dir"
+ dest_iso: "{{ output_test_dir }}/test1.iso"
+ interchange_level: 3
+ register: iso_result
+- debug: var=iso_result
+
+- name: Check if iso file created
+ stat:
+ path: "{{ output_test_dir }}/test1.iso"
+ register: iso_file
+
+- assert:
+ that:
+ - iso_result is changed
+ - iso_file.stat.exists == True
+
+- name: Create iso file with volume identification string
+ iso_create:
+ src_files:
+ - "{{ remote_tmp_dir }}/test1.cfg"
+ dest_iso: "{{ output_test_dir }}/test2.iso"
+ vol_ident: "OEMDRV"
+ register: iso_result
+- debug: var=iso_result
+
+- name: Check if iso file created
+ stat:
+ path: "{{ output_test_dir }}/test2.iso"
+ register: iso_file
+
+- assert:
+ that:
+ - iso_result is changed
+ - iso_file.stat.exists == True
+
+- name: Create iso file with Rock Ridge extension
+ iso_create:
+ src_files:
+ - "{{ remote_tmp_dir }}/test1.cfg"
+ dest_iso: "{{ output_test_dir }}/test3.iso"
+ rock_ridge: "1.09"
+ register: iso_result
+- debug: var=iso_result
+
+- name: Check if iso file created
+ stat:
+ path: "{{ output_test_dir }}/test3.iso"
+ register: iso_file
+
+- assert:
+ that:
+ - iso_result is changed
+ - iso_file.stat.exists == True
+
+- name: Create iso file with Joliet extension
+ iso_create:
+ src_files:
+ - "{{ remote_tmp_dir }}/test1.cfg"
+ dest_iso: "{{ output_test_dir }}/test4.iso"
+ joliet: 3
+ register: iso_result
+- debug: var=iso_result
+
+- name: Check if iso file created
+ stat:
+ path: "{{ output_test_dir }}/test4.iso"
+ register: iso_file
+
+- assert:
+ that:
+ - iso_result is changed
+ - iso_file.stat.exists == True
+
+- name: Create iso file with UDF enabled
+ iso_create:
+ src_files:
+ - "{{ remote_tmp_dir }}/test1.cfg"
+ dest_iso: "{{ output_test_dir }}/test5.iso"
+ udf: true
+ register: iso_result
+- debug: var=iso_result
+
+- name: Check if iso file created
+ stat:
+ path: "{{ output_test_dir }}/test5.iso"
+ register: iso_file
+
+- assert:
+ that:
+ - iso_result is changed
+ - iso_file.stat.exists == True
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_create/tasks/prepare_dest_dir.yml b/ansible_collections/community/general/tests/integration/targets/iso_create/tasks/prepare_dest_dir.yml
new file mode 100644
index 000000000..d1f405b5f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_create/tasks/prepare_dest_dir.yml
@@ -0,0 +1,13 @@
+# Test code for iso_create module
+# Copyright (c) 2020, Diane Wang (Tomorrow9) <dianew@vmware.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+- name: Make sure our testing sub-directory does not exist
+ file:
+ path: '{{ output_test_dir }}'
+ state: absent
+
+- name: Create our testing sub-directory
+ file:
+ path: '{{ output_test_dir }}'
+ state: directory
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_customize/aliases b/ansible_collections/community/general/tests/integration/targets/iso_customize/aliases
new file mode 100644
index 000000000..54a0f1a04
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_customize/aliases
@@ -0,0 +1,13 @@
+# Copyright (c) 2022, Ansible Project
+# Copyright (c) 2022, VMware, Inc. All Rights Reserved.
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+destructive
+skip/aix
+skip/freebsd
+skip/alpine
+skip/python2.6
+skip/docker
+needs/root
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_customize/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/iso_customize/meta/main.yml
new file mode 100644
index 000000000..5b9177b12
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_customize/meta/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_remote_tmp_dir
+ - setup_remote_constraints
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/iso_customize.yml b/ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/iso_customize.yml
new file mode 100644
index 000000000..f7d7bffd1
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/iso_customize.yml
@@ -0,0 +1,75 @@
+# Copyright (c) 2022, Ansible Project
+# Copyright (c) 2022, VMware, Inc. All Rights Reserved.
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Add a line to the file test02.cfg and make sure it succeed
+ ansible.builtin.lineinfile:
+ path: "{{ test_dir }}/test02.cfg"
+ regexp: "^test"
+ line: "test"
+
+- name: "Customize ISO file: add file, delete file and change file"
+ community.general.iso_customize:
+ src_iso: "{{ test_dir }}/test.iso"
+ dest_iso: "{{ test_dir }}/{{ dest_iso_name }}"
+ delete_files:
+ - "/test01.cfg"
+ add_files:
+ - src_file: "{{ test_dir }}/test01.cfg"
+ dest_file: "/preseed/ubuntu.seed"
+ - src_file: "{{ test_dir }}/test02.cfg"
+ dest_file: "/test02.cfg"
+
+- include_tasks: iso_mount.yml
+ vars:
+ iso_name: "{{ dest_iso_name }}"
+
+- debug: var=mount_root_dir
+
+- name: Check the file test01.cfg is deleted
+ stat:
+ path: "{{ mount_root_dir }}/test01.cfg"
+ register: check_file
+
+- assert:
+ that:
+ - check_file.stat.exists == False
+
+- name: Check the file /preseed/ubuntu.seed is added
+ stat:
+ path: "{{ mount_root_dir }}/preseed/ubuntu.seed"
+ register: check_file
+
+- assert:
+ that:
+ - check_file.stat.exists == True
+
+- block:
+ - name: Get the content of file test02.cfg
+ command: "cat {{ mount_root_dir }}/test02.cfg"
+ register: get_file_content
+
+ - set_fact:
+ file_contents: "{{ get_file_content.stdout }}"
+ when: ansible_distribution == 'RedHat' and ansible_distribution_version is version('7.9', '==')
+
+- name: Get the content of file test02.cfg
+ set_fact:
+ file_contents: "{{ lookup('file', mount_root_dir + '/test02.cfg') }}"
+ when: not (ansible_distribution == 'RedHat' and ansible_distribution_version is version('7.9', '=='))
+
+- fail: msg="Failed to replace the file test02.cfg"
+ when: file_contents != "test"
+
+- name: Umount ISO
+ mount:
+ path: "{{ mount_root_dir }}"
+ fstab: "{{ test_dir }}/temp.fstab"
+ state: unmounted
+
+- name: Delete line of file test02.cfg
+ ansible.builtin.lineinfile:
+ path: "{{ test_dir }}/test02.cfg"
+ regexp: "test"
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/iso_customize_add_files.yml b/ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/iso_customize_add_files.yml
new file mode 100644
index 000000000..210767707
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/iso_customize_add_files.yml
@@ -0,0 +1,34 @@
+# Copyright (c) 2022, Ansible Project
+# Copyright (c) 2022, VMware, Inc. All Rights Reserved.
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: "Customize ISO file: add file"
+ community.general.iso_customize:
+ src_iso: "{{ test_dir }}/test1.iso"
+ dest_iso: "{{ test_dir }}/{{ dest_iso_name }}"
+ add_files:
+ - src_file: "{{ test_dir }}/test01.cfg"
+ dest_file: "preseed/ubuntu.seed"
+
+
+- include_tasks: iso_mount.yml
+ vars:
+ iso_name: "{{ dest_iso_name }}"
+
+- debug: var=mount_root_dir
+
+- name: Check the file /preseed/ubuntu.seed is added
+ stat:
+ path: "{{ mount_root_dir }}/preseed/ubuntu.seed"
+ register: check_file
+
+- assert:
+ that:
+ - check_file.stat.exists == True
+
+- name: Umount ISO
+ mount:
+ path: "{{ mount_root_dir }}"
+ fstab: "{{ test_dir }}/temp.fstab"
+ state: unmounted
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/iso_customize_delete_files.yml b/ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/iso_customize_delete_files.yml
new file mode 100644
index 000000000..bceeeb53a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/iso_customize_delete_files.yml
@@ -0,0 +1,34 @@
+# Copyright (c) 2022, Ansible Project
+# Copyright (c) 2022, VMware, Inc. All Rights Reserved.
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: "Customize ISO file: delete file"
+ community.general.iso_customize:
+ src_iso: "{{ test_dir }}/test1.iso"
+ dest_iso: "{{ test_dir }}/{{ dest_iso_name }}"
+ delete_files:
+ - "test01.cfg"
+
+- debug: var=ansible_distribution
+
+- include_tasks: iso_mount.yml
+ vars:
+ iso_name: "{{ dest_iso_name }}"
+
+- debug: var=mount_root_dir
+
+- name: Check the file test01.cfg is deleted
+ stat:
+ path: "{{ mount_root_dir }}/test01.cfg"
+ register: check_file
+
+- assert:
+ that:
+ - check_file.stat.exists == False
+
+- name: Umount ISO
+ mount:
+ path: "{{ mount_root_dir }}"
+ fstab: "{{ test_dir }}/temp.fstab"
+ state: unmounted
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/iso_customize_exception.yml b/ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/iso_customize_exception.yml
new file mode 100644
index 000000000..b2130bb6b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/iso_customize_exception.yml
@@ -0,0 +1,71 @@
+# Copyright (c) 2022, Ansible Project
+# Copyright (c) 2022, VMware, Inc. All Rights Reserved.
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: "Testcase: local resource ISO does not exists"
+ community.general.iso_customize:
+ src_iso: "{{ test_dir }}/test11.iso"
+ dest_iso: "{{ test_dir }}/{{ dest_iso_name }}"
+ register: customized_result
+ failed_when: customized_result.msg.find('does not exist') == -1
+
+- name: "Testcase:: dest dir does not exists"
+ community.general.iso_customize:
+ src_iso: "{{ test_dir }}/test1.iso"
+ dest_iso: "/aaa/{{ dest_iso_name }}"
+ register: customized_result
+ failed_when: customized_result.msg.find('does not exist') == -1
+
+# Test: nothing is changed when no options "add files" and "delete files"
+- block:
+ - name: "Testcase: no options 'add files' and 'delete files'"
+ community.general.iso_customize:
+ src_iso: "{{ test_dir }}/test1.iso"
+ dest_iso: "{{ test_dir }}/iso_customize_nochanged.iso"
+
+ - name: Get stats of a file test1.iso
+ ansible.builtin.stat:
+ path: "{{ test_dir }}/test1.iso"
+ register: iso_orginal
+
+ - name: Get stats of a file iso_customize_nochanged.iso
+ ansible.builtin.stat:
+ path: "{{ test_dir }}/iso_customize_nochanged.iso"
+ register: iso_customized
+
+ - name: compare size
+ fail: msg="Check we have nothing changed for customized ISO"
+ when: iso_orginal.stat.size != iso_customized.stat.size
+
+- name: "Testcase: delete the non-existing file in ISO"
+ community.general.iso_customize:
+ src_iso: "{{ test_dir }}/test1.iso"
+ dest_iso: "{{ test_dir }}/{{ dest_iso_name }}"
+ delete_files:
+ - "/test03.cfg"
+ register: customized_result
+ failed_when: customized_result.msg.find("does not exist") == -1
+
+# Test: failed when local src file does not exists
+- name: "Testcase: local src file does not exists"
+ community.general.iso_customize:
+ src_iso: "{{ test_dir }}/test.iso"
+ dest_iso: "{{ test_dir }}/{{ dest_iso_name }}"
+ add_files:
+ - src_file: "{{ test_dir }}/test03.cfg"
+ dest_file: "/preseed/ubuntu.seed"
+ register: customized_result
+ failed_when: customized_result.msg.find("does not exist") == -1
+
+# Test: filenames with whitespaces
+# We report error: the user should be reponsible for the it
+- name: "Testcase: filenames with whitespaces"
+ community.general.iso_customize:
+ src_iso: "{{ test_dir }}/test.iso"
+ dest_iso: "{{ test_dir }}/{{ dest_iso_name }}"
+ add_files:
+ - src_file: " {{ test_dir }}/test01.cfg "
+ dest_file: "/preseed/ubuntu.seed"
+ register: customized_result
+ failed_when: customized_result.msg.find("does not exist") == -1
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/iso_mount.yml b/ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/iso_mount.yml
new file mode 100644
index 000000000..cf4ab8199
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/iso_mount.yml
@@ -0,0 +1,39 @@
+# Copyright (c) 2022, Ansible Project
+# Copyright (c) 2022, VMware, Inc. All Rights Reserved.
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- debug: var=ansible_distribution
+
+- block:
+ - name: "Mount customized ISO on MAC"
+ command: "hdiutil attach {{ test_dir }}/{{ iso_name }} -mountroot {{ test_dir }}/iso_mount"
+
+ # For MAC, we have different root directory for different type of ISO
+ - set_fact:
+ mount_root_dir: "{{ test_dir }}/iso_mount/disk_image"
+
+ - set_fact:
+ mount_root_dir: "{{ test_dir }}/iso_mount/AUTOINSTALL"
+ when: iso_name.find('joliet') != -1
+
+ - set_fact:
+ mount_root_dir: "{{ test_dir }}/iso_mount/CDROM"
+ when: iso_name.find('udf') != -1
+ when: ansible_distribution == "MacOSX"
+
+- block:
+ - name: "Mount {{ iso_name }} to {{ test_dir }}/iso_mount on localhost"
+ become: true
+ ansible.posix.mount:
+ path: "{{ test_dir }}/iso_mount"
+ src: "{{ test_dir }}/{{ iso_name }}"
+ opts: "ro,noauto"
+ fstab: "{{ test_dir }}/temp.fstab"
+ fstype: "iso9660"
+ state: mounted
+
+ - set_fact:
+ mount_root_dir: "{{ test_dir }}/iso_mount"
+ when:
+ - ansible_distribution != "MacOSX"
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/main.yml
new file mode 100644
index 000000000..dafd84dd5
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/main.yml
@@ -0,0 +1,94 @@
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2022, Ansible Project
+# Copyright (c) 2022, VMware, Inc. All Rights Reserved.
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Skip some platforms which does not support ansible.posix.mount
+ meta: end_play
+ when: ansible_distribution in ['Alpine']
+
+- set_fact:
+ test_dir: '{{ remote_tmp_dir }}/test_iso_customize'
+
+- include_tasks: prepare.yml
+
+- name: Create iso file with a specified file and directory
+ community.general.iso_create:
+ src_files:
+ - "{{ test_dir }}/test01.cfg"
+ - "{{ test_dir }}/test02.cfg"
+ dest_iso: "{{ test_dir }}/test.iso"
+ interchange_level: 3
+
+- include_tasks: iso_customize.yml
+ vars:
+ dest_iso_name: "iso_customize.iso"
+
+- name: Create an ISO file with Rock Ridge extension
+ community.general.iso_create:
+ src_files:
+ - "{{ test_dir }}/test01.cfg"
+ - "{{ test_dir }}/test02.cfg"
+ dest_iso: "{{ test_dir }}/test.iso"
+ rock_ridge: "1.09"
+
+- include_tasks: iso_customize.yml
+ vars:
+ dest_iso_name: "iso_customize_rr.iso"
+
+- name: Create an ISO file with Joliet support
+ community.general.iso_create:
+ src_files:
+ - "{{ test_dir }}/test01.cfg"
+ - "{{ test_dir }}/test02.cfg"
+ dest_iso: "{{ test_dir }}/test.iso"
+ interchange_level: 3
+ joliet: 3
+ vol_ident: AUTOINSTALL
+
+- include_tasks: iso_customize.yml
+ vars:
+ dest_iso_name: "iso_customize_joliet.iso"
+
+- name: Create iso file with UDF enabled
+ community.general.iso_create:
+ src_files:
+ - "{{ test_dir }}/test01.cfg"
+ - "{{ test_dir }}/test02.cfg"
+ dest_iso: "{{ test_dir }}/test.iso"
+ udf: true
+
+- include_tasks: iso_customize.yml
+ vars:
+ dest_iso_name: "iso_customize_udf.iso"
+
+# Create initial iso for customzing with only option add_files/delete_files
+- name: Create iso file with a specified file and directory
+ community.general.iso_create:
+ src_files:
+ - "{{ test_dir }}/test01.cfg"
+ dest_iso: "{{ test_dir }}/test1.iso"
+ interchange_level: 3
+
+- include_tasks: iso_customize_add_files.yml
+ vars:
+ dest_iso_name: "iso_customize_add.iso"
+
+- include_tasks: iso_customize_delete_files.yml
+ vars:
+ dest_iso_name: "iso_customize_delete.iso"
+
+# Test: misc exception
+- include_tasks: iso_customize_exception.yml
+ vars:
+ dest_iso_name: "iso_customize_exception.iso"
+
+- name: Delete testing sub-directory
+ ansible.builtin.file:
+ path: '{{ test_dir }}'
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/prepare.yml b/ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/prepare.yml
new file mode 100644
index 000000000..e3c860b7c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_customize/tasks/prepare.yml
@@ -0,0 +1,40 @@
+# Copyright (c) 2022, Ansible Project
+# Copyright (c) 2022, VMware, Inc. All Rights Reserved.
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: install pycdlib
+ ansible.builtin.pip:
+ name: pycdlib
+ extra_args: "-c {{ remote_constraints }}"
+
+- name: Make sure the previous testing sub-directory is deleted
+ ansible.builtin.file:
+ path: '{{ test_dir }}'
+ state: absent
+
+- name: Create our testing sub-directory
+ ansible.builtin.file:
+ path: '{{ test_dir }}'
+ state: directory
+
+- name: Create sub directory to mount customized ISO
+ ansible.builtin.file:
+ path: '{{ test_dir }}/iso_mount'
+ state: directory
+
+- name: Create temporary file test01.cfg for testing
+ ansible.builtin.file:
+ path: "{{ test_dir }}/test01.cfg"
+ state: touch
+
+- name: Add a line to the file test01.cfg and make sure it succeed
+ ansible.builtin.lineinfile:
+ path: "{{ test_dir }}/test01.cfg"
+ regexp: "^aaa"
+ line: "aaa"
+
+- name: Create temporary file test02.cfg for testing
+ ansible.builtin.file:
+ path: "{{ test_dir }}/test02.cfg"
+ state: touch
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_extract/aliases b/ansible_collections/community/general/tests/integration/targets/iso_extract/aliases
new file mode 100644
index 000000000..33041456a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_extract/aliases
@@ -0,0 +1,13 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+needs/target/setup_epel
+destructive
+skip/aix
+skip/osx # FIXME
+skip/rhel9.0 # FIXME
+skip/rhel9.1 # FIXME
+skip/freebsd12.4 # FIXME
+skip/freebsd13.2 # FIXME
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_extract/files/test.iso b/ansible_collections/community/general/tests/integration/targets/iso_extract/files/test.iso
new file mode 100644
index 000000000..d06ff73ca
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_extract/files/test.iso
Binary files differ
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_extract/files/test.iso.license b/ansible_collections/community/general/tests/integration/targets/iso_extract/files/test.iso.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_extract/files/test.iso.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_extract/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/iso_extract/meta/main.yml
new file mode 100644
index 000000000..ca1915e05
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_extract/meta/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_extract/tasks/7zip.yml b/ansible_collections/community/general/tests/integration/targets/iso_extract/tasks/7zip.yml
new file mode 100644
index 000000000..e0f1586ce
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_extract/tasks/7zip.yml
@@ -0,0 +1,54 @@
+---
+# Test code for the iso_extract module.
+# Copyright (c) 2017, James Tanner <tanner.jc@gmail.com>
+# Copyright (c) 2017, Dag Wieers <dag@wieers.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Gather facts
+ setup:
+ become: true
+
+- name: Include distribution specific variables
+ include_vars: "{{ lookup('first_found', params) }}"
+ vars:
+ params:
+ files:
+ - "{{ ansible_facts.distribution }}.yml"
+ - "{{ ansible_facts.os_family }}.yml"
+ - default.yml
+ paths:
+ - "{{ role_path }}/vars"
+
+- name: "{{ ansible_facts.os_family | upper }} | Install 7zip package"
+ action: "{{ ansible_facts.pkg_mgr }}"
+ args:
+ name: "{{ iso_extract_7zip_package }}"
+ state: present
+ when: ansible_facts.distribution != 'MacOSX'
+
+- name: macOS
+ when: ansible_facts.distribution == 'MacOSX'
+ block:
+ - name: MACOS | Find brew binary
+ command: which brew
+ register: brew_which
+ when: ansible_distribution in ['MacOSX']
+
+ - name: MACOS | Get owner of brew binary
+ stat:
+ path: "{{ brew_which.stdout }}"
+ register: brew_stat
+ when: ansible_distribution in ['MacOSX']
+
+ - name: MACOS | Install 7zip package
+ homebrew:
+ name: p7zip
+ state: present
+ update_homebrew: false
+ become: true
+ become_user: "{{ brew_stat.stat.pw_name }}"
+ # Newer versions of brew want to compile a package which takes a long time. Do not upgrade homebrew until a
+ # proper solution can be found
+ environment:
+ HOMEBREW_NO_AUTO_UPDATE: "True"
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_extract/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/iso_extract/tasks/main.yml
new file mode 100644
index 000000000..67ebfa7ab
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_extract/tasks/main.yml
@@ -0,0 +1,43 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Test code for the iso_extract module.
+# Copyright (c) 2017, James Tanner <tanner.jc@gmail.com>
+# Copyright (c) 2017, Dag Wieers <dag@wieers.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- set_fact:
+ output_test_dir: '{{ remote_tmp_dir }}/test_iso_extract'
+
+- name: Install EPEL repository (RHEL only)
+ include_role:
+ name: setup_epel
+ when:
+ - ansible_distribution in ['RedHat', 'CentOS']
+ - ansible_distribution_major_version is version('9', '<')
+
+- name: Install 7zip
+ import_tasks: 7zip.yml
+
+- name: Prepare environment
+ import_tasks: prepare.yml
+
+- name: Test in normal mode
+ import_tasks: tests.yml
+ vars:
+ in_check_mode: false
+
+- name: Prepare environment
+ import_tasks: prepare.yml
+
+- name: Test in check-mode
+ import_tasks: tests.yml
+ vars:
+ in_check_mode: true
+ check_mode: true
+
+# FIXME - fill this in after figuring out how to allow mounts
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_extract/tasks/prepare.yml b/ansible_collections/community/general/tests/integration/targets/iso_extract/tasks/prepare.yml
new file mode 100644
index 000000000..57e10c0db
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_extract/tasks/prepare.yml
@@ -0,0 +1,21 @@
+---
+# Test code for the iso_extract module.
+# Copyright (c) 2017, James Tanner <tanner.jc@gmail.com>
+# Copyright (c) 2017, Dag Wieers <dag@wieers.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Make sure our testing sub-directory does not exist
+ file:
+ path: '{{ output_test_dir }}'
+ state: absent
+
+- name: Create our testing sub-directory
+ file:
+ path: '{{ output_test_dir }}'
+ state: directory
+
+- name: copy the iso to the test dir
+ copy:
+ src: test.iso
+ dest: '{{ output_test_dir }}'
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_extract/tasks/tests.yml b/ansible_collections/community/general/tests/integration/targets/iso_extract/tasks/tests.yml
new file mode 100644
index 000000000..6919a7c2e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_extract/tasks/tests.yml
@@ -0,0 +1,40 @@
+---
+# Test code for the iso_extract module.
+# Copyright (c) 2017, James Tanner <tanner.jc@gmail.com>
+# Copyright (c) 2017, Dag Wieers <dag@wieers.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Extract the iso
+ iso_extract:
+ image: '{{ output_test_dir }}/test.iso'
+ dest: '{{ output_test_dir }}'
+ files:
+ - 1.txt
+ - 2.txt
+ register: iso_extract_test0
+
+- assert:
+ that:
+ - iso_extract_test0 is changed
+
+- name: Extract the iso again
+ iso_extract:
+ image: '{{ output_test_dir }}/test.iso'
+ dest: '{{ output_test_dir }}'
+ files:
+ - 1.txt
+ - 2.txt
+ register: iso_extract_test0_again
+
+- name: Test iso_extract_test0_again (normal mode)
+ assert:
+ that:
+ - iso_extract_test0_again is not changed
+ when: not in_check_mode
+
+- name: Test iso_extract_test0_again (check-mode)
+ assert:
+ that:
+ - iso_extract_test0_again is changed
+ when: in_check_mode
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_extract/vars/Alpine.yml b/ansible_collections/community/general/tests/integration/targets/iso_extract/vars/Alpine.yml
new file mode 100644
index 000000000..bcb92f79b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_extract/vars/Alpine.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+iso_extract_7zip_package: p7zip
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_extract/vars/Archlinux.yml b/ansible_collections/community/general/tests/integration/targets/iso_extract/vars/Archlinux.yml
new file mode 100644
index 000000000..bcb92f79b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_extract/vars/Archlinux.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+iso_extract_7zip_package: p7zip
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_extract/vars/Debian.yml b/ansible_collections/community/general/tests/integration/targets/iso_extract/vars/Debian.yml
new file mode 100644
index 000000000..09436ceb0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_extract/vars/Debian.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+iso_extract_7zip_package: p7zip-full
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_extract/vars/FreeBSD.yml b/ansible_collections/community/general/tests/integration/targets/iso_extract/vars/FreeBSD.yml
new file mode 100644
index 000000000..bcb92f79b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_extract/vars/FreeBSD.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+iso_extract_7zip_package: p7zip
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_extract/vars/RedHat.yml b/ansible_collections/community/general/tests/integration/targets/iso_extract/vars/RedHat.yml
new file mode 100644
index 000000000..2bcdf4bff
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_extract/vars/RedHat.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+iso_extract_7zip_package: p7zip-plugins
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_extract/vars/Suse.yml b/ansible_collections/community/general/tests/integration/targets/iso_extract/vars/Suse.yml
new file mode 100644
index 000000000..1b695ce72
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_extract/vars/Suse.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# The 7z executable moved from p7zip to p7zip-full;
+# see https://build.opensuse.org/package/view_file/openSUSE:Leap:15.2/p7zip/p7zip.changes?expand=1
+iso_extract_7zip_package: p7zip-full
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_extract/vars/Ubuntu.yml b/ansible_collections/community/general/tests/integration/targets/iso_extract/vars/Ubuntu.yml
new file mode 100644
index 000000000..09436ceb0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_extract/vars/Ubuntu.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+iso_extract_7zip_package: p7zip-full
diff --git a/ansible_collections/community/general/tests/integration/targets/iso_extract/vars/default.yml b/ansible_collections/community/general/tests/integration/targets/iso_extract/vars/default.yml
new file mode 100644
index 000000000..f55df21f8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/iso_extract/vars/default.yml
@@ -0,0 +1,4 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/ansible_collections/community/general/tests/integration/targets/java_cert/aliases b/ansible_collections/community/general/tests/integration/targets/java_cert/aliases
new file mode 100644
index 000000000..573cb189b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/java_cert/aliases
@@ -0,0 +1,11 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/3
+destructive
+skip/aix
+skip/osx
+skip/macos
+skip/freebsd
+needs/root
diff --git a/ansible_collections/community/general/tests/integration/targets/java_cert/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/java_cert/defaults/main.yml
new file mode 100644
index 000000000..ebac2789b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/java_cert/defaults/main.yml
@@ -0,0 +1,19 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+test_pkcs12_path: testpkcs.p12
+test_keystore_path: keystore.jks
+test_keystore2_path: "{{ remote_tmp_dir }}/keystore2.jks"
+test_keystore2_password: changeit
+test_cert_path: "{{ remote_tmp_dir }}/cert.pem"
+test_key_path: "{{ remote_tmp_dir }}/key.pem"
+test_csr_path: "{{ remote_tmp_dir }}/req.csr"
+test_cert2_path: "{{ remote_tmp_dir }}/cert2.pem"
+test_key2_path: "{{ remote_tmp_dir }}/key2.pem"
+test_csr2_path: "{{ remote_tmp_dir }}/req2.csr"
+test_pkcs_path: "{{ remote_tmp_dir }}/cert.p12"
+test_pkcs2_path: "{{ remote_tmp_dir }}/cert2.p12"
+test_ssl: setupSSLServer.py
+test_ssl_port: 21500
diff --git a/ansible_collections/community/general/tests/integration/targets/java_cert/files/setupSSLServer.py b/ansible_collections/community/general/tests/integration/targets/java_cert/files/setupSSLServer.py
new file mode 100644
index 000000000..4b0a42185
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/java_cert/files/setupSSLServer.py
@@ -0,0 +1,24 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+import ssl
+import os
+import sys
+
+root_dir = sys.argv[1]
+port = int(sys.argv[2])
+
+try:
+ from BaseHTTPServer import HTTPServer
+ from SimpleHTTPServer import SimpleHTTPRequestHandler
+except ModuleNotFoundError:
+ from http.server import HTTPServer, SimpleHTTPRequestHandler
+
+httpd = HTTPServer(('localhost', port), SimpleHTTPRequestHandler)
+httpd.socket = ssl.wrap_socket(httpd.socket, server_side=True,
+ certfile=os.path.join(root_dir, 'cert.pem'),
+ keyfile=os.path.join(root_dir, 'key.pem'))
+httpd.handle_request()
diff --git a/ansible_collections/community/general/tests/integration/targets/java_cert/files/testpkcs.p12 b/ansible_collections/community/general/tests/integration/targets/java_cert/files/testpkcs.p12
new file mode 100644
index 000000000..e0fee618c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/java_cert/files/testpkcs.p12
Binary files differ
diff --git a/ansible_collections/community/general/tests/integration/targets/java_cert/files/testpkcs.p12.license b/ansible_collections/community/general/tests/integration/targets/java_cert/files/testpkcs.p12.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/java_cert/files/testpkcs.p12.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/java_cert/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/java_cert/meta/main.yml
new file mode 100644
index 000000000..0371df88e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/java_cert/meta/main.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_java_keytool
+ - setup_openssl
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/java_cert/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/java_cert/tasks/main.yml
new file mode 100644
index 000000000..25ec87e8f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/java_cert/tasks/main.yml
@@ -0,0 +1,116 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- when: has_java_keytool
+ block:
+
+ - name: prep pkcs12 file
+ ansible.builtin.copy:
+ src: "{{ test_pkcs12_path }}"
+ dest: "{{ remote_tmp_dir }}/{{ test_pkcs12_path }}"
+
+ - name: import pkcs12
+ community.general.java_cert:
+ pkcs12_path: "{{ remote_tmp_dir }}/{{ test_pkcs12_path }}"
+ pkcs12_password: changeit
+ pkcs12_alias: default
+ cert_alias: default
+ keystore_path: "{{ remote_tmp_dir }}/{{ test_keystore_path }}"
+ keystore_pass: changeme_keystore
+ keystore_create: true
+ state: present
+ register: result_success
+
+ - name: verify success
+ ansible.builtin.assert:
+ that:
+ - result_success is successful
+
+ - name: import pkcs12 with wrong password
+ community.general.java_cert:
+ pkcs12_path: "{{ remote_tmp_dir }}/{{ test_pkcs12_path }}"
+ pkcs12_password: wrong_pass
+ pkcs12_alias: default
+ cert_alias: default_new
+ keystore_path: "{{ remote_tmp_dir }}/{{ test_keystore_path }}"
+ keystore_pass: changeme_keystore
+ keystore_create: true
+ state: present
+ ignore_errors: true
+ register: result_wrong_pass
+
+ - name: verify fail with wrong import password
+ ansible.builtin.assert:
+ that:
+ - result_wrong_pass is failed
+
+ - name: test fail on mutually exclusive params
+ community.general.java_cert:
+ cert_path: ca.crt
+ pkcs12_path: "{{ remote_tmp_dir }}/{{ test_pkcs12_path }}"
+ cert_alias: default
+ keystore_path: "{{ remote_tmp_dir }}/{{ test_keystore_path }}"
+ keystore_pass: changeme_keystore
+ keystore_create: true
+ state: present
+ ignore_errors: true
+ register: result_excl_params
+
+ - name: verify failed exclusive params
+ ansible.builtin.assert:
+ that:
+ - result_excl_params is failed
+
+ - name: test fail on missing required params
+ community.general.java_cert:
+ keystore_path: "{{ remote_tmp_dir }}/{{ test_keystore_path }}"
+ keystore_pass: changeme_keystore
+ state: absent
+ ignore_errors: true
+ register: result_missing_required_param
+
+ - name: verify failed missing required params
+ ansible.builtin.assert:
+ that:
+ - result_missing_required_param is failed
+
+ - name: delete object based on cert_alias parameter
+ community.general.java_cert:
+ keystore_path: "{{ remote_tmp_dir }}/{{ test_keystore_path }}"
+ keystore_pass: changeme_keystore
+ cert_alias: default
+ state: absent
+ ignore_errors: true
+ register: result_alias_deleted
+
+ - name: verify object successfully deleted
+ ansible.builtin.assert:
+ that:
+ - result_alias_deleted is successful
+
+ - name: include extended test suite
+ import_tasks: state_change.yml
+
+ - name: cleanup environment
+ ansible.builtin.file:
+ path: "{{ item }}"
+ state: absent
+ loop:
+ - "{{ remote_tmp_dir }}/{{ test_pkcs12_path }}"
+ - "{{ remote_tmp_dir }}/{{ test_keystore_path }}"
+ - "{{ test_keystore2_path }}"
+ - "{{ test_cert_path }}"
+ - "{{ test_key_path }}"
+ - "{{ test_csr_path }}"
+ - "{{ test_cert2_path }}"
+ - "{{ test_key2_path }}"
+ - "{{ test_csr2_path }}"
+ - "{{ test_pkcs_path }}"
+ - "{{ test_pkcs2_path }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/java_cert/tasks/state_change.yml b/ansible_collections/community/general/tests/integration/targets/java_cert/tasks/state_change.yml
new file mode 100644
index 000000000..e135a60a3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/java_cert/tasks/state_change.yml
@@ -0,0 +1,298 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+#
+# Prepare X509 and PKCS#12 materials
+#
+
+- name: Create private keys
+ community.crypto.openssl_privatekey:
+ path: "{{ item }}"
+ mode: "u=rw,go="
+ loop:
+ - "{{ test_key_path }}"
+ - "{{ test_key2_path }}"
+
+- name: Generate CSR for self-signed certificate used as a placeholder to create the java keystore
+ community.crypto.openssl_csr:
+ path: "{{ test_csr_path }}"
+ privatekey_path: "{{ test_key_path }}"
+ commonName: "localhost"
+
+- name: Generate CSR for self-signed certificate used for testing
+ community.crypto.openssl_csr:
+ path: "{{ test_csr2_path }}"
+ privatekey_path: "{{ test_key2_path }}"
+ commonName: "localhost"
+
+- name: Generate the self-signed cert used as a placeholder to create the java keystore
+ community.crypto.x509_certificate:
+ path: "{{ test_cert_path }}"
+ csr_path: "{{ test_csr_path }}"
+ privatekey_path: "{{ test_key_path }}"
+ provider: selfsigned
+
+- name: Generate the self signed cert we will use for testing
+ community.crypto.x509_certificate:
+ path: "{{ test_cert2_path }}"
+ csr_path: "{{ test_csr2_path }}"
+ privatekey_path: "{{ test_key2_path }}"
+ provider: selfsigned
+
+- name: Create the pkcs12 archive from the test x509 cert
+ community.crypto.openssl_pkcs12:
+ name: "test_pkcs12_cert"
+ path: "{{ test_pkcs_path }}"
+ passphrase: "{{ test_keystore2_password }}"
+ certificate_path: "{{ test_cert_path }}"
+ privatekey_path: "{{ test_key_path }}"
+ when:
+ - "not (ansible_os_family == 'RedHat' and ansible_distribution_version is version('8.0', '<'))"
+
+- name: Create the pkcs12 archive from the test x509 cert (command)
+ ansible.builtin.command:
+ cmd: >
+ openssl pkcs12 -export
+ -in {{ test_cert_path }}
+ -inkey {{ test_key_path }}
+ -name test_pkcs12_cert
+ -out {{ test_pkcs_path }}
+ -passout stdin
+ stdin: "{{ test_keystore2_password }}"
+ when:
+ - "ansible_os_family == 'RedHat'"
+ - "ansible_distribution_version is version('8.0', '<')"
+
+- name: Create the pkcs12 archive from the certificate we will be trying to add to the keystore
+ community.crypto.openssl_pkcs12:
+ name: "test_pkcs12_cert"
+ path: "{{ test_pkcs2_path }}"
+ passphrase: "{{ test_keystore2_password }}"
+ certificate_path: "{{ test_cert2_path }}"
+ privatekey_path: "{{ test_key2_path }}"
+ when:
+ - "not (ansible_os_family == 'RedHat' and ansible_distribution_version is version('8.0', '<'))"
+
+- name: Create the pkcs12 archive from the certificate we will be trying to add to the keystore (command)
+ ansible.builtin.command:
+ cmd: >
+ openssl pkcs12 -export
+ -in {{ test_cert2_path }}
+ -inkey {{ test_key2_path }}
+ -name test_pkcs12_cert
+ -out {{ test_pkcs2_path }}
+ -passout stdin
+ stdin: "{{ test_keystore2_password }}"
+ when:
+ - "ansible_os_family == 'RedHat'"
+ - "ansible_distribution_version is version('8.0', '<')"
+
+#
+# Run tests
+#
+
+- name: try to create the test keystore based on the just created pkcs12, keystore_create flag not enabled
+ community.general.java_cert:
+ cert_alias: test_pkcs12_cert
+ pkcs12_alias: test_pkcs12_cert
+ pkcs12_path: "{{ test_pkcs_path }}"
+ pkcs12_password: "{{ test_keystore2_password }}"
+ keystore_path: "{{ test_keystore2_path }}"
+ keystore_pass: "{{ test_keystore2_password }}"
+ ignore_errors: true
+ register: result_x509_changed
+
+- name: Verify the x509 status is failed
+ ansible.builtin.assert:
+ that:
+ - result_x509_changed is failed
+
+- name: Create the test keystore based on the just created pkcs12
+ community.general.java_cert:
+ cert_alias: test_pkcs12_cert
+ pkcs12_alias: test_pkcs12_cert
+ pkcs12_path: "{{ test_pkcs_path }}"
+ pkcs12_password: "{{ test_keystore2_password }}"
+ keystore_path: "{{ test_keystore2_path }}"
+ keystore_pass: "{{ test_keystore2_password }}"
+ keystore_create: true
+
+- name: List newly created keystore content
+ ansible.builtin.command:
+ cmd: "keytool -list -keystore {{ test_keystore2_path }}"
+ stdin: "{{ test_keystore2_password }}"
+ register: keytool_list_keystore
+
+- name: Assert that the keystore has a private key entry
+ ansible.builtin.assert:
+ that:
+ - "keytool_list_keystore.stdout_lines[5] is match('test_pkcs12_cert,.*, PrivateKeyEntry, $')"
+
+- name: try to import from pkcs12 a non existing alias
+ community.general.java_cert:
+ cert_alias: test_pkcs12_cert
+ pkcs12_alias: non_existing_alias
+ pkcs12_path: "{{ test_pkcs_path }}"
+ pkcs12_password: "{{ test_keystore2_password }}"
+ keystore_path: "{{ test_keystore2_path }}"
+ keystore_pass: "{{ test_keystore2_password }}"
+ keystore_create: true
+ ignore_errors: true
+ register: result_x509_changed
+
+- name: Verify the x509 status is failed
+ ansible.builtin.assert:
+ that:
+ - result_x509_changed is failed
+
+- name: import initial test certificate from file path
+ community.general.java_cert:
+ cert_alias: test_cert
+ cert_path: "{{ test_cert_path }}"
+ keystore_path: "{{ test_keystore2_path }}"
+ keystore_pass: "{{ test_keystore2_password }}"
+ keystore_create: true
+ state: present
+ register: result_x509_changed
+
+- name: Verify the x509 status is changed
+ ansible.builtin.assert:
+ that:
+ - result_x509_changed is changed
+
+- name: |
+ Import the newly created certificate. This is our main test.
+ If the java_cert has been updated properly, then this task will report changed each time
+ since the module will be comparing the hash of the certificate instead of validating that the alias
+ simply exists
+ community.general.java_cert:
+ cert_alias: test_cert
+ cert_path: "{{ test_cert2_path }}"
+ keystore_path: "{{ test_keystore2_path }}"
+ keystore_pass: "{{ test_keystore2_password }}"
+ state: present
+ register: result_x509_changed
+
+- name: Verify the x509 status is changed
+ ansible.builtin.assert:
+ that:
+ - result_x509_changed is changed
+
+- name: |
+ We also want to make sure that the status doesnt change if we import the same cert
+ community.general.java_cert:
+ cert_alias: test_cert
+ cert_path: "{{ test_cert2_path }}"
+ keystore_path: "{{ test_keystore2_path }}"
+ keystore_pass: "{{ test_keystore2_password }}"
+ state: present
+ register: result_x509_succeeded
+
+- name: Verify the x509 status is ok
+ ansible.builtin.assert:
+ that:
+ - result_x509_succeeded is succeeded
+
+- name: >
+ Ensure the original pkcs12 cert is in the keystore
+ community.general.java_cert:
+ cert_alias: test_pkcs12_cert
+ pkcs12_alias: test_pkcs12_cert
+ pkcs12_path: "{{ test_pkcs_path }}"
+ pkcs12_password: "{{ test_keystore2_password }}"
+ keystore_path: "{{ test_keystore2_path }}"
+ keystore_pass: "{{ test_keystore2_password }}"
+ state: present
+
+- name: |
+ Perform the same test, but we will now be testing the pkcs12 functionality
+ If we add a different pkcs12 cert with the same alias, we should have a changed result, NOT the same
+ community.general.java_cert:
+ cert_alias: test_pkcs12_cert
+ pkcs12_alias: test_pkcs12_cert
+ pkcs12_path: "{{ test_pkcs2_path }}"
+ pkcs12_password: "{{ test_keystore2_password }}"
+ keystore_path: "{{ test_keystore2_path }}"
+ keystore_pass: "{{ test_keystore2_password }}"
+ state: present
+ register: result_pkcs12_changed
+
+- name: Verify the pkcs12 status is changed
+ ansible.builtin.assert:
+ that:
+ - result_pkcs12_changed is changed
+
+- name: |
+ We are requesting the same cert now, so the status should show OK
+ community.general.java_cert:
+ cert_alias: test_pkcs12_cert
+ pkcs12_alias: test_pkcs12_cert
+ pkcs12_path: "{{ test_pkcs2_path }}"
+ pkcs12_password: "{{ test_keystore2_password }}"
+ keystore_path: "{{ test_keystore2_path }}"
+ keystore_pass: "{{ test_keystore2_password }}"
+ register: result_pkcs12_succeeded
+
+- name: Verify the pkcs12 status is ok
+ ansible.builtin.assert:
+ that:
+ - result_pkcs12_succeeded is succeeded
+
+- name: Copy the ssl server script
+ copy:
+ src: "setupSSLServer.py"
+ dest: "{{ remote_tmp_dir }}"
+
+- name: Create an SSL server that we will use for testing URL imports
+ command: "{{ ansible_python.executable }} {{ remote_tmp_dir }}/setupSSLServer.py {{ remote_tmp_dir }} {{ test_ssl_port }}"
+ async: 10
+ poll: 0
+
+- name: "Wait for one second to make sure that the serve script has actually been started"
+ pause:
+ seconds: 1
+
+- name: |
+ Download the original cert.pem from our temporary server. The current cert should contain
+ cert2.pem. Importing this cert should return a status of changed
+ community.general.java_cert:
+ cert_alias: test_cert_localhost
+ cert_url: localhost
+ cert_port: "{{ test_ssl_port }}"
+ keystore_path: "{{ test_keystore2_path }}"
+ keystore_pass: "{{ test_keystore2_password }}"
+ state: present
+ register: result_url_changed
+
+- name: Verify that the url status is changed
+ ansible.builtin.assert:
+ that:
+ - result_url_changed is changed
+
+- name: Ensure we can remove the x509 cert
+ community.general.java_cert:
+ cert_alias: test_cert
+ keystore_path: "{{ test_keystore2_path }}"
+ keystore_pass: "{{ test_keystore2_password }}"
+ state: absent
+ register: result_x509_absent
+
+- name: Verify the x509 cert is absent
+ ansible.builtin.assert:
+ that:
+ - result_x509_absent is changed
+
+- name: Ensure we can remove the certificate imported from pkcs12 archive
+ community.general.java_cert:
+ cert_alias: test_pkcs12_cert
+ keystore_path: "{{ test_keystore2_path }}"
+ keystore_pass: "{{ test_keystore2_password }}"
+ state: absent
+ register: result_pkcs12_absent
+
+- name: Verify the pkcs12 archive is absent
+ ansible.builtin.assert:
+ that:
+ - result_pkcs12_absent is changed
diff --git a/ansible_collections/community/general/tests/integration/targets/java_keystore/aliases b/ansible_collections/community/general/tests/integration/targets/java_keystore/aliases
new file mode 100644
index 000000000..573cb189b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/java_keystore/aliases
@@ -0,0 +1,11 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/3
+destructive
+skip/aix
+skip/osx
+skip/macos
+skip/freebsd
+needs/root
diff --git a/ansible_collections/community/general/tests/integration/targets/java_keystore/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/java_keystore/defaults/main.yml
new file mode 100644
index 000000000..b51461462
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/java_keystore/defaults/main.yml
@@ -0,0 +1,20 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+java_keystore_certs:
+ - name: cert
+ commonName: example.com
+ - name: cert-pw
+ passphrase: hunter2
+ commonName: example.com
+
+java_keystore_new_certs:
+ - name: cert2
+ keyname: cert
+ commonName: example.org
+ - name: cert2-pw
+ keyname: cert-pw
+ passphrase: hunter2
+ commonName: example.org
diff --git a/ansible_collections/community/general/tests/integration/targets/java_keystore/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/java_keystore/meta/main.yml
new file mode 100644
index 000000000..0371df88e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/java_keystore/meta/main.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_java_keytool
+ - setup_openssl
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/java_keystore/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/java_keystore/tasks/main.yml
new file mode 100644
index 000000000..2a95cfe50
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/java_keystore/tasks/main.yml
@@ -0,0 +1,43 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- when: has_java_keytool
+ connection: local
+ block:
+ - name: Include tasks to create ssl materials on the controller
+ include_tasks: prepare.yml
+
+- set_fact:
+ ssl_backends: ['openssl']
+
+- set_fact:
+ ssl_backends: "{{ ssl_backends + ['cryptography'] }}"
+ when: cryptography_version.stdout is version('3.0', '>=')
+
+- when: has_java_keytool
+ block:
+ - name: Include tasks to play with 'certificate' and 'private_key' contents
+ include_tasks: tests.yml
+ vars:
+ remote_cert: false
+ loop: "{{ ssl_backends }}"
+ loop_control:
+ loop_var: ssl_backend
+
+ - name: Include tasks to create ssl materials on the remote host
+ include_tasks: prepare.yml
+
+ - name: Include tasks to play with 'certificate_path' and 'private_key_path' locations
+ include_tasks: tests.yml
+ vars:
+ remote_cert: true
+ loop: "{{ ssl_backends }}"
+ loop_control:
+ loop_var: ssl_backend
diff --git a/ansible_collections/community/general/tests/integration/targets/java_keystore/tasks/prepare.yml b/ansible_collections/community/general/tests/integration/targets/java_keystore/tasks/prepare.yml
new file mode 100644
index 000000000..7c4c5c98d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/java_keystore/tasks/prepare.yml
@@ -0,0 +1,37 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create test directory
+ ansible.builtin.file:
+ path: "{{ remote_tmp_dir }}"
+ state: directory
+
+- name: Create private keys
+ community.crypto.openssl_privatekey:
+ path: "{{ remote_tmp_dir ~ '/' ~ (item.keyname | default(item.name)) ~ '.key' }}"
+ size: 2048 # this should work everywhere
+ # The following is more efficient, but might not work everywhere:
+ # type: ECC
+ # curve: secp384r1
+ cipher: "{{ 'auto' if item.passphrase is defined else omit }}"
+ passphrase: "{{ item.passphrase | default(omit) }}"
+ loop: "{{ java_keystore_certs }}"
+
+- name: Create CSRs
+ community.crypto.openssl_csr:
+ path: "{{ remote_tmp_dir ~ '/' ~ item.name ~ '.csr' }}"
+ privatekey_path: "{{ remote_tmp_dir ~ '/' ~ (item.keyname | default(item.name)) ~ '.key' }}"
+ privatekey_passphrase: "{{ item.passphrase | default(omit) }}"
+ commonName: "{{ item.commonName }}"
+ loop: "{{ java_keystore_certs + java_keystore_new_certs }}"
+
+- name: Create certificates
+ community.crypto.x509_certificate:
+ path: "{{ remote_tmp_dir ~ '/' ~ item.name ~ '.pem' }}"
+ csr_path: "{{ remote_tmp_dir ~ '/' ~ item.name ~ '.csr' }}"
+ privatekey_path: "{{ remote_tmp_dir ~ '/' ~ (item.keyname | default(item.name)) ~ '.key' }}"
+ privatekey_passphrase: "{{ item.passphrase | default(omit) }}"
+ provider: selfsigned
+ loop: "{{ java_keystore_certs + java_keystore_new_certs }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/java_keystore/tasks/tests.yml b/ansible_collections/community/general/tests/integration/targets/java_keystore/tasks/tests.yml
new file mode 100644
index 000000000..899fe27e8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/java_keystore/tasks/tests.yml
@@ -0,0 +1,313 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create test directory
+ ansible.builtin.file:
+ path: "{{ remote_tmp_dir }}"
+ state: directory
+
+- name: Ensure the Java keystore does not exist (cleanup between tests)
+ ansible.builtin.file:
+ path: "{{ remote_tmp_dir ~ '/' ~ item.name ~ '.jks' }}"
+ state: absent
+ loop: "{{ java_keystore_certs }}"
+ loop_control:
+ label: "{{ remote_tmp_dir ~ '/' ~ item.name ~ '.jks' }}"
+
+
+- name: Read certificates
+ slurp:
+ src: "{{ remote_tmp_dir ~ '/' ~ item.name ~ '.pem' }}"
+ loop: "{{ java_keystore_certs }}"
+ when: not remote_cert
+ register: certificates
+
+- name: Read certificate keys
+ slurp:
+ src: "{{ remote_tmp_dir ~ '/' ~ (item.keyname | d(item.name)) ~ '.key' }}"
+ loop: "{{ java_keystore_certs }}"
+ when: not remote_cert
+ register: certificate_keys
+
+- name: Create a Java keystore for the given ({{ 'remote' if remote_cert else 'local' }}) certificates (check mode)
+ community.general.java_keystore: &java_keystore_params
+ name: example
+ dest: "{{ remote_tmp_dir ~ '/' ~ (item.keyname | d(item.name)) ~ '.jks' }}"
+ certificate: "{{ omit if remote_cert else (certificates.results[loop_index].content | b64decode) }}"
+ private_key: "{{ omit if remote_cert else (certificate_keys.results[loop_index].content | b64decode) }}"
+ certificate_path: "{{ omit if not remote_cert else remote_tmp_dir ~ '/' ~ item.name ~ '.pem' }}"
+ private_key_path: "{{ omit if not remote_cert else remote_tmp_dir ~ '/' ~ (item.keyname | d(item.name)) ~ '.key' }}"
+ private_key_passphrase: "{{ item.passphrase | d(omit) }}"
+ password: changeit
+ ssl_backend: "{{ ssl_backend }}"
+ keystore_type: "{{ item.keystore_type | d(omit) }}"
+ loop: "{{ java_keystore_certs }}"
+ loop_control:
+ index_var: loop_index
+ check_mode: true
+ register: result_check
+
+- name: Create a Java keystore for the given certificates
+ community.general.java_keystore: *java_keystore_params
+ loop: "{{ java_keystore_certs }}"
+ loop_control:
+ index_var: loop_index
+ register: result
+
+
+- name: Create a Java keystore for the given certificates (idempotency, check mode)
+ community.general.java_keystore: *java_keystore_params
+ loop: "{{ java_keystore_certs }}"
+ loop_control:
+ index_var: loop_index
+ check_mode: true
+ register: result_idem_check
+
+- name: Create a Java keystore for the given certificates (idempotency)
+ community.general.java_keystore: *java_keystore_params
+ loop: "{{ java_keystore_certs }}"
+ loop_control:
+ index_var: loop_index
+ register: result_idem
+
+
+- name: Read certificates (new)
+ slurp:
+ src: "{{ remote_tmp_dir ~ '/' ~ item.name ~ '.pem' }}"
+ loop: "{{ java_keystore_new_certs }}"
+ when: not remote_cert
+ register: certificates_new
+
+- name: Read certificate keys (new)
+ slurp:
+ src: "{{ remote_tmp_dir ~ '/' ~ (item.keyname | d(item.name)) ~ '.key' }}"
+ loop: "{{ java_keystore_new_certs }}"
+ when: not remote_cert
+ register: certificate_keys_new
+
+- name: Create a Java keystore for the given certificates (certificate changed, check mode)
+ community.general.java_keystore: &java_keystore_params_new_certs
+ name: example
+ dest: "{{ remote_tmp_dir ~ '/' ~ (item.keyname | d(item.name)) ~ '.jks' }}"
+ certificate: "{{ omit if remote_cert else (certificates_new.results[loop_index].content | b64decode) }}"
+ private_key: "{{ omit if remote_cert else (certificate_keys_new.results[loop_index].content | b64decode) }}"
+ certificate_path: "{{ omit if not remote_cert else remote_tmp_dir ~ '/' ~ item.name ~ '.pem' }}"
+ private_key_path: "{{ omit if not remote_cert else remote_tmp_dir ~ '/' ~ (item.keyname | d(item.name)) ~ '.key' }}"
+ private_key_passphrase: "{{ item.passphrase | d(omit) }}"
+ password: changeit
+ ssl_backend: "{{ ssl_backend }}"
+ keystore_type: "{{ item.keystore_type | d(omit) }}"
+ loop: "{{ java_keystore_new_certs }}"
+ loop_control:
+ index_var: loop_index
+ check_mode: true
+ register: result_change_check
+
+- name: Create a Java keystore for the given certificates (certificate changed)
+ community.general.java_keystore: *java_keystore_params_new_certs
+ loop: "{{ java_keystore_new_certs }}"
+ loop_control:
+ index_var: loop_index
+ register: result_change
+
+
+- name: Create a Java keystore for the given certificates (alias changed, check mode)
+ community.general.java_keystore:
+ <<: *java_keystore_params_new_certs
+ name: foobar
+ loop: "{{ java_keystore_new_certs }}"
+ loop_control:
+ index_var: loop_index
+ check_mode: true
+ register: result_alias_change_check
+
+- name: Create a Java keystore for the given certificates (alias changed)
+ community.general.java_keystore:
+ <<: *java_keystore_params_new_certs
+ name: foobar
+ loop: "{{ java_keystore_new_certs }}"
+ loop_control:
+ index_var: loop_index
+ register: result_alias_change
+
+
+- name: Create a Java keystore for the given certificates (password changed, check mode)
+ community.general.java_keystore:
+ <<: *java_keystore_params_new_certs
+ name: foobar
+ password: hunter2
+ loop: "{{ java_keystore_new_certs }}"
+ loop_control:
+ index_var: loop_index
+ check_mode: true
+ register: result_pw_change_check
+
+- name: Create a Java keystore for the given certificates (password changed)
+ community.general.java_keystore:
+ <<: *java_keystore_params_new_certs
+ name: foobar
+ password: hunter2
+ loop: "{{ java_keystore_new_certs }}"
+ loop_control:
+ index_var: loop_index
+ register: result_pw_change
+
+
+- name: Create a Java keystore for the given certificates (force keystore type pkcs12, check mode)
+ community.general.java_keystore:
+ <<: *java_keystore_params_new_certs
+ name: foobar
+ password: hunter2
+ keystore_type: pkcs12
+ loop: "{{ java_keystore_new_certs }}"
+ loop_control:
+ index_var: loop_index
+ check_mode: true
+ register: result_type_pkcs12_check
+
+- name: Create a Java keystore for the given certificates (force keystore type jks, check mode)
+ community.general.java_keystore:
+ <<: *java_keystore_params_new_certs
+ name: foobar
+ password: hunter2
+ keystore_type: jks
+ loop: "{{ java_keystore_new_certs }}"
+ loop_control:
+ index_var: loop_index
+ check_mode: true
+ register: result_type_jks_check
+
+- name: Create a Java keystore for the given certificates (force keystore type jks)
+ community.general.java_keystore:
+ <<: *java_keystore_params_new_certs
+ name: foobar
+ password: hunter2
+ keystore_type: jks
+ loop: "{{ java_keystore_new_certs }}"
+ loop_control:
+ index_var: loop_index
+ register: result_type_jks
+
+
+- name: Stat keystore (before failure)
+ ansible.builtin.stat:
+ path: "{{ remote_tmp_dir ~ '/' ~ (item.keyname | d(item.name)) ~ '.jks' }}"
+ loop: "{{ java_keystore_new_certs }}"
+ register: result_stat_before
+
+- name: Fail to create a Java keystore for the given certificates (password too short)
+ community.general.java_keystore:
+ <<: *java_keystore_params_new_certs
+ name: foobar
+ password: short
+ keystore_type: jks
+ loop: "{{ java_keystore_new_certs }}"
+ loop_control:
+ index_var: loop_index
+ register: result_fail_jks
+ ignore_errors: true
+
+- name: Stat keystore (after failure)
+ ansible.builtin.stat:
+ path: "{{ remote_tmp_dir ~ '/' ~ (item.keyname | d(item.name)) ~ '.jks' }}"
+ loop: "{{ java_keystore_new_certs }}"
+ register: result_stat_after
+
+
+- name: Create a Java keystore for the given certificates (keystore type changed, check mode)
+ community.general.java_keystore:
+ <<: *java_keystore_params_new_certs
+ name: foobar
+ password: hunter2
+ keystore_type: pkcs12
+ loop: "{{ java_keystore_new_certs }}"
+ loop_control:
+ index_var: loop_index
+ check_mode: true
+ register: result_type_change_check
+
+- name: Create a Java keystore for the given certificates (keystore type changed)
+ community.general.java_keystore:
+ <<: *java_keystore_params_new_certs
+ name: foobar
+ password: hunter2
+ keystore_type: pkcs12
+ loop: "{{ java_keystore_new_certs }}"
+ loop_control:
+ index_var: loop_index
+ register: result_type_change
+
+
+- name: Create a Java keystore for the given certificates (omit keystore type, check mode)
+ community.general.java_keystore:
+ <<: *java_keystore_params_new_certs
+ name: foobar
+ password: hunter2
+ loop: "{{ java_keystore_new_certs }}"
+ loop_control:
+ index_var: loop_index
+ check_mode: true
+ register: result_type_omit_check
+
+- name: Create a Java keystore for the given certificates (omit keystore type)
+ community.general.java_keystore:
+ <<: *java_keystore_params_new_certs
+ name: foobar
+ password: hunter2
+ loop: "{{ java_keystore_new_certs }}"
+ loop_control:
+ index_var: loop_index
+ register: result_type_omit
+
+
+- name: Check that the remote certificates have not been removed
+ ansible.builtin.file:
+ path: "{{ remote_tmp_dir ~ '/' ~ item.name ~ '.pem' }}"
+ state: file
+ loop: "{{ java_keystore_certs + java_keystore_new_certs }}"
+ when: remote_cert
+
+- name: Check that the remote private keys have not been removed
+ ansible.builtin.file:
+ path: "{{ remote_tmp_dir ~ '/' ~ item.name ~ '.key' }}"
+ state: file
+ loop: "{{ java_keystore_certs }}"
+ when: remote_cert
+
+- name: Validate results
+ assert:
+ that:
+ - result is changed
+ - result_check is changed
+ - result_idem is not changed
+ - result_idem_check is not changed
+ - result_change is changed
+ - result_change_check is changed
+ - result_alias_change is changed
+ - result_alias_change_check is changed
+ - result_pw_change is changed
+ - result_pw_change_check is changed
+
+ # We don't know if we start from jks or pkcs12 format, anyway check mode
+ # and actual mode must return the same 'changed' state, and 'jks' and
+ # 'pkcs12' must give opposite results on a same host.
+ - result_type_jks_check.changed != result_type_pkcs12_check.changed
+ - result_type_jks_check.changed == result_type_jks.changed
+
+ - result_type_change is changed
+ - result_type_change_check is changed
+ - result_type_omit is not changed
+ - result_type_omit_check is not changed
+
+ # keystore properties must remain the same after failure
+ - result_fail_jks is failed
+ - result_stat_before.results[0].stat.uid == result_stat_after.results[0].stat.uid
+ - result_stat_before.results[1].stat.uid == result_stat_after.results[1].stat.uid
+ - result_stat_before.results[0].stat.gid == result_stat_after.results[0].stat.gid
+ - result_stat_before.results[1].stat.gid == result_stat_after.results[1].stat.gid
+ - result_stat_before.results[0].stat.mode == result_stat_after.results[0].stat.mode
+ - result_stat_before.results[1].stat.mode == result_stat_after.results[1].stat.mode
+ - result_stat_before.results[0].stat.checksum == result_stat_after.results[0].stat.checksum
+ - result_stat_before.results[1].stat.checksum == result_stat_after.results[1].stat.checksum
diff --git a/ansible_collections/community/general/tests/integration/targets/jboss/aliases b/ansible_collections/community/general/tests/integration/targets/jboss/aliases
new file mode 100644
index 000000000..38b6706fe
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/jboss/aliases
@@ -0,0 +1,12 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+destructive
+skip/aix
+skip/osx
+skip/macos
+skip/freebsd
+skip/rhel
+needs/root
diff --git a/ansible_collections/community/general/tests/integration/targets/jboss/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/jboss/meta/main.yml
new file mode 100644
index 000000000..c2bf37df7
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/jboss/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+- setup_wildfly_server
diff --git a/ansible_collections/community/general/tests/integration/targets/jboss/tasks/jboss.yml b/ansible_collections/community/general/tests/integration/targets/jboss/tasks/jboss.yml
new file mode 100644
index 000000000..2403a02c4
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/jboss/tasks/jboss.yml
@@ -0,0 +1,238 @@
+---
+# Copyright (c) 2019, Andrew Klychkov (@Andersson007) <aaklychkov@mail.ru>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# Integration tests for jboss module.
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# helloworld.war (got from https://github.com/aeimer/java-example-helloworld-war/) is licensed
+# under the MIT license:
+#
+# Copyright (c) 2017 Alex Eimer
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+# ===============================
+# Module's note section contains:
+# "- The JBoss standalone deployment-scanner has to be enabled in standalone.xml"
+#
+# Also from https://docs.jboss.org/author/display/WFLY10/Application+deployment?_sscc=t
+# "Deployment content (for example, war, ear, jar, and sar files) can be placed
+# in the standalone/deployments directory of the WildFly distribution,
+# in order to be automatically deployed into the server runtime.
+# For this to work the deployment-scanner subsystem must be present.
+# The scanner periodically checks the contents of the deployments directory
+# and reacts to changes by updating the server."
+# Regarding the information above JBoss server must be installed and running for full test suite.
+# We use WildFly server, free alternative, instead. See setup_wildfly_server role for more information.
+
+- vars:
+ war_file_1: 'helloworld-1.war'
+ war_file_1_path: '{{ wf_homedir }}/{{ war_file_1 }}'
+ fake_src_path: /fake/src
+ test_deployment: helloworld-1.war
+ task_parameters: &task_parameters
+ become_user: '{{ wf_user }}'
+ become: true
+ register: result
+
+ block:
+ - name: Create test files
+ <<: *task_parameters
+ get_url:
+ url: 'https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/jboss/{{ war_file_1 }}'
+ dest: '{{ wf_homedir }}'
+
+ ##################
+ # Start the tests:
+
+ # Test if state=present and not deployed, check_mode:
+ - name: jboss - deploy war in check_mode, the default deploy_path
+ <<: *task_parameters
+ jboss:
+ deployment: '{{ war_file_1 }}'
+ src: '{{ war_file_1_path }}'
+ check_mode: true
+
+ - assert:
+ that:
+ - result is changed
+
+ # Check
+ - name: check that nothing changed after the previous step
+ <<: *task_parameters
+ file:
+ path: '{{ deploy_dir }}/{{ war_file_1 }}.deployed'
+ ignore_errors: true
+
+ - assert:
+ that:
+ - "'is absent' in result.msg"
+
+ # Test if state=present and not deployed, actual mode:
+ - name: jboss - deploy war
+ <<: *task_parameters
+ jboss:
+ deployment: helloworld-1.war
+ deploy_path: '{{ deploy_dir }}'
+ src: '{{ war_file_1_path }}'
+
+ - assert:
+ that:
+ - result is changed
+
+ # Check
+ - name: check that the file is deployed after the previous step
+ <<: *task_parameters
+ file:
+ path: '{{ deploy_dir }}/{{ war_file_1 }}.deployed'
+
+ - assert:
+ that:
+ - result.state == 'file'
+
+ # Test if state=present and deployed in check mode, try again:
+ - name: jboss - try again to deploy war in check_mode, war is deployed now
+ <<: *task_parameters
+ jboss:
+ deployment: '{{ war_file_1 }}'
+ src: '{{ war_file_1_path }}'
+ deploy_path: '{{ deploy_dir }}'
+ check_mode: true
+
+ - assert:
+ that:
+ - result is not changed
+
+ # Test if state=present and deployed, try again:
+ - name: jboss - try again to deploy war in actual mode, war is deployed now
+ <<: *task_parameters
+ jboss:
+ deployment: '{{ war_file_1 }}'
+ src: '{{ war_file_1_path }}'
+ deploy_path: '{{ deploy_dir }}'
+
+ - assert:
+ that:
+ - result is not changed
+
+ # Check
+ - name: check that nothing changed after the previous step
+ <<: *task_parameters
+ file:
+ path: '{{ deploy_dir }}/{{ war_file_1 }}.deployed'
+
+ - assert:
+ that:
+ - result.state == 'file'
+
+ # Test if state=absent and deployed:
+ - name: jboss - undeploy war in check_mode, war is deployed
+ <<: *task_parameters
+ jboss:
+ deployment: '{{ war_file_1 }}'
+ deploy_path: '{{ deploy_dir }}'
+ state: absent
+ check_mode: true
+
+ - assert:
+ that:
+ - result is changed
+
+ - name: check that nothing actually changed after the previous step
+ <<: *task_parameters
+ file:
+ path: '{{ deploy_dir }}/{{ war_file_1 }}.deployed'
+
+ - assert:
+ that:
+ - result.state == 'file'
+
+ # Test if state=absent and deployed:
+ - name: jboss - undeploy war in actual mode, war is deployed
+ <<: *task_parameters
+ jboss:
+ deployment: '{{ war_file_1 }}'
+ deploy_path: '{{ deploy_dir }}'
+ state: absent
+
+ - assert:
+ that:
+ - result is changed
+
+ - name: check that file is undeployed after the previous step
+ <<: *task_parameters
+ file:
+ path: '{{ deploy_dir }}/{{ war_file_1 }}.undeployed'
+
+ - assert:
+ that:
+ - result.state == 'file'
+
+ # Test if state=absent and undeployed:
+ - name: jboss - undeploy war in check_mode, war is undeployed
+ <<: *task_parameters
+ jboss:
+ deployment: '{{ war_file_1 }}'
+ deploy_path: '{{ deploy_dir }}'
+ state: absent
+ check_mode: true
+
+ - assert:
+ that:
+ - result is not changed
+
+ # Test if state=absent and undeployed:
+ - name: jboss - undeploy war in actual_mode, war is undeployed
+ <<: *task_parameters
+ jboss:
+ deployment: '{{ war_file_1 }}'
+ deploy_path: '{{ deploy_dir }}'
+ state: absent
+
+ - assert:
+ that:
+ - result is not changed
+
+ # Test fake src:
+ - name: jboss - test fake src
+ <<: *task_parameters
+ jboss:
+ deployment: '{{ war_file_1 }}'
+ deploy_path: '{{ deploy_dir }}'
+ src: '{{ fake_src_path }}'
+ state: present
+ ignore_errors: true
+
+ - assert:
+ that:
+ - result is failed
+ - "'Source file {{ fake_src_path }} does not exist.' in result.msg"
+
+ # Test errors where state=present and src is not passed:
+ - name: jboss - must fail when state=present and src is not passed
+ <<: *task_parameters
+ jboss:
+ deployment: '{{ war_file_1 }}'
+ state: present
+ ignore_errors: true
+
+ - assert:
+ that:
+ - result is failed
+ - "'state is present but all of the following are missing: src' in result.msg"
diff --git a/ansible_collections/community/general/tests/integration/targets/jboss/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/jboss/tasks/main.yml
new file mode 100644
index 000000000..891c802d7
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/jboss/tasks/main.yml
@@ -0,0 +1,11 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- import_tasks: jboss.yml
diff --git a/ansible_collections/community/general/tests/integration/targets/jira/aliases b/ansible_collections/community/general/tests/integration/targets/jira/aliases
new file mode 100644
index 000000000..9c3dc5670
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/jira/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/3
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/jira/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/jira/tasks/main.yml
new file mode 100644
index 000000000..129070871
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/jira/tasks/main.yml
@@ -0,0 +1,111 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: create test ticket
+ community.general.jira:
+ uri: "{{ uri }}"
+ username: "{{ user }}"
+ password: "{{ pasw }}"
+ project: "{{ proj }}"
+ operation: create
+ summary: test ticket
+ description: bla bla bla
+ issuetype: Task
+ register: issue
+- debug:
+ msg: Issue={{ issue }}
+- name: assert test ticket
+ assert:
+ that:
+ - issue is changed
+ - issue.meta.key.startswith(proj)
+
+- name: add comment bleep bleep
+ community.general.jira:
+ uri: "{{ uri }}"
+ username: "{{ user }}"
+ password: "{{ pasw }}"
+ issue: "{{ issue.meta.key }}"
+ operation: comment
+ comment: bleep bleep!
+ register: comment_bleep_bleep
+- name: assert comment bleep bleep
+ assert:
+ that:
+ - comment_bleep_bleep is changed
+ - comment_bleep_bleep.meta.body == "bleep bleep!"
+ - comment_bleep_bleep.meta.body != None
+
+- name: transition -> In Progress with comment
+ community.general.jira:
+ uri: "{{ uri }}"
+ username: "{{ user }}"
+ password: "{{ pasw }}"
+ issue: "{{ issue.meta.key }}"
+ operation: transition
+ status: Start Progress
+ comment: -> in progress
+ register: transition_inprog
+- name: assert transition -> In Progress with comment
+ assert:
+ that:
+ - transition_inprog is changed
+
+- name: change assignee
+ community.general.jira:
+ uri: "{{ uri }}"
+ username: "{{ user }}"
+ password: "{{ pasw }}"
+ issue: "{{ issue.meta.key }}"
+ operation: edit
+ account_id: "{{ user2 }}"
+ register: assign
+- name: assert change assignee
+ assert:
+ that:
+ - assign is changed
+
+- name: Worklog on issue
+ community.general.jira:
+ uri: '{{ server }}'
+ username: '{{ user }}'
+ password: '{{ pass }}'
+ issue: '{{ issue.meta.key }}'
+ operation: worklog
+ comment: Worklog
+ fields:
+ timeSpentSeconds: 1200
+ register: worklog
+- name: assert worklog -> with comment
+ assert:
+ that:
+ - worklog is changed
+ - worklog.meta.comment == 'Worklog'
+ - worklog.meta.timeSpentSeconds == 1200
+
+- name: transition -> Resolved with comment
+ community.general.jira:
+ uri: "{{ uri }}"
+ username: "{{ user }}"
+ password: "{{ pasw }}"
+ issue: "{{ issue.meta.key }}"
+ operation: transition
+ status: Resolve Issue
+ comment: -> resolved
+ account_id: "{{ user1 }}"
+ fields:
+ resolution:
+ name: Done
+ description: wakawakawakawaka
+ register: transition_resolved
+- name: assert transition -> Resolved with comment
+ assert:
+ that:
+ - transition_resolved is changed
+
+- debug:
+ msg:
+ - Issue = {{ issue.meta.key }}
+ - URL = {{ issue.meta.self }}
diff --git a/ansible_collections/community/general/tests/integration/targets/jira/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/jira/vars/main.yml
new file mode 100644
index 000000000..781fde8ca
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/jira/vars/main.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+uri: https://xxxx.atlassian.net/
+user: xxx@xxxx.xxx
+pasw: supersecret
+proj: ABC
+user1: 6574474636373822y7338
+user2: 6574474636373822y73959696
diff --git a/ansible_collections/community/general/tests/integration/targets/kdeconfig/aliases b/ansible_collections/community/general/tests/integration/targets/kdeconfig/aliases
new file mode 100644
index 000000000..12d1d6617
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/kdeconfig/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
diff --git a/ansible_collections/community/general/tests/integration/targets/kdeconfig/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/kdeconfig/meta/main.yml
new file mode 100644
index 000000000..982de6eb0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/kdeconfig/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/kdeconfig/tasks/files/kwriteconf_fake b/ansible_collections/community/general/tests/integration/targets/kdeconfig/tasks/files/kwriteconf_fake
new file mode 100755
index 000000000..c29627257
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/kdeconfig/tasks/files/kwriteconf_fake
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+# Copyright (c) 2023, Salvatore Mesoraca <s.mesoraca16@gmail.com>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# This script is not supposed to correctly emulate
+# kwriteconf output format.
+# It only tries to emulate its behaviour from the
+# point of view of the Ansible module.
+# Which is: write something that depends on the arguments
+# to the output file, unless we already wrote that before.
+
+set -e
+
+args=""
+prev_was_file=0
+for var in "$@"; do
+ if [ $prev_was_file -eq 1 ]; then
+ fname="$var"
+ prev_was_file=0
+ else
+ args="$args $var"
+ fi
+ if [ "$var" = "--file" ]; then
+ prev_was_file=1
+ fi
+done
+
+if [ "x$fname" = "x" ]; then
+ exit 1
+fi
+
+if [ -e "$fname" ]; then
+ grep -qF "$args" "$fname" && exit 0
+fi
+
+echo "$args" >> "$fname"
diff --git a/ansible_collections/community/general/tests/integration/targets/kdeconfig/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/kdeconfig/tasks/main.yml
new file mode 100644
index 000000000..790bb378d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/kdeconfig/tasks/main.yml
@@ -0,0 +1,369 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2023, Salvatore Mesoraca <s.mesoraca16@gmail.com>
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Set paths
+ set_fact:
+ output_file: "{{ remote_tmp_dir }}/kdeconf"
+ kwriteconf_fake: "{{ remote_tmp_dir }}/kwriteconf"
+
+- name: Install fake kwriteconf
+ copy:
+ dest: "{{ kwriteconf_fake }}"
+ src: kwriteconf_fake
+ mode: 0755
+
+- name: Simple test
+ kdeconfig:
+ path: "{{ output_file }}"
+ values:
+ - group: test
+ key: test1
+ value: test2
+ kwriteconfig_path: "{{ kwriteconf_fake }}"
+ register: result_simple
+ ignore_errors: true
+
+- name: Simple test - checks
+ assert:
+ that:
+ - result_simple is changed
+ - result_simple is not failed
+
+- name: Simple test - idempotence
+ kdeconfig:
+ path: "{{ output_file }}"
+ values:
+ - group: test
+ key: test1
+ value: test2
+ kwriteconfig_path: "{{ kwriteconf_fake }}"
+ register: result_simple_idem
+ ignore_errors: true
+
+- name: Simple test - idempotence - checks
+ assert:
+ that:
+ - result_simple_idem is not changed
+ - result_simple_idem is not failed
+
+- name: Reset
+ file:
+ path: "{{ output_file }}"
+ state: absent
+
+- name: Group and groups are mutually exclusive
+ kdeconfig:
+ path: "{{ output_file }}"
+ values:
+ - group: test
+ groups: [test2]
+ key: test1
+ value: test2
+ kwriteconfig_path: "{{ kwriteconf_fake }}"
+ register: result_group_mutex
+ ignore_errors: true
+
+- name: Group and groups are mutually exclusive - checks
+ assert:
+ that:
+ - result_group_mutex is not changed
+ - result_group_mutex is failed
+ - "result_group_mutex.msg == 'parameters are mutually exclusive: group|groups found in values'"
+
+- name: value and bool_value are mutually exclusive
+ kdeconfig:
+ path: "{{ output_file }}"
+ values:
+ - group: test
+ key: test1
+ value: test2
+ bool_value: true
+ kwriteconfig_path: "{{ kwriteconf_fake }}"
+ register: result_val_mutex
+ ignore_errors: true
+
+- name: value and bool_value are mutually exclusive - checks
+ assert:
+ that:
+ - result_val_mutex is not changed
+ - result_val_mutex is failed
+ - "result_val_mutex.msg == 'parameters are mutually exclusive: value|bool_value found in values'"
+
+- name: bool_value must be bool
+ kdeconfig:
+ path: "{{ output_file }}"
+ values:
+ - group: test
+ key: test1
+ bool_value: thisisastring
+ kwriteconfig_path: "{{ kwriteconf_fake }}"
+ register: result_val_bool
+ ignore_errors: true
+
+- name: bool_value must be bool - checks
+ assert:
+ that:
+ - result_val_bool is not changed
+ - result_val_bool is failed
+ - "'is not a valid boolean' in result_val_bool.msg"
+
+- name: Multiple groups test
+ kdeconfig:
+ path: "{{ output_file }}"
+ values:
+ - groups:
+ - test
+ - test1
+ - test2
+ key: test3
+ value: test4
+ kwriteconfig_path: "{{ kwriteconf_fake }}"
+ register: result_groups
+ ignore_errors: true
+
+- name: Multiple groups test - checks
+ assert:
+ that:
+ - result_groups is changed
+ - result_groups is not failed
+
+- name: Multiple groups test - idempotence
+ kdeconfig:
+ path: "{{ output_file }}"
+ values:
+ - groups:
+ - test
+ - test1
+ - test2
+ key: test3
+ value: test4
+ kwriteconfig_path: "{{ kwriteconf_fake }}"
+ register: result_groups_idem
+ ignore_errors: true
+
+- name: Multiple groups test - idempotence - checks
+ assert:
+ that:
+ - result_groups_idem is not changed
+ - result_groups_idem is not failed
+
+- name: Reset
+ file:
+ path: "{{ output_file }}"
+ state: absent
+
+- name: Bool test
+ kdeconfig:
+ path: "{{ output_file }}"
+ values:
+ - group: test
+ key: test1
+ bool_value: true
+ kwriteconfig_path: "{{ kwriteconf_fake }}"
+ register: result_bool
+ ignore_errors: true
+
+- name: Simple test - checks
+ assert:
+ that:
+ - result_bool is changed
+ - result_bool is not failed
+
+- name: Bool test - idempotence
+ kdeconfig:
+ path: "{{ output_file }}"
+ values:
+ - group: test
+ key: test1
+ bool_value: on
+ kwriteconfig_path: "{{ kwriteconf_fake }}"
+ register: result_bool_idem
+ ignore_errors: true
+
+- name: Bool test - idempotence - checks
+ assert:
+ that:
+ - result_bool_idem is not changed
+ - result_bool_idem is not failed
+
+- name: Reset
+ file:
+ path: "{{ output_file }}"
+ state: absent
+
+- name: check_mode test
+ kdeconfig:
+ path: "{{ output_file }}"
+ values:
+ - group: test
+ key: test1
+ value: test2
+ - groups: [testx, testy]
+ key: testz
+ bool_value: on
+ kwriteconfig_path: "{{ kwriteconf_fake }}"
+ register: result_checkmode
+ ignore_errors: true
+ check_mode: true
+ diff: true
+
+- name: check_mode test file contents
+ slurp:
+ src: "{{ output_file }}"
+ register: check_mode_contents
+ ignore_errors: true
+
+- name: check_mode test - checks
+ assert:
+ that:
+ - result_checkmode is changed
+ - result_checkmode is not failed
+ - check_mode_contents is failed
+
+- name: check_mode test - apply
+ kdeconfig:
+ path: "{{ output_file }}"
+ values:
+ - group: test
+ key: test1
+ value: test2
+ - groups: [testx, testy]
+ key: testz
+ bool_value: on
+ kwriteconfig_path: "{{ kwriteconf_fake }}"
+ register: result_checkmode_apply
+ ignore_errors: true
+ check_mode: false
+ diff: true
+
+- name: check_mode test - apply - checks
+ assert:
+ that:
+ - result_checkmode_apply is changed
+ - result_checkmode_apply is not failed
+ - "result_checkmode_apply['diff']['after'] == result_checkmode['diff']['after']"
+ - "result_checkmode_apply['diff']['before'] == result_checkmode['diff']['before']"
+
+- name: check_mode test - idempotence
+ kdeconfig:
+ path: "{{ output_file }}"
+ values:
+ - group: test
+ key: test1
+ value: test2
+ - groups: [testx, testy]
+ key: testz
+ bool_value: on
+ kwriteconfig_path: "{{ kwriteconf_fake }}"
+ register: result_checkmode2
+ ignore_errors: true
+ check_mode: true
+
+- name: check_mode test - idempotence - checks
+ assert:
+ that:
+ - result_checkmode2 is not changed
+ - result_checkmode2 is not failed
+
+- name: Reset
+ file:
+ path: "{{ output_file }}"
+ state: absent
+
+- name: Unicode test
+ kdeconfig:
+ path: "{{ output_file }}"
+ values:
+ - group: tesòt
+ key: testè1
+ value: testù2
+ kwriteconfig_path: "{{ kwriteconf_fake }}"
+ register: result_unicode
+ ignore_errors: true
+
+- name: Unicode test - checks
+ assert:
+ that:
+ - result_unicode is changed
+ - result_unicode is not failed
+
+- name: Reset
+ file:
+ path: "{{ output_file }}"
+ state: absent
+
+- name: Missing groups
+ kdeconfig:
+ path: "{{ output_file }}"
+ values:
+ - key: test1
+ value: test2
+ kwriteconfig_path: "{{ kwriteconf_fake }}"
+ register: result_mgroup
+ ignore_errors: true
+
+- name: Missing groups - checks
+ assert:
+ that:
+ - result_mgroup is not changed
+ - result_mgroup is failed
+ - "result_mgroup.msg == 'one of the following is required: group, groups found in values'"
+
+- name: Missing key
+ kdeconfig:
+ path: "{{ output_file }}"
+ values:
+ - group: test1
+ value: test2
+ kwriteconfig_path: "{{ kwriteconf_fake }}"
+ register: result_mkey
+ ignore_errors: true
+
+- name: Missing key - checks
+ assert:
+ that:
+ - result_mkey is not changed
+ - result_mkey is failed
+ - "result_mkey.msg == 'missing required arguments: key found in values'"
+
+- name: Missing value
+ kdeconfig:
+ path: "{{ output_file }}"
+ values:
+ - group: test1
+ key: test2
+ kwriteconfig_path: "{{ kwriteconf_fake }}"
+ register: result_mvalue
+ ignore_errors: true
+
+- name: Missing value - checks
+ assert:
+ that:
+ - result_mvalue is not changed
+ - result_mvalue is failed
+ - "result_mvalue.msg == 'one of the following is required: value, bool_value found in values'"
+
+- name: Empty key
+ kdeconfig:
+ path: "{{ output_file }}"
+ values:
+ - group: test1
+ key: ''
+ value: test2
+ kwriteconfig_path: "{{ kwriteconf_fake }}"
+ register: result_ekey
+ ignore_errors: true
+
+- name: Empty key - checks
+ assert:
+ that:
+ - result_ekey is not changed
+ - result_ekey is failed
+ - "result_ekey.msg == \"'key' cannot be empty\""
diff --git a/ansible_collections/community/general/tests/integration/targets/kernel_blacklist/aliases b/ansible_collections/community/general/tests/integration/targets/kernel_blacklist/aliases
new file mode 100644
index 000000000..afda346c4
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/kernel_blacklist/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
diff --git a/ansible_collections/community/general/tests/integration/targets/kernel_blacklist/files/blacklist b/ansible_collections/community/general/tests/integration/targets/kernel_blacklist/files/blacklist
new file mode 100644
index 000000000..eeaf32246
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/kernel_blacklist/files/blacklist
@@ -0,0 +1,7 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+blacklist aaaa
+blacklist bbbb
+blacklist cccc
diff --git a/ansible_collections/community/general/tests/integration/targets/kernel_blacklist/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/kernel_blacklist/meta/main.yml
new file mode 100644
index 000000000..982de6eb0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/kernel_blacklist/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/kernel_blacklist/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/kernel_blacklist/tasks/main.yml
new file mode 100644
index 000000000..e169d5479
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/kernel_blacklist/tasks/main.yml
@@ -0,0 +1,111 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: set destination filename
+ set_fact:
+ bl_file: '{{ remote_tmp_dir }}/blacklist-ansible.conf'
+
+- name: copy blacklist file
+ copy:
+ src: 'files/blacklist'
+ dest: '{{ bl_file }}'
+
+- name: Original stat
+ stat:
+ path: '{{ bl_file }}'
+ register: orig_stat
+
+- name: remove non-existing item from list
+ community.general.kernel_blacklist:
+ blacklist_file: '{{ bl_file }}'
+ state: absent
+ name: zzzz
+ register: bl_test_1
+
+- name: add existing item from list
+ community.general.kernel_blacklist:
+ blacklist_file: '{{ bl_file }}'
+ state: present
+ name: bbbb
+ register: bl_test_1a
+
+- name: stat_test_1
+ stat:
+ path: '{{ bl_file }}'
+ register: stat_test_1
+
+- name: assert file is unchanged
+ assert:
+ that:
+ - bl_test_1 is not changed
+ - bl_test_1a is not changed
+ - orig_stat.stat.size == stat_test_1.stat.size
+ - orig_stat.stat.checksum == stat_test_1.stat.checksum
+ - orig_stat.stat.mtime == stat_test_1.stat.mtime
+ - stat_test_1.stat.checksum == expected_content | checksum
+ vars:
+ expected_content: |
+ # Copyright (c) Ansible Project
+ # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+ # SPDX-{{ '' }}License-Identifier: GPL-3.0-or-later
+
+ blacklist aaaa
+ blacklist bbbb
+ blacklist cccc
+
+- name: add new item to list
+ community.general.kernel_blacklist:
+ blacklist_file: '{{ bl_file }}'
+ state: present
+ name: dddd
+ register: bl_test_2
+
+- name: slurp_test_2
+ slurp:
+ src: '{{ bl_file }}'
+ register: slurp_test_2
+
+- name: assert element is added
+ assert:
+ that:
+ - bl_test_2 is changed
+ - slurp_test_2.content|b64decode == content
+ vars:
+ content: |
+ # Copyright (c) Ansible Project
+ # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+ # SPDX-{{ '' }}License-Identifier: GPL-3.0-or-later
+
+ blacklist aaaa
+ blacklist bbbb
+ blacklist cccc
+ blacklist dddd
+
+- name: remove item from list
+ community.general.kernel_blacklist:
+ blacklist_file: '{{ bl_file }}'
+ state: absent
+ name: bbbb
+ register: bl_test_3
+
+- name: slurp_test_3
+ slurp:
+ src: '{{ bl_file }}'
+ register: slurp_test_3
+
+- name: assert element is added
+ assert:
+ that:
+ - bl_test_3 is changed
+ - slurp_test_3.content|b64decode == content
+ vars:
+ content: |
+ # Copyright (c) Ansible Project
+ # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+ # SPDX-{{ '' }}License-Identifier: GPL-3.0-or-later
+
+ blacklist aaaa
+ blacklist cccc
+ blacklist dddd
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_authz_authorization_scope/aliases b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_authorization_scope/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_authorization_scope/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_authz_authorization_scope/readme.adoc b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_authorization_scope/readme.adoc
new file mode 100644
index 000000000..1941e54ef
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_authorization_scope/readme.adoc
@@ -0,0 +1,27 @@
+// Copyright (c) Ansible Project
+// GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+To be able to run these integration tests a keycloak server must be
+reachable under a specific url with a specific admin user and password.
+The exact values expected for these parameters can be found in
+'vars/main.yml' file. A simple way to do this is to use the official
+keycloak docker images like this:
+
+----
+docker run --name mykeycloak -p 8080:8080 -e KC_HTTP_RELATIVE_PATH=<url-path> -e KEYCLOAK_ADMIN=<admin_user> -e KEYCLOAK_ADMIN_PASSWORD=<admin_password> quay.io/keycloak/keycloak:20.0.2 start-dev
+----
+
+Example with concrete values inserted:
+
+----
+docker run --name mykeycloak -p 8080:8080 -e KC_HTTP_RELATIVE_PATH=/auth -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=password quay.io/keycloak/keycloak:20.0.2 start-dev
+----
+
+This test suite can run against a fresh unconfigured server instance
+(no preconfiguration required) and cleans up after itself (undoes all
+its config changes) as long as it runs through completly. While its active
+it changes the server configuration in the following ways:
+
+ * creating, modifying and deleting some keycloak groups
+
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_authz_authorization_scope/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_authorization_scope/tasks/main.yml
new file mode 100644
index 000000000..504a24a01
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_authorization_scope/tasks/main.yml
@@ -0,0 +1,234 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+- name: Remove keycloak client to avoid failures from previous failed runs
+ community.general.keycloak_client:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ state: absent
+
+- name: Create keycloak client with authorization services enabled
+ community.general.keycloak_client:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ state: present
+ enabled: true
+ public_client: false
+ service_accounts_enabled: true
+ authorization_services_enabled: true
+
+- name: Create an authorization scope (check mode)
+ community.general.keycloak_authz_authorization_scope:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: present
+ name: "file:delete"
+ display_name: "File delete"
+ icon_uri: "http://localhost/icon.png"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ check_mode: true
+ diff: true
+ register: result
+
+- name: Assert that authorization scope was not created in check mode
+ assert:
+ that:
+ - result is changed
+ - result.end_state == {}
+ - result.msg == 'Authorization scope would be created'
+ - result.diff.before == {}
+ - result.diff.after.name == 'file:delete'
+ - result.diff.after.displayName == 'File delete'
+ - result.diff.after.iconUri == 'http://localhost/icon.png'
+
+- name: Create authorization scope
+ community.general.keycloak_authz_authorization_scope:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: present
+ name: "file:delete"
+ display_name: "File delete"
+ icon_uri: "http://localhost/icon.png"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert that authorization scope was created
+ assert:
+ that:
+ - result is changed
+ - result.end_state != {}
+ - result.end_state.name == "file:delete"
+ - result.end_state.iconUri == "http://localhost/icon.png"
+ - result.end_state.displayName == "File delete"
+
+- name: Create authorization scope (test for idempotency)
+ community.general.keycloak_authz_authorization_scope:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: present
+ name: "file:delete"
+ display_name: "File delete"
+ icon_uri: "http://localhost/icon.png"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert that nothing has changed
+ assert:
+ that:
+ - result is not changed
+ - result.end_state != {}
+ - result.end_state.name == "file:delete"
+ - result.end_state.iconUri == "http://localhost/icon.png"
+ - result.end_state.displayName == "File delete"
+
+- name: Authorization scope update (check mode)
+ community.general.keycloak_authz_authorization_scope:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: present
+ name: "file:delete"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ diff: true
+ check_mode: true
+ register: result
+
+- name: Assert that authorization scope was not updated in check mode
+ assert:
+ that:
+ - result is changed
+ - result.msg == 'Authorization scope would be updated'
+ - result.diff.before.displayName == 'File delete'
+ - result.diff.before.iconUri == 'http://localhost/icon.png'
+ - result.diff.after.displayName == ''
+ - result.diff.after.iconUri == ''
+
+- name: Authorization scope update (remove optional parameters)
+ community.general.keycloak_authz_authorization_scope:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: present
+ name: "file:delete"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert that optional parameters have been removed
+ assert:
+ that:
+ - result is changed
+ - result.end_state != {}
+ - result.end_state.name == "file:delete"
+ - result.end_state.iconUri == ""
+ - result.end_state.displayName == ""
+
+- name: Authorization scope update (test for idempotency)
+ community.general.keycloak_authz_authorization_scope:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: present
+ name: "file:delete"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert that nothing has changed
+ assert:
+ that:
+ - result is not changed
+ - result.end_state != {}
+ - result.end_state.name == "file:delete"
+ - result.end_state.iconUri == ""
+ - result.end_state.displayName == ""
+
+- name: Authorization scope remove (check mode)
+ community.general.keycloak_authz_authorization_scope:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: absent
+ name: "file:delete"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ diff: true
+ check_mode: true
+ register: result
+
+- name: Assert that authorization scope has not been removed in check mode
+ assert:
+ that:
+ - result is changed
+ - result.msg == 'Authorization scope would be removed'
+ - result.diff.before.name == 'file:delete'
+ - result.diff.after == {}
+
+- name: Authorization scope remove
+ community.general.keycloak_authz_authorization_scope:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: absent
+ name: "file:delete"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert that authorization scope has been removed
+ assert:
+ that:
+ - result is changed
+ - result.end_state == {}
+
+- name: Authorization scope remove (test for idempotency)
+ community.general.keycloak_authz_authorization_scope:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ state: absent
+ name: "file:delete"
+ client_id: "{{ client_id }}"
+ realm: "{{ realm }}"
+ register: result
+
+- name: Assert that nothing has changed
+ assert:
+ that:
+ - result is not changed
+ - result.end_state == {}
+
+- name: Remove keycloak client
+ community.general.keycloak_client:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_authz_authorization_scope/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_authorization_scope/vars/main.yml
new file mode 100644
index 000000000..c1d5fc983
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_authz_authorization_scope/vars/main.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+url: http://localhost:8080/auth
+admin_realm: master
+admin_user: admin
+admin_password: password
+realm: master
+client_id: authz
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_client/README.md b/ansible_collections/community/general/tests/integration/targets/keycloak_client/README.md
new file mode 100644
index 000000000..d8bcc08ec
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_client/README.md
@@ -0,0 +1,17 @@
+<!--
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+-->
+
+The integration test can be performed as follows:
+
+```
+# 1. Start docker-compose:
+docker-compose -f tests/integration/targets/keycloak_client/docker-compose.yml stop
+docker-compose -f tests/integration/targets/keycloak_client/docker-compose.yml rm -f -v
+docker-compose -f tests/integration/targets/keycloak_client/docker-compose.yml up -d
+
+# 2. Run the integration tests:
+ansible-test integration keycloak_client --allow-unsupported -v
+```
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_client/docker-compose.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_client/docker-compose.yml
new file mode 100644
index 000000000..5e14e9aac
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_client/docker-compose.yml
@@ -0,0 +1,31 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+version: '3.4'
+
+services:
+ postgres:
+ image: postgres:9.6
+ restart: always
+ environment:
+ POSTGRES_USER: postgres
+ POSTGRES_DB: postgres
+ POSTGRES_PASSWORD: postgres
+
+ keycloak:
+ image: jboss/keycloak:12.0.4
+ ports:
+ - 8080:8080
+
+ environment:
+ DB_VENDOR: postgres
+ DB_ADDR: postgres
+ DB_DATABASE: postgres
+ DB_USER: postgres
+ DB_SCHEMA: public
+ DB_PASSWORD: postgres
+
+ KEYCLOAK_USER: admin
+ KEYCLOAK_PASSWORD: password
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_client/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_client/tasks/main.yml
new file mode 100644
index 000000000..513d5836b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_client/tasks/main.yml
@@ -0,0 +1,63 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Delete realm
+ community.general.keycloak_realm: "{{ auth_args | combine(call_args) }}"
+ vars:
+ call_args:
+ id: "{{ realm }}"
+ realm: "{{ realm }}"
+ state: absent
+
+- name: Create realm
+ community.general.keycloak_realm: "{{ auth_args | combine(call_args) }}"
+ vars:
+ call_args:
+ id: "{{ realm }}"
+ realm: "{{ realm }}"
+ state: present
+
+- name: Desire client
+ community.general.keycloak_client: "{{ auth_args | combine(call_args) }}"
+ vars:
+ call_args:
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ state: present
+ redirect_uris: '{{redirect_uris1}}'
+ attributes: '{{client_attributes1}}'
+ protocol_mappers: '{{protocol_mappers1}}'
+ register: desire_client_not_present
+
+- name: Desire client again with same props
+ community.general.keycloak_client: "{{ auth_args | combine(call_args) }}"
+ vars:
+ call_args:
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ state: present
+ redirect_uris: '{{redirect_uris1}}'
+ attributes: '{{client_attributes1}}'
+ protocol_mappers: '{{protocol_mappers1}}'
+ register: desire_client_when_present_and_same
+
+- name: Check client again with same props
+ community.general.keycloak_client: "{{ auth_args | combine(call_args) }}"
+ check_mode: true
+ vars:
+ call_args:
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ state: present
+ redirect_uris: '{{redirect_uris1}}'
+ attributes: '{{client_attributes1}}'
+ protocol_mappers: '{{protocol_mappers1}}'
+ register: check_client_when_present_and_same
+
+- name: Assert changes not detected in last two tasks (desire when same, and check)
+ assert:
+ that:
+ - desire_client_when_present_and_same is not changed
+ - check_client_when_present_and_same is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_client/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_client/vars/main.yml
new file mode 100644
index 000000000..53ba35fca
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_client/vars/main.yml
@@ -0,0 +1,61 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+url: http://localhost:8080/auth
+admin_realm: master
+admin_user: admin
+admin_password: password
+realm: myrealm
+client_id: myclient
+role: myrole
+description_1: desc 1
+description_2: desc 2
+
+auth_args:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+
+redirect_uris1:
+ - "http://example.c.com/"
+ - "http://example.b.com/"
+ - "http://example.a.com/"
+
+client_attributes1: {"backchannel.logout.session.required": true, "backchannel.logout.revoke.offline.tokens": false}
+
+protocol_mappers1:
+ - name: 'email'
+ protocol: 'openid-connect'
+ protocolMapper: 'oidc-usermodel-property-mapper'
+ config:
+ "claim.name": "email"
+ "user.attribute": "email"
+ "jsonType.label": "String"
+ "id.token.claim": "true"
+ "access.token.claim": "true"
+ "userinfo.token.claim": "true"
+
+ - name: 'email_verified'
+ protocol: 'openid-connect'
+ protocolMapper: 'oidc-usermodel-property-mapper'
+ config:
+ "claim.name": "email_verified"
+ "user.attribute": "emailVerified"
+ "jsonType.label": "boolean"
+ "id.token.claim": "true"
+ "access.token.claim": "true"
+ "userinfo.token.claim": "true"
+
+ - name: 'family_name'
+ protocol: 'openid-connect'
+ protocolMapper: 'oidc-usermodel-property-mapper'
+ config:
+ "claim.name": "family_name"
+ "user.attribute": "lastName"
+ "jsonType.label": "String"
+ "id.token.claim": "true"
+ "access.token.claim": "true"
+ "userinfo.token.claim": "true"
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_clientscope_type/README.md b/ansible_collections/community/general/tests/integration/targets/keycloak_clientscope_type/README.md
new file mode 100644
index 000000000..3f3685f9b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_clientscope_type/README.md
@@ -0,0 +1,16 @@
+<!--
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+-->
+
+The integration test can be performed as follows:
+
+```
+# 1. Start docker-compose:
+docker-compose -f tests/integration/targets/keycloak_clientscope_type/docker-compose.yml down
+docker-compose -f tests/integration/targets/keycloak_clientscope_type/docker-compose.yml up -d
+
+# 2. Run the integration tests:
+ansible-test integration keycloak_clientscope_type --allow-unsupported -v
+```
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_clientscope_type/docker-compose.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_clientscope_type/docker-compose.yml
new file mode 100644
index 000000000..b73ddff16
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_clientscope_type/docker-compose.yml
@@ -0,0 +1,16 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+version: '3.4'
+
+services:
+ keycloak:
+ image: quay.io/keycloak/keycloak:21.0.2
+ ports:
+ - 8080:8080
+ environment:
+ KEYCLOAK_ADMIN: admin
+ KEYCLOAK_ADMIN_PASSWORD: password
+ command: start-dev
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_clientscope_type/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_clientscope_type/tasks/main.yml
new file mode 100644
index 000000000..76daace73
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_clientscope_type/tasks/main.yml
@@ -0,0 +1,164 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+
+# Fixtures
+- name: Create keycloak realm
+ community.general.keycloak_realm:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ id: ""
+ state: present
+ enabled: true
+
+- name: Create keycloak client
+ community.general.keycloak_client:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ state: present
+ enabled: true
+
+- name: Create a scope1 client scope
+ community.general.keycloak_clientscope:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: scope1
+ description: "test 1"
+ protocol: openid-connect
+
+- name: Create a scope2 client scope
+ community.general.keycloak_clientscope:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: scope2
+ description: "test 2"
+ protocol: openid-connect
+
+### Tests
+### Realm
+- name: adjust client-scope types in realm
+ community.general.keycloak_clientscope_type:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ default_clientscopes: ['scope1', 'scope2']
+ optional_clientscopes: []
+ register: result
+
+- name: Assert that client scope types are set
+ assert:
+ that:
+ - result is changed
+ - result.end_state != {}
+ - '"scope1" in result.end_state.default_clientscopes'
+ - '"scope2" in result.end_state.default_clientscopes'
+ - result.end_state.default_clientscopes|length == 2
+ - result.end_state.optional_clientscopes|length == 0
+
+- name: adjust client-scope types in realm again
+ community.general.keycloak_clientscope_type:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ default_clientscopes: ['scope1', 'scope2']
+ optional_clientscopes: []
+ register: result
+ failed_when: result is changed
+
+- name: adjust client-scope types in realm move scope 2 to optional
+ community.general.keycloak_clientscope_type:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ default_clientscopes: ['scope1']
+ optional_clientscopes: ['scope2']
+ register: result
+
+- name: Assert that client scope types are set
+ assert:
+ that:
+ - result is changed
+ - result.end_state != {}
+ - '"scope1" in result.end_state.default_clientscopes'
+ - '"scope2" in result.end_state.optional_clientscopes'
+ - result.end_state.default_clientscopes|length == 1
+ - result.end_state.optional_clientscopes|length == 1
+
+### Client
+- name: adjust client-scope types in client
+ community.general.keycloak_clientscope_type:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ default_clientscopes: ['scope1', 'scope2']
+ optional_clientscopes: []
+ register: result
+
+- name: Assert that client scope types are set
+ assert:
+ that:
+ - result is changed
+ - result.end_state != {}
+ - '"scope1" in result.end_state.default_clientscopes'
+ - '"scope2" in result.end_state.default_clientscopes'
+ - result.end_state.default_clientscopes|length == 2
+ - result.end_state.optional_clientscopes|length == 0
+
+- name: adjust client-scope types in client again
+ community.general.keycloak_clientscope_type:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ default_clientscopes: ['scope1', 'scope2']
+ optional_clientscopes: []
+ register: result
+ failed_when: result is changed
+
+- name: adjust client-scope types in client move scope 2 to optional
+ community.general.keycloak_clientscope_type:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ default_clientscopes: ['scope1']
+ optional_clientscopes: ['scope2']
+ register: result
+
+- name: Assert that client scope types are set
+ assert:
+ that:
+ - result is changed
+ - result.end_state != {}
+ - '"scope1" in result.end_state.default_clientscopes'
+ - '"scope2" in result.end_state.optional_clientscopes'
+ - result.end_state.default_clientscopes|length == 1
+ - result.end_state.optional_clientscopes|length == 1
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_clientscope_type/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_clientscope_type/vars/main.yml
new file mode 100644
index 000000000..7efd2b04e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_clientscope_type/vars/main.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+url: http://localhost:8080
+admin_realm: master
+admin_user: admin
+admin_password: password
+realm: clientscope-type-realm
+client_id: clientscope-type-client
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_info/README.md b/ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_info/README.md
new file mode 100644
index 000000000..fb721801d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_info/README.md
@@ -0,0 +1,17 @@
+<!--
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+-->
+
+The integration test can be performed as follows:
+
+```
+# 1. Start docker-compose:
+docker-compose -f tests/integration/targets/keycloak_clientsecret_info/docker-compose.yml stop
+docker-compose -f tests/integration/targets/keycloak_clientsecret_info/docker-compose.yml rm -f -v
+docker-compose -f tests/integration/targets/keycloak_clientsecret_info/docker-compose.yml up -d
+
+# 2. Run the integration tests:
+ansible-test integration keycloak_clientsecret_info --allow-unsupported -v
+```
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_info/docker-compose.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_info/docker-compose.yml
new file mode 100644
index 000000000..5e14e9aac
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_info/docker-compose.yml
@@ -0,0 +1,31 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+version: '3.4'
+
+services:
+ postgres:
+ image: postgres:9.6
+ restart: always
+ environment:
+ POSTGRES_USER: postgres
+ POSTGRES_DB: postgres
+ POSTGRES_PASSWORD: postgres
+
+ keycloak:
+ image: jboss/keycloak:12.0.4
+ ports:
+ - 8080:8080
+
+ environment:
+ DB_VENDOR: postgres
+ DB_ADDR: postgres
+ DB_DATABASE: postgres
+ DB_USER: postgres
+ DB_SCHEMA: public
+ DB_PASSWORD: postgres
+
+ KEYCLOAK_USER: admin
+ KEYCLOAK_PASSWORD: password
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_info/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_info/tasks/main.yml
new file mode 100644
index 000000000..a0cacf188
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_info/tasks/main.yml
@@ -0,0 +1,48 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create realm
+ community.general.keycloak_realm: "{{ auth_args | combine(call_args) }}"
+ vars:
+ call_args:
+ id: "{{ realm }}"
+ realm: "{{ realm }}"
+ state: present
+
+- name: Keycloak Client
+ community.general.keycloak_client: "{{ auth_args | combine(call_args) }}"
+ vars:
+ call_args:
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ state: present
+ register: client
+
+- name: Keycloak Client fetch clientsecret by client_id
+ community.general.keycloak_clientsecret_info: "{{ auth_args | combine(call_args) }}"
+ vars:
+ call_args:
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ register: fetch_by_client_id_result
+
+- name: Assert that the client secret was retrieved
+ assert:
+ that:
+ - fetch_by_client_id_result.clientsecret_info.type == "secret"
+ - "{{ fetch_by_client_id_result.clientsecret_info.value | length }} >= 32"
+
+- name: Keycloak Client fetch clientsecret by id
+ community.general.keycloak_clientsecret_info: "{{ auth_args | combine(call_args) }}"
+ vars:
+ call_args:
+ realm: "{{ realm }}"
+ id: "{{ client.end_state.id }}"
+ register: fetch_by_id_result
+
+- name: Assert that the same client secret was retrieved both times
+ assert:
+ that:
+ - fetch_by_id_result.clientsecret_info.value == fetch_by_client_id_result.clientsecret_info.value
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_info/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_info/vars/main.yml
new file mode 100644
index 000000000..8c913705f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_info/vars/main.yml
@@ -0,0 +1,20 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+url: http://localhost:8080/auth
+admin_realm: master
+admin_user: admin
+admin_password: password
+realm: myrealm
+client_id: myclient
+role: myrole
+description_1: desc 1
+description_2: desc 2
+
+auth_args:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_regenerate/README.md b/ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_regenerate/README.md
new file mode 100644
index 000000000..08251b4c5
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_regenerate/README.md
@@ -0,0 +1,17 @@
+<!--
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+-->
+
+The integration test can be performed as follows:
+
+```
+# 1. Start docker-compose:
+docker-compose -f tests/integration/targets/keycloak_clientsecret_regenerate/docker-compose.yml stop
+docker-compose -f tests/integration/targets/keycloak_clientsecret_regenerate/docker-compose.yml rm -f -v
+docker-compose -f tests/integration/targets/keycloak_clientsecret_regenerate/docker-compose.yml up -d
+
+# 2. Run the integration tests:
+ansible-test integration keycloak_clientsecret_regenerate --allow-unsupported -v
+```
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_regenerate/docker-compose.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_regenerate/docker-compose.yml
new file mode 100644
index 000000000..5e14e9aac
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_regenerate/docker-compose.yml
@@ -0,0 +1,31 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+version: '3.4'
+
+services:
+ postgres:
+ image: postgres:9.6
+ restart: always
+ environment:
+ POSTGRES_USER: postgres
+ POSTGRES_DB: postgres
+ POSTGRES_PASSWORD: postgres
+
+ keycloak:
+ image: jboss/keycloak:12.0.4
+ ports:
+ - 8080:8080
+
+ environment:
+ DB_VENDOR: postgres
+ DB_ADDR: postgres
+ DB_DATABASE: postgres
+ DB_USER: postgres
+ DB_SCHEMA: public
+ DB_PASSWORD: postgres
+
+ KEYCLOAK_USER: admin
+ KEYCLOAK_PASSWORD: password
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_regenerate/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_regenerate/tasks/main.yml
new file mode 100644
index 000000000..9bd52698a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_regenerate/tasks/main.yml
@@ -0,0 +1,49 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create realm
+ community.general.keycloak_realm: "{{ auth_args | combine(call_args) }}"
+ vars:
+ call_args:
+ id: "{{ realm }}"
+ realm: "{{ realm }}"
+ state: present
+
+- name: Keycloak Client
+ community.general.keycloak_client: "{{ auth_args | combine(call_args) }}"
+ vars:
+ call_args:
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ state: present
+ register: client
+
+- name: Keycloak Client regenerate clientsecret by client_id
+ community.general.keycloak_clientsecret_regenerate: "{{ auth_args | combine(call_args) }}"
+ vars:
+ call_args:
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ register: regenerate_by_client_id
+
+- name: Assert that the client secret was retrieved
+ assert:
+ that:
+ - regenerate_by_client_id.end_state.type == "secret"
+ - "{{ regenerate_by_client_id.end_state.value | length }} >= 32"
+
+- name: Keycloak Client regenerate clientsecret by id
+ community.general.keycloak_clientsecret_regenerate: "{{ auth_args | combine(call_args) }}"
+ vars:
+ call_args:
+ realm: "{{ realm }}"
+ id: "{{ client.end_state.id }}"
+ register: regenerate_by_id
+
+- name: Assert that client secret was regenerated
+ assert:
+ that:
+ - "{{ regenerate_by_id.end_state.value | length }} >= 32"
+ - regenerate_by_id.end_state.value != regenerate_by_client_id.end_state.value
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_regenerate/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_regenerate/vars/main.yml
new file mode 100644
index 000000000..8c913705f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_clientsecret_regenerate/vars/main.yml
@@ -0,0 +1,20 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+url: http://localhost:8080/auth
+admin_realm: master
+admin_user: admin
+admin_password: password
+realm: myrealm
+client_id: myclient
+role: myrole
+description_1: desc 1
+description_2: desc 2
+
+auth_args:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_group/aliases b/ansible_collections/community/general/tests/integration/targets/keycloak_group/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_group/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_group/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_group/meta/main.yml
new file mode 100644
index 000000000..5769ff1cb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_group/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_docker
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_group/readme.adoc b/ansible_collections/community/general/tests/integration/targets/keycloak_group/readme.adoc
new file mode 100644
index 000000000..1941e54ef
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_group/readme.adoc
@@ -0,0 +1,27 @@
+// Copyright (c) Ansible Project
+// GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+To be able to run these integration tests a keycloak server must be
+reachable under a specific url with a specific admin user and password.
+The exact values expected for these parameters can be found in
+'vars/main.yml' file. A simple way to do this is to use the official
+keycloak docker images like this:
+
+----
+docker run --name mykeycloak -p 8080:8080 -e KC_HTTP_RELATIVE_PATH=<url-path> -e KEYCLOAK_ADMIN=<admin_user> -e KEYCLOAK_ADMIN_PASSWORD=<admin_password> quay.io/keycloak/keycloak:20.0.2 start-dev
+----
+
+Example with concrete values inserted:
+
+----
+docker run --name mykeycloak -p 8080:8080 -e KC_HTTP_RELATIVE_PATH=/auth -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=password quay.io/keycloak/keycloak:20.0.2 start-dev
+----
+
+This test suite can run against a fresh unconfigured server instance
+(no preconfiguration required) and cleans up after itself (undoes all
+its config changes) as long as it runs through completly. While its active
+it changes the server configuration in the following ways:
+
+ * creating, modifying and deleting some keycloak groups
+
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_group/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_group/tasks/main.yml
new file mode 100644
index 000000000..8b115e3a2
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_group/tasks/main.yml
@@ -0,0 +1,527 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Start container
+ community.docker.docker_container:
+ name: mykeycloak
+ image: "quay.io/keycloak/keycloak:20.0.2"
+ command: start-dev
+ env:
+ KC_HTTP_RELATIVE_PATH: /auth
+ KEYCLOAK_ADMIN: admin
+ KEYCLOAK_ADMIN_PASSWORD: password
+ ports:
+ - "8080:8080"
+ detach: true
+ auto_remove: true
+ memory: 2200M
+
+- name: Check default ports
+ ansible.builtin.wait_for:
+ host: "localhost"
+ port: "8080"
+ state: started # Port should be open
+ delay: 30 # Wait before first check
+ timeout: 50 # Stop checking after timeout (sec)
+
+- name: Create a keycloak group
+ community.general.keycloak_group:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: test-group
+ state: present
+ register: result
+ retries: 3
+ delay: 20
+ until: result is not failed
+
+- name: Assert group was created
+ assert:
+ that:
+ - result is changed
+ - result.end_state != {}
+ - result.end_state.name == "test-group"
+ - result.end_state.path == "/test-group"
+ - result.end_state.attributes == {}
+ - result.end_state.clientRoles == {}
+ - result.end_state.realmRoles == []
+ - result.end_state.subGroups == []
+
+- set_fact:
+ test_group_id: "{{ result.end_state.id }}"
+
+- name: Group creation rerun (test for idempotency)
+ community.general.keycloak_group:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: test-group
+ state: present
+ register: result
+
+- name: Assert that nothing has changed
+ assert:
+ that:
+ - result is not changed
+ - result.end_state != {}
+ - result.end_state.name == "test-group"
+ - result.end_state.path == "/test-group"
+ - result.end_state.attributes == {}
+ - result.end_state.clientRoles == {}
+ - result.end_state.realmRoles == []
+ - result.end_state.subGroups == []
+
+- name: Update the name of a keycloak group
+ community.general.keycloak_group:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ id: "{{ test_group_id }}"
+ name: new-test-group
+ state: present
+ register: result
+
+- name: Assert that group name was updated
+ assert:
+ that:
+ - result is changed
+ - result.end_state != {}
+ - result.end_state.name == "new-test-group"
+ - result.end_state.path == "/new-test-group"
+ - result.end_state.attributes == {}
+ - result.end_state.clientRoles == {}
+ - result.end_state.realmRoles == []
+ - result.end_state.subGroups == []
+
+- name: Delete a keycloak group by id
+ community.general.keycloak_group:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ id: "{{ test_group_id }}"
+ state: absent
+ register: result
+
+- name: Assert that group was deleted
+ assert:
+ that:
+ - result is changed
+ - result.end_state == {}
+
+- name: Redo group deletion (check for idempotency)
+ community.general.keycloak_group:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ id: "{{ test_group_id }}"
+ state: absent
+ register: result
+
+- name: Assert that nothing has changed
+ assert:
+ that:
+ - result is not changed
+ - result.end_state == {}
+
+- name: Create a keycloak group with some custom attributes
+ community.general.keycloak_group:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: my-new_group
+ attributes:
+ attrib1: value1
+ attrib2: value2
+ attrib3:
+ - item1
+ - item2
+ register: result
+
+- name: Assert that group was correctly created
+ assert:
+ that:
+ - result is changed
+ - result.end_state != {}
+ - result.end_state.name == "my-new_group"
+ - result.end_state.path == "/my-new_group"
+ - result.end_state.clientRoles == {}
+ - result.end_state.realmRoles == []
+ - result.end_state.subGroups == []
+ - result.end_state.attributes != {}
+ - result.end_state.attributes.attrib1 == ["value1"]
+ - result.end_state.attributes.attrib2 == ["value2"]
+ - result.end_state.attributes.attrib3 == ["item1", "item2"]
+
+- name: Delete a keycloak group based on name
+ community.general.keycloak_group:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: my-new_group
+ state: absent
+ register: result
+
+- name: Assert that group was deleted
+ assert:
+ that:
+ - result is changed
+ - result.end_state == {}
+
+## subgroup tests
+## we already testet this so no asserts for this
+- name: Create a new base group for subgroup testing (test setup)
+ community.general.keycloak_group:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: rootgrp
+ register: subgrp_basegrp_result
+
+- name: Create a subgroup using parent id
+ community.general.keycloak_group:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: subgrp1
+ parents:
+ - id: "{{ subgrp_basegrp_result.end_state.id }}"
+ register: result
+
+- name: Assert that subgroup was correctly created
+ assert:
+ that:
+ - result is changed
+ - result.end_state != {}
+ - result.end_state.name == "subgrp1"
+ - result.end_state.path == "/rootgrp/subgrp1"
+ - result.end_state.attributes == {}
+ - result.end_state.clientRoles == {}
+ - result.end_state.realmRoles == []
+ - result.end_state.subGroups == []
+
+- name: Recreate a subgroup using parent id (test idempotency)
+ community.general.keycloak_group:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: subgrp1
+ parents:
+ - id: "{{ subgrp_basegrp_result.end_state.id }}"
+ register: result
+
+- name: Assert that nothing has changed
+ assert:
+ that:
+ - result is not changed
+ - result.end_state != {}
+ - result.end_state.name == "subgrp1"
+ - result.end_state.path == "/rootgrp/subgrp1"
+ - result.end_state.attributes == {}
+ - result.end_state.clientRoles == {}
+ - result.end_state.realmRoles == []
+ - result.end_state.subGroups == []
+
+- name: Changing name of existing group
+ community.general.keycloak_group:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ id: "{{ result.end_state.id }}"
+ name: new-subgrp1
+ parents:
+ - id: "{{ subgrp_basegrp_result.end_state.id }}"
+ register: result
+
+- name: Assert that subgroup name has changed correctly
+ assert:
+ that:
+ - result is changed
+ - result.end_state != {}
+ - result.end_state.name == "new-subgrp1"
+ - result.end_state.path == "/rootgrp/new-subgrp1"
+ - result.end_state.attributes == {}
+ - result.end_state.clientRoles == {}
+ - result.end_state.realmRoles == []
+ - result.end_state.subGroups == []
+
+- name: Create a subgroup using parent name
+ community.general.keycloak_group:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: subgrp2
+ parents:
+ - name: rootgrp
+ register: result
+
+- name: Assert that subgroup was correctly created
+ assert:
+ that:
+ - result is changed
+ - result.end_state != {}
+ - result.end_state.name == "subgrp2"
+ - result.end_state.path == "/rootgrp/subgrp2"
+ - result.end_state.attributes == {}
+ - result.end_state.clientRoles == {}
+ - result.end_state.realmRoles == []
+ - result.end_state.subGroups == []
+
+- name: Recreate a subgroup using parent name (test idempotency)
+ community.general.keycloak_group:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: subgrp2
+ parents:
+ - name: rootgrp
+ register: result
+
+- name: Assert that nothing has changed
+ assert:
+ that:
+ - result is not changed
+ - result.end_state != {}
+ - result.end_state.name == "subgrp2"
+ - result.end_state.path == "/rootgrp/subgrp2"
+ - result.end_state.attributes == {}
+ - result.end_state.clientRoles == {}
+ - result.end_state.realmRoles == []
+ - result.end_state.subGroups == []
+
+## subgroup of subgroup tests
+- name: Create a subgroup of a subgroup using parent names (complete parent chain)
+ community.general.keycloak_group:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: subsubgrp
+ parents:
+ - name: rootgrp
+ - name: subgrp2
+ register: result
+
+- name: Assert subgroup of subgroup was created
+ assert:
+ that:
+ - result is changed
+ - result.end_state != {}
+ - result.end_state.name == "subsubgrp"
+ - result.end_state.path == "/rootgrp/subgrp2/subsubgrp"
+ - result.end_state.attributes == {}
+ - result.end_state.clientRoles == {}
+ - result.end_state.realmRoles == []
+ - result.end_state.subGroups == []
+
+- name: ReCreate a subgroup of a subgroup using parent names (test idempotency)
+ community.general.keycloak_group:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: subsubgrp
+ parents:
+ - name: rootgrp
+ - name: subgrp2
+ register: result_subsubgrp
+
+- name: Assert that nothing has changed
+ assert:
+ that:
+ - result_subsubgrp is not changed
+ - result_subsubgrp.end_state != {}
+ - result_subsubgrp.end_state.name == "subsubgrp"
+ - result_subsubgrp.end_state.path == "/rootgrp/subgrp2/subsubgrp"
+ - result_subsubgrp.end_state.attributes == {}
+ - result_subsubgrp.end_state.clientRoles == {}
+ - result_subsubgrp.end_state.realmRoles == []
+ - result_subsubgrp.end_state.subGroups == []
+
+- name: Create a subgroup of a subgroup using direct parent id (incomplete parent chain)
+ community.general.keycloak_group:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: subsubsubgrp
+ parents:
+ - id: "{{ result_subsubgrp.end_state.id }}"
+ register: result
+
+- name: Assert subgroup of subgroup was created
+ assert:
+ that:
+ - result is changed
+ - result.end_state != {}
+ - result.end_state.name == "subsubsubgrp"
+ - result.end_state.path == "/rootgrp/subgrp2/subsubgrp/subsubsubgrp"
+ - result.end_state.attributes == {}
+ - result.end_state.clientRoles == {}
+ - result.end_state.realmRoles == []
+ - result.end_state.subGroups == []
+
+- name: ReCreate a subgroup of a subgroup using direct parent id (test idempotency)
+ community.general.keycloak_group:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: subsubsubgrp
+ parents:
+ - id: "{{ result_subsubgrp.end_state.id }}"
+ register: result_subsubsubgrp
+
+- name: Assert that nothing changed
+ assert:
+ that:
+ - result_subsubsubgrp is not changed
+ - result_subsubsubgrp.end_state != {}
+ - result_subsubsubgrp.end_state.name == "subsubsubgrp"
+ - result_subsubsubgrp.end_state.path == "/rootgrp/subgrp2/subsubgrp/subsubsubgrp"
+ - result_subsubsubgrp.end_state.attributes == {}
+ - result_subsubsubgrp.end_state.clientRoles == {}
+ - result_subsubsubgrp.end_state.realmRoles == []
+ - result_subsubsubgrp.end_state.subGroups == []
+
+## subgroup deletion tests
+## note: in principle we already have tested group deletion in general
+## enough already, but what makes it interesting here again is to
+## see it works also properly for subgroups and groups with subgroups
+- name: Deleting a subgroup by id (no parents needed)
+ community.general.keycloak_group:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ id: "{{ result_subsubsubgrp.end_state.id }}"
+ state: absent
+ register: result
+
+- name: Assert that subgroup was deleted
+ assert:
+ that:
+ - result is changed
+ - result.end_state == {}
+
+- name: Redo subgroup deletion (idempotency test)
+ community.general.keycloak_group:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ id: "{{ result_subsubsubgrp.end_state.id }}"
+ state: absent
+ register: result
+
+- name: Assert that nothing changed
+ assert:
+ that:
+ - result is not changed
+ - result.end_state == {}
+
+- name: Deleting a subgroup by name
+ community.general.keycloak_group:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: new-subgrp1
+ parents:
+ - name: rootgrp
+ state: absent
+ register: result
+
+- name: Assert that subgroup was deleted
+ assert:
+ that:
+ - result is changed
+ - result.end_state == {}
+
+- name: Redo deleting a subgroup by name (idempotency test)
+ community.general.keycloak_group:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: new-subgrp1
+ parents:
+ - name: rootgrp
+ state: absent
+ register: result
+
+- name: Assert that nothing has changed
+ assert:
+ that:
+ - result is not changed
+ - result.end_state == {}
+
+- name: Delete keycloak group which has subgroups
+ community.general.keycloak_group:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: rootgrp
+ state: absent
+ register: result
+
+- name: Assert that group was deleted
+ assert:
+ that:
+ - result is changed
+ - result.end_state == {}
+
+- name: Redo delete keycloak group which has subgroups (idempotency test)
+ community.general.keycloak_group:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: rootgrp
+ state: absent
+ register: result
+
+- name: Assert that group was deleted
+ assert:
+ that:
+ - result is not changed
+ - result.end_state == {}
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_group/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_group/vars/main.yml
new file mode 100644
index 000000000..e8aeb4f3f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_group/vars/main.yml
@@ -0,0 +1,10 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+url: http://localhost:8080/auth
+admin_realm: master
+admin_user: admin
+admin_password: password
+realm: master
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_identity_provider/aliases b/ansible_collections/community/general/tests/integration/targets/keycloak_identity_provider/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_identity_provider/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_identity_provider/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_identity_provider/tasks/main.yml
new file mode 100644
index 000000000..79ba33049
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_identity_provider/tasks/main.yml
@@ -0,0 +1,175 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create realm
+ community.general.keycloak_realm:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ id: "{{ realm }}"
+ realm: "{{ realm }}"
+ state: present
+
+- name: Create new identity provider
+ community.general.keycloak_identity_provider:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ alias: "{{ idp }}"
+ display_name: OpenID Connect IdP
+ enabled: true
+ provider_id: oidc
+ config:
+ issuer: https://idp.example.com
+ authorizationUrl: https://idp.example.com/auth
+ tokenUrl: https://idp.example.com/token
+ userInfoUrl: https://idp.example.com/userinfo
+ clientAuthMethod: client_secret_post
+ clientId: clientid
+ clientSecret: clientsecret
+ syncMode: FORCE
+ mappers:
+ - name: "first_name"
+ identityProviderAlias: "oidc-idp"
+ identityProviderMapper: "oidc-user-attribute-idp-mapper"
+ config:
+ claim: "first_name"
+ user.attribute: "first_name"
+ syncMode: "INHERIT"
+ - name: "last_name"
+ identityProviderAlias: "oidc-idp"
+ identityProviderMapper: "oidc-user-attribute-idp-mapper"
+ config:
+ claim: "last_name"
+ user.attribute: "last_name"
+ syncMode: "INHERIT"
+ state: present
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert identity provider created
+ assert:
+ that:
+ - result is changed
+ - result.existing == {}
+ - result.end_state.alias == "{{ idp }}"
+ - result.end_state.mappers != []
+
+- name: Update existing identity provider (no change)
+ community.general.keycloak_identity_provider:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ alias: "{{ idp }}"
+ enabled: true
+ provider_id: oidc
+ config:
+ issuer: https://idp.example.com
+ authorizationUrl: https://idp.example.com/auth
+ tokenUrl: https://idp.example.com/token
+ userInfoUrl: https://idp.example.com/userinfo
+ clientAuthMethod: client_secret_post
+ clientId: clientid
+ clientSecret: "**********"
+ syncMode: FORCE
+ mappers:
+ - name: "first_name"
+ identityProviderAlias: "oidc-idp"
+ identityProviderMapper: "oidc-user-attribute-idp-mapper"
+ config:
+ claim: "first_name"
+ user.attribute: "first_name"
+ syncMode: "INHERIT"
+ - name: "last_name"
+ identityProviderAlias: "oidc-idp"
+ identityProviderMapper: "oidc-user-attribute-idp-mapper"
+ config:
+ claim: "last_name"
+ user.attribute: "last_name"
+ syncMode: "INHERIT"
+ state: present
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert identity provider unchanged
+ assert:
+ that:
+ - result is not changed
+
+- name: Update existing identity provider (with change)
+ community.general.keycloak_identity_provider:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ alias: "{{ idp }}"
+ enabled: false
+ state: present
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert identity provider updated
+ assert:
+ that:
+ - result is changed
+ - result.existing.enabled == true
+ - result.end_state.enabled == false
+
+- name: Delete existing identity provider
+ community.general.keycloak_identity_provider:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ alias: "{{ idp }}"
+ state: absent
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert identity provider deleted
+ assert:
+ that:
+ - result is changed
+ - result.end_state == {}
+
+- name: Delete absent identity provider
+ community.general.keycloak_identity_provider:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ alias: "{{ idp }}"
+ state: absent
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert identity provider unchanged
+ assert:
+ that:
+ - result is not changed
+ - result.end_state == {}
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_identity_provider/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_identity_provider/vars/main.yml
new file mode 100644
index 000000000..6d2078ca0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_identity_provider/vars/main.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+url: http://localhost:8080/auth
+admin_realm: master
+admin_user: admin
+admin_password: password
+realm: myrealm
+idp: myidp
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_role/aliases b/ansible_collections/community/general/tests/integration/targets/keycloak_role/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_role/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_role/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_role/tasks/main.yml
new file mode 100644
index 000000000..61b62629a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_role/tasks/main.yml
@@ -0,0 +1,250 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create realm
+ community.general.keycloak_realm:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ id: "{{ realm }}"
+ realm: "{{ realm }}"
+ state: present
+
+- name: Create client
+ community.general.keycloak_client:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ state: present
+ register: client
+
+- name: Create new realm role
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: "{{ role }}"
+ description: "{{ description_1 }}"
+ state: present
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert realm role created
+ assert:
+ that:
+ - result is changed
+ - result.existing == {}
+ - result.end_state.name == "{{ role }}"
+ - result.end_state.containerId == "{{ realm }}"
+
+- name: Create existing realm role
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: "{{ role }}"
+ description: "{{ description_1 }}"
+ state: present
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert realm role unchanged
+ assert:
+ that:
+ - result is not changed
+
+- name: Update realm role
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: "{{ role }}"
+ description: "{{ description_2 }}"
+ state: present
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert realm role updated
+ assert:
+ that:
+ - result is changed
+ - result.existing.description == "{{ description_1 }}"
+ - result.end_state.description == "{{ description_2 }}"
+
+- name: Delete existing realm role
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: "{{ role }}"
+ state: absent
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert realm role deleted
+ assert:
+ that:
+ - result is changed
+ - result.end_state == {}
+
+- name: Delete absent realm role
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: "{{ role }}"
+ state: absent
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert realm role unchanged
+ assert:
+ that:
+ - result is not changed
+ - result.end_state == {}
+
+- name: Create new client role
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ name: "{{ role }}"
+ description: "{{ description_1 }}"
+ state: present
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert client role created
+ assert:
+ that:
+ - result is changed
+ - result.existing == {}
+ - result.end_state.name == "{{ role }}"
+ - result.end_state.containerId == "{{ client.end_state.id }}"
+
+- name: Create existing client role
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ name: "{{ role }}"
+ description: "{{ description_1 }}"
+ state: present
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert client role unchanged
+ assert:
+ that:
+ - result is not changed
+
+- name: Update client role
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ name: "{{ role }}"
+ description: "{{ description_2 }}"
+ state: present
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert client role updated
+ assert:
+ that:
+ - result is changed
+ - result.existing.description == "{{ description_1 }}"
+ - result.end_state.description == "{{ description_2 }}"
+
+- name: Delete existing client role
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ name: "{{ role }}"
+ state: absent
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert client role deleted
+ assert:
+ that:
+ - result is changed
+ - result.end_state == {}
+
+- name: Delete absent client role
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ name: "{{ role }}"
+ state: absent
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert client role unchanged
+ assert:
+ that:
+ - result is not changed
+ - result.end_state == {}
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_role/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_role/vars/main.yml
new file mode 100644
index 000000000..b003311e0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_role/vars/main.yml
@@ -0,0 +1,14 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+url: http://localhost:8080/auth
+admin_realm: master
+admin_user: admin
+admin_password: password
+realm: myrealm
+client_id: myclient
+role: myrole
+description_1: desc 1
+description_2: desc 2
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_user_federation/aliases b/ansible_collections/community/general/tests/integration/targets/keycloak_user_federation/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_user_federation/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_user_federation/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_user_federation/tasks/main.yml
new file mode 100644
index 000000000..ae0b4bf16
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_user_federation/tasks/main.yml
@@ -0,0 +1,425 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create realm
+ community.general.keycloak_realm:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ id: "{{ realm }}"
+ realm: "{{ realm }}"
+ state: present
+
+- name: Create new user federation
+ community.general.keycloak_user_federation:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: "{{ federation }}"
+ state: present
+ provider_id: ldap
+ provider_type: org.keycloak.storage.UserStorageProvider
+ config:
+ enabled: true
+ priority: 0
+ fullSyncPeriod: -1
+ changedSyncPeriod: -1
+ cachePolicy: DEFAULT
+ batchSizeForSync: 1000
+ editMode: READ_ONLY
+ importEnabled: true
+ syncRegistrations: false
+ vendor: other
+ usernameLDAPAttribute: uid
+ rdnLDAPAttribute: uid
+ uuidLDAPAttribute: entryUUID
+ userObjectClasses: "inetOrgPerson, organizationalPerson"
+ connectionUrl: "ldaps://ldap.example.com:636"
+ usersDn: "ou=Users,dc=example,dc=com"
+ authType: simple
+ bindDn: cn=directory reader
+ bindCredential: secret
+ searchScope: 1
+ validatePasswordPolicy: false
+ trustEmail: false
+ useTruststoreSpi: "ldapsOnly"
+ connectionPooling: true
+ pagination: true
+ allowKerberosAuthentication: false
+ useKerberosForPasswordAuthentication: false
+ debug: false
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert user federation created
+ assert:
+ that:
+ - result is changed
+ - result.existing == {}
+ - result.end_state.name == "{{ federation }}"
+
+- name: Create new user federation in admin realm
+ community.general.keycloak_user_federation:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ admin_realm }}"
+ name: "{{ federation }}"
+ state: present
+ provider_id: ldap
+ provider_type: org.keycloak.storage.UserStorageProvider
+ config:
+ enabled: true
+ priority: 0
+ fullSyncPeriod: -1
+ changedSyncPeriod: -1
+ cachePolicy: DEFAULT
+ batchSizeForSync: 1000
+ editMode: READ_ONLY
+ importEnabled: true
+ syncRegistrations: false
+ vendor: other
+ usernameLDAPAttribute: uid
+ rdnLDAPAttribute: uid
+ uuidLDAPAttribute: entryUUID
+ userObjectClasses: "inetOrgPerson, organizationalPerson"
+ connectionUrl: "ldaps://ldap.example.com:636"
+ usersDn: "ou=Users,dc=example,dc=com"
+ authType: simple
+ bindDn: cn=directory reader
+ bindCredential: secret
+ searchScope: 1
+ validatePasswordPolicy: false
+ trustEmail: false
+ useTruststoreSpi: "ldapsOnly"
+ connectionPooling: true
+ pagination: true
+ allowKerberosAuthentication: false
+ useKerberosForPasswordAuthentication: false
+ debug: false
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert user federation created (admin realm)
+ assert:
+ that:
+ - result is changed
+ - result.existing == {}
+ - result.end_state.name == "{{ federation }}"
+
+- name: Update existing user federation (no change)
+ community.general.keycloak_user_federation:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: "{{ federation }}"
+ state: present
+ provider_id: ldap
+ provider_type: org.keycloak.storage.UserStorageProvider
+ config:
+ enabled: true
+ priority: 0
+ fullSyncPeriod: -1
+ changedSyncPeriod: -1
+ cachePolicy: DEFAULT
+ batchSizeForSync: 1000
+ editMode: READ_ONLY
+ importEnabled: true
+ syncRegistrations: false
+ vendor: other
+ usernameLDAPAttribute: uid
+ rdnLDAPAttribute: uid
+ uuidLDAPAttribute: entryUUID
+ userObjectClasses: "inetOrgPerson, organizationalPerson"
+ connectionUrl: "ldaps://ldap.example.com:636"
+ usersDn: "ou=Users,dc=example,dc=com"
+ authType: simple
+ bindDn: cn=directory reader
+ bindCredential: "**********"
+ searchScope: 1
+ validatePasswordPolicy: false
+ trustEmail: false
+ useTruststoreSpi: "ldapsOnly"
+ connectionPooling: true
+ pagination: true
+ allowKerberosAuthentication: false
+ useKerberosForPasswordAuthentication: false
+ debug: false
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert user federation unchanged
+ assert:
+ that:
+ - result is not changed
+ - result.existing != {}
+ - result.existing.name == "{{ federation }}"
+ - result.end_state != {}
+ - result.end_state.name == "{{ federation }}"
+
+- name: Update existing user federation (no change, admin realm)
+ community.general.keycloak_user_federation:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ admin_realm }}"
+ name: "{{ federation }}"
+ state: present
+ provider_id: ldap
+ provider_type: org.keycloak.storage.UserStorageProvider
+ config:
+ enabled: true
+ priority: 0
+ fullSyncPeriod: -1
+ changedSyncPeriod: -1
+ cachePolicy: DEFAULT
+ batchSizeForSync: 1000
+ editMode: READ_ONLY
+ importEnabled: true
+ syncRegistrations: false
+ vendor: other
+ usernameLDAPAttribute: uid
+ rdnLDAPAttribute: uid
+ uuidLDAPAttribute: entryUUID
+ userObjectClasses: "inetOrgPerson, organizationalPerson"
+ connectionUrl: "ldaps://ldap.example.com:636"
+ usersDn: "ou=Users,dc=example,dc=com"
+ authType: simple
+ bindDn: cn=directory reader
+ bindCredential: "**********"
+ searchScope: 1
+ validatePasswordPolicy: false
+ trustEmail: false
+ useTruststoreSpi: "ldapsOnly"
+ connectionPooling: true
+ pagination: true
+ allowKerberosAuthentication: false
+ useKerberosForPasswordAuthentication: false
+ debug: false
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert user federation unchanged (admin realm)
+ assert:
+ that:
+ - result is not changed
+ - result.existing != {}
+ - result.existing.name == "{{ federation }}"
+ - result.end_state != {}
+ - result.end_state.name == "{{ federation }}"
+
+- name: Update existing user federation (with change)
+ community.general.keycloak_user_federation:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: "{{ federation }}"
+ state: present
+ provider_id: ldap
+ provider_type: org.keycloak.storage.UserStorageProvider
+ config:
+ enabled: true
+ priority: 0
+ fullSyncPeriod: -1
+ changedSyncPeriod: -1
+ cachePolicy: DEFAULT
+ batchSizeForSync: 1000
+ editMode: READ_ONLY
+ importEnabled: true
+ syncRegistrations: false
+ vendor: other
+ usernameLDAPAttribute: uid
+ rdnLDAPAttribute: uid
+ uuidLDAPAttribute: entryUUID
+ userObjectClasses: "inetOrgPerson, organizationalPerson"
+ connectionUrl: "ldaps://ldap.example.com:636"
+ usersDn: "ou=Users,dc=example,dc=com"
+ authType: simple
+ bindDn: cn=directory reader
+ bindCredential: "**********"
+ searchScope: 1
+ validatePasswordPolicy: false
+ trustEmail: false
+ useTruststoreSpi: "ldapsOnly"
+ connectionPooling: true
+ pagination: true
+ allowKerberosAuthentication: false
+ useKerberosForPasswordAuthentication: false
+ debug: false
+ mappers:
+ # overwrite / update pre existing default mapper
+ - name: "username"
+ providerId: "user-attribute-ldap-mapper"
+ config:
+ ldap.attribute: ldap_user
+ user.model.attribute: usr
+ read.only: true
+ # create new mapper
+ - name: "full name"
+ providerId: "full-name-ldap-mapper"
+ providerType: "org.keycloak.storage.ldap.mappers.LDAPStorageMapper"
+ config:
+ ldap.full.name.attribute: cn
+ read.only: true
+ write.only: false
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert user federation created
+ assert:
+ that:
+ - result is changed
+ - result.existing != {}
+ - result.existing.name == "{{ federation }}"
+ - result.end_state != {}
+ - result.end_state.name == "{{ federation }}"
+
+- name: Delete existing user federation
+ community.general.keycloak_user_federation:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: "{{ federation }}"
+ state: absent
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert user federation deleted
+ assert:
+ that:
+ - result is changed
+ - result.existing != {}
+ - result.end_state == {}
+
+- name: Delete absent user federation
+ community.general.keycloak_user_federation:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: "{{ federation }}"
+ state: absent
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert user federation unchanged
+ assert:
+ that:
+ - result is not changed
+ - result.existing == {}
+ - result.end_state == {}
+
+- name: Create new user federation together with mappers
+ community.general.keycloak_user_federation:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: "{{ federation }}"
+ state: present
+ provider_id: ldap
+ provider_type: org.keycloak.storage.UserStorageProvider
+ config:
+ enabled: true
+ priority: 0
+ fullSyncPeriod: -1
+ changedSyncPeriod: -1
+ cachePolicy: DEFAULT
+ batchSizeForSync: 1000
+ editMode: READ_ONLY
+ importEnabled: true
+ syncRegistrations: false
+ vendor: other
+ usernameLDAPAttribute: uid
+ rdnLDAPAttribute: uid
+ uuidLDAPAttribute: entryUUID
+ userObjectClasses: "inetOrgPerson, organizationalPerson"
+ connectionUrl: "ldaps://ldap.example.com:636"
+ usersDn: "ou=Users,dc=example,dc=com"
+ authType: simple
+ bindDn: cn=directory reader
+ bindCredential: secret
+ searchScope: 1
+ validatePasswordPolicy: false
+ trustEmail: false
+ useTruststoreSpi: "ldapsOnly"
+ connectionPooling: true
+ pagination: true
+ allowKerberosAuthentication: false
+ useKerberosForPasswordAuthentication: false
+ debug: false
+ mappers:
+ # overwrite / update pre existing default mapper
+ - name: "username"
+ providerId: "user-attribute-ldap-mapper"
+ config:
+ ldap.attribute: ldap_user
+ user.model.attribute: usr
+ read.only: true
+ # create new mapper
+ - name: "full name"
+ providerId: "full-name-ldap-mapper"
+ providerType: "org.keycloak.storage.ldap.mappers.LDAPStorageMapper"
+ config:
+ ldap.full.name.attribute: cn
+ read.only: true
+ write.only: false
+ register: result
+
+- name: Debug
+ debug:
+ var: result
+
+- name: Assert user federation created
+ assert:
+ that:
+ - result is changed
+ - result.existing == {}
+ - result.end_state.name == "{{ federation }}"
+
+## no point in retesting this, just doing it to clean up introduced server changes
+- name: Delete absent user federation
+ community.general.keycloak_user_federation:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: "{{ federation }}"
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_user_federation/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_user_federation/vars/main.yml
new file mode 100644
index 000000000..acf73e2ca
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_user_federation/vars/main.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+url: http://localhost:8080/auth
+admin_realm: master
+admin_user: admin
+admin_password: password
+realm: myrealm
+federation: myfed
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_user_rolemapping/aliases b/ansible_collections/community/general/tests/integration/targets/keycloak_user_rolemapping/aliases
new file mode 100644
index 000000000..cdeae1417
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_user_rolemapping/aliases
@@ -0,0 +1,4 @@
+# Copyright (c) 2022, Dušan Marković (@bratwurzt)
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_user_rolemapping/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_user_rolemapping/tasks/main.yml
new file mode 100644
index 000000000..1a897ad9a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_user_rolemapping/tasks/main.yml
@@ -0,0 +1,143 @@
+# Copyright (c) 2022, Dušan Marković (@bratwurzt)
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create realm
+ community.general.keycloak_realm:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ id: "{{ realm }}"
+ realm: "{{ realm }}"
+ state: present
+
+- name: Create client
+ community.general.keycloak_client:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ service_accounts_enabled: true
+ state: present
+ register: client
+
+- name: Create new realm role
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: "{{ role }}"
+ description: "{{ description_1 }}"
+ state: present
+
+- name: Map a realm role to client service account
+ vars:
+ - roles: [ {'name': '{{ role }}'} ]
+ community.general.keycloak_user_rolemapping:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ service_account_user_client_id: "{{ client_id }}"
+ roles: "{{ roles }}"
+ state: present
+ register: result
+
+- name: Assert realm role is assigned
+ assert:
+ that:
+ - result is changed
+ - result.end_state | selectattr("clientRole", "eq", false) | selectattr("name", "eq", "{{role}}") | list | count > 0
+
+- name: Unmap a realm role from client service account
+ vars:
+ - roles: [ {'name': '{{ role }}'} ]
+ community.general.keycloak_user_rolemapping:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ service_account_user_client_id: "{{ client_id }}"
+ roles: "{{ roles }}"
+ state: absent
+ register: result
+
+- name: Assert realm role is unassigned
+ assert:
+ that:
+ - result is changed
+ - (result.end_state | length) == (result.existing | length) - 1
+ - result.existing | selectattr("clientRole", "eq", false) | selectattr("name", "eq", "{{role}}") | list | count > 0
+ - result.end_state | selectattr("clientRole", "eq", false) | selectattr("name", "eq", "{{role}}") | list | count == 0
+
+- name: Delete existing realm role
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ name: "{{ role }}"
+ state: absent
+
+- name: Create new client role
+ community.general.keycloak_role:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ name: "{{ role }}"
+ description: "{{ description_1 }}"
+ state: present
+
+- name: Map a client role to client service account
+ vars:
+ - roles: [ {'name': '{{ role }}'} ]
+ community.general.keycloak_user_rolemapping:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ service_account_user_client_id: "{{ client_id }}"
+ roles: "{{ roles }}"
+ state: present
+ register: result
+
+- name: Assert client role is assigned
+ assert:
+ that:
+ - result is changed
+ - result.end_state | selectattr("clientRole", "eq", true) | selectattr("name", "eq", "{{role}}") | list | count > 0
+
+- name: Unmap a client role from client service account
+ vars:
+ - roles: [ {'name': '{{ role }}'} ]
+ community.general.keycloak_user_rolemapping:
+ auth_keycloak_url: "{{ url }}"
+ auth_realm: "{{ admin_realm }}"
+ auth_username: "{{ admin_user }}"
+ auth_password: "{{ admin_password }}"
+ realm: "{{ realm }}"
+ client_id: "{{ client_id }}"
+ service_account_user_client_id: "{{ client_id }}"
+ roles: "{{ roles }}"
+ state: absent
+ register: result
+
+- name: Assert client role is unassigned
+ assert:
+ that:
+ - result is changed
+ - result.end_state == []
+ - result.existing | selectattr("clientRole", "eq", true) | selectattr("name", "eq", "{{role}}") | list | count > 0
diff --git a/ansible_collections/community/general/tests/integration/targets/keycloak_user_rolemapping/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/keycloak_user_rolemapping/vars/main.yml
new file mode 100644
index 000000000..385dbea44
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keycloak_user_rolemapping/vars/main.yml
@@ -0,0 +1,14 @@
+---
+# Copyright (c) 2022, Dušan Marković (@bratwurzt)
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+url: http://localhost:8080/auth
+admin_realm: master
+admin_user: admin
+admin_password: password
+realm: myrealm
+client_id: myclient
+role: myrole
+description_1: desc 1
+description_2: desc 2
diff --git a/ansible_collections/community/general/tests/integration/targets/keyring/aliases b/ansible_collections/community/general/tests/integration/targets/keyring/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keyring/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/keyring/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/keyring/tasks/main.yml
new file mode 100644
index 000000000..3833018e8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keyring/tasks/main.yml
@@ -0,0 +1,99 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Ensure required packages for headless keyring access are installed (RPM)
+ ansible.builtin.package:
+ name: gnome-keyring
+ become: true
+ when: "'localhost' not in inventory_hostname"
+
+- name: Ensure keyring is installed (RPM)
+ ansible.builtin.dnf:
+ name: python3-keyring
+ state: present
+ become: true
+ when: ansible_facts['os_family'] == 'RedHat'
+
+- name: Ensure keyring is installed (pip)
+ ansible.builtin.pip:
+ name: keyring
+ state: present
+ become: true
+ when: ansible_facts['os_family'] != 'RedHat'
+
+# Set password for new account
+# Expected result: success
+- name: Set password for test/test1
+ community.general.keyring:
+ service: test
+ username: test1
+ user_password: "{{ user_password }}"
+ keyring_password: "{{ keyring_password }}"
+ register: set_password
+
+- name: Assert that the password has been set
+ ansible.builtin.assert:
+ that:
+ - set_password.msg == "Passphrase has been updated for test@test1"
+
+# Print out password to confirm it has been set
+# Expected result: success
+- name: Retrieve password for test/test1
+ community.general.keyring_info:
+ service: test
+ username: test1
+ keyring_password: "{{ keyring_password }}"
+ register: test_set_password
+
+- name: Assert that the password exists
+ ansible.builtin.assert:
+ that:
+ - test_set_password.passphrase == user_password
+
+# Attempt to set password again
+# Expected result: success - nothing should happen
+- name: Attempt to re-set password for test/test1
+ community.general.keyring:
+ service: test
+ username: test1
+ user_password: "{{ user_password }}"
+ keyring_password: "{{ keyring_password }}"
+ register: second_set_password
+
+- name: Assert that the password has not been changed
+ ansible.builtin.assert:
+ that:
+ - second_set_password.msg == "Passphrase already set for test@test1"
+
+# Delete account
+# Expected result: success
+- name: Delete password for test/test1
+ community.general.keyring:
+ service: test
+ username: test1
+ user_password: "{{ user_password }}"
+ keyring_password: "{{ keyring_password }}"
+ state: absent
+ register: del_password
+
+- name: Assert that the password has been deleted
+ ansible.builtin.assert:
+ that:
+ - del_password.msg == "Passphrase has been removed for test@test1"
+
+# Attempt to get deleted account (to confirm it has been deleted).
+# Don't use `no_log` as run completes due to failed task.
+# Expected result: fail
+- name: Retrieve password for test/test1
+ community.general.keyring_info:
+ service: test
+ username: test1
+ keyring_password: "{{ keyring_password }}"
+ register: test_del_password
+
+- name: Assert that the password no longer exists
+ ansible.builtin.assert:
+ that:
+ - test_del_password.passphrase is not defined
diff --git a/ansible_collections/community/general/tests/integration/targets/keyring/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/keyring/vars/main.yml
new file mode 100644
index 000000000..b4997b6d3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/keyring/vars/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+keyring_password: Password123
+user_password: Test123
diff --git a/ansible_collections/community/general/tests/integration/targets/launchd/aliases b/ansible_collections/community/general/tests/integration/targets/launchd/aliases
new file mode 100644
index 000000000..a35088696
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/launchd/aliases
@@ -0,0 +1,7 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+skip/freebsd
+skip/rhel
diff --git a/ansible_collections/community/general/tests/integration/targets/launchd/files/ansible_test_service.py b/ansible_collections/community/general/tests/integration/targets/launchd/files/ansible_test_service.py
new file mode 100644
index 000000000..31de6c586
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/launchd/files/ansible_test_service.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+import sys
+
+if __name__ == '__main__':
+ if sys.version_info[0] >= 3:
+ import http.server
+ import socketserver
+ PORT = int(sys.argv[1])
+ Handler = http.server.SimpleHTTPRequestHandler
+ httpd = socketserver.TCPServer(("", PORT), Handler)
+ httpd.serve_forever()
+ else:
+ import mimetypes
+ mimetypes.init()
+ mimetypes.add_type('application/json', '.json')
+ import SimpleHTTPServer
+ SimpleHTTPServer.test()
diff --git a/ansible_collections/community/general/tests/integration/targets/launchd/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/launchd/tasks/main.yml
new file mode 100644
index 000000000..8f5b14a59
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/launchd/tasks/main.yml
@@ -0,0 +1,30 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Test launchd module
+ block:
+ - name: Expect that launchctl exists
+ stat:
+ path: /bin/launchctl
+ register: launchctl_check
+ failed_when:
+ - not launchctl_check.stat.exists
+
+ - name: Run tests
+ include_tasks: test.yml
+ with_items:
+ - test_unknown
+ - test_start_stop
+ - test_restart
+ - test_unload
+ - test_reload
+ - test_runatload
+
+ when: ansible_os_family == 'Darwin'
diff --git a/ansible_collections/community/general/tests/integration/targets/launchd/tasks/setup.yml b/ansible_collections/community/general/tests/integration/targets/launchd/tasks/setup.yml
new file mode 100644
index 000000000..bd7134cc0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/launchd/tasks/setup.yml
@@ -0,0 +1,23 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: "[{{ item }}] Deploy test service configuration"
+ template:
+ src: "{{ launchd_service_name }}.plist.j2"
+ dest: "{{ launchd_plist_location }}"
+ become: true
+
+- name: install the test daemon script
+ copy:
+ src: ansible_test_service.py
+ dest: /usr/local/sbin/ansible_test_service
+ mode: '755'
+
+- name: rewrite shebang in the test daemon script
+ lineinfile:
+ path: /usr/local/sbin/ansible_test_service
+ line: "#!{{ ansible_python_interpreter | realpath }}"
+ insertbefore: BOF
+ firstmatch: true
diff --git a/ansible_collections/community/general/tests/integration/targets/launchd/tasks/teardown.yml b/ansible_collections/community/general/tests/integration/targets/launchd/tasks/teardown.yml
new file mode 100644
index 000000000..e364056e6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/launchd/tasks/teardown.yml
@@ -0,0 +1,30 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: "[{{ item }}] Unload service"
+ launchd:
+ name: "{{ launchd_service_name }}"
+ state: unloaded
+ become: true
+ register: launchd_unloaded_result
+
+- name: "[{{ item }}] Validation"
+ assert:
+ that:
+ - launchd_unloaded_result is success
+ - launchd_unloaded_result.status.current_state == 'unloaded'
+ - launchd_unloaded_result.status.current_pid == '-'
+
+- name: "[{{ item }}] Remove test service configuration"
+ file:
+ path: "{{ launchd_plist_location }}"
+ state: absent
+ become: true
+
+- name: "[{{ item }}] Remove test service server"
+ file:
+ path: "/usr/local/sbin/ansible_test_service"
+ state: absent
+ become: true
diff --git a/ansible_collections/community/general/tests/integration/targets/launchd/tasks/test.yml b/ansible_collections/community/general/tests/integration/targets/launchd/tasks/test.yml
new file mode 100644
index 000000000..25a7bba00
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/launchd/tasks/test.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: "Running {{ item }}"
+ block:
+ - include_tasks: setup.yml
+ - include_tasks: "tests/{{ item }}.yml"
+ always:
+ - include_tasks: teardown.yml
diff --git a/ansible_collections/community/general/tests/integration/targets/launchd/tasks/tests/test_reload.yml b/ansible_collections/community/general/tests/integration/targets/launchd/tasks/tests/test_reload.yml
new file mode 100644
index 000000000..04dc8ae72
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/launchd/tasks/tests/test_reload.yml
@@ -0,0 +1,71 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# -----------------------------------------------------------
+
+- name: "[{{ item }}] Given a started service in check_mode"
+ launchd:
+ name: "{{ launchd_service_name }}"
+ state: started
+ become: true
+ register: "test_1_launchd_start_result_check_mode"
+ check_mode: true
+
+- name: "[{{ item }}] Assert that everything work in check mode"
+ assert:
+ that:
+ - test_1_launchd_start_result_check_mode is success
+ - test_1_launchd_start_result_check_mode is changed
+
+- name: "[{{ item }}] Given a started service..."
+ launchd:
+ name: "{{ launchd_service_name }}"
+ state: started
+ become: true
+ register: "test_1_launchd_start_result"
+
+
+- name: "[{{ item }}] The started service should run on port 21212"
+ wait_for:
+ port: 21212
+ delay: 5
+ timeout: 10
+
+- name: "[{{ item }}] Deploy a new test service configuration with a new port 21213"
+ template:
+ src: "modified.{{ launchd_service_name }}.plist.j2"
+ dest: "{{ launchd_plist_location }}"
+ become: true
+
+- name: "[{{ item }}] When reloading the service..."
+ launchd:
+ name: "{{ launchd_service_name }}"
+ state: reloaded
+ become: true
+ register: "test_1_launchd_reload_result"
+
+- name: "[{{ item }}] Validate that service was reloaded"
+ assert:
+ that:
+ - test_1_launchd_reload_result is success
+ - test_1_launchd_reload_result is changed
+ - test_1_launchd_reload_result.status.previous_pid == test_1_launchd_start_result.status.current_pid
+ - test_1_launchd_reload_result.status.previous_state == test_1_launchd_start_result.status.current_state
+ - test_1_launchd_reload_result.status.current_state == 'stopped'
+ - test_1_launchd_reload_result.status.current_pid == '-'
+
+- name: "[{{ item }}] Start the service with the new configuration..."
+ launchd:
+ name: "{{ launchd_service_name }}"
+ state: started
+ become: true
+ register: "test_1_launchd_start_result"
+
+
+- name: "[{{ item }}] The started service should run on port 21213"
+ wait_for:
+ port: 21213
+ delay: 5
+ timeout: 10
diff --git a/ansible_collections/community/general/tests/integration/targets/launchd/tasks/tests/test_restart.yml b/ansible_collections/community/general/tests/integration/targets/launchd/tasks/tests/test_restart.yml
new file mode 100644
index 000000000..44064cef1
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/launchd/tasks/tests/test_restart.yml
@@ -0,0 +1,46 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# -----------------------------------------------------------
+
+- name: "[{{ item }}] Given a started service..."
+ launchd:
+ name: "{{ launchd_service_name }}"
+ state: started
+ become: true
+ register: "test_1_launchd_start_result"
+
+
+- name: "[{{ item }}] When restarting the service in check mode"
+ launchd:
+ name: "{{ launchd_service_name }}"
+ state: restarted
+ become: true
+ register: "test_1_launchd_restart_result_check_mode"
+ check_mode: true
+
+- name: "[{{ item }}] Validate that service was restarted in check mode"
+ assert:
+ that:
+ - test_1_launchd_restart_result_check_mode is success
+ - test_1_launchd_restart_result_check_mode is changed
+
+- name: "[{{ item }}] When restarting the service..."
+ launchd:
+ name: "{{ launchd_service_name }}"
+ state: restarted
+ become: true
+ register: "test_1_launchd_restart_result"
+
+- name: "[{{ item }}] Validate that service was restarted"
+ assert:
+ that:
+ - test_1_launchd_restart_result is success
+ - test_1_launchd_restart_result is changed
+ - test_1_launchd_restart_result.status.previous_pid == test_1_launchd_start_result.status.current_pid
+ - test_1_launchd_restart_result.status.previous_state == test_1_launchd_start_result.status.current_state
+ - test_1_launchd_restart_result.status.current_state == 'started'
+ - test_1_launchd_restart_result.status.current_pid != '-'
+ - test_1_launchd_restart_result.status.status_code == '0'
diff --git a/ansible_collections/community/general/tests/integration/targets/launchd/tasks/tests/test_runatload.yml b/ansible_collections/community/general/tests/integration/targets/launchd/tasks/tests/test_runatload.yml
new file mode 100644
index 000000000..87c72d532
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/launchd/tasks/tests/test_runatload.yml
@@ -0,0 +1,36 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# -----------------------------------------------------------
+
+- name: "[{{ item }}] Given a started service with RunAtLoad set to true..."
+ launchd:
+ name: "{{ launchd_service_name }}"
+ state: started
+ enabled: true
+ become: true
+ register: test_1_launchd_start_result
+
+- name: "[{{ item }}] Validate that service was started"
+ assert:
+ that:
+ - test_1_launchd_start_result is success
+ - test_1_launchd_start_result is changed
+ - test_1_launchd_start_result.status.previous_pid == '-'
+ - test_1_launchd_start_result.status.previous_state == 'unloaded'
+ - test_1_launchd_start_result.status.current_state == 'started'
+ - test_1_launchd_start_result.status.current_pid != '-'
+ - test_1_launchd_start_result.status.status_code == '0'
+
+- name: "[{{ item }}] Validate that RunAtLoad is set to true"
+ replace:
+ path: "{{ launchd_plist_location }}"
+ regexp: |
+ \s+<key>RunAtLoad</key>
+ \s+<true/>
+ replace: found_run_at_load
+ check_mode: true
+ register: contents_would_have
+ failed_when: not contents_would_have is changed
diff --git a/ansible_collections/community/general/tests/integration/targets/launchd/tasks/tests/test_start_stop.yml b/ansible_collections/community/general/tests/integration/targets/launchd/tasks/tests/test_start_stop.yml
new file mode 100644
index 000000000..bf59979aa
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/launchd/tasks/tests/test_start_stop.yml
@@ -0,0 +1,115 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# -----------------------------------------------------------
+
+- name: "[{{ item }}] Given a started service in check mode"
+ launchd:
+ name: "{{ launchd_service_name }}"
+ state: started
+ become: true
+ register: "test_1_launchd_start_result_check_mode"
+ check_mode: true
+
+
+- name: "[{{ item }}] Validate that service was started in check mode"
+ assert:
+ that:
+ - test_1_launchd_start_result_check_mode is success
+ - test_1_launchd_start_result_check_mode is changed
+
+
+- name: "[{{ item }}] Given a started service..."
+ launchd:
+ name: "{{ launchd_service_name }}"
+ state: started
+ become: true
+ register: "test_1_launchd_start_result"
+
+
+- name: "[{{ item }}] Validate that service was started"
+ assert:
+ that:
+ - test_1_launchd_start_result is success
+ - test_1_launchd_start_result is changed
+ - test_1_launchd_start_result.status.previous_pid == '-'
+ - test_1_launchd_start_result.status.previous_state == 'unloaded'
+ - test_1_launchd_start_result.status.current_state == 'started'
+ - test_1_launchd_start_result.status.current_pid != '-'
+ - test_1_launchd_start_result.status.status_code == '0'
+
+# -----------------------------------------------------------
+
+- name: "[{{ item }}] Given a stopped service..."
+ launchd:
+ name: "{{ launchd_service_name }}"
+ state: stopped
+ become: true
+ register: "test_2_launchd_stop_result"
+
+- name: "[{{ item }}] Validate that service was stopped after it was started"
+ assert:
+ that:
+ - test_2_launchd_stop_result is success
+ - test_2_launchd_stop_result is changed
+ - test_2_launchd_stop_result.status.previous_pid == test_1_launchd_start_result.status.current_pid
+ - test_2_launchd_stop_result.status.previous_state == test_1_launchd_start_result.status.current_state
+ - test_2_launchd_stop_result.status.current_state == 'stopped'
+ - test_2_launchd_stop_result.status.current_pid == '-'
+
+# -----------------------------------------------------------
+
+- name: "[{{ item }}] Given a stopped service..."
+ launchd:
+ name: "{{ launchd_service_name }}"
+ state: stopped
+ become: true
+ register: "test_3_launchd_stop_result"
+
+- name: "[{{ item }}] Validate that service can be stopped after being already stopped"
+ assert:
+ that:
+ - test_3_launchd_stop_result is success
+ - not test_3_launchd_stop_result is changed
+ - test_3_launchd_stop_result.status.previous_pid == '-'
+ - test_3_launchd_stop_result.status.previous_state == 'stopped'
+ - test_3_launchd_stop_result.status.current_state == 'stopped'
+ - test_3_launchd_stop_result.status.current_pid == '-'
+
+# -----------------------------------------------------------
+
+- name: "[{{ item }}] Given a started service..."
+ launchd:
+ name: "{{ launchd_service_name }}"
+ state: started
+ become: true
+ register: "test_4_launchd_start_result"
+
+- name: "[{{ item }}] Validate that service was started..."
+ assert:
+ that:
+ - test_4_launchd_start_result is success
+ - test_4_launchd_start_result is changed
+ - test_4_launchd_start_result.status.previous_pid == '-'
+ - test_4_launchd_start_result.status.previous_state == 'stopped'
+ - test_4_launchd_start_result.status.current_state == 'started'
+ - test_4_launchd_start_result.status.current_pid != '-'
+ - test_4_launchd_start_result.status.status_code == '0'
+
+- name: "[{{ item }}] And when service is started again..."
+ launchd:
+ name: "{{ launchd_service_name }}"
+ state: started
+ become: true
+ register: "test_5_launchd_start_result"
+
+- name: "[{{ item }}] Validate that service is still in the same state as before"
+ assert:
+ that:
+ - test_5_launchd_start_result is success
+ - not test_5_launchd_start_result is changed
+ - test_5_launchd_start_result.status.previous_pid == test_4_launchd_start_result.status.current_pid
+ - test_5_launchd_start_result.status.previous_state == test_4_launchd_start_result.status.current_state
+ - test_5_launchd_start_result.status.status_code == '0'
diff --git a/ansible_collections/community/general/tests/integration/targets/launchd/tasks/tests/test_unknown.yml b/ansible_collections/community/general/tests/integration/targets/launchd/tasks/tests/test_unknown.yml
new file mode 100644
index 000000000..d18ea5453
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/launchd/tasks/tests/test_unknown.yml
@@ -0,0 +1,14 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# -----------------------------------------------------------
+
+- name: "[{{ item }}] Expect that an error occurs when an unknown service is used."
+ launchd:
+ name: com.acme.unknownservice
+ state: started
+ register: result
+ failed_when:
+ - not '"Unable to infer the path of com.acme.unknownservice service plist file and it was not found among active services" in result.msg'
diff --git a/ansible_collections/community/general/tests/integration/targets/launchd/tasks/tests/test_unload.yml b/ansible_collections/community/general/tests/integration/targets/launchd/tasks/tests/test_unload.yml
new file mode 100644
index 000000000..8915aac8b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/launchd/tasks/tests/test_unload.yml
@@ -0,0 +1,65 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# -----------------------------------------------------------
+
+- name: "[{{ item }}] Given a started service..."
+ launchd:
+ name: "{{ launchd_service_name }}"
+ state: started
+ become: true
+ register: "test_1_launchd_start_result"
+
+
+- name: "[{{ item }}] When unloading the service in check mode"
+ launchd:
+ name: "{{ launchd_service_name }}"
+ state: unloaded
+ become: true
+ register: "test_1_launchd_unloaded_result_check_mode"
+ check_mode: true
+
+- name: "[{{ item }}] Validate that service was unloaded in check mode"
+ assert:
+ that:
+ - test_1_launchd_unloaded_result_check_mode is success
+ - test_1_launchd_unloaded_result_check_mode is changed
+
+
+- name: "[{{ item }}] When unloading the service..."
+ launchd:
+ name: "{{ launchd_service_name }}"
+ state: unloaded
+ become: true
+ register: "test_1_launchd_unloaded_result"
+
+- name: "[{{ item }}] Validate that service was unloaded"
+ assert:
+ that:
+ - test_1_launchd_unloaded_result is success
+ - test_1_launchd_unloaded_result is changed
+ - test_1_launchd_unloaded_result.status.previous_pid == test_1_launchd_start_result.status.current_pid
+ - test_1_launchd_unloaded_result.status.previous_state == test_1_launchd_start_result.status.current_state
+ - test_1_launchd_unloaded_result.status.current_state == 'unloaded'
+ - test_1_launchd_unloaded_result.status.current_pid == '-'
+
+# -----------------------------------------------------------
+
+- name: "[{{ item }}] Given an unloaded service on an unloaded service..."
+ launchd:
+ name: "{{ launchd_service_name }}"
+ state: unloaded
+ become: true
+ register: "test_2_launchd_unloaded_result"
+
+- name: "[{{ item }}] Validate that service did not change and is still unloaded"
+ assert:
+ that:
+ - test_2_launchd_unloaded_result is success
+ - not test_2_launchd_unloaded_result is changed
+ - test_2_launchd_unloaded_result.status.previous_pid == '-'
+ - test_2_launchd_unloaded_result.status.previous_state == 'unloaded'
+ - test_2_launchd_unloaded_result.status.current_state == 'unloaded'
+ - test_2_launchd_unloaded_result.status.current_pid == '-'
diff --git a/ansible_collections/community/general/tests/integration/targets/launchd/templates/launchd.test.service.plist.j2 b/ansible_collections/community/general/tests/integration/targets/launchd/templates/launchd.test.service.plist.j2
new file mode 100644
index 000000000..43f43c24f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/launchd/templates/launchd.test.service.plist.j2
@@ -0,0 +1,18 @@
+{#
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+#}
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+ <dict>
+ <key>Label</key>
+ <string>{{ launchd_service_name }}</string>
+ <key>ProgramArguments</key>
+ <array>
+ <string>/usr/local/sbin/ansible_test_service</string>
+ <string>21212</string>
+ </array>
+ </dict>
+</plist>
diff --git a/ansible_collections/community/general/tests/integration/targets/launchd/templates/modified.launchd.test.service.plist.j2 b/ansible_collections/community/general/tests/integration/targets/launchd/templates/modified.launchd.test.service.plist.j2
new file mode 100644
index 000000000..a41b65562
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/launchd/templates/modified.launchd.test.service.plist.j2
@@ -0,0 +1,18 @@
+{#
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+#}
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+ <dict>
+ <key>Label</key>
+ <string>{{ launchd_service_name }}</string>
+ <key>ProgramArguments</key>
+ <array>
+ <string>/usr/local/sbin/ansible_test_service</string>
+ <string>21213</string>
+ </array>
+ </dict>
+</plist>
diff --git a/ansible_collections/community/general/tests/integration/targets/launchd/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/launchd/vars/main.yml
new file mode 100644
index 000000000..ce880ed9d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/launchd/vars/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+launchd_service_name: launchd.test.service
+launchd_plist_location: /Library/LaunchDaemons/{{ launchd_service_name }}.plist
diff --git a/ansible_collections/community/general/tests/integration/targets/ldap_search/aliases b/ansible_collections/community/general/tests/integration/targets/ldap_search/aliases
new file mode 100644
index 000000000..795844548
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ldap_search/aliases
@@ -0,0 +1,11 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+skip/aix
+skip/freebsd
+skip/osx
+skip/macos
+skip/rhel
+needs/root
diff --git a/ansible_collections/community/general/tests/integration/targets/ldap_search/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/ldap_search/meta/main.yml
new file mode 100644
index 000000000..d282aa0dc
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ldap_search/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_openldap
diff --git a/ansible_collections/community/general/tests/integration/targets/ldap_search/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/ldap_search/tasks/main.yml
new file mode 100644
index 000000000..521075b5e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ldap_search/tasks/main.yml
@@ -0,0 +1,16 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Run LDAP search module tests
+ block:
+ - include_tasks: "{{ item }}"
+ with_fileglob:
+ - 'tests/*.yml'
+ when: ansible_os_family in ['Ubuntu', 'Debian']
diff --git a/ansible_collections/community/general/tests/integration/targets/ldap_search/tasks/tests/basic.yml b/ansible_collections/community/general/tests/integration/targets/ldap_search/tasks/tests/basic.yml
new file mode 100644
index 000000000..36d245d39
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ldap_search/tasks/tests/basic.yml
@@ -0,0 +1,25 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- debug:
+ msg: Running tests/basic.yml
+
+####################################################################
+## Search ##########################################################
+####################################################################
+- name: Test simple search for a user
+ ldap_search:
+ dn: "ou=users,dc=example,dc=com"
+ scope: "onelevel"
+ filter: "(uid=ldaptest)"
+ ignore_errors: true
+ register: output
+
+- name: assert that test LDAP user can be found
+ assert:
+ that:
+ - output is not failed
+ - output.results | length == 1
+ - output.results.0.displayName == "LDAP Test"
diff --git a/ansible_collections/community/general/tests/integration/targets/listen_ports_facts/aliases b/ansible_collections/community/general/tests/integration/targets/listen_ports_facts/aliases
new file mode 100644
index 000000000..620afe071
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/listen_ports_facts/aliases
@@ -0,0 +1,10 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/3
+destructive
+skip/aix
+skip/osx
+skip/macos
+skip/freebsd
diff --git a/ansible_collections/community/general/tests/integration/targets/listen_ports_facts/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/listen_ports_facts/meta/main.yml
new file mode 100644
index 000000000..2fcd152f9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/listen_ports_facts/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
diff --git a/ansible_collections/community/general/tests/integration/targets/listen_ports_facts/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/listen_ports_facts/tasks/main.yml
new file mode 100644
index 000000000..70649f505
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/listen_ports_facts/tasks/main.yml
@@ -0,0 +1,112 @@
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Test playbook for the listen_ports_facts module
+# Copyright (c) 2019, Nathan Davison <ndavison85@gmail.com>
+
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: install netstat and netcat on deb
+ ansible.builtin.package:
+ name:
+ - net-tools
+ - netcat
+ state: latest
+ when: ansible_os_family == "Debian"
+
+- name: install netstat and netcat on rh < 7
+ ansible.builtin.package:
+ name:
+ - net-tools
+ - nc.x86_64
+ state: latest
+ when: ansible_os_family == "RedHat" and ansible_distribution_major_version|int < 7
+
+- name: install netcat on rh >= 7
+ ansible.builtin.package:
+ name: 'nmap-ncat'
+ state: latest
+ when: ansible_os_family == "RedHat" and ansible_distribution_major_version|int >= 7
+
+- name: start UDP server on port 5555
+ command: nc -u -l -p 5555
+ async: 1000
+ poll: 0
+ when: (ansible_os_family == "RedHat" and ansible_distribution_major_version|int >= 7) or ansible_os_family == "Debian"
+
+- name: start UDP server on port 5555
+ command: nc -u -l 5555
+ async: 1000
+ poll: 0
+ when: ansible_os_family == "RedHat" and ansible_distribution_major_version|int < 7
+
+- name: start TCP server on port 5556
+ command: "nc -l -p 5556"
+ async: 1000
+ poll: 0
+ when: (ansible_os_family == "RedHat" and ansible_distribution_major_version|int >= 7) or ansible_os_family == "Debian"
+
+- name: start TCP server on port 5556
+ command: "nc -l 5556"
+ async: 1000
+ poll: 0
+ when: ansible_os_family == "RedHat" and ansible_distribution_major_version|int < 7
+
+- name: Gather listening ports facts
+ listen_ports_facts:
+ when: ansible_os_family == "RedHat" or ansible_os_family == "Debian"
+
+- name: check that the include_non_listening parameters ('state' and 'foreign_address') are not active in default setting
+ assert:
+ that:
+ - ansible_facts.tcp_listen | selectattr('state', 'defined') | list | length == 0
+ - ansible_facts.tcp_listen | selectattr('foreign_address', 'defined') | list | length == 0
+ when: ansible_os_family == "RedHat" or ansible_os_family == "Debian"
+
+- name: Gather listening ports facts explicitly via netstat and include_non_listening
+ listen_ports_facts:
+ command: 'netstat'
+ include_non_listening: 'yes'
+ when: (ansible_os_family == "RedHat" and ansible_distribution_major_version|int < 7) or ansible_os_family == "Debian"
+
+- name: Gather listening ports facts explicitly via ss and include_non_listening
+ listen_ports_facts:
+ command: 'ss'
+ include_non_listening: 'yes'
+ when: ansible_os_family == "RedHat" and ansible_distribution_major_version|int >= 7
+
+- name: check for ansible_facts.udp_listen exists
+ assert:
+ that: ansible_facts.udp_listen is defined
+ when: ansible_os_family == "RedHat" or ansible_os_family == "Debian"
+
+- name: check for ansible_facts.tcp_listen exists
+ assert:
+ that: ansible_facts.tcp_listen is defined
+ when: ansible_os_family == "RedHat" or ansible_os_family == "Debian"
+
+- name: check that the include_non_listening parameter 'state' and 'foreign_address' exists
+ assert:
+ that:
+ - ansible_facts.tcp_listen | selectattr('state', 'defined') | list | length > 0
+ - ansible_facts.tcp_listen | selectattr('foreign_address', 'defined') | list | length > 0
+ when: ansible_os_family == "RedHat" or ansible_os_family == "Debian"
+
+- name: check TCP 5556 is in listening ports
+ assert:
+ that: 5556 in ansible_facts.tcp_listen | map(attribute='port') | sort | list
+ when: (ansible_os_family == "RedHat" and ansible_distribution_major_version|int >= 7) or ansible_os_family == "Debian"
+
+- name: check UDP 5555 is in listening ports
+ assert:
+ that: 5555 in ansible_facts.udp_listen | map(attribute='port') | sort | list
+ when: (ansible_os_family == "RedHat" and ansible_distribution_major_version|int >= 7) or ansible_os_family == "Debian"
+
+- name: kill all async commands
+ command: "kill -9 {{ item.pid }}"
+ loop: "{{ [tcp_listen, udp_listen]|flatten }}"
+ when: item.name == 'nc'
+ ignore_errors: true
diff --git a/ansible_collections/community/general/tests/integration/targets/locale_gen/aliases b/ansible_collections/community/general/tests/integration/targets/locale_gen/aliases
new file mode 100644
index 000000000..f7f4063f6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/locale_gen/aliases
@@ -0,0 +1,8 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/3
+destructive
+needs/root
+skip/aix
diff --git a/ansible_collections/community/general/tests/integration/targets/locale_gen/tasks/locale_gen.yml b/ansible_collections/community/general/tests/integration/targets/locale_gen/tasks/locale_gen.yml
new file mode 100644
index 000000000..c6bdcc046
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/locale_gen/tasks/locale_gen.yml
@@ -0,0 +1,99 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Is the locale we're going to test against installed?
+ shell: locale -a | grep pt_BR
+ register: initial_state
+ ignore_errors: true
+
+- name: Make sure the locale is not installed
+ locale_gen:
+ name: pt_BR
+ state: absent
+
+- name: Is the locale present?
+ shell: locale -a | grep pt_BR
+ register: cleaned
+ ignore_errors: true
+
+- name: Make sure the locale is not present
+ assert:
+ that:
+ - "cleaned.rc == 1"
+
+- name: Install the locale
+ locale_gen:
+ name: pt_BR
+ state: present
+ register: output
+
+- name: Is the locale present?
+ shell: locale -a | grep pt_BR
+ register: post_check_output
+ ignore_errors: true
+
+- name: Make sure the locale is present and we say we installed it
+ assert:
+ that:
+ - "post_check_output.rc == 0"
+ - "output.changed"
+
+- name: Install the locale a second time
+ locale_gen:
+ name: pt_BR
+ state: present
+ register: output
+
+- name: Is the locale present?
+ shell: locale -a | grep pt_BR
+ register: post_check_output
+ ignore_errors: true
+
+- name: Make sure the locale is present and we reported no change
+ assert:
+ that:
+ - "post_check_output.rc == 0"
+ - "not output.changed"
+
+- name: Remove the locale
+ locale_gen:
+ name: pt_BR
+ state: absent
+ register: output
+
+- name: Is the locale present?
+ shell: locale -a | grep pt_BR
+ register: post_check_output
+ ignore_errors: true
+
+- name: Make sure the locale is absent and we reported a change
+ assert:
+ that:
+ - "post_check_output.rc == 1"
+ - "output.changed"
+
+- name: Remove the locale a second time
+ locale_gen:
+ name: pt_BR
+ state: absent
+ register: output
+
+- name: Is the locale present?
+ shell: locale -a | grep pt_BR
+ register: post_check_output
+ ignore_errors: true
+
+- name: Make sure the locale is absent and we reported no change
+ assert:
+ that:
+ - "post_check_output.rc == 1"
+ - "not output.changed"
+
+# Cleanup
+- name: Reinstall the locale we tested against if it was initially installed
+ locale_gen:
+ name: pt_BR
+ state: present
+ when: initial_state.rc == 0
diff --git a/ansible_collections/community/general/tests/integration/targets/locale_gen/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/locale_gen/tasks/main.yml
new file mode 100644
index 000000000..de3e673be
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/locale_gen/tasks/main.yml
@@ -0,0 +1,12 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2014, James Tanner <tanner.jc@gmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- include_tasks: 'locale_gen.yml'
+ when: ansible_distribution in ('Ubuntu', 'Debian')
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_cartesian/aliases b/ansible_collections/community/general/tests/integration/targets/lookup_cartesian/aliases
new file mode 100644
index 000000000..2bdcc0113
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_cartesian/aliases
@@ -0,0 +1,7 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+skip/aix
+skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_cartesian/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/lookup_cartesian/tasks/main.yml
new file mode 100644
index 000000000..5575f22ba
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_cartesian/tasks/main.yml
@@ -0,0 +1,32 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Test cartesian lookup
+ debug: var=item
+ register: product
+ with_community.general.cartesian:
+ - - A
+ - B
+ - C
+ - - '1'
+ - '2'
+ - '3'
+- name: Verify cartesian lookup
+ assert:
+ that:
+ - product.results[0]['item'] == ["A", "1"]
+ - product.results[1]['item'] == ["A", "2"]
+ - product.results[2]['item'] == ["A", "3"]
+ - product.results[3]['item'] == ["B", "1"]
+ - product.results[4]['item'] == ["B", "2"]
+ - product.results[5]['item'] == ["B", "3"]
+ - product.results[6]['item'] == ["C", "1"]
+ - product.results[7]['item'] == ["C", "2"]
+ - product.results[8]['item'] == ["C", "3"]
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/aliases b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/aliases
new file mode 100644
index 000000000..343f119da
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/3
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll/galaxy.yml b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll/galaxy.yml
new file mode 100644
index 000000000..2243e0dba
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll/galaxy.yml
@@ -0,0 +1,12 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+namespace: testns
+name: testcoll
+version: 0.0.1
+authors:
+ - Ansible (https://github.com/ansible)
+description: null
+tags: [community]
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll/plugins/modules/collection_module.py b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll/plugins/modules/collection_module.py
new file mode 100644
index 000000000..e7f1a987a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll/plugins/modules/collection_module.py
@@ -0,0 +1,33 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2021, Felix Fontein <felix@fontein.de>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: collection_module
+short_description: Test collection module
+description:
+ - This is a test module in a local collection.
+author: "Felix Fontein (@felixfontein)"
+options: {}
+'''
+
+EXAMPLES = ''' # '''
+
+RETURN = ''' # '''
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ AnsibleModule(argument_spec={}).exit_json()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_mf/FILES.json b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_mf/FILES.json
new file mode 100644
index 000000000..57bc66cc2
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_mf/FILES.json
@@ -0,0 +1,40 @@
+{
+ "files": [
+ {
+ "name": ".",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "README.md",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
+ "format": 1
+ },
+ {
+ "name": "plugins",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "plugins/modules",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/collection_module.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "c3f0114d080c409c58c8846be8da7b91137b38eaf2d24f72a4a61a303f925f4d",
+ "format": 1
+ }
+ ],
+ "format": 1
+}
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_mf/FILES.json.license b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_mf/FILES.json.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_mf/FILES.json.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_mf/MANIFEST.json b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_mf/MANIFEST.json
new file mode 100644
index 000000000..e4a9e7d8f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_mf/MANIFEST.json
@@ -0,0 +1,30 @@
+{
+ "collection_info": {
+ "namespace": "testns",
+ "name": "testcoll_mf",
+ "version": "0.0.1",
+ "authors": [
+ "Ansible (https://github.com/ansible)"
+ ],
+ "readme": "README.md",
+ "tags": [
+ "community"
+ ],
+ "description": null,
+ "license": [],
+ "license_file": null,
+ "dependencies": {},
+ "repository": null,
+ "documentation": null,
+ "homepage": null,
+ "issues": null
+ },
+ "file_manifest_file": {
+ "name": "FILES.json",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "025818f18fcae5c9f78d778ae6e246ecffed6d56a886ffbc145cb66d54e9951e",
+ "format": 1
+ },
+ "format": 1
+}
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_mf/MANIFEST.json.license b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_mf/MANIFEST.json.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_mf/MANIFEST.json.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_mf/README.md b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_mf/README.md
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_mf/README.md
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_mf/plugins/modules/collection_module.py b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_mf/plugins/modules/collection_module.py
new file mode 100644
index 000000000..e7f1a987a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_mf/plugins/modules/collection_module.py
@@ -0,0 +1,33 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2021, Felix Fontein <felix@fontein.de>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: collection_module
+short_description: Test collection module
+description:
+ - This is a test module in a local collection.
+author: "Felix Fontein (@felixfontein)"
+options: {}
+'''
+
+EXAMPLES = ''' # '''
+
+RETURN = ''' # '''
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ AnsibleModule(argument_spec={}).exit_json()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_nothing/plugins/modules/collection_module.py b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_nothing/plugins/modules/collection_module.py
new file mode 100644
index 000000000..e7f1a987a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_nothing/plugins/modules/collection_module.py
@@ -0,0 +1,33 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2021, Felix Fontein <felix@fontein.de>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: collection_module
+short_description: Test collection module
+description:
+ - This is a test module in a local collection.
+author: "Felix Fontein (@felixfontein)"
+options: {}
+'''
+
+EXAMPLES = ''' # '''
+
+RETURN = ''' # '''
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ AnsibleModule(argument_spec={}).exit_json()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_nv/galaxy.yml b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_nv/galaxy.yml
new file mode 100644
index 000000000..96aae3d64
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_nv/galaxy.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+namespace: testns
+name: testcoll_nv
+authors:
+ - Ansible (https://github.com/ansible)
+description: null
+tags: [community]
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_nv/plugins/modules/collection_module.py b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_nv/plugins/modules/collection_module.py
new file mode 100644
index 000000000..e7f1a987a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/collections/ansible_collections/testns/testcoll_nv/plugins/modules/collection_module.py
@@ -0,0 +1,33 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2021, Felix Fontein <felix@fontein.de>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: collection_module
+short_description: Test collection module
+description:
+ - This is a test module in a local collection.
+author: "Felix Fontein (@felixfontein)"
+options: {}
+'''
+
+EXAMPLES = ''' # '''
+
+RETURN = ''' # '''
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ AnsibleModule(argument_spec={}).exit_json()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/library/local_module.py b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/library/local_module.py
new file mode 100644
index 000000000..9e9e649cb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/library/local_module.py
@@ -0,0 +1,33 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2021, Felix Fontein <felix@fontein.de>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: local_module
+short_description: Test local module
+description:
+ - This is a test module locally next to a playbook.
+author: "Felix Fontein (@felixfontein)"
+options: {}
+'''
+
+EXAMPLES = ''' # '''
+
+RETURN = ''' # '''
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ AnsibleModule(argument_spec={}).exit_json()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/runme.sh b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/runme.sh
new file mode 100755
index 000000000..118abbc29
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/runme.sh
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+set -eux
+
+source virtualenv.sh
+
+# The collection loader ignores paths which have more than one ansible_collections in it.
+# That's why we have to copy this directory to a temporary place and run the test there.
+
+# Create temporary folder
+TEMPDIR=$(mktemp -d)
+trap '{ rm -rf ${TEMPDIR}; }' EXIT
+
+cp -r . "${TEMPDIR}"
+cd "${TEMPDIR}"
+
+ansible-playbook runme.yml "$@"
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/runme.yml b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/runme.yml
new file mode 100644
index 000000000..54c58614f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_collection_version/runme.yml
@@ -0,0 +1,40 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- hosts: localhost
+ tasks:
+ - name: Test collection_version
+ assert:
+ that:
+ # Collection that does not exist
+ - query('community.general.collection_version', 'foo.bar') == [none]
+ - lookup('community.general.collection_version', 'foo.bar', result_not_found='foo') == 'foo'
+ # Collection that exists
+ - lookup('community.general.collection_version', 'community.general') is string
+ # Local collection
+ - lookup('community.general.collection_version', 'testns.testcoll') == '0.0.1'
+ # Local collection with no version
+ - lookup('community.general.collection_version', 'testns.testcoll_nv') == '*'
+ - lookup('community.general.collection_version', 'testns.testcoll_nv', result_no_version='') == ''
+ # Local collection with MANIFEST.json
+ - lookup('community.general.collection_version', 'testns.testcoll_mf') == '0.0.1'
+ # Local collection with no galaxy.yml and no MANIFEST.json
+ - lookup('community.general.collection_version', 'testns.testcoll_nothing') == '*'
+ - lookup('community.general.collection_version', 'testns.testcoll_nothing', result_no_version='0.0.0') == '0.0.0'
+ # Multiple collection names at once
+ - lookup('community.general.collection_version', 'testns.testcoll', 'testns.testcoll_nv', 'testns.testcoll_nv', 'testns.testcoll_mf', 'foo.bar')
+ == ['0.0.1', '*', '*', '0.0.1', none]
+
+ - name: Invalid FQCN
+ set_fact:
+ test: "{{ query('community.general.collection_version', 'foo.bar.baz') }}"
+ ignore_errors: true
+ register: invalid_fqcn
+
+ - name: Validate error message
+ assert:
+ that:
+ - >
+ '"foo.bar.baz" is not a FQCN' in invalid_fqcn.msg
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_dependent/aliases b/ansible_collections/community/general/tests/integration/targets/lookup_dependent/aliases
new file mode 100644
index 000000000..26ad5c244
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_dependent/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_dependent/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/lookup_dependent/tasks/main.yml
new file mode 100644
index 000000000..b2f209729
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_dependent/tasks/main.yml
@@ -0,0 +1,183 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Test 1
+ set_fact:
+ loop_result: >-
+ {{
+ query('community.general.dependent',
+ dict(key1=[1, 2]),
+ dict(key2='[item.key1 + 3, item.key1 + 6]'),
+ dict(key3='[item.key1 + item.key2 * 10]'))
+ }}
+
+- name: Check result of Test 1
+ assert:
+ that:
+ - loop_result == expected_result
+ vars:
+ expected_result:
+ - key1: 1
+ key2: 4
+ key3: 41
+ - key1: 1
+ key2: 7
+ key3: 71
+ - key1: 2
+ key2: 5
+ key3: 52
+ - key1: 2
+ key2: 8
+ key3: 82
+
+- name: Test 2
+ set_fact:
+ loop_result: >-
+ {{ query('community.general.dependent',
+ dict([['a', [1, 2, 3]]]),
+ dict([['b', '[1, 2, 3, 4] if item.a == 1 else [2, 3, 4] if item.a == 2 else [3, 4]']])) }}
+ # The last expression could have been `range(item.a, 5)`, but that's not supported by all Jinja2 versions used in CI
+
+- name: Check result of Test 2
+ assert:
+ that:
+ - loop_result == expected_result
+ vars:
+ expected_result:
+ - a: 1
+ b: 1
+ - a: 1
+ b: 2
+ - a: 1
+ b: 3
+ - a: 1
+ b: 4
+ - a: 2
+ b: 2
+ - a: 2
+ b: 3
+ - a: 2
+ b: 4
+ - a: 3
+ b: 3
+ - a: 3
+ b: 4
+
+- name: Test 3
+ debug:
+ var: item
+ with_community.general.dependent:
+ - var1:
+ a:
+ - 1
+ - 2
+ b:
+ - 3
+ - 4
+ - var2: 'item.var1.value'
+ - var3: 'dependent_lookup_test[item.var1.key ~ "_" ~ item.var2]'
+ loop_control:
+ label: "{{ [item.var1.key, item.var2, item.var3] }}"
+ register: dependent
+ vars:
+ dependent_lookup_test:
+ a_1:
+ - A
+ - B
+ a_2:
+ - C
+ b_3:
+ - D
+ b_4:
+ - E
+ - F
+ - G
+
+- name: Check result of Test 3
+ assert:
+ that:
+ - (dependent.results | length) == 7
+ - dependent.results[0].item.var1.key == "a"
+ - dependent.results[0].item.var2 == 1
+ - dependent.results[0].item.var3 == "A"
+ - dependent.results[1].item.var1.key == "a"
+ - dependent.results[1].item.var2 == 1
+ - dependent.results[1].item.var3 == "B"
+ - dependent.results[2].item.var1.key == "a"
+ - dependent.results[2].item.var2 == 2
+ - dependent.results[2].item.var3 == "C"
+ - dependent.results[3].item.var1.key == "b"
+ - dependent.results[3].item.var2 == 3
+ - dependent.results[3].item.var3 == "D"
+ - dependent.results[4].item.var1.key == "b"
+ - dependent.results[4].item.var2 == 4
+ - dependent.results[4].item.var3 == "E"
+ - dependent.results[5].item.var1.key == "b"
+ - dependent.results[5].item.var2 == 4
+ - dependent.results[5].item.var3 == "F"
+ - dependent.results[6].item.var1.key == "b"
+ - dependent.results[6].item.var2 == 4
+ - dependent.results[6].item.var3 == "G"
+
+- name: "Test 4: template failure"
+ debug:
+ msg: "{{ item }}"
+ with_community.general.dependent:
+ - a:
+ - 1
+ - 2
+ - b: "[item.a + foo]"
+ ignore_errors: true
+ register: eval_error
+
+- name: Check result of Test 4
+ assert:
+ that:
+ - eval_error is failed
+ - eval_error.msg.startswith("Caught \"'foo' is undefined")
+
+- name: "Test 5: same variable name reused"
+ debug:
+ msg: "{{ item }}"
+ with_community.general.dependent:
+ - a: x
+ - b: x
+ ignore_errors: true
+ register: eval_error
+
+- name: Check result of Test 5
+ assert:
+ that:
+ - eval_error is failed
+ - eval_error.msg.startswith("Caught \"'x' is undefined")
+
+- name: "Test 6: multi-value dict"
+ debug:
+ msg: "{{ item }}"
+ with_community.general.dependent:
+ - a: x
+ b: x
+ ignore_errors: true
+ register: eval_error
+
+- name: Check result of Test 6
+ assert:
+ that:
+ - eval_error is failed
+ - eval_error.msg == 'Parameter 0 must be a one-element dictionary, got 2 elements'
+
+- name: "Test 7: empty dict"
+ debug:
+ msg: "{{ item }}"
+ with_community.general.dependent:
+ - {}
+ ignore_errors: true
+ register: eval_error
+
+- name: Check result of Test 7
+ assert:
+ that:
+ - eval_error is failed
+ - eval_error.msg == 'Parameter 0 must be a one-element dictionary, got 0 elements'
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_dig/aliases b/ansible_collections/community/general/tests/integration/targets/lookup_dig/aliases
new file mode 100644
index 000000000..eb449a9cf
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_dig/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_dig/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/lookup_dig/meta/main.yml
new file mode 100644
index 000000000..fe9e33681
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_dig/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_remote_constraints
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_dig/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/lookup_dig/tasks/main.yml
new file mode 100644
index 000000000..2f48333cb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_dig/tasks/main.yml
@@ -0,0 +1,37 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install dnspython library
+ pip:
+ name: dnspython
+ state: present
+ extra_args: "-c {{ remote_constraints }}"
+
+- name: Test dig lookup with existing domain
+ set_fact:
+ dig_existing: "{{ lookup('community.general.dig', 'github.com.') }}"
+
+- name: Test dig lookup with non-existing domain and fail_on_error=no
+ set_fact:
+ dig_nonexisting_fail_no: "{{ lookup('community.general.dig', 'non-existing.domain.', 'fail_on_error=no') }}"
+
+- name: Verify that NXDOMAIN was returned
+ assert:
+ that: dig_nonexisting_fail_no == 'NXDOMAIN'
+
+- name: Test dig lookup with non-existing domain and fail_on_error=yes
+ set_fact:
+ dig_nonexisting_fail_yes: "{{ lookup('community.general.dig', 'non-existing.domain.', 'fail_on_error=yes') }}"
+ ignore_errors: true
+ register: dig_nonexisting_fail_yes_result
+
+- name: Verify that the task failed
+ assert:
+ that: dig_nonexisting_fail_yes_result is failed
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/aliases b/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/aliases
new file mode 100644
index 000000000..b9f3395f7
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/aliases
@@ -0,0 +1,14 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+destructive
+needs/file/tests/utils/constraints.txt
+needs/target/setup_etcd3
+skip/aix
+skip/osx
+skip/macos
+skip/freebsd
+skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
+disabled # see https://github.com/ansible-collections/community.general/issues/322
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/defaults/main.yml
new file mode 100644
index 000000000..de726382b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/defaults/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ etcd3_prefix: '/keyprefix/'
+ etcd3_singlekey: '/singlekeypath'
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/dependencies.yml b/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/dependencies.yml
new file mode 100644
index 000000000..ea012594d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/dependencies.yml
@@ -0,0 +1,10 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- hosts: localhost
+ tasks:
+ - name: Setup etcd3
+ import_role:
+ name: setup_etcd3
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/meta/main.yml
new file mode 100644
index 000000000..2fcd152f9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/runme.sh b/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/runme.sh
new file mode 100755
index 000000000..1b37ae4f3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/runme.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+# Copyright (c) Ansible project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+set -eux
+
+ANSIBLE_ROLES_PATH=../ \
+ ansible-playbook dependencies.yml -v "$@"
+
+ANSIBLE_ROLES_PATH=../ \
+ ansible-playbook test_lookup_etcd3.yml -v "$@"
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/tasks/main.yml
new file mode 100644
index 000000000..47f1916c0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/tasks/main.yml
@@ -0,0 +1,28 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# lookup_etcd3 integration tests
+# Copyright 2020, SCC France, Eric Belhomme <ebelhomme@fr.scc.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: put key/values with an etcd prefix
+ etcd3:
+ key: "{{ etcd3_prefix }}foo{{ item }}"
+ value: "bar{{ item }}"
+ state: present
+ loop:
+ - 1
+ - 2
+ - 3
+
+- name: put a single key/values in etcd
+ etcd3:
+ key: "{{ etcd3_singlekey }}"
+ value: "foobar"
+ state: present
+
+- import_tasks: tests.yml
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/tasks/tests.yml b/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/tasks/tests.yml
new file mode 100644
index 000000000..929c6f142
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/tasks/tests.yml
@@ -0,0 +1,27 @@
+---
+# lookup_etcd3 integration tests
+# Copyright 2020, SCC France, Eric Belhomme <ebelhomme@fr.scc.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- block:
+ - name: 'Fetch secrets using "etcd3" lookup'
+ set_fact:
+ etcdoutkey1: "{{ lookup('community.general.etcd3', etcd3_prefix, prefix=True) }}"
+ etcdoutkey2: "{{ lookup('community.general.etcd3', etcd3_singlekey) }}"
+ key_inexistent: "{{ lookup('community.general.etcd3', 'inexistent_key') }}"
+
+ - name: 'Check etcd values'
+ assert:
+ msg: 'unexpected etcd3 values'
+ that:
+ - etcdoutkey1 is sequence
+ - etcdoutkey1 | length() == 3
+ - etcdoutkey1[0].value == 'bar1'
+ - etcdoutkey1[1].value == 'bar2'
+ - etcdoutkey1[2].value == 'bar3'
+ - etcdoutkey2 is sequence
+ - etcdoutkey2 | length() == 2
+ - etcdoutkey2.value == 'foobar'
+ - key_inexistent is sequence
+ - key_inexistent | length() == 0
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/test_lookup_etcd3.yml b/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/test_lookup_etcd3.yml
new file mode 100644
index 000000000..c18138888
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_etcd3/test_lookup_etcd3.yml
@@ -0,0 +1,10 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- hosts: localhost
+ tasks:
+ - name: Test lookup etcd3
+ import_role:
+ name: lookup_etcd3
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_flattened/aliases b/ansible_collections/community/general/tests/integration/targets/lookup_flattened/aliases
new file mode 100644
index 000000000..0ac9bad98
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_flattened/aliases
@@ -0,0 +1,7 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+skip/aix
+skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_flattened/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/lookup_flattened/tasks/main.yml
new file mode 100644
index 000000000..37af1327b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_flattened/tasks/main.yml
@@ -0,0 +1,24 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: test with_flattened
+ set_fact: '{{ item }}=flattened'
+ with_community.general.flattened:
+ - - a__
+ - - b__
+ - - c__
+ - d__
+- name: verify with_flattened results
+ assert:
+ that:
+ - a__ == 'flattened'
+ - b__ == 'flattened'
+ - c__ == 'flattened'
+ - d__ == 'flattened'
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/aliases b/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/aliases
new file mode 100644
index 000000000..66632fb4a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/aliases
@@ -0,0 +1,8 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+destructive
+skip/aix
+skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/dependencies.yml b/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/dependencies.yml
new file mode 100644
index 000000000..9fc63b19f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/dependencies.yml
@@ -0,0 +1,16 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- hosts: localhost
+ tasks:
+ - name: Install LMDB Python package
+ pip:
+ name: lmdb
+ environment:
+ LMDB_PURE: "1"
+ - name: Setup test data
+ script: test_db.py
+ args:
+ executable: "{{ ansible_python.executable }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/runme.sh b/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/runme.sh
new file mode 100755
index 000000000..71faa439d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/runme.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+# Copyright (c) Ansible project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+set -eux
+
+ANSIBLE_ROLES_PATH=../ \
+ ansible-playbook dependencies.yml -v "$@"
+
+ANSIBLE_ROLES_PATH=../ \
+ ansible-playbook test.yml -v "$@"
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/test.yml b/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/test.yml
new file mode 100644
index 000000000..217c020ca
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/test.yml
@@ -0,0 +1,31 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- hosts: localhost
+ tasks:
+ - debug:
+ msg: '{{ query("community.general.lmdb_kv", "nl", "be", "lu", db="jp.mdb") }}'
+ - debug:
+ var: item.1
+ loop: '{{ query("community.general.lmdb_kv", db="jp.mdb") }}'
+ - assert:
+ that:
+ - query('community.general.lmdb_kv', 'nl', 'be', 'lu', db='jp.mdb') == ['Netherlands', 'Belgium', 'Luxembourg']
+ - query('community.general.lmdb_kv', db='jp.mdb')|length == 5
+ - assert:
+ that:
+ - item.0 == 'nl'
+ - item.1 == 'Netherlands'
+ vars:
+ - lmdb_kv_db: jp.mdb
+ with_community.general.lmdb_kv:
+ - n*
+ - assert:
+ that:
+ - item == 'Belgium'
+ vars:
+ - lmdb_kv_db: jp.mdb
+ with_community.general.lmdb_kv:
+ - be
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/test_db.py b/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/test_db.py
new file mode 100644
index 000000000..b906c4c39
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_lmdb_kv/test_db.py
@@ -0,0 +1,15 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+import lmdb
+map_size = 1024 * 100
+env = lmdb.open('./jp.mdb', map_size=map_size)
+with env.begin(write=True) as txn:
+ txn.put('fr'.encode(), 'France'.encode())
+ txn.put('nl'.encode(), 'Netherlands'.encode())
+ txn.put('es'.encode(), 'Spain'.encode())
+ txn.put('be'.encode(), 'Belgium'.encode())
+ txn.put('lu'.encode(), 'Luxembourg'.encode())
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/aliases b/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/aliases
new file mode 100644
index 000000000..eb449a9cf
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/runme.sh b/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/runme.sh
new file mode 100755
index 000000000..52a38f4a5
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/runme.sh
@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+# Copyright (c) 2020, Thales Netherlands
+# Copyright (c) 2021, Ansible project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+set -eux
+
+ANSIBLE_LOG_PATH=/tmp/ansible-test-merge-variables \
+ ansible-playbook test.yml "$@"
+
+ANSIBLE_LOG_PATH=/tmp/ansible-test-merge-variables \
+ANSIBLE_MERGE_VARIABLES_PATTERN_TYPE=suffix \
+ ansible-playbook test_with_env.yml "$@"
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test.yml b/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test.yml
new file mode 100644
index 000000000..fbd884393
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test.yml
@@ -0,0 +1,174 @@
+---
+# Copyright (c) 2020, Thales Netherlands
+# Copyright (c) 2021, Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Test merge_variables lookup plugin
+ hosts: localhost
+ tasks:
+ - name: Include test data
+ include_vars: vars.yml
+
+ # Test the default behavior
+ - name: Test merge list
+ block:
+ - name: Print the merged list
+ debug:
+ msg: "{{ merged_list }}"
+
+ - name: Validate that the list is complete
+ assert:
+ that:
+ - "(merged_list | length) == 2"
+ - "'item1' in merged_list"
+ - "'item3' in merged_list"
+ vars:
+ merged_list: "{{ lookup('community.general.merge_variables', '^.+__merge_list$') }}"
+
+ - name: Test merge dict
+ block:
+ - name: Print the merged list
+ debug:
+ msg: "{{ merged_dict }}"
+
+ - name: Validate that dict is complete
+ assert:
+ that:
+ - "'item1' in merged_dict"
+ - "'item2' in merged_dict"
+ - "'list_item' in merged_dict"
+ - "(merged_dict.list_item | length) == 2"
+ - "'test1' in (merged_dict.list_item)"
+ - "'test2' in (merged_dict.list_item)"
+ vars:
+ merged_dict: "{{ lookup('community.general.merge_variables', '^.+__merge_dict$') }}"
+
+ # Test the behavior when no results are found
+ - name: Test merge without results
+ block:
+ - debug:
+ msg: "{{ not_found }}"
+ - name: Validate that the variable defaults to an empty list
+ vars:
+ assert:
+ that:
+ - "(not_found | default('default-used', True)) == 'default-used'"
+ vars:
+ not_found: "{{ lookup('community.general.merge_variables', '^.+__merge_not_found$') }}"
+
+ # Test the 'pattern_type' options
+ - name: Test merge list (pattern_type = prefix)
+ block:
+ - name: Print the merged list
+ debug:
+ msg: "{{ merged_list }}"
+
+ - name: Validate that the list is complete
+ assert:
+ that:
+ - "(merged_list | length) == 4"
+ - "'item1' in merged_list"
+ - "'item2' in merged_list"
+ - "'item2' in merged_list"
+ - "'item3' in merged_list"
+ vars:
+ merged_list: "{{ lookup('community.general.merge_variables', 'testlist', pattern_type='prefix') }}"
+
+ - name: Test merge list (pattern_type = suffix)
+ block:
+ - name: Print the merged list
+ debug:
+ msg: "{{ merged_list }}"
+
+ - name: Validate that the list is complete
+ assert:
+ that:
+ - "(merged_list | length) == 2"
+ - "'item1' in merged_list"
+ - "'item3' in merged_list"
+ vars:
+ merged_list: "{{ lookup('community.general.merge_variables', '__merge_list', pattern_type='suffix') }}"
+
+ - name: Test merge list (pattern_type = regex)
+ block:
+ - name: Print the merged list
+ debug:
+ msg: "{{ merged_list }}"
+
+ - name: Validate that the list is complete
+ assert:
+ that:
+ - "(merged_list | length) == 3"
+ - "'item1' in merged_list"
+ - "'item2' in merged_list"
+ - "'item3' in merged_list"
+ vars:
+ merged_list: "{{ lookup('community.general.merge_variables', '^testlist[0-9].*', pattern_type='regex') }}"
+
+ # Test the 'initial_value' option
+ - name: Test merge without results but with initial value
+ block:
+ - name: Print the merged list
+ debug:
+ msg: "{{ not_found_initial_value }}"
+
+ - name: Validate that the variable only contains the initial value
+ vars:
+ assert:
+ that:
+ - "(not_found_initial_value | count) == 1"
+ - "(not_found_initial_value | first) == 'item2'"
+ vars:
+ not_found_initial_value: "{{ lookup('community.general.merge_variables', '^.+__merge_not_found$', initial_value=testlist_initial_value) }}"
+
+ - name: Test merging a list with an initial value
+ block:
+ - name: Print the merged list
+ debug:
+ msg: "{{ merged_list_with_initial_value }}"
+
+ - name: Validate that the list is complete
+ assert:
+ that:
+ - "(merged_list_with_initial_value | length) == 3"
+ - "'item1' in merged_list_with_initial_value"
+ - "'item2' in merged_list_with_initial_value"
+ - "'item3' in merged_list_with_initial_value"
+ vars:
+ merged_list_with_initial_value: "{{ lookup('community.general.merge_variables', '^.+__merge_list$', initial_value=testlist_initial_value) }}"
+
+ # Test the 'override' options
+ - name: Test the 'override=warn' option
+ block:
+ - name: Print the merged list
+ debug:
+ msg: "{{ merged_with_override_warn }}"
+
+ - name: Validate that the dict is complete and the warning is printed
+ assert:
+ that:
+ - "'key_to_override' in merged_with_override_warn"
+ - "merged_with_override_warn.key_to_override == 'Override value'"
+ - "'key_to_override' in lookup('file', logging_output_file)" # Check if a message is given
+ - "'[WARNING]' in lookup('file', logging_output_file)" # and verify that the message is a WARNING
+ vars:
+ merged_with_override_warn: "{{ lookup('community.general.merge_variables', '^.+__override_warn$', initial_value=override_warn_init, override='warn') }}"
+
+ - name: Test the 'override=error' option
+ block:
+ - name: Validate that an override result in an error
+ debug:
+ msg: "{{ lookup('community.general.merge_variables', '^.+__override_error$', initial_value=override_error_init, override='error') }}"
+ ignore_errors: true # Do not stop the playbook
+ register: _override_error_result
+
+ - name: Print the output
+ debug:
+ msg: "{{ _override_error_result }}"
+
+ - name: Validate that the error is reported
+ assert:
+ that:
+ - "_override_error_result.failed"
+ - "'key_to_override' in _override_error_result.msg"
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test_with_env.yml b/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test_with_env.yml
new file mode 100644
index 000000000..7fbb664fd
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/test_with_env.yml
@@ -0,0 +1,44 @@
+---
+# Copyright (c) 2020, Thales Netherlands
+# Copyright (c) 2021, Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Test merge_variables lookup plugin
+ hosts: localhost
+ tasks:
+ - name: Include test data
+ include_vars: vars.yml
+
+ # Test the pattern option using the environment variable
+ - name: Test merge list (pattern_type = regex)
+ block:
+ - name: Print the merged list
+ debug:
+ msg: "{{ merged_list }}"
+
+ - name: Validate that the list is complete
+ assert:
+ that:
+ - "(merged_list | length) == 2"
+ - "'item1' in merged_list"
+ - "'item3' in merged_list"
+ vars:
+ merged_list: "{{ lookup('community.general.merge_variables', '__merge_list') }}"
+
+ # Test whether the pattern option can be overridden
+ - name: Test merge list (pattern_type = suffix)
+ block:
+ - name: Print the merged list
+ debug:
+ msg: "{{ merged_list }}"
+
+ - name: Validate that the list is complete
+ assert:
+ that:
+ - "(merged_list | length) == 3"
+ - "'item1' in merged_list"
+ - "'item2' in merged_list"
+ - "'item3' in merged_list"
+ vars:
+ merged_list: "{{ lookup('community.general.merge_variables', '^testlist[0-9].*', pattern_type='regex') }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/vars.yml b/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/vars.yml
new file mode 100644
index 000000000..d1a4ace21
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_merge_variables/vars.yml
@@ -0,0 +1,34 @@
+---
+# Copyright (c) 2020, Thales Netherlands
+# Copyright (c) 2021, Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+testlist_initial_value: "{{ testlist2 }}"
+testlist1__merge_list:
+ - item1
+testlist2:
+ - item2
+testlist3__merge_list:
+ - item3
+
+testdict1__merge_dict:
+ item1: test
+ list_item:
+ - test1
+testdict2__merge_dict:
+ item2: test
+ list_item:
+ - test2
+
+override_warn_init:
+ key_to_override: Initial value
+override__override_warn:
+ key_to_override: Override value
+
+override_error_init:
+ key_to_override: Initial value
+override__override_error:
+ key_to_override: Override value
+
+logging_output_file: /tmp/ansible-test-merge-variables # The Ansible log output is available in this file
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/aliases b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/aliases
new file mode 100644
index 000000000..0d4c5af3b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/aliases
@@ -0,0 +1,11 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+destructive
+skip/aix
+skip/rhel
+skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
+skip/osx # FIXME https://github.com/ansible-collections/community.general/issues/2978
+skip/macos # FIXME https://github.com/ansible-collections/community.general/issues/2978
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/meta/main.yml
new file mode 100644
index 000000000..2fcd152f9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/tasks/main.yml
new file mode 100644
index 000000000..c0b5eb5bd
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/tasks/main.yml
@@ -0,0 +1,17 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- block:
+ - include_tasks: package.yml
+ - include_tasks: tests.yml
+ when:
+ # The pass package is no longer available in EPEL, so only test on Fedora, OpenSUSE, FreeBSD, macOS, and Ubuntu
+ # https://lists.zx2c4.com/pipermail/password-store/2019-July/003689.html
+ - ansible_facts.distribution in ['FreeBSD', 'MacOSX', 'openSUSE Leap', 'Ubuntu']
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/tasks/package.yml b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/tasks/package.yml
new file mode 100644
index 000000000..e5ccd5677
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/tasks/package.yml
@@ -0,0 +1,84 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Include distribution specific variables
+ include_vars: "{{ lookup('first_found', params) }}"
+ vars:
+ params:
+ files:
+ - "{{ ansible_facts.distribution }}.yml"
+ - "{{ ansible_facts.os_family }}.yml"
+ - default.yml
+ paths:
+ - "{{ role_path }}/vars"
+
+- name: Install package
+ action: "{{ ansible_facts.pkg_mgr }}"
+ args:
+ name: "{{ passwordstore_packages }}"
+ state: present
+ when: ansible_facts.pkg_mgr in ['apt', 'dnf', 'yum', 'pkgng', 'community.general.pkgng']
+
+- block:
+ # OpenSUSE Leap>=15.0 don't include password-store in main repo
+ - name: SUSE | Add security:privacy repo
+ template:
+ src: security-privacy.repo.j2
+ dest: /etc/zypp/repos.d/security:privacy.repo
+
+ - name: SUSE | Install package
+ package:
+ name: password-store
+ state: present
+ update_cache: true
+ disable_gpg_check: true
+ when: ansible_facts.pkg_mgr in ['zypper', 'community.general.zypper']
+
+# See https://github.com/gopasspw/gopass/issues/1849#issuecomment-802789285
+- name: Install gopass on Debian
+ when: ansible_facts.os_family == 'Debian'
+ become: true
+ block:
+ - name: Fetch gopass repo keyring
+ ansible.builtin.get_url:
+ url: https://packages.gopass.pw/repos/gopass/gopass-archive-keyring.gpg
+ dest: /usr/share/keyrings/gopass-archive-keyring.gpg
+ - name: Add gopass repo
+ ansible.builtin.apt_repository:
+ repo: "deb [arch=amd64,arm64,armhf \
+ signed-by=/usr/share/keyrings/gopass-archive-keyring.gpg] \
+ https://packages.gopass.pw/repos/gopass stable main"
+ state: present
+ - name: Update apt-cache and install gopass package
+ ansible.builtin.apt:
+ name: gopass
+ update_cache: true
+
+- name: Install on macOS
+ when: ansible_facts.distribution == 'MacOSX'
+ block:
+ - name: MACOS | Find brew binary
+ command: which brew
+ register: brew_which
+
+ - name: MACOS | Get owner of brew binary
+ stat:
+ path: "{{ brew_which.stdout }}"
+ register: brew_stat
+
+ - name: MACOS | Install package
+ homebrew:
+ name:
+ - gnupg2
+ - pass
+ - gopass
+ state: present
+ update_homebrew: false
+ become: true
+ become_user: "{{ brew_stat.stat.pw_name }}"
+ # Newer versions of brew want to compile a package which takes a long time. Do not upgrade homebrew until a
+ # proper solution can be found
+ environment:
+ HOMEBREW_NO_AUTO_UPDATE: "True"
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/tasks/password_tests.yml b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/tasks/password_tests.yml
new file mode 100644
index 000000000..a94529e46
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/tasks/password_tests.yml
@@ -0,0 +1,130 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Create a password ({{ backend }})
+ set_fact:
+ newpass: "{{ lookup('community.general.passwordstore', 'test-pass', length=8, create=true, backend=backend) }}"
+
+ - name: Fetch password from an existing file ({{ backend }})
+ set_fact:
+ readpass: "{{ lookup('community.general.passwordstore', 'test-pass', backend=backend) }}"
+
+ - name: Verify password ({{ backend }})
+ assert:
+ that:
+ - readpass == newpass
+
+ - name: Create a password with equal sign ({{ backend }})
+ set_fact:
+ newpass: "{{ lookup('community.general.passwordstore', 'test-pass-equal userpass=SimpleSample= create=true', backend=backend) }}"
+
+ - name: Fetch a password with equal sign ({{ backend }})
+ set_fact:
+ readpass: "{{ lookup('community.general.passwordstore', 'test-pass-equal', backend=backend) }}"
+
+ - name: Verify password ({{ backend }})
+ assert:
+ that:
+ - readpass == newpass
+
+ - name: Create a password using missing=create ({{ backend }})
+ set_fact:
+ newpass: "{{ lookup('community.general.passwordstore', 'test-missing-create', missing='create', length=8, backend=backend) }}"
+
+ - name: Fetch password from an existing file ({{ backend }})
+ set_fact:
+ readpass: "{{ lookup('community.general.passwordstore', 'test-missing-create', backend=backend) }}"
+
+ - name: Verify password ({{ backend }})
+ assert:
+ that:
+ - readpass == newpass
+
+ - name: Fetch password from existing file using missing=empty ({{ backend }})
+ set_fact:
+ readpass: "{{ lookup('community.general.passwordstore', 'test-missing-create', missing='empty', backend=backend) }}"
+
+ - name: Verify password ({{ backend }})
+ assert:
+ that:
+ - readpass == newpass
+
+ - name: Fetch password from non-existing file using missing=empty ({{ backend }})
+ set_fact:
+ readpass: "{{ query('community.general.passwordstore', 'test-missing-pass', missing='empty', backend=backend) }}"
+
+ - name: Verify password ({{ backend }})
+ assert:
+ that:
+ - readpass == [ none ]
+
+ - name: Create the YAML password ({{ backend }})
+ command: "{{ backend }} insert -m -f test-yaml-pass"
+ args:
+ stdin: |
+ testpassword
+ key: |
+ multi
+ line
+
+ - name: Fetch a password with YAML subkey ({{ backend }})
+ set_fact:
+ readyamlpass: "{{ lookup('community.general.passwordstore', 'test-yaml-pass', subkey='key', backend=backend) }}"
+
+ - name: Read a yaml subkey ({{ backend }})
+ assert:
+ that:
+ - readyamlpass == 'multi\nline\n'
+
+ - name: Create a non-YAML multiline file ({{ backend }})
+ command: "{{ backend }} insert -m -f test-multiline-pass"
+ args:
+ stdin: |
+ testpassword
+ random additional line
+
+ - name: Fetch password from multiline file ({{ backend }})
+ set_fact:
+ readyamlpass: "{{ lookup('community.general.passwordstore', 'test-multiline-pass', backend=backend) }}"
+
+ - name: Multiline pass only returns first line ({{ backend }})
+ assert:
+ that:
+ - readyamlpass == 'testpassword'
+
+ - name: Fetch all from multiline file ({{ backend }})
+ set_fact:
+ readyamlpass: "{{ lookup('community.general.passwordstore', 'test-multiline-pass', returnall='yes', backend=backend) }}"
+
+ - name: Multiline pass returnall returns everything in the file ({{ backend }})
+ assert:
+ that:
+ - readyamlpass == 'testpassword\nrandom additional line\n'
+
+ - name: Create a password in a folder ({{ backend }})
+ set_fact:
+ newpass: "{{ lookup('community.general.passwordstore', 'folder/test-pass', length=8, create=true, backend=backend) }}"
+
+ - name: Fetch password from folder ({{ backend }})
+ set_fact:
+ readpass: "{{ lookup('community.general.passwordstore', 'folder/test-pass', backend=backend) }}"
+
+ - name: Verify password from folder ({{ backend }})
+ assert:
+ that:
+ - readpass == newpass
+
+ - name: Try to read folder as passname ({{ backend }})
+ set_fact:
+ newpass: "{{ lookup('community.general.passwordstore', 'folder', backend=backend) }}"
+ ignore_errors: true
+ register: eval_error
+
+ - name: Make sure reading folder as passname failed ({{ backend }})
+ assert:
+ that:
+ - eval_error is failed
+ - '"passname folder not found" in eval_error.msg'
+ when: backend != "gopass" # Remove this line once gopass backend can handle this
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/tasks/tests.yml b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/tasks/tests.yml
new file mode 100644
index 000000000..65a578c96
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/tasks/tests.yml
@@ -0,0 +1,239 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Check name of gpg2 binary
+ command: which gpg2
+ register: gpg2_check
+ ignore_errors: true
+
+- name: Set gpg2 binary name
+ set_fact:
+ gpg2_bin: '{{ "gpg2" if gpg2_check is successful else "gpg" }}'
+
+- name: Stop gpg-agent so we can remove any locks on the GnuPG dir
+ command: gpgconf --kill gpg-agent
+ ignore_errors: true
+
+- name: Remove previous password files and directory
+ file:
+ dest: "{{ item }}"
+ state: absent
+ loop:
+ - "~/.gnupg"
+ - "~/.password-store"
+
+- name: Get path of pass executable
+ command: which pass
+ register: result
+
+- name: Store path of pass executable
+ set_fact:
+ passpath: "{{ result.stdout }}"
+
+- name: Move original pass into place if there was a leftover
+ command:
+ argv:
+ - mv
+ - "{{ passpath }}.testorig"
+ - "{{ passpath }}"
+ args:
+ removes: "{{ passpath }}.testorig"
+
+# having gopass is not required for this test, but we store
+# its path in case it is installed, so we can restore it
+- name: Try to find gopass in path
+ command: which gopass
+ register: result
+
+- name: Store path of gopass executable
+ set_fact:
+ gopasspath: "{{ result.stdout }}"
+
+- name: Move original gopass into place if there was a leftover
+ command:
+ argv:
+ - mv
+ - "{{ gopasspath }}.testorig"
+ - "{{ gopasspath }}"
+ args:
+ removes: "{{ gopasspath }}.testorig"
+
+- name: Get versions of tools
+ command: "{{ item }} --version"
+ register: versions
+ loop:
+ - "{{ gpg2_bin }}"
+ - pass
+ - gopass
+
+- name: Output versions of tools
+ debug:
+ msg: "{{ versions.results | map(attribute='stdout_lines') }}"
+
+# How to generate a new GPG key:
+# gpg2 --batch --gen-key input # See templates/input
+# gpg2 --list-secret-keys --keyid-format LONG
+# gpg2 --armor --export-secret-keys [key id]
+# # Get the fingerprint
+# gpg2 --fingerprint --keyid-format LONG | grep [key id] -A 1 | tail -1 | tr -d '[:space:]' | awk -F '=' '{print $2":6:"}'
+
+- name: Import GPG private key
+ shell: echo "{{ passwordstore_privkey }}" | {{ gpg2_bin }} --import --allow-secret-key-import -
+
+- name: Trust key
+ shell: echo "D3E1CC8934E97270CEB066023AF1BD3619AB496A:6:" | {{ gpg2_bin }} --import-ownertrust
+
+- name: Initialise pass passwordstore
+ command: pass init ansible-test
+
+- name: Initialise gopass passwordstore
+ command: gopass init --path $HOME/.gopass-store ansible-test
+ args:
+ creates: "{{ lookup('env','HOME') }}/.gopass-store"
+
+# these tests should apply to all backends
+- name: Password tests
+ include_tasks: password_tests.yml
+ loop:
+ - pass
+ - gopass
+ loop_control:
+ loop_var: backend
+
+- name: Change passwordstore location explicitly
+ set_fact:
+ passwordstore: "{{ lookup('env','HOME') }}/.password-store"
+
+- name: Make sure password store still works with explicit location set
+ set_fact:
+ newpass: "{{ lookup('community.general.passwordstore', 'test-pass') }}"
+
+- name: Change passwordstore location to a non-existent place
+ set_fact:
+ passwordstore: "somenonexistentplace"
+
+- name: Try reading from non-existent passwordstore location
+ set_fact:
+ newpass: "{{ lookup('community.general.passwordstore', 'test-pass') }}"
+ ignore_errors: true
+ register: eval_error
+
+- name: Make sure reading from non-existent passwordstore location failed
+ assert:
+ that:
+ - eval_error is failed
+ - >-
+ "Passwordstore directory '" in eval_error.msg
+ - >-
+ "/somenonexistentplace' does not exist" in eval_error.msg
+
+- name: Test pass compatibility shim detection
+ block:
+ - name: Move original pass out of the way
+ command:
+ argv:
+ - mv
+ - "{{ passpath }}"
+ - "{{ passpath }}.testorig"
+ args:
+ creates: "{{ passpath }}.testorig"
+
+ - name: Create dummy pass script
+ ansible.builtin.copy:
+ content: |
+ #!/bin/sh
+ echo "shim_ok"
+ dest: "{{ passpath }}"
+ mode: '0755'
+
+ - name: Try reading from non-existent passwordstore location with different pass utility
+ set_fact:
+ newpass: "{{ lookup('community.general.passwordstore', 'test-pass') }}"
+ environment:
+ PATH: "/tmp"
+
+ - name: Verify password received from shim
+ assert:
+ that:
+ - newpass == "shim_ok"
+
+ - name: Try to read folder as passname with a different pass utility
+ set_fact:
+ newpass: "{{ lookup('community.general.passwordstore', 'folder') }}"
+
+ - name: Verify password received from shim
+ assert:
+ that:
+ - newpass == "shim_ok"
+
+ always:
+ - name: Move original pass back into place
+ command:
+ argv:
+ - mv
+ - "{{ passpath }}.testorig"
+ - "{{ passpath }}"
+ args:
+ removes: "{{ passpath }}.testorig"
+
+# This are in addition to the real gopass tests above
+# and verify plugin logic
+- name: gopass plugin logic tests
+ vars:
+ passwordstore_backend: "gopass"
+ block:
+ - name: Check if gopass executable exists
+ stat:
+ path: "{{ gopasspath }}"
+ register: gopass_check
+
+ - name: Move original gopass out of the way
+ command:
+ argv:
+ - mv
+ - "{{ gopasspath }}"
+ - "{{ gopasspath }}.testorig"
+ args:
+ creates: "{{ gopasspath }}.testorig"
+ when: gopass_check.stat.exists == true
+
+ - name: Create mocked gopass script
+ ansible.builtin.copy:
+ content: |
+ #!/bin/sh
+ if [ "$GOPASS_NO_REMINDER" != "YES" ]; then
+ exit 1
+ fi
+ if [ "$1" = "--version" ]; then
+ exit 2
+ fi
+ echo "gopass_ok"
+ dest: "{{ gopasspath }}"
+ mode: '0755'
+
+ - name: Try to read folder as passname using gopass mock
+ set_fact:
+ newpass: "{{ lookup('community.general.passwordstore', 'folder') }}"
+
+ - name: Verify password received from gopass mock
+ assert:
+ that:
+ - newpass == "gopass_ok"
+
+ always:
+ - name: Remove mocked gopass
+ ansible.builtin.file:
+ path: "{{ gopasspath }}"
+ state: absent
+
+ - name: Move original gopass back into place
+ command:
+ argv:
+ - mv
+ - "{{ gopasspath }}.testorig"
+ - "{{ gopasspath }}"
+ args:
+ removes: "{{ gopasspath }}.testorig"
+ when: gopass_check.stat.exists == true
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/templates/input b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/templates/input
new file mode 100644
index 000000000..d639accdb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/templates/input
@@ -0,0 +1,9 @@
+%echo Generating a Ansible Test PGP key
+Key-Type: RSA
+Key-Length: 4096
+Subkey-Type: RSA
+Subkey-Length: 4096
+Name-Real: ansible-test
+Expire-Date: 0
+%commit
+%echo done
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/templates/input.license b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/templates/input.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/templates/input.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/templates/security-privacy.repo.j2 b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/templates/security-privacy.repo.j2
new file mode 100644
index 000000000..72eca99ec
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/templates/security-privacy.repo.j2
@@ -0,0 +1,13 @@
+{#
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+#}
+
+[security_privacy]
+name=Crypto applications and utilities (openSUSE_Leap_{{ ansible_distribution_version }})
+type=rpm-md
+baseurl=http://download.opensuse.org/repositories/security:/privacy/openSUSE_Leap_{{ ansible_distribution_version }}/
+gpgcheck=1
+gpgkey=http://download.opensuse.org/repositories/security:/privacy/openSUSE_Leap_{{ ansible_distribution_version }}/repodata/repomd.xml.key
+enabled=1
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/Alpine.yml b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/Alpine.yml
new file mode 100644
index 000000000..f18329ed1
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/Alpine.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+passwordstore_packages:
+ - gopass
+ - pass
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/Archlinux.yml b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/Archlinux.yml
new file mode 100644
index 000000000..f18329ed1
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/Archlinux.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+passwordstore_packages:
+ - gopass
+ - pass
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/Debian.yml b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/Debian.yml
new file mode 100644
index 000000000..825a6a8bb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/Debian.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+passwordstore_packages:
+ - pass
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/Fedora.yml b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/Fedora.yml
new file mode 100644
index 000000000..f18329ed1
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/Fedora.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+passwordstore_packages:
+ - gopass
+ - pass
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/FreeBSD.yml b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/FreeBSD.yml
new file mode 100644
index 000000000..9e9da2772
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/FreeBSD.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+passwordstore_packages:
+ - gopass
+ - gnupg
+ - password-store
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/default.yml b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/default.yml
new file mode 100644
index 000000000..f55df21f8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/default.yml
@@ -0,0 +1,4 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/main.yml
new file mode 100644
index 000000000..2b4fa1b22
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_passwordstore/vars/main.yml
@@ -0,0 +1,122 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+passwordstore_privkey: |
+ -----BEGIN PGP PRIVATE KEY BLOCK-----
+ Version: GnuPG v2.0.22 (GNU/Linux)
+
+ lQcYBF0L9gUBEACrYsKIj/rXFQPURHz+YKg54BW6utIvwoF/CbQarc8iXoXfPZW4
+ wQnFaX+dLifkvX5f4xIUVD94qyMXT2oNg+HZXH2y7VwqBFeG9TrNqfgJsYTbTlgP
+ 0MOD3FtZkMy/6TrJyOzY7x7oHUwWY1S5YeBDBsRqWwhS5fIfHLGbZLwoHC/53mlP
+ ve0zL1u28y3Kh8JvYBSlcYrbMlbKQb1g0TSb8gVwq+Iv2CriEmHipUvLI02z02Ny
+ XnT0+rzOEEynaoF7zX1S0eoIwKz46/sen1L5YAYhLM16gq4WSquxUz8klff+jVD5
+ uLgUKzEkhBdBuTvWKjknk6Wu2aDPC6IQXUjm+5dIh+/IyD4SKPA+HY1QZjIF/6nH
+ KV43RRzB8YWkAEW/iQdKCXWyNz1o8zYiun/PxiJtgV2qpz4z5M+ANx1VCj31eMTE
+ A0exSnMLjbUknE3JX2bnBfTgbiKbeXQcL6FNrKIPJrwgNlP3g48JzY6aPT3Tej8Q
+ pd6DqamU0sQfoi2K8zs/Ltl+REocKqzQ9cz0dj7ykQqAMf+TunQfC3pY8yI7IKCr
+ YM2L3aJbiqLTp31dCfwxBSZJ+oalUzp2l91ugu1k1mjuik7ZJaflfBNEFWK9ig3v
+ qhv8FwdoPFNh8TC11btfU1wphcBl65pCaPff2s94/Gj2aQ0PrFYuhPtzqwARAQAB
+ AA//UMXH1yK8XrfJyTXKDv0w663fr9SykM3DyEKjfltiHtmbkF3u/VcFKuQQv9xr
+ 8tMYB0r2T1xxWYaWkDreSaZZP97mYviZEjhfo/xZjWpIuxDOA6nFuRZzvuaQqwKi
+ bOQXz9gBQDBaSZzdKkQAPyqQziYXVeS3ZJJ47Q7R6eGtB95ZAhM/YNSrQQ9V00CC
+ 2UvoaCNJN7vubGYqH0KiZUnT2JdU1wg7Hr9rXoa5WV77/K4Txeefm9xGlNrDNv7Z
+ kaGRiu6K3QiPmzZrjxlwjbsbGOqXmPULlmyWbW0dxAHu5WhEq9SgUEEtiFve2k3i
+ xBfvyny12SAt2t04e7wI0luUqnpQR8j3JPFXcCiFszIauMbXhIAd0QhRfS6/pRCf
+ iBRliFqvQpgmz9w8/enfQtBvyAwZLr3p2vk4OyRW/GLFnfkoKcCvgZtL5vNDPYJm
+ Y1koC+jAsiiFRmUvP9SLyNabVTANz5Hg/jZmcdh+OTWs1xdZl1JyjUOxV6n1n1pW
+ BPc0FaNvFS+wkx6Rp9DgryTP1oTD6wjacNljFh3A9LJ0DTnQgsghoi5ArBKnRP7R
+ 9i0DKUqywoukm+GQHoZlB6bglDBVc3wKZvtw17/SgD6GnKZ3zH+Y8yx3K3MI9wjT
+ Od1jMxQxzKWMxrv72mtzchm/utkubL5BpM5hn6fg32NEkxEIAMhc2f01fuv/UZ1i
+ zlkqXkcMzrd/+9+Mv53meLMJsW2biOwRF52ZXi3k9ulUwHB21FaAXeyOFhueKrh/
+ iKu5Hpydxruj0XCgMRArgvghPL4KLfhh54xvXGKxWw7B0IWkOnvELPikOl3h17cY
+ lQ5rN5mQtlxaqqrJKOxkseEFTvVJudZXZH9oArlVXO88HklDeEHtV4xjdiyvtFKg
+ qWUvo6oNT0LmpFdgstoKJ8H5gKiV3wfl2QJQxqWT40wUFVnNEAoBYC7PbHWajxmD
+ 7ZGoKE9o3ythg11D4rH23uTUFLd5Hc5xeQ2/+OhEKv4Qe0X+okv8/RpM94ObfsW9
+ HdQBsgMIANr6B/SzwhPn8eK0c6wrOYU/B/V370qgTBRpWgrNRCvtN8NuSJKOJRU/
+ qYm74dCsVxBfvUlEPRp9DEsE9djvwZLdIqOfn4amDoLZmYdMQ5LQCOaHlrnEx+ng
+ uHUklFUXIHDNcVRWzhrHm4KQWeB7RrCRL1nEimW/nhh8y++4TmxZQ1Zr2fdUWdMs
+ dSWryw3RE5nwDd7nW8+Wgm3TfS4jhhn3DcKFZxLzG1eo4ZaXoPa4j7zps3xFyBtF
+ KMPgrvAAxzqFwklQKjwXcthYUQ5OzXTt94m8VqOz0nZGoizaGBFRz1l1q9QQxTv4
+ BUI+2OeyfrzWIaKEu+9gsNbx/OfxmzkH/2quLKJj0FQ+aEYkeGXVtf2DsceQXB1l
+ QtBo/qvBWP2XYk6GzAfwjvI8ifEG4MzXCZxm5SKtQ8UljrCo2T6OArG2FK1FSJDX
+ UlQBXPLYWIJCkC9X8SB6UztPSXPoNS6Ktc0K5XFxvGzIDpxAE+zE4UAe3gWGaROe
+ bwxbuRb9/aHAEk6CU3mrgEUUqet+4qUNRpAzJdwYIN6nOAVghHWiVY4OoCSCgMYY
+ 4B9Aa9bVeDQH9S88X5ux3bDW1DPjiewNIYo+0z53gfY3HZeDfHFWD4iM6vaJjSVb
+ 65trGHyGhElkWub56Q3nHXPOxiAKeRBn3iL54wDNiGMlfw/tkoAkTuaNI7QMYW5z
+ aWJsZS10ZXN0iQI5BBMBAgAjBQJdC/YFAhsvBwsJCAcDAgEGFQgCCQoLBBYCAwEC
+ HgECF4AACgkQOvG9NhmrSWo7YhAAhsp+j13R3bJkv/esJwaDa0dbdm1iJzKB9bkf
+ Bi10qMFmJUEDyHHKL9OBiAgSCKna5F4EuEFnaV9YPs1n6PVE+FX3m5UAfCULR6Qk
+ G064+nd25LWEjSJ3I85WHfJNz/fPr3fQvQNH67GEdTZIr7hrWeZHH1nnpGrZ6xx6
+ sVBxKMp3g8wNXey/DJSaDcry5cQ8cZW2RrUzmfXgcSlwAIVBkmHKA1UtgAGu1kq/
+ LzaCJus7ffMdUZd7IYAM5fIdnNEf0fi8/oKcWiv9TqynGJmu2AxjSUu9EG9idESu
+ bZtXZntM2ODbqepfQ0i44ew9Y3HQS8ciP8uhbQYFZuhbMQobXNIkvO6XA1cePSt2
+ Wh4qCh+ymk9u2qBqb4JkqORyOCJhLdOj6TGU0o9TQ8h0EqjB/Wx69ppA0GFQh5si
+ CG7GnwZhabgiPIxoCPQuhDPv+rXgFx5YiGofMddst9DFn0nR/fFx9hqaTuZ4iiuH
+ UzvqQAMGtIMxiOdJKSSI9emsNfQvXTMHjB+s6Cjiw7nF0+G2ciXlLTPbtTFePZVN
+ seDosuN6uMqwm8KNZVJpU0O0qXu5EdI7ptbOooSR7WZSJdQ+MWyr0vGYKKFGYkwp
+ jl/pDzXCA1d3AxK4Mzmb+KvFQvh+9X7VwI9Pgg4HHE5KeyX8wXhrvT2itPoznnC2
+ 33tCCZmdBxcEXQv2BQEQANtkIv93lunfgRUt7X4hJXT8rw/Y787b+xQ/FcApQnfd
+ 5Zg6pubrMPbOoIKFJG4vzNBSmXGSBmqGIdIYqT2eR9eBDoOv5Cl8tCQ+zNoC2V0Q
+ uCOLZV86hoakduHniCv8cKSbsG6mm5oFP61/82yJLlPUarT+EGSuWCR6W1pGC5WR
+ GElnE9VFpaQ5TZ8A3EBWky2YhdX7vOzbjP8x0Jd/3UFfpNd5gRnxfJLx8rrdKt20
+ xYxR4FPUbu9kQFZIyUr2kxNi30R1+oK4hcXbID6gqxt1oW5PWGkNOXYTY6r/Vv6D
+ zU4Bf4gngWc7hgwbtGRkv2jR8Zv3ZIUbo4ZwMAMMs3Un7RWjjEJkrtUzdaIdjtwM
+ jZIH7xMNz/NK748EB3uMKiIOkmWqHrWkU2aa86V8heuTg/AWluKFG6J+WHzzYnPE
+ pb+WbWbZi2PcIQlDY2EDQyluXN0YKdHeFRXdo5QllN+oZ54e0EVioYzpUlzyD4/m
+ sqfGS/ZF//r7EoTeIbrqBJDbEc9pjB3cphpWWHLxxbo42u27w+Gvda6B+1ad2bZX
+ lBp8tnQl2y5JtMPWW7kVZs5EBPS8OY5NRWqVAFPBg1OlnC6OYC2c1rW7tqZll0T0
+ UORR+zdhayYDtLZhJdD5QcSVLRe26jlyeT4920dOUvjI8ANiRSjSOx3wwcnnhtLt
+ ABEBAAEAD/jW435kO/7VlNYaqKG2qUDHFbljDFnXhCCp9CCZ19ADGJWKRei0xilv
+ lXQiY8cLJka2xjEFzMH8FOWLpBwg/qffrclJsz8IY90Oo3SDFcdSIM48Ao2IeQrL
+ Vswa+W2np9utX9GwkABZHEsC5hDIfpWiBq1+Glx0QVCUakSQZ4txNG1VeGE0xMM5
+ 1+bvlygk3KfMQVjV/31Ngr7YNzLZMaTGI6iSZbDOeHpMdDAMWBVkk2vrxUa01Z7T
+ XJ6n5SNFCb+FfZKyu9xjrdlZswgiT71JaC52ncE7JHjj7pnxI6lSIkc14MHJ2ugk
+ 9WiW84v9ybCyOvEsk2Uh+7BwPfLJCee7SIWcVses55mVUm0YNoU68isQfuuuF2+B
+ OwTaoFT5sDwGlE7exdgk7DyUYxIIB3aRTUfNYeAIVW2uR5GruOgTLUw54KPa1N7O
+ NAfiC4OAfc+s6KBTU/Reozdq6mewLEM0UBccEmBtWevet64p5TWleyaL1TtEPZlX
+ DnrkTXA/ZRTCteuSLwmMDpcFEYc3IcgZIQfvqtHO2cDJ67AjlsgvEDwTV65l1MnN
+ krYIgUh8yFMnFGZPO1jw3mRtuU0QottdPj14Xcn855GS2C4CZ31N3YJq7eR+j5Bh
+ SmXk6k5ys8eF/gw4rbEaBbXFTjw8eb1q7Nwus0W+0yrq4r9/J1fxCADkCFXD95jm
+ sddOHz0Dih6c3KEvpkiPLzITOSp5/nPyd3K7T3xx0L2sBQQt2QGT0zeJCwAB5uTE
+ uTb6AjKcvOn7KlPQQqP9O2mgHo7Zzwr/I69DkYLuLGNCsr0XGi5sn9aaDG0dpFqg
+ 2VzItHVTCefoVF5EOmOaDwB1QYunKwXy3vtgNBJ7LwJb4rm1TgNHsheT/rtUsVYP
+ Z7lAxcLGa2xNm215nf8fzmbjZnCfPEyRpMgqlN+YUzGiDJwfN/fwr8OgFnjDSqOL
+ htbqCiLv7vTbsw6TWIuKr21QVEc3Qcqu96v0dNXk6wr4PTnPmezswSK0+Dc2+5JZ
+ PBkYIkbE5eYxCAD2THuc0iiqX4ZFS8KhbjWvmng08xulj45BpHCkY8oRcaMCRD0c
+ AoEDZyPEfwfb8SMNb2NHzvYi8djM0uU5NzqURKUF22bAAbxkgPyBKp8CBECD0X50
+ O4HpJIYShbfUD/XWKLvxGxKYlrOvwHuUboPPnMqsaMLwezu0MoaUztbTlr/OZgA0
+ 8/hwiyXDcsrf7yg5BPfAZghC1OYEvhEiS43VefAPVv/bvwz3Aml0kQLH14eZxGxL
+ z7mb0qoZJ0Qkn36QQ2L9GcWYRfBDgUXcxfZm6JW+UZWuWMBAPMSaPoRd9yt+MMPC
+ QsmyUrBxT9vTLFysUIJYQThycucvO9Xud/19CADt0G5p1u8uRzKi5Qnbtd79V0v5
+ Obud6LRooXJNprYVLhPE6lr0aeeZK6QDIrmRrZqeByQ2kfY6XP6Tl4/9wZX2ajS/
+ 8GJGmv7HP6vqfJdrOQhnAjQkUYYm72C/eicAsm8e/fiOSrpf1ithyPKOArFqVyth
+ pVkAnteqNDABBNellUbqS//XUKnk/Cd2WWaGe4J/nIuj78MphBEzSO4CmWkdbH5G
+ CPyXdq6LEnDp1By3LNmZTwqbeMUtzVcaJVh6k4jW3OEL9h0PIWQ8Ol42+0Wn57Pn
+ 5vPzGwKaf7zFhJlLRCiCdJJl4QOjXo0jvQHBvelQ8NVpeCCAabWmR9OwldqOhJiJ
+ BD4EGAECAAkFAl0L9gUCGy4CKQkQOvG9NhmrSWrBXSAEGQECAAYFAl0L9gUACgkQ
+ kjr8nlUnTh1fBBAAqFbBzvU44nvoxYtBz0b3ZJ8TBCu8rCAwXEquvb+sXWYj52jh
+ ThW+ke24rX178JZDPu6f8EZwF98voZCDxU5XTexqMugTubVSMmTGbJ63YN99Nl5P
+ jjdwO4r1LaBJ7ef30YLT0ZIUI73dDTolQ0ENHxwtD1xnwx8JvXpmQdDJ9/HINQlU
+ HRSt2qWHRSgrutRLFlO7trWQZXIrUwjY3qgKJMPYc2tJqmfsoD6EeISyZOVOJ7m5
+ xgs1f7UgtbVrHYhQOxRiMIAbMDbukRKwlvp1af8R7e+EoFMIcewaObe6/PUTuOFL
+ 0VkCWoHBBKWAJQJ7vHmzW1tgyrDjchHSUAGMqZOEL84uOCWqMQ/6HCj/zaEqiOqg
+ fuoh54K05lKE5OOIBWITVGgqsT9tli29Lov9vJb2p4csN4kSrdKJpLCgP21V8Utk
+ ZWR1OgDhD7h40Eobpph4KauYoAZiAfu3cb4BzNhUAJ69fJ5lrOlKP1GLmYyQ5jfx
+ s73TDCNfj42OBeUCO6tncTSPXs/9P2FziynVLxkCT8cbVq1C4H87BO7TEW9FuxKJ
+ hLfpVGbt/yG1HrvGJ/kRPk0sXu2md9quWkh6qPHF5EThCOrlfbwLD5Pqvt0ZPZlR
+ xxMSRP9L9w09ZYO1Y7f6gegElTpEh/aFLq1jjUxm8h/cO6A9lJ3Bjxb/xmoKoBAA
+ ieGiHu3YgsN0jmxvlnf7GwB89BNajyH6D0tbdsH+OeSU8e6xItxpe6s5GfonWAt+
+ ngPutPSPhgS5AUx8GrxHGu3Sx+wmGvGKpsH+2Tu1ciUN34K/sfrzKjxCuvnpcBTd
+ rOSiEObnKnb6OI6sW329ZH4z/r5tVoetWr45xspc9IE8TVIuavOlJkuInX5/B3Sa
+ DPwAH/aQAYc71j7yDr7ezFzx07h+pH4ePeGsnfdKy6ZWoQ1mmM35j93ZhH8P8YCC
+ N8lklRhxvZhXkHWt4ns/QzT+QawW2sR8Kkha3ydzx9cEcalmNq7nG+QkwSlliazE
+ 6peVL6ga2H1+XM+1p/P/qCsvbLmRobWSyfMURKkL05iykNjnHOYno+A+NaM3IR12
+ uf5tWvNfiJpNXbUf8Yjh0ep73aZfF1kODIcLR1AHtVVt0Yc05XKEwFfv4kADi1Mh
+ Pp0s4MHRMjPCgPU1j2b5ulGZGZKlCECu3799bw8yb7n9Hpj42hL0ZOEsMdMHbCfd
+ 7eQUNNncVW/KDnwrJQAabr/771xSTauWDDdpEJEc2Mdx3m6e7doQvboYaKYvK4kg
+ x/Vi7pcHS1xQO0zC8BPPBq9tMyy5QGSybfVSvMPo+7nIsumZ9fvJwjjRHreZP4pa
+ nbE9Gt4CrEbWoo6jbcscycpQbduEhGtvwj8UFXe5z+M=
+ =o0Ig
+ -----END PGP PRIVATE KEY BLOCK-----
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_random_pet/aliases b/ansible_collections/community/general/tests/integration/targets/lookup_random_pet/aliases
new file mode 100644
index 000000000..0ac9bad98
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_random_pet/aliases
@@ -0,0 +1,7 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+skip/aix
+skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_random_pet/dependencies.yml b/ansible_collections/community/general/tests/integration/targets/lookup_random_pet/dependencies.yml
new file mode 100644
index 000000000..464b5c428
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_random_pet/dependencies.yml
@@ -0,0 +1,10 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- hosts: localhost
+ tasks:
+ - name: Install Petname Python package
+ pip:
+ name: petname
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_random_pet/runme.sh b/ansible_collections/community/general/tests/integration/targets/lookup_random_pet/runme.sh
new file mode 100755
index 000000000..71faa439d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_random_pet/runme.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+# Copyright (c) Ansible project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+set -eux
+
+ANSIBLE_ROLES_PATH=../ \
+ ansible-playbook dependencies.yml -v "$@"
+
+ANSIBLE_ROLES_PATH=../ \
+ ansible-playbook test.yml -v "$@"
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_random_pet/test.yml b/ansible_collections/community/general/tests/integration/targets/lookup_random_pet/test.yml
new file mode 100644
index 000000000..c61461867
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_random_pet/test.yml
@@ -0,0 +1,30 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- hosts: localhost
+ gather_facts: false
+ tasks:
+ - name: Call plugin
+ set_fact:
+ result1: "{{ query('community.general.random_pet', words=3) }}"
+ result2: "{{ query('community.general.random_pet', length=3) }}"
+ result3: "{{ query('community.general.random_pet', prefix='kubernetes') }}"
+ result4: "{{ query('community.general.random_pet', separator='_') }}"
+ result5: "{{ query('community.general.random_pet', words=2, length=6, prefix='kubernetes', separator='_') }}"
+
+ - name: Check results
+ assert:
+ that:
+ - result1 | length == 1
+ - result1[0].split('-') | length == 3
+ - result2 | length == 1
+ - result2[0].split('-')[0] | length <= 3
+ - result3 | length == 1
+ - result3[0].split('-')[0] == 'kubernetes'
+ - result4 | length == 1
+ - result4[0].split('_') | length == 2
+ - result5 | length == 1
+ - result5[0].split('_') | length == 3
+ - result5[0].split('_')[0] == 'kubernetes'
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_random_string/aliases b/ansible_collections/community/general/tests/integration/targets/lookup_random_string/aliases
new file mode 100644
index 000000000..0ac9bad98
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_random_string/aliases
@@ -0,0 +1,7 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+skip/aix
+skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_random_string/runme.sh b/ansible_collections/community/general/tests/integration/targets/lookup_random_string/runme.sh
new file mode 100755
index 000000000..35c79500c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_random_string/runme.sh
@@ -0,0 +1,8 @@
+#!/usr/bin/env bash
+# Copyright (c) Ansible project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+set -eux
+
+ANSIBLE_ROLES_PATH=../ \
+ ansible-playbook test.yml -v "$@"
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_random_string/test.yml b/ansible_collections/community/general/tests/integration/targets/lookup_random_string/test.yml
new file mode 100644
index 000000000..b1f623410
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_random_string/test.yml
@@ -0,0 +1,53 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- hosts: localhost
+ gather_facts: false
+ tasks:
+ - name: Call plugin
+ set_fact:
+ result1: "{{ query('community.general.random_string') }}"
+ result2: "{{ query('community.general.random_string', length=0) }}"
+ result3: "{{ query('community.general.random_string', length=10) }}"
+ result4: "{{ query('community.general.random_string', length=-1) }}"
+ result5: "{{ query('community.general.random_string', override_special='_', min_special=1) }}"
+ result6: "{{ query('community.general.random_string', upper=false, special=false) }}" # lower case only
+ result7: "{{ query('community.general.random_string', lower=false, special=false) }}" # upper case only
+ result8: "{{ query('community.general.random_string', lower=false, upper=false, special=false) }}" # number only
+ result9: "{{ query('community.general.random_string', lower=false, upper=false, special=false, min_numeric=1, length=1) }}" # single digit only
+ result10: "{{ query('community.general.random_string', numbers=false, upper=false, special=false, min_lower=1, length=1) }}" # single lowercase character only
+ result11: "{{ query('community.general.random_string', base64=true, length=8) }}"
+ result12: "{{ query('community.general.random_string', upper=false, numbers=false, special=false) }}" # all lower case
+ result13: "{{ query('community.general.random_string', override_all='0', length=2) }}"
+
+ - name: Raise error when impossible constraints are provided
+ set_fact:
+ impossible: "{{ query('community.general.random_string', upper=false, lower=false, special=false, numbers=false) }}"
+ ignore_errors: true
+ register: impossible_result
+
+ - name: Check results
+ assert:
+ that:
+ - result1[0] | length == 8
+ - result2[0] | length == 0
+ - result3[0] | length == 10
+ - result4[0] | length == 0
+ - result5[0] | length == 8
+ - "'_' in result5[0]"
+ - result6[0] is lower
+ - result7[0] is upper
+ - result8[0] | regex_replace('^(\d+)$', '') == ''
+ - result9[0] | regex_replace('^(\d+)$', '') == ''
+ - result9[0] | length == 1
+ - result10[0] | length == 1
+ - result10[0] is lower
+ # if input string is not multiple of 3, base64 encoded string will be padded with =
+ - result11[0].endswith('=')
+ - result12[0] is lower
+ - result13[0] | length == 2
+ - result13[0] == '00'
+ - impossible_result is failed
+ - "'Available characters cannot' in impossible_result.msg"
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_random_words/aliases b/ansible_collections/community/general/tests/integration/targets/lookup_random_words/aliases
new file mode 100644
index 000000000..0ac9bad98
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_random_words/aliases
@@ -0,0 +1,7 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+skip/aix
+skip/python2.6 # lookups are controller only, and we no longer support Python 2.6 on the controller
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_random_words/dependencies.yml b/ansible_collections/community/general/tests/integration/targets/lookup_random_words/dependencies.yml
new file mode 100644
index 000000000..1cb0b0d3a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_random_words/dependencies.yml
@@ -0,0 +1,10 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- hosts: localhost
+ tasks:
+ - name: Install xkcdpass Python package
+ pip:
+ name: xkcdpass
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_random_words/runme.sh b/ansible_collections/community/general/tests/integration/targets/lookup_random_words/runme.sh
new file mode 100755
index 000000000..71faa439d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_random_words/runme.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+# Copyright (c) Ansible project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+set -eux
+
+ANSIBLE_ROLES_PATH=../ \
+ ansible-playbook dependencies.yml -v "$@"
+
+ANSIBLE_ROLES_PATH=../ \
+ ansible-playbook test.yml -v "$@"
diff --git a/ansible_collections/community/general/tests/integration/targets/lookup_random_words/test.yml b/ansible_collections/community/general/tests/integration/targets/lookup_random_words/test.yml
new file mode 100644
index 000000000..90c672730
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lookup_random_words/test.yml
@@ -0,0 +1,32 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- hosts: localhost
+ gather_facts: false
+ tasks:
+ - name: Call random_words plugin
+ set_fact:
+ result1: "{{ query('community.general.random_words') }}"
+ result2: "{{ query('community.general.random_words', min_length=5, max_length=5) }}"
+ result3: "{{ query('community.general.random_words', delimiter='!') }}"
+ result4: "{{ query('community.general.random_words', numwords=3, delimiter='-', case='capitalize') }}"
+ result5: "{{ query('community.general.random_words', min_length=5, max_length=5, numwords=3, delimiter='') }}"
+
+ - name: Check results
+ assert:
+ that:
+ - result1 | length == 1
+ - result1[0] | length >= 35
+ - result2 | length == 1
+ - result2[0] | length == 35
+ - result3 | length == 1
+ - result3[0].count("!") == 5
+ - result4 | length == 1
+ - result4[0] | length >= 17
+ - result4[0] | length <= 29
+ - result4[0] | regex_findall("[A-Z]") | length == 3
+ - result4[0].count("-") == 2
+ - result5 | length == 1
+ - result5[0] | length == 15
diff --git a/ansible_collections/community/general/tests/integration/targets/lvg/aliases b/ansible_collections/community/general/tests/integration/targets/lvg/aliases
new file mode 100644
index 000000000..3b92ba75c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lvg/aliases
@@ -0,0 +1,12 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+azp/posix/vm
+destructive
+needs/privileged
+skip/aix
+skip/freebsd
+skip/osx
+skip/macos
diff --git a/ansible_collections/community/general/tests/integration/targets/lvg/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/lvg/meta/main.yml
new file mode 100644
index 000000000..ca1915e05
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lvg/meta/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/lvg/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/main.yml
new file mode 100644
index 000000000..e14c48c3f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/main.yml
@@ -0,0 +1,27 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install required packages (Linux)
+ package:
+ name: lvm2
+ state: present
+ when: ansible_system == 'Linux'
+
+- name: Test lvg module
+ block:
+ - import_tasks: setup.yml
+
+ - import_tasks: test_indempotency.yml
+
+ - import_tasks: test_grow_reduce.yml
+
+ - import_tasks: test_pvresize.yml
+ always:
+ - import_tasks: teardown.yml
diff --git a/ansible_collections/community/general/tests/integration/targets/lvg/tasks/setup.yml b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/setup.yml
new file mode 100644
index 000000000..3984b9fc3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/setup.yml
@@ -0,0 +1,27 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: "Create files to use as a disk devices"
+ command: "dd if=/dev/zero of={{ remote_tmp_dir }}/img{{ item }} bs=1M count=10"
+ with_sequence: 'count=2'
+
+- name: "Show next free loop device"
+ command: "losetup -f"
+ register: loop_device1
+
+- name: "Create loop device for file"
+ command: "losetup -f {{ remote_tmp_dir }}/img1"
+
+- name: "Show next free loop device"
+ command: "losetup -f"
+ register: loop_device2
+
+- name: "Create loop device for file"
+ command: "losetup -f {{ remote_tmp_dir }}/img2"
+
+- name: "Affect name on disk to work on"
+ set_fact:
+ loop_device1: "{{ loop_device1.stdout }}"
+ loop_device2: "{{ loop_device2.stdout }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/lvg/tasks/teardown.yml b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/teardown.yml
new file mode 100644
index 000000000..de4957321
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/teardown.yml
@@ -0,0 +1,23 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Remove test volume group
+ lvg:
+ vg: testvg
+ state: absent
+
+- name: Detach loop devices
+ command: "losetup -d {{ item }}"
+ loop:
+ - "{{ loop_device1 | default('') }}"
+ - "{{ loop_device2 | default('') }}"
+ when:
+ - item != ''
+
+- name: Remove device files
+ file:
+ path: "{{ remote_tmp_dir }}/img{{ item }}"
+ state: absent
+ with_sequence: 'count=2'
diff --git a/ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_grow_reduce.yml b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_grow_reduce.yml
new file mode 100644
index 000000000..857df9246
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_grow_reduce.yml
@@ -0,0 +1,38 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: "Create volume group on first disk"
+ lvg:
+ vg: testvg
+ pvs: "{{ loop_device1 }}"
+
+- name: "get lvm facts"
+ setup:
+
+- debug: var=ansible_lvm
+
+- name: "Assert the testvg span only on first disk"
+ assert:
+ that:
+ - ansible_lvm.pvs[loop_device1].vg == "testvg"
+ - 'loop_device2 not in ansible_lvm.pvs or
+ ansible_lvm.pvs[loop_device2].vg == ""'
+
+- name: "Extend to second disk AND reduce from the first disk"
+ lvg:
+ vg: testvg
+ pvs: "{{ loop_device2 }}"
+
+- name: "get lvm facts"
+ setup:
+
+- debug: var=ansible_lvm
+
+- name: "Assert the testvg span only on first disk"
+ assert:
+ that:
+ - 'loop_device1 not in ansible_lvm.pvs or
+ ansible_lvm.pvs[loop_device1].vg == ""'
+ - ansible_lvm.pvs[loop_device2].vg == "testvg"
diff --git a/ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_indempotency.yml b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_indempotency.yml
new file mode 100644
index 000000000..758912484
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_indempotency.yml
@@ -0,0 +1,20 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create volume group on disk device
+ lvg:
+ vg: testvg
+ pvs: "{{ loop_device1 }}"
+
+- name: Create the volume group again to verify idempotence
+ lvg:
+ vg: testvg
+ pvs: "{{ loop_device1 }}"
+ register: repeat_vg_create
+
+- name: Do all assertions to verify expected results
+ assert:
+ that:
+ - repeat_vg_create is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_pvresize.yml b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_pvresize.yml
new file mode 100644
index 000000000..f15add91c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lvg/tasks/test_pvresize.yml
@@ -0,0 +1,81 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: "Create volume group on first disk"
+ lvg:
+ vg: testvg
+ pvs: "{{ loop_device1 }}"
+
+- name: Gets current vg size
+ shell: vgs -v testvg -o pv_size --noheading --units b | xargs
+ register: cmd_result
+
+- name: Assert the testvg size is 8388608B
+ assert:
+ that:
+ - "'8388608B' == cmd_result.stdout"
+
+- name: Increases size in file
+ command: "dd if=/dev/zero bs=8MiB count=1 of={{ remote_tmp_dir }}/img1 conv=notrunc oflag=append"
+
+- name: "Reread size of file associated with loop_device1"
+ command: "losetup -c {{ loop_device1 }}"
+
+- name: "Reruns lvg with pvresize:no"
+ lvg:
+ vg: testvg
+ pvs: "{{ loop_device1 }}"
+ pvresize: false
+ register: cmd_result
+
+- assert:
+ that:
+ - cmd_result is not changed
+
+- name: Gets current vg size
+ shell: vgs -v testvg -o pv_size --noheading --units b | xargs
+ register: cmd_result
+
+- name: Assert the testvg size is still 8388608B
+ assert:
+ that:
+ - "'8388608B' == cmd_result.stdout"
+
+- name: "Reruns lvg with pvresize:yes and check_mode:yes"
+ lvg:
+ vg: testvg
+ pvs: "{{ loop_device1 }}"
+ pvresize: true
+ check_mode: true
+ register: cmd_result
+
+- name: Assert that the module returned the state was changed
+ assert:
+ that:
+ - cmd_result is changed
+
+- name: Gets current vg size
+ shell: vgs -v testvg -o pv_size --noheading --units b | xargs
+ register: cmd_result
+
+- name: Assert the testvg size is still 8388608B
+ assert:
+ that:
+ - "'8388608B' == cmd_result.stdout"
+
+- name: "Reruns lvg with pvresize:yes"
+ lvg:
+ vg: testvg
+ pvs: "{{ loop_device1 }}"
+ pvresize: true
+
+- name: Gets current vg size
+ shell: vgs -v testvg -o pv_size --noheading --units b | xargs
+ register: cmd_result
+
+- name: Assert the testvg size is now 16777216B
+ assert:
+ that:
+ - "'16777216B' == cmd_result.stdout"
diff --git a/ansible_collections/community/general/tests/integration/targets/lxd_project/aliases b/ansible_collections/community/general/tests/integration/targets/lxd_project/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lxd_project/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/lxd_project/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/lxd_project/tasks/main.yml
new file mode 100644
index 000000000..d1340eebd
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/lxd_project/tasks/main.yml
@@ -0,0 +1,142 @@
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Clean up test project
+ lxd_project:
+ name: ansible-test-project
+ state: absent
+
+- name: Clean up test project
+ lxd_project:
+ name: ansible-test-project-renamed
+ state: absent
+
+- name: Create test project
+ lxd_project:
+ name: ansible-test-project
+ config:
+ features.images: "false"
+ features.networks: "true"
+ features.profiles: "true"
+ limits.cpu: "3"
+ state: present
+ register: results
+
+- name: Check project has been created correctly
+ assert:
+ that:
+ - results is changed
+ - results.actions is defined
+ - "'create' in results.actions"
+
+- name: Create test project again with merge_project set to true
+ lxd_project:
+ name: ansible-test-project
+ merge_project: true
+ config:
+ features.images: "false"
+ features.networks: "true"
+ features.profiles: "true"
+ limits.cpu: "3"
+ state: present
+ register: results
+
+- name: Check state is not changed
+ assert:
+ that:
+ - results is not changed
+ - "{{ results.actions | length }} == 0"
+
+- name: Create test project again with merge_project set to false
+ lxd_project:
+ name: ansible-test-project
+ merge_project: false
+ config:
+ features.images: "false"
+ features.networks: "true"
+ features.profiles: "true"
+ limits.cpu: "3"
+ state: present
+ register: results
+
+- name: Check state is not changed
+ assert:
+ that:
+ - results is changed
+ - "'apply_projects_configs' in results.actions"
+
+- name: Update project test => update description
+ lxd_project:
+ name: ansible-test-project
+ merge_project: false
+ description: "ansible test project"
+ config:
+ features.images: "false"
+ features.networks: "true"
+ features.profiles: "true"
+ limits.cpu: "3"
+ state: present
+ register: results
+
+- name: Check state is changed
+ assert:
+ that:
+ - results is changed
+ - "'apply_projects_configs' in results.actions"
+
+- name: Update project test => update project config
+ lxd_project:
+ name: ansible-test-project
+ merge_project: false
+ description: "ansible test project"
+ config:
+ features.images: "false"
+ features.networks: "true"
+ features.profiles: "true"
+ limits.cpu: "4"
+ state: present
+ register: results
+
+- name: Check state is changed
+ assert:
+ that:
+ - results is changed
+ - "'apply_projects_configs' in results.actions"
+
+- name: Rename project test
+ lxd_project:
+ name: ansible-test-project
+ new_name: ansible-test-project-renamed
+ merge_project: true
+ description: "ansible test project"
+ config:
+ features.images: "false"
+ features.networks: "true"
+ features.profiles: "true"
+ limits.cpu: "4"
+ state: present
+ register: results
+
+- name: Check state is changed
+ assert:
+ that:
+ - results is changed
+ - "'rename' in results.actions"
+
+- name: Clean up test project
+ lxd_project:
+ name: ansible-test-project-renamed
+ state: absent
+ register: results
+
+- name: Check project is deleted
+ assert:
+ that:
+ - results is changed
+ - "'delete' in results.actions"
diff --git a/ansible_collections/community/general/tests/integration/targets/mail/aliases b/ansible_collections/community/general/tests/integration/targets/mail/aliases
new file mode 100644
index 000000000..afda346c4
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/mail/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
diff --git a/ansible_collections/community/general/tests/integration/targets/mail/files/smtpserver.crt b/ansible_collections/community/general/tests/integration/targets/mail/files/smtpserver.crt
new file mode 100644
index 000000000..2fcbb3a1d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/mail/files/smtpserver.crt
@@ -0,0 +1,26 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+-----BEGIN CERTIFICATE-----
+MIIDrzCCApegAwIBAgIJAJyHQUcqSOQpMA0GCSqGSIb3DQEBCwUAMG4xCzAJBgNV
+BAYTAkJFMRMwEQYDVQQIDApWbGFhbmRlcmVuMQ0wCwYDVQQHDARHZW50MQ4wDAYD
+VQQKDAVEYWdpdDELMAkGA1UECwwCSVQxHjAcBgNVBAMMFWxvY2FsaG9zdC5sb2Nh
+bGRvbWFpbjAeFw0xODExMjgxMjQ3MzlaFw0yODExMjUxMjQ3MzlaMG4xCzAJBgNV
+BAYTAkJFMRMwEQYDVQQIDApWbGFhbmRlcmVuMQ0wCwYDVQQHDARHZW50MQ4wDAYD
+VQQKDAVEYWdpdDELMAkGA1UECwwCSVQxHjAcBgNVBAMMFWxvY2FsaG9zdC5sb2Nh
+bGRvbWFpbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANLqBGgIF44U
+zRhNupGwSKAeTIXT4nXPIJKlIi1kTSQwtywQmBw6leBlvj1qwU73+nhqwSclIrYx
+3ltvrpKHAWG1jqqsExuLRaKRdWgx1YC2WPgZwYC0C+LkE8vs/Kl1v0HgPuPMkzeK
+hDctQfWOaykFOy0mB/BfP2vSVoEckffMlDjG/bHwNt7cG8BnqKd8e9VR+ZcBazFK
+bnKhht0ldR84Wbp+5wpuCr1R1R0ltdO2O+LACrXzvH9Kf0CGhKXGccwGpi43eXyK
+CDbubkGcLjg9Fo7kZ6uW5nU2vHJ1iDGnvUl8X96qKoOFU0EvBveCisc1bY433uG1
+NjEZ1xLPGK8CAwEAAaNQME4wHQYDVR0OBBYEFO6nDFzJBZBLJt4yza+VrUEOy3Zl
+MB8GA1UdIwQYMBaAFO6nDFzJBZBLJt4yza+VrUEOy3ZlMAwGA1UdEwQFMAMBAf8w
+DQYJKoZIhvcNAQELBQADggEBALTq0ycKhEr/3KOsfKBup4bs5Oqv0x7ePaUNxyef
+JSyKTjD0gPY8YNAeNA7gU5XGjMr4h9cNpRmJ0TyfwWJxH4uK4d2p5k1ZpQWKv8jG
+4U9sZTQzkh8nqRBaEl94qsiCIRCllb6VveWbIGE6eqt4rT0V9l9fvbw+hSXdiYXT
+KkkX5VZxctV2OMkbP1mbOYIA22jqZKQiIvAVcMA6vSnlDAJKTi9/kw99/zjUQ9Jb
+8bF2gcnzAijJAWsCqf8hZVq9+pogptBd/bkKUCuTA4MACX5ppgQltkgX2mLrj6Ep
+Po2euqzUZREzKl2cUaP85m+8tClYk0Wjfm0RjxPRa8fgUfM=
+-----END CERTIFICATE-----
diff --git a/ansible_collections/community/general/tests/integration/targets/mail/files/smtpserver.key b/ansible_collections/community/general/tests/integration/targets/mail/files/smtpserver.key
new file mode 100644
index 000000000..193ec9cda
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/mail/files/smtpserver.key
@@ -0,0 +1,32 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDS6gRoCBeOFM0Y
+TbqRsEigHkyF0+J1zyCSpSItZE0kMLcsEJgcOpXgZb49asFO9/p4asEnJSK2Md5b
+b66ShwFhtY6qrBMbi0WikXVoMdWAtlj4GcGAtAvi5BPL7Pypdb9B4D7jzJM3ioQ3
+LUH1jmspBTstJgfwXz9r0laBHJH3zJQ4xv2x8Dbe3BvAZ6infHvVUfmXAWsxSm5y
+oYbdJXUfOFm6fucKbgq9UdUdJbXTtjviwAq187x/Sn9AhoSlxnHMBqYuN3l8igg2
+7m5BnC44PRaO5GerluZ1NrxydYgxp71JfF/eqiqDhVNBLwb3gorHNW2ON97htTYx
+GdcSzxivAgMBAAECggEALDCRucYwQTmEexoWA94+aSXP/J4XLX23ImJs1bvVGccH
+KblUVV3E9x36DN4oIEZ+eOpNC8mRC0FJiDjPB643kOQ8PvAMlNHKRjRZt/nw9KW/
+4ENtMm0GrIQCzdAaY9ritoeoRYwgMBvadcEKt8seEpsg+eWk9izOmeWY8DYvMw6N
+hNu5zQLkMGTTqfDxkl7KnyKPhjW/++eUdgsTIA31/wHsJSiNR5Pkoy2fOVtNO7JN
+EghcKE3lYKKzOW6vg0LBY8xVQ4KMbCVgnYNI3MU9qpG2bYxy1hlWIrsjrt9PyRp8
+jDSKnLD4Zvv4L6gj2fhelES/YQ/055YyzG801Q+gUQKBgQDohqr5fwQj8Awrc0K/
+DodaIkVwXHkQAhSWidrqxZXmtn4ZsgDA3V82ZTIjWe2v7ES5U4jeYKGoUweCUodr
+PPT0IKEFmS2Fq1AZZx7Ry+ihA7gw6PV5DbG5DwyNYlhn6F6Bghl8pKAcXPGuwtgd
+BKXj7utEp57Q9ue3P00cGNokKQKBgQDoNNFMPnfv5UQp+K0A89cKW8q6sf93/ul4
+kjh72q/KbK57ouhWPNib3tJLvkl7P8S45nrUGQZtd6zLhU/6SzAnGGnNZ7gNAs3l
+SWidcmZDqIiIXh6BF4/4WxXMXJdhfrux9/O8Xk89v+EDAbLbN8jSrvy87+6mOmRM
+r/MAXToxFwKBgHpGbtxalbPMRKoIp33OxxB32yoWBreLUIZFIfC5THWRW8hpWYoS
+H0J8fpwmax5K0WzfZ6cBC6F3YAiBG6Mh3/IMwoAuJ8kV6D4jgwpx/vfE+/QEXSl2
+MRIOvtwObkzd3eyenIZ2D5g6rADphznjOtUcy21D8/kRDZLIX+U5kGTZAoGBAIYg
+/ETuUJlh9V3JJyXFtBFntFLjPo4x0Oq0i6v/RkvHO4JvN4WY4AYpT5Aw+oEW9KtZ
+dtnNGslgt49YEjqh886ha3wazVW2qPgozyUjT68FSth6hWRMF/19n7nMQiUu73x9
+nWzRjTQ+Aduav5WhQ39vVM5OSav7TrR9bgBn2ZVBAoGBAN4Hle/PIFzApQYQRIT0
+wPpOvEVx56+c70ZMvLv5UgmY2jLKZKFUV6oGGUZlJXfh1ZMnXShWY1pjvi/FnIIi
+AKDB9N17DE5AmpzuXFjU3YwXde98MjuUY03P3yaFQ4cXYryqgZxuMPgyGFM9vtMd
+WXFdvCtm0c3WMpPJSr9kgy6Q
+-----END PRIVATE KEY-----
diff --git a/ansible_collections/community/general/tests/integration/targets/mail/files/smtpserver.py b/ansible_collections/community/general/tests/integration/targets/mail/files/smtpserver.py
new file mode 100644
index 000000000..18c6fbf9b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/mail/files/smtpserver.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2018, Dag Wieers (@dagwieers) <dag@wieers.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+import asyncore
+import os.path
+import ssl
+import sys
+
+# Handle TLS and non-TLS support
+try:
+ import smtpd_tls
+ HAS_TLS = True
+except ImportError:
+ import smtpd
+ HAS_TLS = False
+ print('Library smtpd-tls is missing or not supported, hence starttls is NOT supported.')
+
+# Handle custom ports
+port = '25:465'
+if len(sys.argv) > 1:
+ port = sys.argv[1]
+ports = port.split(':')
+if len(ports) > 1:
+ port1, port2 = int(ports[0]), int(ports[1])
+else:
+ port1, port2 = int(port), None
+
+# Handle custom certificate
+basename = os.path.splitext(sys.argv[0])[0]
+certfile = basename + '.crt'
+if len(sys.argv) > 2:
+ certfile = sys.argv[2]
+
+# Handle custom key
+keyfile = basename + '.key'
+if len(sys.argv) > 3:
+ keyfile = sys.argv[3]
+
+try:
+ ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
+except AttributeError:
+ ssl_ctx = None
+ if HAS_TLS:
+ print('Python ssl library does not support SSLContext, hence starttls and TLS are not supported.')
+ import smtpd
+
+if HAS_TLS and ssl_ctx is not None:
+ print('Using %s and %s' % (certfile, keyfile))
+ ssl_ctx.load_cert_chain(certfile=certfile, keyfile=keyfile)
+
+ print('Start SMTP server on port', port1)
+ smtp_server1 = smtpd_tls.DebuggingServer(('127.0.0.1', port1), None, ssl_ctx=ssl_ctx, starttls=True)
+ if port2:
+ print('Start TLS SMTP server on port', port2)
+ smtp_server2 = smtpd_tls.DebuggingServer(('127.0.0.1', port2), None, ssl_ctx=ssl_ctx, starttls=False)
+else:
+ print('Start SMTP server on port', port1)
+ smtp_server1 = smtpd.DebuggingServer(('127.0.0.1', port1), None) # pylint: disable=used-before-assignment
+ if port2:
+ print('WARNING: TLS is NOT supported on this system, not listening on port %s.' % port2)
+
+asyncore.loop()
diff --git a/ansible_collections/community/general/tests/integration/targets/mail/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/mail/meta/main.yml
new file mode 100644
index 000000000..982de6eb0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/mail/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/mail/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/mail/tasks/main.yml
new file mode 100644
index 000000000..4f3f90a51
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/mail/tasks/main.yml
@@ -0,0 +1,105 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# TODO: Our current implementation does not handle SMTP authentication
+
+# NOTE: If the system does not support smtpd-tls (python 2.6 and older) we do basic tests
+- name: Attempt to install smtpd-tls
+ pip:
+ name: smtpd-tls
+ state: present
+ ignore_errors: true
+ register: smtpd_tls
+
+- name: Install test smtpserver
+ copy:
+ src: '{{ item }}'
+ dest: '{{ remote_tmp_dir }}/{{ item }}'
+ loop:
+ - smtpserver.py
+ - smtpserver.crt
+ - smtpserver.key
+
+# FIXME: Verify the mail after it was send would be nice
+# This would require either dumping the content, or registering async task output
+- name: Start test smtpserver
+ shell: '{{ ansible_python.executable }} {{ remote_tmp_dir }}/smtpserver.py 10025:10465'
+ async: 45
+ poll: 0
+ register: smtpserver
+
+- name: Send a basic test-mail
+ mail:
+ port: 10025
+ subject: Test mail 1 (smtp)
+ secure: never
+
+- name: Send a test-mail with body and specific recipient
+ mail:
+ port: 10025
+ from: ansible@localhost
+ to: root@localhost
+ subject: Test mail 2 (smtp + body)
+ body: Test body 2
+ secure: never
+
+- name: Send a test-mail with attachment
+ mail:
+ port: 10025
+ from: ansible@localhost
+ to: root@localhost
+ subject: Test mail 3 (smtp + body + attachment)
+ body: Test body 3
+ attach: /etc/group
+ secure: never
+
+# NOTE: This might fail if smtpd-tls is missing or python 2.7.8 or older is used
+- name: Send a test-mail using starttls
+ mail:
+ port: 10025
+ from: ansible@localhost
+ to: root@localhost
+ subject: Test mail 4 (smtp + starttls + body + attachment)
+ body: Test body 4
+ attach: /etc/group
+ secure: starttls
+ ignore_errors: true
+ register: starttls_support
+
+# NOTE: This might fail if smtpd-tls is missing or python 2.7.8 or older is used
+- name: Send a test-mail using TLS
+ mail:
+ port: 10465
+ from: ansible@localhost
+ to: root@localhost
+ subject: Test mail 5 (smtp + tls + body + attachment)
+ body: Test body 5
+ attach: /etc/group
+ secure: always
+ ignore_errors: true
+ register: tls_support
+
+- fail:
+ msg: Sending mail using starttls failed.
+ when: smtpd_tls is succeeded and starttls_support is failed and tls_support is succeeded
+
+- fail:
+ msg: Send mail using TLS failed.
+ when: smtpd_tls is succeeded and tls_support is failed and starttls_support is succeeded
+
+- name: Send a test-mail with body, specific recipient and specific ehlohost
+ mail:
+ port: 10025
+ ehlohost: some.domain.tld
+ from: ansible@localhost
+ to: root@localhost
+ subject: Test mail 6 (smtp + body + ehlohost)
+ body: Test body 6
+ secure: never
diff --git a/ansible_collections/community/general/tests/integration/targets/mas/aliases b/ansible_collections/community/general/tests/integration/targets/mas/aliases
new file mode 100644
index 000000000..ea236467f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/mas/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+needs/root
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/mas/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/mas/tasks/main.yml
new file mode 100644
index 000000000..f659160dc
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/mas/tasks/main.yml
@@ -0,0 +1,158 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Test code for the mas module.
+# Copyright (c) 2020, Lukas Bestle <project-ansible@lukasbestle.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Test preparation
+- name: Uninstall Rested to ensure consistent starting point
+ mas:
+ id: 421879749
+ state: absent
+ become: true
+
+- name: Determine whether the app is installed
+ stat:
+ path: /Applications/Rested.app
+ register: install_status
+
+- name: Ensure the app is uninstalled
+ assert:
+ that:
+ - install_status.stat.exists == false
+
+- name: Wait until the OS-internal cache was updated
+ pause:
+ seconds: 5
+
+# Installation
+- name: Check if Rested needs to be installed
+ mas:
+ id: 421879749
+ state: present
+ register: install_check
+ check_mode: true
+
+- name: Ensure that the status would have changed
+ assert:
+ that:
+ - install_check is changed
+ - install_check.msg == "Installed 1 app(s)"
+
+- name: Determine whether the app is installed
+ stat:
+ path: /Applications/Rested.app
+ register: install_status
+
+- name: Ensure the app is not yet installed
+ assert:
+ that:
+ - install_status.stat.exists == false
+
+- name: Install Rested
+ mas:
+ id: 421879749
+ state: present
+ register: install
+
+- name: Ensure that the status changed
+ assert:
+ that:
+ - install is changed
+ - install.msg == "Installed 1 app(s)"
+
+- name: Determine whether the app is installed
+ stat:
+ path: /Applications/Rested.app
+ register: install_status
+
+- name: Ensure the app is installed
+ assert:
+ that:
+ - install_status.stat.exists == true
+
+- name: Wait until the OS-internal cache was updated
+ pause:
+ seconds: 5
+
+- name: Install Rested again
+ mas:
+ id: 421879749
+ state: present
+ register: install_again
+
+- name: Ensure that the status is unchanged (already installed)
+ assert:
+ that:
+ - install_again is not changed
+ - "'msg' not in install_again"
+
+# Uninstallation
+- name: Check if Rested needs to be uninstalled
+ mas:
+ id: 421879749
+ state: absent
+ register: uninstall_check
+ become: true
+ check_mode: true
+
+- name: Ensure that the status would have changed
+ assert:
+ that:
+ - uninstall_check is changed
+ - uninstall_check.msg == "Uninstalled 1 app(s)"
+
+- name: Determine whether the app is installed
+ stat:
+ path: /Applications/Rested.app
+ register: install_status
+
+- name: Ensure the app is not yet uninstalled
+ assert:
+ that:
+ - install_status.stat.exists == true
+
+- name: Unistall Rested
+ mas:
+ id: 421879749
+ state: absent
+ register: uninstall
+ become: true
+
+- name: Ensure that the status changed
+ assert:
+ that:
+ - uninstall is changed
+ - uninstall.msg == "Uninstalled 1 app(s)"
+
+- name: Determine whether the app is installed
+ stat:
+ path: /Applications/Rested.app
+ register: uninstall_status
+
+- name: Ensure the app is uninstalled
+ assert:
+ that:
+ - uninstall_status.stat.exists == false
+
+- name: Wait until the OS-internal cache was updated
+ pause:
+ seconds: 5
+
+- name: Uninstall Rested again
+ mas:
+ id: 421879749
+ state: absent
+ register: uninstall_again
+ become: true
+
+- name: Ensure that the status is unchanged (already uninstalled)
+ assert:
+ that:
+ - uninstall_again is not changed
+ - "'msg' not in uninstall_again"
diff --git a/ansible_collections/community/general/tests/integration/targets/memset_dns_reload/aliases b/ansible_collections/community/general/tests/integration/targets/memset_dns_reload/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/memset_dns_reload/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/memset_dns_reload/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/memset_dns_reload/meta/main.yml
new file mode 100644
index 000000000..f55df21f8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/memset_dns_reload/meta/main.yml
@@ -0,0 +1,4 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/ansible_collections/community/general/tests/integration/targets/memset_dns_reload/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/memset_dns_reload/tasks/main.yml
new file mode 100644
index 000000000..153df95ba
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/memset_dns_reload/tasks/main.yml
@@ -0,0 +1,33 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: request reload with invalid API key
+ memset_dns_reload:
+ api_key: "wa9aerahhie0eekee9iaphoorovooyia"
+ ignore_errors: true
+ register: result
+
+- name: check API response with invalid API key
+ assert:
+ that:
+ - "'Memset API returned a 403 response (ApiErrorForbidden, Bad api_key)' in result.msg"
+ - result is not successful
+
+- name: request reload and poll
+ memset_dns_reload:
+ api_key: "{{ api_key }}"
+ poll: true
+ register: result
+
+- name: check reload succeeded
+ assert:
+ that:
+ - result is changed
+ - result is successful
diff --git a/ansible_collections/community/general/tests/integration/targets/memset_memstore_info/aliases b/ansible_collections/community/general/tests/integration/targets/memset_memstore_info/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/memset_memstore_info/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/memset_memstore_info/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/memset_memstore_info/meta/main.yml
new file mode 100644
index 000000000..f55df21f8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/memset_memstore_info/meta/main.yml
@@ -0,0 +1,4 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/ansible_collections/community/general/tests/integration/targets/memset_memstore_info/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/memset_memstore_info/tasks/main.yml
new file mode 100644
index 000000000..7dc7f7c69
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/memset_memstore_info/tasks/main.yml
@@ -0,0 +1,34 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: query API with invalid API key
+ memset_memstore_info:
+ api_key: 'wa9aerahhie0eekee9iaphoorovooyia'
+ name: 'mstestyaa1'
+ ignore_errors: true
+ register: result
+
+- name: check API response with invalid API key
+ assert:
+ that:
+ - "'Memset API returned a 403 response (ApiErrorForbidden, Bad api_key)' in result.msg"
+ - result is not successful
+
+- name: request memstore infos
+ memset_memstore_info:
+ api_key: "{{ api_key }}"
+ name: 'mstestyaa1'
+ register: result
+
+- name: check the request succeeded
+ assert:
+ that:
+ - result is not changed
+ - result is successful
diff --git a/ansible_collections/community/general/tests/integration/targets/memset_server_info/aliases b/ansible_collections/community/general/tests/integration/targets/memset_server_info/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/memset_server_info/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/memset_server_info/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/memset_server_info/meta/main.yml
new file mode 100644
index 000000000..f55df21f8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/memset_server_info/meta/main.yml
@@ -0,0 +1,4 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/ansible_collections/community/general/tests/integration/targets/memset_server_info/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/memset_server_info/tasks/main.yml
new file mode 100644
index 000000000..79066fac7
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/memset_server_info/tasks/main.yml
@@ -0,0 +1,34 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: query API with invalid API key
+ memset_server_info:
+ api_key: 'wa9aerahhie0eekee9iaphoorovooyia'
+ name: 'testyaa1'
+ ignore_errors: true
+ register: result
+
+- name: check API response with invalid API key
+ assert:
+ that:
+ - "'Memset API returned a 403 response (ApiErrorForbidden, Bad api_key)' in result.msg"
+ - result is not successful
+
+- name: request server infos
+ memset_server_info:
+ api_key: "{{ api_key }}"
+ name: 'testyaa1'
+ register: result
+
+- name: check the request succeeded
+ assert:
+ that:
+ - result is not changed
+ - result is successful
diff --git a/ansible_collections/community/general/tests/integration/targets/memset_zone/aliases b/ansible_collections/community/general/tests/integration/targets/memset_zone/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/memset_zone/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/memset_zone/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/memset_zone/meta/main.yml
new file mode 100644
index 000000000..f55df21f8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/memset_zone/meta/main.yml
@@ -0,0 +1,4 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/ansible_collections/community/general/tests/integration/targets/memset_zone/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/memset_zone/tasks/main.yml
new file mode 100644
index 000000000..091bab823
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/memset_zone/tasks/main.yml
@@ -0,0 +1,125 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: create random string
+ set_fact:
+ zone_name: "{{ 65535 | random | string }}.ansible.example.com"
+
+- name: create zone with incorrect API key
+ memset_zone:
+ api_key: "wa9aerahhie0eekee9iaphoorovooyia"
+ state: present
+ name: "{{ zone_name }}"
+ ttl: 300
+ ignore_errors: true
+ register: result
+
+- name: check API response with invalid API key
+ assert:
+ that:
+ - "'Memset API returned a 403 response (ApiErrorForbidden, Bad api_key)' in result.msg"
+ - result is not successful
+
+- name: test creating zone
+ memset_zone:
+ api_key: "{{ api_key }}"
+ state: present
+ name: "{{ zone_name }}"
+ ttl: 300
+ check_mode: true
+ register: result
+
+- name: check if the zone would be created
+ assert:
+ that:
+ - result is changed
+ - result is successful
+
+- name: create zone
+ memset_zone:
+ api_key: "{{ api_key }}"
+ state: present
+ name: "{{ zone_name }}"
+ ttl: 300
+ register: result
+
+- name: create the zone
+ assert:
+ that:
+ - result is changed
+ - result is successful
+
+- name: create duplicate zone
+ memset_zone:
+ api_key: "{{ api_key }}"
+ state: present
+ name: "{{ zone_name }}"
+ ttl: 300
+ register: result
+
+- name: ensure we can't create duplicate zones
+ assert:
+ that:
+ - result is not changed
+
+- name: test deleting zone
+ memset_zone:
+ api_key: "{{ api_key }}"
+ state: absent
+ name: "{{ zone_name }}"
+ check_mode: true
+ register: result
+
+- name: check if the zone would be deleted
+ assert:
+ that:
+ - result is changed
+ - result is successful
+
+- name: delete empty zone
+ memset_zone:
+ api_key: "{{ api_key }}"
+ state: absent
+ name: "{{ zone_name }}"
+ force: false
+ register: result
+
+- name: delete the zone
+ assert:
+ that:
+ - result is changed
+ - result is successful
+
+- name: create zone for deletion test
+ memset_zone:
+ api_key: "{{ api_key }}"
+ state: present
+ name: "{{ zone_name }}"
+ register: result
+
+- name: ensure we can't create duplicate zones
+ assert:
+ that:
+ - result is changed
+ - result is successful
+
+- name: delete zone with force
+ memset_zone:
+ api_key: "{{ api_key }}"
+ state: absent
+ name: "{{ zone_name }}"
+ force: true
+ register: result
+
+- name: ensure force is respected
+ assert:
+ that:
+ - result is changed
+ - result is successful
diff --git a/ansible_collections/community/general/tests/integration/targets/memset_zone/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/memset_zone/vars/main.yml
new file mode 100644
index 000000000..8828011b0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/memset_zone/vars/main.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+random_string: "baiqui8ci6miedoo9eivohJ0aixei7oo"
diff --git a/ansible_collections/community/general/tests/integration/targets/memset_zone_domain/aliases b/ansible_collections/community/general/tests/integration/targets/memset_zone_domain/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/memset_zone_domain/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/memset_zone_domain/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/memset_zone_domain/meta/main.yml
new file mode 100644
index 000000000..f55df21f8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/memset_zone_domain/meta/main.yml
@@ -0,0 +1,4 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/ansible_collections/community/general/tests/integration/targets/memset_zone_domain/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/memset_zone_domain/tasks/main.yml
new file mode 100644
index 000000000..e92ffcdcf
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/memset_zone_domain/tasks/main.yml
@@ -0,0 +1,152 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: create domain with invalid API key
+ memset_zone_domain:
+ api_key: "wa9aerahhie0eekee9iaphoorovooyia"
+ state: present
+ domain: "{{ test_domain }}"
+ zone: "{{ target_zone }}"
+ ignore_errors: true
+ register: result
+
+- name: check API response with invalid API key
+ assert:
+ that:
+ - "'Memset API returned a 403 response (ApiErrorForbidden, Bad api_key)' in result.msg"
+ - result is not successful
+
+- name: create domain over 250 chars
+ memset_zone_domain:
+ api_key: "{{ api_key }}"
+ state: present
+ domain: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com'
+ zone: "{{ target_zone }}"
+ ignore_errors: true
+ register: result
+
+- name: test domain length is validated
+ assert:
+ that:
+ - result is failed
+ - "'Zone domain must be less than 250 characters in length' in result.stderr"
+
+- name: create domain in non-existent zone
+ memset_zone_domain:
+ api_key: "{{ api_key }}"
+ state: present
+ domain: "{{ test_domain }}"
+ zone: "non-existent-zone"
+ ignore_errors: true
+ register: result
+
+- name: fail if zone does not exist
+ assert:
+ that:
+ - result is failed
+ - "'does not exist, cannot create domain.' in result.stderr"
+
+- name: create domain in non-unique zone
+ memset_zone_domain:
+ api_key: "{{ api_key }}"
+ state: present
+ domain: "{{ test_domain }}"
+ zone: "{{ duplicate_zone }}"
+ ignore_errors: true
+ register: result
+
+- name: fail if the zone is not unique
+ assert:
+ that:
+ - result is failed
+ - "'matches multiple zones, cannot create domain' in result.stderr"
+
+- name: test creating domain
+ memset_zone_domain:
+ api_key: "{{ api_key }}"
+ state: present
+ domain: "{{ test_domain }}"
+ zone: "{{ target_zone }}"
+ check_mode: true
+ register: result
+
+- name: create domain with check mode
+ assert:
+ that:
+ - result is changed
+ - result is successful
+
+- name: create domain
+ memset_zone_domain:
+ api_key: "{{ api_key }}"
+ state: present
+ domain: "{{ test_domain }}"
+ zone: "{{ target_zone }}"
+ register: result
+
+- name: create domain
+ assert:
+ that:
+ - result is changed
+ - result is successful
+
+- name: create existing domain
+ memset_zone_domain:
+ api_key: "{{ api_key }}"
+ state: present
+ domain: "{{ test_domain }}"
+ zone: "{{ target_zone }}"
+ register: result
+
+- name: create existing domain
+ assert:
+ that:
+ - result is not changed
+
+- name: test deleting domain
+ memset_zone_domain:
+ api_key: "{{ api_key }}"
+ state: absent
+ domain: "{{ test_domain }}"
+ zone: "{{ target_zone }}"
+ check_mode: true
+ register: result
+
+- name: delete domain with check mode
+ assert:
+ that:
+ - result is changed
+ - result is successful
+
+- name: delete domain
+ memset_zone_domain:
+ api_key: "{{ api_key }}"
+ state: absent
+ domain: "{{ test_domain }}"
+ zone: "{{ target_zone }}"
+ register: result
+
+- name: delete domain
+ assert:
+ that:
+ - result is changed
+
+- name: delete non-existent domain
+ memset_zone_domain:
+ api_key: "{{ api_key }}"
+ state: absent
+ domain: "{{ test_domain }}"
+ zone: "{{ target_zone }}"
+ register: result
+
+- name: delete absent domain
+ assert:
+ that:
+ - result is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/memset_zone_domain/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/memset_zone_domain/vars/main.yml
new file mode 100644
index 000000000..e891ff49f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/memset_zone_domain/vars/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+test_domain: ansible.example.com
+target_zone: ansible-dns-zone
+duplicate_zone: ansible-dns-zone-dupe
diff --git a/ansible_collections/community/general/tests/integration/targets/memset_zone_record/aliases b/ansible_collections/community/general/tests/integration/targets/memset_zone_record/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/memset_zone_record/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/memset_zone_record/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/memset_zone_record/meta/main.yml
new file mode 100644
index 000000000..f55df21f8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/memset_zone_record/meta/main.yml
@@ -0,0 +1,4 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/ansible_collections/community/general/tests/integration/targets/memset_zone_record/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/memset_zone_record/tasks/main.yml
new file mode 100644
index 000000000..c1bdd6873
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/memset_zone_record/tasks/main.yml
@@ -0,0 +1,235 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: create record with incorrect API key
+ memset_zone_record:
+ api_key: "wa9aerahhie0eekee9iaphoorovooyia"
+ state: present
+ zone: "{{ test_zone }}"
+ type: A
+ address: 127.0.0.1
+ ignore_errors: true
+ register: result
+
+- assert:
+ that:
+ - "'Memset API returned a 403 response (ApiErrorForbidden, Bad api_key)' in result.msg"
+ - result is not successful
+
+- name: create record in non-existent zone
+ memset_zone_record:
+ api_key: "{{ api_key }}"
+ state: present
+ zone: "a-non-existent-zone"
+ type: A
+ address: 127.0.0.1
+ ignore_errors: true
+ register: result
+
+- name: assert that record is not created
+ assert:
+ that:
+ - "'DNS zone a-non-existent-zone does not exist.' in result.msg"
+ - result is not successful
+
+- name: create record in non-unique zone
+ memset_zone_record:
+ api_key: "{{ api_key }}"
+ state: present
+ zone: "{{ duplicate_zone }}"
+ type: A
+ address: 127.0.0.1
+ ignore_errors: true
+ register: result
+
+- name: assert that record is not created
+ assert:
+ that:
+ - "'ansible-dns-zone-dupe matches multiple zones.' in result.msg"
+ - result is not successful
+
+- name: create record with invalid priority
+ memset_zone_record:
+ api_key: "{{ api_key }}"
+ state: present
+ zone: "{{ test_zone }}"
+ type: SRV
+ address: "0 5269 hostname.example.com"
+ record: "_jabber._tcp"
+ priority: 1001
+ ignore_errors: true
+ register: result
+
+- name: assert that priority was out of range
+ assert:
+ that:
+ - "'Priority must be in the range 0 > 999 (inclusive).' in result.msg"
+ - result is not successful
+
+- name: create record with address longer than 250 chars
+ memset_zone_record:
+ api_key: "{{ api_key }}"
+ state: present
+ zone: "{{ test_zone }}"
+ type: CNAME
+ address: "aaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com"
+ record: "aaa.ansible.com"
+ ignore_errors: true
+ register: result
+
+- name: assert that address was longer than allowed
+ assert:
+ that:
+ - "'Address must be less than 250 characters in length.' in result.msg"
+ - result is not successful
+
+- name: create record longer than 63 chars
+ memset_zone_record:
+ api_key: "{{ api_key }}"
+ state: present
+ zone: "{{ test_zone }}"
+ type: A
+ address: 127.0.0.1
+ record: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ ignore_errors: true
+ register: result
+
+- name: assert that record was longer than allowed
+ assert:
+ that:
+ - "'Record must be less than 63 characters in length.' in result.msg"
+ - result is not successful
+
+- name: create record which cannot have relative enabled
+ memset_zone_record:
+ api_key: "{{ api_key }}"
+ state: present
+ zone: "{{ test_zone }}"
+ type: A
+ address: 127.0.0.1
+ relative: true
+ ignore_errors: true
+ register: result
+
+- name: assert that setting relative failed
+ assert:
+ that:
+ - "'Relative is only valid for CNAME, MX, NS and SRV record types' in result.msg"
+ - result is not successful
+
+- name: test creating valid A record
+ memset_zone_record:
+ api_key: "{{ api_key }}"
+ state: present
+ zone: "{{ test_zone }}"
+ type: A
+ address: 127.0.0.1
+ record: "www"
+ check_mode: true
+ register: result
+
+- name: assert that result would have changed
+ assert:
+ that:
+ - result is changed
+ - result is successful
+
+- name: actually create valid A record
+ memset_zone_record:
+ api_key: "{{ api_key }}"
+ state: present
+ zone: "{{ test_zone }}"
+ type: A
+ address: 127.0.0.1
+ record: "www"
+ register: result
+
+- name: assert that result changed
+ assert:
+ that:
+ - result is changed
+ - result is successful
+
+- name: create valid SPF record
+ memset_zone_record:
+ api_key: "{{ api_key }}"
+ state: present
+ zone: "{{ test_zone }}"
+ type: TXT
+ address: "v=spf1 +a +mx +ip4:127.0.0.1 ?all"
+ register: result
+
+- name: assert that result changed
+ assert:
+ that:
+ - result is changed
+ - result is successful
+
+- name: test deleting A record
+ memset_zone_record:
+ api_key: "{{ api_key }}"
+ state: absent
+ zone: "{{ test_zone }}"
+ type: A
+ address: 127.0.0.1
+ record: "www"
+ check_mode: true
+ register: result
+
+- name: assert that result changed
+ assert:
+ that:
+ - result is changed
+ - result is successful
+
+- name: actually delete A record
+ memset_zone_record:
+ api_key: "{{ api_key }}"
+ state: absent
+ zone: "{{ test_zone }}"
+ type: A
+ address: 127.0.0.1
+ record: "www"
+ register: result
+
+- name: assert that result changed
+ assert:
+ that:
+ - result is changed
+ - result is successful
+
+- name: delete SPF record
+ memset_zone_record:
+ api_key: "{{ api_key }}"
+ state: absent
+ zone: "{{ test_zone }}"
+ type: TXT
+ address: "v=spf1 +a +mx +ip4:127.0.0.1 ?all"
+ register: result
+
+- name: assert that result changed
+ assert:
+ that:
+ - result is changed
+ - result is successful
+
+- name: delete non-existent SPF record
+ memset_zone_record:
+ api_key: "{{ api_key }}"
+ state: absent
+ zone: "{{ test_zone }}"
+ type: TXT
+ address: "v=spf1 +a +mx +ip4:127.0.0.1 ?all"
+ register: result
+
+- name: assert that result changed
+ assert:
+ that:
+ - result is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/memset_zone_record/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/memset_zone_record/vars/main.yml
new file mode 100644
index 000000000..857f1c722
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/memset_zone_record/vars/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+test_zone: ansible-dns-record-tests
+duplicate_zone: ansible-dns-zone-dupe
diff --git a/ansible_collections/community/general/tests/integration/targets/module_helper/aliases b/ansible_collections/community/general/tests/integration/targets/module_helper/aliases
new file mode 100644
index 000000000..12d1d6617
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/module_helper/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
diff --git a/ansible_collections/community/general/tests/integration/targets/module_helper/library/mdepfail.py b/ansible_collections/community/general/tests/integration/targets/module_helper/library/mdepfail.py
new file mode 100644
index 000000000..92ebbde6e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/module_helper/library/mdepfail.py
@@ -0,0 +1,70 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright (c) 2021, Alexei Znamensky <russoz@gmail.com>
+#
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+DOCUMENTATION = '''
+module: mdepfail
+author: "Alexei Znamensky (@russoz)"
+short_description: Simple module for testing
+description:
+ - Simple module test description.
+options:
+ a:
+ description: aaaa
+ type: int
+ b:
+ description: bbbb
+ type: str
+ c:
+ description: cccc
+ type: str
+'''
+
+EXAMPLES = ""
+
+RETURN = ""
+
+from ansible_collections.community.general.plugins.module_utils.module_helper import ModuleHelper
+from ansible.module_utils.basic import missing_required_lib
+
+with ModuleHelper.dependency("nopackagewiththisname", missing_required_lib("nopackagewiththisname")):
+ import nopackagewiththisname # noqa: F401, pylint: disable=unused-import
+
+
+class MSimple(ModuleHelper):
+ output_params = ('a', 'b', 'c')
+ module = dict(
+ argument_spec=dict(
+ a=dict(type='int'),
+ b=dict(type='str'),
+ c=dict(type='str'),
+ ),
+ )
+
+ def __init_module__(self):
+ self.vars.set('value', None)
+ self.vars.set('abc', "abc", diff=True)
+
+ def __run__(self):
+ if (0 if self.vars.a is None else self.vars.a) >= 100:
+ raise Exception("a >= 100")
+ if self.vars.c == "abc change":
+ self.vars['abc'] = "changed abc"
+ if self.vars.get('a', 0) == 2:
+ self.vars['b'] = str(self.vars.b) * 2
+ self.vars['c'] = str(self.vars.c) * 2
+
+
+def main():
+ msimple = MSimple()
+ msimple.run()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/general/tests/integration/targets/module_helper/library/msimple.py b/ansible_collections/community/general/tests/integration/targets/module_helper/library/msimple.py
new file mode 100644
index 000000000..096e51524
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/module_helper/library/msimple.py
@@ -0,0 +1,78 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright (c) 2021, Alexei Znamensky <russoz@gmail.com>
+#
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+DOCUMENTATION = '''
+module: msimple
+author: "Alexei Znamensky (@russoz)"
+short_description: Simple module for testing
+description:
+ - Simple module test description.
+options:
+ a:
+ description: aaaa
+ type: int
+ b:
+ description: bbbb
+ type: str
+ c:
+ description: cccc
+ type: str
+'''
+
+EXAMPLES = ""
+
+RETURN = ""
+
+from ansible_collections.community.general.plugins.module_utils.module_helper import ModuleHelper
+from ansible_collections.community.general.plugins.module_utils.mh.deco import check_mode_skip
+
+
+class MSimple(ModuleHelper):
+ output_params = ('a', 'b', 'c', 'm')
+ module = dict(
+ argument_spec=dict(
+ a=dict(type='int', default=0),
+ b=dict(type='str'),
+ c=dict(type='str'),
+ m=dict(type='str'),
+ ),
+ supports_check_mode=True,
+ )
+
+ def __init_module__(self):
+ self.vars.set('value', None)
+ self.vars.set('abc', "abc", diff=True)
+
+ @check_mode_skip
+ def process_a3_bc(self):
+ if self.vars.a == 3:
+ self.vars['b'] = str(self.vars.b) * 3
+ self.vars['c'] = str(self.vars.c) * 3
+
+ def __run__(self):
+ if self.vars.m:
+ self.vars.msg = self.vars.m
+ if self.vars.a >= 100:
+ raise Exception("a >= 100")
+ if self.vars.c == "abc change":
+ self.vars['abc'] = "changed abc"
+ if self.vars.get('a', 0) == 2:
+ self.vars['b'] = str(self.vars.b) * 2
+ self.vars['c'] = str(self.vars.c) * 2
+ self.process_a3_bc()
+
+
+def main():
+ msimple = MSimple()
+ msimple.run()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/general/tests/integration/targets/module_helper/library/msimpleda.py b/ansible_collections/community/general/tests/integration/targets/module_helper/library/msimpleda.py
new file mode 100644
index 000000000..c21c3d2ea
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/module_helper/library/msimpleda.py
@@ -0,0 +1,66 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright (c) 2021, Alexei Znamensky <russoz@gmail.com>
+#
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+DOCUMENTATION = '''
+module: msimpleda
+author: "Alexei Znamensky (@russoz)"
+short_description: Simple module for testing DeprecationAttrsMixin
+description:
+ - Simple module test description.
+options:
+ a:
+ description: aaaa
+ type: int
+'''
+
+EXAMPLES = ""
+
+RETURN = ""
+
+from ansible_collections.community.general.plugins.module_utils.module_helper import ModuleHelper
+from ansible_collections.community.general.plugins.module_utils.mh.mixins.deprecate_attrs import ( # noqa: F401, pylint: disable=unused-import
+ DeprecateAttrsMixin
+)
+
+
+class MSimpleDA(ModuleHelper):
+ output_params = ('a',)
+ module = dict(
+ argument_spec=dict(
+ a=dict(type='int'),
+ ),
+ )
+
+ attr1 = "abc"
+ attr2 = "def"
+
+ def __init_module__(self):
+ self._deprecate_attr(
+ "attr2",
+ msg="Attribute attr2 is deprecated",
+ version="9.9.9",
+ collection_name="community.general",
+ target=self.__class__,
+ module=self.module,
+ )
+
+ def __run__(self):
+ if self.vars.a == 1:
+ self.vars.attr1 = self.attr1
+ if self.vars.a == 2:
+ self.vars.attr2 = self.attr2
+
+
+def main():
+ MSimpleDA.execute()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/general/tests/integration/targets/module_helper/library/mstate.py b/ansible_collections/community/general/tests/integration/targets/module_helper/library/mstate.py
new file mode 100644
index 000000000..bfaab0375
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/module_helper/library/mstate.py
@@ -0,0 +1,78 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright (c) 2021, Alexei Znamensky <russoz@gmail.com>
+#
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+DOCUMENTATION = '''
+module: mstate
+author: "Alexei Znamensky (@russoz)"
+short_description: State-based module for testing
+description:
+ - State-based module test description.
+options:
+ a:
+ description: aaaa
+ type: int
+ required: true
+ b:
+ description: bbbb
+ type: str
+ c:
+ description: cccc
+ type: str
+ state:
+ description: test states
+ type: str
+ choices: [join, b_x_a, c_x_a, both_x_a]
+ default: join
+'''
+
+EXAMPLES = ""
+
+RETURN = ""
+
+from ansible_collections.community.general.plugins.module_utils.module_helper import StateModuleHelper
+
+
+class MState(StateModuleHelper):
+ output_params = ('a', 'b', 'c', 'state')
+ module = dict(
+ argument_spec=dict(
+ a=dict(type='int', required=True),
+ b=dict(type='str'),
+ c=dict(type='str'),
+ state=dict(type='str', choices=['join', 'b_x_a', 'c_x_a', 'both_x_a', 'nop'], default='join'),
+ ),
+ )
+
+ def __init_module__(self):
+ self.vars.set('result', "abc", diff=True)
+
+ def state_join(self):
+ self.vars['result'] = "".join([str(self.vars.a), str(self.vars.b), str(self.vars.c)])
+
+ def state_b_x_a(self):
+ self.vars['result'] = str(self.vars.b) * self.vars.a
+
+ def state_c_x_a(self):
+ self.vars['result'] = str(self.vars.c) * self.vars.a
+
+ def state_both_x_a(self):
+ self.vars['result'] = (str(self.vars.b) + str(self.vars.c)) * self.vars.a
+
+ def state_nop(self):
+ pass
+
+
+def main():
+ mstate = MState()
+ mstate.run()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/general/tests/integration/targets/module_helper/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/module_helper/tasks/main.yml
new file mode 100644
index 000000000..2368cfcbb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/module_helper/tasks/main.yml
@@ -0,0 +1,9 @@
+# Copyright (c) 2021, Alexei Znamensky
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- include_tasks: msimple.yml
+- include_tasks: msimple_output_conflict.yml
+- include_tasks: mdepfail.yml
+- include_tasks: mstate.yml
+- include_tasks: msimpleda.yml
diff --git a/ansible_collections/community/general/tests/integration/targets/module_helper/tasks/mdepfail.yml b/ansible_collections/community/general/tests/integration/targets/module_helper/tasks/mdepfail.yml
new file mode 100644
index 000000000..1655be54e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/module_helper/tasks/mdepfail.yml
@@ -0,0 +1,18 @@
+# Copyright (c) 2021, Alexei Znamensky
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: test failing dependency
+ mdepfail:
+ a: 123
+ ignore_errors: true
+ register: result
+
+- name: assert failing dependency
+ assert:
+ that:
+ - result is failed
+ - '"Failed to import" in result.msg'
+ - '"nopackagewiththisname" in result.msg'
+ - '"ModuleNotFoundError:" in result.exception or "ImportError:" in result.exception'
+ - '"nopackagewiththisname" in result.exception'
diff --git a/ansible_collections/community/general/tests/integration/targets/module_helper/tasks/msimple.yml b/ansible_collections/community/general/tests/integration/targets/module_helper/tasks/msimple.yml
new file mode 100644
index 000000000..03818639c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/module_helper/tasks/msimple.yml
@@ -0,0 +1,85 @@
+# Copyright (c) 2021, Alexei Znamensky
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: test msimple (set a=80)
+ msimple:
+ a: 80
+ register: simple1
+
+- name: assert simple1
+ assert:
+ that:
+ - simple1.a == 80
+ - simple1.abc == "abc"
+ - simple1 is not changed
+ - simple1.value is none
+
+- name: test msimple 2
+ msimple:
+ a: 101
+ ignore_errors: true
+ register: simple2
+
+- name: assert simple2
+ assert:
+ that:
+ - simple2.a == 101
+ - 'simple2.msg == "Module failed with exception: a >= 100"'
+ - simple2.abc == "abc"
+ - simple2 is failed
+ - simple2 is not changed
+ - simple2.value is none
+
+- name: test msimple 3
+ msimple:
+ a: 2
+ b: potatoes
+ register: simple3
+
+- name: assert simple3
+ assert:
+ that:
+ - simple3.a == 2
+ - simple3.b == "potatoespotatoes"
+ - simple3.c == "NoneNone"
+ - simple3 is not changed
+
+- name: test msimple 4
+ msimple:
+ c: abc change
+ register: simple4
+
+- name: assert simple4
+ assert:
+ that:
+ - simple4.c == "abc change"
+ - simple4.abc == "changed abc"
+ - simple4 is changed
+
+- name: test msimple 5a
+ msimple:
+ a: 3 # should triple b and c
+ b: oh
+ c: my
+ register: simple5a
+
+- name: test msimple 5b
+ check_mode: true
+ msimple:
+ a: 3 # should triple b and c
+ b: oh
+ c: my
+ register: simple5b
+
+- name: assert simple5
+ assert:
+ that:
+ - simple5a.a == 3
+ - simple5a.b == "ohohoh"
+ - simple5a.c == "mymymy"
+ - simple5a is not changed
+ - simple5b.a == 3
+ - simple5b.b == "oh"
+ - simple5b.c == "my"
+ - simple5b is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/module_helper/tasks/msimple_output_conflict.yml b/ansible_collections/community/general/tests/integration/targets/module_helper/tasks/msimple_output_conflict.yml
new file mode 100644
index 000000000..62fe1e327
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/module_helper/tasks/msimple_output_conflict.yml
@@ -0,0 +1,54 @@
+# Copyright (c) 2023, Alexei Znamensky
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: test msimple conflict output (set a=80)
+ msimple:
+ a: 80
+ register: simple1
+
+- name: assert simple1
+ assert:
+ that:
+ - simple1.a == 80
+ - simple1.abc == "abc"
+ - simple1 is not changed
+ - simple1.value is none
+
+- name: test msimple conflict output 2
+ msimple:
+ a: 80
+ m: a message in a bottle
+ register: simple2
+
+- name: assert simple2
+ assert:
+ that:
+ - simple1.a == 80
+ - simple1.abc == "abc"
+ - simple1 is not changed
+ - simple1.value is none
+ - >
+ "_msg" not in simple2
+ - >
+ simple2.msg == "a message in a bottle"
+
+- name: test msimple 3
+ msimple:
+ a: 101
+ m: a message in a bottle
+ ignore_errors: true
+ register: simple3
+
+- name: assert simple3
+ assert:
+ that:
+ - simple3.a == 101
+ - >
+ simple3.msg == "Module failed with exception: a >= 100"
+ - >
+ simple3._msg == "a message in a bottle"
+ - simple3.abc == "abc"
+ - simple3 is failed
+ - simple3 is not changed
+ - simple3.value is none
diff --git a/ansible_collections/community/general/tests/integration/targets/module_helper/tasks/msimpleda.yml b/ansible_collections/community/general/tests/integration/targets/module_helper/tasks/msimpleda.yml
new file mode 100644
index 000000000..e01b65e12
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/module_helper/tasks/msimpleda.yml
@@ -0,0 +1,39 @@
+# Copyright (c) 2021, Alexei Znamensky
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- set_fact:
+ attr2_d:
+ msg: Attribute attr2 is deprecated
+ version: 9.9.9
+ collection_name: community.general
+ attr2_d_29:
+ msg: Attribute attr2 is deprecated
+ version: 9.9.9
+- set_fact:
+ attr2_depr_dict: "{{ ((ansible_version.major, ansible_version.minor) < (2, 10))|ternary(attr2_d_29, attr2_d) }}"
+
+- name: test msimpleda 1
+ msimpleda:
+ a: 1
+ register: simple1
+
+- name: assert simple1
+ assert:
+ that:
+ - simple1.a == 1
+ - simple1.attr1 == "abc"
+ - ("deprecations" not in simple1) or attr2_depr_dict not in simple1.deprecations
+
+- name: test msimpleda 2
+ msimpleda:
+ a: 2
+ register: simple2
+
+- name: assert simple2
+ assert:
+ that:
+ - simple2.a == 2
+ - simple2.attr2 == "def"
+ - '"deprecations" in simple2'
+ - attr2_depr_dict in simple2.deprecations
diff --git a/ansible_collections/community/general/tests/integration/targets/module_helper/tasks/mstate.yml b/ansible_collections/community/general/tests/integration/targets/module_helper/tasks/mstate.yml
new file mode 100644
index 000000000..40c695f6d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/module_helper/tasks/mstate.yml
@@ -0,0 +1,83 @@
+# Copyright (c) 2021, Alexei Znamensky
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: test mstate 1
+ mstate:
+ a: 80
+ b: banana
+ c: cashew
+ state: nop
+ register: state1
+
+- name: assert state1
+ assert:
+ that:
+ - state1.a == 80
+ - state1.b == "banana"
+ - state1.c == "cashew"
+ - state1.result == "abc"
+ - state1 is not changed
+
+- name: test mstate 2
+ mstate:
+ a: 80
+ b: banana
+ c: cashew
+ register: state2
+
+- name: assert state2
+ assert:
+ that:
+ - state2.a == 80
+ - state2.b == "banana"
+ - state2.c == "cashew"
+ - state2.result == "80bananacashew"
+ - state2 is changed
+
+- name: test mstate 3
+ mstate:
+ a: 3
+ b: banana
+ state: b_x_a
+ register: state3
+
+- name: assert state3
+ assert:
+ that:
+ - state3.a == 3
+ - state3.b == "banana"
+ - state3.result == "bananabananabanana"
+ - state3 is changed
+
+- name: test mstate 4
+ mstate:
+ a: 4
+ c: cashew
+ state: c_x_a
+ register: state4
+
+- name: assert state4
+ assert:
+ that:
+ - state4.a == 4
+ - state4.c == "cashew"
+ - state4.result == "cashewcashewcashewcashew"
+ - state4 is changed
+
+- name: test mstate 5
+ mstate:
+ a: 5
+ b: foo
+ c: bar
+ state: both_x_a
+ register: state5
+
+- name: assert state5
+ assert:
+ that:
+ - state5.a == 5
+ - state5.b == "foo"
+ - state5.c == "bar"
+ - state5.result == "foobarfoobarfoobarfoobarfoobar"
+ - state5 is changed
diff --git a/ansible_collections/community/general/tests/integration/targets/monit/aliases b/ansible_collections/community/general/tests/integration/targets/monit/aliases
new file mode 100644
index 000000000..ca39d1353
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/monit/aliases
@@ -0,0 +1,14 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+destructive
+needs/target/setup_epel
+skip/osx
+skip/macos
+skip/freebsd
+skip/aix
+skip/python2.6 # python-daemon package used in integration tests requires >=2.7
+skip/rhel # FIXME
+unstable # TODO: the tests fail a lot; 'unstable' only requires them to pass when the module itself has been modified
diff --git a/ansible_collections/community/general/tests/integration/targets/monit/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/monit/defaults/main.yml
new file mode 100644
index 000000000..ec064643c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/monit/defaults/main.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+process_root: /opt/httpd_echo
+process_file: "{{ process_root }}/httpd_echo.py"
+process_venv: "{{ process_root }}/venv"
+process_run_cmd: "{{ process_venv }}/bin/python {{ process_file }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/monit/files/httpd_echo.py b/ansible_collections/community/general/tests/integration/targets/monit/files/httpd_echo.py
new file mode 100644
index 000000000..cd77da26b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/monit/files/httpd_echo.py
@@ -0,0 +1,51 @@
+# Copyright (c) 2020, Simon Kelly <simongdkelly@gmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+import daemon
+
+try:
+ from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
+
+ def write_to_output(stream, content):
+ stream.write(content)
+except ImportError:
+ from http.server import BaseHTTPRequestHandler, HTTPServer
+
+ def write_to_output(stream, content):
+ stream.write(bytes(content, "utf-8"))
+
+
+hostname = "localhost"
+server_port = 8082
+
+
+class EchoServer(BaseHTTPRequestHandler):
+ def do_GET(self):
+ self.send_response(200)
+ self.send_header("Content-type", "text/plain")
+ self.end_headers()
+ write_to_output(self.wfile, self.path)
+
+
+def run_webserver():
+ webServer = HTTPServer((hostname, server_port), EchoServer)
+ print("Server started http://%s:%s" % (hostname, server_port))
+
+ try:
+ webServer.serve_forever()
+ except KeyboardInterrupt:
+ pass
+
+ webServer.server_close()
+ print("Server stopped.")
+
+
+if __name__ == "__main__":
+ context = daemon.DaemonContext()
+
+ with context:
+ run_webserver()
diff --git a/ansible_collections/community/general/tests/integration/targets/monit/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/monit/meta/main.yml
new file mode 100644
index 000000000..2d6cafb56
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/monit/meta/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
+ - setup_remote_constraints
diff --git a/ansible_collections/community/general/tests/integration/targets/monit/tasks/check_state.yml b/ansible_collections/community/general/tests/integration/targets/monit/tasks/check_state.yml
new file mode 100644
index 000000000..bc8eb7c81
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/monit/tasks/check_state.yml
@@ -0,0 +1,21 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: "{{ reason }} ('up')"
+ command: "curl -sf http://localhost:8082/hello"
+ when: service_state == 'up'
+ register: curl_result
+ until: not curl_result.failed
+ retries: 5
+ delay: 1
+
+- name: "{{ reason }} ('down')"
+ command: "curl -sf http://localhost:8082/hello"
+ register: curl_result
+ failed_when: curl_result == 0
+ when: service_state == 'down'
+ until: not curl_result.failed
+ retries: 5
+ delay: 1
diff --git a/ansible_collections/community/general/tests/integration/targets/monit/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/monit/tasks/main.yml
new file mode 100644
index 000000000..ea8595412
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/monit/tasks/main.yml
@@ -0,0 +1,99 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- block:
+ - name: Install EPEL repository (RHEL only)
+ include_role:
+ name: setup_epel
+ when:
+ - ansible_distribution in ['RedHat', 'CentOS']
+ - ansible_distribution_major_version is version('9', '<')
+
+ - name: create required directories
+ become: true
+ file:
+ path: "{{ item }}"
+ state: directory
+ loop:
+ - /var/lib/monit
+ - /var/run/monit
+ - "{{ process_root }}"
+
+ - name: install monit
+ become: true
+ package:
+ name: monit
+ state: present
+
+ - include_vars: '{{ item }}'
+ with_first_found:
+ - files:
+ - "{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_major_version }}.yml"
+ - '{{ ansible_os_family }}.yml'
+ - 'defaults.yml'
+
+ - name: monit config
+ become: true
+ template:
+ src: "monitrc.j2"
+ dest: "{{ monitrc }}"
+
+ - name: copy process file
+ become: true
+ copy:
+ src: httpd_echo.py
+ dest: "{{ process_file }}"
+
+ - name: Install virtualenv on CentOS 8
+ package:
+ name: virtualenv
+ state: present
+ when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '8'
+
+ - name: Install virtualenv on Arch Linux
+ pip:
+ name: virtualenv
+ state: present
+ when: ansible_os_family == 'Archlinux'
+
+ - name: install dependencies
+ pip:
+ name: "{{ item }}"
+ virtualenv: "{{ process_venv }}"
+ extra_args: "-c {{ remote_constraints }}"
+ loop:
+ - setuptools==44
+ - python-daemon
+
+ - name: restart monit
+ become: true
+ service:
+ name: monit
+ state: restarted
+
+ - include_tasks: test.yml
+
+ always:
+ - name: stop monit
+ become: true
+ service:
+ name: monit
+ state: stopped
+
+ - name: uninstall monit
+ become: true
+ package:
+ name: monit
+ state: absent
+
+ - name: remove process files
+ file:
+ path: "{{ process_root }}"
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/monit/tasks/test.yml b/ansible_collections/community/general/tests/integration/targets/monit/tasks/test.yml
new file mode 100644
index 000000000..42fd033c7
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/monit/tasks/test.yml
@@ -0,0 +1,33 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# order is important
+- import_tasks: test_reload_present.yml
+
+- import_tasks: test_state.yml
+ vars:
+ state: stopped
+ initial_state: up
+ expected_state: down
+
+- import_tasks: test_state.yml
+ vars:
+ state: started
+ initial_state: down
+ expected_state: up
+
+- import_tasks: test_state.yml
+ vars:
+ state: unmonitored
+ initial_state: up
+ expected_state: down
+
+- import_tasks: test_state.yml
+ vars:
+ state: monitored
+ initial_state: down
+ expected_state: up
+
+- import_tasks: test_errors.yml
diff --git a/ansible_collections/community/general/tests/integration/targets/monit/tasks/test_errors.yml b/ansible_collections/community/general/tests/integration/targets/monit/tasks/test_errors.yml
new file mode 100644
index 000000000..362672387
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/monit/tasks/test_errors.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Check an error occurs when wrong process name is used
+ monit:
+ name: missing
+ state: started
+ register: result
+ failed_when: result is not skip and (result is success or result is not failed)
diff --git a/ansible_collections/community/general/tests/integration/targets/monit/tasks/test_reload_present.yml b/ansible_collections/community/general/tests/integration/targets/monit/tasks/test_reload_present.yml
new file mode 100644
index 000000000..0bd6cd073
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/monit/tasks/test_reload_present.yml
@@ -0,0 +1,65 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: reload monit when process is missing
+ monit:
+ name: httpd_echo
+ state: reloaded
+ register: result
+
+- name: check that state is changed
+ assert:
+ that:
+ - result is success
+ - result is changed
+
+- name: test process not present
+ monit:
+ name: httpd_echo
+ state: present
+ timeout: 5
+ register: result
+ failed_when: result is not skip and result is success
+
+- name: test monitor missing process
+ monit:
+ name: httpd_echo
+ state: monitored
+ register: result
+ failed_when: result is not skip and result is success
+
+- name: start process
+ shell: "{{ process_run_cmd }}"
+
+- import_tasks: check_state.yml
+ vars:
+ reason: verify service running
+ service_state: "up"
+
+- name: add process config
+ blockinfile:
+ path: "{{ monitrc }}"
+ block: |
+ check process httpd_echo with matching "httpd_echo"
+ start program = "{{ process_run_cmd }}"
+ stop program = "/bin/sh -c 'kill `pgrep -f httpd_echo`'"
+ if failed host localhost port 8082 then restart
+
+- name: restart monit
+ service:
+ name: monit
+ state: restarted
+
+- name: test process present again
+ monit:
+ name: httpd_echo
+ state: present
+ register: result
+
+- name: check that state is unchanged
+ assert:
+ that:
+ - result is success
+ - result is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/monit/tasks/test_state.yml b/ansible_collections/community/general/tests/integration/targets/monit/tasks/test_state.yml
new file mode 100644
index 000000000..33a70c196
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/monit/tasks/test_state.yml
@@ -0,0 +1,38 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- import_tasks: check_state.yml
+ vars:
+ reason: verify initial service state
+ service_state: "{{ initial_state }}"
+
+- name: change httpd_echo process state to {{ state }}
+ monit:
+ name: httpd_echo
+ state: "{{ state }}"
+ register: result
+
+- name: check that state changed
+ assert:
+ that:
+ - result is success
+ - result is changed
+
+- import_tasks: check_state.yml
+ vars:
+ reason: check service state after action
+ service_state: "{{ expected_state }}"
+
+- name: try change state again to {{ state }}
+ monit:
+ name: httpd_echo
+ state: "{{ state }}"
+ register: result
+
+- name: check that state is not changed
+ assert:
+ that:
+ - result is success
+ - result is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/monit/templates/monitrc.j2 b/ansible_collections/community/general/tests/integration/targets/monit/templates/monitrc.j2
new file mode 100644
index 000000000..4f1a6e247
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/monit/templates/monitrc.j2
@@ -0,0 +1,19 @@
+{#
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+#}
+
+set daemon 2
+set logfile /var/log/monit.log
+set idfile /var/lib/monit/id
+set statefile /var/lib/monit/state
+set pidfile /var/run/monit.pid
+
+set eventqueue
+ basedir /var/lib/monit/events
+ slots 100
+
+set httpd port 2812 and
+ use address localhost
+ allow localhost
diff --git a/ansible_collections/community/general/tests/integration/targets/monit/vars/Alpine.yml b/ansible_collections/community/general/tests/integration/targets/monit/vars/Alpine.yml
new file mode 100644
index 000000000..773c9d985
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/monit/vars/Alpine.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+monitrc: "/etc/monitrc"
diff --git a/ansible_collections/community/general/tests/integration/targets/monit/vars/Archlinux.yml b/ansible_collections/community/general/tests/integration/targets/monit/vars/Archlinux.yml
new file mode 100644
index 000000000..773c9d985
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/monit/vars/Archlinux.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+monitrc: "/etc/monitrc"
diff --git a/ansible_collections/community/general/tests/integration/targets/monit/vars/CentOS-6.yml b/ansible_collections/community/general/tests/integration/targets/monit/vars/CentOS-6.yml
new file mode 100644
index 000000000..9ff9c2641
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/monit/vars/CentOS-6.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+monitrc: "/etc/monit.conf"
diff --git a/ansible_collections/community/general/tests/integration/targets/monit/vars/RedHat.yml b/ansible_collections/community/general/tests/integration/targets/monit/vars/RedHat.yml
new file mode 100644
index 000000000..773c9d985
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/monit/vars/RedHat.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+monitrc: "/etc/monitrc"
diff --git a/ansible_collections/community/general/tests/integration/targets/monit/vars/Suse.yml b/ansible_collections/community/general/tests/integration/targets/monit/vars/Suse.yml
new file mode 100644
index 000000000..773c9d985
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/monit/vars/Suse.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+monitrc: "/etc/monitrc"
diff --git a/ansible_collections/community/general/tests/integration/targets/monit/vars/defaults.yml b/ansible_collections/community/general/tests/integration/targets/monit/vars/defaults.yml
new file mode 100644
index 000000000..74c76c7c9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/monit/vars/defaults.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+monitrc: "/etc/monit/monitrc"
diff --git a/ansible_collections/community/general/tests/integration/targets/mqtt/aliases b/ansible_collections/community/general/tests/integration/targets/mqtt/aliases
new file mode 100644
index 000000000..c25e0b6d5
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/mqtt/aliases
@@ -0,0 +1,10 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+skip/aix
+skip/osx
+skip/macos
+skip/freebsd
+skip/rhel
diff --git a/ansible_collections/community/general/tests/integration/targets/mqtt/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/mqtt/meta/main.yml
new file mode 100644
index 000000000..a9c2068ed
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/mqtt/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_mosquitto
diff --git a/ansible_collections/community/general/tests/integration/targets/mqtt/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/mqtt/tasks/main.yml
new file mode 100644
index 000000000..0beb1b3b2
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/mqtt/tasks/main.yml
@@ -0,0 +1,14 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- include_tasks: ubuntu.yml
+ when:
+ - ansible_distribution == 'Ubuntu'
+ - ansible_distribution_release not in ['focal', 'jammy']
diff --git a/ansible_collections/community/general/tests/integration/targets/mqtt/tasks/ubuntu.yml b/ansible_collections/community/general/tests/integration/targets/mqtt/tasks/ubuntu.yml
new file mode 100644
index 000000000..0c0a12d04
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/mqtt/tasks/ubuntu.yml
@@ -0,0 +1,147 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install pip packages
+ pip:
+ name: paho-mqtt>=1.4.0
+ state: present
+
+- name: MQTT non-TLS endpoint
+ mqtt:
+ topic: /node/s/bar/blurb
+ payload: foo
+ qos: 1
+ client_id: me001
+ register: result
+
+- assert:
+ that:
+ - result is success
+
+- name: Send a test message to TLS1.1 endpoint, no client version specified
+ mqtt:
+ topic: /node/s/bar/blurb
+ payload: foo-tls
+ qos: 1
+ client_id: me001
+ ca_certs: /tls/ca_certificate.pem
+ certfile: /tls/client_certificate.pem
+ keyfile: /tls/client_key.pem
+ port: 8883
+ register: result
+
+- assert:
+ that:
+ - result is success
+
+- name: Send a test message to TLS1.2 endpoint, no client version specified
+ mqtt:
+ topic: /node/s/bar/blurb
+ payload: foo-tls
+ qos: 1
+ client_id: me001
+ ca_certs: /tls/ca_certificate.pem
+ certfile: /tls/client_certificate.pem
+ keyfile: /tls/client_key.pem
+ port: 8884
+ register: result
+
+- assert:
+ that:
+ - result is success
+
+# TODO(Uncomment when TLS1.3 is supported in moquitto and ubuntu version)
+#
+# - name: Send a test message to TLS1.3 endpoint
+# mqtt:
+# topic: /node/s/bar/blurb
+# payload: foo-tls
+# qos: 1
+# client_id: me001
+# ca_certs: /tls/ca_certificate.pem
+# certfile: /tls/client_certificate.pem
+# keyfile: /tls/client_key.pem
+# port: 8885
+# register: result
+
+#- assert:
+# that:
+# - result is success
+
+- name: Send a message, client TLS1.1, server (required) TLS1.2 - Expected failure
+ mqtt:
+ topic: /node/s/bar/blurb
+ payload: foo-tls
+ qos: 1
+ client_id: me001
+ ca_certs: /tls/ca_certificate.pem
+ certfile: /tls/client_certificate.pem
+ keyfile: /tls/client_key.pem
+ tls_version: tlsv1.1
+ port: 8884
+ register: result
+ failed_when: result is success
+
+- assert:
+ that:
+ - result is success
+
+# TODO(Uncomment when TLS1.3 is supported in moquitto and ubuntu version)
+#
+# - name: Send a message, client TLS1.1, server (required) TLS1.3 - Expected failure
+# mqtt:
+# topic: /node/s/bar/blurb
+# payload: foo-tls
+# qos: 1
+# client_id: me001
+# ca_certs: /tls/ca_certificate.pem
+# certfile: /tls/client_certificate.pem
+# keyfile: /tls/client_key.pem
+# tls_version: tlsv1.1
+# port: 8885
+# register: result
+# failed_when: result is success
+
+# - assert:
+# that:
+# - result is success
+
+- name: Send a message, client TLS1.2, server (required) TLS1.1 - Expected failure
+ mqtt:
+ topic: /node/s/bar/blurb
+ payload: foo-tls
+ qos: 1
+ client_id: me001
+ ca_certs: /tls/ca_certificate.pem
+ certfile: /tls/client_certificate.pem
+ keyfile: /tls/client_key.pem
+ tls_version: tlsv1.2
+ port: 8883
+ register: result
+ failed_when: result is success
+
+- assert:
+ that:
+ - result is success
+
+# TODO(Uncomment when TLS1.3 is supported in moquitto and ubuntu version)
+#
+# - name: Send a message, client TLS1.2, server (required) TLS1.3 - Expected failure
+# mqtt:
+# topic: /node/s/bar/blurb
+# payload: foo-tls
+# qos: 1
+# client_id: me001
+# ca_certs: /tls/ca_certificate.pem
+# certfile: /tls/client_certificate.pem
+# keyfile: /tls/client_key.pem
+# tls_version: tlsv1.2
+# port: 8885
+# register: result
+# failed_when: result is success
+
+# - assert:
+# that:
+# - result is success
diff --git a/ansible_collections/community/general/tests/integration/targets/mssql_script/aliases b/ansible_collections/community/general/tests/integration/targets/mssql_script/aliases
new file mode 100644
index 000000000..023e2edce
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/mssql_script/aliases
@@ -0,0 +1,10 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+skip/osx
+skip/macos
+skip/freebsd
+skip/rhel
+disabled
+destructive
diff --git a/ansible_collections/community/general/tests/integration/targets/mssql_script/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/mssql_script/defaults/main.yml
new file mode 100644
index 000000000..d1ca77f55
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/mssql_script/defaults/main.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+mssql_host: localhost
+mssql_port: 1433
+mssql_login_user: sa
+mssql_login_password: "Abcd!234"
diff --git a/ansible_collections/community/general/tests/integration/targets/mssql_script/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/mssql_script/meta/main.yml
new file mode 100644
index 000000000..5769ff1cb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/mssql_script/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_docker
diff --git a/ansible_collections/community/general/tests/integration/targets/mssql_script/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/mssql_script/tasks/main.yml
new file mode 100644
index 000000000..6fa4d3501
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/mssql_script/tasks/main.yml
@@ -0,0 +1,246 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# TODO: Find out how to setup mssql server for tests
+# For the moment you have to run the tests locally
+# docker run --name mssql-test -e "ACCEPT_EULA=Y" -e 'SA_PASSWORD={{ mssql_login_password }}' -p "{ mssql_port }"0:"{ mssql_port }" -d mcr.microsoft.com/mssql/server:2019-latest
+# ansible-test integration mssql_script -v --allow-disabled
+
+- name: Install pymssql
+ ansible.builtin.pip:
+ name:
+ - pymssql
+ state: present
+
+- name: Start container
+ community.docker.docker_container:
+ name: mssql-test
+ image: "mcr.microsoft.com/mssql/server:2019-latest"
+ env:
+ ACCEPT_EULA: "Y"
+ SA_PASSWORD: "{{ mssql_login_password }}"
+ MSSQL_PID: Developer
+ ports:
+ - "{{ mssql_port }}:1433"
+ detach: true
+ auto_remove: true
+ memory: 2200M
+
+- name: Check default ports
+ ansible.builtin.wait_for:
+ host: "{{ mssql_host }}"
+ port: "{{ mssql_port }}"
+ state: started # Port should be open
+ delay: 10 # Wait 10 secs before first check
+ timeout: 30 # Stop checking after timeout (sec)
+
+- name: Check DB connection
+ community.general.mssql_script:
+ login_user: "{{ mssql_login_user }}"
+ login_password: "{{ mssql_login_password }}"
+ login_host: "{{ mssql_host }}"
+ login_port: "{{ mssql_port }}"
+ script: "SELECT 1"
+
+- name: two batches with default output
+ community.general.mssql_script:
+ login_user: "{{ mssql_login_user }}"
+ login_password: "{{ mssql_login_password }}"
+ login_host: "{{ mssql_host }}"
+ login_port: "{{ mssql_port }}"
+ script: |
+ SELECT 'Batch 0 - Select 0'
+ SELECT 'Batch 0 - Select 1'
+ GO
+ SELECT 'Batch 1 - Select 0'
+ register: result_batches
+# "result_batches.query_results":
+# [ # batches
+# [ # selects
+# [ # Rows
+# [ # Columns
+# "Batch 1 - Select 1"
+# ]
+# ],
+# [
+# [
+# "Batch 1 - Select 2"
+# ]
+# ]
+# ],
+# [
+# [
+# [
+# "Batch 2 - Select 1"
+# ]
+# ]
+# ]
+# ]
+
+- assert:
+ that:
+ - result_batches.query_results | length == 2 # two batch results
+ - result_batches.query_results[0] | length == 2 # two selects in first batch
+ - result_batches.query_results[0][0] | length == 1 # one row in first select
+ - result_batches.query_results[0][0][0] | length == 1 # one column in first row
+ - result_batches.query_results[0][0][0][0] == 'Batch 0 - Select 0' # first column of first row
+
+
+- name: two batches with dict output
+ community.general.mssql_script:
+ login_user: "{{ mssql_login_user }}"
+ login_password: "{{ mssql_login_password }}"
+ login_host: "{{ mssql_host }}"
+ login_port: "{{ mssql_port }}"
+ output: dict
+ script: |
+ SELECT 'Batch 0 - Select 0' as b0s0
+ SELECT 'Batch 0 - Select 1' as b0s1
+ GO
+ SELECT 'Batch 1 - Select 0' as b1s0
+ register: result_batches_dict
+# "result_batches_dict.query_results":
+# [ # batches
+# [ # selects
+# [ # Rows
+# { # dict columns
+# "b0s0": "Batch 0 - Select 0"
+# }
+# ],
+# [
+# {
+# "b0s1": "Batch 0 - Select 1"
+# }
+# ]
+# ],
+# [
+# [
+# {
+# "b1s0": "Batch 1 - Select 0"
+# }
+# ]
+# ]
+# ]
+- assert:
+ that:
+ - result_batches_dict.query_results_dict | length == 2 # two batch results
+ - result_batches_dict.query_results_dict[0] | length == 2 # two selects in first batch
+ - result_batches_dict.query_results_dict[0][0] | length == 1 # one row in first select
+ - result_batches_dict.query_results_dict[0][0][0]['b0s0'] == 'Batch 0 - Select 0' # column 'b0s0' of first row
+
+- name: Stored procedure may return multiple result sets
+ community.general.mssql_script:
+ login_user: "{{ mssql_login_user }}"
+ login_password: "{{ mssql_login_password }}"
+ login_host: "{{ mssql_host }}"
+ login_port: "{{ mssql_port }}"
+ script: sp_spaceused
+ output: dict
+ register: result_spaceused
+- assert:
+ that:
+ - result_spaceused.query_results_dict | length == 1 # one batch
+ - result_spaceused.query_results_dict[0] | length == 2 # stored procedure returns two result sets
+ - result_spaceused.query_results_dict[0][0][0]['database_name'] == 'master' # output dict
+
+- name: Ensure that passed 'db' is used
+ community.general.mssql_script:
+ login_user: "{{ mssql_login_user }}"
+ login_password: "{{ mssql_login_password }}"
+ login_host: "{{ mssql_host }}"
+ login_port: "{{ mssql_port }}"
+ script: exec sp_spaceused
+ output: dict
+ db: msdb
+ register: result_db
+- assert:
+ that:
+ - result_db.query_results_dict[0][0][0]['database_name'] == 'msdb'
+
+- name: pass params to query
+ community.general.mssql_script:
+ login_user: "{{ mssql_login_user }}"
+ login_password: "{{ mssql_login_password }}"
+ login_host: "{{ mssql_host }}"
+ login_port: "{{ mssql_port }}"
+ script: |
+ SELECT name, state_desc FROM sys.databases WHERE name = %(dbname)s
+ params:
+ dbname: msdb
+ register: result_params
+- assert:
+ that:
+ - result_params.query_results[0][0][0][0] == 'msdb'
+ - result_params.query_results[0][0][0][1] == 'ONLINE'
+
+- name: check_mode connects but does not run the query
+ community.general.mssql_script:
+ login_user: "{{ mssql_login_user }}"
+ login_password: "{{ mssql_login_password }}"
+ login_host: "{{ mssql_host }}"
+ login_port: "{{ mssql_port }}"
+ script: SELECT Invalid_Column FROM Does_Not_Exist WITH Invalid Syntax
+ check_mode: true
+ register: check_mode
+- assert:
+ that: check_mode.query_results is undefined
+
+- name: "Test: Value of unknown type: <class 'uuid.UUID'>"
+ community.general.mssql_script:
+ login_user: "{{ mssql_login_user }}"
+ login_password: "{{ mssql_login_password }}"
+ login_host: "{{ mssql_host }}"
+ login_port: "{{ mssql_port }}"
+ script: |
+ SELECT service_broker_guid, * FROM sys.databases WHERE name = 'master'
+ register: result_databases
+- debug:
+ var: result_databases
+- name: check types
+ assert:
+ that:
+ - result_databases.query_results[0][0][0][0] == '00000000-0000-0000-0000-000000000000' # guid
+ - result_databases.query_results[0][0][0][1] == 'master' # string
+ - result_databases.query_results[0][0][0][3] == None # byte string representation
+ - result_databases.query_results[0][0][0][4] == "b'\\x01'" # byte string representation
+ - result_databases.query_results[0][0][0][6] == 150 # int
+ - result_databases.query_results[0][0][0][10] == false # bool
+
+- name: "Test: Value of unknown type: <class 'uuid.UUID'>-dict"
+ community.general.mssql_script:
+ login_user: "{{ mssql_login_user }}"
+ login_password: "{{ mssql_login_password }}"
+ login_host: "{{ mssql_host }}"
+ login_port: "{{ mssql_port }}"
+ output: dict
+ script: |
+ SELECT service_broker_guid, * FROM sys.databases
+
+# Known issue: empty result set breaks return values
+- name: empty result set
+ community.general.mssql_script:
+ login_user: "{{ mssql_login_user }}"
+ login_password: "{{ mssql_login_password }}"
+ login_host: "{{ mssql_host }}"
+ login_port: "{{ mssql_port }}"
+ script: |
+ SELECT name, state_desc FROM sys.databases WHERE name = %(dbname)s
+ SELECT name, state_desc FROM sys.databases WHERE name = 'DoesNotexist'
+ SELECT name, state_desc FROM sys.databases WHERE name = %(dbname)s
+ params:
+ dbname: msdb
+ register: empty_result
+- assert:
+ that:
+ - empty_result.query_results[0] | length == 3 # == 1 ; issue: only first result is returned
+ - empty_result.query_results[0][0][0][0] == 'msdb'
+ - empty_result.query_results[0][1] | length == 0
+ - empty_result.query_results[0][2][0][0] == 'msdb'
+ failed_when: false # known issue
diff --git a/ansible_collections/community/general/tests/integration/targets/nomad/aliases b/ansible_collections/community/general/tests/integration/targets/nomad/aliases
new file mode 100644
index 000000000..ad2435c82
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/nomad/aliases
@@ -0,0 +1,10 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+nomad_job_info
+destructive
+skip/aix
+skip/centos6
+skip/freebsd
diff --git a/ansible_collections/community/general/tests/integration/targets/nomad/files/job.hcl b/ansible_collections/community/general/tests/integration/targets/nomad/files/job.hcl
new file mode 100644
index 000000000..8f01f0439
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/nomad/files/job.hcl
@@ -0,0 +1,400 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# There can only be a single job definition per file. This job is named
+# "example" so it will create a job with the ID and Name "example".
+
+# The "job" stanza is the top-most configuration option in the job
+# specification. A job is a declarative specification of tasks that Nomad
+# should run. Jobs have a globally unique name, one or many task groups, which
+# are themselves collections of one or many tasks.
+#
+# For more information and examples on the "job" stanza, please see
+# the online documentation at:
+#
+#
+# https://www.nomadproject.io/docs/job-specification/job.html
+#
+job "example" {
+ # The "region" parameter specifies the region in which to execute the job.
+ # If omitted, this inherits the default region name of "global".
+ # region = "global"
+ #
+ # The "datacenters" parameter specifies the list of datacenters which should
+ # be considered when placing this task. This must be provided.
+ datacenters = ["dc1"]
+
+ # The "type" parameter controls the type of job, which impacts the scheduler's
+ # decision on placement. This configuration is optional and defaults to
+ # "service". For a full list of job types and their differences, please see
+ # the online documentation.
+ #
+ # For more information, please see the online documentation at:
+ #
+ # https://www.nomadproject.io/docs/jobspec/schedulers.html
+ #
+ type = "service"
+
+
+ # The "constraint" stanza defines additional constraints for placing this job,
+ # in addition to any resource or driver constraints. This stanza may be placed
+ # at the "job", "group", or "task" level, and supports variable interpolation.
+ #
+ # For more information and examples on the "constraint" stanza, please see
+ # the online documentation at:
+ #
+ # https://www.nomadproject.io/docs/job-specification/constraint.html
+ #
+ # constraint {
+ # attribute = "${attr.kernel.name}"
+ # value = "linux"
+ # }
+
+ # The "update" stanza specifies the update strategy of task groups. The update
+ # strategy is used to control things like rolling upgrades, canaries, and
+ # blue/green deployments. If omitted, no update strategy is enforced. The
+ # "update" stanza may be placed at the job or task group. When placed at the
+ # job, it applies to all groups within the job. When placed at both the job and
+ # group level, the stanzas are merged with the group's taking precedence.
+ #
+ # For more information and examples on the "update" stanza, please see
+ # the online documentation at:
+ #
+ # https://www.nomadproject.io/docs/job-specification/update.html
+ #
+ update {
+ # The "max_parallel" parameter specifies the maximum number of updates to
+ # perform in parallel. In this case, this specifies to update a single task
+ # at a time.
+ max_parallel = 1
+
+ # The "min_healthy_time" parameter specifies the minimum time the allocation
+ # must be in the healthy state before it is marked as healthy and unblocks
+ # further allocations from being updated.
+ min_healthy_time = "10s"
+
+ # The "healthy_deadline" parameter specifies the deadline in which the
+ # allocation must be marked as healthy after which the allocation is
+ # automatically transitioned to unhealthy. Transitioning to unhealthy will
+ # fail the deployment and potentially roll back the job if "auto_revert" is
+ # set to true.
+ healthy_deadline = "3m"
+
+ # The "progress_deadline" parameter specifies the deadline in which an
+ # allocation must be marked as healthy. The deadline begins when the first
+ # allocation for the deployment is created and is reset whenever an allocation
+ # as part of the deployment transitions to a healthy state. If no allocation
+ # transitions to the healthy state before the progress deadline, the
+ # deployment is marked as failed.
+ progress_deadline = "10m"
+
+ # The "auto_revert" parameter specifies if the job should auto-revert to the
+ # last stable job on deployment failure. A job is marked as stable if all the
+ # allocations as part of its deployment were marked healthy.
+ auto_revert = false
+
+ # The "canary" parameter specifies that changes to the job that would result
+ # in destructive updates should create the specified number of canaries
+ # without stopping any previous allocations. Once the operator determines the
+ # canaries are healthy, they can be promoted which unblocks a rolling update
+ # of the remaining allocations at a rate of "max_parallel".
+ #
+ # Further, setting "canary" equal to the count of the task group allows
+ # blue/green deployments. When the job is updated, a full set of the new
+ # version is deployed and upon promotion the old version is stopped.
+ canary = 0
+ }
+ # The migrate stanza specifies the group's strategy for migrating off of
+ # draining nodes. If omitted, a default migration strategy is applied.
+ #
+ # For more information on the "migrate" stanza, please see
+ # the online documentation at:
+ #
+ # https://www.nomadproject.io/docs/job-specification/migrate.html
+ #
+ migrate {
+ # Specifies the number of task groups that can be migrated at the same
+ # time. This number must be less than the total count for the group as
+ # (count - max_parallel) will be left running during migrations.
+ max_parallel = 1
+
+ # Specifies the mechanism in which allocations health is determined. The
+ # potential values are "checks" or "task_states".
+ health_check = "checks"
+
+ # Specifies the minimum time the allocation must be in the healthy state
+ # before it is marked as healthy and unblocks further allocations from being
+ # migrated. This is specified using a label suffix like "30s" or "15m".
+ min_healthy_time = "10s"
+
+ # Specifies the deadline in which the allocation must be marked as healthy
+ # after which the allocation is automatically transitioned to unhealthy. This
+ # is specified using a label suffix like "2m" or "1h".
+ healthy_deadline = "5m"
+ }
+ # The "group" stanza defines a series of tasks that should be co-located on
+ # the same Nomad client. Any task within a group will be placed on the same
+ # client.
+ #
+ # For more information and examples on the "group" stanza, please see
+ # the online documentation at:
+ #
+ # https://www.nomadproject.io/docs/job-specification/group.html
+ #
+ group "cache" {
+ # The "count" parameter specifies the number of the task groups that should
+ # be running under this group. This value must be non-negative and defaults
+ # to 1.
+ count = 1
+
+ # The "restart" stanza configures a group's behavior on task failure. If
+ # left unspecified, a default restart policy is used based on the job type.
+ #
+ # For more information and examples on the "restart" stanza, please see
+ # the online documentation at:
+ #
+ # https://www.nomadproject.io/docs/job-specification/restart.html
+ #
+ restart {
+ # The number of attempts to run the job within the specified interval.
+ attempts = 2
+ interval = "30m"
+
+ # The "delay" parameter specifies the duration to wait before restarting
+ # a task after it has failed.
+ delay = "15s"
+
+ # The "mode" parameter controls what happens when a task has restarted
+ # "attempts" times within the interval. "delay" mode delays the next
+ # restart until the next interval. "fail" mode does not restart the task
+ # if "attempts" has been hit within the interval.
+ mode = "fail"
+ }
+
+ # The "ephemeral_disk" stanza instructs Nomad to utilize an ephemeral disk
+ # instead of a hard disk requirement. Clients using this stanza should
+ # not specify disk requirements in the resources stanza of the task. All
+ # tasks in this group will share the same ephemeral disk.
+ #
+ # For more information and examples on the "ephemeral_disk" stanza, please
+ # see the online documentation at:
+ #
+ # https://www.nomadproject.io/docs/job-specification/ephemeral_disk.html
+ #
+ ephemeral_disk {
+ # When sticky is true and the task group is updated, the scheduler
+ # will prefer to place the updated allocation on the same node and
+ # will migrate the data. This is useful for tasks that store data
+ # that should persist across allocation updates.
+ # sticky = true
+ #
+ # Setting migrate to true results in the allocation directory of a
+ # sticky allocation directory to be migrated.
+ # migrate = true
+ #
+ # The "size" parameter specifies the size in MB of shared ephemeral disk
+ # between tasks in the group.
+ size = 300
+ }
+
+ # The "affinity" stanza enables operators to express placement preferences
+ # based on node attributes or metadata.
+ #
+ # For more information and examples on the "affinity" stanza, please
+ # see the online documentation at:
+ #
+ # https://www.nomadproject.io/docs/job-specification/affinity.html
+ #
+ # affinity {
+ # attribute specifies the name of a node attribute or metadata
+ # attribute = "${node.datacenter}"
+
+
+ # value specifies the desired attribute value. In this example Nomad
+ # will prefer placement in the "us-west1" datacenter.
+ # value = "us-west1"
+
+
+ # weight can be used to indicate relative preference
+ # when the job has more than one affinity. It defaults to 50 if not set.
+ # weight = 100
+ # }
+
+
+ # The "spread" stanza allows operators to increase the failure tolerance of
+ # their applications by specifying a node attribute that allocations
+ # should be spread over.
+ #
+ # For more information and examples on the "spread" stanza, please
+ # see the online documentation at:
+ #
+ # https://www.nomadproject.io/docs/job-specification/spread.html
+ #
+ # spread {
+ # attribute specifies the name of a node attribute or metadata
+ # attribute = "${node.datacenter}"
+
+
+ # targets can be used to define desired percentages of allocations
+ # for each targeted attribute value.
+ #
+ # target "us-east1" {
+ # percent = 60
+ # }
+ # target "us-west1" {
+ # percent = 40
+ # }
+ # }
+
+ # The "task" stanza creates an individual unit of work, such as a Docker
+ # container, web application, or batch processing.
+ #
+ # For more information and examples on the "task" stanza, please see
+ # the online documentation at:
+ #
+ # https://www.nomadproject.io/docs/job-specification/task.html
+ #
+ task "redis" {
+ # The "driver" parameter specifies the task driver that should be used to
+ # run the task.
+ driver = "docker"
+
+ # The "config" stanza specifies the driver configuration, which is passed
+ # directly to the driver to start the task. The details of configurations
+ # are specific to each driver, so please see specific driver
+ # documentation for more information.
+ config {
+ image = "redis:3.2"
+
+ port_map {
+ db = 6379
+ }
+ }
+
+ # The "artifact" stanza instructs Nomad to download an artifact from a
+ # remote source prior to starting the task. This provides a convenient
+ # mechanism for downloading configuration files or data needed to run the
+ # task. It is possible to specify the "artifact" stanza multiple times to
+ # download multiple artifacts.
+ #
+ # For more information and examples on the "artifact" stanza, please see
+ # the online documentation at:
+ #
+ # https://www.nomadproject.io/docs/job-specification/artifact.html
+ #
+ # artifact {
+ # source = "http://foo.com/artifact.tar.gz"
+ # options {
+ # checksum = "md5:c4aa853ad2215426eb7d70a21922e794"
+ # }
+ # }
+
+
+ # The "logs" stanza instructs the Nomad client on how many log files and
+ # the maximum size of those logs files to retain. Logging is enabled by
+ # default, but the "logs" stanza allows for finer-grained control over
+ # the log rotation and storage configuration.
+ #
+ # For more information and examples on the "logs" stanza, please see
+ # the online documentation at:
+ #
+ # https://www.nomadproject.io/docs/job-specification/logs.html
+ #
+ # logs {
+ # max_files = 10
+ # max_file_size = 15
+ # }
+
+ # The "resources" stanza describes the requirements a task needs to
+ # execute. Resource requirements include memory, network, cpu, and more.
+ # This ensures the task will execute on a machine that contains enough
+ # resource capacity.
+ #
+ # For more information and examples on the "resources" stanza, please see
+ # the online documentation at:
+ #
+ # https://www.nomadproject.io/docs/job-specification/resources.html
+ #
+ resources {
+ cpu = 500 # 500 MHz
+ memory = 256 # 256MB
+
+ network {
+ mbits = 10
+ port "db" {}
+ }
+ }
+ # The "service" stanza instructs Nomad to register this task as a service
+ # in the service discovery engine, which is currently Consul. This will
+ # make the service addressable after Nomad has placed it on a host and
+ # port.
+ #
+ # For more information and examples on the "service" stanza, please see
+ # the online documentation at:
+ #
+ # https://www.nomadproject.io/docs/job-specification/service.html
+ #
+ service {
+ name = "redis-cache"
+ tags = ["global", "cache"]
+ port = "db"
+
+ check {
+ name = "alive"
+ type = "tcp"
+ interval = "10s"
+ timeout = "2s"
+ }
+ }
+
+ # The "template" stanza instructs Nomad to manage a template, such as
+ # a configuration file or script. This template can optionally pull data
+ # from Consul or Vault to populate runtime configuration data.
+ #
+ # For more information and examples on the "template" stanza, please see
+ # the online documentation at:
+ #
+ # https://www.nomadproject.io/docs/job-specification/template.html
+ #
+ # template {
+ # data = "---\nkey: {{ key \"service/my-key\" }}"
+ # destination = "local/file.yml"
+ # change_mode = "signal"
+ # change_signal = "SIGHUP"
+ # }
+
+ # The "template" stanza can also be used to create environment variables
+ # for tasks that prefer those to config files. The task will be restarted
+ # when data pulled from Consul or Vault changes.
+ #
+ # template {
+ # data = "KEY={{ key \"service/my-key\" }}"
+ # destination = "local/file.env"
+ # env = true
+ # }
+
+ # The "vault" stanza instructs the Nomad client to acquire a token from
+ # a HashiCorp Vault server. The Nomad servers must be configured and
+ # authorized to communicate with Vault. By default, Nomad will inject
+ # The token into the job via an environment variable and make the token
+ # available to the "template" stanza. The Nomad client handles the renewal
+ # and revocation of the Vault token.
+ #
+ # For more information and examples on the "vault" stanza, please see
+ # the online documentation at:
+ #
+ # https://www.nomadproject.io/docs/job-specification/vault.html
+ #
+ # vault {
+ # policies = ["cdn", "frontend"]
+ # change_mode = "signal"
+ # change_signal = "SIGHUP"
+ # }
+
+ # Controls the timeout between signalling a task it will be killed
+ # and killing the task. If not set a default is used.
+ # kill_timeout = "20s"
+ }
+ }
+}
diff --git a/ansible_collections/community/general/tests/integration/targets/nomad/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/nomad/meta/main.yml
new file mode 100644
index 000000000..0909be206
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/nomad/meta/main.yml
@@ -0,0 +1,10 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
+ - setup_openssl
+ - setup_remote_tmp_dir
+ - setup_remote_constraints
diff --git a/ansible_collections/community/general/tests/integration/targets/nomad/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/nomad/tasks/main.yml
new file mode 100644
index 000000000..1a143be05
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/nomad/tasks/main.yml
@@ -0,0 +1,111 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Skip unsupported platforms
+ meta: end_play
+ # TODO: figure out why Alpine does not work!
+ when: |
+ ansible_distribution == 'CentOS' and ansible_distribution_major_version is not version('7', '>=')
+ or ansible_distribution == 'Alpine'
+
+- name: Install Nomad and test
+ vars:
+ nomad_version: 0.12.4
+ nomad_uri: https://releases.hashicorp.com/nomad/{{ nomad_version }}/nomad_{{ nomad_version }}_{{ ansible_system | lower }}_{{ nomad_arch }}.zip
+ nomad_cmd: '{{ remote_tmp_dir }}/nomad'
+ block:
+
+ - name: Install requests<2.20 (CentOS/RHEL 6)
+ pip:
+ name: requests<2.20
+ extra_args: "-c {{ remote_constraints }}"
+ register: result
+ until: result is success
+ when: ansible_distribution_file_variety|default() == 'RedHat' and ansible_distribution_major_version is version('6', '<=')
+
+ - name: Install python-nomad
+ pip:
+ name: python-nomad
+ extra_args: "-c {{ remote_constraints }}"
+ register: result
+ until: result is success
+
+ - name: Install jmespath
+ pip:
+ name: jmespath
+ extra_args: "-c {{ remote_constraints }}"
+ register: result
+ until: result is success
+
+ - name: Generate privatekey
+ community.crypto.openssl_privatekey:
+ path: '{{ remote_tmp_dir }}/privatekey.pem'
+
+ - name: Generate CSR
+ community.crypto.openssl_csr:
+ path: '{{ remote_tmp_dir }}/csr.csr'
+ privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
+ subject:
+ commonName: localhost
+
+ - name: Generate selfsigned certificate
+ register: selfsigned_certificate
+ community.crypto.x509_certificate:
+ path: '{{ remote_tmp_dir }}/cert.pem'
+ csr_path: '{{ remote_tmp_dir }}/csr.csr'
+ privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
+ provider: selfsigned
+ selfsigned_digest: sha256
+
+ - name: Install unzip
+ package:
+ name: unzip
+ register: result
+ until: result is success
+ when: ansible_distribution != "MacOSX"
+
+ - assert:
+ that: ansible_architecture in ['i386', 'x86_64', 'amd64']
+
+ - set_fact:
+ nomad_arch: '386'
+ when: ansible_architecture == 'i386'
+
+ - set_fact:
+ nomad_arch: amd64
+ when: ansible_architecture in ['x86_64', 'amd64']
+
+ - name: Download nomad binary
+ unarchive:
+ src: '{{ nomad_uri }}'
+ dest: '{{ remote_tmp_dir }}'
+ remote_src: true
+ register: result
+ until: result is success
+
+ - vars:
+ remote_dir: '{{ echo_remote_tmp_dir.stdout }}'
+ block:
+
+ - command: echo {{ remote_tmp_dir }}
+ register: echo_remote_tmp_dir
+
+ - name: Run tests integration
+ block:
+ - name: Start nomad (dev mode enabled)
+ shell: nohup {{ nomad_cmd }} agent -dev </dev/null >/dev/null 2>&1 &
+
+ - name: wait nomad up
+ wait_for:
+ host: localhost
+ port: 4646
+ delay: 10
+ timeout: 60
+
+ - import_tasks: nomad_job.yml
+ always:
+
+ - name: kill nomad
+ shell: pkill nomad
diff --git a/ansible_collections/community/general/tests/integration/targets/nomad/tasks/nomad_job.yml b/ansible_collections/community/general/tests/integration/targets/nomad/tasks/nomad_job.yml
new file mode 100644
index 000000000..2a4f223aa
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/nomad/tasks/nomad_job.yml
@@ -0,0 +1,111 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: run check deploy nomad job
+ nomad_job:
+ host: localhost
+ state: present
+ use_ssl: false
+ content: "{{ lookup('file', 'job.hcl') }}"
+ register: job_check_deployed
+ check_mode: true
+
+- name: run create nomad job
+ nomad_job:
+ host: localhost
+ state: present
+ use_ssl: false
+ content: "{{ lookup('file', 'job.hcl') }}"
+ force_start: true
+ register: job_deployed
+
+- name: get nomad job deployed
+ nomad_job_info:
+ host: localhost
+ use_ssl: false
+ name: example
+ register: get_nomad_job
+
+- name: get list of nomad jobs
+ nomad_job_info:
+ host: localhost
+ use_ssl: false
+ register: list_nomad_jobs
+
+- name: assert job is deployed and tasks is changed
+ assert:
+ that:
+ - job_check_deployed is changed
+ - job_deployed is changed
+ - get_nomad_job.result[0].ID == "example"
+ - list_nomad_jobs.result | length == 1
+
+- name: run check deploy job idempotence
+ nomad_job:
+ host: localhost
+ state: present
+ use_ssl: false
+ content: "{{ lookup('file', 'job.hcl') }}"
+ register: job_check_deployed_idempotence
+ check_mode: true
+
+- name: run create nomad job idempotence
+ nomad_job:
+ host: localhost
+ state: present
+ use_ssl: false
+ content: "{{ lookup('file', 'job.hcl') }}"
+ register: job_deployed_idempotence
+
+- name: get list of nomad jobs
+ nomad_job_info:
+ host: localhost
+ use_ssl: false
+ register: list_nomad_jobs
+
+- debug:
+ msg: "{{ list_nomad_jobs }}"
+
+- name: run check delete nomad job
+ nomad_job:
+ host: localhost
+ state: absent
+ use_ssl: false
+ content: "{{ lookup('file', 'job.hcl') }}"
+ register: job_deleted_check
+ check_mode: true
+
+- name: run delete nomad job
+ nomad_job:
+ host: localhost
+ state: absent
+ use_ssl: false
+ content: "{{ lookup('file', 'job.hcl') }}"
+ register: job_deleted
+
+- name: get job deleted
+ nomad_job_info:
+ host: localhost
+ use_ssl: false
+ name: example
+ register: get_job_delete
+
+- name: get list of nomad jobs
+ nomad_job_info:
+ host: localhost
+ use_ssl: false
+ register: list_nomad_jobs
+
+- debug:
+ msg: "{{ list_nomad_jobs }}"
+
+- name: assert idempotence
+ assert:
+ that:
+ - job_check_deployed_idempotence is not changed
+ - job_deployed_idempotence is not changed
+ - job_deleted_check is changed
+ - job_deleted is changed
+ - get_job_delete.result[0].Stop
diff --git a/ansible_collections/community/general/tests/integration/targets/npm/aliases b/ansible_collections/community/general/tests/integration/targets/npm/aliases
new file mode 100644
index 000000000..6e2c65f38
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/npm/aliases
@@ -0,0 +1,8 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+destructive
+skip/aix
+skip/freebsd
diff --git a/ansible_collections/community/general/tests/integration/targets/npm/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/npm/meta/main.yml
new file mode 100644
index 000000000..6147ad33e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/npm/meta/main.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
+ - setup_gnutar
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/npm/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/npm/tasks/main.yml
new file mode 100644
index 000000000..500e15fdb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/npm/tasks/main.yml
@@ -0,0 +1,32 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# test code for the npm module
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# -------------------------------------------------------------
+# Setup steps
+
+- when:
+ - not (ansible_os_family == 'Alpine') # TODO
+ block:
+
+ # expand remote path
+ - command: 'echo {{ remote_tmp_dir }}'
+ register: echo
+ - set_fact:
+ remote_dir: '{{ echo.stdout }}'
+
+ - include_tasks: run.yml
+ vars:
+ nodejs_version: '{{ item }}'
+ nodejs_path: 'node-v{{ nodejs_version }}-{{ ansible_system|lower }}-x{{ ansible_userspace_bits }}'
+ with_items:
+ - 7.10.1 # provides npm 4.2.0 (last npm < 5 released)
+ - 8.0.0 # provides npm 5.0.0
+ - 8.2.0 # provides npm 5.3.0 (output change with this version)
diff --git a/ansible_collections/community/general/tests/integration/targets/npm/tasks/no_bin_links.yml b/ansible_collections/community/general/tests/integration/targets/npm/tasks/no_bin_links.yml
new file mode 100644
index 000000000..3588f7642
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/npm/tasks/no_bin_links.yml
@@ -0,0 +1,68 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: 'Remove any node modules'
+ file:
+ path: '{{ remote_dir }}/node_modules'
+ state: absent
+
+- vars:
+ # sample: node-v8.2.0-linux-x64.tar.xz
+ node_path: '{{ remote_dir }}/{{ nodejs_path }}/bin'
+ package: 'ncp'
+ block:
+ - shell: npm --version
+ environment:
+ PATH: '{{ node_path }}:{{ ansible_env.PATH }}'
+ register: npm_version
+
+ - debug:
+ var: npm_version.stdout
+
+ - name: 'Install simple package with no_bin_links disabled'
+ npm:
+ path: '{{ remote_dir }}'
+ executable: '{{ node_path }}/npm'
+ state: present
+ name: '{{ package }}'
+ no_bin_links: false
+ environment:
+ PATH: '{{ node_path }}:{{ ansible_env.PATH }}'
+ register: npm_install_no_bin_links_disabled
+
+ - name: 'Make sure .bin folder has been created'
+ stat:
+ path: "{{ remote_dir }}/node_modules/.bin"
+ register: npm_dotbin_folder_disabled
+
+ - name: 'Remove any node modules'
+ file:
+ path: '{{ remote_dir }}/node_modules'
+ state: absent
+
+ - name: 'Install simple package with no_bin_links enabled'
+ npm:
+ path: '{{ remote_dir }}'
+ executable: '{{ node_path }}/npm'
+ state: present
+ name: '{{ package }}'
+ no_bin_links: true
+ environment:
+ PATH: '{{ node_path }}:{{ ansible_env.PATH }}'
+ register: npm_install_no_bin_links_enabled
+
+ - name: 'Make sure .bin folder has not been created'
+ stat:
+ path: "{{ remote_dir }}/node_modules/.bin"
+ register: npm_dotbin_folder_enabled
+
+ - assert:
+ that:
+ - npm_install_no_bin_links_disabled is success
+ - npm_install_no_bin_links_disabled is changed
+ - npm_install_no_bin_links_enabled is success
+ - npm_install_no_bin_links_enabled is changed
+ - npm_dotbin_folder_disabled.stat.exists
+ - not npm_dotbin_folder_enabled.stat.exists
diff --git a/ansible_collections/community/general/tests/integration/targets/npm/tasks/run.yml b/ansible_collections/community/general/tests/integration/targets/npm/tasks/run.yml
new file mode 100644
index 000000000..9ce380270
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/npm/tasks/run.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- include_tasks: setup.yml
+- include_tasks: test.yml
+- include_tasks: no_bin_links.yml
diff --git a/ansible_collections/community/general/tests/integration/targets/npm/tasks/setup.yml b/ansible_collections/community/general/tests/integration/targets/npm/tasks/setup.yml
new file mode 100644
index 000000000..bad927915
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/npm/tasks/setup.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: 'Download NPM'
+ unarchive:
+ src: 'https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/npm/{{ nodejs_path }}.tar.gz'
+ dest: '{{ remote_tmp_dir }}'
+ remote_src: true
+ creates: '{{ remote_tmp_dir }}/{{ nodejs_path }}.tar.gz'
diff --git a/ansible_collections/community/general/tests/integration/targets/npm/tasks/test.yml b/ansible_collections/community/general/tests/integration/targets/npm/tasks/test.yml
new file mode 100644
index 000000000..c8e83f602
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/npm/tasks/test.yml
@@ -0,0 +1,74 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: 'Remove any node modules'
+ file:
+ path: '{{ remote_dir }}/node_modules'
+ state: absent
+
+- vars:
+ # sample: node-v8.2.0-linux-x64.tar.xz
+ node_path: '{{ remote_dir }}/{{ nodejs_path }}/bin'
+ package: 'iconv-lite'
+ block:
+ - shell: npm --version
+ environment:
+ PATH: '{{ node_path }}:{{ ansible_env.PATH }}'
+ register: npm_version
+
+ - debug:
+ var: npm_version.stdout
+
+ - name: 'Install simple package without dependency'
+ npm:
+ path: '{{ remote_dir }}'
+ executable: '{{ node_path }}/npm'
+ state: present
+ name: '{{ package }}'
+ environment:
+ PATH: '{{ node_path }}:{{ ansible_env.PATH }}'
+ register: npm_install
+
+ - assert:
+ that:
+ - npm_install is success
+ - npm_install is changed
+
+ - name: 'Reinstall simple package without dependency'
+ npm:
+ path: '{{ remote_dir }}'
+ executable: '{{ node_path }}/npm'
+ state: present
+ name: '{{ package }}'
+ environment:
+ PATH: '{{ node_path }}:{{ ansible_env.PATH }}'
+ register: npm_reinstall
+
+ - name: Check there is no change
+ assert:
+ that:
+ - npm_reinstall is success
+ - not (npm_reinstall is changed)
+
+ - name: 'Manually delete package'
+ file:
+ path: '{{ remote_dir }}/node_modules/{{ package }}'
+ state: absent
+
+ - name: 'reinstall simple package'
+ npm:
+ path: '{{ remote_dir }}'
+ executable: '{{ node_path }}/npm'
+ state: present
+ name: '{{ package }}'
+ environment:
+ PATH: '{{ node_path }}:{{ ansible_env.PATH }}'
+ register: npm_fix_install
+
+ - name: Check result is changed and successful
+ assert:
+ that:
+ - npm_fix_install is success
+ - npm_fix_install is changed
diff --git a/ansible_collections/community/general/tests/integration/targets/odbc/aliases b/ansible_collections/community/general/tests/integration/targets/odbc/aliases
new file mode 100644
index 000000000..e8465c50e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/odbc/aliases
@@ -0,0 +1,12 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+destructive
+skip/osx
+skip/macos
+skip/rhel8.0
+skip/rhel9.0
+skip/rhel9.1
+skip/freebsd
diff --git a/ansible_collections/community/general/tests/integration/targets/odbc/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/odbc/defaults/main.yml
new file mode 100644
index 000000000..dd75f5471
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/odbc/defaults/main.yml
@@ -0,0 +1,38 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# defaults file for test_postgresql_db
+my_user: 'ansible_user'
+my_pass: 'md5d5e044ccd9b4b8adc89e8fed2eb0db8a'
+my_pass_decrypted: '6EjMk<hcX3<5(Yp?Xi5aQ8eS`a#Ni'
+dsn: "DRIVER={PostgreSQL};Server=localhost;Port=5432;Database=postgres;Uid={{ my_user }};Pwd={{ my_pass_decrypted }};UseUnicode=True"
+packages:
+ Alpine:
+ - psqlodbc
+ - unixodbc
+ - unixodbc-dev
+ - g++
+ Archlinux:
+ - unixodbc
+ RedHat:
+ - postgresql-odbc
+ - unixODBC
+ - unixODBC-devel
+ - gcc
+ - gcc-c++
+ Debian:
+ - odbc-postgresql
+ - unixodbc
+ - unixodbc-dev
+ - gcc
+ - g++
+ Suse:
+ - psqlODBC
+ - unixODBC
+ - unixODBC-devel
+ - gcc
+ - gcc-c++
+ FreeBSD:
+ - unixODBC
diff --git a/ansible_collections/community/general/tests/integration/targets/odbc/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/odbc/meta/main.yml
new file mode 100644
index 000000000..0d06eaa39
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/odbc/meta/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
+ - setup_postgresql_db
diff --git a/ansible_collections/community/general/tests/integration/targets/odbc/tasks/install_pyodbc.yml b/ansible_collections/community/general/tests/integration/targets/odbc/tasks/install_pyodbc.yml
new file mode 100644
index 000000000..e0cefe14d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/odbc/tasks/install_pyodbc.yml
@@ -0,0 +1,12 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: "Install {{ ansible_os_family }} Libraries"
+ package:
+ name: "{{ packages[ansible_os_family] }}"
+
+- name: "Install pyodbc"
+ pip:
+ name: pyodbc
diff --git a/ansible_collections/community/general/tests/integration/targets/odbc/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/odbc/tasks/main.yml
new file mode 100644
index 000000000..ce55ea8aa
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/odbc/tasks/main.yml
@@ -0,0 +1,158 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- when:
+ - ansible_os_family != 'Archlinux' # TODO install driver from AUR: https://aur.archlinux.org/packages/psqlodbc
+ block:
+
+ #
+ # Test for proper failures without pyodbc
+ #
+ # Some of the docker images already have pyodbc installed on it
+ - include_tasks: no_pyodbc.yml
+ when: ansible_os_family != 'FreeBSD' and ansible_os_family != 'Suse' and ansible_os_family != 'Debian'
+
+ #
+ # Get pyodbc installed
+ #
+ - include_tasks: install_pyodbc.yml
+
+ #
+ # Test missing parameters & invalid DSN
+ #
+ - include_tasks: negative_tests.yml
+
+ #
+ # Setup DSN per env
+ #
+ - name: Changing DSN for Suse
+ set_fact:
+ dsn: "DRIVER={PSQL};Server=localhost;Port=5432;Database=postgres;Uid={{ my_user }};Pwd={{ my_pass_decrypted }};UseUnicode=True"
+ when: ansible_os_family == 'Suse' or ansible_os_family == 'Alpine'
+
+ - name: Changing DSN for Alpine
+ set_fact:
+ dsn: "DRIVER={/usr/lib/psqlodbcw.so};Server=localhost;Port=5432;Database=postgres;Uid={{ my_user }};Pwd={{ my_pass_decrypted }};UseUnicode=True"
+ when: ansible_os_family == 'Alpine'
+
+ - name: Changing DSN for Debian
+ set_fact:
+ dsn: "DRIVER={PostgreSQL Unicode};Server=localhost;Port=5432;Database=postgres;Uid={{ my_user }};Pwd={{ my_pass_decrypted }};UseUnicode=True"
+ when: ansible_os_family == 'Debian'
+
+ #
+ # Name setup database
+ #
+ - name: Create a user to run the tests with
+ shell: echo "CREATE USER {{ my_user }} SUPERUSER PASSWORD '{{ my_pass }}'" | psql postgres
+ become_user: "{{ pg_user }}"
+ become: true
+
+ - name: Create a table
+ odbc:
+ dsn: "{{ dsn }}"
+ query: |
+ CREATE TABLE films (
+ code char(5) CONSTRAINT firstkey PRIMARY KEY,
+ title varchar(40) NOT NULL,
+ did integer NOT NULL,
+ date_prod date,
+ kind varchar(10),
+ len interval hour to minute
+ );
+ become_user: "{{ pg_user }}"
+ become: true
+ register: results
+
+ - assert:
+ that:
+ - results is changed
+
+ #
+ # Insert records
+ #
+ - name: Insert a record without params
+ odbc:
+ dsn: "{{ dsn }}"
+ query: "INSERT INTO films (code, title, did, date_prod, kind, len) VALUES ('asdfg', 'My First Movie', 1, '2019-01-12', 'SyFi', '02:00')"
+ become_user: "{{ pg_user }}"
+ become: true
+ register: results
+
+ - assert:
+ that:
+ - results is changed
+
+ - name: Insert a record with params
+ odbc:
+ dsn: "{{ dsn }}"
+ query: "INSERT INTO films (code, title, did, date_prod, kind, len) VALUES (?, ?, ?, ?, ?, ?)"
+ params:
+ - 'qwert'
+ - 'My Second Movie'
+ - 2
+ - '2019-01-12'
+ - 'Comedy'
+ - '01:30'
+ become_user: "{{ pg_user }}"
+ become: true
+ register: results
+
+ - assert:
+ that:
+ - results is changed
+ - results['row_count'] == -1
+ - results['results'] == []
+ - results['description'] == []
+
+ #
+ # Select data
+ #
+ - name: Perform select single row without params (do not coherse changed)
+ odbc:
+ dsn: "{{ dsn }}"
+ query: "SELECT * FROM films WHERE code='asdfg'"
+ register: results
+
+ - assert:
+ that:
+ - results is changed
+ - results is successful
+ - results.row_count == 1
+
+ - name: Perform select multiple rows with params (coherse changed)
+ odbc:
+ dsn: "{{ dsn }}"
+ query: 'SELECT * FROM films WHERE code=? or code=?'
+ params:
+ - 'asdfg'
+ - 'qwert'
+ register: results
+ changed_when: false
+
+ - assert:
+ that:
+ - results is not changed
+ - results is successful
+ - results.row_count == 2
+
+ - name: Drop the table
+ odbc:
+ dsn: "{{ dsn }}"
+ query: "DROP TABLE films"
+ register: results
+
+ - assert:
+ that:
+ - results is successful
+ - results is changed
+ - results['row_count'] == -1
+ - results['results'] == []
+ - results['description'] == []
diff --git a/ansible_collections/community/general/tests/integration/targets/odbc/tasks/negative_tests.yml b/ansible_collections/community/general/tests/integration/targets/odbc/tasks/negative_tests.yml
new file mode 100644
index 000000000..f779e6a53
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/odbc/tasks/negative_tests.yml
@@ -0,0 +1,24 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+#
+# Missing params for the module
+# There is nothing you need to do here because the params are required
+#
+
+#
+# Invalid DSN in the module
+#
+- name: "Test with an invalid DSN"
+ odbc:
+ dsn: "t1"
+ query: "SELECT * FROM nothing"
+ register: results
+ ignore_errors: true
+
+- assert:
+ that:
+ - results is failed
+ - "'Failed to connect to DSN' in results.msg"
diff --git a/ansible_collections/community/general/tests/integration/targets/odbc/tasks/no_pyodbc.yml b/ansible_collections/community/general/tests/integration/targets/odbc/tasks/no_pyodbc.yml
new file mode 100644
index 000000000..3a52d85a1
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/odbc/tasks/no_pyodbc.yml
@@ -0,0 +1,16 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Testing the module without pyodbc
+ odbc:
+ dsn: "Test"
+ query: "SELECT * FROM nothing"
+ ignore_errors: true
+ register: results
+
+- assert:
+ that:
+ - results is failed
+ - "'Failed to import the required Python library (pyodbc) on' in results.msg"
diff --git a/ansible_collections/community/general/tests/integration/targets/one_host/aliases b/ansible_collections/community/general/tests/integration/targets/one_host/aliases
new file mode 100644
index 000000000..100ba0f97
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/one_host/aliases
@@ -0,0 +1,7 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/generic/1
+cloud/opennebula
+disabled # FIXME - when this is fixed, also re-enable the generic tests in CI!
diff --git a/ansible_collections/community/general/tests/integration/targets/one_host/files/testhost/tmp/opennebula-fixtures.json.gz b/ansible_collections/community/general/tests/integration/targets/one_host/files/testhost/tmp/opennebula-fixtures.json.gz
new file mode 100644
index 000000000..8b67b548a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/one_host/files/testhost/tmp/opennebula-fixtures.json.gz
Binary files differ
diff --git a/ansible_collections/community/general/tests/integration/targets/one_host/files/testhost/tmp/opennebula-fixtures.json.gz.license b/ansible_collections/community/general/tests/integration/targets/one_host/files/testhost/tmp/opennebula-fixtures.json.gz.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/one_host/files/testhost/tmp/opennebula-fixtures.json.gz.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/one_host/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/one_host/meta/main.yml
new file mode 100644
index 000000000..1a4a42fb5
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/one_host/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_opennebula
diff --git a/ansible_collections/community/general/tests/integration/targets/one_host/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/one_host/tasks/main.yml
new file mode 100644
index 000000000..ffd5ac04c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/one_host/tasks/main.yml
@@ -0,0 +1,243 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# test code for the one_host module
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# ENVIRONENT PREPARACTION
+
+- set_fact: test_number= 0
+
+- name: "test_{{test_number}}: copy fixtures to test host"
+ copy:
+ src: testhost/tmp/opennebula-fixtures.json.gz
+ dest: /tmp
+ when:
+ - opennebula_test_fixture
+ - opennebula_test_fixture_replay
+
+
+# SETUP INITIAL TESTING CONDITION
+
+- set_fact: test_number={{ test_number | int + 1 }}
+
+- name: "test_{{test_number}}: ensure the tests hosts are absent"
+ one_host:
+ name: "{{ item }}"
+ state: absent
+ api_endpoint: "{{ opennebula_url }}"
+ api_username: "{{ opennebula_username }}"
+ api_token: "{{ opennebula_password }}"
+ validate_certs: false
+ environment:
+ PYONE_TEST_FIXTURE: "{{ opennebula_test_fixture }}"
+ PYONE_TEST_FIXTURE_FILE: /tmp/opennebula-fixtures.json.gz
+ PYONE_TEST_FIXTURE_REPLAY: "{{ opennebula_test_fixture_replay }}"
+ PYONE_TEST_FIXTURE_UNIT: "test_{{test_number}}_{{ item }}"
+ with_items: "{{opennebula_test.hosts}}"
+ register: result
+
+# NOT EXISTING HOSTS
+
+- set_fact: test_number={{ test_number | int + 1 }}
+
+- name: "test_{{test_number}}: attempt to enable a host that does not exists"
+ one_host:
+ name: badhost
+ state: "{{item}}"
+ api_url: "{{ opennebula_url }}"
+ api_username: "{{ opennebula_username }}"
+ api_password: "{{ opennebula_password }}"
+ validate_certs: false
+ environment:
+ PYONE_TEST_FIXTURE: "{{ opennebula_test_fixture }}"
+ PYONE_TEST_FIXTURE_FILE: /tmp/opennebula-fixtures.json.gz
+ PYONE_TEST_FIXTURE_REPLAY: "{{ opennebula_test_fixture_replay }}"
+ PYONE_TEST_FIXTURE_UNIT: "test_{{test_number}}_{{item}}"
+ ignore_errors: true
+ register: result
+ with_items:
+ - enabled
+ - disabled
+ - offline
+
+- name: "assert test_{{test_number}} failed"
+ assert:
+ that:
+ - result is failed
+ - result.results[0].msg == 'invalid host state ERROR'
+
+# ---
+
+- set_fact: test_number={{ test_number | int + 1 }}
+
+- name: "test_{{test_number}}: delete an unexisting host"
+ one_host:
+ name: badhost
+ state: absent
+ validate_certs: false
+ environment:
+ ONE_URL: "{{ opennebula_url }}"
+ ONE_USERNAME: "{{ opennebula_username }}"
+ ONE_PASSWORD: "{{ opennebula_password }}"
+ PYONE_TEST_FIXTURE: "{{ opennebula_test_fixture }}"
+ PYONE_TEST_FIXTURE_FILE: /tmp/opennebula-fixtures.json.gz
+ PYONE_TEST_FIXTURE_REPLAY: "{{ opennebula_test_fixture_replay }}"
+ PYONE_TEST_FIXTURE_UNIT: "test_{{test_number}}"
+ register: result
+
+- name: "assert test_{{test_number}} worked"
+ assert:
+ that:
+ - result.changed
+
+# HOST ENABLEMENT
+
+- set_fact: test_number={{ test_number | int + 1 }}
+
+
+- name: "test_{{test_number}}: enable the test hosts"
+ one_host:
+ name: "{{ item }}"
+ state: enabled
+ api_url: "{{ opennebula_url }}"
+ api_username: "{{ opennebula_username }}"
+ api_password: "{{ opennebula_password }}"
+ validate_certs: false
+ environment:
+ PYONE_TEST_FIXTURE: "{{ opennebula_test_fixture }}"
+ PYONE_TEST_FIXTURE_FILE: /tmp/opennebula-fixtures.json.gz
+ PYONE_TEST_FIXTURE_REPLAY: "{{ opennebula_test_fixture_replay }}"
+ PYONE_TEST_FIXTURE_UNIT: "test_{{test_number}}_{{ item }}"
+ with_items: "{{opennebula_test.hosts}}"
+ register: result
+
+- name: "assert test_{{test_number}} worked"
+ assert:
+ that:
+ - result.changed
+
+# TEMPLATE MANAGEMENT
+
+- set_fact: test_number={{ test_number | int + 1 }}
+
+- name: "test_{{test_number}}: setup template values on hosts"
+ one_host:
+ name: "{{ item }}"
+ state: enabled
+ api_url: "{{ opennebula_url }}"
+ api_username: "{{ opennebula_username }}"
+ api_password: "{{ opennebula_password }}"
+ validate_certs: false
+ template:
+ LABELS:
+ - test
+ - custom
+ TEST_VALUE: 2
+ environment:
+ PYONE_TEST_FIXTURE: "{{ opennebula_test_fixture }}"
+ PYONE_TEST_FIXTURE_FILE: /tmp/opennebula-fixtures.json.gz
+ PYONE_TEST_FIXTURE_REPLAY: "{{ opennebula_test_fixture_replay }}"
+ PYONE_TEST_FIXTURE_UNIT: "test_{{test_number}}_{{ item }}"
+ with_items: "{{opennebula_test.hosts}}"
+ register: result
+
+- name: "assert test_{{test_number}} worked"
+ assert:
+ that:
+ - result.changed
+
+# ---
+
+- set_fact: test_number={{ test_number | int + 1 }}
+
+- name: "test_{{test_number}}: setup equivalent template values on hosts"
+ one_host:
+ name: "{{ item }}"
+ state: enabled
+ api_url: "{{ opennebula_url }}"
+ api_username: "{{ opennebula_username }}"
+ api_password: "{{ opennebula_password }}"
+ validate_certs: false
+ labels:
+ - test
+ - custom
+ attributes:
+ TEST_VALUE: "2"
+ environment:
+ PYONE_TEST_FIXTURE: "{{ opennebula_test_fixture }}"
+ PYONE_TEST_FIXTURE_FILE: /tmp/opennebula-fixtures.json.gz
+ PYONE_TEST_FIXTURE_REPLAY: "{{ opennebula_test_fixture_replay }}"
+ PYONE_TEST_FIXTURE_UNIT: "test_{{test_number}}_{{ item }}"
+ with_items: "{{opennebula_test.hosts}}"
+ register: result
+
+- name: "assert test_{{test_number}} worked"
+ assert:
+ that:
+ - result is not changed
+
+# HOST DISABLEMENT
+
+- set_fact: test_number={{ test_number | int + 1 }}
+
+- name: "test_{{test_number}}: disable the test hosts"
+ one_host:
+ name: "{{ item }}"
+ state: disabled
+ api_url: "{{ opennebula_url }}"
+ api_username: "{{ opennebula_username }}"
+ api_password: "{{ opennebula_password }}"
+ validate_certs: false
+ environment:
+ PYONE_TEST_FIXTURE: "{{ opennebula_test_fixture }}"
+ PYONE_TEST_FIXTURE_FILE: /tmp/opennebula-fixtures.json.gz
+ PYONE_TEST_FIXTURE_REPLAY: "{{ opennebula_test_fixture_replay }}"
+ PYONE_TEST_FIXTURE_UNIT: "test_{{test_number}}_{{ item }}"
+ with_items: "{{opennebula_test.hosts}}"
+ register: result
+
+- name: "assert test_{{test_number}} worked"
+ assert:
+ that:
+ - result.changed
+
+# HOST OFFLINE
+
+- set_fact: test_number={{ test_number | int + 1 }}
+
+- name: "test_{{test_number}}: offline the test hosts"
+ one_host:
+ name: "{{ item }}"
+ state: offline
+ api_url: "{{ opennebula_url }}"
+ api_username: "{{ opennebula_username }}"
+ api_password: "{{ opennebula_password }}"
+ validate_certs: false
+ environment:
+ PYONE_TEST_FIXTURE: "{{ opennebula_test_fixture }}"
+ PYONE_TEST_FIXTURE_FILE: /tmp/opennebula-fixtures.json.gz
+ PYONE_TEST_FIXTURE_REPLAY: "{{ opennebula_test_fixture_replay }}"
+ PYONE_TEST_FIXTURE_UNIT: "test_{{test_number}}_{{ item }}"
+ with_items: "{{opennebula_test.hosts}}"
+ register: result
+
+- name: "assert test_{{test_number}} worked"
+ assert:
+ that:
+ - result.changed
+
+# TEARDOWN
+
+- name: fetch fixtures
+ fetch:
+ src: /tmp/opennebula-fixtures.json.gz
+ dest: targets/one_host/files
+ when:
+ - opennebula_test_fixture
+ - not opennebula_test_fixture_replay
diff --git a/ansible_collections/community/general/tests/integration/targets/one_template/aliases b/ansible_collections/community/general/tests/integration/targets/one_template/aliases
new file mode 100644
index 000000000..100ba0f97
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/one_template/aliases
@@ -0,0 +1,7 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/generic/1
+cloud/opennebula
+disabled # FIXME - when this is fixed, also re-enable the generic tests in CI!
diff --git a/ansible_collections/community/general/tests/integration/targets/one_template/files/testhost/tmp/opennebula-fixtures.json.gz b/ansible_collections/community/general/tests/integration/targets/one_template/files/testhost/tmp/opennebula-fixtures.json.gz
new file mode 100644
index 000000000..169451a22
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/one_template/files/testhost/tmp/opennebula-fixtures.json.gz
Binary files differ
diff --git a/ansible_collections/community/general/tests/integration/targets/one_template/files/testhost/tmp/opennebula-fixtures.json.gz.license b/ansible_collections/community/general/tests/integration/targets/one_template/files/testhost/tmp/opennebula-fixtures.json.gz.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/one_template/files/testhost/tmp/opennebula-fixtures.json.gz.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/one_template/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/one_template/meta/main.yml
new file mode 100644
index 000000000..1a4a42fb5
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/one_template/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_opennebula
diff --git a/ansible_collections/community/general/tests/integration/targets/one_template/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/one_template/tasks/main.yml
new file mode 100644
index 000000000..58bca9c6c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/one_template/tasks/main.yml
@@ -0,0 +1,246 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# test code for the one_template module
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# ENVIRONMENT PREPARATION
+
+- name: "copy fixtures to test host"
+ copy:
+ src: testhost/tmp/opennebula-fixtures.json.gz
+ dest: /tmp
+ when:
+ - opennebula_test_fixture
+ - opennebula_test_fixture_replay
+
+
+# Create a new template
+
+- name: "Create a new TEMPLATE"
+ one_template:
+ api_url: "{{ opennebula_url }}"
+ api_username: "{{ opennebula_username }}"
+ api_password: "{{ opennebula_password }}"
+ name: ansible-onetemplate-test
+ template: |
+ CONTEXT = [
+ HOSTNAME = "ansible-onetemplate",
+ NETWORK = "YES",
+ SSH_PUBLIC_KEY = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKAQwTkU84eEnhX3r60Mn5TPh99BDxyCNJu12OB5sfMu foxy@FoxPad",
+ USERNAME = "root" ]
+ CPU = "1"
+ CUSTOM_ATTRIBUTE = ""
+ DISK = [
+ CACHE = "writeback",
+ DEV_PREFIX = "sd",
+ DISCARD = "unmap",
+ IMAGE = "ansible-onetemplate",
+ IMAGE_UNAME = "oneadmin",
+ IO = "threads",
+ SIZE = "" ]
+ FEATURES = [
+ VIRTIO_SCSI_QUEUES = "2" ]
+ GRAPHICS = [
+ KEYMAP = "de",
+ LISTEN = "0.0.0.0",
+ TYPE = "VNC" ]
+ MEMORY = "2048"
+ NIC = [
+ MODEL = "virtio",
+ NETWORK = "tf-prd-centos",
+ NETWORK_UNAME = "oneadmin" ]
+ OS = [
+ ARCH = "x86_64",
+ BOOT = "disk0" ]
+ SCHED_REQUIREMENTS = "CLUSTER_ID=\"100\""
+ VCPU = "2"
+ environment:
+ PYONE_TEST_FIXTURE: "{{ opennebula_test_fixture }}"
+ PYONE_TEST_FIXTURE_FILE: /tmp/opennebula-fixtures.json.gz
+ PYONE_TEST_FIXTURE_REPLAY: "{{ opennebula_test_fixture_replay }}"
+ PYONE_TEST_FIXTURE_UNIT: test_create_template
+ register: result
+
+- name: "assert that creation worked"
+ assert:
+ that:
+ - result is changed
+
+
+# Updating a template
+
+- name: "Update an existing TEMPLATE"
+ one_template:
+ api_url: "{{ opennebula_url }}"
+ api_username: "{{ opennebula_username }}"
+ api_password: "{{ opennebula_password }}"
+ name: ansible-onetemplate-test
+ template: |
+ CONTEXT = [
+ HOSTNAME = "ansible-onetemplate",
+ NETWORK = "YES",
+ SSH_PUBLIC_KEY = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKAQwTkU84eEnhX3r60Mn5TPh99BDxyCNJu12OB5sfMu foxy@FoxPad",
+ USERNAME = "root" ]
+ CPU = "1"
+ CUSTOM_ATTRIBUTE = ""
+ DISK = [
+ CACHE = "writeback",
+ DEV_PREFIX = "sd",
+ DISCARD = "unmap",
+ IMAGE = "ansible-onetemplate",
+ IMAGE_UNAME = "oneadmin",
+ IO = "threads",
+ SIZE = "" ]
+ FEATURES = [
+ VIRTIO_SCSI_QUEUES = "2" ]
+ GRAPHICS = [
+ KEYMAP = "de",
+ LISTEN = "0.0.0.0",
+ TYPE = "VNC" ]
+ MEMORY = "4096"
+ NIC = [
+ MODEL = "virtio",
+ NETWORK = "tf-prd-centos",
+ NETWORK_UNAME = "oneadmin" ]
+ OS = [
+ ARCH = "x86_64",
+ BOOT = "disk0" ]
+ SCHED_REQUIREMENTS = "CLUSTER_ID=\"100\""
+ VCPU = "2"
+ environment:
+ PYONE_TEST_FIXTURE: "{{ opennebula_test_fixture }}"
+ PYONE_TEST_FIXTURE_FILE: /tmp/opennebula-fixtures.json.gz
+ PYONE_TEST_FIXTURE_REPLAY: "{{ opennebula_test_fixture_replay }}"
+ PYONE_TEST_FIXTURE_UNIT: test_update_existing_template
+ register: result
+
+- name: "assert that it updated the template"
+ assert:
+ that:
+ - result is changed
+
+- name: "Update an existing TEMPLATE with the same changes again"
+ one_template:
+ api_url: "{{ opennebula_url }}"
+ api_username: "{{ opennebula_username }}"
+ api_password: "{{ opennebula_password }}"
+ name: ansible-onetemplate-test
+ template: |
+ CONTEXT = [
+ HOSTNAME = "ansible-onetemplate",
+ NETWORK = "YES",
+ SSH_PUBLIC_KEY = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKAQwTkU84eEnhX3r60Mn5TPh99BDxyCNJu12OB5sfMu foxy@FoxPad",
+ USERNAME = "root" ]
+ CPU = "1"
+ CUSTOM_ATTRIBUTE = ""
+ DISK = [
+ CACHE = "writeback",
+ DEV_PREFIX = "sd",
+ DISCARD = "unmap",
+ IMAGE = "ansible-onetemplate",
+ IMAGE_UNAME = "oneadmin",
+ IO = "threads",
+ SIZE = "" ]
+ FEATURES = [
+ VIRTIO_SCSI_QUEUES = "2" ]
+ GRAPHICS = [
+ KEYMAP = "de",
+ LISTEN = "0.0.0.0",
+ TYPE = "VNC" ]
+ MEMORY = "4096"
+ NIC = [
+ MODEL = "virtio",
+ NETWORK = "tf-prd-centos",
+ NETWORK_UNAME = "oneadmin" ]
+ OS = [
+ ARCH = "x86_64",
+ BOOT = "disk0" ]
+ SCHED_REQUIREMENTS = "CLUSTER_ID=\"100\""
+ VCPU = "2"
+ environment:
+ PYONE_TEST_FIXTURE: "{{ opennebula_test_fixture }}"
+ PYONE_TEST_FIXTURE_FILE: /tmp/opennebula-fixtures.json.gz
+ PYONE_TEST_FIXTURE_REPLAY: "{{ opennebula_test_fixture_replay }}"
+ PYONE_TEST_FIXTURE_UNIT: test_update_existing_and_already_updated_template
+ register: result
+
+- name: "assert that there was no change"
+ assert:
+ that:
+ - result is not changed
+
+
+# Deletion of templates
+
+- name: "Delete a nonexisting TEMPLATE"
+ one_template:
+ api_url: "{{ opennebula_url }}"
+ api_username: "{{ opennebula_username }}"
+ api_password: "{{ opennebula_password }}"
+ name: ansible-onetemplate-test-nonexisting
+ state: absent
+ environment:
+ PYONE_TEST_FIXTURE: "{{ opennebula_test_fixture }}"
+ PYONE_TEST_FIXTURE_FILE: /tmp/opennebula-fixtures.json.gz
+ PYONE_TEST_FIXTURE_REPLAY: "{{ opennebula_test_fixture_replay }}"
+ PYONE_TEST_FIXTURE_UNIT: test_delete_nonexisting_template
+ register: result
+
+- name: "assert that there was no change"
+ assert:
+ that:
+ - result is not changed
+
+- name: "Delete an existing TEMPLATE"
+ one_template:
+ api_url: "{{ opennebula_url }}"
+ api_username: "{{ opennebula_username }}"
+ api_password: "{{ opennebula_password }}"
+ name: ansible-onetemplate-test
+ state: absent
+ environment:
+ PYONE_TEST_FIXTURE: "{{ opennebula_test_fixture }}"
+ PYONE_TEST_FIXTURE_FILE: /tmp/opennebula-fixtures.json.gz
+ PYONE_TEST_FIXTURE_REPLAY: "{{ opennebula_test_fixture_replay }}"
+ PYONE_TEST_FIXTURE_UNIT: test_delete_existing_template
+ register: result
+
+- name: "assert that there was a change"
+ assert:
+ that:
+ - result is changed
+
+
+# Usage without `template` parameter
+
+- name: "Try to create use one_template with state=present and without the template parameter"
+ one_template:
+ api_url: "{{ opennebula_url }}"
+ api_username: "{{ opennebula_username }}"
+ api_password: "{{ opennebula_password }}"
+ name: ansible-onetemplate-test
+ state: present
+ register: result
+ ignore_errors: true
+
+- name: "assert that it failed because template is missing"
+ assert:
+ that:
+ - result is failed
+
+
+# TEARDOWN
+
+- name: "fetch fixtures"
+ fetch:
+ src: /tmp/opennebula-fixtures.json.gz
+ dest: targets/one_host/files
+ when:
+ - opennebula_test_fixture
+ - not opennebula_test_fixture_replay
diff --git a/ansible_collections/community/general/tests/integration/targets/osx_defaults/aliases b/ansible_collections/community/general/tests/integration/targets/osx_defaults/aliases
new file mode 100644
index 000000000..bd478505d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/osx_defaults/aliases
@@ -0,0 +1,9 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+skip/aix
+skip/freebsd
+skip/rhel
+skip/docker
diff --git a/ansible_collections/community/general/tests/integration/targets/osx_defaults/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/osx_defaults/tasks/main.yml
new file mode 100644
index 000000000..f7bcb8944
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/osx_defaults/tasks/main.yml
@@ -0,0 +1,255 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Test code for the osx_defaults module.
+# Copyright (c) 2019, Abhijeet Kasurde <akasurde@redhat.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Check if name is required for present
+ osx_defaults:
+ domain: NSGlobalDomain
+ key: AppleMeasurementUnits
+ type: string
+ state: present
+ register: missing_value
+ ignore_errors: true
+
+- name: Test if state and value are required together
+ assert:
+ that:
+ - "'following are missing: value' in '{{ missing_value['msg'] }}'"
+
+- name: Change value of AppleMeasurementUnits to centimeter in check_mode
+ osx_defaults:
+ domain: NSGlobalDomain
+ key: AppleMeasurementUnits
+ type: string
+ value: Centimeter
+ state: present
+ register: measure_task_check_mode
+ check_mode: true
+
+- name: Test if AppleMeasurementUnits value is changed to Centimeters in check_mode
+ assert:
+ that:
+ - measure_task_check_mode.changed
+
+- name: Find the current value of AppleMeasurementUnits
+ osx_defaults:
+ domain: NSGlobalDomain
+ key: AppleMeasurementUnits
+ state: list
+ register: apple_measure_value
+
+- debug:
+ msg: "{{ apple_measure_value['value'] }}"
+
+- set_fact:
+ new_value: "Centimeters"
+ when: apple_measure_value['value'] == 'Inches' or apple_measure_value['value'] == None
+
+- set_fact:
+ new_value: "Inches"
+ when: apple_measure_value['value'] == 'Centimeters'
+
+- name: Change value of AppleMeasurementUnits to {{ new_value }}
+ osx_defaults:
+ domain: NSGlobalDomain
+ key: AppleMeasurementUnits
+ type: string
+ value: "{{ new_value }}"
+ state: present
+ register: change_value
+
+- name: Test if AppleMeasurementUnits value is changed to {{ new_value }}
+ assert:
+ that:
+ - change_value.changed
+
+- name: Again change value of AppleMeasurementUnits to {{ new_value }}
+ osx_defaults:
+ domain: NSGlobalDomain
+ key: AppleMeasurementUnits
+ type: string
+ value: "{{ new_value }}"
+ state: present
+ register: change_value
+
+- name: Again test if AppleMeasurementUnits value is not changed to {{ new_value }}
+ assert:
+ that:
+ - not change_value.changed
+
+- name: Check a fake setting for delete operation
+ osx_defaults:
+ domain: com.ansible.fake_value
+ key: ExampleKeyToRemove
+ state: list
+ register: list_fake_value
+
+- debug:
+ msg: "{{ list_fake_value }}"
+
+- name: Check if fake value is listed
+ assert:
+ that:
+ - not list_fake_value.changed
+
+- name: Create a fake setting for delete operation
+ osx_defaults:
+ domain: com.ansible.fake_value
+ key: ExampleKeyToRemove
+ state: present
+ value: sample
+ register: present_fake_value
+
+- debug:
+ msg: "{{ present_fake_value }}"
+
+- name: Check if fake is created
+ assert:
+ that:
+ - present_fake_value.changed
+ when: present_fake_value.changed
+
+- name: List a fake setting
+ osx_defaults:
+ domain: com.ansible.fake_value
+ key: ExampleKeyToRemove
+ state: list
+ register: list_fake
+
+- debug:
+ msg: "{{ list_fake }}"
+
+- name: Delete a fake setting
+ osx_defaults:
+ domain: com.ansible.fake_value
+ key: ExampleKeyToRemove
+ state: absent
+ register: absent_task
+
+- debug:
+ msg: "{{ absent_task }}"
+
+- name: Check if fake setting is deleted
+ assert:
+ that:
+ - absent_task.changed
+ when: present_fake_value.changed
+
+- name: Try deleting a fake setting again
+ osx_defaults:
+ domain: com.ansible.fake_value
+ key: ExampleKeyToRemove
+ state: absent
+ register: absent_task
+
+- debug:
+ msg: "{{ absent_task }}"
+
+- name: Check if fake setting is not deleted
+ assert:
+ that:
+ - not absent_task.changed
+
+- name: Delete operation in check_mode
+ osx_defaults:
+ domain: com.ansible.fake_value
+ key: ExampleKeyToRemove
+ state: absent
+ register: absent_check_mode_task
+ check_mode: true
+
+- debug:
+ msg: "{{ absent_check_mode_task }}"
+
+- name: Check delete operation with check mode
+ assert:
+ that:
+ - not absent_check_mode_task.changed
+
+
+- name: Use different data types and check if it works with them
+ osx_defaults:
+ domain: com.ansible.fake_values
+ key: "{{ item.key }}"
+ type: "{{ item.type }}"
+ value: "{{ item.value }}"
+ state: present
+ with_items: &data_type
+ - { type: 'int', value: 1, key: 'sample_int'}
+ - { type: 'integer', value: 1, key: 'sample_int_2'}
+ - { type: 'integer', value: -1, key: 'negative_int'}
+ - { type: 'bool', value: true, key: 'sample_bool'}
+ - { type: 'boolean', value: true, key: 'sample_bool_2'}
+ - { type: 'date', value: "2019-02-19 10:10:10", key: 'sample_date'}
+ - { type: 'float', value: 1.2, key: 'sample_float'}
+ - { type: 'string', value: 'sample', key: 'sample_string'}
+ - { type: 'array', value: ['1', '2'], key: 'sample_array'}
+ register: test_data_types
+
+- assert:
+ that: "{{ item.changed }}"
+ with_items: "{{ test_data_types.results }}"
+
+- name: Use different data types and delete them
+ osx_defaults:
+ domain: com.ansible.fake_values
+ key: "{{ item.key }}"
+ value: "{{ item.value }}"
+ type: "{{ item.type }}"
+ state: absent
+ with_items: *data_type
+ register: test_data_types
+
+- assert:
+ that: "{{ item.changed }}"
+ with_items: "{{ test_data_types.results }}"
+
+
+- name: Ensure test key does not exist
+ osx_defaults:
+ domain: com.ansible.fake_array_value
+ key: ExampleArrayKey
+ state: absent
+
+- name: add array value for the first time
+ osx_defaults:
+ domain: com.ansible.fake_array_value
+ key: ExampleArrayKey
+ value:
+ - 'Value with spaces'
+ type: array
+ array_add: true
+ register: test_array_add
+
+- assert:
+ that: test_array_add.changed
+
+- name: add for the second time, should be skipped
+ osx_defaults:
+ domain: com.ansible.fake_array_value
+ key: ExampleArrayKey
+ value:
+ - 'Value with spaces'
+ type: array
+ array_add: true
+ register: test_array_add
+
+- assert:
+ that: not test_array_add.changed
+
+- name: Clean up test key
+ osx_defaults:
+ domain: com.ansible.fake_array_value
+ key: ExampleArrayKey
+ state: absent
+ register: test_array_add
+
+- assert:
+ that: test_array_add.changed
diff --git a/ansible_collections/community/general/tests/integration/targets/pacman/aliases b/ansible_collections/community/general/tests/integration/targets/pacman/aliases
new file mode 100644
index 000000000..1d25c0193
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pacman/aliases
@@ -0,0 +1,12 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+destructive
+skip/aix
+skip/freebsd
+skip/osx
+skip/macos
+skip/rhel
+needs/root
diff --git a/ansible_collections/community/general/tests/integration/targets/pacman/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/pacman/meta/main.yml
new file mode 100644
index 000000000..08ce20c21
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pacman/meta/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_remote_tmp_dir
+ - setup_pkg_mgr
diff --git a/ansible_collections/community/general/tests/integration/targets/pacman/tasks/basic.yml b/ansible_collections/community/general/tests/integration/targets/pacman/tasks/basic.yml
new file mode 100644
index 000000000..ae2f9c0b5
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pacman/tasks/basic.yml
@@ -0,0 +1,86 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- vars:
+ package_name: unarj
+ block:
+ - name: Make sure that {{ package_name }} is not installed
+ pacman:
+ name: '{{ package_name }}'
+ state: absent
+
+ - name: Install {{ package_name }} (check mode)
+ pacman:
+ name: '{{ package_name }}'
+ state: present
+ check_mode: true
+ register: install_1
+
+ - name: Install {{ package_name }}
+ pacman:
+ name: '{{ package_name }}'
+ state: present
+ register: install_2
+
+ - name: Install {{ package_name }} (check mode, idempotent)
+ pacman:
+ name: '{{ package_name }}'
+ state: present
+ check_mode: true
+ register: install_3
+
+ - name: Install {{ package_name }} (idempotent)
+ pacman:
+ name: '{{ package_name }}'
+ state: present
+ register: install_4
+
+ - assert:
+ that:
+ - install_1 is changed
+ - install_1.msg == 'Would have installed 1 packages'
+ - install_2 is changed
+ - install_2.msg == 'Installed 1 package(s)'
+ - install_3 is not changed
+ - install_3.msg == 'package(s) already installed'
+ - install_4 is not changed
+ - install_4.msg == 'package(s) already installed'
+
+ - name: Uninstall {{ package_name }} (check mode)
+ pacman:
+ name: '{{ package_name }}'
+ state: absent
+ check_mode: true
+ register: uninstall_1
+
+ - name: Uninstall {{ package_name }}
+ pacman:
+ name: '{{ package_name }}'
+ state: absent
+ register: uninstall_2
+
+ - name: Uninstall {{ package_name }} (check mode, idempotent)
+ pacman:
+ name: '{{ package_name }}'
+ state: absent
+ check_mode: true
+ register: uninstall_3
+
+ - name: Uninstall {{ package_name }} (idempotent)
+ pacman:
+ name: '{{ package_name }}'
+ state: absent
+ register: uninstall_4
+
+ - assert:
+ that:
+ - uninstall_1 is changed
+ - uninstall_1.msg == 'Would have removed 1 packages'
+ - uninstall_2 is changed
+ - uninstall_2.msg == 'Removed 1 package(s)'
+ - uninstall_3 is not changed
+ - uninstall_3.msg == 'package(s) already absent'
+ - uninstall_4 is not changed
+ - uninstall_4.msg == 'package(s) already absent'
diff --git a/ansible_collections/community/general/tests/integration/targets/pacman/tasks/locally_installed_package.yml b/ansible_collections/community/general/tests/integration/targets/pacman/tasks/locally_installed_package.yml
new file mode 100644
index 000000000..a5f183236
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pacman/tasks/locally_installed_package.yml
@@ -0,0 +1,85 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- vars:
+ package_name: ansible-test-foo
+ username: ansible-regular-user
+ block:
+ - name: Install fakeroot
+ pacman:
+ state: present
+ name:
+ - fakeroot
+
+ - name: Create user
+ user:
+ name: '{{ username }}'
+ home: '/home/{{ username }}'
+ create_home: true
+
+ - name: Create directory
+ file:
+ path: '/home/{{ username }}/{{ package_name }}'
+ state: directory
+ owner: '{{ username }}'
+
+ - name: Create PKGBUILD
+ copy:
+ dest: '/home/{{ username }}/{{ package_name }}/PKGBUILD'
+ content: |
+ pkgname=('{{ package_name }}')
+ pkgver=1.0.0
+ pkgrel=1
+ pkgdesc="Test removing a local package not in the repositories"
+ arch=('any')
+ license=('GPL v3+')
+ owner: '{{ username }}'
+
+ - name: Build package
+ command:
+ cmd: su {{ username }} -c "makepkg -srf"
+ chdir: '/home/{{ username }}/{{ package_name }}'
+
+ - name: Install package
+ pacman:
+ state: present
+ name:
+ - '/home/{{ username }}/{{ package_name }}/{{ package_name }}-1.0.0-1-any.pkg.tar.zst'
+
+ - name: Remove package (check mode)
+ pacman:
+ state: absent
+ name:
+ - '{{ package_name }}'
+ check_mode: true
+ register: remove_1
+
+ - name: Remove package
+ pacman:
+ state: absent
+ name:
+ - '{{ package_name }}'
+ register: remove_2
+
+ - name: Remove package (idempotent)
+ pacman:
+ state: absent
+ name:
+ - '{{ package_name }}'
+ register: remove_3
+
+ - name: Check conditions
+ assert:
+ that:
+ - remove_1 is changed
+ - remove_2 is changed
+ - remove_3 is not changed
+
+ always:
+ - name: Remove directory
+ file:
+ path: '{{ remote_tmp_dir }}/{{ package_name }}'
+ state: absent
+ become: true
diff --git a/ansible_collections/community/general/tests/integration/targets/pacman/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/pacman/tasks/main.yml
new file mode 100644
index 000000000..12d28a2d3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pacman/tasks/main.yml
@@ -0,0 +1,19 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- when: ansible_os_family == 'Archlinux'
+ block:
+ # Add more tests here by including more task files:
+ - include_tasks: 'basic.yml'
+ - include_tasks: 'package_urls.yml'
+ - include_tasks: 'remove_nosave.yml'
+ - include_tasks: 'update_cache.yml'
+ - include_tasks: 'locally_installed_package.yml'
+ - include_tasks: 'reason.yml'
diff --git a/ansible_collections/community/general/tests/integration/targets/pacman/tasks/package_urls.yml b/ansible_collections/community/general/tests/integration/targets/pacman/tasks/package_urls.yml
new file mode 100644
index 000000000..4df531285
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pacman/tasks/package_urls.yml
@@ -0,0 +1,219 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- vars:
+ http_port: 27617
+ reg_pkg: ed
+ url_pkg: lemon
+ url_pkg_filename: url.pkg.zst
+ url_pkg_path: '/tmp/'
+ url_pkg_url: 'http://localhost:{{http_port}}/{{url_pkg_filename}}'
+ file_pkg: hdparm
+ file_pkg_path: /tmp/file.pkg.zst
+ extra_pkg: core/sdparm
+ extra_pkg_outfmt: sdparm
+ block:
+ - name: Make sure that test packages are not installed
+ pacman:
+ name:
+ - '{{reg_pkg}}'
+ - '{{url_pkg}}'
+ - '{{file_pkg}}'
+ - '{{extra_pkg}}'
+ state: absent
+ - name: Make sure that url package is not cached
+ file:
+ path: '/var/cache/pacman/pkg/{{url_pkg_filename}}'
+ state: absent
+
+ - name: Get URL for {{url_pkg}}
+ command:
+ cmd: pacman --sync --print-format "%l" {{url_pkg}}
+ register: url_pkg_stdout
+ - name: Download {{url_pkg}} pkg
+ get_url:
+ url: '{{url_pkg_stdout.stdout}}'
+ dest: '{{url_pkg_path}}/{{url_pkg_filename}}'
+ - name: Download {{url_pkg}} pkg sig
+ get_url:
+ url: '{{url_pkg_stdout.stdout}}.sig'
+ dest: '{{url_pkg_path}}/{{url_pkg_filename}}.sig'
+ - name: Host {{url_pkg}}
+ shell:
+ cmd: 'python -m http.server --directory {{url_pkg_path}} {{http_port}} >/dev/null 2>&1'
+ async: 90
+ poll: 0
+ - name: Wait for http.server to come up online
+ wait_for:
+ host: 'localhost'
+ port: '{{http_port}}'
+ state: started
+
+ - name: Get URL for {{file_pkg}}
+ command:
+ cmd: pacman --sync --print-format "%l" {{file_pkg}}
+ register: file_pkg_url
+ - name: Download {{file_pkg}} pkg
+ get_url:
+ url: '{{file_pkg_url.stdout}}'
+ dest: '{{file_pkg_path}}'
+
+ - name: Install packages from mixed sources (check mode)
+ pacman:
+ name:
+ - '{{reg_pkg}}'
+ - '{{url_pkg_url}}'
+ - '{{file_pkg_path}}'
+ check_mode: true
+ register: install_1
+
+ - name: Install packages from url (check mode, cached)
+ pacman:
+ name:
+ - '{{url_pkg_url}}'
+ check_mode: true
+ register: install_1c
+ - name: Delete cached {{url_pkg}}
+ file:
+ path: '/var/cache/pacman/pkg/{{url_pkg_filename}}'
+ state: absent
+
+ - name: Install packages from mixed sources
+ pacman:
+ name:
+ - '{{reg_pkg}}'
+ - '{{url_pkg_url}}'
+ - '{{file_pkg_path}}'
+ register: install_2
+ - name: Delete cached {{url_pkg}}
+ file:
+ path: '/var/cache/pacman/pkg/{{url_pkg_filename}}'
+ state: absent
+
+ - name: Install packages from mixed sources - (idempotency)
+ pacman:
+ name:
+ - '{{reg_pkg}}'
+ - '{{url_pkg_url}}'
+ - '{{file_pkg_path}}'
+ register: install_3
+ - name: Install packages from url - (idempotency, cached)
+ pacman:
+ name:
+ - '{{url_pkg_url}}'
+ register: install_3c
+ - name: Delete cached {{url_pkg}}
+ file:
+ path: '/var/cache/pacman/pkg/{{url_pkg_filename}}'
+ state: absent
+
+ - name: Install packages with their regular names (idempotency)
+ pacman:
+ name:
+ - '{{reg_pkg}}'
+ - '{{url_pkg}}'
+ - '{{file_pkg}}'
+ register: install_4
+ - name: Delete cached {{url_pkg}}
+ file:
+ path: '/var/cache/pacman/pkg/{{url_pkg_filename}}'
+ state: absent
+
+ - name: Install new package with already installed packages from mixed sources
+ pacman:
+ name:
+ - '{{reg_pkg}}'
+ - '{{url_pkg_url}}'
+ - '{{file_pkg_path}}'
+ - '{{extra_pkg}}'
+ register: install_5
+ - name: Delete cached {{url_pkg}}
+ file:
+ path: '/var/cache/pacman/pkg/{{url_pkg_filename}}'
+ state: absent
+
+ - name: Uninstall packages - mixed sources (check mode)
+ pacman:
+ state: absent
+ name:
+ - '{{reg_pkg}}'
+ - '{{url_pkg_url}}'
+ - '{{file_pkg_path}}'
+ check_mode: true
+ register: uninstall_1
+ - name: Uninstall packages - url (check mode, cached)
+ pacman:
+ state: absent
+ name:
+ - '{{url_pkg_url}}'
+ check_mode: true
+ register: uninstall_1c
+ - name: Delete cached {{url_pkg}}
+ file:
+ path: '/var/cache/pacman/pkg/{{url_pkg_filename}}'
+ state: absent
+
+ - name: Uninstall packages - mixed sources
+ pacman:
+ state: absent
+ name:
+ - '{{reg_pkg}}'
+ - '{{url_pkg_url}}'
+ - '{{file_pkg_path}}'
+ register: uninstall_2
+ - name: Delete cached {{url_pkg}}
+ file:
+ path: '/var/cache/pacman/pkg/{{url_pkg_filename}}'
+ state: absent
+
+ - name: Uninstall packages - mixed sources (idempotency)
+ pacman:
+ state: absent
+ name:
+ - '{{reg_pkg}}'
+ - '{{url_pkg_url}}'
+ - '{{file_pkg_path}}'
+ register: uninstall_3
+
+ - name: Uninstall package - url (idempotency, cached)
+ pacman:
+ state: absent
+ name:
+ - '{{url_pkg_url}}'
+ register: uninstall_3c
+
+ - assert:
+ that:
+ - install_1 is changed
+ - install_1.msg == 'Would have installed 3 packages'
+ - install_1.packages|sort() == [reg_pkg, url_pkg, file_pkg]|sort()
+ - install_1c is changed
+ - install_1c.msg == 'Would have installed 1 packages'
+ - install_1c.packages|sort() == [url_pkg]
+ - install_2 is changed
+ - install_2.msg == 'Installed 3 package(s)'
+ - install_2.packages|sort() == [reg_pkg, url_pkg, file_pkg]|sort()
+ - install_3 is not changed
+ - install_3.msg == 'package(s) already installed'
+ - install_3c is not changed
+ - install_3c.msg == 'package(s) already installed'
+ - install_4 is not changed
+ - install_4.msg == 'package(s) already installed'
+ - install_5 is changed
+ - install_5.msg == 'Installed 1 package(s)'
+ - install_5.packages == [extra_pkg_outfmt]
+ - uninstall_1 is changed
+ - uninstall_1.msg == 'Would have removed 3 packages'
+ - uninstall_1.packages | length() == 3 # pkgs have versions here
+ - uninstall_1c is changed
+ - uninstall_1c.msg == 'Would have removed 1 packages'
+ - uninstall_1c.packages | length() == 1 # pkgs have versions here
+ - uninstall_2 is changed
+ - uninstall_2.msg == 'Removed 3 package(s)'
+ - uninstall_2.packages | length() == 3
+ - uninstall_3 is not changed
+ - uninstall_3.msg == 'package(s) already absent'
+ - uninstall_3c is not changed
+ - uninstall_3c.msg == 'package(s) already absent'
diff --git a/ansible_collections/community/general/tests/integration/targets/pacman/tasks/reason.yml b/ansible_collections/community/general/tests/integration/targets/pacman/tasks/reason.yml
new file mode 100644
index 000000000..5a26e3e10
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pacman/tasks/reason.yml
@@ -0,0 +1,101 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- vars:
+ reg_pkg: ed
+ url_pkg: lemon
+ file_pkg: hdparm
+ file_pkg_path: /tmp/pkg.zst
+ extra_pkg: core/sdparm
+ extra_pkg_outfmt: sdparm
+ block:
+ - name: Make sure that test packages are not installed
+ pacman:
+ name:
+ - '{{reg_pkg}}'
+ - '{{url_pkg}}'
+ - '{{file_pkg}}'
+ - '{{extra_pkg}}'
+ state: absent
+
+ - name: Get URL for {{url_pkg}}
+ command:
+ cmd: pacman --sync --print-format "%l" {{url_pkg}}
+ register: url_pkg_url
+
+ - name: Get URL for {{file_pkg}}
+ command:
+ cmd: pacman --sync --print-format "%l" {{file_pkg}}
+ register: file_pkg_url
+ - name: Download {{file_pkg}} pkg
+ get_url:
+ url: '{{file_pkg_url.stdout}}'
+ dest: '{{file_pkg_path}}'
+
+ - name: Install packages from mixed sources as dependency (check mode)
+ pacman:
+ name:
+ - '{{reg_pkg}}'
+ - '{{url_pkg_url.stdout}}'
+ - '{{file_pkg_path}}'
+ reason: dependency
+ check_mode: true
+ register: install_1
+
+ - name: Install packages from mixed sources as explicit
+ pacman:
+ name:
+ - '{{reg_pkg}}'
+ - '{{url_pkg_url.stdout}}'
+ - '{{file_pkg_path}}'
+ reason: explicit
+ register: install_2
+
+ - name: Install packages from mixed sources with new packages being installed as dependency - (idempotency)
+ pacman:
+ name:
+ - '{{reg_pkg}}'
+ - '{{url_pkg_url.stdout}}'
+ - '{{file_pkg_path}}'
+ reason: dependency
+ register: install_3
+
+ - name: Install new package with already installed packages from mixed sources as dependency
+ pacman:
+ name:
+ - '{{reg_pkg}}'
+ - '{{url_pkg_url.stdout}}'
+ - '{{file_pkg_path}}'
+ - '{{extra_pkg}}'
+ reason: dependency
+ register: install_4
+
+ - name: Set install reason for all packages to dependency
+ pacman:
+ name:
+ - '{{reg_pkg}}'
+ - '{{url_pkg_url.stdout}}'
+ - '{{file_pkg_path}}'
+ - '{{extra_pkg}}'
+ reason: dependency
+ reason_for: all
+ register: install_5
+
+ - assert:
+ that:
+ - install_1 is changed
+ - install_1.msg == 'Would have installed 3 packages'
+ - install_1.packages|sort() == [reg_pkg, url_pkg, file_pkg]|sort()
+ - install_2 is changed
+ - install_2.msg == 'Installed 3 package(s)'
+ - install_2.packages|sort() == [reg_pkg, url_pkg, file_pkg]|sort()
+ - install_3 is not changed
+ - install_3.msg == 'package(s) already installed'
+ - install_4 is changed
+ - install_4.msg == 'Installed 1 package(s)'
+ - install_4.packages == [extra_pkg_outfmt]
+ - install_5 is changed
+ - install_5.msg == 'Installed 3 package(s)'
+ - install_5.packages|sort() == [reg_pkg, url_pkg, file_pkg]|sort()
diff --git a/ansible_collections/community/general/tests/integration/targets/pacman/tasks/remove_nosave.yml b/ansible_collections/community/general/tests/integration/targets/pacman/tasks/remove_nosave.yml
new file mode 100644
index 000000000..2271ebc03
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pacman/tasks/remove_nosave.yml
@@ -0,0 +1,74 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- vars:
+ package_name: xinetd
+ config_file: /etc/xinetd.conf
+ block:
+ - name: Make sure that {{ package_name }} is not installed
+ pacman:
+ name: '{{ package_name }}'
+ state: absent
+ - name: Make sure {{config_file}}.pacsave file doesn't exist
+ file:
+ path: '{{config_file}}.pacsave'
+ state: absent
+
+ - name: Install {{ package_name }}
+ pacman:
+ name: '{{ package_name }}'
+ state: present
+
+ - name: Modify {{config_file}}
+ blockinfile:
+ path: '{{config_file}}'
+ block: |
+ # something something
+ # on 2 lines
+
+ - name: Remove {{ package_name }} - generate pacsave
+ pacman:
+ name: '{{ package_name }}'
+ state: absent
+ - name: Make sure {{config_file}}.pacsave exists
+ stat:
+ path: '{{config_file}}.pacsave'
+ register: pacsave_st_1
+
+ - assert:
+ that:
+ - pacsave_st_1.stat.exists
+
+ - name: Delete {{config_file}}.pacsave
+ file:
+ path: '{{config_file}}.pacsave'
+ state: absent
+
+ - name: Install {{ package_name }}
+ pacman:
+ name: '{{ package_name }}'
+ state: present
+
+ - name: Modify {{config_file}}
+ blockinfile:
+ path: '{{config_file}}'
+ block: |
+ # something something
+ # on 2 lines
+
+ - name: Remove {{ package_name }} - nosave
+ pacman:
+ name: '{{ package_name }}'
+ remove_nosave: true
+ state: absent
+
+ - name: Make sure {{config_file}}.pacsave does not exist
+ stat:
+ path: '{{config_file}}.pacsave'
+ register: pacsave_st_2
+
+ - assert:
+ that:
+ - not pacsave_st_2.stat.exists
diff --git a/ansible_collections/community/general/tests/integration/targets/pacman/tasks/update_cache.yml b/ansible_collections/community/general/tests/integration/targets/pacman/tasks/update_cache.yml
new file mode 100644
index 000000000..ee2ac3b9f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pacman/tasks/update_cache.yml
@@ -0,0 +1,27 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Make sure package cache is updated
+ pacman:
+ update_cache: true
+
+- name: Update package cache again (should not be changed)
+ pacman:
+ update_cache: true
+ register: update_cache_idem
+
+- name: Update package cache again with force=true (should be changed)
+ pacman:
+ update_cache: true
+ force: true
+ register: update_cache_force
+
+- name: Check conditions
+ assert:
+ that:
+ - update_cache_idem is not changed
+ - update_cache_idem.cache_updated == false
+ - update_cache_force is changed
+ - update_cache_force.cache_updated == true
diff --git a/ansible_collections/community/general/tests/integration/targets/pagerduty_user/aliases b/ansible_collections/community/general/tests/integration/targets/pagerduty_user/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pagerduty_user/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/pagerduty_user/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/pagerduty_user/tasks/main.yml
new file mode 100644
index 000000000..13a0a5e09
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pagerduty_user/tasks/main.yml
@@ -0,0 +1,25 @@
+# Test code for pagerduty_user module
+#
+# Copyright (c) 2020, Zainab Alsaffar <Zainab.Alsaffar@mail.rit.edu>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+- name: Install required library
+ pip:
+ name: pdpyras
+ state: present
+
+- name: Create a user account on PagerDuty
+ pagerduty_user:
+ access_token: '{{ pd_api_access_token }}'
+ pd_user: '{{ fullname }}'
+ pd_email: '{{ email }}'
+ pd_role: '{{ pd_role }}'
+ pd_teams: '{{ pd_team }}'
+ state: present
+
+- name: Remove a user account from PagerDuty
+ pagerduty_user:
+ access_token: "{{ pd_api_access_token }}"
+ pd_user: "{{ fullname }}"
+ pd_email: "{{ email }}"
+ state: "absent"
diff --git a/ansible_collections/community/general/tests/integration/targets/pagerduty_user/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/pagerduty_user/vars/main.yml
new file mode 100644
index 000000000..723755727
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pagerduty_user/vars/main.yml
@@ -0,0 +1,10 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+pd_api_access_token: your_api_access_token
+fullname: User Name
+email: user@email.com
+pd_role: observer
+pd_teams: team1
diff --git a/ansible_collections/community/general/tests/integration/targets/pam_limits/aliases b/ansible_collections/community/general/tests/integration/targets/pam_limits/aliases
new file mode 100644
index 000000000..b85ae6419
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pam_limits/aliases
@@ -0,0 +1,9 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+skip/aix
+skip/freebsd
+skip/osx
+skip/macos
diff --git a/ansible_collections/community/general/tests/integration/targets/pam_limits/files/test_pam_limits.conf b/ansible_collections/community/general/tests/integration/targets/pam_limits/files/test_pam_limits.conf
new file mode 100644
index 000000000..7d5d8bc85
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pam_limits/files/test_pam_limits.conf
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# /etc/security/limits.conf
diff --git a/ansible_collections/community/general/tests/integration/targets/pam_limits/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/pam_limits/tasks/main.yml
new file mode 100644
index 000000000..5ad68f4a6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pam_limits/tasks/main.yml
@@ -0,0 +1,92 @@
+# Test code for the pam_limits module
+# Copyright (c) 2021, Abhijeet Kasurde <akasurde@redhat.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Set value for temp limit configuration
+ set_fact:
+ test_limit_file: "/tmp/limits.conf"
+
+- name: Copy temporary limits.conf
+ copy:
+ src: test_pam_limits.conf
+ dest: "{{ test_limit_file }}"
+
+- name: Test check mode support in pam_limits
+ community.general.pam_limits:
+ domain: smith
+ limit_type: soft
+ limit_item: nofile
+ value: '64000'
+ dest: "{{ test_limit_file }}"
+ check_mode: true
+ register: check_mode_test
+
+- name: Test that check mode is working
+ assert:
+ that:
+ - check_mode_test is changed
+
+- name: Add soft limit for smith user
+ community.general.pam_limits:
+ domain: smith
+ limit_type: soft
+ limit_item: nofile
+ value: '64000'
+ dest: "{{ test_limit_file }}"
+ register: soft_limit_test
+
+- name: Check if changes are made
+ assert:
+ that:
+ - soft_limit_test is changed
+
+- name: Aagin change soft limit for smith user for idempotency
+ community.general.pam_limits:
+ domain: smith
+ limit_type: soft
+ limit_item: nofile
+ value: '64000'
+ dest: "{{ test_limit_file }}"
+ register: soft_limit_test
+
+- name: Check if changes are not made idempotency
+ assert:
+ that:
+ - not soft_limit_test.changed
+
+- name: Change hard limit for Joe user for diff
+ community.general.pam_limits:
+ domain: joe
+ limit_type: hard
+ limit_item: nofile
+ value: '100000'
+ dest: "{{ test_limit_file }}"
+ register: hard_limit_test
+ diff: true
+
+- name: Debugging output for hard limit test
+ debug:
+ msg: "{{ hard_limit_test }}"
+
+- name: Check if changes made
+ assert:
+ that:
+ - hard_limit_test is changed
+ - hard_limit_test.diff.after is defined
+ - hard_limit_test.diff.before is defined
+
+- name: Add comment with change
+ community.general.pam_limits:
+ domain: doom
+ limit_type: hard
+ limit_item: nofile
+ value: '100000'
+ dest: "{{ test_limit_file }}"
+ comment: "This is a nice comment"
+ register: comment_test
+
+- name: Check if changes made
+ assert:
+ that:
+ - comment_test is changed
diff --git a/ansible_collections/community/general/tests/integration/targets/pamd/aliases b/ansible_collections/community/general/tests/integration/targets/pamd/aliases
new file mode 100644
index 000000000..b85ae6419
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pamd/aliases
@@ -0,0 +1,9 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+skip/aix
+skip/freebsd
+skip/osx
+skip/macos
diff --git a/ansible_collections/community/general/tests/integration/targets/pamd/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/pamd/tasks/main.yml
new file mode 100644
index 000000000..fdd16d166
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pamd/tasks/main.yml
@@ -0,0 +1,74 @@
+# Copyright (c) 2021, Alexei Znamensky
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Set value for temp limit configuration
+ set_fact:
+ test_pamd_file: "/tmp/pamd_file"
+
+- name: Create temporary pam.d file
+ copy:
+ content: "session required pam_lastlog.so silent showfailed"
+ dest: "{{ test_pamd_file }}"
+- name: Test working on a single-line file works (2925)
+ community.general.pamd:
+ path: /tmp
+ name: pamd_file
+ type: session
+ control: required
+ module_path: pam_lastlog.so
+ module_arguments: silent
+ state: args_absent
+ register: pamd_file_output
+- name: Check if changes made
+ assert:
+ that:
+ - pamd_file_output is changed
+
+- name: Test removing all arguments from an entry (3260)
+ community.general.pamd:
+ path: /tmp
+ name: pamd_file
+ type: session
+ control: required
+ module_path: pam_lastlog.so
+ module_arguments: ""
+ state: updated
+ register: pamd_file_output_noargs
+- name: Read back the file (3260)
+ slurp:
+ src: "{{ test_pamd_file }}"
+ register: pamd_file_slurp_noargs
+- name: Check if changes made (3260)
+ vars:
+ line_array: "{{ (pamd_file_slurp_noargs.content|b64decode).split('\n')[2].split() }}"
+ assert:
+ that:
+ - pamd_file_output_noargs is changed
+ - line_array == ['session', 'required', 'pam_lastlog.so']
+
+- name: Create temporary pam.d file
+ copy:
+ content: ""
+ dest: "{{ test_pamd_file }}"
+# This test merely demonstrates that, as-is, module will not perform any changes on an empty file
+# All the existing values for "state" will first search for a rule matching type, control, module_path
+# and will not perform any change whatsoever if no existing rules match.
+- name: Test working on a empty file works (2925)
+ community.general.pamd:
+ path: /tmp
+ name: pamd_file
+ type: session
+ control: required
+ module_path: pam_lastlog.so
+ module_arguments: silent
+ register: pamd_file_output_empty
+- name: Read back the file
+ slurp:
+ src: "{{ test_pamd_file }}"
+ register: pamd_file_slurp
+- name: Check if changes made
+ assert:
+ that:
+ - pamd_file_output_empty is not changed
+ - pamd_file_slurp.content|b64decode == ''
diff --git a/ansible_collections/community/general/tests/integration/targets/parted/aliases b/ansible_collections/community/general/tests/integration/targets/parted/aliases
new file mode 100644
index 000000000..b2b1b25fd
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/parted/aliases
@@ -0,0 +1,13 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+azp/posix/vm
+skip/aix
+skip/freebsd
+skip/osx
+skip/macos
+skip/docker
+needs/root
+destructive
diff --git a/ansible_collections/community/general/tests/integration/targets/parted/handlers/main.yml b/ansible_collections/community/general/tests/integration/targets/parted/handlers/main.yml
new file mode 100644
index 000000000..e292260d0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/parted/handlers/main.yml
@@ -0,0 +1,14 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Remove loopback device
+ command:
+ cmd: losetup -d {{ losetup_name.stdout }}
+ changed_when: true
+
+- name: Remove file
+ file:
+ path: /bigfile
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/parted/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/parted/tasks/main.yml
new file mode 100644
index 000000000..c91258d35
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/parted/tasks/main.yml
@@ -0,0 +1,86 @@
+# Copyright (c) 2021, Alexei Znamensky
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install parted
+ package:
+ name: parted
+ state: present
+ when: ansible_os_family == 'Alpine'
+
+- name: Create empty file
+ community.general.filesize:
+ path: /bigfile
+ size: 1GiB
+ notify: Remove file
+
+- name: Obtain loop device name
+ command:
+ cmd: losetup -f
+ changed_when: false
+ register: losetup_name
+
+- name: Create loopback device
+ command:
+ cmd: losetup -f /bigfile
+ changed_when: true
+ register: losetup_cmd
+ notify: Remove loopback device
+
+- name: Create first partition
+ community.general.parted:
+ device: "{{ losetup_name.stdout }}"
+ number: 1
+ state: present
+ fs_type: ext4
+ part_end: "50%"
+ register: partition1
+
+- name: Make filesystem
+ community.general.filesystem:
+ device: "{{ losetup_name.stdout }}p1"
+ fstype: ext4
+ register: fs1_succ
+
+- name: Make filesystem (fail)
+ community.general.filesystem:
+ device: "{{ losetup_name.stdout }}p2"
+ fstype: ext4
+ ignore_errors: true
+ register: fs_fail
+
+- name: Create second partition
+ community.general.parted:
+ device: "{{ losetup_name.stdout }}"
+ number: 2
+ state: present
+ fs_type: ext4
+ part_start: "{{ partition1.partitions[0].end + 1 }}KiB"
+ part_end: "100%"
+ register: partition2
+
+- name: Make filesystem
+ community.general.filesystem:
+ device: "{{ losetup_name.stdout }}p2"
+ fstype: ext4
+ register: fs2_succ
+
+- name: Remove first partition
+ community.general.parted:
+ device: "{{ losetup_name.stdout }}"
+ number: 1
+ state: absent
+ register: partition_rem1
+
+- name: Assert results
+ assert:
+ that:
+ - partition1 is changed
+ - fs1_succ is changed
+ - fs_fail is failed
+ - fs_fail is not changed
+ - partition2 is changed
+ - partition2.partitions | length == 2
+ - fs2_succ is changed
+ - partition_rem1 is changed
+ - partition_rem1.partitions | length == 1
diff --git a/ansible_collections/community/general/tests/integration/targets/pids/aliases b/ansible_collections/community/general/tests/integration/targets/pids/aliases
new file mode 100644
index 000000000..343f119da
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pids/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/3
diff --git a/ansible_collections/community/general/tests/integration/targets/pids/files/sleeper.c b/ansible_collections/community/general/tests/integration/targets/pids/files/sleeper.c
new file mode 100644
index 000000000..16d4b0eaa
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pids/files/sleeper.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2022, Alexei Znamensky <russoz@gmail.com>
+ * GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+
+int main(int argc, char **argv) {
+ int delay = atoi(argv[1]);
+ sleep(delay);
+}
diff --git a/ansible_collections/community/general/tests/integration/targets/pids/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/pids/meta/main.yml
new file mode 100644
index 000000000..982de6eb0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pids/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/pids/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/pids/tasks/main.yml
new file mode 100644
index 000000000..2ba7f3754
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pids/tasks/main.yml
@@ -0,0 +1,120 @@
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Test code for the pids module
+# Copyright (c) 2019, Saranya Sridharan
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Attempt installation of latest 'psutil' version
+ pip:
+ name: psutil
+ ignore_errors: true
+ register: psutil_latest_install
+
+- name: Install greatest 'psutil' version which will work with all pip versions
+ pip:
+ name: psutil < 5.7.0
+ when: psutil_latest_install is failed
+
+- name: "Checking the empty result"
+ pids:
+ name: "blahblah"
+ register: emptypids
+
+- name: "Verify that the list of Process IDs (PIDs) returned is empty"
+ assert:
+ that:
+ - emptypids is not changed
+ - emptypids.pids == []
+
+- name: "Picking a random process name"
+ set_fact:
+ random_name: some-random-long-name-{{ 10000000000 + (9999999999 | random) }}
+
+- name: Copy the fake 'sleep' source code
+ copy:
+ src: sleeper.c
+ dest: "{{ remote_tmp_dir }}/sleeper.c"
+ mode: 0644
+
+- name: Compile fake 'sleep' binary
+ command: cc {{ remote_tmp_dir }}/sleeper.c -o {{ remote_tmp_dir }}/{{ random_name }}
+
+- name: Copy templated helper script
+ template:
+ src: obtainpid.sh
+ dest: "{{ remote_tmp_dir }}/obtainpid.sh"
+ mode: 0755
+
+- name: "Run the fake 'sleep' binary"
+ command: sh {{ remote_tmp_dir }}/obtainpid.sh
+ async: 100
+ poll: 0
+
+- name: "Wait for one second to make sure that the fake 'sleep' binary has actually been started"
+ pause:
+ seconds: 1
+
+- name: "Checking the process IDs (PIDs) of fake 'sleep' binary"
+ pids:
+ name: "{{ random_name }}"
+ register: pids
+
+- name: "Checking that exact non-substring matches are required"
+ pids:
+ name: "{{ random_name[0:25] }}"
+ register: exactpidmatch
+
+- name: "Checking that patterns can be used with the pattern option"
+ pids:
+ pattern: "{{ random_name[0:25] }}"
+ register: pattern_pid_match
+
+- name: "Checking that case-insensitive patterns can be used with the pattern option"
+ pids:
+ pattern: "{{ random_name[0:25] | upper }}"
+ ignore_case: true
+ register: caseinsensitive_pattern_pid_match
+
+- name: "Checking that .* includes test pid"
+ pids:
+ pattern: .*
+ register: match_all
+
+- name: "Reading pid from the file"
+ slurp:
+ src: "{{ remote_tmp_dir }}/obtainpid.txt"
+ register: newpid
+
+- name: Gather all processes to make debugging easier
+ command: ps aux
+ register: result
+ no_log: true
+
+- name: List all processes to make debugging easier
+ debug:
+ var: result.stdout_lines
+
+- name: "Verify that the Process IDs (PIDs) returned is not empty and also equal to the PIDs obtained in console"
+ assert:
+ that:
+ - "pids.pids | join(' ') == newpid.content | b64decode | trim"
+ - "pids.pids | length > 0"
+ - "exactpidmatch.pids == []"
+ - "pattern_pid_match.pids | join(' ') == newpid.content | b64decode | trim"
+ - "caseinsensitive_pattern_pid_match.pids | join(' ') == newpid.content | b64decode | trim"
+ - newpid.content | b64decode | trim | int in match_all.pids
+
+- name: "Register output of bad input pattern"
+ pids:
+ pattern: (unterminated
+ register: bad_pattern_result
+ ignore_errors: true
+
+- name: "Verify that bad input pattern result is failed"
+ assert:
+ that:
+ - bad_pattern_result is failed
diff --git a/ansible_collections/community/general/tests/integration/targets/pids/templates/obtainpid.sh b/ansible_collections/community/general/tests/integration/targets/pids/templates/obtainpid.sh
new file mode 100644
index 000000000..ecbf56aab
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pids/templates/obtainpid.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+"{{ remote_tmp_dir }}/{{ random_name }}" 100 &
+echo "$!" > "{{ remote_tmp_dir }}/obtainpid.txt"
diff --git a/ansible_collections/community/general/tests/integration/targets/pipx/aliases b/ansible_collections/community/general/tests/integration/targets/pipx/aliases
new file mode 100644
index 000000000..9f87ec348
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pipx/aliases
@@ -0,0 +1,8 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+destructive
+skip/python2
+skip/python3.5
diff --git a/ansible_collections/community/general/tests/integration/targets/pipx/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/pipx/tasks/main.yml
new file mode 100644
index 000000000..567405ec4
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pipx/tasks/main.yml
@@ -0,0 +1,316 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: install pipx
+ pip:
+ name: pipx
+ extra_args: --user
+
+##############################################################################
+- name: ensure application tox is uninstalled
+ community.general.pipx:
+ state: absent
+ name: tox
+ register: uninstall_tox
+
+- name: install application tox
+ community.general.pipx:
+ name: tox
+ register: install_tox
+
+- name: set fact latest_tox_version
+ set_fact:
+ latest_tox_version: "{{ install_tox.application.tox.version }}"
+
+- name: install application tox again
+ community.general.pipx:
+ name: tox
+ register: install_tox_again
+
+- name: install application tox again force
+ community.general.pipx:
+ name: tox
+ force: true
+ register: install_tox_again_force
+
+- name: uninstall application tox
+ community.general.pipx:
+ state: absent
+ name: tox
+ register: uninstall_tox
+
+- name: check assertions tox
+ assert:
+ that:
+ - install_tox is changed
+ - "'tox' in install_tox.application"
+ - install_tox_again is not changed
+ - install_tox_again_force is changed
+ - uninstall_tox is changed
+ - "'tox' not in uninstall_tox.application"
+
+##############################################################################
+- name: install application tox with system-site-packages
+ community.general.pipx:
+ name: tox
+ system_site_packages: true
+ register: install_tox
+
+- name: get raw pipx_info
+ community.general.pipx_info:
+ include_raw: true
+ register: pipx_info_raw
+
+- name: uninstall application tox
+ community.general.pipx:
+ state: absent
+ name: tox
+ register: uninstall_tox
+
+- name: check assertions tox
+ assert:
+ that:
+ - install_tox is changed
+ - "'tox' in install_tox.application"
+ - pipx_info_raw is not changed
+ - "'--system-site-packages' in pipx_info_raw.raw_output.venvs.tox.metadata.venv_args"
+ - uninstall_tox is changed
+ - "'tox' not in uninstall_tox.application"
+
+##############################################################################
+- name: install application tox 3.24.0
+ community.general.pipx:
+ name: tox
+ source: tox==3.24.0
+ register: install_tox_324
+
+- name: reinstall tox 3.24.0
+ community.general.pipx:
+ name: tox
+ state: reinstall
+ register: reinstall_tox_324
+
+- name: reinstall without name
+ community.general.pipx:
+ state: reinstall
+ register: reinstall_noname
+ ignore_errors: true
+
+- name: upgrade tox from 3.24.0
+ community.general.pipx:
+ name: tox
+ state: upgrade
+ register: upgrade_tox_324
+
+- name: upgrade without name
+ community.general.pipx:
+ state: upgrade
+ register: upgrade_noname
+ ignore_errors: true
+
+- name: downgrade tox 3.24.0
+ community.general.pipx:
+ name: tox
+ source: tox==3.24.0
+ force: true
+ register: downgrade_tox_324
+
+- name: cleanup tox 3.24.0
+ community.general.pipx:
+ state: absent
+ name: tox
+ register: uninstall_tox_324
+
+- name: check assertions tox 3.24.0
+ assert:
+ that:
+ - install_tox_324 is changed
+ - "'tox' in install_tox_324.application"
+ - install_tox_324.application.tox.version == '3.24.0'
+ - reinstall_tox_324 is changed
+ - reinstall_tox_324.application.tox.version == '3.24.0'
+ - upgrade_tox_324 is changed
+ - upgrade_tox_324.application.tox.version != '3.24.0'
+ - downgrade_tox_324 is changed
+ - downgrade_tox_324.application.tox.version == '3.24.0'
+ - uninstall_tox_324 is changed
+ - "'tox' not in uninstall_tox_324.application"
+ - upgrade_noname is failed
+ - reinstall_noname is failed
+
+##############################################################################
+- name: install application latest tox
+ community.general.pipx:
+ name: tox
+ state: latest
+ register: install_tox_latest
+
+- name: cleanup tox latest
+ community.general.pipx:
+ state: absent
+ name: tox
+ register: uninstall_tox_latest
+
+- name: install application tox 3.24.0 for latest
+ community.general.pipx:
+ name: tox
+ source: tox==3.24.0
+ register: install_tox_324_for_latest
+
+- name: install application latest tox
+ community.general.pipx:
+ name: tox
+ state: latest
+ register: install_tox_latest_with_preinstall
+
+- name: install application latest tox again
+ community.general.pipx:
+ name: tox
+ state: latest
+ register: install_tox_latest_with_preinstall_again
+
+- name: install application latest tox
+ community.general.pipx:
+ name: tox
+ state: latest
+ force: true
+ register: install_tox_latest_with_preinstall_again_force
+
+- name: cleanup tox latest again
+ community.general.pipx:
+ state: absent
+ name: tox
+ register: uninstall_tox_latest_again
+
+- name: install application tox with deps
+ community.general.pipx:
+ state: latest
+ name: tox
+ install_deps: true
+ register: install_tox_with_deps
+
+- name: cleanup tox latest yet again
+ community.general.pipx:
+ state: absent
+ name: tox
+ register: uninstall_tox_again
+
+- name: check assertions tox latest
+ assert:
+ that:
+ - install_tox_latest is changed
+ - uninstall_tox_latest is changed
+ - install_tox_324_for_latest is changed
+ - install_tox_324_for_latest.application.tox.version == '3.24.0'
+ - install_tox_latest_with_preinstall is changed
+ - install_tox_latest_with_preinstall.application.tox.version == latest_tox_version
+ - install_tox_latest_with_preinstall_again is not changed
+ - install_tox_latest_with_preinstall_again.application.tox.version == latest_tox_version
+ - install_tox_latest_with_preinstall_again_force is changed
+ - install_tox_latest_with_preinstall_again_force.application.tox.version == latest_tox_version
+ - uninstall_tox_latest_again is changed
+ - install_tox_with_deps is changed
+ - install_tox_with_deps.application.tox.version == latest_tox_version
+ - uninstall_tox_again is changed
+ - "'tox' not in uninstall_tox_again.application"
+
+##############################################################################
+- name: ensure application ansible-lint is uninstalled
+ community.general.pipx:
+ name: ansible-lint
+ state: absent
+
+- name: install application ansible-lint
+ community.general.pipx:
+ name: ansible-lint
+ register: install_ansible_lint
+
+- name: inject packages
+ community.general.pipx:
+ state: inject
+ name: ansible-lint
+ inject_packages:
+ - licenses
+ register: inject_pkgs_ansible_lint
+
+- name: inject packages with apps
+ community.general.pipx:
+ state: inject
+ name: ansible-lint
+ inject_packages:
+ - black
+ install_apps: true
+ register: inject_pkgs_apps_ansible_lint
+
+- name: cleanup ansible-lint
+ community.general.pipx:
+ state: absent
+ name: ansible-lint
+ register: uninstall_ansible_lint
+
+- name: check assertions inject_packages
+ assert:
+ that:
+ - install_ansible_lint is changed
+ - inject_pkgs_ansible_lint is changed
+ - '"ansible-lint" in inject_pkgs_ansible_lint.application'
+ - '"licenses" in inject_pkgs_ansible_lint.application["ansible-lint"]["injected"]'
+ - inject_pkgs_apps_ansible_lint is changed
+ - '"ansible-lint" in inject_pkgs_apps_ansible_lint.application'
+ - '"black" in inject_pkgs_apps_ansible_lint.application["ansible-lint"]["injected"]'
+ - uninstall_ansible_lint is changed
+
+##############################################################################
+- name: install jupyter - not working smoothly in freebsd
+ when: ansible_system != 'FreeBSD'
+ block:
+ - name: ensure application jupyter is uninstalled
+ community.general.pipx:
+ name: jupyter
+ state: absent
+
+ - name: install application jupyter
+ community.general.pipx:
+ name: jupyter
+ install_deps: true
+ register: install_jupyter
+
+ - name: cleanup jupyter
+ community.general.pipx:
+ state: absent
+ name: jupyter
+
+ - name: check assertions
+ assert:
+ that:
+ - install_jupyter is changed
+ - '"ipython" in install_jupyter.stdout'
+
+##############################################################################
+- name: ensure /opt/pipx
+ ansible.builtin.file:
+ path: /opt/pipx
+ state: directory
+ mode: 0755
+
+- name: install tox site-wide
+ community.general.pipx:
+ name: tox
+ state: latest
+ register: install_tox_sitewide
+ environment:
+ PIPX_HOME: /opt/pipx
+ PIPX_BIN_DIR: /usr/local/bin
+
+- name: stat /usr/local/bin/tox
+ ansible.builtin.stat:
+ path: /usr/local/bin/tox
+ register: usrlocaltox
+
+- name: check assertions
+ ansible.builtin.assert:
+ that:
+ - install_tox_sitewide is changed
+ - usrlocaltox.stat.exists
diff --git a/ansible_collections/community/general/tests/integration/targets/pipx_info/aliases b/ansible_collections/community/general/tests/integration/targets/pipx_info/aliases
new file mode 100644
index 000000000..a28278bbc
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pipx_info/aliases
@@ -0,0 +1,8 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/3
+destructive
+skip/python2
+skip/python3.5
diff --git a/ansible_collections/community/general/tests/integration/targets/pipx_info/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/pipx_info/tasks/main.yml
new file mode 100644
index 000000000..0a01f0af9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pipx_info/tasks/main.yml
@@ -0,0 +1,140 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: install pipx
+ pip:
+ name: pipx
+ extra_args: --user
+
+##############################################################################
+- name: ensure application tox is uninstalled
+ community.general.pipx:
+ state: absent
+ name: tox
+
+- name: retrieve applications (empty)
+ community.general.pipx_info: {}
+ register: info_empty
+
+- name: install application tox
+ community.general.pipx:
+ name: tox
+
+- name: retrieve applications
+ community.general.pipx_info: {}
+ register: info_all
+
+- name: retrieve applications (include_deps=true)
+ community.general.pipx_info:
+ include_deps: true
+ register: info_all_deps
+
+- name: retrieve application tox
+ community.general.pipx_info:
+ name: tox
+ include_deps: true
+ register: info_tox
+
+- name: uninstall application tox
+ community.general.pipx:
+ state: absent
+ name: tox
+
+- name: check assertions tox
+ assert:
+ that:
+ - info_empty.application|length == 0
+
+ - info_all.application|length == 1
+ - info_all.application[0].name == "tox"
+ - "'version' in info_all.application[0]"
+ - "'dependencies' not in info_all.application[0]"
+ - "'injected' not in info_all.application[0]"
+
+ - info_all_deps.application|length == 1
+ - info_all_deps.application[0].name == "tox"
+ - "'version' in info_all_deps.application[0]"
+ - info_all_deps.application[0].dependencies == ["chardet", "virtualenv"]
+ or info_all_deps.application[0].dependencies == ["virtualenv"]
+ - "'injected' not in info_all.application[0]"
+
+ - info_tox.application == info_all_deps.application
+
+##############################################################################
+- name: set test applications
+ set_fact:
+ apps:
+ - name: tox
+ source: tox==3.24.0
+ - name: ansible-lint
+ inject_packages:
+ - licenses
+
+- name: ensure applications are uninstalled
+ community.general.pipx:
+ name: "{{ item.name }}"
+ state: absent
+ loop: "{{ apps }}"
+
+- name: install applications
+ community.general.pipx:
+ name: "{{ item.name }}"
+ source: "{{ item.source|default(omit) }}"
+ loop: "{{ apps }}"
+
+- name: inject packages
+ community.general.pipx:
+ state: inject
+ name: "{{ item.name }}"
+ inject_packages: "{{ item.inject_packages }}"
+ when: "'inject_packages' in item"
+ loop: "{{ apps }}"
+
+- name: retrieve applications
+ community.general.pipx_info: {}
+ register: info2_all
+
+- name: retrieve applications (include_deps=true)
+ community.general.pipx_info:
+ include_deps: true
+ include_injected: true
+ register: info2_all_deps
+
+- name: retrieve application ansible-lint
+ community.general.pipx_info:
+ name: ansible-lint
+ include_deps: true
+ include_injected: true
+ register: info2_lint
+
+- name: ensure applications are uninstalled
+ community.general.pipx:
+ name: "{{ item.name }}"
+ state: absent
+ loop: "{{ apps }}"
+
+- name: check assertions multiple apps
+ assert:
+ that:
+ - all_apps|length == 2
+ - all_apps[1].name == "tox"
+ - all_apps[1].version == "3.24.0"
+ - "'dependencies' not in all_apps[1]"
+ - "'injected' not in all_apps[1]"
+
+ - all_apps_deps|length == 2
+ - all_apps_deps[1].name == "tox"
+ - all_apps_deps[1].version == "3.24.0"
+ - all_apps_deps[1].dependencies == ["virtualenv"]
+ - "'injected' in all_apps_deps[0]"
+ - "'licenses' in all_apps_deps[0].injected"
+
+ - lint|length == 1
+ - all_apps_deps|length == 2
+ - lint[0] == all_apps_deps[0]
+ vars:
+ all_apps: "{{ info2_all.application|sort(attribute='name') }}"
+ all_apps_deps: "{{ info2_all_deps.application|sort(attribute='name') }}"
+ lint: "{{ info2_lint.application|sort(attribute='name') }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/pkgng/aliases b/ansible_collections/community/general/tests/integration/targets/pkgng/aliases
new file mode 100644
index 000000000..e13fde32c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pkgng/aliases
@@ -0,0 +1,9 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+needs/root
+skip/docker
+skip/osx
+skip/rhel
diff --git a/ansible_collections/community/general/tests/integration/targets/pkgng/tasks/create-outofdate-pkg.yml b/ansible_collections/community/general/tests/integration/targets/pkgng/tasks/create-outofdate-pkg.yml
new file mode 100644
index 000000000..4028c57d8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pkgng/tasks/create-outofdate-pkg.yml
@@ -0,0 +1,52 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create temporary directory for package creation
+ tempfile:
+ state: directory
+ register: pkgng_test_outofdate_pkg_tempdir
+
+- name: Copy intentionally out-of-date package manifest to testhost
+ template:
+ src: MANIFEST.json.j2
+ # Plus-sign must be added at the destination
+ # CI doesn't like files with '+' in them in the repository
+ dest: '{{ pkgng_test_outofdate_pkg_tempdir.path }}/MANIFEST'
+
+- name: Create out-of-date test package file
+ command:
+ argv:
+ - pkg
+ - create
+ - '--verbose'
+ - '--out-dir'
+ - '{{ pkgng_test_outofdate_pkg_tempdir.path }}'
+ - '--manifest'
+ - '{{ pkgng_test_outofdate_pkg_tempdir.path }}/MANIFEST'
+
+# pkg switched from .txz to .pkg in version 1.17.0
+# Might as well look for all valid pkg extensions.
+- name: Find created package file
+ find:
+ path: '{{ pkgng_test_outofdate_pkg_tempdir.path }}'
+ use_regex: true
+ pattern: '.*\.(pkg|tzst|t[xbg]z|tar)'
+ register: pkgng_test_outofdate_pkg_tempfile
+
+- name: There should be only one package
+ assert:
+ that:
+ - pkgng_test_outofdate_pkg_tempfile.files | count == 1
+
+- name: Copy the created package file to the expected location
+ copy:
+ remote_src: true
+ src: '{{ pkgng_test_outofdate_pkg_tempfile.files[0].path }}'
+ dest: '{{ pkgng_test_outofdate_pkg_path }}'
+
+- name: Remove temporary directory
+ file:
+ state: absent
+ path: '{{ pkgng_test_outofdate_pkg_tempdir.path }}'
diff --git a/ansible_collections/community/general/tests/integration/targets/pkgng/tasks/freebsd.yml b/ansible_collections/community/general/tests/integration/targets/pkgng/tasks/freebsd.yml
new file mode 100644
index 000000000..0c8001899
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pkgng/tasks/freebsd.yml
@@ -0,0 +1,551 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+##
+## pkgng - prepare test environment
+##
+- name: Remove test package
+ pkgng:
+ name: '{{ pkgng_test_pkg_name }}'
+ state: absent
+
+##
+## pkgng - example - state=present for single package
+##
+- name: 'state=present for single package'
+ include_tasks: install_single_package.yml
+
+##
+## pkgng - example - state=latest for already up-to-date package
+##
+- name: Upgrade package (idempotent)
+ pkgng:
+ name: '{{ pkgng_test_pkg_name }}'
+ state: latest
+ register: pkgng_example2
+
+- name: Ensure pkgng does not upgrade up-to-date package
+ assert:
+ that:
+ - not pkgng_example2.changed
+
+##
+## pkgng - example - state=absent for single package
+##
+- name: Verify package sentinel file is present
+ stat:
+ path: '{{ pkgng_test_pkg_sentinelfile_path }}'
+ get_attributes: false
+ get_checksum: false
+ get_mime: false
+ register: pkgng_example3_stat_before
+
+- name: Install package (checkmode)
+ pkgng:
+ name: '{{ pkgng_test_pkg_name }}'
+ check_mode: true
+ register: pkgng_example3_checkmode
+
+- name: Remove package
+ pkgng:
+ name: '{{ pkgng_test_pkg_name }}'
+ state: absent
+ register: pkgng_example3
+
+- name: Remove package (idempotent)
+ pkgng:
+ name: '{{ pkgng_test_pkg_name }}'
+ state: absent
+ register: pkgng_example3_idempotent
+
+- name: Verify package sentinel file is not present
+ stat:
+ path: '{{ pkgng_test_pkg_sentinelfile_path }}'
+ get_attributes: false
+ get_checksum: false
+ get_mime: false
+ register: pkgng_example3_stat_after
+
+- name: Ensure pkgng installs package correctly
+ assert:
+ that:
+ - pkgng_example3_stat_before.stat.exists
+ - pkgng_example3_stat_before.stat.executable
+ - not pkgng_example3_checkmode.changed
+ - pkgng_example3.changed
+ - not pkgng_example3_idempotent.changed
+ - not pkgng_example3_stat_after.stat.exists
+
+##
+## pkgng - example - state=latest for out-of-date package
+##
+- name: Install intentionally out-of-date package and upgrade it
+ #
+ # NOTE: The out-of-date package provided is a minimal,
+ # no-contents test package that declares {{ pkgng_test_pkg_name }} with
+ # a version of 0, so it should always be upgraded.
+ #
+ # This test might fail at some point in the
+ # future if the FreeBSD package format receives
+ # breaking changes that prevent pkg from installing
+ # older package formats.
+ #
+ block:
+ - name: Create out-of-date test package
+ import_tasks: create-outofdate-pkg.yml
+
+ - name: Install out-of-date test package
+ command: 'pkg add {{ pkgng_test_outofdate_pkg_path }}'
+ register: pkgng_example4_prepare
+
+ - name: Check for any available package upgrades (checkmode)
+ pkgng:
+ name: '*'
+ state: latest
+ check_mode: true
+ register: pkgng_example4_wildcard_checkmode
+
+ - name: Check for available package upgrade (checkmode)
+ pkgng:
+ name: '{{ pkgng_test_pkg_name }}'
+ state: latest
+ check_mode: true
+ register: pkgng_example4_checkmode
+
+ - name: Upgrade out-of-date package
+ pkgng:
+ name: '{{ pkgng_test_pkg_name }}'
+ state: latest
+ register: pkgng_example4
+
+ - name: Upgrade out-of-date package (idempotent)
+ pkgng:
+ name: '{{ pkgng_test_pkg_name }}'
+ state: latest
+ register: pkgng_example4_idempotent
+
+ - name: Remove test out-of-date package
+ pkgng:
+ name: '{{ pkgng_test_pkg_name }}'
+ state: absent
+
+ - name: Ensure pkgng upgrades package correctly
+ assert:
+ that:
+ - not pkgng_example4_prepare.failed
+ - pkgng_example4_wildcard_checkmode.changed
+ - pkgng_example4_checkmode.changed
+ - pkgng_example4.changed
+ - not pkgng_example4_idempotent.changed
+
+##
+## pkgng - example - state=latest for out-of-date package without privileges
+##
+- name: Install intentionally out-of-date package and try to upgrade it with unprivileged user
+ block:
+ - ansible.builtin.user:
+ name: powerless
+ shell: /bin/bash
+
+ - name: Create out-of-date test package
+ import_tasks: create-outofdate-pkg.yml
+
+ - name: Install out-of-date test package
+ command: 'pkg add {{ pkgng_test_outofdate_pkg_path }}'
+ register: pkgng_example4_nopower_prepare
+
+ - name: Check for any available package upgrades with unprivileged user
+ become: true
+ become_user: powerless
+ pkgng:
+ name: '*'
+ state: latest
+ register: pkgng_example4_nopower_wildcard
+ ignore_errors: true
+
+ - name: Remove test out-of-date package
+ pkgng:
+ name: '{{ pkgng_test_pkg_name }}'
+ state: absent
+
+ - name: Ensure pkgng upgrades package correctly
+ assert:
+ that:
+ - not pkgng_example4_nopower_prepare.failed
+ - pkgng_example4_nopower_wildcard.failed
+
+##
+## pkgng - example - Install multiple packages in one command
+##
+- name: Remove test package (checkmode)
+ pkgng:
+ name: '{{ pkgng_test_pkg_name }}'
+ state: absent
+ check_mode: true
+ register: pkgng_example5_prepare
+
+- name: Install three packages
+ pkgng:
+ name:
+ - '{{ pkgng_test_pkg_name }}'
+ - fish
+ - busybox
+ register: pkgng_example5
+
+- name: Remove three packages
+ pkgng:
+ name:
+ - '{{ pkgng_test_pkg_name }}'
+ - fish
+ - busybox
+ state: absent
+ register: pkgng_example5_cleanup
+
+- name: Ensure pkgng installs multiple packages with one command
+ assert:
+ that:
+ - not pkgng_example5_prepare.changed
+ - pkgng_example5.changed
+ - '(pkgng_example5.stdout | regex_search("^Number of packages to be installed: (\d+)", "\\1", multiline=True) | first | int) >= 3'
+ - '(pkgng_example5.stdout | regex_findall("^Number of packages to be", multiline=True) | count) == 1'
+ - pkgng_example5_cleanup.changed
+
+##
+## pkgng - example - state=latest multiple packages, some already installed
+##
+- name: Remove test package (checkmode)
+ pkgng:
+ name: '{{ pkgng_test_pkg_name }}'
+ state: absent
+ check_mode: true
+ register: pkgng_example6_check
+
+- name: Create out-of-date test package
+ import_tasks: create-outofdate-pkg.yml
+
+- name: Install out-of-date test package
+ command: 'pkg add {{ pkgng_test_outofdate_pkg_path }}'
+ register: pkgng_example6_prepare
+
+- name: Upgrade and/or install two packages
+ pkgng:
+ name:
+ - '{{ pkgng_test_pkg_name }}'
+ - fish
+ state: latest
+ register: pkgng_example6
+
+- name: Remove two packages
+ pkgng:
+ name:
+ - '{{ pkgng_test_pkg_name }}'
+ - fish
+ state: absent
+ register: pkgng_example6_cleanup
+
+- name: Ensure pkgng installs multiple packages with one command
+ assert:
+ that:
+ - not pkgng_example6_check.changed
+ - not pkgng_example6_prepare.failed
+ - pkgng_example6.changed
+ - '(pkgng_example6.stdout | regex_search("^Number of packages to be installed: (\d+)", "\\1", multiline=True) | first | int) >= 1'
+ - '(pkgng_example6.stdout | regex_search("^Number of packages to be upgraded: (\d+)", "\\1", multiline=True) | first | int) >= 1'
+ # Checking that "will be affected" occurs twice in the output ensures
+ # that the module runs two separate commands for install and upgrade,
+ # as the pkg command only outputs the string once per invocation.
+ - '(pkgng_example6.stdout | regex_findall("will be affected", multiline=True) | count) == 2'
+ - pkgng_example6_cleanup.changed
+
+##
+## pkgng - example - autoremove=yes
+##
+- name: "Test autoremove=yes"
+ #
+ # NOTE: FreeBSD 12.0 test runner receives a "connection reset by peer" after ~20% downloaded so we are
+ # only running this on 12.1 or higher
+ #
+ when: ansible_distribution_version is version('12.01', '>=')
+ block:
+ - name: Install GNU autotools
+ pkgng:
+ name: autotools
+ state: latest
+ register: pkgng_example7_prepare_install
+
+ - name: Remove GNU autotools and run pkg autoremove
+ pkgng:
+ name: autotools
+ state: absent
+ autoremove: true
+ register: pkgng_example7
+
+ - name: Check if autoremove uninstalled known autotools dependencies
+ pkgng:
+ name:
+ - autoconf
+ - automake
+ - libtool
+ state: absent
+ check_mode: true
+ register: pkgng_example7_cleanup
+
+ - name: Ensure pkgng autoremove works correctly
+ assert:
+ that:
+ - pkgng_example7_prepare_install is changed
+ - "'autoremoved' is in(pkgng_example7.msg)"
+ - pkgng_example7_cleanup is not changed
+
+##
+## pkgng - example - single annotations
+##
+- name: Install and annotate single package
+ pkgng:
+ name: '{{ pkgng_test_pkg_name }}'
+ annotation: '+ansibletest_example8=added'
+ register: pkgng_example8_add_annotation
+
+- name: Should fail to add duplicate annotation
+ pkgng:
+ name: '{{ pkgng_test_pkg_name }}'
+ annotation: '+ansibletest_example8=duplicate'
+ ignore_errors: true
+ register: pkgng_example8_add_annotation_failure
+
+- name: Verify annotation is actually there
+ command: 'pkg annotate -q -S {{ pkgng_test_pkg_name }} ansibletest_example8'
+ register: pkgng_example8_add_annotation_verify
+
+- name: Install and annotate single package (checkmode, not changed)
+ pkgng:
+ name: '{{ pkgng_test_pkg_name }}'
+ annotation: '+ansibletest_example8=added'
+ check_mode: true
+ register: pkgng_example8_add_annotation_checkmode_nochange
+
+- name: Install and annotate single package (checkmode, changed)
+ pkgng:
+ name: '{{ pkgng_test_pkg_name }}'
+ annotation: '+ansibletest_example8_checkmode=added'
+ check_mode: true
+ register: pkgng_example8_add_annotation_checkmode_change
+
+- name: Verify check_mode did not add an annotation
+ command: 'pkg annotate -q -S {{ pkgng_test_pkg_name }} ansibletest_example8_checkmode'
+ register: pkgng_example8_add_annotation_checkmode_change_verify
+
+- name: Modify annotation on single package
+ pkgng:
+ name: '{{ pkgng_test_pkg_name }}'
+ annotation: ':ansibletest_example8=modified'
+ register: pkgng_example8_modify_annotation
+
+- name: Should fail to modify missing annotation
+ pkgng:
+ name: '{{ pkgng_test_pkg_name }}'
+ annotation: ':ansiblemissing=modified'
+ ignore_errors: true
+ register: pkgng_example8_modify_annotation_failure
+
+- name: Verify annotation has been modified
+ command: 'pkg annotate -q -S {{ pkgng_test_pkg_name }} ansibletest_example8'
+ register: pkgng_example8_modify_annotation_verify
+
+- name: Remove annotation on single package
+ pkgng:
+ name: '{{ pkgng_test_pkg_name }}'
+ annotation: '-ansibletest_example8'
+ register: pkgng_example8_remove_annotation
+
+- name: Verify annotation has been removed
+ command: 'pkg annotate -q -S {{ pkgng_test_pkg_name }} ansibletest_example8'
+ register: pkgng_example8_remove_annotation_verify
+
+- name: Ensure pkgng annotations on single packages work correctly
+ assert:
+ that:
+ - pkgng_example8_add_annotation.changed
+ - pkgng_example8_add_annotation_failure.failed
+ - pkgng_example8_add_annotation_checkmode_nochange is not changed
+ - pkgng_example8_add_annotation_checkmode_change is changed
+ - 'pkgng_example8_add_annotation_checkmode_change_verify.stdout_lines | count == 0'
+ - 'pkgng_example8_add_annotation_verify.stdout_lines | first == "added"'
+ - pkgng_example8_modify_annotation.changed
+ - pkgng_example8_modify_annotation_failure.failed
+ - 'pkgng_example8_modify_annotation_verify.stdout_lines | first == "modified"'
+ - pkgng_example8_remove_annotation.changed
+ - 'pkgng_example8_remove_annotation_verify.stdout_lines | count == 0'
+
+##
+## pkgng - example - multiple annotations
+##
+- name: Annotate single package with multiple annotations
+ pkgng:
+ name: '{{ pkgng_test_pkg_name }}'
+ annotation:
+ - '+ansibletest_example9_1=added'
+ - '+ansibletest_example9_2=added'
+ register: pkgng_example9_add_annotation
+
+- name: Verify annotation is actually there
+ command: 'pkg info -q -A {{ pkgng_test_pkg_name }}'
+ register: pkgng_example9_add_annotation_verify
+ # Assert, below, tests that stdout includes:
+ # ```
+ # ansibletest_example9_1 : added
+ # ansibletest_example9_2 : added
+ # ```
+
+- name: Multiple annotation operations on single package
+ pkgng:
+ name: '{{ pkgng_test_pkg_name }}'
+ annotation:
+ - ':ansibletest_example9_1=modified'
+ - '+ansibletest_example9_3=added'
+ register: pkgng_example9_multiple_annotation
+
+- name: Verify multiple operations succeeded
+ command: 'pkg info -q -A {{ pkgng_test_pkg_name }}'
+ register: pkgng_example9_multiple_annotation_verify
+ # Assert, below, tests that stdout includes:
+ # ```
+ # ansibletest_example9_1 : modified
+ # ansibletest_example9_2 : added
+ # ansibletest_example9_3 : added
+ # ```
+
+- name: Add multiple annotations with old syntax
+ pkgng:
+ name: '{{ pkgng_test_pkg_name }}'
+ annotation: '+ansibletest_example9_4=added,+ansibletest_example9_5=added'
+ register: pkgng_example9_add_annotation_old
+
+- name: Verify annotation is actually there
+ command: 'pkg info -q -A {{ pkgng_test_pkg_name }}'
+ register: pkgng_example9_add_annotation_old_verify
+ # Assert, below, tests that stdout includes:
+ # ```
+ # ansibletest_example9_4 : added
+ # ansibletest_example9_5 : added
+ # ```
+
+- name: Ensure multiple annotations work correctly
+ assert:
+ that:
+ - pkgng_example9_add_annotation.changed
+ - '(pkgng_example9_add_annotation_verify.stdout_lines | select("match", "ansibletest_example9_[12]\s*:\s*added") | list | count) == 2'
+ - pkgng_example9_multiple_annotation.changed
+ - '(pkgng_example9_multiple_annotation_verify.stdout_lines | select("match", "ansibletest_example9_1\s*:\s*modified") | list | count) == 1'
+ - '(pkgng_example9_multiple_annotation_verify.stdout_lines | select("match", "ansibletest_example9_[23]\s*:\s*added") | list | count) == 2'
+ - pkgng_example9_add_annotation_old.changed
+ - '(pkgng_example9_add_annotation_old_verify.stdout_lines | select("match", "ansibletest_example9_[45]\s*:\s*added") | list | count) == 2'
+
+##
+## pkgng - example - invalid annotation strings
+##
+- name: Should fail on invalid annotate strings
+ pkgng:
+ name: '{{ pkgng_test_pkg_name }}'
+ annotation: '{{ item }}'
+ ignore_errors: true
+ register: pkgng_example8_invalid_annotation_failure
+ loop:
+ - 'naked_string'
+ - '/invalid_operation'
+ - ',empty_first_tag=validsecond'
+ - '=notag'
+
+- name: Verify invalid annotate strings did not add annotations
+ command: 'pkg info -q -A {{ pkgng_test_pkg_name }}'
+ register: pkgng_example8_invalid_annotation_verify
+
+- name: Ensure invalid annotate strings fail safely
+ assert:
+ that:
+ # Invalid strings should not change anything
+ - '(pkgng_example8_invalid_annotation_failure.results | selectattr("changed") | list | count) == 0'
+ # Invalid strings should always fail
+ - '(pkgng_example8_invalid_annotation_failure.results | rejectattr("failed") | list | count) == 0'
+ # Invalid strings should not cause an exception
+ - '(pkgng_example8_invalid_annotation_failure.results | selectattr("exception", "defined") | list | count) == 0'
+ # Verify annotations are unaffected
+ - '(pkgng_example8_invalid_annotation_verify.stdout_lines | select("search", "(naked_string|invalid_operation|empty_first_tag|validsecond|notag)") | list | count) == 0'
+
+##
+## pkgng - example - pkgsite=...
+##
+# NOTE: testing for failure here to not have to set up our own
+# or depend on a third-party, alternate package repo
+- name: Should fail with invalid pkgsite
+ pkgng:
+ name: '{{ pkgng_test_pkg_name }}'
+ pkgsite: DoesNotExist
+ ignore_errors: true
+ register: pkgng_example10_invalid_pkgsite_failure
+
+- name: Ensure invalid pkgsite fails as expected
+ assert:
+ that:
+ - pkgng_example10_invalid_pkgsite_failure.failed
+ - 'pkgng_example10_invalid_pkgsite_failure.stdout is search("^No repositories are enabled.", multiline=True)'
+
+##
+## pkgng - example - Install single package in jail
+##
+- name: Test within jail
+ #
+ # NOTE: FreeBSD 12.0 test runner receives a "connection reset by peer" after ~20% downloaded so we are
+ # only running this on 12.1 or higher
+ #
+ # NOTE: FreeBSD 12.3 fails with some kernel mismatch for packages
+ # (someone with FreeBSD knowledge has to take a look)
+ #
+ # NOTE: FreeBSD 12.4 fails to update repositories because it cannot load certificates from /usr/share/keys/pkg/trusted
+ # (someone with FreeBSD knowledge has to take a look)
+ #
+ # NOTE: FreeBSD 13.0 fails to update the package catalogue for unknown reasons (someone with FreeBSD
+ # knowledge has to take a look)
+ #
+ # NOTE: FreeBSD 13.1 fails to update the package catalogue for unknown reasons (someone with FreeBSD
+ # knowledge has to take a look)
+ #
+ # NOTE: FreeBSD 13.2 fails to update the package catalogue for unknown reasons (someone with FreeBSD
+ # knowledge has to take a look)
+ #
+ # See also
+ # https://github.com/ansible-collections/community.general/issues/5795
+ when: >-
+ (ansible_distribution_version is version('12.01', '>=') and ansible_distribution_version is version('12.3', '<'))
+ or ansible_distribution_version is version('13.3', '>=')
+ block:
+ - name: Setup testjail
+ include_tasks: setup-testjail.yml
+
+ - name: Install package in jail as rootdir
+ include_tasks: install_single_package.yml
+ vars:
+ pkgng_test_rootdir: /usr/jails/testjail
+ pkgng_test_install_prefix: /usr/jails/testjail
+ pkgng_test_install_cleanup: true
+
+ - name: Install package in jail
+ include_tasks: install_single_package.yml
+ vars:
+ pkgng_test_jail: testjail
+ pkgng_test_install_prefix: /usr/jails/testjail
+ pkgng_test_install_cleanup: true
+
+ - name: Install package in jail as chroot
+ include_tasks: install_single_package.yml
+ vars:
+ pkgng_test_chroot: /usr/jails/testjail
+ pkgng_test_install_prefix: /usr/jails/testjail
+ pkgng_test_install_cleanup: true
+ always:
+ - name: Stop and remove testjail
+ failed_when: false
+ changed_when: false
+ command: "ezjail-admin delete -wf testjail"
diff --git a/ansible_collections/community/general/tests/integration/targets/pkgng/tasks/install_single_package.yml b/ansible_collections/community/general/tests/integration/targets/pkgng/tasks/install_single_package.yml
new file mode 100644
index 000000000..5ba529af3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pkgng/tasks/install_single_package.yml
@@ -0,0 +1,58 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Verify package sentinel file is not present
+ stat:
+ path: '{{ pkgng_test_install_prefix | default("") }}{{ pkgng_test_pkg_sentinelfile_path }}'
+ get_attributes: false
+ get_checksum: false
+ get_mime: false
+ register: pkgng_install_stat_before
+
+- name: Install package
+ pkgng: &pkgng_install_params
+ name: '{{ pkgng_test_pkg_name }}'
+ jail: '{{ pkgng_test_jail | default(omit) }}'
+ chroot: '{{ pkgng_test_chroot | default(omit) }}'
+ rootdir: '{{ pkgng_test_rootdir | default(omit) }}'
+ register: pkgng_install
+
+- name: Remove package (checkmode)
+ pkgng:
+ <<: *pkgng_install_params
+ state: absent
+ check_mode: true
+ register: pkgng_install_checkmode
+
+- name: Install package (idempotent, cached)
+ pkgng:
+ <<: *pkgng_install_params
+ cached: true
+ register: pkgng_install_idempotent_cached
+
+- name: Verify package sentinel file is present
+ stat:
+ path: '{{ pkgng_test_install_prefix | default("") }}{{ pkgng_test_pkg_sentinelfile_path }}'
+ get_attributes: false
+ get_checksum: false
+ get_mime: false
+ register: pkgng_install_stat_after
+
+- name: Remove test package (if requested)
+ pkgng:
+ <<: *pkgng_install_params
+ state: absent
+ when: 'pkgng_test_install_cleanup | default(False)'
+
+- name: Ensure pkgng installs package correctly
+ assert:
+ that:
+ - not pkgng_install_stat_before.stat.exists
+ - pkgng_install.changed
+ - pkgng_install_checkmode.changed
+ - not pkgng_install_idempotent_cached.changed
+ - not pkgng_install_idempotent_cached.stdout is match("Updating \w+ repository catalogue\.\.\.")
+ - pkgng_install_stat_after.stat.exists
+ - pkgng_install_stat_after.stat.executable
diff --git a/ansible_collections/community/general/tests/integration/targets/pkgng/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/pkgng/tasks/main.yml
new file mode 100644
index 000000000..59ca83d9f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pkgng/tasks/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- import_tasks: freebsd.yml
+ when:
+ - ansible_facts.distribution == 'FreeBSD'
diff --git a/ansible_collections/community/general/tests/integration/targets/pkgng/tasks/setup-testjail.yml b/ansible_collections/community/general/tests/integration/targets/pkgng/tasks/setup-testjail.yml
new file mode 100644
index 000000000..3055d29e8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pkgng/tasks/setup-testjail.yml
@@ -0,0 +1,100 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+#
+# Instructions for setting up a jail
+# https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/jails-ezjail.html
+#
+- name: Setup cloned interfaces
+ lineinfile:
+ dest: /etc/rc.conf
+ regexp: ^cloned_interfaces=lo1
+ line: cloned_interfaces=lo1
+
+- name: Activate cloned interfaces
+ command: "service netif cloneup"
+ changed_when: false
+
+- name: Add nat rule for cloned interfaces
+ copy:
+ dest: /etc/pf.conf
+ content: |
+ nat on {{ ansible_default_ipv4.interface }} from 127.0.1.0/24 -> {{ ansible_default_ipv4.interface }}:0
+ validate: "pfctl -nf %s"
+
+- name: Start pf firewall
+ service:
+ name: pf
+ state: started
+ enabled: true
+
+- name: Install ezjail
+ pkgng:
+ name: ezjail
+
+- name: Configure ezjail to use http
+ when: ansible_distribution_version is version('11.01', '>')
+ lineinfile:
+ dest: /usr/local/etc/ezjail.conf
+ regexp: ^ezjail_ftphost
+ line: ezjail_ftphost=http://ftp.freebsd.org
+
+- name: Configure ezjail to use archive for old freebsd releases
+ when: ansible_distribution_version is version('11.01', '<=')
+ lineinfile:
+ dest: /usr/local/etc/ezjail.conf
+ regexp: ^ezjail_ftphost
+ line: ezjail_ftphost=http://ftp-archive.freebsd.org
+
+- name: Start ezjail
+ ignore_errors: true
+ service:
+ name: ezjail
+ state: started
+ enabled: true
+
+- name: Redirect logs depending on verbosity
+ set_fact:
+ pkgng_jail_log_redirect: "2>&1 | tee -a /tmp/ezjail.log {{ '> /dev/null' if ansible_verbosity < 2 else '' }}"
+
+- name: Has ezjail
+ register: ezjail_base_jail
+ stat:
+ path: /usr/jails/basejail
+
+- name: Setup ezjail base
+ when: not ezjail_base_jail.stat.exists
+ shell: "ezjail-admin install {{ pkgng_jail_log_redirect }}"
+ changed_when: false
+
+- name: Has testjail
+ register: ezjail_test_jail
+ stat:
+ path: /usr/jails/testjail
+
+- name: Create testjail
+ when: not ezjail_test_jail.stat.exists
+ shell: "ezjail-admin create testjail 'lo1|127.0.1.1' {{ pkgng_jail_log_redirect }}"
+ changed_when: false
+
+- name: Configure testjail to use Cloudflare DNS
+ lineinfile:
+ dest: /usr/jails/testjail/etc/resolv.conf
+ regexp: "^nameserver[[:blank:]]+{{ item }}$"
+ line: "nameserver {{ item }}"
+ create: true
+ loop:
+ - "1.1.1.1"
+ - "1.0.0.1"
+
+- name: Is testjail running
+ shell: "jls | grep testjail"
+ changed_when: false
+ failed_when: false
+ register: is_testjail_up
+
+- name: Start testjail
+ when: is_testjail_up.rc == 1
+ command: "ezjail-admin start testjail"
diff --git a/ansible_collections/community/general/tests/integration/targets/pkgng/templates/MANIFEST.json.j2 b/ansible_collections/community/general/tests/integration/targets/pkgng/templates/MANIFEST.json.j2
new file mode 100644
index 000000000..e8537e89b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pkgng/templates/MANIFEST.json.j2
@@ -0,0 +1,16 @@
+{
+ "name": "{{ pkgng_test_pkg_name }}",
+ "origin": "{{ pkgng_test_pkg_category }}/{{ pkgng_test_pkg_name }}",
+ "version": "{{ pkgng_test_pkg_version | default('0') }}",
+ "comment": "{{ pkgng_test_pkg_name }} (Ansible Integration Test Package)",
+ "maintainer": "ansible-devel@googlegroups.com",
+ "www": "https://github.com/ansible-collections/community.general",
+ "abi": "FreeBSD:*:*",
+ "arch": "freebsd:*:*",
+ "prefix": "/usr/local",
+ "flatsize":0,
+ "licenselogic": "single",
+ "licenses":["GPLv3"],
+ "desc": "This package is only installed temporarily for integration testing of the community.general.pkgng Ansible module.\nIts version number is 0 so that ANY version of the real package, with the same name, will be considered an upgrade.\nIts architecture and abi are FreeBSD:*:* so that it will install on any version or architecture of FreeBSD,\nthus future-proof as long as the package MANIFEST format does not change\nand a wildcard in the version portion of the abi or arch field is not prohibited.",
+ "categories":["{{ pkgng_test_pkg_category }}"]
+}
diff --git a/ansible_collections/community/general/tests/integration/targets/pkgng/templates/MANIFEST.json.j2.license b/ansible_collections/community/general/tests/integration/targets/pkgng/templates/MANIFEST.json.j2.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pkgng/templates/MANIFEST.json.j2.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/pkgng/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/pkgng/vars/main.yml
new file mode 100644
index 000000000..e32cc4110
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pkgng/vars/main.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+pkgng_test_outofdate_pkg_path: "/tmp/ansible_pkgng_test_package.pkg"
+pkgng_test_pkg_name: zsh
+pkgng_test_pkg_category: shells
+pkgng_test_pkg_sentinelfile_path: /usr/local/bin/zsh
diff --git a/ansible_collections/community/general/tests/integration/targets/pkgutil/aliases b/ansible_collections/community/general/tests/integration/targets/pkgutil/aliases
new file mode 100644
index 000000000..4232e0baa
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pkgutil/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+destructive
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/pkgutil/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/pkgutil/tasks/main.yml
new file mode 100644
index 000000000..8ceb4adcc
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/pkgutil/tasks/main.yml
@@ -0,0 +1,117 @@
+# Test code for the pkgutil module
+
+# Copyright (c) 2019, Dag Wieers (@dagwieers) <dag@wieers.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+
+# CLEAN ENVIRONMENT
+- name: Remove CSWtop
+ pkgutil:
+ name: CSWtop
+ state: absent
+ register: originally_installed
+
+
+# ADD PACKAGE
+- name: Add package (check_mode)
+ pkgutil:
+ name: CSWtop
+ state: present
+ check_mode: true
+ register: cm_add_package
+
+- name: Verify cm_add_package
+ assert:
+ that:
+ - cm_add_package is changed
+
+- name: Add package (normal mode)
+ pkgutil:
+ name: CSWtop
+ state: present
+ register: nm_add_package
+
+- name: Verify nm_add_package
+ assert:
+ that:
+ - nm_add_package is changed
+
+- name: Add package again (check_mode)
+ pkgutil:
+ name: CSWtop
+ state: present
+ check_mode: true
+ register: cm_add_package_again
+
+- name: Verify cm_add_package_again
+ assert:
+ that:
+ - cm_add_package_again is not changed
+
+- name: Add package again (normal mode)
+ pkgutil:
+ name: CSWtop
+ state: present
+ register: nm_add_package_again
+
+- name: Verify nm_add_package_again
+ assert:
+ that:
+ - nm_add_package_again is not changed
+
+
+# REMOVE PACKAGE
+- name: Remove package (check_mode)
+ pkgutil:
+ name: CSWtop
+ state: absent
+ check_mode: true
+ register: cm_remove_package
+
+- name: Verify cm_remove_package
+ assert:
+ that:
+ - cm_remove_package is changed
+
+- name: Remove package (normal mode)
+ pkgutil:
+ name: CSWtop
+ state: absent
+ register: nm_remove_package
+
+- name: Verify nm_remove_package
+ assert:
+ that:
+ - nm_remove_package is changed
+
+- name: Remove package again (check_mode)
+ pkgutil:
+ name: CSWtop
+ state: absent
+ check_mode: true
+ register: cm_remove_package_again
+
+- name: Verify cm_remove_package_again
+ assert:
+ that:
+ - cm_remove_package_again is not changed
+
+- name: Remove package again (normal mode)
+ pkgutil:
+ name: CSWtop
+ state: absent
+ register: nm_remove_package_again
+
+- name: Verify nm_remove_package_again
+ assert:
+ that:
+ - nm_remove_package_again is not changed
+
+
+# RESTORE ENVIRONMENT
+- name: Reinstall CSWtop
+ pkgutil:
+ name: CSWtop
+ state: present
+ when: originally_installed is changed
diff --git a/ansible_collections/community/general/tests/integration/targets/proxmox/aliases b/ansible_collections/community/general/tests/integration/targets/proxmox/aliases
new file mode 100644
index 000000000..5e5957a5c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/proxmox/aliases
@@ -0,0 +1,9 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
+proxmox_domain_info
+proxmox_group_info
+proxmox_user_info
+proxmox_storage_info
diff --git a/ansible_collections/community/general/tests/integration/targets/proxmox/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/proxmox/tasks/main.yml
new file mode 100644
index 000000000..22d7fcd29
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/proxmox/tasks/main.yml
@@ -0,0 +1,579 @@
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2020, Tristan Le Guern <tleguern at bouledef.eu>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: List domains
+ proxmox_domain_info:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ validate_certs: "{{ validate_certs }}"
+ register: results
+
+- assert:
+ that:
+ - results is not changed
+ - results.proxmox_domains is defined
+
+- name: Retrieve info about pve
+ proxmox_domain_info:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ validate_certs: "{{ validate_certs }}"
+ domain: pve
+ register: results
+
+- assert:
+ that:
+ - results is not changed
+ - results.proxmox_domains is defined
+ - results.proxmox_domains|length == 1
+ - results.proxmox_domains[0].type == 'pve'
+
+- name: List groups
+ proxmox_group_info:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ validate_certs: "{{ validate_certs }}"
+ register: results
+
+- assert:
+ that:
+ - results is not changed
+ - results.proxmox_groups is defined
+
+- name: List users
+ proxmox_user_info:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ validate_certs: "{{ validate_certs }}"
+ register: results
+
+- assert:
+ that:
+ - results is not changed
+ - results.proxmox_users is defined
+
+- name: Retrieve info about api_user using name and domain
+ proxmox_user_info:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ validate_certs: "{{ validate_certs }}"
+ user: "{{ user }}"
+ domain: "{{ domain }}"
+ register: results_user_domain
+
+- assert:
+ that:
+ - results_user_domain is not changed
+ - results_user_domain.proxmox_users is defined
+ - results_user_domain.proxmox_users|length == 1
+ - results_user_domain.proxmox_users[0].domain == "{{ domain }}"
+ - results_user_domain.proxmox_users[0].user == "{{ user }}"
+ - results_user_domain.proxmox_users[0].userid == "{{ user }}@{{ domain }}"
+
+- name: Retrieve info about api_user using userid
+ proxmox_user_info:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ validate_certs: "{{ validate_certs }}"
+ userid: "{{ user }}@{{ domain }}"
+ register: results_userid
+
+- assert:
+ that:
+ - results_userid is not changed
+ - results_userid.proxmox_users is defined
+ - results_userid.proxmox_users|length == 1
+ - results_userid.proxmox_users[0].domain == "{{ domain }}"
+ - results_userid.proxmox_users[0].user == "{{ user }}"
+ - results_userid.proxmox_users[0].userid == "{{ user }}@{{ domain }}"
+
+- name: Retrieve info about storage
+ proxmox_storage_info:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ validate_certs: "{{ validate_certs }}"
+ storage: "{{ storage }}"
+ register: results_storage
+
+- assert:
+ that:
+ - results_storage is not changed
+ - results_storage.proxmox_storages is defined
+ - results_storage.proxmox_storages|length == 1
+ - results_storage.proxmox_storages[0].storage == "{{ storage }}"
+
+- name: VM creation
+ tags: [ 'create' ]
+ block:
+ - name: Create test vm test-instance
+ proxmox_kvm:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ validate_certs: "{{ validate_certs }}"
+ node: "{{ node }}"
+ storage: "{{ storage }}"
+ vmid: "{{ from_vmid }}"
+ name: test-instance
+ clone: 'yes'
+ state: present
+ timeout: 500
+ register: results_kvm
+
+ - set_fact:
+ vmid: "{{ results_kvm.msg.split(' ')[-7] }}"
+
+ - assert:
+ that:
+ - results_kvm is changed
+ - results_kvm.vmid == from_vmid
+ - results_kvm.msg == "VM test-instance with newid {{ vmid }} cloned from vm with vmid {{ from_vmid }}"
+
+ - pause:
+ seconds: 30
+
+- name: VM start
+ tags: [ 'start' ]
+ block:
+ - name: Start test VM
+ proxmox_kvm:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ validate_certs: "{{ validate_certs }}"
+ node: "{{ node }}"
+ vmid: "{{ vmid }}"
+ state: started
+ register: results_action_start
+
+ - assert:
+ that:
+ - results_action_start is changed
+ - results_action_start.status == 'stopped'
+ - results_action_start.vmid == {{ vmid }}
+ - results_action_start.msg == "VM {{ vmid }} started"
+
+ - pause:
+ seconds: 90
+
+ - name: Try to start test VM again
+ proxmox_kvm:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ validate_certs: "{{ validate_certs }}"
+ node: "{{ node }}"
+ vmid: "{{ vmid }}"
+ state: started
+ register: results_action_start_again
+
+ - assert:
+ that:
+ - results_action_start_again is not changed
+ - results_action_start_again.status == 'running'
+ - results_action_start_again.vmid == {{ vmid }}
+ - results_action_start_again.msg == "VM {{ vmid }} is already running"
+
+ - name: Check current status
+ proxmox_kvm:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ validate_certs: "{{ validate_certs }}"
+ node: "{{ node }}"
+ vmid: "{{ vmid }}"
+ state: current
+ register: results_action_current
+
+ - assert:
+ that:
+ - results_action_current is not changed
+ - results_action_current.status == 'running'
+ - results_action_current.vmid == {{ vmid }}
+ - results_action_current.msg == "VM test-instance with vmid = {{ vmid }} is running"
+
+- name: VM add/change/delete NIC
+ tags: [ 'nic' ]
+ block:
+ - name: Add NIC to test VM
+ proxmox_nic:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ validate_certs: "{{ validate_certs }}"
+ vmid: "{{ vmid }}"
+ state: present
+ interface: net5
+ bridge: vmbr0
+ tag: 42
+ register: results
+
+ - assert:
+ that:
+ - results is changed
+ - results.vmid == {{ vmid }}
+ - results.msg == "Nic net5 updated on VM with vmid {{ vmid }}"
+
+ - name: Update NIC no changes
+ proxmox_nic:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ validate_certs: "{{ validate_certs }}"
+ vmid: "{{ vmid }}"
+ state: present
+ interface: net5
+ bridge: vmbr0
+ tag: 42
+ register: results
+
+ - assert:
+ that:
+ - results is not changed
+ - results.vmid == {{ vmid }}
+ - results.msg == "Nic net5 unchanged on VM with vmid {{ vmid }}"
+
+ - name: Update NIC with changes
+ proxmox_nic:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ validate_certs: "{{ validate_certs }}"
+ vmid: "{{ vmid }}"
+ state: present
+ interface: net5
+ bridge: vmbr0
+ tag: 24
+ firewall: true
+ register: results
+
+ - assert:
+ that:
+ - results is changed
+ - results.vmid == {{ vmid }}
+ - results.msg == "Nic net5 updated on VM with vmid {{ vmid }}"
+
+ - name: Delete NIC
+ proxmox_nic:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ validate_certs: "{{ validate_certs }}"
+ vmid: "{{ vmid }}"
+ state: absent
+ interface: net5
+ register: results
+
+ - assert:
+ that:
+ - results is changed
+ - results.vmid == {{ vmid }}
+ - results.msg == "Nic net5 deleted on VM with vmid {{ vmid }}"
+
+- name: Create new disk in VM
+ tags: ['create_disk']
+ block:
+ - name: Add new disk (without force) to VM
+ proxmox_disk:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ vmid: "{{ vmid }}"
+ disk: "{{ disk }}"
+ storage: "{{ storage }}"
+ size: 1
+ state: present
+ register: results
+
+ - assert:
+ that:
+ - results is changed
+ - results.vmid == {{ vmid }}
+ - results.msg == "Disk {{ disk }} created in VM {{ vmid }}"
+
+ - name: Try add disk again with same options (expect no-op)
+ proxmox_disk:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ vmid: "{{ vmid }}"
+ disk: "{{ disk }}"
+ storage: "{{ storage }}"
+ size: 1
+ state: present
+ register: results
+
+ - assert:
+ that:
+ - results is not changed
+ - results.vmid == {{ vmid }}
+ - results.msg == "Disk {{ disk }} is up to date in VM {{ vmid }}"
+
+ - name: Add new disk replacing existing disk (detach old and leave unused)
+ proxmox_disk:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ vmid: "{{ vmid }}"
+ disk: "{{ disk }}"
+ storage: "{{ storage }}"
+ size: 2
+ create: forced
+ state: present
+ register: results
+
+ - assert:
+ that:
+ - results is changed
+ - results.vmid == {{ vmid }}
+ - results.msg == "Disk {{ disk }} created in VM {{ vmid }}"
+
+- name: Update existing disk in VM
+ tags: ['update_disk']
+ block:
+ - name: Update disk configuration
+ proxmox_disk:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ vmid: "{{ vmid }}"
+ disk: "{{ disk }}"
+ backup: false
+ ro: true
+ aio: native
+ state: present
+ register: results
+
+ - assert:
+ that:
+ - results is changed
+ - results.vmid == {{ vmid }}
+ - results.msg == "Disk {{ disk }} updated in VM {{ vmid }}"
+
+- name: Grow existing disk in VM
+ tags: ['grow_disk']
+ block:
+ - name: Increase disk size
+ proxmox_disk:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ vmid: "{{ vmid }}"
+ disk: "{{ disk }}"
+ size: +1G
+ state: resized
+ register: results
+
+ - assert:
+ that:
+ - results is changed
+ - results.vmid == {{ vmid }}
+ - results.msg == "Disk {{ disk }} resized in VM {{ vmid }}"
+
+- name: Detach disk and leave it unused
+ tags: ['detach_disk']
+ block:
+ - name: Detach disk
+ proxmox_disk:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ vmid: "{{ vmid }}"
+ disk: "{{ disk }}"
+ state: detached
+ register: results
+
+ - assert:
+ that:
+ - results is changed
+ - results.vmid == {{ vmid }}
+ - results.msg == "Disk {{ disk }} detached from VM {{ vmid }}"
+
+- name: Move disk to another storage or another VM
+ tags: ['move_disk']
+ block:
+ - name: Move disk to another storage inside same VM
+ proxmox_disk:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ vmid: "{{ vmid }}"
+ disk: "{{ disk }}"
+ target_storage: "{{ target_storage }}"
+ format: "{{ target_format }}"
+ state: moved
+ register: results
+
+ - assert:
+ that:
+ - results is changed
+ - results.vmid == {{ vmid }}
+ - results.msg == "Disk {{ disk }} moved from VM {{ vmid }} storage {{ results.storage }}"
+
+ - name: Move disk to another VM (same storage)
+ proxmox_disk:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ vmid: "{{ vmid }}"
+ disk: "{{ disk }}"
+ target_vmid: "{{ target_vm }}"
+ target_disk: "{{ target_disk }}"
+ state: moved
+ register: results
+
+ - assert:
+ that:
+ - results is changed
+ - results.vmid == {{ vmid }}
+ - results.msg == "Disk {{ disk }} moved from VM {{ vmid }} storage {{ results.storage }}"
+
+
+- name: Remove disk permanently
+ tags: ['remove_disk']
+ block:
+ - name: Remove disk
+ proxmox_disk:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ vmid: "{{ target_vm }}"
+ disk: "{{ target_disk }}"
+ state: absent
+ register: results
+
+ - assert:
+ that:
+ - results is changed
+ - results.vmid == {{ target_vm }}
+ - results.msg == "Disk {{ target_disk }} removed from VM {{ target_vm }}"
+
+- name: VM stop
+ tags: [ 'stop' ]
+ block:
+ - name: Stop test VM
+ proxmox_kvm:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ validate_certs: "{{ validate_certs }}"
+ node: "{{ node }}"
+ vmid: "{{ vmid }}"
+ state: stopped
+ register: results_action_stop
+
+ - assert:
+ that:
+ - results_action_stop is changed
+ - results_action_stop.status == 'running'
+ - results_action_stop.vmid == {{ vmid }}
+ - results_action_stop.msg == "VM {{ vmid }} is shutting down"
+
+ - pause:
+ seconds: 5
+
+ - name: Check current status again
+ proxmox_kvm:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ validate_certs: "{{ validate_certs }}"
+ node: "{{ node }}"
+ vmid: "{{ vmid }}"
+ state: current
+ register: results_action_current
+
+ - assert:
+ that:
+ - results_action_current is not changed
+ - results_action_current.status == 'stopped'
+ - results_action_current.vmid == {{ vmid }}
+ - results_action_current.msg == "VM test-instance with vmid = {{ vmid }} is stopped"
+
+- name: VM destroy
+ tags: [ 'destroy' ]
+ block:
+ - name: Destroy test VM
+ proxmox_kvm:
+ api_host: "{{ api_host }}"
+ api_user: "{{ user }}@{{ domain }}"
+ api_password: "{{ api_password | default(omit) }}"
+ api_token_id: "{{ api_token_id | default(omit) }}"
+ api_token_secret: "{{ api_token_secret | default(omit) }}"
+ validate_certs: "{{ validate_certs }}"
+ proxmox_default_behavior: "no_defaults"
+ node: "{{ node }}"
+ vmid: "{{ vmid }}"
+ state: absent
+ register: results_kvm_destroy
+
+ - assert:
+ that:
+ - results_kvm_destroy is changed
+ - results_kvm_destroy.vmid == {{ vmid }}
+ - results_kvm_destroy.msg == "VM {{ vmid }} removed"
diff --git a/ansible_collections/community/general/tests/integration/targets/python_requirements_info/aliases b/ansible_collections/community/general/tests/integration/targets/python_requirements_info/aliases
new file mode 100644
index 000000000..12d1d6617
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/python_requirements_info/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
diff --git a/ansible_collections/community/general/tests/integration/targets/python_requirements_info/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/python_requirements_info/tasks/main.yml
new file mode 100644
index 000000000..24a7d1366
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/python_requirements_info/tasks/main.yml
@@ -0,0 +1,45 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: run python_requirements_info module
+ python_requirements_info:
+ register: basic_info
+
+- name: ensure python_requirements_info returns desired info
+ assert:
+ that:
+ - "'python' in basic_info"
+ - "'python_version' in basic_info"
+ - basic_info.python_version_info == ansible_python.version
+
+- name: run python_requirements_info module
+ python_requirements_info:
+ dependencies:
+ - notreal<1
+ - pip>1
+ register: dep_info
+
+- name: ensure python_requirements_info returns desired info
+ assert:
+ that:
+ - "'installed' in dep_info.valid.pip"
+ - "'notreal' in dep_info.not_found"
+
+- name: wrong specs
+ python_requirements_info:
+ dependencies:
+ - ansible<
+ register: wrong_spec1
+ ignore_errors: true
+
+- name: ensure wrong specs return error
+ assert:
+ that:
+ - wrong_spec1 is failed
diff --git a/ansible_collections/community/general/tests/integration/targets/read_csv/aliases b/ansible_collections/community/general/tests/integration/targets/read_csv/aliases
new file mode 100644
index 000000000..12d1d6617
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/read_csv/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
diff --git a/ansible_collections/community/general/tests/integration/targets/read_csv/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/read_csv/meta/main.yml
new file mode 100644
index 000000000..982de6eb0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/read_csv/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/read_csv/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/read_csv/tasks/main.yml
new file mode 100644
index 000000000..c09349dd5
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/read_csv/tasks/main.yml
@@ -0,0 +1,176 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Create basic CSV file
+- name: Create unique CSV file
+ copy:
+ content: &users_content |
+ name,uid,gid,gecos
+ dag,500,500,Dag Wieërs
+ jeroen,501,500,Jeroen Hoekx
+ dest: "{{ remote_tmp_dir }}/users_unique.csv"
+
+# Read a CSV file and access user 'dag'
+- name: Read users from CSV file and return a dictionary
+ read_csv:
+ path: "{{ remote_tmp_dir }}/users_unique.csv"
+ key: name
+ register: users_unique
+
+- assert:
+ that:
+ - users_unique.dict.dag.name == 'dag'
+ - users_unique.dict.dag.gecos == 'Dag Wieërs'
+ - users_unique.dict.dag.uid == '500'
+ - users_unique.dict.dag.gid == '500'
+ - users_unique.dict.jeroen.name == 'jeroen'
+ - users_unique.dict.jeroen.gecos == 'Jeroen Hoekx'
+ - users_unique.dict.jeroen.uid == '501'
+ - users_unique.dict.jeroen.gid == '500'
+
+# Read a CSV file and access the first item
+- name: Read users from CSV file and return a list
+ read_csv:
+ path: "{{ remote_tmp_dir }}/users_unique.csv"
+ register: users_unique
+
+- assert:
+ that:
+ - users_unique.list.0.name == 'dag'
+ - users_unique.list.0.gecos == 'Dag Wieërs'
+ - users_unique.list.0.uid == '500'
+ - users_unique.list.0.gid == '500'
+ - users_unique.list.1.name == 'jeroen'
+ - users_unique.list.1.gecos == 'Jeroen Hoekx'
+ - users_unique.list.1.uid == '501'
+ - users_unique.list.1.gid == '500'
+
+
+# Create basic CSV file using semi-colon
+- name: Create non-unique CSV file using semi-colon
+ copy:
+ content: |
+ name;uid;gid;gecos
+ dag;500;500;Dag Wieërs
+ jeroen;501;500;Jeroen Hoekx
+ dag;502;500;Dag Wieers
+ dest: "{{ remote_tmp_dir }}/users_nonunique.csv"
+
+# Read a CSV file and access user 'dag'
+- name: Read users from CSV file and return a dictionary
+ read_csv:
+ path: "{{ remote_tmp_dir }}/users_nonunique.csv"
+ key: name
+ unique: false
+ delimiter: ';'
+ register: users_nonunique
+
+- assert:
+ that:
+ - users_nonunique.dict.dag.name == 'dag'
+ - users_nonunique.dict.dag.gecos == 'Dag Wieers'
+ - users_nonunique.dict.dag.uid == '502'
+ - users_nonunique.dict.dag.gid == '500'
+ - users_nonunique.dict.jeroen.name == 'jeroen'
+ - users_nonunique.dict.jeroen.gecos == 'Jeroen Hoekx'
+ - users_nonunique.dict.jeroen.uid == '501'
+ - users_nonunique.dict.jeroen.gid == '500'
+
+
+# Read a CSV file using an non-existing dialect
+- name: Read users from CSV file and return a dictionary
+ read_csv:
+ path: "{{ remote_tmp_dir }}/users_nonunique.csv"
+ dialect: placebo
+ register: users_placebo
+ ignore_errors: true
+
+- assert:
+ that:
+ - users_placebo is failed
+ - users_placebo.msg == "Dialect 'placebo' is not supported by your version of python."
+
+
+# Create basic CSV file without header
+- name: Create unique CSV file without header
+ copy:
+ content: |
+ dag,500,500,Dag Wieërs
+ jeroen,501,500,Jeroen Hoekx
+ dest: "{{ remote_tmp_dir }}/users_noheader.csv"
+
+# Read a CSV file and access user 'dag'
+- name: Read users from CSV file and return a dictionary
+ read_csv:
+ path: "{{ remote_tmp_dir }}/users_noheader.csv"
+ key: name
+ fieldnames: name,uid,gid,gecos
+ register: users_noheader
+
+- assert:
+ that:
+ - users_noheader.dict.dag.name == 'dag'
+ - users_noheader.dict.dag.gecos == 'Dag Wieërs'
+ - users_noheader.dict.dag.uid == '500'
+ - users_noheader.dict.dag.gid == '500'
+ - users_noheader.dict.jeroen.name == 'jeroen'
+ - users_noheader.dict.jeroen.gecos == 'Jeroen Hoekx'
+ - users_noheader.dict.jeroen.uid == '501'
+ - users_noheader.dict.jeroen.gid == '500'
+
+
+# Create broken file
+- name: Create unique CSV file
+ copy:
+ content: |
+ name,uid,gid,gecos
+ dag,500,500,Dag Wieërs
+ jeroen,501,500,"Jeroen"Hoekx"
+ dest: "{{ remote_tmp_dir }}/users_broken.csv"
+
+# Read a broken CSV file using strict
+- name: Read users from a broken CSV file
+ read_csv:
+ path: "{{ remote_tmp_dir }}/users_broken.csv"
+ key: name
+ strict: true
+ register: users_broken
+ ignore_errors: true
+
+- assert:
+ that:
+ - users_broken is failed
+ - "'Unable to process file' in users_broken.msg"
+
+# Create basic CSV file with BOM
+- name: Create unique CSV file with BOM
+ copy:
+ content: "{{ bom + content }}"
+ dest: "{{ remote_tmp_dir }}/users_bom.csv"
+ vars:
+ content: *users_content
+ bom: "{{ '\ufeff' }}"
+
+ # Read a CSV file and access the first item
+- name: Read users from CSV file and return a list
+ read_csv:
+ path: "{{ remote_tmp_dir }}/users_bom.csv"
+ register: users_bom
+
+- assert:
+ that:
+ - users_bom.list.0.name == 'dag'
+ - users_bom.list.0.gecos == 'Dag Wieërs'
+ - users_bom.list.0.uid == '500'
+ - users_bom.list.0.gid == '500'
+ - users_bom.list.1.name == 'jeroen'
+ - users_bom.list.1.gecos == 'Jeroen Hoekx'
+ - users_bom.list.1.uid == '501'
+ - users_bom.list.1.gid == '500'
diff --git a/ansible_collections/community/general/tests/integration/targets/redis_info/aliases b/ansible_collections/community/general/tests/integration/targets/redis_info/aliases
new file mode 100644
index 000000000..1f1c4baf7
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/redis_info/aliases
@@ -0,0 +1,10 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+destructive
+skip/aix
+skip/osx
+skip/macos
+skip/rhel
diff --git a/ansible_collections/community/general/tests/integration/targets/redis_info/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/redis_info/defaults/main.yml
new file mode 100644
index 000000000..56e9c4386
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/redis_info/defaults/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+redis_password: PASS
+master_port: 6379
+replica_port: 6380
diff --git a/ansible_collections/community/general/tests/integration/targets/redis_info/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/redis_info/meta/main.yml
new file mode 100644
index 000000000..cd516fd23
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/redis_info/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+- setup_redis_replication
diff --git a/ansible_collections/community/general/tests/integration/targets/redis_info/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/redis_info/tasks/main.yml
new file mode 100644
index 000000000..4a11de365
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/redis_info/tasks/main.yml
@@ -0,0 +1,48 @@
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2020, Pavlo Bashynskyi (@levonet) <levonet@gmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: redis_info - connect to master with default host/port
+ community.general.redis_info:
+ login_password: "{{ redis_password }}"
+ register: result
+
+- assert:
+ that:
+ - result is not changed
+ - result.info is defined
+ - result.info.tcp_port == master_port
+ - result.info.role == 'master'
+
+- name: redis_info - connect to master (check)
+ community.general.redis_info:
+ login_host: 127.0.0.1
+ login_port: "{{ master_port }}"
+ login_password: "{{ redis_password }}"
+ check_mode: true
+ register: result
+
+- assert:
+ that:
+ - result is not changed
+ - result.info is defined
+ - result.info.tcp_port == master_port
+ - result.info.role == 'master'
+
+- name: redis_info - connect to replica
+ community.general.redis_info:
+ login_port: "{{ replica_port }}"
+ login_password: "{{ redis_password }}"
+ register: result
+
+- assert:
+ that:
+ - result is not changed
+ - result.info is defined
+ - result.info.tcp_port == replica_port
+ - result.info.role == 'slave'
diff --git a/ansible_collections/community/general/tests/integration/targets/rundeck/aliases b/ansible_collections/community/general/tests/integration/targets/rundeck/aliases
new file mode 100644
index 000000000..3cf494c4c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/rundeck/aliases
@@ -0,0 +1,12 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+destructive
+skip/aix
+skip/osx
+skip/macos
+skip/windows
+skip/freebsd
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/rundeck/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/rundeck/defaults/main.yml
new file mode 100644
index 000000000..4d7ea3146
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/rundeck/defaults/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+rundeck_url: http://localhost:4440
+rundeck_api_version: 39
+rundeck_job_id: 3b8a6e54-69fb-42b7-b98f-f82e59238478
diff --git a/ansible_collections/community/general/tests/integration/targets/rundeck/files/test_job.yaml b/ansible_collections/community/general/tests/integration/targets/rundeck/files/test_job.yaml
new file mode 100644
index 000000000..baa852ecc
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/rundeck/files/test_job.yaml
@@ -0,0 +1,28 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- defaultTab: nodes
+ description: ''
+ executionEnabled: true
+ id: 3b8a6e54-69fb-42b7-b98f-f82e59238478
+ loglevel: INFO
+ name: test_job
+ nodeFilterEditable: false
+ options:
+ - label: Exit Code
+ name: exit_code
+ value: '0'
+ - label: Sleep
+ name: sleep
+ value: '1'
+ plugins:
+ ExecutionLifecycle: null
+ scheduleEnabled: true
+ sequence:
+ commands:
+ - exec: sleep $RD_OPTION_SLEEP && echo "Test done!" && exit $RD_OPTION_EXIT_CODE
+ keepgoing: false
+ strategy: node-first
+ uuid: 3b8a6e54-69fb-42b7-b98f-f82e59238478
diff --git a/ansible_collections/community/general/tests/integration/targets/rundeck/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/rundeck/meta/main.yml
new file mode 100644
index 000000000..c125e4046
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/rundeck/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+- setup_rundeck
diff --git a/ansible_collections/community/general/tests/integration/targets/rundeck/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/rundeck/tasks/main.yml
new file mode 100644
index 000000000..e42780b9b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/rundeck/tasks/main.yml
@@ -0,0 +1,127 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Generate a Rundeck API Token
+ ansible.builtin.command: java -jar {{ rdeck_base }}/rundeck-cli.jar tokens create -u admin -d 24h -r admin
+ environment:
+ RD_URL: "{{ rundeck_url }}"
+ RD_USER: admin
+ RD_PASSWORD: admin
+ register: rundeck_api_token
+
+- name: Create a Rundeck project
+ community.general.rundeck_project:
+ name: "test_project"
+ api_version: "{{ rundeck_api_version }}"
+ url: "{{ rundeck_url }}"
+ token: "{{ rundeck_api_token.stdout_lines[-1] }}"
+ state: present
+
+- name: Copy test_job definition to /tmp
+ copy:
+ src: test_job.yaml
+ dest: /tmp/test_job.yaml
+
+- name: Create Rundeck job Test
+ ansible.builtin.command: java -jar {{ rdeck_base }}/rundeck-cli.jar jobs load -f /tmp/test_job.yaml -F yaml -p test_project
+ environment:
+ RD_URL: "{{ rundeck_url }}"
+ RD_USER: admin
+ RD_PASSWORD: admin
+
+- name: Wrong Rundeck API Token
+ community.general.rundeck_job_run:
+ url: "{{ rundeck_url }}"
+ api_version: "{{ rundeck_api_version }}"
+ api_token: wrong_token
+ job_id: "{{ rundeck_job_id }}"
+ ignore_errors: true
+ register: rundeck_job_run_wrong_token
+
+- name: Assert that Rundeck authorization failed
+ ansible.builtin.assert:
+ that:
+ - rundeck_job_run_wrong_token.msg == "Token authorization failed"
+
+- name: Success run Rundeck job test_job
+ community.general.rundeck_job_run:
+ url: "{{ rundeck_url }}"
+ api_version: "{{ rundeck_api_version }}"
+ api_token: "{{ rundeck_api_token.stdout_lines[-1] }}"
+ job_id: "{{ rundeck_job_id }}"
+ register: rundeck_job_run_success
+
+- name: Assert that Rundeck job test_job runs successfully
+ ansible.builtin.assert:
+ that:
+ - rundeck_job_run_success.execution_info.status == "succeeded"
+
+- name: Fail run Rundeck job test_job
+ community.general.rundeck_job_run:
+ url: "{{ rundeck_url }}"
+ api_version: "{{ rundeck_api_version }}"
+ api_token: "{{ rundeck_api_token.stdout_lines[-1] }}"
+ job_id: "{{ rundeck_job_id }}"
+ job_options:
+ exit_code: "1"
+ ignore_errors: true
+ register: rundeck_job_run_fail
+
+- name: Assert that Rundeck job test_job failed
+ ansible.builtin.assert:
+ that:
+ - rundeck_job_run_fail.execution_info.status == "failed"
+
+- name: Abort run Rundeck job test_job due timeout
+ community.general.rundeck_job_run:
+ url: "{{ rundeck_url }}"
+ api_version: "{{ rundeck_api_version }}"
+ api_token: "{{ rundeck_api_token.stdout_lines[-1] }}"
+ job_id: "{{ rundeck_job_id }}"
+ job_options:
+ sleep: "5"
+ wait_execution_timeout: 2
+ abort_on_timeout: true
+ ignore_errors: true
+ register: rundeck_job_run_aborted
+
+- name: Assert that Rundeck job test_job is aborted
+ ansible.builtin.assert:
+ that:
+ - rundeck_job_run_aborted.execution_info.status == "aborted"
+
+- name: Fire-and-forget run Rundeck job test_job
+ community.general.rundeck_job_run:
+ url: "{{ rundeck_url }}"
+ api_version: "{{ rundeck_api_version }}"
+ api_token: "{{ rundeck_api_token.stdout_lines[-1] }}"
+ job_id: "{{ rundeck_job_id }}"
+ job_options:
+ sleep: "5"
+ wait_execution: false
+ register: rundeck_job_run_forget
+
+- name: Assert that Rundeck job test_job is running
+ ansible.builtin.assert:
+ that:
+ - rundeck_job_run_forget.execution_info.status == "running"
+
+- name: Get Rundeck job test_job executions info
+ community.general.rundeck_job_executions_info:
+ url: "{{ rundeck_url }}"
+ api_version: "{{ rundeck_api_version }}"
+ api_token: "{{ rundeck_api_token.stdout_lines[-1] }}"
+ job_id: "{{ rundeck_job_id }}"
+ register: rundeck_job_executions_info
+
+- name: Assert that Rundeck job executions info has 4 registers
+ ansible.builtin.assert:
+ that:
+ - rundeck_job_executions_info.paging.total | int == 4
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_compute/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_compute/aliases
new file mode 100644
index 000000000..b2267f631
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_compute/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_compute/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_compute/defaults/main.yml
new file mode 100644
index 000000000..dfa104bdd
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_compute/defaults/main.yml
@@ -0,0 +1,13 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Below information has been taken from https://developer.scaleway.com/#servers
+scaleway_image_id: 6a601340-19c1-4ca7-9c1c-0704bcc9f5fe
+scaleway_organization: '{{ scw_org }}'
+scaleway_region: ams1
+scaleway_commerial_type: START1-S
+scaleway_name: scaleway_compute_test
+first_server_name: scaleway_compute_test_first
+second_server_name: scaleway_compute_test_second
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_compute/tasks/ip.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_compute/tasks/ip.yml
new file mode 100644
index 000000000..094176ce8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_compute/tasks/ip.yml
@@ -0,0 +1,206 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create a server with no IP (Check)
+ check_mode: true
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: present
+ public_ip: absent
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+
+ register: server_creation_absent_check_task
+
+- debug: var=server_creation_absent_check_task
+
+- assert:
+ that:
+ - server_creation_absent_check_task is success
+ - server_creation_absent_check_task is changed
+
+- name: Create a server
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: present
+ public_ip: absent
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+
+ register: server_creation_absent_task
+
+- debug: var=server_creation_absent_task
+
+- assert:
+ that:
+ - server_creation_absent_task is success
+ - server_creation_absent_task is changed
+
+- name: Create a server (Confirmation)
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: present
+ public_ip: absent
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+
+ register: server_creation_absent_confirmation_task
+
+- debug: var=server_creation_absent_confirmation_task
+
+- assert:
+ that:
+ - server_creation_absent_confirmation_task is success
+ - server_creation_absent_confirmation_task is not changed
+
+# Add a dynamic IP to the instance
+
+- name: Patch server tags (Check)
+ check_mode: true
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: present
+ public_ip: dynamic
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+
+ register: ip_patching_check_task
+
+- debug: var=ip_patching_check_task
+
+- assert:
+ that:
+ - ip_patching_check_task is success
+ - ip_patching_check_task is changed
+
+- name: Patch server tags
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: present
+ public_ip: dynamic
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+ register: ip_patching_task
+
+- debug: var=ip_patching_task
+
+- assert:
+ that:
+ - ip_patching_task is success
+ - ip_patching_task is changed
+
+- name: Patch server tags (Confirmation)
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: present
+ public_ip: dynamic
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+
+ register: ip_patching_confirmation_task
+
+- debug: var=ip_patching_confirmation_task
+
+- assert:
+ that:
+ - ip_patching_confirmation_task is success
+ - ip_patching_confirmation_task is not changed
+
+# Remove dynamic IP
+
+- name: Patch server tags (Check)
+ check_mode: true
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: present
+ public_ip: absent
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+
+ register: remove_ip_check_task
+
+- debug: var=remove_ip_check_task
+
+- assert:
+ that:
+ - remove_ip_check_task is success
+ - remove_ip_check_task is changed
+
+- name: Patch server tags
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: present
+ public_ip: absent
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+
+ register: remove_ip_task
+
+- debug: var=remove_ip_task
+
+- assert:
+ that:
+ - remove_ip_task is success
+ - remove_ip_task is changed
+
+- name: Patch server tags (Confirmation)
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: present
+ public_ip: absent
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+
+ register: remove_ip_confirmation_task
+
+- debug: var=remove_ip_confirmation_task
+
+- assert:
+ that:
+ - remove_ip_confirmation_task is success
+ - remove_ip_confirmation_task is not changed
+
+- name: Destroy it
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: absent
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+
+ register: server_destroy_task
+
+- debug: var=server_destroy_task
+
+- assert:
+ that:
+ - server_destroy_task is success
+ - server_destroy_task is changed
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_compute/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_compute/tasks/main.yml
new file mode 100644
index 000000000..eca689b40
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_compute/tasks/main.yml
@@ -0,0 +1,14 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- include_tasks: state.yml
+- include_tasks: ip.yml
+- include_tasks: security_group.yml
+- include_tasks: pagination.yml
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_compute/tasks/pagination.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_compute/tasks/pagination.yml
new file mode 100644
index 000000000..5a674b801
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_compute/tasks/pagination.yml
@@ -0,0 +1,76 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create a first server
+ scaleway_compute:
+ name: '{{ first_server_name }}'
+ state: present
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+
+- name: Create a second server
+ scaleway_compute:
+ name: '{{ second_server_name }}'
+ state: present
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+
+- name: Get server informations of the first page
+ scaleway_server_info:
+ region: par1
+ query_parameters:
+ per_page: 1
+ page: 1
+ register: first_page
+
+- debug: var=first_page
+
+- assert:
+ that:
+ - first_page is success
+
+- name: Get server informations of the second page
+ scaleway_server_info:
+ region: par1
+ query_parameters:
+ per_page: 1
+ page: 2
+ register: second_page
+
+- debug: var=second_page
+
+- assert:
+ that:
+ - second_page is success
+
+- assert:
+ that:
+ - first_page.scaleway_server_info[0].id != second_page.scaleway_server_info[0].id
+
+- name: Delete first server
+ scaleway_compute:
+ name: '{{ first_server_name }}'
+ state: absent
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+
+- name: Delete second server
+ scaleway_compute:
+ name: '{{ second_server_name }}'
+ state: absent
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_compute/tasks/security_group.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_compute/tasks/security_group.yml
new file mode 100644
index 000000000..59f81e6af
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_compute/tasks/security_group.yml
@@ -0,0 +1,152 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create a scaleway security_group
+ scaleway_security_group:
+ state: present
+ region: '{{ scaleway_region }}'
+ name: test_compute
+ description: test_compute
+ organization: '{{ scaleway_organization }}'
+ stateful: true
+ inbound_default_policy: accept
+ outbound_default_policy: accept
+ organization_default: false
+ register: security_group
+
+- debug: var=security_group
+
+- block:
+ - name: Create a server with security_group (Check)
+ check_mode: true
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: present
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ security_group: '{{ security_group.scaleway_security_group.id }}'
+
+ register: server_creation_check_task
+
+ - debug: var=server_creation_check_task
+
+ - assert:
+ that:
+ - server_creation_check_task is success
+ - server_creation_check_task is changed
+
+ - name: Create a server
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: present
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ security_group: '{{ security_group.scaleway_security_group.id }}'
+ wait: true
+
+ register: server_creation_task
+
+ - debug: var=server_creation_task
+
+ - assert:
+ that:
+ - server_creation_task is success
+ - server_creation_task is changed
+
+ - name: Create a server with security_group (Confirmation)
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: present
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ security_group: '{{ security_group.scaleway_security_group.id }}'
+ wait: true
+
+ register: server_creation_confirmation_task
+
+ - debug: var=server_creation_confirmation_task
+
+ - assert:
+ that:
+ - server_creation_confirmation_task is success
+ - server_creation_confirmation_task is not changed
+
+ - name: Keep current security_group (Check)
+ check_mode: true
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: present
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ security_group: '{{ security_group.scaleway_security_group.id }}'
+ wait: true
+
+ register: server_creation_confirmation_task
+
+ - debug: var=server_creation_confirmation_task
+
+ - assert:
+ that:
+ - server_creation_confirmation_task is success
+ - server_creation_confirmation_task is not changed
+
+ - name: Keep current security_group
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: present
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+
+ register: server_creation_confirmation_task
+
+ - debug: var=server_creation_confirmation_task
+
+ - assert:
+ that:
+ - server_creation_confirmation_task is success
+ - server_creation_confirmation_task is not changed
+
+ always:
+ - name: Destroy it
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: absent
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+
+ register: server_destroy_task
+
+ - debug: var=server_destroy_task
+
+ - assert:
+ that:
+ - server_destroy_task is success
+ - server_destroy_task is changed
+
+ - name: Create a scaleway security_group
+ scaleway_security_group:
+ state: absent
+ region: '{{ scaleway_region }}'
+ name: test_compute
+ description: test_compute
+ organization: '{{ scaleway_organization }}'
+ stateful: true
+ inbound_default_policy: accept
+ outbound_default_policy: accept
+ organization_default: false
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_compute/tasks/state.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_compute/tasks/state.yml
new file mode 100644
index 000000000..b3f256762
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_compute/tasks/state.yml
@@ -0,0 +1,392 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create a server (Check)
+ check_mode: true
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: present
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+
+ register: server_creation_check_task
+
+- debug: var=server_creation_check_task
+
+- assert:
+ that:
+ - server_creation_check_task is success
+ - server_creation_check_task is changed
+
+- name: Create a server
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: present
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+
+ register: server_creation_task
+
+- debug: var=server_creation_task
+
+- assert:
+ that:
+ - server_creation_task is success
+ - server_creation_task is changed
+
+- name: Create a server (Confirmation)
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: present
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+
+ register: server_creation_confirmation_task
+
+- debug: var=server_creation_confirmation_task
+
+- assert:
+ that:
+ - server_creation_confirmation_task is success
+ - server_creation_confirmation_task is not changed
+
+- name: Patch server tags (Check)
+ check_mode: true
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: present
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ tags:
+ - test
+ - www
+ register: server_patching_check_task
+
+- debug: var=server_patching_check_task
+
+- assert:
+ that:
+ - server_patching_check_task is success
+ - server_patching_check_task is changed
+
+- name: Patch server tags
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: present
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+ tags:
+ - test
+ - www
+ register: server_patching_task
+
+- debug: var=server_patching_task
+
+- assert:
+ that:
+ - server_patching_task is success
+ - server_patching_task is changed
+
+- name: Patch server tags (Confirmation)
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: present
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+ tags:
+ - test
+ - www
+ register: server_patching_confirmation_task
+
+- debug: var=server_patching_confirmation_task
+
+- assert:
+ that:
+ - server_patching_confirmation_task is success
+ - server_patching_confirmation_task is not changed
+
+- name: Run it (Check mode)
+ check_mode: true
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: running
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ tags:
+ - test
+ - www
+ register: server_run_check_task
+
+- debug: var=server_run_check_task
+
+- assert:
+ that:
+ - server_run_check_task is success
+ - server_run_check_task is changed
+
+- name: Run it
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: running
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+ tags:
+ - test
+ - www
+ register: server_run_task
+
+- debug: var=server_run_task
+
+- assert:
+ that:
+ - server_run_task is success
+ - server_run_task is changed
+
+- name: Run it
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: running
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+ tags:
+ - test
+ - www
+ register: server_run_confirmation_task
+
+- debug: var=server_run_confirmation_task
+
+- assert:
+ that:
+ - server_run_confirmation_task is success
+ - server_run_confirmation_task is not changed
+
+- name: Reboot it (Check mode)
+ check_mode: true
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: restarted
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ tags:
+ - test
+ - www
+ register: server_reboot_check_task
+
+- debug: var=server_reboot_check_task
+
+- assert:
+ that:
+ - server_reboot_check_task is success
+ - server_reboot_check_task is changed
+
+- name: Reboot it
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: restarted
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+ tags:
+ - test
+ - www
+ register: server_reboot_task
+
+- debug: var=server_reboot_task
+
+- assert:
+ that:
+ - server_reboot_task is success
+ - server_reboot_task is changed
+
+- name: Stop it (Check mode)
+ check_mode: true
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: stopped
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ tags:
+ - test
+ - www
+ register: server_stop_check_task
+
+- debug: var=server_stop_check_task
+
+- assert:
+ that:
+ - server_stop_check_task is success
+ - server_stop_check_task is changed
+
+- name: Stop it
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: stopped
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+ tags:
+ - test
+ - www
+ register: server_stop_task
+
+- debug: var=server_stop_task
+
+- assert:
+ that:
+ - server_stop_task is success
+ - server_stop_task is changed
+
+- name: Stop it (Confirmation)
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: stopped
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+ tags:
+ - test
+ - www
+ register: server_stop_confirmation_task
+
+- debug: var=server_stop_confirmation_task
+
+- assert:
+ that:
+ - server_stop_confirmation_task is success
+ - server_stop_confirmation_task is not changed
+
+- name: Destroy it (Check mode)
+ check_mode: true
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: absent
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ tags:
+ - test
+ - www
+ register: server_destroy_check_task
+
+- debug: var=server_destroy_check_task
+
+- assert:
+ that:
+ - server_destroy_check_task is success
+ - server_destroy_check_task is changed
+
+- name: Destroy it
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: absent
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+ tags:
+ - test
+ - www
+ register: server_destroy_task
+
+- debug: var=server_destroy_task
+
+- assert:
+ that:
+ - server_destroy_task is success
+ - server_destroy_task is changed
+
+- name: Destroy it (Confirmation)
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: absent
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+ tags:
+ - test
+ - www
+ register: server_destroy_confirmation_task
+
+- debug: var=server_destroy_confirmation_task
+
+- assert:
+ that:
+ - server_destroy_confirmation_task is success
+ - server_destroy_confirmation_task is not changed
+
+- name: Testing for unauthorized organization
+ ignore_errors: true
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: present
+ image: '{{ scaleway_image_id }}'
+ organization: this-organization-does-not-exists
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ register: unauthorized_organization_task
+
+- debug: var=unauthorized_organization_task
+
+- assert:
+ that:
+ - unauthorized_organization_task is not success
+ - unauthorized_organization_task is not changed
+
+- name: Testing for unexisting image
+ ignore_errors: true
+ scaleway_compute:
+ name: '{{ scaleway_name }}'
+ state: present
+ image: this-image-does-not-exists
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ register: unexisting_image_check
+
+- debug: var=unexisting_image_check
+
+- assert:
+ that:
+ - unexisting_image_check is not success
+ - unexisting_image_check is not changed
+ - unexisting_image_check.msg == "Error in getting image this-image-does-not-exists on https://cp-{{scaleway_region}}.scaleway.com"
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_container/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_container/aliases
new file mode 100644
index 000000000..a5ac5181f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_container/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_container/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_container/defaults/main.yml
new file mode 100644
index 000000000..01b8719fc
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_container/defaults/main.yml
@@ -0,0 +1,18 @@
+---
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+scaleway_region: fr-par
+container_namespace_name: cn-ansible-test
+name: cn-ansible-test
+description: Container used for testing scaleway_container ansible module
+updated_description: Container used for testing scaleway_container ansible module (Updated description)
+environment_variables:
+ MY_VAR: my_value
+secret_environment_variables:
+ MY_SECRET_VAR: my_secret_value
+updated_secret_environment_variables:
+ MY_SECRET_VAR: my_other_secret_value
+image: rg.fr-par.scw.cloud/namespace-ansible-ci/nginx:latest
+port: 80
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_container/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_container/tasks/main.yml
new file mode 100644
index 000000000..d0bf4206f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_container/tasks/main.yml
@@ -0,0 +1,290 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create container_namespace
+ community.general.scaleway_container_namespace:
+ state: present
+ name: '{{ container_namespace_name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ description }}'
+ register: integration_container_namespace
+
+- name: Create a container (Check)
+ check_mode: true
+ community.general.scaleway_container:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ namespace_id: '{{ integration_container_namespace.container_namespace.id }}'
+ registry_image: '{{ image }}'
+ description: '{{ description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+ port: '{{ port }}'
+ register: cn_creation_check_task
+
+- ansible.builtin.debug:
+ var: cn_creation_check_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_creation_check_task is success
+ - cn_creation_check_task is changed
+
+- name: Create container
+ community.general.scaleway_container:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ namespace_id: '{{ integration_container_namespace.container_namespace.id }}'
+ registry_image: '{{ image }}'
+ description: '{{ description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+ port: '{{ port }}'
+ register: cn_creation_task
+
+- ansible.builtin.debug:
+ var: cn_creation_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_creation_task is success
+ - cn_creation_task is changed
+ - cn_creation_task.container.status in ["created", "ready"]
+
+- name: Create container (Confirmation)
+ community.general.scaleway_container:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ namespace_id: '{{ integration_container_namespace.container_namespace.id }}'
+ registry_image: '{{ image }}'
+ description: '{{ description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+ port: '{{ port }}'
+ register: cn_creation_confirmation_task
+
+- ansible.builtin.debug:
+ var: cn_creation_confirmation_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_creation_confirmation_task is success
+ - cn_creation_confirmation_task is not changed
+ - cn_creation_confirmation_task.container.status in ["created", "ready"]
+
+- name: Update container (Check)
+ check_mode: true
+ community.general.scaleway_container:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ namespace_id: '{{ integration_container_namespace.container_namespace.id }}'
+ registry_image: '{{ image }}'
+ description: '{{ updated_description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+ port: '{{ port }}'
+ register: cn_update_check_task
+
+- ansible.builtin.debug:
+ var: cn_update_check_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_update_check_task is success
+ - cn_update_check_task is changed
+
+- name: Update container
+ community.general.scaleway_container:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ namespace_id: '{{ integration_container_namespace.container_namespace.id }}'
+ registry_image: '{{ image }}'
+ description: '{{ updated_description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+ port: '{{ port }}'
+ register: cn_update_task
+
+- ansible.builtin.debug:
+ var: cn_update_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_update_task is success
+ - cn_update_task is changed
+ - cn_update_task.container.status in ["created", "ready"]
+
+- name: Update container (Confirmation)
+ community.general.scaleway_container:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ namespace_id: '{{ integration_container_namespace.container_namespace.id }}'
+ registry_image: '{{ image }}'
+ description: '{{ updated_description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+ port: '{{ port }}'
+ register: cn_update_confirmation_task
+
+- ansible.builtin.debug:
+ var: cn_update_confirmation_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_update_confirmation_task is success
+ - cn_update_confirmation_task is not changed
+ - cn_update_confirmation_task.container.status in ["created", "ready"]
+
+- name: Update container secret variables (Check)
+ check_mode: true
+ community.general.scaleway_container:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ namespace_id: '{{ integration_container_namespace.container_namespace.id }}'
+ registry_image: '{{ image }}'
+ description: '{{ updated_description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ updated_secret_environment_variables }}'
+ port: '{{ port }}'
+ register: cn_update_secret_check_task
+
+- ansible.builtin.debug:
+ var: cn_update_secret_check_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_update_secret_check_task is success
+ - cn_update_secret_check_task is changed
+
+- name: Update container secret variables
+ community.general.scaleway_container:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ namespace_id: '{{ integration_container_namespace.container_namespace.id }}'
+ registry_image: '{{ image }}'
+ description: '{{ updated_description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ updated_secret_environment_variables }}'
+ port: '{{ port }}'
+ register: cn_update_secret_task
+
+- ansible.builtin.debug:
+ var: cn_update_secret_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_update_secret_task is success
+ - cn_update_secret_task is changed
+ - cn_update_secret_task.container.status in ["created", "ready"]
+ - "'hashed_value' in cn_update_secret_task.container.secret_environment_variables[0]"
+
+- name: Update container secret variables (Confirmation)
+ community.general.scaleway_container:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ namespace_id: '{{ integration_container_namespace.container_namespace.id }}'
+ registry_image: '{{ image }}'
+ description: '{{ updated_description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ updated_secret_environment_variables }}'
+ port: '{{ port }}'
+ register: cn_update_secret_confirmation_task
+
+- ansible.builtin.debug:
+ var: cn_update_secret_confirmation_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_update_secret_confirmation_task is success
+ - cn_update_secret_confirmation_task is not changed
+ - cn_update_secret_confirmation_task.container.status == "ready"
+ - "'hashed_value' in cn_update_secret_confirmation_task.container.secret_environment_variables[0]"
+
+- name: Delete container (Check)
+ check_mode: true
+ community.general.scaleway_container:
+ state: absent
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ namespace_id: '{{ integration_container_namespace.container_namespace.id }}'
+ registry_image: '{{ image }}'
+ register: cn_deletion_check_task
+
+- ansible.builtin.debug:
+ var: cn_deletion_check_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_deletion_check_task is success
+ - cn_deletion_check_task is changed
+
+- name: Delete container
+ community.general.scaleway_container:
+ state: absent
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ namespace_id: '{{ integration_container_namespace.container_namespace.id }}'
+ registry_image: '{{ image }}'
+ register: cn_deletion_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_deletion_task is success
+ - cn_deletion_task is changed
+
+- name: Delete container (Confirmation)
+ community.general.scaleway_container:
+ state: absent
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ namespace_id: '{{ integration_container_namespace.container_namespace.id }}'
+ registry_image: '{{ image }}'
+ register: cn_deletion_confirmation_task
+
+- ansible.builtin.debug:
+ var: cn_deletion_confirmation_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_deletion_confirmation_task is success
+ - cn_deletion_confirmation_task is not changed
+
+- name: Delete container namespace
+ community.general.scaleway_container_namespace:
+ state: absent
+ name: '{{ container_namespace_name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ project_id: '{{ scw_project }}'
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_container_info/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_container_info/aliases
new file mode 100644
index 000000000..a5ac5181f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_container_info/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_container_info/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_container_info/defaults/main.yml
new file mode 100644
index 000000000..f3dadf71a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_container_info/defaults/main.yml
@@ -0,0 +1,16 @@
+---
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+scaleway_region: fr-par
+container_namespace_name: cn-ansible-test
+name: cn-ansible-test
+description: Container used for testing scaleway_container_info ansible module
+updated_description: Container used for testing scaleway_container_info ansible module (Updated description)
+environment_variables:
+ MY_VAR: my_value
+secret_environment_variables:
+ MY_SECRET_VAR: my_secret_value
+image: rg.fr-par.scw.cloud/namespace-ansible-ci/nginx:latest
+port: 80
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_container_info/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_container_info/tasks/main.yml
new file mode 100644
index 000000000..9f9fe401c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_container_info/tasks/main.yml
@@ -0,0 +1,63 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create container_namespace
+ community.general.scaleway_container_namespace:
+ state: present
+ name: '{{ container_namespace_name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ description }}'
+ register: integration_container_namespace
+
+- name: Create container
+ community.general.scaleway_container:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ namespace_id: '{{ integration_container_namespace.container_namespace.id }}'
+ registry_image: '{{ image }}'
+ description: '{{ description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+ port: '{{ port }}'
+
+- name: Get container info
+ community.general.scaleway_container_info:
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ namespace_id: '{{ integration_container_namespace.container_namespace.id }}'
+ register: cn_info_task
+
+- ansible.builtin.debug:
+ var: cn_info_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_info_task is success
+ - cn_info_task is not changed
+
+- name: Delete container
+ community.general.scaleway_container:
+ state: absent
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ namespace_id: '{{ integration_container_namespace.container_namespace.id }}'
+ registry_image: '{{ image }}'
+
+- name: Delete container namespace
+ community.general.scaleway_container_namespace:
+ state: absent
+ name: '{{ container_namespace_name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ project_id: '{{ scw_project }}'
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_container_namespace/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_container_namespace/aliases
new file mode 100644
index 000000000..a5ac5181f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_container_namespace/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_container_namespace/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_container_namespace/defaults/main.yml
new file mode 100644
index 000000000..876f8b7a6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_container_namespace/defaults/main.yml
@@ -0,0 +1,15 @@
+---
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+scaleway_region: fr-par
+name: cn-ansible-test
+description: Container namespace used for testing scaleway_container_namespace ansible module
+updated_description: Container namespace used for testing scaleway_container_namespace ansible module (Updated description)
+environment_variables:
+ MY_VAR: my_value
+secret_environment_variables:
+ MY_SECRET_VAR: my_secret_value
+updated_secret_environment_variables:
+ MY_SECRET_VAR: my_other_secret_value \ No newline at end of file
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_container_namespace/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_container_namespace/tasks/main.yml
new file mode 100644
index 000000000..73e43ff15
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_container_namespace/tasks/main.yml
@@ -0,0 +1,255 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create a container namespace (Check)
+ check_mode: true
+ community.general.scaleway_container_namespace:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+ register: cn_creation_check_task
+
+- ansible.builtin.debug:
+ var: cn_creation_check_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_creation_check_task is success
+ - cn_creation_check_task is changed
+
+- name: Create container_namespace
+ community.general.scaleway_container_namespace:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+ register: cn_creation_task
+
+- ansible.builtin.debug:
+ var: cn_creation_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_creation_task is success
+ - cn_creation_task is changed
+ - cn_creation_task.container_namespace.status == "ready"
+
+- name: Create container namespace (Confirmation)
+ community.general.scaleway_container_namespace:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+ register: cn_creation_confirmation_task
+
+- ansible.builtin.debug:
+ var: cn_creation_confirmation_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_creation_confirmation_task is success
+ - cn_creation_confirmation_task is not changed
+ - cn_creation_confirmation_task.container_namespace.status == "ready"
+
+- name: Update container namespace (Check)
+ check_mode: true
+ community.general.scaleway_container_namespace:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ updated_description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+ register: cn_update_check_task
+
+- ansible.builtin.debug:
+ var: cn_update_check_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_update_check_task is success
+ - cn_update_check_task is changed
+
+- name: Update container namespace
+ community.general.scaleway_container_namespace:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ updated_description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+ register: cn_update_task
+
+- ansible.builtin.debug:
+ var: cn_update_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_update_task is success
+ - cn_update_task is changed
+ - cn_update_task.container_namespace.status == "ready"
+
+- name: Update container namespace (Confirmation)
+ community.general.scaleway_container_namespace:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ updated_description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+ register: cn_update_confirmation_task
+
+- ansible.builtin.debug:
+ var: cn_update_confirmation_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_update_confirmation_task is success
+ - cn_update_confirmation_task is not changed
+ - cn_update_confirmation_task.container_namespace.status == "ready"
+
+- name: Update container namespace secret variables (Check)
+ check_mode: true
+ community.general.scaleway_container_namespace:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ updated_description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ updated_secret_environment_variables }}'
+ register: cn_update_secret_check_task
+
+- ansible.builtin.debug:
+ var: cn_update_secret_check_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_update_secret_check_task is success
+ - cn_update_secret_check_task is changed
+
+- name: Update container namespace secret variables
+ community.general.scaleway_container_namespace:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ updated_description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ updated_secret_environment_variables }}'
+ register: cn_update_secret_task
+
+- ansible.builtin.debug:
+ var: cn_update_secret_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_update_secret_task is success
+ - cn_update_secret_task is changed
+ - cn_update_secret_task.container_namespace.status == "ready"
+ - "'hashed_value' in cn_update_secret_task.container_namespace.secret_environment_variables[0]"
+
+- name: Update container namespace secret variables (Confirmation)
+ community.general.scaleway_container_namespace:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ updated_description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ updated_secret_environment_variables }}'
+ register: cn_update_secret_congfirmation_task
+
+- ansible.builtin.debug:
+ var: cn_update_secret_confirmation_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_update_secret_confirmation_task is success
+ - cn_update_secret_confirmation_task is not changed
+ - cn_update_secret_confirmation_task.container_namespace.status == "ready"
+ - "'hashed_value' in cn_update_secret_confirmation_task.container_namespace.secret_environment_variables[0]"
+
+- name: Delete container namespace (Check)
+ check_mode: true
+ community.general.scaleway_container_namespace:
+ state: absent
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ project_id: '{{ scw_project }}'
+ register: cn_deletion_check_task
+
+- ansible.builtin.debug:
+ var: cn_deletion_check_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_deletion_check_task is success
+ - cn_deletion_check_task is changed
+
+- name: Delete container namespace
+ community.general.scaleway_container_namespace:
+ state: absent
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ project_id: '{{ scw_project }}'
+ register: cn_deletion_task
+
+- ansible.builtin.debug:
+ var: cn_deletion_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_deletion_task is success
+ - cn_deletion_task is changed
+
+- name: Delete container namespace (Confirmation)
+ community.general.scaleway_container_namespace:
+ state: absent
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ project_id: '{{ scw_project }}'
+ register: cn_deletion_confirmation_task
+
+- ansible.builtin.debug:
+ var: cn_deletion_confirmation_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_deletion_confirmation_task is success
+ - cn_deletion_confirmation_task is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_container_namespace_info/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_container_namespace_info/aliases
new file mode 100644
index 000000000..a5ac5181f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_container_namespace_info/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_container_namespace_info/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_container_namespace_info/defaults/main.yml
new file mode 100644
index 000000000..238f79fe5
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_container_namespace_info/defaults/main.yml
@@ -0,0 +1,13 @@
+---
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+scaleway_region: fr-par
+name: cn-ansible-test
+description: Container namespace used for testing scaleway_container_namespace_info ansible module
+updated_description: Container namespace used for testing scaleway_container_namespace_info ansible module (Updated description)
+environment_variables:
+ MY_VAR: my_value
+secret_environment_variables:
+ MY_SECRET_VAR: my_secret_value
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_container_namespace_info/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_container_namespace_info/tasks/main.yml
new file mode 100644
index 000000000..17ac07e81
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_container_namespace_info/tasks/main.yml
@@ -0,0 +1,41 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create container_namespace
+ community.general.scaleway_container_namespace:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ description }}'
+
+- name: Get container namespace info
+ community.general.scaleway_container_namespace_info:
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ register: cn_info_task
+
+- ansible.builtin.debug:
+ var: cn_info_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cn_info_task is success
+ - cn_info_task is not changed
+
+- name: Delete container namespace
+ community.general.scaleway_container_namespace:
+ state: absent
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ project_id: '{{ scw_project }}'
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_container_registry/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_container_registry/aliases
new file mode 100644
index 000000000..a5ac5181f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_container_registry/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_container_registry/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_container_registry/defaults/main.yml
new file mode 100644
index 000000000..73b31423f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_container_registry/defaults/main.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+scaleway_region: fr-par
+name: cr_ansible_test
+description: Container registry used for testing scaleway_container_registry ansible module
+updated_description: Container registry used for testing scaleway_container_registry ansible module (Updated description)
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_container_registry/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_container_registry/tasks/main.yml
new file mode 100644
index 000000000..91cea20f3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_container_registry/tasks/main.yml
@@ -0,0 +1,178 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create a container registry (Check)
+ check_mode: true
+ community.general.scaleway_container_registry:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ description }}'
+ register: cr_creation_check_task
+
+- ansible.builtin.debug:
+ var: cr_creation_check_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cr_creation_check_task is success
+ - cr_creation_check_task is changed
+
+- name: Create container_registry
+ community.general.scaleway_container_registry:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ description }}'
+ register: cr_creation_task
+
+- ansible.builtin.debug:
+ var: cr_creation_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cr_creation_task is success
+ - cr_creation_task is changed
+ - cr_creation_task.container_registry.status == "ready"
+
+- name: Create container registry (Confirmation)
+ community.general.scaleway_container_registry:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ description }}'
+ register: cr_creation_confirmation_task
+
+- ansible.builtin.debug:
+ var: cr_creation_confirmation_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cr_creation_confirmation_task is success
+ - cr_creation_confirmation_task is not changed
+ - cr_creation_confirmation_task.container_registry.status == "ready"
+
+- name: Update container registry (Check)
+ check_mode: true
+ community.general.scaleway_container_registry:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ updated_description }}'
+ register: cr_update_check_task
+
+- ansible.builtin.debug:
+ var: cr_update_check_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cr_update_check_task is success
+ - cr_update_check_task is changed
+
+- name: Update container registry
+ community.general.scaleway_container_registry:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ updated_description }}'
+ register: cr_update_task
+
+- ansible.builtin.debug:
+ var: cr_update_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cr_update_task is success
+ - cr_update_task is changed
+ - cr_update_task.container_registry.status == "ready"
+
+- name: Update container registry (Confirmation)
+ community.general.scaleway_container_registry:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ updated_description }}'
+ register: cr_update_confirmation_task
+
+- ansible.builtin.debug:
+ var: cr_update_confirmation_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cr_update_confirmation_task is success
+ - cr_update_confirmation_task is not changed
+ - cr_update_confirmation_task.container_registry.status == "ready"
+
+- name: Delete container registry (Check)
+ check_mode: true
+ community.general.scaleway_container_registry:
+ state: absent
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ project_id: '{{ scw_project }}'
+ register: cr_deletion_check_task
+
+- ansible.builtin.debug:
+ var: cr_deletion_check_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cr_deletion_check_task is success
+ - cr_deletion_check_task is changed
+
+- name: Delete container registry
+ community.general.scaleway_container_registry:
+ state: absent
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ project_id: '{{ scw_project }}'
+ register: cr_deletion_task
+
+- ansible.builtin.debug:
+ var: cr_deletion_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cr_deletion_task is success
+ - cr_deletion_task is changed
+
+- name: Delete container regitry (Confirmation)
+ community.general.scaleway_container_registry:
+ state: absent
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ project_id: '{{ scw_project }}'
+ register: cr_deletion_confirmation_task
+
+- ansible.builtin.debug:
+ var: cr_deletion_confirmation_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cr_deletion_confirmation_task is success
+ - cr_deletion_confirmation_task is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_container_registry_info/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_container_registry_info/aliases
new file mode 100644
index 000000000..a5ac5181f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_container_registry_info/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_container_registry_info/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_container_registry_info/defaults/main.yml
new file mode 100644
index 000000000..8c53a31e7
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_container_registry_info/defaults/main.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+scaleway_region: fr-par
+name: cr_ansible_test
+description: Container registry used for testing scaleway_container_registry_info ansible module
+updated_description: Container registry used for testing scaleway_container_registry_info ansible module (Updated description)
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_container_registry_info/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_container_registry_info/tasks/main.yml
new file mode 100644
index 000000000..7de4d245a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_container_registry_info/tasks/main.yml
@@ -0,0 +1,41 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create container_registry
+ community.general.scaleway_container_registry:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ description }}'
+
+- name: Get container registry info
+ community.general.scaleway_container_registry_info:
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ register: cr_info_task
+
+- ansible.builtin.debug:
+ var: cr_info_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - cr_info_task is success
+ - cr_info_task is not changed
+
+- name: Delete container registry
+ community.general.scaleway_container_registry:
+ state: absent
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ project_id: '{{ scw_project }}'
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_database_backup/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_database_backup/aliases
new file mode 100644
index 000000000..b2267f631
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_database_backup/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_database_backup/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_database_backup/defaults/main.yml
new file mode 100644
index 000000000..1a5306ecf
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_database_backup/defaults/main.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+scaleway_name: scaleway_database_backup_test
+scaleway_region: fr-par
+scaleway_database_name: scaleway_database_test
+scaleway_instance_id:
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_database_backup/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_database_backup/tasks/main.yml
new file mode 100644
index 000000000..fdef03fb3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_database_backup/tasks/main.yml
@@ -0,0 +1,238 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create a backup (Check)
+ check_mode: true
+ scaleway_database_backup:
+ name: '{{ scaleway_name }}'
+ state: present
+ region: '{{ scaleway_region }}'
+ database_name: '{{ scaleway_database_name }}'
+ instance_id: '{{ scaleway_instance_id }}'
+
+ register: backup_creation_check_task
+
+- debug: var=backup_creation_check_task
+
+- assert:
+ that:
+ - backup_creation_check_task is success
+ - backup_creation_check_task is changed
+
+- name: Create a backup
+ scaleway_database_backup:
+ name: '{{ scaleway_name }}'
+ state: present
+ region: '{{ scaleway_region }}'
+ database_name: '{{ scaleway_database_name }}'
+ instance_id: '{{ scaleway_instance_id }}'
+ wait: true
+
+ register: backup_creation_task
+
+- debug: var=backup_creation_task
+
+- assert:
+ that:
+ - backup_creation_task is success
+ - backup_creation_task is changed
+
+- name: Create a backup (Confirmation)
+ scaleway_database_backup:
+ name: '{{ scaleway_name }}'
+ state: present
+ region: '{{ scaleway_region }}'
+ database_name: '{{ scaleway_database_name }}'
+ instance_id: '{{ scaleway_instance_id }}'
+ id: '{{ backup_creation_task.metadata.id }}'
+
+ register: backup_creation_confirmation_task
+
+- debug: var=backup_creation_confirmation_task
+
+- assert:
+ that:
+ - backup_creation_confirmation_task is success
+ - backup_creation_confirmation_task is not changed
+
+- name: Patch backup name (Check)
+ check_mode: true
+ scaleway_database_backup:
+ name: '{{ scaleway_name }}-changed'
+ state: present
+ region: '{{ scaleway_region }}'
+ database_name: '{{ scaleway_database_name }}'
+ instance_id: '{{ scaleway_instance_id }}'
+ id: '{{ backup_creation_task.metadata.id }}'
+ register: backup_patching_check_task
+
+- debug: var=backup_patching_check_task
+
+- assert:
+ that:
+ - backup_patching_check_task is success
+ - backup_patching_check_task is changed
+
+- name: Patch backup name
+ scaleway_database_backup:
+ name: '{{ scaleway_name }}-changed'
+ state: present
+ region: '{{ scaleway_region }}'
+ database_name: '{{ scaleway_database_name }}'
+ instance_id: '{{ scaleway_instance_id }}'
+ id: '{{ backup_creation_task.metadata.id }}'
+ register: backup_patching_task
+
+- debug: var=backup_patching_task
+
+- assert:
+ that:
+ - backup_patching_task is success
+ - backup_patching_task is changed
+
+- name: Patch backup name (Confirmation)
+ scaleway_database_backup:
+ name: '{{ scaleway_name }}-changed'
+ state: present
+ region: '{{ scaleway_region }}'
+ database_name: '{{ scaleway_database_name }}'
+ instance_id: '{{ scaleway_instance_id }}'
+ id: '{{ backup_creation_task.metadata.id }}'
+ register: backup_patching_confirmation_task
+
+- debug: var=backup_patching_confirmation_task
+
+- assert:
+ that:
+ - backup_patching_confirmation_task is success
+ - backup_patching_confirmation_task is not changed
+
+- name: Export backup (Check)
+ check_mode: true
+ scaleway_database_backup:
+ id: '{{ backup_creation_task.metadata.id }}'
+ state: exported
+ region: '{{ scaleway_region }}'
+ register: backup_export_check_task
+
+- debug: var=backup_export_check_task
+
+- assert:
+ that:
+ - backup_export_check_task is success
+ - backup_export_check_task is changed
+
+- name: Export backup
+ scaleway_database_backup:
+ id: '{{ backup_creation_task.metadata.id }}'
+ state: exported
+ region: '{{ scaleway_region }}'
+ wait: true
+ register: backup_export_task
+
+- debug: var=backup_export_task
+
+- assert:
+ that:
+ - backup_export_task is success
+ - backup_export_task is changed
+ - backup_export_task.metadata.download_url != ""
+
+- name: Export backup (Confirmation)
+ scaleway_database_backup:
+ id: '{{ backup_creation_task.metadata.id }}'
+ state: exported
+ region: '{{ scaleway_region }}'
+ register: backup_export_confirmation_task
+
+- debug: var=backup_export_confirmation_task
+
+- assert:
+ that:
+ - backup_export_confirmation_task is success
+ - backup_export_confirmation_task is not changed
+ - backup_export_confirmation_task.metadata.download_url != ""
+
+- name: Restore backup (Check)
+ check_mode: true
+ scaleway_database_backup:
+ id: '{{ backup_creation_task.metadata.id }}'
+ state: restored
+ region: '{{ scaleway_region }}'
+ database_name: '{{ scaleway_database_name }}'
+ instance_id: '{{ scaleway_instance_id }}'
+ register: backup_restore_check_task
+
+- debug: var=backup_restore_check_task
+
+- assert:
+ that:
+ - backup_restore_check_task is success
+ - backup_restore_check_task is changed
+
+- name: Restore backup
+ scaleway_database_backup:
+ id: '{{ backup_creation_task.metadata.id }}'
+ state: restored
+ region: '{{ scaleway_region }}'
+ database_name: '{{ scaleway_database_name }}'
+ instance_id: '{{ scaleway_instance_id }}'
+ wait: true
+ register: backup_restore_task
+
+- debug: var=backup_restore_task
+
+- assert:
+ that:
+ - backup_restore_task is success
+ - backup_restore_task is changed
+
+- name: Delete backup (Check)
+ check_mode: true
+ scaleway_database_backup:
+ id: '{{ backup_creation_task.metadata.id }}'
+ state: absent
+ region: '{{ scaleway_region }}'
+ register: backup_delete_check_task
+
+- debug: var=backup_delete_check_task
+
+- assert:
+ that:
+ - backup_delete_check_task is success
+ - backup_delete_check_task is changed
+
+- name: Delete backup
+ scaleway_database_backup:
+ id: '{{ backup_creation_task.metadata.id }}'
+ state: absent
+ region: '{{ scaleway_region }}'
+ register: backup_delete_task
+
+- debug: var=backup_delete_task
+
+- assert:
+ that:
+ - backup_delete_task is success
+ - backup_delete_task is changed
+
+- name: Delete backup (Confirmation)
+ scaleway_database_backup:
+ id: '{{ backup_creation_task.metadata.id }}'
+ state: absent
+ region: '{{ scaleway_region }}'
+ register: backup_delete_confirmation_task
+
+- debug: var=backup_delete_confirmation_task
+
+- assert:
+ that:
+ - backup_delete_confirmation_task is success
+ - backup_delete_confirmation_task is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_function/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_function/aliases
new file mode 100644
index 000000000..a5ac5181f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_function/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_function/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_function/defaults/main.yml
new file mode 100644
index 000000000..df02a4665
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_function/defaults/main.yml
@@ -0,0 +1,17 @@
+---
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+scaleway_region: fr-par
+function_namespace_name: fn-ansible-test
+name: fn-ansible-test
+description: Function used for testing scaleway_function_infoansible module
+updated_description: Function used for testing scaleway_function_info ansible module (Updated description)
+environment_variables:
+ MY_VAR: my_value
+secret_environment_variables:
+ MY_SECRET_VAR: my_secret_value
+updated_secret_environment_variables:
+ MY_SECRET_VAR: my_other_secret_value
+runtime: python310
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_function/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_function/tasks/main.yml
new file mode 100644
index 000000000..d4552d0b3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_function/tasks/main.yml
@@ -0,0 +1,284 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create function_namespace
+ community.general.scaleway_function_namespace:
+ state: present
+ name: '{{ function_namespace_name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ description }}'
+ register: integration_function_namespace
+
+- name: Create a function (Check)
+ check_mode: true
+ community.general.scaleway_function:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ namespace_id: '{{ integration_function_namespace.function_namespace.id }}'
+ runtime: '{{ runtime }}'
+ description: '{{ description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+ register: fn_creation_check_task
+
+- ansible.builtin.debug:
+ var: fn_creation_check_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_creation_check_task is success
+ - fn_creation_check_task is changed
+
+- name: Create function
+ community.general.scaleway_function:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ namespace_id: '{{ integration_function_namespace.function_namespace.id }}'
+ runtime: '{{ runtime }}'
+ description: '{{ description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+ register: fn_creation_task
+
+- ansible.builtin.debug:
+ var: fn_creation_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_creation_task is success
+ - fn_creation_task is changed
+ - fn_creation_task.function.status in ["created", "ready"]
+
+- name: Create function (Confirmation)
+ community.general.scaleway_function:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ namespace_id: '{{ integration_function_namespace.function_namespace.id }}'
+ runtime: '{{ runtime }}'
+ description: '{{ description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+ register: fn_creation_confirmation_task
+
+- ansible.builtin.debug:
+ var: fn_creation_confirmation_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_creation_confirmation_task is success
+ - fn_creation_confirmation_task is not changed
+ - fn_creation_confirmation_task.function.status in ["created", "ready"]
+
+- name: Update function (Check)
+ check_mode: true
+ community.general.scaleway_function:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ namespace_id: '{{ integration_function_namespace.function_namespace.id }}'
+ runtime: '{{ runtime }}'
+ description: '{{ updated_description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+ register: fn_update_check_task
+
+- ansible.builtin.debug:
+ var: fn_update_check_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_update_check_task is success
+ - fn_update_check_task is changed
+
+- name: Update function
+ community.general.scaleway_function:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ namespace_id: '{{ integration_function_namespace.function_namespace.id }}'
+ runtime: '{{ runtime }}'
+ description: '{{ updated_description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+ register: fn_update_task
+
+- ansible.builtin.debug:
+ var: fn_update_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_update_task is success
+ - fn_update_task is changed
+ - fn_update_task.function.status in ["created", "ready"]
+
+- name: Update function (Confirmation)
+ community.general.scaleway_function:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ namespace_id: '{{ integration_function_namespace.function_namespace.id }}'
+ runtime: '{{ runtime }}'
+ description: '{{ updated_description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+ register: fn_update_confirmation_task
+
+- ansible.builtin.debug:
+ var: fn_update_confirmation_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_update_confirmation_task is success
+ - fn_update_confirmation_task is not changed
+ - fn_update_confirmation_task.function.status in ["created", "ready"]
+
+- name: Update function secret variables (Check)
+ check_mode: true
+ community.general.scaleway_function:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ namespace_id: '{{ integration_function_namespace.function_namespace.id }}'
+ runtime: '{{ runtime }}'
+ description: '{{ updated_description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ updated_secret_environment_variables }}'
+ register: fn_update_secret_check_task
+
+- ansible.builtin.debug:
+ var: fn_update_secret_check_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_update_secret_check_task is success
+ - fn_update_secret_check_task is changed
+
+- name: Update function secret variables
+ community.general.scaleway_function:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ namespace_id: '{{ integration_function_namespace.function_namespace.id }}'
+ runtime: '{{ runtime }}'
+ description: '{{ updated_description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ updated_secret_environment_variables }}'
+ register: fn_update_secret_task
+
+- ansible.builtin.debug:
+ var: fn_update_secret_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_update_secret_task is success
+ - fn_update_secret_task is changed
+ - fn_update_secret_task.function.status in ["created", "ready"]
+ - "'hashed_value' in fn_update_secret_task.function.secret_environment_variables[0]"
+
+- name: Update function secret variables (Confirmation)
+ community.general.scaleway_function:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ namespace_id: '{{ integration_function_namespace.function_namespace.id }}'
+ runtime: '{{ runtime }}'
+ description: '{{ updated_description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ updated_secret_environment_variables }}'
+ register: fn_update_secret_confirmation_task
+
+- ansible.builtin.debug:
+ var: fn_update_secret_confirmation_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_update_secret_confirmation_task is success
+ - fn_update_secret_confirmation_task is not changed
+ - fn_update_secret_confirmation_task.function.status in ["created", "ready"]
+ - "'hashed_value' in fn_update_secret_confirmation_task.function.secret_environment_variables[0]"
+
+- name: Delete function (Check)
+ check_mode: true
+ community.general.scaleway_function:
+ state: absent
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ namespace_id: '{{ integration_function_namespace.function_namespace.id }}'
+ runtime: '{{ runtime }}'
+ register: fn_deletion_check_task
+
+- ansible.builtin.debug:
+ var: fn_deletion_check_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_deletion_check_task is success
+ - fn_deletion_check_task is changed
+
+- name: Delete function
+ community.general.scaleway_function:
+ state: absent
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ namespace_id: '{{ integration_function_namespace.function_namespace.id }}'
+ runtime: '{{ runtime }}'
+ register: fn_deletion_task
+
+- ansible.builtin.debug:
+ var: fn_deletion_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_deletion_task is success
+ - fn_deletion_task is changed
+
+- name: Delete function (Confirmation)
+ community.general.scaleway_function:
+ state: absent
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ namespace_id: '{{ integration_function_namespace.function_namespace.id }}'
+ runtime: '{{ runtime }}'
+ register: fn_deletion_confirmation_task
+
+- ansible.builtin.debug:
+ var: fn_deletion_confirmation_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_deletion_confirmation_task is success
+ - fn_deletion_confirmation_task is not changed
+
+- name: Delete function namespace
+ community.general.scaleway_function_namespace:
+ state: absent
+ name: '{{ function_namespace_name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ project_id: '{{ scw_project }}'
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_function_info/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_function_info/aliases
new file mode 100644
index 000000000..a5ac5181f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_function_info/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_function_info/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_function_info/defaults/main.yml
new file mode 100644
index 000000000..71d2fe780
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_function_info/defaults/main.yml
@@ -0,0 +1,15 @@
+---
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+scaleway_region: fr-par
+function_namespace_name: fn-ansible-test
+name: fn-ansible-test
+description: Container used for testing scaleway_function_info ansible module
+updated_description: Container used for testing scaleway_function_info ansible module (Updated description)
+environment_variables:
+ MY_VAR: my_value
+secret_environment_variables:
+ MY_SECRET_VAR: my_secret_value
+runtime: python310
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_function_info/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_function_info/tasks/main.yml
new file mode 100644
index 000000000..17b07f5f9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_function_info/tasks/main.yml
@@ -0,0 +1,62 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create function_namespace
+ community.general.scaleway_function_namespace:
+ state: present
+ name: '{{ function_namespace_name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ description }}'
+ register: integration_function_namespace
+
+- name: Create function
+ community.general.scaleway_function:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ namespace_id: '{{ integration_function_namespace.function_namespace.id }}'
+ runtime: '{{ runtime }}'
+ description: '{{ description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+
+- name: Get function info
+ community.general.scaleway_function_info:
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ namespace_id: '{{ integration_function_namespace.function_namespace.id }}'
+ register: fn_info_task
+
+- ansible.builtin.debug:
+ var: fn_info_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_info_task is success
+ - fn_info_task is not changed
+
+- name: Delete function
+ community.general.scaleway_function:
+ state: absent
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ namespace_id: '{{ integration_function_namespace.function_namespace.id }}'
+ runtime: '{{ runtime }}'
+
+- name: Delete function namespace
+ community.general.scaleway_function_namespace:
+ state: absent
+ name: '{{ function_namespace_name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ project_id: '{{ scw_project }}'
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_function_namespace/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_function_namespace/aliases
new file mode 100644
index 000000000..a5ac5181f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_function_namespace/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_function_namespace/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_function_namespace/defaults/main.yml
new file mode 100644
index 000000000..399d0ea1a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_function_namespace/defaults/main.yml
@@ -0,0 +1,15 @@
+---
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+scaleway_region: fr-par
+name: fn-ansible-test
+description: Function namespace used for testing scaleway_function_namespace ansible module
+updated_description: Function namespace used for testing scaleway_function_namespace ansible module (Updated description)
+environment_variables:
+ MY_VAR: my_value
+secret_environment_variables:
+ MY_SECRET_VAR: my_secret_value
+updated_secret_environment_variables:
+ MY_SECRET_VAR: my_other_secret_value
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_function_namespace/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_function_namespace/tasks/main.yml
new file mode 100644
index 000000000..50af4449d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_function_namespace/tasks/main.yml
@@ -0,0 +1,260 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create a function namespace (Check)
+ check_mode: true
+ community.general.scaleway_function_namespace:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+ register: fn_creation_check_task
+
+- ansible.builtin.debug:
+ var: fn_creation_check_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_creation_check_task is success
+ - fn_creation_check_task is changed
+
+- name: Create function_namespace
+ community.general.scaleway_function_namespace:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+ register: fn_creation_task
+
+- ansible.builtin.debug:
+ var: fn_creation_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_creation_task is success
+ - fn_creation_task is changed
+ - fn_creation_task.function_namespace.status == "ready"
+ - "'hashed_value' in fn_creation_task.function_namespace.secret_environment_variables[0]"
+
+- name: Create function namespace (Confirmation)
+ community.general.scaleway_function_namespace:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+ register: fn_creation_confirmation_task
+
+- ansible.builtin.debug:
+ var: fn_creation_confirmation_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_creation_confirmation_task is success
+ - fn_creation_confirmation_task is not changed
+ - fn_creation_confirmation_task.function_namespace.status == "ready"
+ - "'hashed_value' in fn_creation_task.function_namespace.secret_environment_variables[0]"
+
+- name: Update function namespace (Check)
+ check_mode: true
+ community.general.scaleway_function_namespace:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ updated_description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+ register: fn_update_check_task
+
+- ansible.builtin.debug:
+ var: fn_update_check_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_update_check_task is success
+ - fn_update_check_task is changed
+
+- name: Update function namespace
+ community.general.scaleway_function_namespace:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ updated_description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+ register: fn_update_task
+
+- ansible.builtin.debug:
+ var: fn_update_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_update_task is success
+ - fn_update_task is changed
+ - fn_update_task.function_namespace.status == "ready"
+ - "'hashed_value' in fn_creation_task.function_namespace.secret_environment_variables[0]"
+
+- name: Update function namespace (Confirmation)
+ community.general.scaleway_function_namespace:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ updated_description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+ register: fn_update_confirmation_task
+
+- ansible.builtin.debug:
+ var: fn_update_confirmation_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_update_confirmation_task is success
+ - fn_update_confirmation_task is not changed
+ - fn_update_confirmation_task.function_namespace.status == "ready"
+ - "'hashed_value' in fn_creation_task.function_namespace.secret_environment_variables[0]"
+
+- name: Update function namespace secret variables (Check)
+ check_mode: true
+ community.general.scaleway_function_namespace:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ updated_description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ updated_secret_environment_variables }}'
+ register: fn_update_secret_check_task
+
+- ansible.builtin.debug:
+ var: fn_update_secret_check_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_update_secret_check_task is success
+ - fn_update_secret_check_task is changed
+
+- name: Update function namespace secret variables
+ community.general.scaleway_function_namespace:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ updated_description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ updated_secret_environment_variables }}'
+ register: fn_update_secret_task
+
+- ansible.builtin.debug:
+ var: fn_update_secret_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_update_secret_task is success
+ - fn_update_secret_task is changed
+ - fn_update_secret_task.function_namespace.status == "ready"
+ - "'hashed_value' in fn_update_secret_task.function_namespace.secret_environment_variables[0]"
+
+- name: Update function namespace secret variables (Confirmation)
+ community.general.scaleway_function_namespace:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ updated_description }}'
+ environment_variables: '{{ environment_variables }}'
+ secret_environment_variables: '{{ updated_secret_environment_variables }}'
+ register: fn_update_secret_confirmation_task
+
+- ansible.builtin.debug:
+ var: fn_update_secret_confirmation_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_update_secret_confirmation_task is success
+ - fn_update_secret_confirmation_task is not changed
+ - fn_update_secret_confirmation_task.function_namespace.status == "ready"
+ - "'hashed_value' in fn_update_secret_confirmation_task.function_namespace.secret_environment_variables[0]"
+
+- name: Delete function namespace (Check)
+ check_mode: true
+ community.general.scaleway_function_namespace:
+ state: absent
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ project_id: '{{ scw_project }}'
+ register: fn_deletion_check_task
+
+- ansible.builtin.debug:
+ var: fn_deletion_check_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_deletion_check_task is success
+ - fn_deletion_check_task is changed
+
+- name: Delete function namespace
+ community.general.scaleway_function_namespace:
+ state: absent
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ project_id: '{{ scw_project }}'
+ register: fn_deletion_task
+
+- ansible.builtin.debug:
+ var: fn_deletion_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_deletion_task is success
+ - fn_deletion_task is changed
+ - "'hashed_value' in fn_creation_task.function_namespace.secret_environment_variables[0]"
+
+- name: Delete function namespace (Confirmation)
+ community.general.scaleway_function_namespace:
+ state: absent
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ project_id: '{{ scw_project }}'
+ register: fn_deletion_confirmation_task
+
+- ansible.builtin.debug:
+ var: fn_deletion_confirmation_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_deletion_confirmation_task is success
+ - fn_deletion_confirmation_task is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_function_namespace_info/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_function_namespace_info/aliases
new file mode 100644
index 000000000..a5ac5181f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_function_namespace_info/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_function_namespace_info/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_function_namespace_info/defaults/main.yml
new file mode 100644
index 000000000..0b05eaac0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_function_namespace_info/defaults/main.yml
@@ -0,0 +1,13 @@
+---
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+scaleway_region: fr-par
+name: fn-ansible-test
+description: Function namespace used for testing scaleway_function_namespace_info ansible module
+updated_description: Function namespace used for testing scaleway_function_namespace_info ansible module (Updated description)
+environment_variables:
+ MY_VAR: my_value
+secret_environment_variables:
+ MY_SECRET_VAR: my_secret_value
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_function_namespace_info/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_function_namespace_info/tasks/main.yml
new file mode 100644
index 000000000..793cd0923
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_function_namespace_info/tasks/main.yml
@@ -0,0 +1,43 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2022, Guillaume MARTINEZ <lunik@tiwabbit.fr>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create function_namespace
+ community.general.scaleway_function_namespace:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ description: '{{ description }}'
+ secret_environment_variables: '{{ secret_environment_variables }}'
+
+- name: Get function namespace info
+ community.general.scaleway_function_namespace_info:
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ project_id: '{{ scw_project }}'
+ register: fn_info_task
+
+- ansible.builtin.debug:
+ var: fn_info_task
+
+- name: Check module call result
+ ansible.builtin.assert:
+ that:
+ - fn_info_task is success
+ - fn_info_task is not changed
+ - "'hashed_value' in fn_info_task.function_namespace.secret_environment_variables[0]"
+
+- name: Delete function namespace
+ community.general.scaleway_function_namespace:
+ state: absent
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ project_id: '{{ scw_project }}'
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_image_info/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_image_info/aliases
new file mode 100644
index 000000000..b2267f631
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_image_info/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_image_info/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_image_info/tasks/main.yml
new file mode 100644
index 000000000..2cdf34fdd
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_image_info/tasks/main.yml
@@ -0,0 +1,37 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Get image informations and register it in a variable
+ scaleway_image_info:
+ region: par1
+ register: images
+
+- name: Display images variable
+ debug:
+ var: images
+
+- name: Ensure retrieval of images info is success
+ assert:
+ that:
+ - images is success
+
+- name: Get image informations from ams1 and register it in a variable
+ scaleway_image_info:
+ region: ams1
+ register: images_ams1
+
+- name: Display images variable from ams1
+ debug:
+ var: images_ams1
+
+- name: Ensure retrieval of images info is success
+ assert:
+ that:
+ - images_ams1 is success
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_ip/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_ip/aliases
new file mode 100644
index 000000000..b2267f631
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_ip/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_ip/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_ip/defaults/main.yml
new file mode 100644
index 000000000..00ec26ff6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_ip/defaults/main.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+scaleway_organization: '{{ scw_org }}'
+scaleway_region: ams1
+scaleway_image_id: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe
+scaleway_commerial_type: START1-S
+scaleway_server_name: scaleway_ip_test_server
+scaleway_reverse_name: scaleway.com
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_ip/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_ip/tasks/main.yml
new file mode 100644
index 000000000..5a396ba4f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_ip/tasks/main.yml
@@ -0,0 +1,449 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create IP (Check)
+ check_mode: true
+ scaleway_ip:
+ state: present
+ region: '{{ scaleway_region }}'
+ organization: '{{ scaleway_organization }}'
+ register: ip_creation_check_task
+
+- debug: var=ip_creation_check_task
+
+- name: ip_creation_check_task is success
+ assert:
+ that:
+ - ip_creation_check_task is success
+
+- name: ip_creation_check_task is changed
+ assert:
+ that:
+ - ip_creation_check_task is changed
+
+- name: Create IP
+ scaleway_ip:
+ state: present
+ region: '{{ scaleway_region }}'
+ organization: '{{ scaleway_organization }}'
+ register: ip_creation_task
+
+- debug: var=ip_creation_task
+
+- name: ip_creation_task is success
+ assert:
+ that:
+ - ip_creation_task is success
+
+- name: ip_creation_task is changed
+ assert:
+ that:
+ - ip_creation_task is changed
+
+- name: ip_creation_task.scaleway_ip.server is none
+ assert:
+ that:
+ - '{{ ip_creation_task.scaleway_ip.server is none }}'
+
+- name: Create IP (Confirmation)
+ scaleway_ip:
+ id: '{{ ip_creation_task.scaleway_ip.id }}'
+ state: present
+ region: '{{ scaleway_region }}'
+ organization: '{{ scaleway_organization }}'
+ register: ip_creation_confirmation_task
+
+- debug: var=ip_creation_confirmation_task
+
+- name: ip_creation_confirmation_task is success
+ assert:
+ that:
+ - ip_creation_confirmation_task is success
+
+- name: ip_creation_confirmation_task is not changed
+ assert:
+ that:
+ - ip_creation_confirmation_task is not changed
+
+- name: ip_creation_confirmation_task.scaleway_ip.server is none
+ assert:
+ that:
+ - '{{ ip_creation_task.scaleway_ip.server is none }}'
+
+- name: Assign reverse to server (Check)
+ check_mode: true
+ scaleway_ip:
+ state: present
+ id: '{{ ip_creation_task.scaleway_ip.id }}'
+ region: '{{ scaleway_region }}'
+ organization: '{{ scaleway_organization }}'
+ reverse: '{{ scaleway_reverse_name }}'
+ register: ip_reverse_assignation_check_task
+
+- debug: var=ip_reverse_assignation_check_task
+
+- name: ip_reverse_assignation_check_task is success
+ assert:
+ that:
+ - ip_reverse_assignation_check_task is success
+
+- name: ip_reverse_assignation_check_task is success
+ assert:
+ that:
+ - ip_reverse_assignation_check_task is success
+
+- name: Assign reverse to an IP
+ scaleway_ip:
+ state: present
+ id: '{{ ip_creation_task.scaleway_ip.id }}'
+ region: '{{ scaleway_region }}'
+ organization: '{{ scaleway_organization }}'
+ reverse: '{{ scaleway_reverse_name }}'
+ register: ip_reverse_assignation_task
+
+- debug: var=ip_reverse_assignation_task
+
+- name: ip_reverse_assignation_task is success
+ assert:
+ that:
+ - ip_reverse_assignation_task is success
+
+- name: ip_reverse_assignation_task is changed
+ assert:
+ that:
+ - ip_reverse_assignation_task is changed
+
+- name: Assign reverse to an IP (Confirmation)
+ scaleway_ip:
+ state: present
+ id: '{{ ip_creation_task.scaleway_ip.id }}'
+ region: '{{ scaleway_region }}'
+ organization: '{{ scaleway_organization }}'
+ reverse: '{{ scaleway_reverse_name }}'
+ register: ip_reverse_assignation_confirmation_task
+
+- debug: var=ip_reverse_assignation_confirmation_task
+
+- name: ip_reverse_assignation_confirmation_task is success
+ assert:
+ that:
+ - ip_reverse_assignation_confirmation_task is success
+
+- name: ip_reverse_assignation_confirmation_task is not changed
+ assert:
+ that:
+ - ip_reverse_assignation_confirmation_task is not changed
+
+- name: Create a server
+ scaleway_compute:
+ state: present
+ name: '{{ scaleway_server_name }}'
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ dynamic_ip_required: false
+ wait: true
+
+ register: server_creation_task
+
+- debug: var=server_creation_task
+
+- name: server_creation_task is success
+ assert:
+ that:
+ - server_creation_task is success
+
+- name: Assign IP to server (Check)
+ check_mode: true
+ scaleway_ip:
+ state: present
+ id: '{{ ip_creation_task.scaleway_ip.id }}'
+ region: '{{ scaleway_region }}'
+ organization: '{{ scaleway_organization }}'
+ server: '{{ server_creation_task.msg.id }}'
+ reverse: '{{ scaleway_reverse_name }}'
+ register: ip_assignation_check_task
+
+- debug: var=ip_assignation_check_task
+
+- name: ip_assignation_check_task is success
+ assert:
+ that:
+ - ip_assignation_check_task is success
+
+- name: ip_assignation_check_task is success
+ assert:
+ that:
+ - ip_assignation_check_task is success
+
+- name: Assign IP to server
+ scaleway_ip:
+ state: present
+ id: '{{ ip_creation_task.scaleway_ip.id }}'
+ region: '{{ scaleway_region }}'
+ organization: '{{ scaleway_organization }}'
+ server: '{{ server_creation_task.msg.id }}'
+ reverse: '{{ scaleway_reverse_name }}'
+ register: ip_assignation_task
+
+- debug: var=ip_assignation_task
+
+- name: ip_assignation_task is success
+ assert:
+ that:
+ - ip_assignation_task is success
+
+- name: ip_assignation_task is changed
+ assert:
+ that:
+ - ip_assignation_task is changed
+
+- name: Assign IP to server (Confirmation)
+ scaleway_ip:
+ state: present
+ id: '{{ ip_creation_task.scaleway_ip.id }}'
+ region: '{{ scaleway_region }}'
+ organization: '{{ scaleway_organization }}'
+ server: '{{ server_creation_task.msg.id }}'
+ reverse: '{{ scaleway_reverse_name }}'
+ register: ip_assignation_confirmation_task
+
+- debug: var=ip_assignation_confirmation_task
+
+- name: ip_assignation_confirmation_task is success
+ assert:
+ that:
+ - ip_assignation_confirmation_task is success
+
+- name: ip_assignation_confirmation_task is not changed
+ assert:
+ that:
+ - ip_assignation_confirmation_task is not changed
+
+- name: Unassign IP to server (Check)
+ check_mode: true
+ scaleway_ip:
+ state: present
+ id: '{{ ip_creation_task.scaleway_ip.id }}'
+ region: '{{ scaleway_region }}'
+ organization: '{{ scaleway_organization }}'
+ reverse: '{{ scaleway_reverse_name }}'
+ register: ip_unassignation_check_task
+
+- debug: var=ip_unassignation_check_task
+
+- name: ip_unassignation_check_task is success
+ assert:
+ that:
+ - ip_unassignation_check_task is success
+
+- name: ip_unassignation_check_task is changed
+ assert:
+ that:
+ - ip_unassignation_check_task is changed
+
+- name: Unassign IP to server
+ scaleway_ip:
+ state: present
+ id: '{{ ip_creation_task.scaleway_ip.id }}'
+ region: '{{ scaleway_region }}'
+ organization: '{{ scaleway_organization }}'
+ reverse: '{{ scaleway_reverse_name }}'
+ register: ip_unassignation_task
+
+- debug: var=ip_unassignation_task
+
+- name: ip_unassignation_task is success
+ assert:
+ that:
+ - ip_unassignation_task is success
+
+- name: ip_unassignation_task is changed
+ assert:
+ that:
+ - ip_unassignation_task is changed
+
+- name: ip_unassignation_task.scaleway_ip.server is none
+ assert:
+ that:
+ - '{{ ip_unassignation_task.scaleway_ip.server is none }}'
+
+- name: Unassign IP to server (Confirmation)
+ scaleway_ip:
+ state: present
+ id: '{{ ip_creation_task.scaleway_ip.id }}'
+ region: '{{ scaleway_region }}'
+ organization: '{{ scaleway_organization }}'
+ reverse: '{{ scaleway_reverse_name }}'
+ register: ip_unassignation_confirmation_task
+
+- debug: var=ip_unassignation_confirmation_task
+
+- name: ip_unassignation_confirmation_task is success
+ assert:
+ that:
+ - ip_unassignation_confirmation_task is success
+
+- name: ip_unassignation_confirmation_task is not changed
+ assert:
+ that:
+ - ip_unassignation_confirmation_task is not changed
+
+- name: ip_unassignation_confirmation_task.scaleway_ip.server is none
+ assert:
+ that:
+ - '{{ ip_unassignation_task.scaleway_ip.server is none }}'
+
+- name: Unassign reverse to IP (Check)
+ check_mode: true
+ scaleway_ip:
+ state: present
+ id: '{{ ip_creation_task.scaleway_ip.id }}'
+ region: '{{ scaleway_region }}'
+ organization: '{{ scaleway_organization }}'
+ register: ip_reverse_unassignation_check_task
+
+- debug: var=ip_reverse_unassignation_check_task
+
+- name: ip_reverse_unassignation_check_task is success
+ assert:
+ that:
+ - ip_reverse_unassignation_check_task is success
+
+- name: ip_reverse_unassignation_check_task is changed
+ assert:
+ that:
+ - ip_reverse_unassignation_check_task is changed
+
+- name: Unassign reverse to an IP
+ scaleway_ip:
+ state: present
+ id: '{{ ip_creation_task.scaleway_ip.id }}'
+ region: '{{ scaleway_region }}'
+ organization: '{{ scaleway_organization }}'
+ register: ip_reverse_unassignation_task
+
+- debug: var=ip_reverse_unassignation_task
+
+- name: ip_reverse_unassignation_task is success
+ assert:
+ that:
+ - ip_reverse_unassignation_task is success
+
+- name: ip_reverse_unassignation_task is changed
+ assert:
+ that:
+ - ip_reverse_unassignation_task is changed
+
+- name: ip_reverse_unassignation_task.scaleway_ip.reverse is none
+ assert:
+ that:
+ - '{{ ip_reverse_unassignation_task.scaleway_ip.reverse is none }}'
+
+- name: Unassign reverse to an IP (Confirmation)
+ scaleway_ip:
+ state: present
+ id: '{{ ip_creation_task.scaleway_ip.id }}'
+ region: '{{ scaleway_region }}'
+ organization: '{{ scaleway_organization }}'
+ register: ip_reverse_unassignation_confirmation_task
+
+- debug: var=ip_reverse_unassignation_confirmation_task
+
+- name: ip_reverse_unassignation_confirmation_task is success
+ assert:
+ that:
+ - ip_reverse_unassignation_confirmation_task is success
+
+- name: ip_reverse_unassignation_confirmation_task is not changed
+ assert:
+ that:
+ - ip_reverse_unassignation_confirmation_task is not changed
+
+- name: ip_reverse_unassignation_confirmation_task.scaleway_ip.server is none
+ assert:
+ that:
+ - '{{ ip_reverse_unassignation_confirmation_task.scaleway_ip.reverse is none }}'
+
+- name: Destroy a server
+ scaleway_compute:
+ name: '{{ scaleway_server_name }}'
+ state: absent
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+ register: server_destroy_task
+
+- debug: var=server_destroy_task
+
+- name: server_destroy_task is success
+ assert:
+ that:
+ - server_destroy_task is success
+
+- name: server_destroy_task is changed
+ assert:
+ that:
+ - server_destroy_task is changed
+
+- name: Delete IP (Check)
+ check_mode: true
+ scaleway_ip:
+ state: absent
+ region: '{{ scaleway_region }}'
+ id: '{{ ip_creation_task.scaleway_ip.id }}'
+ register: ip_deletion_check_task
+
+- name: ip_deletion_check_task is success
+ assert:
+ that:
+ - ip_deletion_check_task is success
+
+- name: ip_deletion_check_task is changed
+ assert:
+ that:
+ - ip_deletion_check_task is changed
+
+- name: Delete IP
+ scaleway_ip:
+ state: absent
+ region: '{{ scaleway_region }}'
+ id: '{{ ip_creation_task.scaleway_ip.id }}'
+ register: ip_deletion_task
+
+- name: ip_deletion_task is success
+ assert:
+ that:
+ - ip_deletion_task is success
+
+- name: ip_deletion_task is changed
+ assert:
+ that:
+ - ip_deletion_task is changed
+
+- name: Delete IP (Confirmation)
+ scaleway_ip:
+ state: absent
+ region: '{{ scaleway_region }}'
+ id: '{{ ip_creation_task.scaleway_ip.id }}'
+ register: ip_deletion_confirmation_task
+
+- name: ip_deletion_confirmation_task is success
+ assert:
+ that:
+ - ip_deletion_confirmation_task is success
+
+- name: ip_deletion_confirmation_task is not changed
+ assert:
+ that:
+ - ip_deletion_confirmation_task is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_ip_info/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_ip_info/aliases
new file mode 100644
index 000000000..b2267f631
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_ip_info/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_ip_info/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_ip_info/tasks/main.yml
new file mode 100644
index 000000000..b560b5658
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_ip_info/tasks/main.yml
@@ -0,0 +1,37 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Get ip informations and register it in a variable
+ scaleway_ip_info:
+ region: par1
+ register: ips
+
+- name: Display ips variable
+ debug:
+ var: ips
+
+- name: Ensure retrieval of ips info is success
+ assert:
+ that:
+ - ips is success
+
+- name: Get ip informations and register it in a variable
+ scaleway_ip_info:
+ region: ams1
+ register: ips_ams1
+
+- name: Display ips variable
+ debug:
+ var: ips_ams1
+
+- name: Ensure retrieval of ips info is success
+ assert:
+ that:
+ - ips_ams1 is success
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_lb/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_lb/aliases
new file mode 100644
index 000000000..b2267f631
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_lb/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_lb/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_lb/defaults/main.yml
new file mode 100644
index 000000000..c0d37800a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_lb/defaults/main.yml
@@ -0,0 +1,12 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+scaleway_region: fr-par
+name: lb_ansible_test
+description: Load-balancer used for testing scaleway_lb ansible module
+updated_description: Load-balancer used for testing scaleway_lb ansible module (Updated description)
+tags:
+ - first_tag
+ - second_tag
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_lb/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_lb/tasks/main.yml
new file mode 100644
index 000000000..2567abd07
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_lb/tasks/main.yml
@@ -0,0 +1,224 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create a load-balancer (Check)
+ check_mode: true
+ scaleway_lb:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ organization_id: '{{ scw_org }}'
+ description: '{{ description }}'
+ tags: '{{ tags }}'
+ register: lb_creation_check_task
+
+- debug: var=lb_creation_check_task
+
+- name: lb_creation_check_task is success
+ assert:
+ that:
+ - lb_creation_check_task is success
+
+- name: lb_creation_check_task is changed
+ assert:
+ that:
+ - lb_creation_check_task is changed
+
+- name: Create load-balancer
+ scaleway_lb:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ organization_id: '{{ scw_org }}'
+ description: '{{ description }}'
+ tags: '{{ tags }}'
+ wait: true
+ register: lb_creation_task
+
+- debug: var=lb_creation_task
+
+- name: lb_creation_task is success
+ assert:
+ that:
+ - lb_creation_task is success
+
+- name: lb_creation_task is changed
+ assert:
+ that:
+ - lb_creation_task is changed
+
+- name: Assert that the load-balancer is in a valid state
+ assert:
+ that:
+ - lb_creation_task.scaleway_lb.status == "ready"
+
+- name: Create load-balancer (Confirmation)
+ scaleway_lb:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ organization_id: '{{ scw_org }}'
+ tags: '{{ tags }}'
+ description: '{{ description }}'
+ register: lb_creation_confirmation_task
+
+- debug: var=lb_creation_confirmation_task
+
+- name: lb_creation_confirmation_task is success
+ assert:
+ that:
+ - lb_creation_confirmation_task is success
+
+- name: lb_creation_confirmation_task is not changed
+ assert:
+ that:
+ - lb_creation_confirmation_task is not changed
+
+- name: Assert that the load-balancer is in a valid state
+ assert:
+ that:
+ - lb_creation_confirmation_task.scaleway_lb.status == "ready"
+
+- name: Update load-balancer (Check)
+ check_mode: true
+ scaleway_lb:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ organization_id: '{{ scw_org }}'
+ tags: '{{ tags }}'
+ description: '{{ updated_description }}'
+ register: lb_update_check_task
+
+- debug: var=lb_update_check_task
+
+- name: lb_update_check_task is success
+ assert:
+ that:
+ - lb_update_check_task is success
+
+- name: lb_update_check_task is changed
+ assert:
+ that:
+ - lb_update_check_task is changed
+
+- name: Update load-balancer
+ scaleway_lb:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ tags: '{{ tags }}'
+ organization_id: '{{ scw_org }}'
+ description: '{{ updated_description }}'
+ wait: true
+ register: lb_update_task
+
+- debug: var=lb_update_task
+
+- name: lb_update_task is success
+ assert:
+ that:
+ - lb_update_task is success
+
+- name: lb_update_task is changed
+ assert:
+ that:
+ - lb_update_task is changed
+
+- name: Assert that the load-balancer is in a valid state
+ assert:
+ that:
+ - lb_update_task.scaleway_lb.status == "ready"
+
+- name: Update load-balancer (Confirmation)
+ scaleway_lb:
+ state: present
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ tags: '{{ tags }}'
+ organization_id: '{{ scw_org }}'
+ description: '{{ updated_description }}'
+ register: lb_update_confirmation_task
+
+- debug: var=lb_update_confirmation_task
+
+- name: lb_update_confirmation_task is success
+ assert:
+ that:
+ - lb_update_confirmation_task is success
+
+- name: lb_update_confirmation_task is not changed
+ assert:
+ that:
+ - lb_update_confirmation_task is not changed
+
+- name: Assert that the load-balancer is in a valid state
+ assert:
+ that:
+ - lb_update_confirmation_task.scaleway_lb.status == "ready"
+
+- name: Delete load-balancer (Check)
+ check_mode: true
+ scaleway_lb:
+ state: absent
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ organization_id: '{{ scw_org }}'
+ register: lb_deletion_check_task
+
+- name: lb_deletion_check_task is success
+ assert:
+ that:
+ - lb_deletion_check_task is success
+
+- name: lb_deletion_check_task is changed
+ assert:
+ that:
+ - lb_deletion_check_task is changed
+
+- name: Delete load-balancer
+ scaleway_lb:
+ state: absent
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ organization_id: '{{ scw_org }}'
+ wait: true
+ register: lb_deletion_task
+
+- name: lb_deletion_task is success
+ assert:
+ that:
+ - lb_deletion_task is success
+
+- name: lb_deletion_task is changed
+ assert:
+ that:
+ - lb_deletion_task is changed
+
+- name: Delete load-balancer (Confirmation)
+ scaleway_lb:
+ state: absent
+ name: '{{ name }}'
+ region: '{{ scaleway_region }}'
+ description: '{{ description }}'
+ organization_id: '{{ scw_org }}'
+ register: lb_deletion_confirmation_task
+
+- name: lb_deletion_confirmation_task is success
+ assert:
+ that:
+ - lb_deletion_confirmation_task is success
+
+- name: lb_deletion_confirmation_task is not changed
+ assert:
+ that:
+ - lb_deletion_confirmation_task is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_organization_info/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_organization_info/aliases
new file mode 100644
index 000000000..b2267f631
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_organization_info/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_organization_info/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_organization_info/tasks/main.yml
new file mode 100644
index 000000000..7326ca226
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_organization_info/tasks/main.yml
@@ -0,0 +1,22 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Get organization informations and register it in a variable
+ scaleway_organization_info:
+ register: organizations
+
+- name: Display organizations variable
+ debug:
+ var: organizations
+
+- name: Ensure retrieval of organizations info is success
+ assert:
+ that:
+ - organizations is success
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_security_group/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_security_group/aliases
new file mode 100644
index 000000000..b2267f631
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_security_group/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_security_group/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_security_group/defaults/main.yml
new file mode 100644
index 000000000..ffada8080
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_security_group/defaults/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+scaleway_organization: '{{ scw_org }}'
+scaleway_region: ams1
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_security_group/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_security_group/tasks/main.yml
new file mode 100644
index 000000000..cab972ae5
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_security_group/tasks/main.yml
@@ -0,0 +1,139 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create security group check
+ check_mode: true
+ scaleway_security_group:
+ state: present
+ region: '{{ scaleway_region }}'
+ name: security_group
+ description: 'my security group description'
+ organization: '{{ scaleway_organization }}'
+ stateful: false
+ inbound_default_policy: accept
+ outbound_default_policy: accept
+ organization_default: false
+ register: security_group_creation
+
+- debug: var=security_group_creation
+
+- name: Ensure security groups check facts is success
+ assert:
+ that:
+ - security_group_creation is success
+ - security_group_creation is changed
+
+- block:
+ - name: Create security group
+ scaleway_security_group:
+ state: present
+ region: '{{ scaleway_region }}'
+ name: security_group
+ description: 'my security group description'
+ organization: '{{ scaleway_organization }}'
+ stateful: false
+ inbound_default_policy: accept
+ outbound_default_policy: accept
+ organization_default: false
+ register: security_group_creation
+
+ - debug: var=security_group_creation
+
+ - name: Ensure security groups facts is success
+ assert:
+ that:
+ - security_group_creation is success
+ - security_group_creation is changed
+
+ - name: Create security group duplicate
+ scaleway_security_group:
+ state: present
+ region: '{{ scaleway_region }}'
+ name: security_group
+ description: 'my security group description'
+ organization: '{{ scaleway_organization }}'
+ stateful: false
+ inbound_default_policy: accept
+ outbound_default_policy: accept
+ organization_default: false
+ register: security_group_creation
+
+ - debug: var=security_group_creation
+
+ - name: Ensure security groups duplicate facts is success
+ assert:
+ that:
+ - security_group_creation is success
+ - security_group_creation is not changed
+
+ - name: Delete security group check
+ check_mode: true
+ scaleway_security_group:
+ state: absent
+ region: '{{ scaleway_region }}'
+ name: security_group
+ description: 'my security group description'
+ organization: '{{ scaleway_organization }}'
+ stateful: false
+ inbound_default_policy: accept
+ outbound_default_policy: accept
+ organization_default: false
+ register: security_group_deletion
+
+ - debug: var=security_group_deletion
+
+ - name: Ensure security groups delete check facts is success
+ assert:
+ that:
+ - security_group_deletion is success
+ - security_group_deletion is changed
+
+ always:
+ - name: Delete security group
+ scaleway_security_group:
+ state: absent
+ region: '{{ scaleway_region }}'
+ name: security_group
+ description: 'my security group description'
+ organization: '{{ scaleway_organization }}'
+ stateful: false
+ inbound_default_policy: accept
+ outbound_default_policy: accept
+ organization_default: false
+ register: security_group_deletion
+
+ - debug: var=security_group_deletion
+
+ - name: Ensure security groups delete facts is success
+ assert:
+ that:
+ - security_group_deletion is success
+ - security_group_deletion is changed
+
+- name: Delete security group duplicate
+ scaleway_security_group:
+ state: absent
+ region: '{{ scaleway_region }}'
+ name: security_group
+ description: 'my security group description'
+ organization: '{{ scaleway_organization }}'
+ stateful: false
+ inbound_default_policy: accept
+ outbound_default_policy: accept
+ organization_default: false
+ register: security_group_deletion
+
+- debug: var=security_group_deletion
+
+- name: Ensure security groups delete duplicate facts is success
+ assert:
+ that:
+ - security_group_deletion is success
+ - security_group_deletion is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_security_group_info/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_security_group_info/aliases
new file mode 100644
index 000000000..b2267f631
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_security_group_info/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_security_group_info/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_security_group_info/tasks/main.yml
new file mode 100644
index 000000000..8029a1e9a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_security_group_info/tasks/main.yml
@@ -0,0 +1,37 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Get security group informations and register it in a variable
+ scaleway_security_group_info:
+ region: par1
+ register: security_groups
+
+- name: Display security_groups variable
+ debug:
+ var: security_groups
+
+- name: Ensure retrieval of security groups info is success
+ assert:
+ that:
+ - security_groups is success
+
+- name: Get security group informations and register it in a variable (AMS1)
+ scaleway_security_group_info:
+ region: ams1
+ register: ams1_security_groups
+
+- name: Display security_groups variable (AMS1)
+ debug:
+ var: ams1_security_groups
+
+- name: Ensure retrieval of security groups info is success (AMS1)
+ assert:
+ that:
+ - ams1_security_groups is success
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_security_group_rule/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_security_group_rule/aliases
new file mode 100644
index 000000000..b2267f631
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_security_group_rule/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_security_group_rule/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_security_group_rule/defaults/main.yml
new file mode 100644
index 000000000..965ccf594
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_security_group_rule/defaults/main.yml
@@ -0,0 +1,12 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+scaleway_organization: '{{ scw_org }}'
+scaleway_region: par1
+protocol: "TCP"
+port: 80
+ip_range: "0.0.0.0/0"
+direction: "inbound"
+action: "accept"
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_security_group_rule/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_security_group_rule/tasks/main.yml
new file mode 100644
index 000000000..383942195
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_security_group_rule/tasks/main.yml
@@ -0,0 +1,252 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create a scaleway security_group
+ scaleway_security_group:
+ state: present
+ region: '{{ scaleway_region }}'
+ name: test_compute
+ description: test_compute
+ organization: '{{ scaleway_organization }}'
+ stateful: true
+ inbound_default_policy: accept
+ outbound_default_policy: accept
+ organization_default: false
+ register: security_group
+
+- debug: var=security_group
+
+- name: Create security_group_rule check
+ check_mode: true
+ scaleway_security_group_rule:
+ state: present
+ region: '{{ scaleway_region }}'
+ protocol: '{{ protocol }}'
+ port: '{{ port }}'
+ ip_range: '{{ ip_range }}'
+ direction: '{{ direction }}'
+ action: '{{ action }}'
+ security_group: '{{ security_group.scaleway_security_group.id }}'
+ register: security_group_rule_creation_task
+
+- debug: var=security_group_rule_creation_task
+
+- assert:
+ that:
+ - security_group_rule_creation_task is success
+ - security_group_rule_creation_task is changed
+
+- block:
+ - name: Create security_group_rule check
+ scaleway_security_group_rule:
+ state: present
+ region: '{{ scaleway_region }}'
+ protocol: '{{ protocol }}'
+ port: '{{ port }}'
+ ip_range: '{{ ip_range }}'
+ direction: '{{ direction }}'
+ action: '{{ action }}'
+ security_group: '{{ security_group.scaleway_security_group.id }}'
+ register: security_group_rule_creation_task
+
+ - debug: var=security_group_rule_creation_task
+
+ - assert:
+ that:
+ - security_group_rule_creation_task is success
+ - security_group_rule_creation_task is changed
+
+ - name: Create security_group_rule duplicate
+ scaleway_security_group_rule:
+ state: present
+ region: '{{ scaleway_region }}'
+ protocol: '{{ protocol }}'
+ port: '{{ port }}'
+ ip_range: '{{ ip_range }}'
+ direction: '{{ direction }}'
+ action: '{{ action }}'
+ security_group: '{{ security_group.scaleway_security_group.id }}'
+ register: security_group_rule_creation_task
+
+ - debug: var=security_group_rule_creation_task
+
+ - assert:
+ that:
+ - security_group_rule_creation_task is success
+ - security_group_rule_creation_task is not changed
+
+ - name: Delete security_group_rule check
+ check_mode: true
+ scaleway_security_group_rule:
+ state: absent
+ region: '{{ scaleway_region }}'
+ protocol: '{{ protocol }}'
+ port: '{{ port }}'
+ ip_range: '{{ ip_range }}'
+ direction: '{{ direction }}'
+ action: '{{ action }}'
+ security_group: '{{ security_group.scaleway_security_group.id }}'
+ register: security_group_rule_deletion_task
+
+ - debug: var=security_group_rule_deletion_task
+
+ - assert:
+ that:
+ - security_group_rule_deletion_task is success
+ - security_group_rule_deletion_task is changed
+
+ always:
+ - name: Delete security_group_rule check
+ scaleway_security_group_rule:
+ state: absent
+ region: '{{ scaleway_region }}'
+ protocol: '{{ protocol }}'
+ port: '{{ port }}'
+ ip_range: '{{ ip_range }}'
+ direction: '{{ direction }}'
+ action: '{{ action }}'
+ security_group: '{{ security_group.scaleway_security_group.id }}'
+ register: security_group_rule_deletion_task
+
+ - debug: var=security_group_rule_deletion_task
+
+ - assert:
+ that:
+ - security_group_rule_deletion_task is success
+ - security_group_rule_deletion_task is changed
+
+- name: Delete security_group_rule check
+ scaleway_security_group_rule:
+ state: absent
+ region: '{{ scaleway_region }}'
+ protocol: '{{ protocol }}'
+ port: '{{ port }}'
+ ip_range: '{{ ip_range }}'
+ direction: '{{ direction }}'
+ action: '{{ action }}'
+ security_group: '{{ security_group.scaleway_security_group.id }}'
+ register: security_group_rule_deletion_task
+
+- debug: var=security_group_rule_deletion_task
+
+- assert:
+ that:
+ - security_group_rule_deletion_task is success
+ - security_group_rule_deletion_task is not changed
+
+- block:
+ - name: Create security_group_rule with null check
+ scaleway_security_group_rule:
+ state: present
+ region: '{{ scaleway_region }}'
+ protocol: '{{ protocol }}'
+ port: null
+ ip_range: '{{ ip_range }}'
+ direction: '{{ direction }}'
+ action: '{{ action }}'
+ security_group: '{{ security_group.scaleway_security_group.id }}'
+ register: security_group_rule_creation_task
+
+ - debug: var=security_group_rule_creation_task
+
+ - assert:
+ that:
+ - security_group_rule_creation_task is success
+ - security_group_rule_creation_task is changed
+
+ - name: Create security_group_rule with null duplicate
+ scaleway_security_group_rule:
+ state: present
+ region: '{{ scaleway_region }}'
+ protocol: '{{ protocol }}'
+ port: null
+ ip_range: '{{ ip_range }}'
+ direction: '{{ direction }}'
+ action: '{{ action }}'
+ security_group: '{{ security_group.scaleway_security_group.id }}'
+ register: security_group_rule_creation_task
+
+ - debug: var=security_group_rule_creation_task
+
+ - assert:
+ that:
+ - security_group_rule_creation_task is success
+ - security_group_rule_creation_task is not changed
+
+ - name: Delete security_group_rule with null check
+ check_mode: true
+ scaleway_security_group_rule:
+ state: absent
+ region: '{{ scaleway_region }}'
+ protocol: '{{ protocol }}'
+ port: null
+ ip_range: '{{ ip_range }}'
+ direction: '{{ direction }}'
+ action: '{{ action }}'
+ security_group: '{{ security_group.scaleway_security_group.id }}'
+ register: security_group_rule_deletion_task
+
+ - debug: var=security_group_rule_deletion_task
+
+ - assert:
+ that:
+ - security_group_rule_deletion_task is success
+ - security_group_rule_deletion_task is changed
+
+ always:
+ - name: Delete security_group_rule with null check
+ scaleway_security_group_rule:
+ state: absent
+ region: '{{ scaleway_region }}'
+ protocol: '{{ protocol }}'
+ port: null
+ ip_range: '{{ ip_range }}'
+ direction: '{{ direction }}'
+ action: '{{ action }}'
+ security_group: '{{ security_group.scaleway_security_group.id }}'
+ register: security_group_rule_deletion_task
+
+ - debug: var=security_group_rule_deletion_task
+
+ - assert:
+ that:
+ - security_group_rule_deletion_task is success
+ - security_group_rule_deletion_task is changed
+
+- name: Delete security_group_rule with null check
+ scaleway_security_group_rule:
+ state: absent
+ region: '{{ scaleway_region }}'
+ protocol: '{{ protocol }}'
+ port: null
+ ip_range: '{{ ip_range }}'
+ direction: '{{ direction }}'
+ action: '{{ action }}'
+ security_group: '{{ security_group.scaleway_security_group.id }}'
+ register: security_group_rule_deletion_task
+
+- debug: var=security_group_rule_deletion_task
+
+- assert:
+ that:
+ - security_group_rule_deletion_task is success
+ - security_group_rule_deletion_task is not changed
+
+- name: Delete scaleway security_group
+ scaleway_security_group:
+ state: absent
+ region: '{{ scaleway_region }}'
+ name: test_compute
+ description: test_compute
+ organization: '{{ scaleway_organization }}'
+ stateful: true
+ inbound_default_policy: accept
+ outbound_default_policy: accept
+ organization_default: false
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_server_info/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_server_info/aliases
new file mode 100644
index 000000000..b2267f631
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_server_info/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_server_info/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_server_info/tasks/main.yml
new file mode 100644
index 000000000..7274e8a85
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_server_info/tasks/main.yml
@@ -0,0 +1,37 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Get server informations and register it in a variable
+ scaleway_server_info:
+ region: par1
+ register: servers
+
+- name: Display servers variable
+ debug:
+ var: servers
+
+- name: Ensure retrieval of servers info is success
+ assert:
+ that:
+ - servers is success
+
+- name: Get server informations and register it in a variable
+ scaleway_server_info:
+ region: ams1
+ register: ams1_servers
+
+- name: Display servers variable
+ debug:
+ var: ams1_servers
+
+- name: Ensure retrieval of servers info is success
+ assert:
+ that:
+ - ams1_servers is success
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_snapshot_info/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_snapshot_info/aliases
new file mode 100644
index 000000000..b2267f631
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_snapshot_info/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_snapshot_info/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_snapshot_info/tasks/main.yml
new file mode 100644
index 000000000..44f15d515
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_snapshot_info/tasks/main.yml
@@ -0,0 +1,37 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Get snapshot informations and register it in a variable
+ scaleway_snapshot_info:
+ region: par1
+ register: snapshots
+
+- name: Display snapshots variable
+ debug:
+ var: snapshots
+
+- name: Ensure retrieval of snapshots info is success
+ assert:
+ that:
+ - snapshots is success
+
+- name: Get snapshot informations and register it in a variable (AMS1)
+ scaleway_snapshot_info:
+ region: ams1
+ register: ams1_snapshots
+
+- name: Display snapshots variable (AMS1)
+ debug:
+ var: ams1_snapshots
+
+- name: Ensure retrieval of snapshots info is success (AMS1)
+ assert:
+ that:
+ - ams1_snapshots is success
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_sshkey/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_sshkey/aliases
new file mode 100644
index 000000000..b2267f631
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_sshkey/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_sshkey/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_sshkey/tasks/main.yml
new file mode 100644
index 000000000..588745abd
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_sshkey/tasks/main.yml
@@ -0,0 +1,49 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- scaleway_sshkey:
+ ssh_pub_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDf29yyommeGyKSIgSmX0ISVXP+3x6RUY4JDGLoAMFh2efkfDaRVdsvkvnFuUywgP2RewrjTyLE8w0NpCBHVS5Fm1BAn3yvxOUtTMxTbsQcw6HQ8swJ02+1tewJYjHPwc4GrBqiDo3Nmlq354Us0zBOJg/bBzuEnVD5eJ3GO3gKaCSUYTVrYwO0U4eJE0D9OJeUP9J48kl4ULbCub976+mTHdBvlzRw0Tzfl2kxgdDwlks0l2NefY/uiTdz2oMt092bAY3wZHxjto/DXoChxvaf5s2k8Zb+J7CjimUYnzPlH+zA9F6ROjP5AUu6ZWPd0jOIBl1nDWWb2j/qfNLYM43l sieben@sieben-macbook.local"
+ state: present
+ check_mode: true
+
+- scaleway_sshkey:
+ ssh_pub_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDf29yyommeGyKSIgSmX0ISVXP+3x6RUY4JDGLoAMFh2efkfDaRVdsvkvnFuUywgP2RewrjTyLE8w0NpCBHVS5Fm1BAn3yvxOUtTMxTbsQcw6HQ8swJ02+1tewJYjHPwc4GrBqiDo3Nmlq354Us0zBOJg/bBzuEnVD5eJ3GO3gKaCSUYTVrYwO0U4eJE0D9OJeUP9J48kl4ULbCub976+mTHdBvlzRw0Tzfl2kxgdDwlks0l2NefY/uiTdz2oMt092bAY3wZHxjto/DXoChxvaf5s2k8Zb+J7CjimUYnzPlH+zA9F6ROjP5AUu6ZWPd0jOIBl1nDWWb2j/qfNLYM43l sieben@sieben-macbook.local"
+ state: present
+ register: result1
+
+- scaleway_sshkey:
+ ssh_pub_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDf29yyommeGyKSIgSmX0ISVXP+3x6RUY4JDGLoAMFh2efkfDaRVdsvkvnFuUywgP2RewrjTyLE8w0NpCBHVS5Fm1BAn3yvxOUtTMxTbsQcw6HQ8swJ02+1tewJYjHPwc4GrBqiDo3Nmlq354Us0zBOJg/bBzuEnVD5eJ3GO3gKaCSUYTVrYwO0U4eJE0D9OJeUP9J48kl4ULbCub976+mTHdBvlzRw0Tzfl2kxgdDwlks0l2NefY/uiTdz2oMt092bAY3wZHxjto/DXoChxvaf5s2k8Zb+J7CjimUYnzPlH+zA9F6ROjP5AUu6ZWPd0jOIBl1nDWWb2j/qfNLYM43l sieben@sieben-macbook.local"
+ state: present
+ register: result2
+
+- assert:
+ that:
+ - result1 is success and result1 is changed
+ - result2 is success and result2 is not changed
+
+- scaleway_sshkey:
+ ssh_pub_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDf29yyommeGyKSIgSmX0ISVXP+3x6RUY4JDGLoAMFh2efkfDaRVdsvkvnFuUywgP2RewrjTyLE8w0NpCBHVS5Fm1BAn3yvxOUtTMxTbsQcw6HQ8swJ02+1tewJYjHPwc4GrBqiDo3Nmlq354Us0zBOJg/bBzuEnVD5eJ3GO3gKaCSUYTVrYwO0U4eJE0D9OJeUP9J48kl4ULbCub976+mTHdBvlzRw0Tzfl2kxgdDwlks0l2NefY/uiTdz2oMt092bAY3wZHxjto/DXoChxvaf5s2k8Zb+J7CjimUYnzPlH+zA9F6ROjP5AUu6ZWPd0jOIBl1nDWWb2j/qfNLYM43l sieben@sieben-macbook.local"
+ state: absent
+ check_mode: true
+
+- scaleway_sshkey:
+ ssh_pub_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDf29yyommeGyKSIgSmX0ISVXP+3x6RUY4JDGLoAMFh2efkfDaRVdsvkvnFuUywgP2RewrjTyLE8w0NpCBHVS5Fm1BAn3yvxOUtTMxTbsQcw6HQ8swJ02+1tewJYjHPwc4GrBqiDo3Nmlq354Us0zBOJg/bBzuEnVD5eJ3GO3gKaCSUYTVrYwO0U4eJE0D9OJeUP9J48kl4ULbCub976+mTHdBvlzRw0Tzfl2kxgdDwlks0l2NefY/uiTdz2oMt092bAY3wZHxjto/DXoChxvaf5s2k8Zb+J7CjimUYnzPlH+zA9F6ROjP5AUu6ZWPd0jOIBl1nDWWb2j/qfNLYM43l sieben@sieben-macbook.local"
+ state: absent
+ register: result1
+
+- scaleway_sshkey:
+ ssh_pub_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDf29yyommeGyKSIgSmX0ISVXP+3x6RUY4JDGLoAMFh2efkfDaRVdsvkvnFuUywgP2RewrjTyLE8w0NpCBHVS5Fm1BAn3yvxOUtTMxTbsQcw6HQ8swJ02+1tewJYjHPwc4GrBqiDo3Nmlq354Us0zBOJg/bBzuEnVD5eJ3GO3gKaCSUYTVrYwO0U4eJE0D9OJeUP9J48kl4ULbCub976+mTHdBvlzRw0Tzfl2kxgdDwlks0l2NefY/uiTdz2oMt092bAY3wZHxjto/DXoChxvaf5s2k8Zb+J7CjimUYnzPlH+zA9F6ROjP5AUu6ZWPd0jOIBl1nDWWb2j/qfNLYM43l sieben@sieben-macbook.local"
+ state: absent
+ register: result2
+
+- assert:
+ that:
+ - result1 is success and result1 is changed
+ - result2 is success and result2 is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_user_data/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_user_data/aliases
new file mode 100644
index 000000000..b2267f631
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_user_data/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_user_data/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_user_data/defaults/main.yml
new file mode 100644
index 000000000..7c53696b6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_user_data/defaults/main.yml
@@ -0,0 +1,18 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud_init_script: '''
+#cloud-config
+
+# final_message
+# default: cloud-init boot finished at $TIMESTAMP. Up $UPTIME seconds
+# this message is written by cloud-final when the system is finished
+# its first boot
+final_message: "The system is finally up, after $UPTIME seconds"
+'''
+scaleway_image_id: 89ee4018-f8c3-4dc4-a6b5-bca14f985ebe
+scaleway_organization: '{{ scw_org }}'
+scaleway_region: ams1
+scaleway_commerial_type: START1-S
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_user_data/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_user_data/tasks/main.yml
new file mode 100644
index 000000000..ce4284127
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_user_data/tasks/main.yml
@@ -0,0 +1,87 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create a server
+ scaleway_compute:
+ name: foobar
+ state: present
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ region: '{{ scaleway_region }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+
+ register: server_creation_task
+
+- debug: var=server_creation_task
+
+- set_fact:
+ server_id: "{{ server_creation_task.msg.id }}"
+
+- debug: var=server_id
+
+- name: Patch user_data cloud-init configuration (Check)
+ check_mode: true
+ scaleway_user_data:
+ region: '{{ scaleway_region }}'
+ server_id: "{{ server_id }}"
+ user_data:
+ cloud-init: "{{ cloud_init_script }}"
+ register: user_data_check_task
+
+- debug: var=user_data_check_task
+
+- assert:
+ that:
+ - user_data_check_task is success
+ - user_data_check_task is changed
+
+- name: Patch user_data cloud-init configuration
+ scaleway_user_data:
+ region: '{{ scaleway_region }}'
+ server_id: "{{ server_id }}"
+ user_data:
+ cloud-init: "{{ cloud_init_script }}"
+ register: user_data_task
+
+- debug: var=user_data_task
+
+- assert:
+ that:
+ - user_data_task is success
+ - user_data_task is changed
+
+- name: Patch user_data cloud-init configuration (Confirmation)
+ scaleway_user_data:
+ region: '{{ scaleway_region }}'
+ server_id: "{{ server_id }}"
+ user_data:
+ cloud-init: "{{ cloud_init_script }}"
+ register: user_data_confirmation_task
+
+- debug: var=user_data_confirmation_task
+
+- assert:
+ that:
+ - user_data_confirmation_task is success
+ - user_data_confirmation_task is not changed
+
+- name: Destroy it
+ scaleway_compute:
+ name: foobar
+ state: absent
+ region: '{{ scaleway_region }}'
+ image: '{{ scaleway_image_id }}'
+ organization: '{{ scaleway_organization }}'
+ commercial_type: '{{ scaleway_commerial_type }}'
+ wait: true
+ register: server_destroy_task
+
+- debug: var=server_destroy_task
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_volume/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_volume/aliases
new file mode 100644
index 000000000..b2267f631
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_volume/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_volume/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_volume/defaults/main.yml
new file mode 100644
index 000000000..ffada8080
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_volume/defaults/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+scaleway_organization: '{{ scw_org }}'
+scaleway_region: ams1
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_volume/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_volume/tasks/main.yml
new file mode 100644
index 000000000..2828a8502
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_volume/tasks/main.yml
@@ -0,0 +1,51 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Make sure volume is not there before tests
+ scaleway_volume:
+ name: ansible-test-volume
+ state: absent
+ region: '{{ scaleway_region }}'
+ organization: '{{ scaleway_organization }}'
+ register: server_creation_check_task
+
+- assert:
+ that:
+ - server_creation_check_task is success
+
+- name: Create volume
+ scaleway_volume:
+ name: ansible-test-volume
+ state: present
+ region: '{{ scaleway_region }}'
+ organization: '{{ scaleway_organization }}'
+ "size": 10000000000
+ volume_type: l_ssd
+ register: server_creation_check_task
+
+- debug: var=server_creation_check_task
+
+- assert:
+ that:
+ - server_creation_check_task is success
+ - server_creation_check_task is changed
+
+- name: Make sure volume is deleted
+ scaleway_volume:
+ name: ansible-test-volume
+ state: absent
+ region: '{{ scaleway_region }}'
+ organization: '{{ scaleway_organization }}'
+ register: server_creation_check_task
+
+- assert:
+ that:
+ - server_creation_check_task is success
+ - server_creation_check_task is changed
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_volume_info/aliases b/ansible_collections/community/general/tests/integration/targets/scaleway_volume_info/aliases
new file mode 100644
index 000000000..b2267f631
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_volume_info/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cloud/scaleway
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/scaleway_volume_info/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/scaleway_volume_info/tasks/main.yml
new file mode 100644
index 000000000..45995a54c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/scaleway_volume_info/tasks/main.yml
@@ -0,0 +1,37 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Get volume informations and register it in a variable
+ scaleway_volume_info:
+ region: par1
+ register: volumes
+
+- name: Display volumes variable
+ debug:
+ var: volumes
+
+- name: Ensure retrieval of volumes info is success
+ assert:
+ that:
+ - volumes is success
+
+- name: Get volume informations and register it in a variable (AMS1)
+ scaleway_volume_info:
+ region: ams1
+ register: ams1_volumes
+
+- name: Display volumes variable
+ debug:
+ var: ams1_volumes
+
+- name: Ensure retrieval of volumes info is success
+ assert:
+ that:
+ - ams1_volumes is success
diff --git a/ansible_collections/community/general/tests/integration/targets/sefcontext/aliases b/ansible_collections/community/general/tests/integration/targets/sefcontext/aliases
new file mode 100644
index 000000000..d318128f8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/sefcontext/aliases
@@ -0,0 +1,7 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+needs/root
+skip/aix
diff --git a/ansible_collections/community/general/tests/integration/targets/sefcontext/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/sefcontext/meta/main.yml
new file mode 100644
index 000000000..2fcd152f9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/sefcontext/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
diff --git a/ansible_collections/community/general/tests/integration/targets/sefcontext/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/sefcontext/tasks/main.yml
new file mode 100644
index 000000000..04143d1cb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/sefcontext/tasks/main.yml
@@ -0,0 +1,21 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2016, Dag Wieers <dag@wieers.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# FIXME: Unfortunately ansible_selinux could be a boolean or a dictionary !
+- debug:
+ msg: SELinux is disabled
+ when: ansible_selinux is defined and ansible_selinux == False
+
+- debug:
+ msg: SELinux is {{ ansible_selinux.status }}
+ when: ansible_selinux is defined and ansible_selinux != False
+
+- include_tasks: sefcontext.yml
+ when: ansible_selinux is defined and ansible_selinux != False and ansible_selinux.status == 'enabled'
diff --git a/ansible_collections/community/general/tests/integration/targets/sefcontext/tasks/sefcontext.yml b/ansible_collections/community/general/tests/integration/targets/sefcontext/tasks/sefcontext.yml
new file mode 100644
index 000000000..258f1ace9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/sefcontext/tasks/sefcontext.yml
@@ -0,0 +1,233 @@
+---
+# Copyright (c) 2016, Dag Wieers <dag@wieers.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: install requirements for RHEL
+ package:
+ name: policycoreutils-python
+ when:
+ - ansible_distribution == 'RedHat'
+ - ansible_distribution_major_version|int < 8
+
+- name: install requirements for rhel8 beta
+ package:
+ name: python3-policycoreutils
+ when:
+ - ansible_distribution == 'RedHat'
+ - ansible_distribution_major_version|int >= 8
+
+- name: Ensure we start with a clean state
+ sefcontext:
+ path: '/tmp/foo/bar(/.*)?'
+ setype: httpd_sys_content_t
+ state: absent
+
+- name: Ensure we start with a clean state
+ sefcontext:
+ path: /tmp/foo
+ state: absent
+
+- name: Set SELinux file context of foo/bar
+ sefcontext:
+ path: '/tmp/foo/bar(/.*)?'
+ setype: httpd_sys_content_t
+ state: present
+ reload: false
+ register: first
+
+- assert:
+ that:
+ - first is changed
+ - first.setype == 'httpd_sys_content_t'
+
+- name: Set SELinux file context of foo/bar (again)
+ sefcontext:
+ path: '/tmp/foo/bar(/.*)?'
+ setype: httpd_sys_content_t
+ state: present
+ reload: false
+ register: second
+
+- assert:
+ that:
+ - second is not changed
+ - second.setype == 'httpd_sys_content_t'
+
+- name: Change SELinux file context of foo/bar
+ sefcontext:
+ path: '/tmp/foo/bar(/.*)?'
+ setype: unlabeled_t
+ state: present
+ reload: false
+ register: third
+
+- assert:
+ that:
+ - third is changed
+ - third.setype == 'unlabeled_t'
+
+- name: Change SELinux file context of foo/bar (again)
+ sefcontext:
+ path: '/tmp/foo/bar(/.*)?'
+ setype: unlabeled_t
+ state: present
+ reload: false
+ register: fourth
+
+- assert:
+ that:
+ - fourth is not changed
+ - fourth.setype == 'unlabeled_t'
+
+- name: Delete SELinux file context of foo/bar
+ sefcontext:
+ path: '/tmp/foo/bar(/.*)?'
+ setype: httpd_sys_content_t
+ state: absent
+ reload: false
+ register: fifth
+
+- assert:
+ that:
+ - fifth is changed
+ - fifth.setype == 'httpd_sys_content_t'
+
+- name: Delete SELinux file context of foo/bar (again)
+ sefcontext:
+ path: '/tmp/foo/bar(/.*)?'
+ setype: unlabeled_t
+ state: absent
+ reload: false
+ register: sixth
+
+- assert:
+ that:
+ - sixth is not changed
+ - sixth.setype == 'unlabeled_t'
+
+- name: Set SELinux file context path substitution of foo
+ sefcontext:
+ path: /tmp/foo
+ substitute: /home
+ state: present
+ reload: false
+ register: subst_first
+
+- assert:
+ that:
+ - subst_first is changed
+ - subst_first.substitute == '/home'
+
+- name: Set SELinux file context path substitution of foo (again)
+ sefcontext:
+ path: /tmp/foo
+ substitute: /home
+ state: present
+ reload: false
+ register: subst_second
+
+- assert:
+ that:
+ - subst_second is not changed
+ - subst_second.substitute == '/home'
+
+- name: Change SELinux file context path substitution of foo
+ sefcontext:
+ path: /tmp/foo
+ substitute: /boot
+ state: present
+ reload: false
+ register: subst_third
+
+- assert:
+ that:
+ - subst_third is changed
+ - subst_third.substitute == '/boot'
+
+- name: Change SELinux file context path substitution of foo (again)
+ sefcontext:
+ path: /tmp/foo
+ substitute: /boot
+ state: present
+ reload: false
+ register: subst_fourth
+
+- assert:
+ that:
+ - subst_fourth is not changed
+ - subst_fourth.substitute == '/boot'
+
+- name: Try to delete non-existing SELinux file context path substitution of foo
+ sefcontext:
+ path: /tmp/foo
+ substitute: /dev
+ state: absent
+ reload: false
+ register: subst_fifth
+
+- assert:
+ that:
+ - subst_fifth is not changed
+ - subst_fifth.substitute == '/dev'
+
+- name: Delete SELinux file context path substitution of foo
+ sefcontext:
+ path: /tmp/foo
+ substitute: /boot
+ state: absent
+ reload: false
+ register: subst_sixth
+
+- assert:
+ that:
+ - subst_sixth is changed
+ - subst_sixth.substitute == '/boot'
+
+- name: Delete SELinux file context path substitution of foo (again)
+ sefcontext:
+ path: /tmp/foo
+ substitute: /boot
+ state: absent
+ reload: false
+ register: subst_seventh
+
+- assert:
+ that:
+ - subst_seventh is not changed
+ - subst_seventh.substitute == '/boot'
+
+- name: Set SELinux file context path substitution of foo
+ sefcontext:
+ path: /tmp/foo
+ substitute: /home
+ state: present
+ reload: false
+ register: subst_eighth
+
+- assert:
+ that:
+ - subst_eighth is changed
+ - subst_eighth.substitute == '/home'
+
+- name: Delete SELinux file context path substitution of foo
+ sefcontext:
+ path: /tmp/foo
+ state: absent
+ reload: false
+ register: subst_ninth
+
+- assert:
+ that:
+ - subst_ninth is changed
+
+- name: Delete SELinux file context path substitution of foo (again)
+ sefcontext:
+ path: /tmp/foo
+ state: absent
+ reload: false
+ register: subst_tenth
+
+- assert:
+ that:
+ - subst_tenth is not changed
diff --git a/ansible_collections/community/general/tests/integration/targets/sensu_client/aliases b/ansible_collections/community/general/tests/integration/targets/sensu_client/aliases
new file mode 100644
index 000000000..bca9905ba
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/sensu_client/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+needs/root
diff --git a/ansible_collections/community/general/tests/integration/targets/sensu_client/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/sensu_client/tasks/main.yml
new file mode 100644
index 000000000..61e49cda0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/sensu_client/tasks/main.yml
@@ -0,0 +1,179 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Creating a client if the directory doesn't exist should work
+ sensu_client:
+ subscriptions:
+ - default
+
+- name: Set variable for client file
+ set_fact:
+ client_file: "/etc/sensu/conf.d/client.json"
+
+- name: Insert invalid JSON in the client file
+ lineinfile:
+ state: "present"
+ create: "yes"
+ path: "{{ client_file }}"
+ line: "{'foo' = bar}"
+
+- name: Configure Sensu client with an existing invalid file
+ sensu_client:
+ name: "client"
+ state: "present"
+ subscriptions:
+ - default
+ register: client
+
+- name: Retrieve configuration file
+ slurp:
+ src: "{{ client_file }}"
+ register: client_config
+
+- name: Assert that client data was set successfully and properly
+ assert:
+ that:
+ - "client is successful"
+ - "client is changed"
+ - "client['config']['name'] == 'client'"
+ - "'default' in client['config']['subscriptions']"
+ - "client['file'] == client_file"
+
+- name: Assert that the client configuration file is actually configured properly
+ vars:
+ config: "{{ client_config.content | b64decode | from_json }}"
+ assert:
+ that:
+ - "config['client']['keepalives'] == true"
+ - "config['client']['name'] == 'client'"
+ - "config['client']['safe_mode'] == false"
+ - "'default' in config['client']['subscriptions']"
+
+- name: Delete Sensu client configuration
+ sensu_client:
+ state: "absent"
+ register: client_delete
+
+- name: Delete Sensu client configuration (again)
+ sensu_client:
+ state: "absent"
+ register: client_delete_twice
+
+- name: Retrieve configuration file stat
+ stat:
+ path: "{{ client_file }}"
+ register: client_stat
+
+- name: Assert that client deletion was successful
+ assert:
+ that:
+ - "client_delete is successful"
+ - "client_delete is changed"
+ - "client_delete_twice is successful"
+ - "client_delete_twice is not changed"
+ - "client_stat.stat.exists == false"
+
+- name: Configuring a client without subscriptions should fail
+ sensu_client:
+ name: "failure"
+ register: failure
+ ignore_errors: true
+
+- name: Assert failure to create client
+ assert:
+ that:
+ - failure is failed
+ - "'the following are missing: subscriptions' in failure['msg']"
+
+- name: Configure a new client from scratch with custom parameters
+ sensu_client:
+ name: "custom"
+ address: "host.fqdn"
+ subscriptions:
+ - "default"
+ - "webserver"
+ redact:
+ - "password"
+ socket:
+ bind: "127.0.0.1"
+ port: "3030"
+ keepalive:
+ thresholds:
+ warning: "180"
+ critical: "300"
+ handlers:
+ - "email"
+ custom:
+ - broadcast: "irc"
+ occurrences: "3"
+ register: client
+
+- name: Configure a new client from scratch with custom parameters (twice)
+ sensu_client:
+ name: "custom"
+ address: "host.fqdn"
+ subscriptions:
+ - "default"
+ - "webserver"
+ redact:
+ - "password"
+ socket:
+ bind: "127.0.0.1"
+ port: "3030"
+ keepalive:
+ thresholds:
+ warning: "180"
+ critical: "300"
+ handlers:
+ - "email"
+ custom:
+ - broadcast: "irc"
+ occurrences: "3"
+ register: client_twice
+
+- name: Retrieve configuration file
+ slurp:
+ src: "{{ client_file }}"
+ register: client_config
+
+- name: Assert that client data was set successfully and properly
+ assert:
+ that:
+ - "client is successful"
+ - "client is changed"
+ - "client_twice is successful"
+ - "client_twice is not changed"
+ - "client['config']['name'] == 'custom'"
+ - "client['config']['address'] == 'host.fqdn'"
+ - "'default' in client['config']['subscriptions']"
+ - "'webserver' in client['config']['subscriptions']"
+ - "'password' in client['config']['redact']"
+ - "client['config']['keepalive']['thresholds']['warning'] == '180'"
+ - "client['config']['keepalive']['thresholds']['critical'] == '300'"
+ - "'email' in client['config']['keepalive']['handlers']"
+ - "client['config']['keepalive']['occurrences'] == '3'"
+ - "client['file'] == client_file"
+
+- name: Assert that the client configuration file is actually configured properly
+ vars:
+ config: "{{ client_config.content | b64decode | from_json }}"
+ assert:
+ that:
+ - "config['client']['name'] == 'custom'"
+ - "config['client']['address'] == 'host.fqdn'"
+ - "config['client']['keepalives'] == true"
+ - "config['client']['safe_mode'] == false"
+ - "'default' in config['client']['subscriptions']"
+ - "'webserver' in config['client']['subscriptions']"
+ - "'password' in config['client']['redact']"
+ - "config['client']['keepalive']['thresholds']['warning'] == '180'"
+ - "config['client']['keepalive']['thresholds']['critical'] == '300'"
+ - "'email' in config['client']['keepalive']['handlers']"
+ - "config['client']['keepalive']['occurrences'] == '3'"
diff --git a/ansible_collections/community/general/tests/integration/targets/sensu_handler/aliases b/ansible_collections/community/general/tests/integration/targets/sensu_handler/aliases
new file mode 100644
index 000000000..bca9905ba
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/sensu_handler/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+needs/root
diff --git a/ansible_collections/community/general/tests/integration/targets/sensu_handler/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/sensu_handler/tasks/main.yml
new file mode 100644
index 000000000..ec73a14c4
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/sensu_handler/tasks/main.yml
@@ -0,0 +1,129 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Creating a handler if the directory doesn't exist should work
+ sensu_handler:
+ name: "handler"
+ type: "pipe"
+ command: "/bin/bash"
+ state: "present"
+
+- name: Insert junk JSON in a handlers file
+ lineinfile:
+ state: "present"
+ create: "yes"
+ path: "/etc/sensu/conf.d/handlers/handler.json"
+ line: "{'foo' = bar}"
+
+- name: Configure a handler with an existing invalid file
+ sensu_handler:
+ name: "handler"
+ type: "pipe"
+ command: "/bin/bash"
+ state: "present"
+ register: handler
+
+- name: Configure a handler (again)
+ sensu_handler:
+ name: "handler"
+ type: "pipe"
+ command: "/bin/bash"
+ state: "present"
+ register: handler_twice
+
+- name: Retrieve configuration file
+ slurp:
+ src: "{{ handler['file'] }}"
+ register: handler_config
+
+- name: Assert that handler data was set successfully and properly
+ assert:
+ that:
+ - "handler is successful"
+ - "handler is changed"
+ - "handler_twice is successful"
+ - "handler_twice is not changed"
+ - "handler['name'] == 'handler'"
+ - "handler['file'] == '/etc/sensu/conf.d/handlers/handler.json'"
+ - "handler['config']['type'] == 'pipe'"
+ - "handler['config']['command'] == '/bin/bash'"
+ - "handler['config']['timeout'] == 10"
+ - "handler['config']['handle_flapping'] == false"
+ - "handler['config']['handle_silenced'] == false"
+
+- name: Assert that the handler configuration file is actually configured properly
+ vars:
+ config: "{{ handler_config.content | b64decode | from_json }}"
+ assert:
+ that:
+ - "'handler' in config['handlers']"
+ - "config['handlers']['handler']['type'] == 'pipe'"
+ - "config['handlers']['handler']['command'] == '/bin/bash'"
+ - "config['handlers']['handler']['timeout'] == 10"
+ - "config['handlers']['handler']['handle_flapping'] == false"
+ - "config['handlers']['handler']['handle_silenced'] == false"
+
+- name: Delete Sensu handler configuration
+ sensu_handler:
+ name: "handler"
+ state: "absent"
+ register: handler_delete
+
+- name: Delete Sensu handler configuration (again)
+ sensu_handler:
+ name: "handler"
+ state: "absent"
+ register: handler_delete_twice
+
+- name: Retrieve configuration file stat
+ stat:
+ path: "{{ handler['file'] }}"
+ register: handler_stat
+
+- name: Assert that handler deletion was successful
+ assert:
+ that:
+ - "handler_delete is successful"
+ - "handler_delete is changed"
+ - "handler_delete_twice is successful"
+ - "handler_delete_twice is not changed"
+ - "handler_stat.stat.exists == false"
+
+- name: Configuring a handler without a name should fail
+ sensu_handler:
+ type: "pipe"
+ command: "/bin/bash"
+ register: failure
+ ignore_errors: true
+
+- name: Assert that configuring a handler without a name fails
+ assert:
+ that:
+ - failure is failed
+ - "'required arguments: name' in failure['msg']"
+
+- name: Configuring a handler without a type should fail
+ sensu_handler:
+ name: "pipe"
+ command: "/bin/bash"
+ register: failure
+ ignore_errors: true
+
+- name: Assert that configuring a handler without a type fails
+ assert:
+ that:
+ - failure is failed
+ - "'the following are missing: type' in failure['msg']"
+
+- include_tasks: pipe.yml
+- include_tasks: tcp.yml
+- include_tasks: udp.yml
+- include_tasks: set.yml
+- include_tasks: transport.yml
diff --git a/ansible_collections/community/general/tests/integration/targets/sensu_handler/tasks/pipe.yml b/ansible_collections/community/general/tests/integration/targets/sensu_handler/tasks/pipe.yml
new file mode 100644
index 000000000..46fe24080
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/sensu_handler/tasks/pipe.yml
@@ -0,0 +1,25 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Note: Pipe handlers are also tested and used as part of basic main.yml coverage
+- name: Configuring a handler with missing pipe parameters should fail
+ sensu_handler:
+ name: "pipe"
+ type: "pipe"
+ register: failure
+ ignore_errors: true
+
+- name: Assert that configuring a handler with missing pipe parameters fails
+ assert:
+ that:
+ - failure is failed
+ - "'the following are missing: command' in failure['msg']"
+
+- name: Configure a handler with pipe parameters
+ sensu_handler:
+ name: "pipe"
+ type: "pipe"
+ command: "/bin/bash"
+ register: handler
diff --git a/ansible_collections/community/general/tests/integration/targets/sensu_handler/tasks/set.yml b/ansible_collections/community/general/tests/integration/targets/sensu_handler/tasks/set.yml
new file mode 100644
index 000000000..e9a86057c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/sensu_handler/tasks/set.yml
@@ -0,0 +1,53 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Configuring a handler with missing set parameters should fail
+ sensu_handler:
+ name: "set"
+ type: "set"
+ register: failure
+ ignore_errors: true
+
+- name: Assert that configuring a handler with missing set parameters fails
+ assert:
+ that:
+ - failure is failed
+ - "'the following are missing: handlers' in failure['msg']"
+
+- name: Configure a set handler
+ sensu_handler:
+ name: "set"
+ type: "set"
+ handlers:
+ - anotherhandler
+ register: handler
+
+- name: Retrieve configuration file
+ slurp:
+ src: "{{ handler['file'] }}"
+ register: handler_config
+
+- name: Validate set handler return data
+ assert:
+ that:
+ - "handler is successful"
+ - "handler is changed"
+ - "handler['name'] == 'set'"
+ - "handler['file'] == '/etc/sensu/conf.d/handlers/set.json'"
+ - "handler['config']['type'] == 'set'"
+ - "'anotherhandler' in handler['config']['handlers']"
+ - "handler['config']['handle_flapping'] == false"
+ - "handler['config']['handle_silenced'] == false"
+
+- name: Assert that the handler configuration file is actually configured properly
+ vars:
+ config: "{{ handler_config.content | b64decode | from_json }}"
+ assert:
+ that:
+ - "'set' in config['handlers']"
+ - "config['handlers']['set']['type'] == 'set'"
+ - "'anotherhandler' in config['handlers']['set']['handlers']"
+ - "config['handlers']['set']['handle_flapping'] == false"
+ - "config['handlers']['set']['handle_silenced'] == false"
diff --git a/ansible_collections/community/general/tests/integration/targets/sensu_handler/tasks/tcp.yml b/ansible_collections/community/general/tests/integration/targets/sensu_handler/tasks/tcp.yml
new file mode 100644
index 000000000..a5db1d397
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/sensu_handler/tasks/tcp.yml
@@ -0,0 +1,56 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Configuring a handler with missing tcp parameters should fail
+ sensu_handler:
+ name: "tcp"
+ type: "tcp"
+ register: failure
+ ignore_errors: true
+
+- name: Assert that configuring a handler with missing tcp parameters fails
+ assert:
+ that:
+ - failure is failed
+ - "'the following are missing: socket' in failure['msg']"
+
+- name: Configure a tcp handler
+ sensu_handler:
+ name: "tcp"
+ type: "tcp"
+ socket:
+ host: 127.0.0.1
+ port: 8000
+ register: handler
+
+- name: Retrieve configuration file
+ slurp:
+ src: "{{ handler['file'] }}"
+ register: handler_config
+
+- name: Validate tcp handler return data
+ assert:
+ that:
+ - "handler is successful"
+ - "handler is changed"
+ - "handler['name'] == 'tcp'"
+ - "handler['file'] == '/etc/sensu/conf.d/handlers/tcp.json'"
+ - "handler['config']['type'] == 'tcp'"
+ - "handler['config']['socket']['host'] == '127.0.0.1'"
+ - "handler['config']['socket']['port'] == 8000"
+ - "handler['config']['handle_flapping'] == false"
+ - "handler['config']['handle_silenced'] == false"
+
+- name: Assert that the handler configuration file is actually configured properly
+ vars:
+ config: "{{ handler_config.content | b64decode | from_json }}"
+ assert:
+ that:
+ - "'tcp' in config['handlers']"
+ - "config['handlers']['tcp']['type'] == 'tcp'"
+ - "config['handlers']['tcp']['socket']['host'] == '127.0.0.1'"
+ - "config['handlers']['tcp']['socket']['port'] == 8000"
+ - "config['handlers']['tcp']['handle_flapping'] == false"
+ - "config['handlers']['tcp']['handle_silenced'] == false"
diff --git a/ansible_collections/community/general/tests/integration/targets/sensu_handler/tasks/transport.yml b/ansible_collections/community/general/tests/integration/targets/sensu_handler/tasks/transport.yml
new file mode 100644
index 000000000..fa2563fa9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/sensu_handler/tasks/transport.yml
@@ -0,0 +1,56 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Configuring a handler with missing transport parameters should fail
+ sensu_handler:
+ name: "transport"
+ type: "transport"
+ register: failure
+ ignore_errors: true
+
+- name: Assert that configuring a handler with missing transport parameters fails
+ assert:
+ that:
+ - failure is failed
+ - "'the following are missing: pipe' in failure['msg']"
+
+- name: Configure a transport handler
+ sensu_handler:
+ name: "transport"
+ type: "transport"
+ pipe:
+ type: "topic"
+ name: "transport_handler"
+ register: handler
+
+- name: Retrieve configuration file
+ slurp:
+ src: "{{ handler['file'] }}"
+ register: handler_config
+
+- name: Validate transport handler return data
+ assert:
+ that:
+ - "handler is successful"
+ - "handler is changed"
+ - "handler['name'] == 'transport'"
+ - "handler['file'] == '/etc/sensu/conf.d/handlers/transport.json'"
+ - "handler['config']['type'] == 'transport'"
+ - "handler['config']['pipe']['type'] == 'topic'"
+ - "handler['config']['pipe']['name'] == 'transport_handler'"
+ - "handler['config']['handle_flapping'] == false"
+ - "handler['config']['handle_silenced'] == false"
+
+- name: Assert that the handler configuration file is actually configured properly
+ vars:
+ config: "{{ handler_config.content | b64decode | from_json }}"
+ assert:
+ that:
+ - "'transport' in config['handlers']"
+ - "config['handlers']['transport']['type'] == 'transport'"
+ - "config['handlers']['transport']['pipe']['type'] == 'topic'"
+ - "config['handlers']['transport']['pipe']['name'] == 'transport_handler'"
+ - "config['handlers']['transport']['handle_flapping'] == false"
+ - "config['handlers']['transport']['handle_silenced'] == false"
diff --git a/ansible_collections/community/general/tests/integration/targets/sensu_handler/tasks/udp.yml b/ansible_collections/community/general/tests/integration/targets/sensu_handler/tasks/udp.yml
new file mode 100644
index 000000000..60e88bb98
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/sensu_handler/tasks/udp.yml
@@ -0,0 +1,56 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Configuring a handler with missing udp parameters should fail
+ sensu_handler:
+ name: "udp"
+ type: "udp"
+ register: failure
+ ignore_errors: true
+
+- name: Assert that configuring a handler with missing udp parameters fails
+ assert:
+ that:
+ - failure is failed
+ - "'the following are missing: socket' in failure['msg']"
+
+- name: Configure a udp handler
+ sensu_handler:
+ name: "udp"
+ type: "udp"
+ socket:
+ host: 127.0.0.1
+ port: 8000
+ register: handler
+
+- name: Retrieve configuration file
+ slurp:
+ src: "{{ handler['file'] }}"
+ register: handler_config
+
+- name: Validate udp handler return data
+ assert:
+ that:
+ - "handler is successful"
+ - "handler is changed"
+ - "handler['name'] == 'udp'"
+ - "handler['file'] == '/etc/sensu/conf.d/handlers/udp.json'"
+ - "handler['config']['type'] == 'udp'"
+ - "handler['config']['socket']['host'] == '127.0.0.1'"
+ - "handler['config']['socket']['port'] == 8000"
+ - "handler['config']['handle_flapping'] == false"
+ - "handler['config']['handle_silenced'] == false"
+
+- name: Assert that the handler configuration file is actually configured properly
+ vars:
+ config: "{{ handler_config.content | b64decode | from_json }}"
+ assert:
+ that:
+ - "'udp' in config['handlers']"
+ - "config['handlers']['udp']['type'] == 'udp'"
+ - "config['handlers']['udp']['socket']['host'] == '127.0.0.1'"
+ - "config['handlers']['udp']['socket']['port'] == 8000"
+ - "config['handlers']['udp']['handle_flapping'] == false"
+ - "config['handlers']['udp']['handle_silenced'] == false"
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_cron/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_cron/defaults/main.yml
new file mode 100644
index 000000000..aa7de77fe
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_cron/defaults/main.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+remote_dir: "{{ lookup('env', 'OUTPUT_DIR') }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_cron/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_cron/meta/main.yml
new file mode 100644
index 000000000..2fcd152f9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_cron/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_cron/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_cron/tasks/main.yml
new file mode 100644
index 000000000..cca7071a3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_cron/tasks/main.yml
@@ -0,0 +1,75 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- when:
+ - not (ansible_os_family == 'Alpine' and ansible_distribution_version is version('3.15', '<')) # TODO
+ block:
+ - name: Include distribution specific variables
+ include_vars: '{{ lookup(''first_found'', search) }}'
+ vars:
+ search:
+ files:
+ - '{{ ansible_distribution | lower }}.yml'
+ - '{{ ansible_os_family | lower }}.yml'
+ - '{{ ansible_system | lower }}.yml'
+ - default.yml
+ paths:
+ - vars
+ - name: install cron package
+ package:
+ name: '{{ cron_pkg }}'
+ when: cron_pkg | default(false, true)
+ register: cron_package_installed
+ until: cron_package_installed is success
+ - when: faketime_pkg | default(false, true)
+ block:
+ - name: install cron and faketime packages
+ package:
+ name: '{{ faketime_pkg }}'
+ register: faketime_package_installed
+ until: faketime_package_installed is success
+ - name: Find libfaketime path
+ shell: '{{ list_pkg_files }} {{ faketime_pkg }} | grep -F libfaketime.so.1'
+ register: libfaketime_path
+ - when: ansible_service_mgr == 'systemd'
+ block:
+ - name: create directory for cron drop-in file
+ file:
+ path: /etc/systemd/system/{{ cron_service }}.service.d
+ state: directory
+ owner: root
+ group: root
+ mode: '0755'
+ - name: Use faketime with cron service
+ copy:
+ content: '[Service]
+
+ Environment=LD_PRELOAD={{ libfaketime_path.stdout_lines[0].strip() }}
+
+ Environment="FAKETIME=+0y x10"
+
+ Environment=RANDOM_DELAY=0'
+ dest: /etc/systemd/system/{{ cron_service }}.service.d/faketime.conf
+ owner: root
+ group: root
+ mode: '0644'
+ - when: ansible_system == 'FreeBSD'
+ name: Use faketime with cron service
+ copy:
+ content: cron_env='LD_PRELOAD={{ libfaketime_path.stdout_lines[0].strip() }} FAKETIME="+0y x10"'
+ dest: /etc/rc.conf.d/cron
+ owner: root
+ group: wheel
+ mode: '0644'
+ - name: enable cron service
+ service:
+ daemon-reload: '{{ (ansible_service_mgr == ''systemd'') | ternary(true, omit) }}'
+ name: '{{ cron_service }}'
+ state: restarted
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_cron/vars/alpine.yml b/ansible_collections/community/general/tests/integration/targets/setup_cron/vars/alpine.yml
new file mode 100644
index 000000000..7c28829c6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_cron/vars/alpine.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cron_pkg: cronie
+cron_service: cronie
+list_pkg_files: apk info -L
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_cron/vars/archlinux.yml b/ansible_collections/community/general/tests/integration/targets/setup_cron/vars/archlinux.yml
new file mode 100644
index 000000000..c714683ad
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_cron/vars/archlinux.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cron_pkg: cronie
+cron_service: cronie
+list_pkg_files: pacman -Ql
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_cron/vars/debian.yml b/ansible_collections/community/general/tests/integration/targets/setup_cron/vars/debian.yml
new file mode 100644
index 000000000..1eefe007c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_cron/vars/debian.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cron_pkg: cron
+cron_service: cron
+list_pkg_files: dpkg -L
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_cron/vars/default.yml b/ansible_collections/community/general/tests/integration/targets/setup_cron/vars/default.yml
new file mode 100644
index 000000000..f55df21f8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_cron/vars/default.yml
@@ -0,0 +1,4 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_cron/vars/fedora.yml b/ansible_collections/community/general/tests/integration/targets/setup_cron/vars/fedora.yml
new file mode 100644
index 000000000..0d17db6ba
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_cron/vars/fedora.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cron_pkg: cronie
+cron_service: crond
+list_pkg_files: rpm -ql
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_cron/vars/freebsd.yml b/ansible_collections/community/general/tests/integration/targets/setup_cron/vars/freebsd.yml
new file mode 100644
index 000000000..284871016
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_cron/vars/freebsd.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cron_pkg:
+cron_service: cron
+list_pkg_files: pkg info --list-files
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_cron/vars/redhat.yml b/ansible_collections/community/general/tests/integration/targets/setup_cron/vars/redhat.yml
new file mode 100644
index 000000000..2998f7b84
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_cron/vars/redhat.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cron_pkg: cronie
+cron_service: crond
+faketime_pkg:
+list_pkg_files: rpm -ql
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_cron/vars/suse.yml b/ansible_collections/community/general/tests/integration/targets/setup_cron/vars/suse.yml
new file mode 100644
index 000000000..77e7e09e3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_cron/vars/suse.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cron_pkg: cron
+cron_service: cron
+list_pkg_files: rpm -ql
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_docker/README.md b/ansible_collections/community/general/tests/integration/targets/setup_docker/README.md
new file mode 100644
index 000000000..f2f26b7cc
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_docker/README.md
@@ -0,0 +1,73 @@
+<!--
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+-->
+
+Setup Docker
+============
+
+This role provides a mechanism to install docker automatically within the context of an integration test.
+
+For the time being (Apr 2023) it has been tested in Fedora 37 and Ubuntu Jammy.
+
+This role was largely based on the `setup_snap` one written by @felixfontein.
+
+
+Quickstart
+----------
+
+Add the file `meta/main.yml` to your integration test target it it does not yet contain one, and add (or update) the `dependencies` block with `setup_docker`, as in:
+
+```yaml
+dependencies:
+ - setup_docker
+```
+
+In your integration test target, add to the beginning of the `tasks/main.yml` something like (example from `mssql_script`):
+
+```yaml
+- name: Start container
+ community.docker.docker_container:
+ name: mssql-test
+ image: "mcr.microsoft.com/mssql/server:2019-latest"
+ env:
+ ACCEPT_EULA: "Y"
+ SA_PASSWORD: "{{ mssql_login_password }}"
+ MSSQL_PID: Developer
+ ports:
+ - "{{ mssql_port }}:1433"
+ detach: true
+ auto_remove: true
+ memory: 2200M
+```
+
+That's it! Your integration test will be using a docker container to support the test.
+
+
+What it does
+------------
+
+The role will install `docker` on the test target, allowing the test to run a container to support its execution.
+
+The installation of the package sends a notification to an Ansible handler that will remove `docker` from the system after the integration test target is done.
+
+This role assumes that developers will use the collection `community.docker` to manage the containers used in the test. To support that assumption, this role will install the `requests` package in the Python runtime environment used, usually a *virtualenv* used for the test. That package is **not removed** from that environment after the test.
+
+The most common use case is to use `community.docker.docker_container` to start a container, as in the example above. It is likely that `community.docker.docker_compose` can be used as well, although this has **not been tested** yet.
+
+
+Recommendations
+---------------
+
+* Don't forget to publish the service ports when starting the container
+* Take into consideration that the services inside the container will take a while to get started. Use both/either `ansible.builtin.wait_for` to check for the availability of the network port and/or `retries` on the first task effectively using those services
+* As a precautionary measure, start using the role in a test that is marked either `disabled` or `unsupported`, and move forward from there.
+
+
+Known Issues & Caveats
+----------------------
+
+* Support only Ubuntu and Fedora, having been tested in Ubuntu Jammy and Fedora 37, respectively
+* Lack mechanism to choose or constraint the `docker` version to be used
+* Lack option to prevent `docker` from being removed at the end of the integration test
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_docker/aliases b/ansible_collections/community/general/tests/integration/targets/setup_docker/aliases
new file mode 100644
index 000000000..0a430dff1
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_docker/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+needs/target/setup_epel
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_docker/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_docker/defaults/main.yml
new file mode 100644
index 000000000..55dc6fdb2
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_docker/defaults/main.yml
@@ -0,0 +1,14 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+distro_lookup_names:
+ - "D-{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_version }}.yml"
+ - "D-{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_major_version }}.yml"
+ - "{{ ansible_facts.os_family }}-{{ ansible_facts.distribution_major_version }}.yml"
+ - "D-{{ ansible_facts.distribution }}.yml"
+ - "{{ ansible_facts.os_family }}.yml"
+ - "default.yml"
+
+has_docker: false
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_docker/handlers/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_docker/handlers/main.yml
new file mode 100644
index 000000000..283496714
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_docker/handlers/main.yml
@@ -0,0 +1,19 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Remove Docker packages
+ package:
+ name: "{{ docker_packages }}"
+ state: absent
+
+- name: "D-Fedora : Remove repository"
+ file:
+ path: /etc/yum.repos.d/docker-ce.repo
+ state: absent
+
+- name: "D-Fedora : Remove dnf-plugins-core"
+ package:
+ name: dnf-plugins-core
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_docker/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_docker/meta/main.yml
new file mode 100644
index 000000000..2fcd152f9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_docker/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_docker/tasks/D-Fedora.yml b/ansible_collections/community/general/tests/integration/targets/setup_docker/tasks/D-Fedora.yml
new file mode 100644
index 000000000..80d6e869d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_docker/tasks/D-Fedora.yml
@@ -0,0 +1,33 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# dnf -y install dnf-plugins-core
+# dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo
+# sudo dnf -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin
+
+- name: Install dnf-plugins-core
+ become: true
+ package:
+ name: dnf-plugins-core
+ state: present
+ notify: "D-Fedora : Remove dnf-plugins-core"
+
+- name: Add docker repo
+ become: true
+ ansible.builtin.command:
+ cmd: dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo
+ notify: "D-Fedora : Remove repository"
+
+- name: Install docker
+ become: true
+ package:
+ name: "{{ item }}"
+ state: present
+ loop: "{{ docker_packages }}"
+ notify: Remove Docker packages
+
+- name: Inform that docker is installed
+ set_fact:
+ has_docker: true
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_docker/tasks/default.yml b/ansible_collections/community/general/tests/integration/targets/setup_docker/tasks/default.yml
new file mode 100644
index 000000000..a628e074b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_docker/tasks/default.yml
@@ -0,0 +1,21 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# dnf -y install dnf-plugins-core
+# dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo
+# sudo dnf -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin
+
+- name: Install docker
+ become: true
+ package:
+ name: "{{ item }}"
+ state: present
+ loop: "{{ docker_packages }}"
+ notify:
+ - Remove Docker packages
+
+- name: Inform that docker is installed
+ set_fact:
+ has_docker: true
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_docker/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_docker/tasks/main.yml
new file mode 100644
index 000000000..4f41da31a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_docker/tasks/main.yml
@@ -0,0 +1,55 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Print information on which we distinguish
+ debug:
+ msg: "Distribution '{{ ansible_facts.distribution }}', version '{{ ansible_facts.distribution_version }}', OS family '{{ ansible_facts.os_family }}'"
+
+- name: Install EPEL repository (RHEL only)
+ include_role:
+ name: setup_epel
+ when:
+ - ansible_distribution in ['RedHat', 'CentOS']
+ - ansible_distribution_major_version is version('9', '<')
+
+- name: Distribution specific
+ block:
+ - name: Include distribution specific vars
+ include_vars: "{{ lookup('first_found', params) }}"
+ vars:
+ params:
+ files: "{{ distro_lookup_names }}"
+ paths:
+ - "{{ role_path }}/vars"
+ - name: Include distribution specific tasks
+ include_tasks: "{{ lookup('first_found', params) }}"
+ vars:
+ params:
+ files: "{{ distro_lookup_names }}"
+ paths:
+ - "{{ role_path }}/tasks"
+
+- name: Start docker service
+ become: true
+ ansible.builtin.service:
+ name: docker
+ state: started
+
+- name: Cheat on the docker socket permissions
+ become: true
+ ansible.builtin.file:
+ path: /var/run/docker.sock
+ mode: 0666
+
+- name: Install python "requests"
+ ansible.builtin.pip:
+ name:
+ - requests
+ state: present
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_docker/vars/D-Fedora.yml b/ansible_collections/community/general/tests/integration/targets/setup_docker/vars/D-Fedora.yml
new file mode 100644
index 000000000..f03626f4a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_docker/vars/D-Fedora.yml
@@ -0,0 +1,10 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+docker_packages:
+ - docker-ce
+ - docker-ce-cli
+ - containerd.io
+ - docker-compose-plugin
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_docker/vars/D-Ubuntu.yml b/ansible_collections/community/general/tests/integration/targets/setup_docker/vars/D-Ubuntu.yml
new file mode 100644
index 000000000..260dc1d5e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_docker/vars/D-Ubuntu.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+docker_packages:
+ - docker.io
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_epel/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_epel/tasks/main.yml
new file mode 100644
index 000000000..186d515f4
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_epel/tasks/main.yml
@@ -0,0 +1,25 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install EPEL
+ yum:
+ name: https://s3.amazonaws.com/ansible-ci-files/test/integration/targets/setup_epel/epel-release-latest-{{ ansible_distribution_major_version }}.noarch.rpm
+ disable_gpg_check: true
+ when:
+ - ansible_facts.distribution in ['RedHat', 'CentOS']
+ - ansible_facts.distribution_major_version == '6'
+
+- name: Install EPEL
+ yum:
+ name: https://ci-files.testing.ansible.com/test/integration/targets/setup_epel/epel-release-latest-{{ ansible_distribution_major_version }}.noarch.rpm
+ disable_gpg_check: true
+ when:
+ - ansible_facts.distribution in ['RedHat', 'CentOS']
+ - ansible_facts.distribution_major_version != '6'
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_etcd3/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_etcd3/defaults/main.yml
new file mode 100644
index 000000000..f185ef0c2
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_etcd3/defaults/main.yml
@@ -0,0 +1,17 @@
+---
+# setup etcd3 for integration tests on module/lookup
+# (c) 2017, Jean-Philippe Evrard <jean-philippe@evrard.me>
+# 2020, SCC France, Eric Belhomme <ebelhomme@fr.scc.com>
+#
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+# # Copyright (c) 2018, Ansible Project
+#
+etcd3_ver: "v3.2.14"
+etcd3_download_server: "https://storage.googleapis.com/etcd"
+#etcd3_download_server: "https://github.com/coreos/etcd/releases/download"
+etcd3_download_url: "{{ etcd3_download_server }}/{{ etcd3_ver }}/etcd-{{ etcd3_ver }}-linux-amd64.tar.gz"
+etcd3_download_location: /tmp/etcd-download-test
+etcd3_path: "{{ etcd3_download_location }}/etcd-{{ etcd3_ver }}-linux-amd64"
+
+etcd3_pip_module: etcd3>=0.12
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_etcd3/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_etcd3/meta/main.yml
new file mode 100644
index 000000000..2fcd152f9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_etcd3/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_etcd3/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_etcd3/tasks/main.yml
new file mode 100644
index 000000000..fe6b9cd02
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_etcd3/tasks/main.yml
@@ -0,0 +1,104 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# setup etcd3 for integration tests on module/lookup
+# Copyright 2017, Jean-Philippe Evrard <jean-philippe@evrard.me>
+# Copyright 2020, SCC France, Eric Belhomme <ebelhomme@fr.scc.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# ============================================================
+
+# setup etcd3 for supported distros
+- block:
+
+ - name: python 2
+ set_fact:
+ python_suffix: ""
+ when: ansible_python_version is version('3', '<')
+
+ - name: python 3
+ set_fact:
+ python_suffix: "-py3"
+ when: ansible_python_version is version('3', '>=')
+
+ - include_vars: '{{ item }}'
+ with_first_found:
+ - files:
+ - '{{ ansible_distribution }}-{{ ansible_distribution_major_version }}{{ python_suffix }}.yml'
+ - '{{ ansible_distribution }}-{{ ansible_distribution_version }}{{ python_suffix }}.yml'
+ - '{{ ansible_os_family }}-{{ ansible_distribution_major_version }}{{ python_suffix }}.yml'
+ - '{{ ansible_os_family }}{{ python_suffix }}.yml'
+ - 'default{{ python_suffix }}.yml'
+ - 'default.yml'
+ paths: '../vars'
+
+ - name: Upgrade setuptools python2 module
+ pip:
+ name: setuptools<45
+ extra_args: --upgrade
+ state: present
+ when: python_suffix == ''
+
+ - name: Install etcd3 python modules
+ pip:
+ name: "{{ etcd3_pip_module }}"
+ extra_args: --only-binary grpcio
+ state: present
+
+ # Check if re-installing etcd3 is required
+ - name: Check if etcd3ctl exists for re-use.
+ shell: "ETCDCTL_API=3 {{ etcd3_path }}/etcdctl --endpoints=localhost:2379 get foo"
+ args:
+ executable: /bin/bash
+ changed_when: false
+ failed_when: false
+ register: _testetcd3ctl
+
+ - block:
+ # Installing etcd3
+ - name: If can't reuse, prepare download folder
+ file:
+ path: "{{ etcd3_download_location }}"
+ state: directory
+ register: _etcddownloadexists
+ when:
+ - _testetcd3ctl.rc != 0
+
+ - name: Delete download folder if already exists (to start clean)
+ file:
+ path: "{{ etcd3_download_location }}"
+ state: absent
+ when:
+ - _etcddownloadexists is not changed
+
+ - name: Recreate download folder if purged
+ file:
+ path: "{{ etcd3_download_location }}"
+ state: directory
+ when:
+ - _etcddownloadexists is not changed
+
+ - name: Download etcd3
+ unarchive:
+ src: "{{ etcd3_download_url }}"
+ dest: "{{ etcd3_download_location }}"
+ remote_src: true
+
+ # Running etcd3 and kill afterwards if it wasn't running before.
+ - name: Run etcd3
+ shell: "{{ etcd3_path }}/etcd &"
+ register: _etcd3run
+ changed_when: true
+
+# - name: kill etcd3
+# command: "pkill etcd"
+
+ when:
+ - _testetcd3ctl.rc != 0
+
+ when:
+ - ansible_distribution | lower ~ "-" ~ ansible_distribution_major_version | lower != 'centos-6'
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_etcd3/vars/RedHat-7.yml b/ansible_collections/community/general/tests/integration/targets/setup_etcd3/vars/RedHat-7.yml
new file mode 100644
index 000000000..6e1017fe8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_etcd3/vars/RedHat-7.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+etcd3_pip_module: etcd3<0.12
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_etcd3/vars/Suse-py3.yml b/ansible_collections/community/general/tests/integration/targets/setup_etcd3/vars/Suse-py3.yml
new file mode 100644
index 000000000..4e7c275b8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_etcd3/vars/Suse-py3.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# SuSE's python 3.6.10 comes with six 1.11.0 as distutil
+# we restrict to etcd3 < 0.11 to avoid pip to try to upgrade six
+etcd3_pip_module: 'etcd3<0.11'
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_etcd3/vars/Suse.yml b/ansible_collections/community/general/tests/integration/targets/setup_etcd3/vars/Suse.yml
new file mode 100644
index 000000000..4e7c275b8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_etcd3/vars/Suse.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# SuSE's python 3.6.10 comes with six 1.11.0 as distutil
+# we restrict to etcd3 < 0.11 to avoid pip to try to upgrade six
+etcd3_pip_module: 'etcd3<0.11'
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_etcd3/vars/default.yml b/ansible_collections/community/general/tests/integration/targets/setup_etcd3/vars/default.yml
new file mode 100644
index 000000000..f7e08fa31
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_etcd3/vars/default.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# default should don't touch anything
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/README.md b/ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/README.md
new file mode 100644
index 000000000..44dfeb0c6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/README.md
@@ -0,0 +1,144 @@
+<!--
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+-->
+
+# Create a dummy flatpak repository remote
+
+This document describes how to create a local flatpak dummy repo. Just like the one contained in the `files/repo.tar.gxz` archive.
+
+
+## Create a hello world app
+
+Prerequisites:
+
+ - flathub
+
+Prepare the environment:
+
+```
+flatpak install --system flathub org.freedesktop.Platform//1.6 org.freedesktop.Sdk//1.6
+```
+
+Create a hello world executable:
+
+```
+echo $'#!/bin/sh\necho hello world' > hello.sh
+```
+
+To create dummy flatpaks, run this (defining a unique NUM for every flatpak to add):
+
+```
+export NUM=1
+flatpak build-init appdir$NUM com.dummy.App$NUM org.freedesktop.Sdk org.freedesktop.Platform 1.6;
+flatpak build appdir$NUM mkdir /app/bin;
+flatpak build appdir$NUM install --mode=750 hello.sh /app/bin;
+flatpak build-finish --command=hello.sh appdir$NUM
+```
+
+## Create a repo and/or add the app to it
+
+Create a repo and add the file to it in one command:
+
+```
+flatpak build-export repo appdir$NUM stable
+```
+
+## Create flatpak*-files
+
+Put a flatpakref file under the repo folder (`repo/com.dummy.App1.flatpakref`):
+
+```
+[Flatpak Ref]
+Title=Dummy App$NUM
+Name=com.dummy.App$NUM
+Branch=stable
+Url=file:///tmp/flatpak/repo
+GPGKey={{ base64-encoded public KEY }}
+IsRuntime=false
+RuntimeRepo=https://flathub.org/repo/flathub.flatpakrepo
+```
+
+Add a `.flatpakrepo` file to the `repo` folder (`repo/dummy-repo.flatpakrepo`):
+
+```
+[Flatpak Repo]
+Title=Dummy Repo
+Url=file:///tmp/flatpak/repo
+Comment=Dummy repo for ansible module integration testing
+Description=Dummy repo for ansible module integration testing
+GPGKey={{ base64-encoded public KEY }}
+```
+
+## Sign the repo
+
+Create a new key in a new gpg home folder (On RedHat systems, the executable needs to addressed as gpg2):
+
+```
+mkdir gpg
+gpg --homedir gpg --quick-gen-key test@dummy.com
+```
+
+Sign the repo and summary file, you need to redo this when you update the repository:
+
+```
+flatpak build-sign repo --gpg-sign=KEY_ID --gpg-homedir=gpg
+flatpak build-update-repo repo --gpg-sign=KEY_ID --gpg-homedir=gpg
+```
+
+Export the public key as a file:
+
+```
+gpg --homedir=gpg --export KEY_ID > dummy-repo.gpg
+```
+
+Create base64-encoded string from gpg-file for `GPGKey=` property in flatpak*-files:
+
+```
+base64 dummy-repo.gpg | tr -d '\n'
+```
+
+## How to use the repo
+
+Now you can add the `repo` folder as a local repo:
+
+```
+flatpak --system remote-add --gpg-import=/tmp/flatpak/repo/dummy-repo.gpg dummy-repo /tmp/flatpak/repo
+```
+
+Or, via `.flatpakrepo` file:
+
+```
+flatpak --system remote-add dummy-repo /tmp/flatpak/repo/dummy-repo.flatpakrepo
+```
+
+And install the hello world flatpaks like this:
+
+```
+flatpak --system install dummy-repo com.dummy.App$NUM
+```
+
+Or from flatpakref:
+
+```
+flatpak --system install --from /tmp/flatpak/repo/com.dummy.App$NUM.flatpakref
+```
+
+Run the app:
+
+```
+flatpak run com.dummy.App$NUM
+```
+
+To install an app without any runtime dependencies (the app will be broken, but it is enough to test flatpak installation):
+
+```
+flatpak --system install --no-deps dummy-repo com.dummy.App$NUM
+```
+
+## Sources:
+
+* https://blogs.gnome.org/alexl/2017/02/10/maintaining-a-flatpak-repository/
+
+* http://docs.flatpak.org/en/latest/first-build.html
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/create-repo.sh b/ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/create-repo.sh
new file mode 100755
index 000000000..11c762184
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/create-repo.sh
@@ -0,0 +1,63 @@
+#!/usr/bin/env bash
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+set -eux
+
+# Delete traces from last run
+rm -rf appdir* dummy-repo.gpg gpg hello.sh repo
+
+# Create GPG key
+mkdir -p gpg
+chmod 0700 gpg
+gpg --homedir gpg --batch --passphrase '' --quick-gen-key test@dummy.com future-default default 10y
+KEY_ID=$(gpg --homedir=gpg --list-keys --with-colons test@dummy.com | grep fpr: | head -1 | cut -d ':' -f 10)
+gpg --homedir=gpg --export "${KEY_ID}" > dummy-repo.gpg
+BASE64_PUBLIC_KEY=$(base64 dummy-repo.gpg | tr -d '\n')
+
+# Install dependencies
+flatpak install -y --system flathub org.freedesktop.Platform//1.6 org.freedesktop.Sdk//1.6
+
+# Add individual flatpaks
+echo $'#!/bin/sh\necho hello world' > hello.sh
+
+for NUM in 1 2 3; do
+ flatpak build-init appdir${NUM} com.dummy.App${NUM} org.freedesktop.Sdk org.freedesktop.Platform 1.6;
+ flatpak build appdir${NUM} mkdir /app/bin;
+ flatpak build appdir${NUM} install --mode=750 hello.sh /app/bin;
+ flatpak build-finish --command=hello.sh appdir${NUM}
+
+ flatpak build-export repo appdir${NUM} stable
+
+ cat > repo/com.dummy.App${NUM}.flatpakref <<EOF
+ [Flatpak Ref]
+ Title=Dummy App${NUM}
+ Name=com.dummy.App${NUM}
+ Branch=stable
+ Url=file:///tmp/flatpak/repo
+ GPGKey=${BASE64_PUBLIC_KEY}
+ IsRuntime=false
+ RuntimeRepo=https://flathub.org/repo/flathub.flatpakrepo
+EOF
+done
+
+# Build repository
+cat > repo/dummy-repo.flatpakrepo <<EOF
+ [Flatpak Repo]
+ Title=Dummy Repo
+ Url=file:///tmp/flatpak/repo
+ Comment=Dummy repo for ansible module integration testing
+ Description=Dummy repo for ansible module integration testing
+ GPGKey=${BASE64_PUBLIC_KEY}
+EOF
+
+flatpak build-sign repo --gpg-sign="${KEY_ID}" --gpg-homedir=gpg
+flatpak build-update-repo repo --gpg-sign="${KEY_ID}" --gpg-homedir=gpg
+
+# Compress repository
+tar cvfJ repo.tar.xz repo/
+mv repo.tar.xz files/
+
+# Cleanup
+rm -rf appdir* dummy-repo.gpg gpg hello.sh repo
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/files/repo.tar.xz b/ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/files/repo.tar.xz
new file mode 100644
index 000000000..609acaad7
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/files/repo.tar.xz
Binary files differ
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/files/repo.tar.xz.license b/ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/files/repo.tar.xz.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/files/repo.tar.xz.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/handlers/main.yaml b/ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/handlers/main.yaml
new file mode 100644
index 000000000..0c88d256e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/handlers/main.yaml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: remove temporary flatpak link
+ file:
+ state: absent
+ path: /tmp/flatpak
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/meta/main.yaml b/ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/meta/main.yaml
new file mode 100644
index 000000000..1b3d5b875
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/meta/main.yaml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/tasks/main.yaml b/ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/tasks/main.yaml
new file mode 100644
index 000000000..037784738
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_flatpak_remote/tasks/main.yaml
@@ -0,0 +1,32 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Set up dummy flatpak repository remote
+ when: |
+ ansible_distribution == 'Fedora' or
+ ansible_distribution == 'Ubuntu' and not ansible_distribution_major_version | int < 16
+ block:
+ - name: Copy repo into place
+ unarchive:
+ src: repo.tar.xz
+ dest: '{{ remote_tmp_dir }}'
+ owner: root
+ group: root
+ mode: '0644'
+ - name: Create deterministic link to temp directory
+ file:
+ state: link
+ src: '{{ remote_tmp_dir }}/'
+ path: /tmp/flatpak
+ owner: root
+ group: root
+ mode: '0644'
+ notify: remove temporary flatpak link
+ become: true
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_gnutar/handlers/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_gnutar/handlers/main.yml
new file mode 100644
index 000000000..f75354097
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_gnutar/handlers/main.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: uninstall gnu-tar
+ community.general.homebrew:
+ name: gnu-tar
+ state: absent
+ become: true
+ become_user: "{{ brew_stat.stat.pw_name }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_gnutar/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_gnutar/tasks/main.yml
new file mode 100644
index 000000000..8dbfebf6f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_gnutar/tasks/main.yml
@@ -0,0 +1,24 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- when: ansible_facts.distribution == 'MacOSX'
+ block:
+ - name: MACOS | Find brew binary
+ command: which brew
+ register: brew_which
+
+ - name: MACOS | Get owner of brew binary
+ stat:
+ path: "{{ brew_which.stdout }}"
+ register: brew_stat
+
+ - name: MACOS | Install gnu-tar
+ community.general.homebrew:
+ name: gnu-tar
+ state: present
+ become: true
+ become_user: "{{ brew_stat.stat.pw_name }}"
+ notify:
+ - uninstall gnu-tar
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_influxdb/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_influxdb/tasks/main.yml
new file mode 100644
index 000000000..bc64ab319
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_influxdb/tasks/main.yml
@@ -0,0 +1,12 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- include_tasks: setup.yml
+ when: ansible_distribution == 'Ubuntu' and ansible_distribution_release == 'trusty'
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_influxdb/tasks/setup.yml b/ansible_collections/community/general/tests/integration/targets/setup_influxdb/tasks/setup.yml
new file mode 100644
index 000000000..205bd27d8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_influxdb/tasks/setup.yml
@@ -0,0 +1,29 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install https transport for apt and ca-certificates
+ apt: name={{ item }} state=latest force=yes
+ with_items:
+ - apt-transport-https
+ - ca-certificates
+
+- name: Install apt_key dependencies
+ pip: name={{ item }}
+ with_items:
+ - pyOpenSSL
+ - ndg-httpsclient
+ - pyasn1
+
+- name: Add InfluxDB public GPG key
+ apt_key: url=https://repos.influxdata.com/influxdb.key state=present
+
+- name: Add InfluxDB repository
+ apt_repository: repo='deb https://repos.influxdata.com/ubuntu trusty stable' filename='influxdb' state=present update_cache=yes
+
+- name: Install InfluxDB
+ apt: name=influxdb state=latest
+
+- name: Start InfluxDB service
+ service: name=influxdb state=started
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_java_keytool/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_java_keytool/meta/main.yml
new file mode 100644
index 000000000..d4a5c7d05
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_java_keytool/meta/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_remote_constraints
+ - setup_pkg_mgr
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_java_keytool/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_java_keytool/tasks/main.yml
new file mode 100644
index 000000000..2ab57d59d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_java_keytool/tasks/main.yml
@@ -0,0 +1,26 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- set_fact:
+ has_java_keytool: >-
+ {{
+ ansible_os_family not in ['Darwin', 'FreeBSD']
+ and not (ansible_distribution == "CentOS" and ansible_distribution_version is version("7.0", "<"))
+ }}
+
+- name: Include OS-specific variables
+ include_vars: '{{ ansible_os_family }}.yml'
+ when: has_java_keytool
+
+- name: Install keytool
+ package:
+ name: '{{ keytool_package_name }}'
+ become: true
+ when: has_java_keytool
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/Alpine.yml b/ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/Alpine.yml
new file mode 100644
index 000000000..4ff75ae8c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/Alpine.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+keytool_package_name: openjdk11-jre-headless
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/Archlinux.yml b/ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/Archlinux.yml
new file mode 100644
index 000000000..9e29065b3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/Archlinux.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+keytool_package_name: jre11-openjdk-headless
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/Debian.yml b/ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/Debian.yml
new file mode 100644
index 000000000..30ae5cd04
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/Debian.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+keytool_package_name: ca-certificates-java
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/RedHat.yml b/ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/RedHat.yml
new file mode 100644
index 000000000..c200091f8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/RedHat.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+keytool_package_name: java-11-openjdk-headless
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/Suse.yml b/ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/Suse.yml
new file mode 100644
index 000000000..c200091f8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_java_keytool/vars/Suse.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+keytool_package_name: java-11-openjdk-headless
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_mosquitto/files/mosquitto.conf b/ansible_collections/community/general/tests/integration/targets/setup_mosquitto/files/mosquitto.conf
new file mode 100644
index 000000000..450330293
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_mosquitto/files/mosquitto.conf
@@ -0,0 +1,39 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Plain MQTT protocol
+listener 1883
+
+# MQTT over TLS 1.1
+listener 8883
+tls_version tlsv1.1
+cafile /tls/ca_certificate.pem
+certfile /tls/server_certificate.pem
+keyfile /tls/server_key.pem
+
+# MQTT over TLS 1.2
+listener 8884
+tls_version tlsv1.2
+cafile /tls/ca_certificate.pem
+certfile /tls/server_certificate.pem
+keyfile /tls/server_key.pem
+
+# TODO(This does not appear to be supported on Ubuntu 18.04. Re-try on 20.04 or next LTS release)
+# MQTT over TLS 1.3
+#
+# listener 8885
+# tls_version tlsv1.3
+# cafile /tls/ca_certificate.pem
+# certfile /tls/server_certificate.pem
+# keyfile /tls/server_key.pem
+
+log_dest syslog
+
+log_type error
+log_type warning
+log_type notice
+log_type information
+log_type debug
+
+connection_messages true
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_mosquitto/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_mosquitto/meta/main.yml
new file mode 100644
index 000000000..488c355d0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_mosquitto/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_tls
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_mosquitto/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_mosquitto/tasks/main.yml
new file mode 100644
index 000000000..2dd0674dc
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_mosquitto/tasks/main.yml
@@ -0,0 +1,12 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- include_tasks: ubuntu.yml
+ when: ansible_distribution == 'Ubuntu'
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_mosquitto/tasks/ubuntu.yml b/ansible_collections/community/general/tests/integration/targets/setup_mosquitto/tasks/ubuntu.yml
new file mode 100644
index 000000000..8222aa175
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_mosquitto/tasks/ubuntu.yml
@@ -0,0 +1,29 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install https transport for apt
+ apt:
+ name: apt-transport-https
+ state: latest
+ force: true
+
+- name: Install Mosquitto Server
+ apt:
+ name: mosquitto
+ state: latest
+ register: result
+ until: result is success
+ delay: 3
+ retries: 10
+
+- name: Ensure TLS config
+ copy:
+ src: mosquitto.conf
+ dest: /etc/mosquitto/mosquitto.conf
+
+- name: Start Mosquitto service
+ service:
+ name: mosquitto
+ state: restarted
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_openldap/files/initial_config.ldif b/ansible_collections/community/general/tests/integration/targets/setup_openldap/files/initial_config.ldif
new file mode 100644
index 000000000..8f8c537bd
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_openldap/files/initial_config.ldif
@@ -0,0 +1,22 @@
+dn: ou=users,dc=example,dc=com
+objectClass: organizationalUnit
+objectClass: top
+ou: users
+
+dn: uid=ldaptest,ou=users,dc=example,dc=com
+uid: ldaptest
+uidNumber: 1111
+gidNUmber: 100
+objectClass: top
+objectClass: posixAccount
+objectClass: shadowAccount
+objectClass: person
+objectClass: organizationalPerson
+objectClass: inetOrgPerson
+loginShell: /bin/sh
+homeDirectory: /home/ldaptest
+cn: LDAP Test
+gecos: LDAP Test
+displayName: LDAP Test
+mail: ldap.test@example.com
+sn: Test
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_openldap/files/initial_config.ldif.license b/ansible_collections/community/general/tests/integration/targets/setup_openldap/files/initial_config.ldif.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_openldap/files/initial_config.ldif.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_openldap/files/rootpw_cnconfig.ldif b/ansible_collections/community/general/tests/integration/targets/setup_openldap/files/rootpw_cnconfig.ldif
new file mode 100644
index 000000000..7fb34d93b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_openldap/files/rootpw_cnconfig.ldif
@@ -0,0 +1,4 @@
+dn: olcDatabase={0}config,cn=config
+changetype: modify
+replace: olcRootPW
+olcRootPW: "Test1234!"
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_openldap/files/rootpw_cnconfig.ldif.license b/ansible_collections/community/general/tests/integration/targets/setup_openldap/files/rootpw_cnconfig.ldif.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_openldap/files/rootpw_cnconfig.ldif.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_openldap/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_openldap/meta/main.yml
new file mode 100644
index 000000000..2fcd152f9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_openldap/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_openldap/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_openldap/tasks/main.yml
new file mode 100644
index 000000000..25077de16
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_openldap/tasks/main.yml
@@ -0,0 +1,72 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Setup OpenLDAP on Debian or Ubuntu
+ block:
+ - name: Include OS-specific variables
+ include_vars: '{{ ansible_os_family }}.yml'
+
+ - name: Install OpenLDAP server and tools
+ become: true
+ package:
+ name: '{{ item }}'
+ loop: '{{ openldap_packages_name }}'
+
+ - name: Install python-ldap (Python 3)
+ become: true
+ package:
+ name: '{{ python_ldap_package_name_python3 }}'
+ when: ansible_python_version is version('3.0', '>=')
+
+ - name: Install python-ldap (Python 2)
+ become: true
+ package:
+ name: '{{ python_ldap_package_name }}'
+ when: ansible_python_version is version('3.0', '<')
+
+ - name: Make sure OpenLDAP service is stopped
+ become: true
+ shell: 'cat /var/run/slapd/slapd.pid | xargs -r kill -9 '
+
+ - name: Debconf
+ shell: 'echo "slapd {{ item.question }} {{ item.vtype }} {{ item.value }}" >> /root/debconf-slapd.conf'
+ loop: "{{ openldap_debconfs }}"
+
+ - name: Dpkg reconfigure
+ shell:
+ cmd: "export DEBIAN_FRONTEND=noninteractive; cat /root/debconf-slapd.conf | debconf-set-selections; dpkg-reconfigure -f noninteractive slapd"
+ creates: "/root/slapd_configured"
+
+ - name: Start OpenLDAP service
+ become: true
+ service:
+ name: '{{ openldap_service_name }}'
+ enabled: true
+ state: started
+
+ - name: Copy initial config ldif file
+ become: true
+ copy:
+ src: 'files/{{ item }}'
+ dest: '/tmp/{{ item }}'
+ owner: root
+ group: root
+ mode: '0644'
+ loop:
+ - rootpw_cnconfig.ldif
+ - initial_config.ldif
+
+ - name: Configure admin password for cn=config
+ shell: "ldapmodify -Y EXTERNAL -H ldapi:/// -f /tmp/rootpw_cnconfig.ldif"
+
+ - name: Add initial config
+ become: true
+ shell: 'ldapadd -H ldapi:/// -x -D "cn=admin,dc=example,dc=com" -w Test1234! -f /tmp/initial_config.ldif'
+ when: ansible_os_family in ['Ubuntu', 'Debian']
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_openldap/vars/Debian.yml b/ansible_collections/community/general/tests/integration/targets/setup_openldap/vars/Debian.yml
new file mode 100644
index 000000000..3b4f19810
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_openldap/vars/Debian.yml
@@ -0,0 +1,60 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+python_ldap_package_name: python-ldap
+python_ldap_package_name_python3: python3-ldap
+openldap_packages_name:
+ - slapd
+ - ldap-utils
+openldap_service_name: slapd
+openldap_debconfs:
+ - question: "shared/organization"
+ value: "Example Organization"
+ vtype: "string"
+ - question: "slapd/allow_ldap_v2"
+ value: "false"
+ vtype: "boolean"
+ - question: "slapd/backend"
+ value: "MDB"
+ vtype: "select"
+ - question: "slapd/domain"
+ value: "example.com"
+ vtype: "string"
+ - question: "slapd/dump_database"
+ value: "when needed"
+ vtype: "select"
+ - question: "slapd/dump_database_destdir"
+ value: "/var/backups/slapd-VERSION"
+ vtype: "string"
+ - question: "slapd/internal/adminpw"
+ value: "Test1234!"
+ vtype: "password"
+ - question: "slapd/internal/generated_adminpw"
+ value: "Test1234!"
+ vtype: "password"
+ - question: "slapd/invalid_config"
+ value: "true"
+ vtype: "boolean"
+ - question: "slapd/move_old_database"
+ value: "true"
+ vtype: "boolean"
+ - question: "slapd/no_configuration"
+ value: "false"
+ vtype: "boolean"
+ - question: "slapd/password1"
+ value: "Test1234!"
+ vtype: "password"
+ - question: "slapd/password2"
+ value: "Test1234!"
+ vtype: "password"
+ - question: "slapd/password_mismatch"
+ value: ""
+ vtype: "note"
+ - question: "slapd/purge_database"
+ value: "false"
+ vtype: "boolean"
+ - question: "slapd/upgrade_slapcat_failure"
+ value: ""
+ vtype: "error"
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_openldap/vars/Ubuntu.yml b/ansible_collections/community/general/tests/integration/targets/setup_openldap/vars/Ubuntu.yml
new file mode 100644
index 000000000..3b4f19810
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_openldap/vars/Ubuntu.yml
@@ -0,0 +1,60 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+python_ldap_package_name: python-ldap
+python_ldap_package_name_python3: python3-ldap
+openldap_packages_name:
+ - slapd
+ - ldap-utils
+openldap_service_name: slapd
+openldap_debconfs:
+ - question: "shared/organization"
+ value: "Example Organization"
+ vtype: "string"
+ - question: "slapd/allow_ldap_v2"
+ value: "false"
+ vtype: "boolean"
+ - question: "slapd/backend"
+ value: "MDB"
+ vtype: "select"
+ - question: "slapd/domain"
+ value: "example.com"
+ vtype: "string"
+ - question: "slapd/dump_database"
+ value: "when needed"
+ vtype: "select"
+ - question: "slapd/dump_database_destdir"
+ value: "/var/backups/slapd-VERSION"
+ vtype: "string"
+ - question: "slapd/internal/adminpw"
+ value: "Test1234!"
+ vtype: "password"
+ - question: "slapd/internal/generated_adminpw"
+ value: "Test1234!"
+ vtype: "password"
+ - question: "slapd/invalid_config"
+ value: "true"
+ vtype: "boolean"
+ - question: "slapd/move_old_database"
+ value: "true"
+ vtype: "boolean"
+ - question: "slapd/no_configuration"
+ value: "false"
+ vtype: "boolean"
+ - question: "slapd/password1"
+ value: "Test1234!"
+ vtype: "password"
+ - question: "slapd/password2"
+ value: "Test1234!"
+ vtype: "password"
+ - question: "slapd/password_mismatch"
+ value: ""
+ vtype: "note"
+ - question: "slapd/purge_database"
+ value: "false"
+ vtype: "boolean"
+ - question: "slapd/upgrade_slapcat_failure"
+ value: ""
+ vtype: "error"
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_opennebula/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_opennebula/meta/main.yml
new file mode 100644
index 000000000..fe9e33681
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_opennebula/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_remote_constraints
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_opennebula/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_opennebula/tasks/main.yml
new file mode 100644
index 000000000..b7babbaab
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_opennebula/tasks/main.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install required library
+ pip:
+ name: pyone
+ extra_args: "-c {{ remote_constraints }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_opennebula/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_opennebula/vars/main.yml
new file mode 100644
index 000000000..39b48270a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_opennebula/vars/main.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+opennebula_test:
+ hosts:
+ - hv1
+ - hv2
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_openssl/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_openssl/meta/main.yml
new file mode 100644
index 000000000..d4a5c7d05
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_openssl/meta/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_remote_constraints
+ - setup_pkg_mgr
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_openssl/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_openssl/tasks/main.yml
new file mode 100644
index 000000000..b8e003710
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_openssl/tasks/main.yml
@@ -0,0 +1,69 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Include OS-specific variables
+ include_vars: '{{ lookup("first_found", search) }}'
+ vars:
+ search:
+ files:
+ - '{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml'
+ - '{{ ansible_distribution }}-{{ ansible_distribution_version }}.yml'
+ - '{{ ansible_distribution }}.yml'
+ - '{{ ansible_os_family }}.yml'
+ - default.yml
+ paths:
+ - vars
+
+- name: Install OpenSSL
+ become: true
+ package:
+ name: '{{ openssl_package_name }}'
+ when: not ansible_os_family == 'Darwin'
+
+- when: ansible_facts.distribution ~ ansible_facts.distribution_major_version not in ['CentOS6', 'RedHat6']
+ block:
+ - name: Install cryptography (Python 3)
+ become: true
+ package:
+ name: '{{ cryptography_package_name_python3 }}'
+ when: not cryptography_from_pip and ansible_python_version is version('3.0', '>=')
+
+ - name: Install cryptography (Python 2)
+ become: true
+ package:
+ name: '{{ cryptography_package_name }}'
+ when: not cryptography_from_pip and ansible_python_version is version('3.0', '<')
+
+ - name: Install cryptography (pip)
+ become: true
+ pip:
+ name: cryptography>=3.3
+ extra_args: "-c {{ remote_constraints }}"
+ when: cryptography_from_pip
+
+- name: Install pyOpenSSL (Python 3)
+ become: true
+ package:
+ name: '{{ pyopenssl_package_name_python3 }}'
+ when: pyopenssl_package_name_python3 is defined and ansible_python_version is version('3.0', '>=')
+
+- name: Install pyOpenSSL (Python 2)
+ become: true
+ package:
+ name: '{{ pyopenssl_package_name }}'
+ when: pyopenssl_package_name is defined and ansible_python_version is version('3.0', '<')
+
+- name: register openssl version
+ shell: "openssl version | cut -d' ' -f2"
+ register: openssl_version
+
+- name: register cryptography version
+ command: "{{ ansible_python.executable }} -c 'import cryptography; print(cryptography.__version__)'"
+ register: cryptography_version
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/Alpine.yml b/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/Alpine.yml
new file mode 100644
index 000000000..c5d4d23a4
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/Alpine.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cryptography_package_name: py-cryptography
+cryptography_package_name_python3: py3-cryptography
+pyopenssl_package_name: py-openssl
+pyopenssl_package_name_python3: py3-openssl
+openssl_package_name: openssl
+cryptography_from_pip: false
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/Archlinux.yml b/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/Archlinux.yml
new file mode 100644
index 000000000..b6ae2fe10
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/Archlinux.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cryptography_package_name: python-cryptography
+cryptography_package_name_python3: python-cryptography
+pyopenssl_package_name: python-pyopenssl
+pyopenssl_package_name_python3: python-pyopenssl
+openssl_package_name: openssl
+cryptography_from_pip: false
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/CentOS-8.yml b/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/CentOS-8.yml
new file mode 100644
index 000000000..875a69718
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/CentOS-8.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cryptography_package_name: python-cryptography
+cryptography_package_name_python3: python3-cryptography
+openssl_package_name: openssl
+cryptography_from_pip: '{{ ansible_python_version is version("3.8", ">=") }}'
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/Darwin.yml b/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/Darwin.yml
new file mode 100644
index 000000000..b3dbd9811
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/Darwin.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cryptography_from_pip: true
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/Debian.yml b/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/Debian.yml
new file mode 100644
index 000000000..6ef3df1a1
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/Debian.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cryptography_package_name: python-cryptography
+cryptography_package_name_python3: python3-cryptography
+pyopenssl_package_name: python-openssl
+pyopenssl_package_name_python3: python3-openssl
+openssl_package_name: openssl
+cryptography_from_pip: false
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/FreeBSD.yml b/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/FreeBSD.yml
new file mode 100644
index 000000000..e5ad6812f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/FreeBSD.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cryptography_package_name: py27-cryptography
+cryptography_package_name_python3: "py{{ ansible_python.version.major }}{{ ansible_python.version.minor }}-cryptography"
+pyopenssl_package_name: py27-openssl
+pyopenssl_package_name_python3: "py{{ ansible_python.version.major }}{{ ansible_python.version.minor }}-openssl"
+openssl_package_name: openssl
+cryptography_from_pip: false
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/RedHat-9.yml b/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/RedHat-9.yml
new file mode 100644
index 000000000..ac9b3344e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/RedHat-9.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cryptography_package_name: python-cryptography
+cryptography_package_name_python3: python3-cryptography
+openssl_package_name: openssl
+cryptography_from_pip: false
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/RedHat.yml b/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/RedHat.yml
new file mode 100644
index 000000000..ef78bab01
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/RedHat.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cryptography_package_name: python-cryptography
+cryptography_package_name_python3: python3-cryptography
+pyopenssl_package_name: pyOpenSSL
+pyopenssl_package_name_python3: python3-pyOpenSSL
+openssl_package_name: openssl
+cryptography_from_pip: false
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/Suse.yml b/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/Suse.yml
new file mode 100644
index 000000000..b7d246653
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_openssl/vars/Suse.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+cryptography_package_name: python-cryptography
+cryptography_package_name_python3: python3-cryptography
+pyopenssl_package_name: python-pyOpenSSL
+pyopenssl_package_name_python3: python3-pyOpenSSL
+openssl_package_name: openssl
+cryptography_from_pip: false
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_pkg_mgr/tasks/archlinux.yml b/ansible_collections/community/general/tests/integration/targets/setup_pkg_mgr/tasks/archlinux.yml
new file mode 100644
index 000000000..fc75f84df
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_pkg_mgr/tasks/archlinux.yml
@@ -0,0 +1,23 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Since Arch Linux is a rolling distribution, it regularly needs its packages upgraded, otherwise some tests might
+# stop working due to conflicts during package installation. Since there is no good way to do this on container
+# startup time, we use the setup_pkg_mgr setup role to do this once per CI run (hopefully). In case the Arch Linux
+# tests are run outside of a container, we're using a date-based tag (see below) to avoid this running more than
+# once per day.
+
+- name: Create tag
+ copy:
+ dest: /tmp/.ansible_archlinux_sysupgrade_tag
+ content: |
+ Last ArchLinux system upgrade by integration tests was done on {{ ansible_facts.date_time.date }}.
+ register: archlinux_upgrade_tag
+
+- name: Upgrade all packages
+ pacman:
+ update_cache: true
+ upgrade: true
+ when: archlinux_upgrade_tag is changed
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_pkg_mgr/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_pkg_mgr/tasks/main.yml
new file mode 100644
index 000000000..5bff53b3b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_pkg_mgr/tasks/main.yml
@@ -0,0 +1,39 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- set_fact:
+ pkg_mgr: community.general.pkgng
+ ansible_pkg_mgr: community.general.pkgng
+ cacheable: true
+ when: ansible_os_family == "FreeBSD"
+
+- set_fact:
+ pkg_mgr: community.general.zypper
+ ansible_pkg_mgr: community.general.zypper
+ cacheable: true
+ when: ansible_os_family == "Suse"
+
+- set_fact:
+ pkg_mgr: community.general.pacman
+ ansible_pkg_mgr: community.general.pacman
+ cacheable: true
+ when: ansible_os_family == "Archlinux"
+
+- shell:
+ cmd: |
+ sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-Linux-*.repo
+ sed -i 's%#baseurl=http://mirror.centos.org/$contentdir/$releasever/%baseurl=https://vault.centos.org/8.4.2105/%g' /etc/yum.repos.d/CentOS-Linux-*.repo
+ ignore_errors: true # This fails for CentOS Stream 8
+ when: ansible_distribution in 'CentOS' and ansible_distribution_major_version == '8'
+
+- when: ansible_os_family == "Archlinux"
+ block:
+ - name: ArchLinux specific setup
+ include_tasks: archlinux.yml
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/defaults/main.yml
new file mode 100644
index 000000000..1a33ecafa
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/defaults/main.yml
@@ -0,0 +1,22 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+postgresql_service: postgresql
+
+postgresql_packages:
+ - postgresql-server
+ - python-psycopg2
+
+pg_user: postgres
+pg_group: root
+
+locale_latin_suffix:
+locale_utf8_suffix:
+
+# defaults for test SSL
+ssl_db: 'ssl_db'
+ssl_user: 'ssl_user'
+ssl_pass: 'ssl_pass'
+ssl_rootcert: '~{{ pg_user }}/root.crt'
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/files/dummy--1.0.sql b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/files/dummy--1.0.sql
new file mode 100644
index 000000000..89b318d77
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/files/dummy--1.0.sql
@@ -0,0 +1,6 @@
+-- Copyright (c) Ansible Project
+-- GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+CREATE OR REPLACE FUNCTION dummy_display_ext_version()
+RETURNS text LANGUAGE SQL AS 'SELECT (''1.0'')::text';
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/files/dummy--2.0.sql b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/files/dummy--2.0.sql
new file mode 100644
index 000000000..c9386cac4
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/files/dummy--2.0.sql
@@ -0,0 +1,6 @@
+-- Copyright (c) Ansible Project
+-- GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+CREATE OR REPLACE FUNCTION dummy_display_ext_version()
+RETURNS text LANGUAGE SQL AS 'SELECT (''2.0'')::text';
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/files/dummy--3.0.sql b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/files/dummy--3.0.sql
new file mode 100644
index 000000000..a96bc8587
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/files/dummy--3.0.sql
@@ -0,0 +1,6 @@
+-- Copyright (c) Ansible Project
+-- GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+-- SPDX-License-Identifier: GPL-3.0-or-later
+
+CREATE OR REPLACE FUNCTION dummy_display_ext_version()
+RETURNS text LANGUAGE SQL AS 'SELECT (''3.0'')::text';
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/files/dummy.control b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/files/dummy.control
new file mode 100644
index 000000000..4f8553c22
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/files/dummy.control
@@ -0,0 +1,3 @@
+comment = 'dummy extension used to test postgresql_ext Ansible module'
+default_version = '3.0'
+relocatable = true
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/files/dummy.control.license b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/files/dummy.control.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/files/dummy.control.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/files/pg_hba.conf b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/files/pg_hba.conf
new file mode 100644
index 000000000..e6b14c4d7
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/files/pg_hba.conf
@@ -0,0 +1,14 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# !!! This file managed by Ansible. Any local changes may be overwritten. !!!
+
+# Database administrative login by UNIX sockets
+# note: you may wish to restrict this further later
+local all {{ pg_user }} trust
+
+# TYPE DATABASE USER CIDR-ADDRESS METHOD
+local all all md5
+host all all 127.0.0.1/32 md5
+host all all ::1/128 md5
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/meta/main.yml
new file mode 100644
index 000000000..2fcd152f9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/tasks/main.yml
new file mode 100644
index 000000000..3dac4a098
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/tasks/main.yml
@@ -0,0 +1,257 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Exit when Suse because it causes CI problems
+- meta: end_play
+ when: ansible_os_family == 'Suse'
+
+# To avoid hangings on service start/stop postgres during CI runs:
+- meta: end_play
+ when: ansible_facts.distribution == 'CentOS' and ansible_facts.distribution_major_version == '8'
+
+# Temporary disable Fedora 34
+- meta: end_play
+ when: ansible_facts.distribution == 'Fedora' and ansible_facts.distribution_major_version == '34'
+
+- name: python 2
+ set_fact:
+ python_suffix: ''
+ when: ansible_python_version is version('3', '<')
+
+- name: python 3
+ set_fact:
+ python_suffix: -py3
+ when: ansible_python_version is version('3', '>=')
+
+- name: Include distribution and Python version specific variables
+ include_vars: '{{ lookup(''first_found'', params) }}'
+ vars:
+ params:
+ files:
+ - '{{ ansible_distribution }}-{{ ansible_distribution_major_version }}{{ python_suffix }}.yml'
+ - '{{ ansible_distribution }}-{{ ansible_distribution_version }}{{ python_suffix }}.yml'
+ - '{{ ansible_os_family }}{{ python_suffix }}.yml'
+ - default{{ python_suffix }}.yml
+ paths:
+ - '{{ role_path }}/vars'
+
+- name: make sure the dbus service is started under systemd
+ systemd:
+ name: dbus
+ state: started
+ when: ansible_service_mgr == 'systemd' and ansible_distribution == 'Fedora'
+
+- name: Kill all postgres processes
+ shell: 'pkill -u {{ pg_user }}'
+ become: true
+ when: ansible_facts.distribution == 'CentOS' and ansible_facts.distribution_major_version == '8'
+ ignore_errors: true
+
+- name: stop postgresql service
+ service: name={{ postgresql_service }} state=stopped
+ ignore_errors: true
+
+- name: remove old db (RedHat or Suse)
+ file:
+ path: '{{ pg_dir }}'
+ state: absent
+ ignore_errors: true
+ when: ansible_os_family == "RedHat" or ansible_os_family == "Suse"
+
+- name: remove old db (FreeBSD)
+ file:
+ path: '{{ pg_dir }}'
+ state: absent
+ ignore_errors: true
+ when: ansible_os_family == "FreeBSD"
+
+- name: remove old db config and files (debian)
+ file:
+ path: '{{ loop_item }}'
+ state: absent
+ ignore_errors: true
+ when: ansible_os_family == "Debian"
+ loop:
+ - /etc/postgresql
+ - /var/lib/postgresql
+ loop_control:
+ loop_var: loop_item
+
+- name: install dependencies for postgresql test
+ package:
+ name: '{{ postgresql_package_item }}'
+ state: present
+ with_items: '{{ postgresql_packages }}'
+ loop_control:
+ loop_var: postgresql_package_item
+
+- name: initialize postgres (FreeBSD)
+ command: /usr/local/etc/rc.d/postgresql oneinitdb
+ when: ansible_os_family == "FreeBSD"
+
+- name: Initialize postgres (RedHat systemd)
+ command: postgresql-setup initdb
+ when: ansible_os_family == "RedHat" and ansible_service_mgr == "systemd"
+
+- name: Initialize postgres (RedHat sysv)
+ command: /sbin/service postgresql initdb
+ when: ansible_os_family == "RedHat" and ansible_service_mgr != "systemd"
+
+- name: Initialize postgres (Archlinux)
+ command: su - postgres -c "initdb --locale en_US.UTF-8 -D '/var/lib/postgres/data'"
+ when: ansible_os_family == "Archlinux"
+
+- name: Initialize postgres (Alpine)
+ command: su - postgres -c "initdb --locale en_US.UTF-8 -D '/var/lib/postgresql/data'"
+ when: ansible_os_family == "Alpine"
+
+- name: Initialize postgres (Debian)
+ shell: . /usr/share/postgresql-common/maintscripts-functions && set_system_locale && /usr/bin/pg_createcluster -u postgres {{ pg_ver }} main
+ args:
+ creates: /etc/postgresql/{{ pg_ver }}/
+ when: ansible_os_family == 'Debian'
+
+- name: Initialize postgres (Suse)
+ service: name=postgresql state=stopped
+ when: ansible_os_family == 'Suse'
+
+- name: Pause between stop and start postgresql
+ pause:
+ seconds: 5
+ when: ansible_os_family == 'Suse'
+
+- name: Initialize postgres (Suse)
+ service: name=postgresql state=started
+ when: ansible_os_family == 'Suse'
+
+- name: Copy pg_hba into place
+ template:
+ src: files/pg_hba.conf
+ dest: '{{ pg_hba_location }}'
+ owner: '{{ pg_user }}'
+ group: '{{ pg_group }}'
+ mode: '0644'
+
+- name: Generate locales (Debian)
+ locale_gen:
+ name: '{{ item }}'
+ state: present
+ with_items:
+ - pt_BR
+ - es_ES
+ when: ansible_os_family == 'Debian'
+
+- block:
+ - name: Install langpacks (RHEL8)
+ yum:
+ name:
+ - glibc-langpack-es
+ - glibc-langpack-pt
+ - glibc-all-langpacks
+ state: present
+ when: ansible_distribution_major_version is version('8', '>=')
+
+ - name: Check if locales need to be generated (RedHat)
+ shell: localedef --list-archive | grep -a -q '^{{ locale }}$'
+ register: locale_present
+ ignore_errors: true
+ with_items:
+ - es_ES
+ - pt_BR
+ loop_control:
+ loop_var: locale
+
+ - name: Reinstall internationalization files
+ shell: yum -y reinstall glibc-common || yum -y install glibc-common
+ when: locale_present is failed
+
+ - name: Generate locale (RedHat)
+ command: localedef -f ISO-8859-1 -i {{ item.locale }} {{ item.locale }}
+ when: item is failed
+ with_items: '{{ locale_present.results }}'
+ when: ansible_os_family == 'RedHat' and ansible_distribution != 'Fedora'
+
+- name: Install glibc langpacks (Fedora >= 24)
+ package:
+ name: '{{ item }}'
+ state: latest
+ with_items:
+ - glibc-langpack-es
+ - glibc-langpack-pt
+ when: ansible_distribution == 'Fedora' and ansible_distribution_major_version is version('24', '>=')
+
+- name: enable postgresql service (FreeBSD)
+ lineinfile:
+ path: /etc/rc.conf
+ line: postgresql_enable="YES"
+ when: ansible_os_family == "FreeBSD"
+
+- name: start postgresql service
+ service: name={{ postgresql_service }} state=started
+
+- name: Pause between start and stop
+ pause:
+ seconds: 5
+
+- name: Kill all postgres processes
+ shell: 'pkill -u {{ pg_user }}'
+ become: true
+ when: ansible_facts.distribution == 'CentOS' and ansible_facts.distribution_major_version == '8'
+ ignore_errors: true
+ register: terminate
+
+- name: Stop postgresql service
+ service: name={{ postgresql_service }} state=stopped
+ when: terminate is not succeeded
+
+- name: Pause between stop and start
+ pause:
+ seconds: 5
+
+- name: Start postgresql service
+ service: name={{ postgresql_service }} state=started
+
+- name: copy control file for dummy ext
+ copy:
+ src: dummy.control
+ dest: /usr/share/postgresql/{{ pg_ver }}/extension/dummy.control
+ mode: '0444'
+ when: ansible_os_family == 'Debian'
+
+- name: copy version files for dummy ext
+ copy:
+ src: '{{ item }}'
+ dest: /usr/share/postgresql/{{ pg_ver }}/extension/{{ item }}
+ mode: '0444'
+ with_items:
+ - dummy--1.0.sql
+ - dummy--2.0.sql
+ - dummy--3.0.sql
+ when: ansible_os_family == 'Debian'
+
+- name: add update paths
+ file:
+ path: /usr/share/postgresql/{{ pg_ver }}/extension/{{ item }}
+ mode: '0444'
+ state: touch
+ with_items:
+ - dummy--1.0--2.0.sql
+ - dummy--2.0--3.0.sql
+ when: ansible_os_family == 'Debian'
+
+- name: Get PostgreSQL version
+ become_user: '{{ pg_user }}'
+ become: true
+ shell: echo 'SHOW SERVER_VERSION' | psql --tuples-only --no-align --dbname postgres
+ register: postgres_version_resp
+
+- name: Print PostgreSQL server version
+ debug:
+ msg: '{{ postgres_version_resp.stdout }}'
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Alpine-py3.yml b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Alpine-py3.yml
new file mode 100644
index 000000000..99a8a14b8
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Alpine-py3.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+postgresql_packages:
+ - "postgresql"
+ - "py3-psycopg2"
+
+pg_hba_location: "/var/lib/postgresql/data/pg_hba.conf"
+pg_dir: "/var/lib/postgresql/data"
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Archlinux-py3.yml b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Archlinux-py3.yml
new file mode 100644
index 000000000..40215d1ad
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Archlinux-py3.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+postgresql_packages:
+ - "postgresql"
+ - "python-psycopg2"
+
+pg_hba_location: "/var/lib/postgres/data/pg_hba.conf"
+pg_dir: "/var/lib/postgres/data"
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Debian-11-py3.yml b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Debian-11-py3.yml
new file mode 100644
index 000000000..1ffd257b2
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Debian-11-py3.yml
@@ -0,0 +1,13 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+postgresql_packages:
+ - "postgresql"
+ - "postgresql-common"
+ - "python3-psycopg2"
+
+pg_hba_location: "/etc/postgresql/13/main/pg_hba.conf"
+pg_dir: "/var/lib/postgresql/13/main"
+pg_ver: 13
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Debian-8.yml b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Debian-8.yml
new file mode 100644
index 000000000..87063214a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Debian-8.yml
@@ -0,0 +1,13 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+postgresql_packages:
+ - "postgresql"
+ - "postgresql-common"
+ - "python-psycopg2"
+
+pg_hba_location: "/etc/postgresql/9.4/main/pg_hba.conf"
+pg_dir: "/var/lib/postgresql/9.4/main"
+pg_ver: 9.4
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/FreeBSD-11-py3.yml b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/FreeBSD-11-py3.yml
new file mode 100644
index 000000000..a92de47cb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/FreeBSD-11-py3.yml
@@ -0,0 +1,17 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+postgresql_packages:
+ - postgresql95-server
+ - "py{{ ansible_python.version.major }}{{ ansible_python.version.minor }}-psycopg2"
+
+pg_dir: /usr/local/pgsql/data
+pg_hba_location: "{{ pg_dir }}/pg_hba.conf"
+pg_ver: 9.5
+pg_user: pgsql
+pg_group: pgsql
+
+locale_latin_suffix: .ISO8859-1
+locale_utf8_suffix: .UTF-8
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/FreeBSD-11.yml b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/FreeBSD-11.yml
new file mode 100644
index 000000000..c38f3b59b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/FreeBSD-11.yml
@@ -0,0 +1,17 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+postgresql_packages:
+ - postgresql95-server
+ - py27-psycopg2
+
+pg_dir: /usr/local/pgsql/data
+pg_hba_location: "{{ pg_dir }}/pg_hba.conf"
+pg_ver: 9.5
+pg_user: pgsql
+pg_group: pgsql
+
+locale_latin_suffix: .ISO8859-1
+locale_utf8_suffix: .UTF-8
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/FreeBSD-12.0-py3.yml b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/FreeBSD-12.0-py3.yml
new file mode 100644
index 000000000..a92de47cb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/FreeBSD-12.0-py3.yml
@@ -0,0 +1,17 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+postgresql_packages:
+ - postgresql95-server
+ - "py{{ ansible_python.version.major }}{{ ansible_python.version.minor }}-psycopg2"
+
+pg_dir: /usr/local/pgsql/data
+pg_hba_location: "{{ pg_dir }}/pg_hba.conf"
+pg_ver: 9.5
+pg_user: pgsql
+pg_group: pgsql
+
+locale_latin_suffix: .ISO8859-1
+locale_utf8_suffix: .UTF-8
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/FreeBSD-12.0.yml b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/FreeBSD-12.0.yml
new file mode 100644
index 000000000..7c5586f5b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/FreeBSD-12.0.yml
@@ -0,0 +1,17 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+postgresql_packages:
+ - postgresql96-server
+ - py27-psycopg2
+
+pg_dir: /usr/local/pgsql/data
+pg_hba_location: "{{ pg_dir }}/pg_hba.conf"
+pg_ver: 9.6
+pg_user: pgsql
+pg_group: pgsql
+
+locale_latin_suffix: .ISO8859-1
+locale_utf8_suffix: .UTF-8
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/FreeBSD-12.1-py3.yml b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/FreeBSD-12.1-py3.yml
new file mode 100644
index 000000000..8e5ddfa13
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/FreeBSD-12.1-py3.yml
@@ -0,0 +1,17 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+postgresql_packages:
+ - postgresql11-server
+ - "py{{ ansible_python.version.major }}{{ ansible_python.version.minor }}-psycopg2"
+
+pg_dir: /var/db/postgres/data11
+pg_hba_location: "{{ pg_dir }}/pg_hba.conf"
+pg_ver: 11
+pg_user: postgres
+pg_group: postgres
+
+locale_latin_suffix: .ISO8859-1
+locale_utf8_suffix: .UTF-8
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/FreeBSD-12.1.yml b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/FreeBSD-12.1.yml
new file mode 100644
index 000000000..0cdc22e13
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/FreeBSD-12.1.yml
@@ -0,0 +1,17 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+postgresql_packages:
+ - postgresql11-server
+ - py27-psycopg2
+
+pg_dir: /var/db/postgres/data11
+pg_hba_location: "{{ pg_dir }}/pg_hba.conf"
+pg_ver: 11
+pg_user: postgres
+pg_group: postgres
+
+locale_latin_suffix: .ISO8859-1
+locale_utf8_suffix: .UTF-8
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/RedHat-py3.yml b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/RedHat-py3.yml
new file mode 100644
index 000000000..3892f2e45
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/RedHat-py3.yml
@@ -0,0 +1,13 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+postgresql_packages:
+ - "postgresql-server"
+ - "python3-psycopg2"
+ - "bzip2"
+ - "xz"
+
+pg_hba_location: "/var/lib/pgsql/data/pg_hba.conf"
+pg_dir: "/var/lib/pgsql/data"
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/RedHat.yml b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/RedHat.yml
new file mode 100644
index 000000000..5670a7fc9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/RedHat.yml
@@ -0,0 +1,12 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+postgresql_packages:
+ - "postgresql-server"
+ - "python-psycopg2"
+ - "bzip2"
+
+pg_hba_location: "/var/lib/pgsql/data/pg_hba.conf"
+pg_dir: "/var/lib/pgsql/data"
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-12.yml b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-12.yml
new file mode 100644
index 000000000..1d850de84
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-12.yml
@@ -0,0 +1,13 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+postgresql_packages:
+ - "postgresql"
+ - "postgresql-common"
+ - "python-psycopg2"
+
+pg_hba_location: "/etc/postgresql/9.1/main/pg_hba.conf"
+pg_dir: "/var/lib/postgresql/9.1/main"
+pg_ver: 9.1
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-14.yml b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-14.yml
new file mode 100644
index 000000000..881fc533e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-14.yml
@@ -0,0 +1,13 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+postgresql_packages:
+ - "postgresql"
+ - "postgresql-common"
+ - "python-psycopg2"
+
+pg_hba_location: "/etc/postgresql/9.3/main/pg_hba.conf"
+pg_dir: "/var/lib/postgresql/9.3/main"
+pg_ver: 9.3
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-16-py3.yml b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-16-py3.yml
new file mode 100644
index 000000000..482982fe1
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-16-py3.yml
@@ -0,0 +1,13 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+postgresql_packages:
+ - "postgresql"
+ - "postgresql-common"
+ - "python3-psycopg2"
+
+pg_hba_location: "/etc/postgresql/9.5/main/pg_hba.conf"
+pg_dir: "/var/lib/postgresql/9.5/main"
+pg_ver: 9.5
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-16.yml b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-16.yml
new file mode 100644
index 000000000..f2df72af7
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-16.yml
@@ -0,0 +1,13 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+postgresql_packages:
+ - "postgresql"
+ - "postgresql-common"
+ - "python-psycopg2"
+
+pg_hba_location: "/etc/postgresql/9.5/main/pg_hba.conf"
+pg_dir: "/var/lib/postgresql/9.5/main"
+pg_ver: 9.5
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-18-py3.yml b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-18-py3.yml
new file mode 100644
index 000000000..19213f4d6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-18-py3.yml
@@ -0,0 +1,13 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+postgresql_packages:
+ - "postgresql"
+ - "postgresql-common"
+ - "python3-psycopg2"
+
+pg_hba_location: "/etc/postgresql/10/main/pg_hba.conf"
+pg_dir: "/var/lib/postgresql/10/main"
+pg_ver: 10
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-20-py3.yml b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-20-py3.yml
new file mode 100644
index 000000000..58fb8a06f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-20-py3.yml
@@ -0,0 +1,13 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+postgresql_packages:
+ - "postgresql"
+ - "postgresql-common"
+ - "python3-psycopg2"
+
+pg_hba_location: "/etc/postgresql/12/main/pg_hba.conf"
+pg_dir: "/var/lib/postgresql/12/main"
+pg_ver: 12
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-22-py3.yml b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-22-py3.yml
new file mode 100644
index 000000000..8ea444099
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/Ubuntu-22-py3.yml
@@ -0,0 +1,13 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+postgresql_packages:
+ - "postgresql"
+ - "postgresql-common"
+ - "python3-psycopg2"
+
+pg_hba_location: "/etc/postgresql/14/main/pg_hba.conf"
+pg_dir: "/var/lib/postgresql/14/main"
+pg_ver: 14
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/default-py3.yml b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/default-py3.yml
new file mode 100644
index 000000000..6f96043a3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/default-py3.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+postgresql_packages:
+ - "postgresql-server"
+ - "python3-psycopg2"
+
+pg_hba_location: "/var/lib/pgsql/data/pg_hba.conf"
+pg_dir: "/var/lib/pgsql/data"
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/default.yml b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/default.yml
new file mode 100644
index 000000000..9d64d969a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_postgresql_db/vars/default.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+postgresql_packages:
+ - "postgresql-server"
+ - "python-psycopg2"
+
+pg_hba_location: "/var/lib/pgsql/data/pg_hba.conf"
+pg_dir: "/var/lib/pgsql/data"
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_redis_replication/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_redis_replication/defaults/main.yml
new file mode 100644
index 000000000..46dae9898
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_redis_replication/defaults/main.yml
@@ -0,0 +1,56 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# General
+redis_packages:
+ Alpine:
+ - redis
+ Archlinux:
+ - redis
+ Debian:
+ - redis-server
+ Ubuntu:
+ - redis-server
+ openSUSE Leap:
+ - redis
+ Fedora:
+ - redis
+ CentOS:
+ - redis
+ FreeBSD:
+ - redis
+
+redis_bin:
+ Alpine: /usr/bin/redis-server
+ Archlinux: /usr/bin/redis-server
+ Debian: /usr/bin/redis-server
+ Ubuntu: /usr/bin/redis-server
+ openSUSE Leap: /usr/sbin/redis-server
+ Fedora: /usr/bin/redis-server
+ CentOS: /usr/bin/redis-server
+ FreeBSD: /usr/local/bin/redis-server
+
+redis_module: redis
+
+redis_password: PASS
+
+old_redis: >-
+ {{
+ (ansible_distribution == 'CentOS' and ansible_distribution_major_version|int <= 7) or
+ (ansible_distribution == 'Ubuntu' and ansible_distribution_major_version|int <= 18) or
+ (ansible_os_family == 'FreeBSD' and ansible_distribution_major_version|int <= 12)
+ }}
+
+# Master
+master_port: 6379
+master_conf: /etc/redis-master.conf
+master_datadir: /var/lib/redis-master
+master_logdir: /var/log/redis-master
+
+# Replica
+replica_port: 6380
+replica_conf: /etc/redis-replica.conf
+replica_datadir: /var/lib/redis-replica
+replica_logdir: /var/log/redis-replica
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_redis_replication/handlers/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_redis_replication/handlers/main.yml
new file mode 100644
index 000000000..a0595cbe3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_redis_replication/handlers/main.yml
@@ -0,0 +1,39 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: stop redis services
+ shell: |
+ kill -TERM $(cat /var/run/redis_{{ master_port }}.pid)
+ kill -TERM $(cat /var/run/redis_{{ replica_port }}.pid)
+ listen: cleanup redis
+
+- name: remove redis packages
+ action: "{{ ansible_facts.pkg_mgr }}"
+ args:
+ name: "{{ item }}"
+ state: absent
+ loop: "{{ redis_packages[ansible_distribution] }}"
+ listen: cleanup redis
+
+- name: remove pip packages
+ pip:
+ name: redis
+ state: absent
+ listen: cleanup redis
+
+- name: remove redis data
+ file:
+ path: "{{ item }}"
+ state: absent
+ loop:
+ - "{{ master_conf }}"
+ - "{{ master_datadir }}"
+ - "{{ master_logdir }}"
+ - /var/run/redis_{{ master_port }}.pid
+ - "{{ replica_conf }}"
+ - "{{ replica_datadir }}"
+ - "{{ replica_logdir }}"
+ - /var/run/redis_{{ replica_port }}.pid
+ listen: cleanup redis
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_redis_replication/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_redis_replication/meta/main.yml
new file mode 100644
index 000000000..db2617f4c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_redis_replication/meta/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+- setup_pkg_mgr
+- setup_remote_constraints
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_redis_replication/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_redis_replication/tasks/main.yml
new file mode 100644
index 000000000..076a47359
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_redis_replication/tasks/main.yml
@@ -0,0 +1,12 @@
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) 2020, Pavlo Bashynskyi (@levonet) <levonet@gmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- import_tasks: setup_redis_cluster.yml
+ when:
+ - ansible_distribution in ['CentOS', 'Fedora', 'FreeBSD', 'openSUSE Leap', 'Ubuntu', 'Debian', 'Archlinux', 'Alpine']
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_redis_replication/tasks/setup_redis_cluster.yml b/ansible_collections/community/general/tests/integration/targets/setup_redis_replication/tasks/setup_redis_cluster.yml
new file mode 100644
index 000000000..dd48bf2b6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_redis_replication/tasks/setup_redis_cluster.yml
@@ -0,0 +1,78 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# We run two servers listening different ports
+# to be able to check replication (one server for master, another for replica).
+
+- name: Install redis dependencies
+ package:
+ name: "{{ redis_packages[ansible_distribution] }}"
+ state: latest
+ policy_rc_d: "{{ 101 if ansible_facts.pkg_mgr == 'apt' else omit }}"
+ notify: cleanup redis
+
+- name: Install redis module
+ pip:
+ name: "{{ redis_module }}"
+ extra_args: "-c {{ remote_constraints }}"
+ state: present
+ notify: cleanup redis
+
+- name: Create redis directories
+ file:
+ path: "{{ item }}"
+ state: directory
+ owner: redis
+ group: redis
+ loop:
+ - "{{ master_datadir }}"
+ - "{{ master_logdir }}"
+ - "{{ replica_datadir }}"
+ - "{{ replica_logdir }}"
+
+- name: Create redis configs
+ copy:
+ dest: "{{ item.file }}"
+ content: |
+ daemonize yes
+ port {{ item.port }}
+ pidfile /var/run/redis_{{ item.port }}.pid
+ logfile {{ item.logdir }}/redis.log
+ dir {{ item.datadir }}
+ requirepass {{ redis_password }}
+ masterauth {{ redis_password }}
+ loop:
+ - file: "{{ master_conf }}"
+ port: "{{ master_port }}"
+ logdir: "{{ master_logdir }}"
+ datadir: "{{ master_datadir }}"
+ - file: "{{ replica_conf }}"
+ port: "{{ replica_port }}"
+ logdir: "{{ replica_logdir }}"
+ datadir: "{{ replica_datadir }}"
+
+- name: Start redis master
+ shell: "{{ redis_bin[ansible_distribution] }} {{ master_conf }}"
+
+- name: Start redis replica
+ shell: "{{ redis_bin[ansible_distribution] }} {{ replica_conf }} --{% if old_redis %}slaveof{% else %}replicaof{% endif %} 127.0.0.1 {{ master_port }}"
+
+- name: Wait for redis master to be started
+ ansible.builtin.wait_for:
+ host: 127.0.0.1
+ port: "{{ master_port }}"
+ state: started
+ delay: 1
+ connect_timeout: 5
+ timeout: 30
+
+- name: Wait for redis replica to be started
+ ansible.builtin.wait_for:
+ host: 127.0.0.1
+ port: "{{ replica_port }}"
+ state: started
+ delay: 1
+ connect_timeout: 5
+ timeout: 30
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_remote_constraints/aliases b/ansible_collections/community/general/tests/integration/targets/setup_remote_constraints/aliases
new file mode 100644
index 000000000..27ce6b087
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_remote_constraints/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+needs/file/tests/utils/constraints.txt
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_remote_constraints/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_remote_constraints/meta/main.yml
new file mode 100644
index 000000000..982de6eb0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_remote_constraints/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_remote_constraints/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_remote_constraints/tasks/main.yml
new file mode 100644
index 000000000..a1ac1aead
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_remote_constraints/tasks/main.yml
@@ -0,0 +1,18 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: record constraints.txt path on remote host
+ set_fact:
+ remote_constraints: "{{ remote_tmp_dir }}/constraints.txt"
+
+- name: copy constraints.txt to remote host
+ copy:
+ src: "{{ role_path }}/../../../utils/constraints.txt"
+ dest: "{{ remote_constraints }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir/handlers/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir/handlers/main.yml
new file mode 100644
index 000000000..f1c55b04f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir/handlers/main.yml
@@ -0,0 +1,10 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: delete temporary directory
+ include_tasks: default-cleanup.yml
+
+- name: delete temporary directory (windows)
+ include_tasks: windows-cleanup.yml
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir/tasks/default-cleanup.yml b/ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir/tasks/default-cleanup.yml
new file mode 100644
index 000000000..cc74b70af
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir/tasks/default-cleanup.yml
@@ -0,0 +1,10 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: delete temporary directory
+ file:
+ path: "{{ remote_tmp_dir }}"
+ state: absent
+ no_log: true
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir/tasks/default.yml b/ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir/tasks/default.yml
new file mode 100644
index 000000000..c9d871c69
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir/tasks/default.yml
@@ -0,0 +1,16 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: create temporary directory
+ tempfile:
+ state: directory
+ suffix: .test
+ register: remote_tmp_dir
+ notify:
+ - delete temporary directory
+
+- name: record temporary directory
+ set_fact:
+ remote_tmp_dir: "{{ remote_tmp_dir.path }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir/tasks/main.yml
new file mode 100644
index 000000000..6632cc848
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir/tasks/main.yml
@@ -0,0 +1,20 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: make sure we have the ansible_os_family and ansible_distribution_version facts
+ setup:
+ gather_subset: distribution
+ when: ansible_facts == {}
+
+- include_tasks: "{{ lookup('first_found', files)}}"
+ vars:
+ files:
+ - "{{ ansible_os_family | lower }}.yml"
+ - "default.yml"
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir_outside_tmp/handlers/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir_outside_tmp/handlers/main.yml
new file mode 100644
index 000000000..f1c55b04f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir_outside_tmp/handlers/main.yml
@@ -0,0 +1,10 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: delete temporary directory
+ include_tasks: default-cleanup.yml
+
+- name: delete temporary directory (windows)
+ include_tasks: windows-cleanup.yml
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir_outside_tmp/tasks/default-cleanup.yml b/ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir_outside_tmp/tasks/default-cleanup.yml
new file mode 100644
index 000000000..cc74b70af
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir_outside_tmp/tasks/default-cleanup.yml
@@ -0,0 +1,10 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: delete temporary directory
+ file:
+ path: "{{ remote_tmp_dir }}"
+ state: absent
+ no_log: true
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir_outside_tmp/tasks/default.yml b/ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir_outside_tmp/tasks/default.yml
new file mode 100644
index 000000000..0aef57f99
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir_outside_tmp/tasks/default.yml
@@ -0,0 +1,22 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: create ~/tmp
+ file:
+ path: '~/tmp'
+ state: directory
+
+- name: create temporary directory
+ tempfile:
+ state: directory
+ suffix: .test
+ path: ~/tmp
+ register: remote_tmp_dir
+ notify:
+ - delete temporary directory
+
+- name: record temporary directory
+ set_fact:
+ remote_tmp_dir: "{{ remote_tmp_dir.path }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir_outside_tmp/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir_outside_tmp/tasks/main.yml
new file mode 100644
index 000000000..6632cc848
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_remote_tmp_dir_outside_tmp/tasks/main.yml
@@ -0,0 +1,20 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: make sure we have the ansible_os_family and ansible_distribution_version facts
+ setup:
+ gather_subset: distribution
+ when: ansible_facts == {}
+
+- include_tasks: "{{ lookup('first_found', files)}}"
+ vars:
+ files:
+ - "{{ ansible_os_family | lower }}.yml"
+ - "default.yml"
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_rundeck/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_rundeck/defaults/main.yml
new file mode 100644
index 000000000..c842901c0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_rundeck/defaults/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+rundeck_war_url: https://packagecloud.io/pagerduty/rundeck/packages/java/org.rundeck/rundeck-3.4.4-20210920.war/artifacts/rundeck-3.4.4-20210920.war/download
+rundeck_cli_url: https://github.com/rundeck/rundeck-cli/releases/download/v1.3.10/rundeck-cli-1.3.10-all.jar
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_rundeck/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_rundeck/meta/main.yml
new file mode 100644
index 000000000..2fcd152f9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_rundeck/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_rundeck/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_rundeck/tasks/main.yml
new file mode 100644
index 000000000..ea8b35f65
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_rundeck/tasks/main.yml
@@ -0,0 +1,41 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Skip unsupported platforms
+ meta: end_play
+ when: ansible_distribution not in ['CentOS', 'Fedora', 'Debian', 'Ubuntu']
+
+- name: Include OS-specific variables
+ include_vars: '{{ ansible_os_family }}.yml'
+ when: ansible_os_family in ['Debian', 'RedHat']
+
+- name: Set Rundeck base dir
+ set_fact:
+ rdeck_base: /home/rundeck
+
+- name: Install OpenJDK
+ package:
+ name: "{{ openjdk_pkg }}"
+ state: present
+
+- name: Install Rundeck
+ shell: |
+ mkdir -p $RDECK_BASE;
+ curl -k -o $RDECK_BASE/rundeck.war -L '{{ rundeck_war_url }}';
+ curl -k -o $RDECK_BASE/rundeck-cli.jar -L '{{ rundeck_cli_url }}'
+ cd $RDECK_BASE;
+ java -Xmx4g -jar rundeck.war &
+ environment:
+ RDECK_BASE: "{{ rdeck_base }}"
+
+- name: Wait for Rundeck port 4440
+ wait_for:
+ host: localhost
+ port: 4440
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_rundeck/vars/Alpine.yml b/ansible_collections/community/general/tests/integration/targets/setup_rundeck/vars/Alpine.yml
new file mode 100644
index 000000000..dbf16b747
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_rundeck/vars/Alpine.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+openjdk_pkg: openjdk11-jre-headless
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_rundeck/vars/Archlinux.yml b/ansible_collections/community/general/tests/integration/targets/setup_rundeck/vars/Archlinux.yml
new file mode 100644
index 000000000..fd4429c0b
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_rundeck/vars/Archlinux.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+openjdk_pkg: jre11-openjdk-headless
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_rundeck/vars/Debian.yml b/ansible_collections/community/general/tests/integration/targets/setup_rundeck/vars/Debian.yml
new file mode 100644
index 000000000..1407cede6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_rundeck/vars/Debian.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+openjdk_pkg: openjdk-11-jre-headless
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_rundeck/vars/RedHat.yml b/ansible_collections/community/general/tests/integration/targets/setup_rundeck/vars/RedHat.yml
new file mode 100644
index 000000000..314f0ef41
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_rundeck/vars/RedHat.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+openjdk_pkg: java-1.8.0-openjdk
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_snap/aliases b/ansible_collections/community/general/tests/integration/targets/setup_snap/aliases
new file mode 100644
index 000000000..0a430dff1
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_snap/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+needs/target/setup_epel
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_snap/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_snap/defaults/main.yml
new file mode 100644
index 000000000..7b4ab8dc7
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_snap/defaults/main.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+has_snap: false
+
+snap_packages:
+ - snapd
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_snap/handlers/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_snap/handlers/main.yml
new file mode 100644
index 000000000..08c1a23f1
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_snap/handlers/main.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Remove snapd
+ package:
+ name: "{{ snap_packages }}"
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_snap/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_snap/meta/main.yml
new file mode 100644
index 000000000..2fcd152f9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_snap/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-Fedora.yml b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-Fedora.yml
new file mode 100644
index 000000000..d0681fa38
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-Fedora.yml
@@ -0,0 +1,25 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install snapd (default)
+ package:
+ name: "{{ snap_packages }}"
+ state: present
+ notify: Remove snapd
+
+- name: Make sure that snapd is running
+ service:
+ name: snapd
+ state: started
+
+- name: Create link /snap
+ file:
+ src: /var/lib/snapd/snap
+ dest: /snap
+ state: link
+
+- name: Inform that snap is installed
+ set_fact:
+ has_snap: true
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-RedHat-8.2.yml b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-RedHat-8.2.yml
new file mode 100644
index 000000000..5bbfaff12
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-RedHat-8.2.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Do nothing
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-RedHat-8.3.yml b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-RedHat-8.3.yml
new file mode 100644
index 000000000..5bbfaff12
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-RedHat-8.3.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Do nothing
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-RedHat-9.0.yml b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-RedHat-9.0.yml
new file mode 100644
index 000000000..5bbfaff12
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-RedHat-9.0.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Do nothing
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-RedHat-9.1.yml b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-RedHat-9.1.yml
new file mode 100644
index 000000000..5bbfaff12
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-RedHat-9.1.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Do nothing
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-Ubuntu.yml b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-Ubuntu.yml
new file mode 100644
index 000000000..93958d38d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/D-Ubuntu.yml
@@ -0,0 +1,19 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install snapd (ubuntu)
+ package:
+ name: "{{ snap_packages }}"
+ state: present
+ notify: Remove snapd
+
+- name: Make sure that snapd is running
+ service:
+ name: snapd
+ state: started
+
+- name: Inform that snap is installed
+ set_fact:
+ has_snap: true
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/Debian.yml b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/Debian.yml
new file mode 100644
index 000000000..d0681fa38
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/Debian.yml
@@ -0,0 +1,25 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install snapd (default)
+ package:
+ name: "{{ snap_packages }}"
+ state: present
+ notify: Remove snapd
+
+- name: Make sure that snapd is running
+ service:
+ name: snapd
+ state: started
+
+- name: Create link /snap
+ file:
+ src: /var/lib/snapd/snap
+ dest: /snap
+ state: link
+
+- name: Inform that snap is installed
+ set_fact:
+ has_snap: true
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/RedHat.yml b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/RedHat.yml
new file mode 100644
index 000000000..d0681fa38
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/RedHat.yml
@@ -0,0 +1,25 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install snapd (default)
+ package:
+ name: "{{ snap_packages }}"
+ state: present
+ notify: Remove snapd
+
+- name: Make sure that snapd is running
+ service:
+ name: snapd
+ state: started
+
+- name: Create link /snap
+ file:
+ src: /var/lib/snapd/snap
+ dest: /snap
+ state: link
+
+- name: Inform that snap is installed
+ set_fact:
+ has_snap: true
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/default.yml b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/default.yml
new file mode 100644
index 000000000..d0681fa38
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/default.yml
@@ -0,0 +1,25 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install snapd (default)
+ package:
+ name: "{{ snap_packages }}"
+ state: present
+ notify: Remove snapd
+
+- name: Make sure that snapd is running
+ service:
+ name: snapd
+ state: started
+
+- name: Create link /snap
+ file:
+ src: /var/lib/snapd/snap
+ dest: /snap
+ state: link
+
+- name: Inform that snap is installed
+ set_fact:
+ has_snap: true
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/main.yml
new file mode 100644
index 000000000..8f3744a70
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/main.yml
@@ -0,0 +1,34 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Print information on which we distinguish
+ debug:
+ msg: "Distribution '{{ ansible_facts.distribution }}', version '{{ ansible_facts.distribution_version }}', OS family '{{ ansible_facts.os_family }}'"
+
+- name: Install EPEL repository (RHEL only)
+ include_role:
+ name: setup_epel
+ when:
+ - ansible_distribution in ['RedHat', 'CentOS']
+ - ansible_distribution_major_version is version('9', '<')
+
+- name: Include distribution specific tasks
+ include_tasks: "{{ lookup('first_found', params) }}"
+ vars:
+ params:
+ files:
+ - "D-{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_version }}.yml"
+ - "D-{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_major_version }}.yml"
+ - "{{ ansible_facts.os_family }}-{{ ansible_facts.distribution_major_version }}.yml"
+ - "D-{{ ansible_facts.distribution }}.yml"
+ - "{{ ansible_facts.os_family }}.yml"
+ - "nothing.yml"
+ paths:
+ - "{{ role_path }}/tasks"
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/nothing.yml b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/nothing.yml
new file mode 100644
index 000000000..5bbfaff12
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_snap/tasks/nothing.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Do nothing
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_tls/files/ca_certificate.pem b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/ca_certificate.pem
new file mode 100644
index 000000000..130e0a2da
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/ca_certificate.pem
@@ -0,0 +1,23 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+-----BEGIN CERTIFICATE-----
+MIIDAjCCAeqgAwIBAgIJANguFROhaWocMA0GCSqGSIb3DQEBCwUAMDExIDAeBgNV
+BAMMF1RMU0dlblNlbGZTaWduZWR0Um9vdENBMQ0wCwYDVQQHDAQkJCQkMB4XDTE5
+MDExMTA4MzMxNVoXDTI5MDEwODA4MzMxNVowMTEgMB4GA1UEAwwXVExTR2VuU2Vs
+ZlNpZ25lZHRSb290Q0ExDTALBgNVBAcMBCQkJCQwggEiMA0GCSqGSIb3DQEBAQUA
+A4IBDwAwggEKAoIBAQDqVt84czSxWnWW4Ng6hmKE3NarbLsycwtjrYBokV7Kk7Mp
+7PrBbYF05FOgSdJLvL6grlRSQK2VPsXdLfEv5uFXX6gyd2WQwKCiGGf4UY4ZIl4l
+JVpSDsBV2orR4pOIf1s1+iSwvcRQkX46SVjoKWbDUc4VLo1uy8UvavQI+DMioYyy
+0K2MbRs7oG2rdKks8zisfT0ymKnrFTdVeUjIrg0sStaMnf9VVkcEeYkfNY0vWqdn
+CV5wPfDBlnnxGMgqGdLSpzfyJ7qafFET+q+gOvjsEqzn7DvlPkmk86hIIWXKi3aM
+A9swknL3rnagJL6GioWRpYUwKdRKmZxdyr4I2JTTAgMBAAGjHTAbMAwGA1UdEwQF
+MAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQACTpPBf5WSwZ7r
+hrbPUN3qVh70HI0ZNK2jlK6b5fpSdw3JI/GQl0Kw3eGICLzwTByWvhD62U7IigL5
+0UWxWuEod310Y/qo/7OxRVPp5PH/0oNGoKHhEzas2ii0heQYGsHQUKGzYNNyVfjy
+nqBFz5AcKf067LcXivYqod6JDQHqFq/5/hWlIsHHrZIeijqqtthPq39GlGAYO+AB
+U66nzlH7YQgmfYfy6l7O4LsjXf/bz9rWvueO3NqCsmXV+FacDkOkwWA5Kf6rcgNL
+3G+2HAVTRIXDnO4ShnK6aYMW+UklpYRlVYBBUOdwoNIp5gI+BlSc1IuF6PdLVt3q
+VdjN1MjY
+-----END CERTIFICATE-----
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_tls/files/ca_key.pem b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/ca_key.pem
new file mode 100644
index 000000000..d9dc5ca0f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/ca_key.pem
@@ -0,0 +1,32 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDqVt84czSxWnWW
+4Ng6hmKE3NarbLsycwtjrYBokV7Kk7Mp7PrBbYF05FOgSdJLvL6grlRSQK2VPsXd
+LfEv5uFXX6gyd2WQwKCiGGf4UY4ZIl4lJVpSDsBV2orR4pOIf1s1+iSwvcRQkX46
+SVjoKWbDUc4VLo1uy8UvavQI+DMioYyy0K2MbRs7oG2rdKks8zisfT0ymKnrFTdV
+eUjIrg0sStaMnf9VVkcEeYkfNY0vWqdnCV5wPfDBlnnxGMgqGdLSpzfyJ7qafFET
++q+gOvjsEqzn7DvlPkmk86hIIWXKi3aMA9swknL3rnagJL6GioWRpYUwKdRKmZxd
+yr4I2JTTAgMBAAECggEBALpg9ZDUMCiOpc+mbNO/ZkP90M7u38Q0M+7HY8XHOPkt
+l+XUkWueSMRLhSeLDzMlnwf1HyN8RZLaJkzP6XAL1VXEwuXAiIskaZ4Cg07Arp/W
+8cHhf4CcMuUVuCtOZcC+ajD4Do5zn9vkm9yH0ap0o0LdoWa/a8WfU+luy0EHBsSW
+6qqI+nqNFmISluVbfWt7t3zp273+8sir6YeHQu9G91/jzggv8rHmu4EHhi3cnU0K
+vY6OPCGBL7nrg9Rv1LSFpH95TvlIM6/Cm0AjgW7m6XwWUTaI9p+GvKzrYUSLd9L/
+QxlmAwiu/sBTXLrsWyr8XEtj+lVGxQ6eFbf6E+lUm8ECgYEA+8Wgmhf3VsC3gvJz
+w2jApEoOioD5iGOWGClGVURkfaBhFELr4XCTVMdBuCtxT7LYTMHTAlBqIbdWDjB4
+m/E417hLGogSDy7j0R0Mx75OOGEitxYUhe0VGDNoytgCNd2UnTMt42lp+9vAHZag
+INhVDOnxRNdtNTf1yYkWUMEbh1sCgYEA7kZNJXPVYJtR78+km/Gcv64Umci7KUV+
+hYc7chR5xv3cXvXg5eojKa4G7CyMQTX7VnRa6CiQKdN73AbIAhS4Oy5UlCOKtmb8
+xnBiOAYwSpOfIeZhjq0RvEeZX0t6u7XsErBZ03rEPKXF2nNDo1x8byrlKPtlUzwJ
+gb5yjmK/mekCgYEA1TWQAs5m4+2Bun+tbv7nnHkmhT4hktGays0xRYYMf6Jwc6MU
+dC5MZg/zZI5Nf8uZhq7hDWWh6vmCA7QifxSxKWVlHIu8l2UDAhRSvVg4j2Aa8Obe
+7GdQZNUsWhLBFHKXpuQvaRTc7q8yqxvicM4igDQg4EZ6sgW4vDm+TxapRF8CgYAz
+n6mhPqpxRtWGxo8cdkmGwfmWpAXg2DykQ3teqQ8FTQUM0erLBWJe6mR3kONGUaLF
+xWnYuMkbNsW0EwgMY17S+6O5gMXR5RhJChpNlxGpZrhoiNiEJ/0atMyG9/x8ZNrj
+5a9ggU248hWe0bBK2YPgNgP2UBlQ4kYRBSkerkhi2QKBgF+tlpyqcU+0iY82qRS2
+wMf7oI2pWR8nX9LPAY/nnvwWvqwcAFJPMlSMTu8Ext6h7l9yu+7JGL6JWwsO57Lb
+Gm/RxbuZ/kG/13+lSNmZiyHrhj6hZhkAMeFM34fpT4+DBXqSxZuvdrmwBc5B2jYg
+F9Bv8gcmZlGhqONL23evr9Gu
+-----END PRIVATE KEY-----
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_tls/files/client_certificate.pem b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/client_certificate.pem
new file mode 100644
index 000000000..9e956e6b0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/client_certificate.pem
@@ -0,0 +1,24 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+-----BEGIN CERTIFICATE-----
+MIIDRjCCAi6gAwIBAgIBAjANBgkqhkiG9w0BAQsFADAxMSAwHgYDVQQDDBdUTFNH
+ZW5TZWxmU2lnbmVkdFJvb3RDQTENMAsGA1UEBwwEJCQkJDAeFw0xOTAxMTEwODMz
+MThaFw0yOTAxMDgwODMzMThaMC0xGjAYBgNVBAMMEWFuc2libGUudGxzLnRlc3Rz
+MQ8wDQYDVQQKDAZjbGllbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQCoM+OQ3HCnCUAAz9KGGTwWB9hQbUfAZXm/stlb2/uOAp3rNwxAlCs/giymBHE6
+Iu6mrK006Vn+Z9ibqIrD2LuCOxcu25y8goqG62TgdP5sa9wR+597s0XssnwnaY8y
+bJ3p2zWAJvMgqQ0iNW/ZynpWbO85K5SryUykF7FAeNU9ogGGlIwCPjHhPvnwjkqd
+yDqaA1VaJKDUWIF9joI7sV4VLgGhQvzXRrHULsTeIF2m0+ebL0PTNEWHQ0dtgLYX
+kW7YO4Y6+n3cjHNH4qTof8V30EK8pk8kTdJ/x6ubwf+klFCAyroOxNOaxUy299Oo
+yD6qIPJPnGkPhrKtWnWIhNzJAgMBAAGjbTBrMAkGA1UdEwQCMAAwCwYDVR0PBAQD
+AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMCMDwGA1UdEQQ1MDOCEWFuc2libGUudGxz
+LnRlc3RzghNNYWNCb29rLVByby00LmxvY2Fsgglsb2NhbGhvc3QwDQYJKoZIhvcN
+AQELBQADggEBAK214+VVXnGnsUlvd9Q6A2Ea6UGrr6b7xkmlnIaNd+6xoUsDsHob
+srHYm7UC0uLi1KwSunI7AU5ZELVEUfAmJzh3O4d6C5sQyqKYPqd5harWOQ3BOD0I
+plHpp7qMtsPDuJBtmE/bmvF85eto0H7pPz+cTTXRlOaVVeiHjMggFcXdy1MzGo9C
+X/4wLQmsFeypTfe+ZGqvDh99VV+ffNMIsMh+opWEloaKiHmDKB6S9aC/MsVVM4RR
+nHm/UKTOukaGE9QIPkSSaygv3sBkVnQ2SHMvvtnjPHVHlizNoq6+YTnuOvKpo4o5
+V7Bij+W7rkBQLsEfwv2IC+gzmRz2yxr2tXk=
+-----END CERTIFICATE-----
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_tls/files/client_key.pem b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/client_key.pem
new file mode 100644
index 000000000..3848ad7cf
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/client_key.pem
@@ -0,0 +1,31 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAqDPjkNxwpwlAAM/Shhk8FgfYUG1HwGV5v7LZW9v7jgKd6zcM
+QJQrP4IspgRxOiLupqytNOlZ/mfYm6iKw9i7gjsXLtucvIKKhutk4HT+bGvcEfuf
+e7NF7LJ8J2mPMmyd6ds1gCbzIKkNIjVv2cp6VmzvOSuUq8lMpBexQHjVPaIBhpSM
+Aj4x4T758I5Kncg6mgNVWiSg1FiBfY6CO7FeFS4BoUL810ax1C7E3iBdptPnmy9D
+0zRFh0NHbYC2F5Fu2DuGOvp93IxzR+Kk6H/Fd9BCvKZPJE3Sf8erm8H/pJRQgMq6
+DsTTmsVMtvfTqMg+qiDyT5xpD4ayrVp1iITcyQIDAQABAoIBAHPszzpXs4xr46Cr
+mvyxB6hnX76OkpUXWwGz0fptcsI9K3mhRuB7PhNXNE53YVIgITreZ8G/0jZ0e+VM
+E9dG2HS5JRE2ap/BmJfERJIuD+vJqrL6KMCondi0arz/E6I9GdjDK+xW69nmqRaa
+nawM0KQgD//m+WAsLJYrfg5hORZwI2SHaahawnCp0QaMmz3bdDWKRacM3q0UFX46
+Ze6CaZkUn+e1rHsTMcZBvxQWIVzysFNXh150idIB/PxL5YfCQqTSAj1c/nxaxz6a
+BvHFlpaYR3tvXXlexxfjglCwsGyckbvTyP1cBZqpv5oES+VKt2PrOve9Zyax+CYT
+0uQf6cECgYEA09+46QHXLfWh6jiJYu9skC9UrLU5czfCNB6PrUtFcjPFMYjZDcw9
+inJmcuTPXmfplxc47YDfpwotU+szTJDF+R8kknnfw9zVr/sIwZ5wsFfUQl/56Svn
+AIOVvHHvcvMX95XKGiuTsoCIJZNjJN3l3ztu/bRciuiVLyizglwIVrMCgYEAyzvK
+PFlWilbp3GPJlnW7x1bUxe1ziLE/Um+ujZx96+fy34hJLFdNdNzpNUjoOf3IDTGq
+6xl+vXcf12gimWMFcD3qNIGKHBDM9cIB2RDbb6YcqI8lOqopsmOyGmVLPkRpCoUK
+72kacQwvw6M9xjmpiG3dN8lE881jDmZi+hyCnJMCgYEAoIQnQAhP8Jbeo2dP1q+T
+bS0elnX532uH6xqYOW8EXwAPznZiEw0ANspzCWqGHHzXQMusKmtvhcq1CpXvWHt6
+MUHB4GMK/wVosxmZya5yq3bu7ZZu7JOBQCdwosMi6NB5AO7vnaIUFLFB9E3UWBLw
+243YicdCMU8B7yeD0ChPfPcCgYA1dYHKBBn+g8Q6Y8lIGaoOUmnfsok8gJtOfPAm
+ce6xmi7J29iboE9QmTeC+62Sa44u4ky6UNeE0QwAJnVLcb+hebfcneKNZWH0l1bT
+GVsPcFuDfzvkxZP4R782sERtmaMj0EFDHpuE9xatWIhMVyigKX4SSZAorXML+6S3
+c75rnwKBgBR+WU934wS+DbwTLlUB2mJWqJMEbOH/CUwPC7+VN4h1h3/i455iAeiU
+BizLS0SlD+MoSbC7URcZuquqGkmMlnJXoxF+NdxoWZK78tYNftryWoR87TloiVc/
+LhkxZxje4tgW/mTLqH3zKDoyyzDzG6Q6tAUN2ZTjJFEws7qF30Qe
+-----END RSA PRIVATE KEY-----
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_tls/files/server_certificate.pem b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/server_certificate.pem
new file mode 100644
index 000000000..b714ddbfb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/server_certificate.pem
@@ -0,0 +1,24 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+-----BEGIN CERTIFICATE-----
+MIIDRjCCAi6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAxMSAwHgYDVQQDDBdUTFNH
+ZW5TZWxmU2lnbmVkdFJvb3RDQTENMAsGA1UEBwwEJCQkJDAeFw0xOTAxMTEwODMz
+MTZaFw0yOTAxMDgwODMzMTZaMC0xGjAYBgNVBAMMEWFuc2libGUudGxzLnRlc3Rz
+MQ8wDQYDVQQKDAZzZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
+AQDIwErHwAesRBfd9HiZkmB3VYh28c1QkE9I8nYyHJKX2ZBUhAzK+h80BkcTJJ94
+265qWyACH/wl54Xe/ofFUFrGa4vz0qz4UkL/KI0OGw28Y4qnKdorb9DumbiIPB+9
+I9TJT9vhtXTxBNlBTpv3ONHL8EzdV6ZmuvELU11H27oQ4xoUYhfXPXLMLK0sOnXZ
+lt0BOMMd5fVpJVa8fvXiw3626a0aXCr4e/MWUsBFRnzrXfgoW+AjYoTjKKS2hLYo
+8//MM05h7ROIXrNe990sf9C1G+fOThmOMszK9sjMhu2xHranRcz5aA0UTfyOjTs8
+9WexUYhC5VorYyRWtVZu2mDjAgMBAAGjbTBrMAkGA1UdEwQCMAAwCwYDVR0PBAQD
+AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMDwGA1UdEQQ1MDOCEWFuc2libGUudGxz
+LnRlc3RzghNNYWNCb29rLVByby00LmxvY2Fsgglsb2NhbGhvc3QwDQYJKoZIhvcN
+AQELBQADggEBAFoPBeB6tQhFS1198sia5NDHDDrghDOIlE0QbaoA+MSKzsaIy8Mu
+mNcM2ewYpT600XXTBxcqF6/vuKL9OEbvivtRYQu1YfkifN1jzREoWTieUkR5ytzt
+8ATfFkgTWJmiRiOIb/fNgewvhd+aKxep0OGwDiSKKl1ab6F17Cp4iK8sDBWmnUb6
+0Wf7pfver1Gl0Gp8vRXGUuc8a7udA9a8mV70HJlLkMdMvR9U8Bqih0+iRaqNWXRZ
+7Lc6v5LbzrW/ntilmgU6F0lwxPydg49MY4UrSXcjYLZs9T4iYHwTfLxFjFMIgGwn
+peYMKRj18akP9i2mjj5O2mRu4K+ecuUSOGI=
+-----END CERTIFICATE-----
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_tls/files/server_key.pem b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/server_key.pem
new file mode 100644
index 000000000..ec0134993
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_tls/files/server_key.pem
@@ -0,0 +1,31 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAyMBKx8AHrEQX3fR4mZJgd1WIdvHNUJBPSPJ2MhySl9mQVIQM
+yvofNAZHEySfeNuualsgAh/8JeeF3v6HxVBaxmuL89Ks+FJC/yiNDhsNvGOKpyna
+K2/Q7pm4iDwfvSPUyU/b4bV08QTZQU6b9zjRy/BM3VemZrrxC1NdR9u6EOMaFGIX
+1z1yzCytLDp12ZbdATjDHeX1aSVWvH714sN+tumtGlwq+HvzFlLARUZ86134KFvg
+I2KE4yiktoS2KPP/zDNOYe0TiF6zXvfdLH/QtRvnzk4ZjjLMyvbIzIbtsR62p0XM
++WgNFE38jo07PPVnsVGIQuVaK2MkVrVWbtpg4wIDAQABAoIBAHw3wA3pnNXTLJGC
+fD1KfbZZjp9K76gyI10X6lsHow2i6dPiAah3LGecms4VkzfNdxcIW7303Kj3obZh
++ND277RnR6oPakgdXqdUCDP6OX2gemMFWqIWBkodhDmIOntmeHw4le4LwdiBD42B
+frBy0B5JCsbLPYPDmPNRGh8krvVS+Eir4hb4tK95TPMSL0vEjvHYFbCxv7//Ri1p
+3CROGp2CGX0WZ+Zs0crRNoIhRRM6kLAhROcqejtnEy6o7l5CWpCAL2vxlE9y8/kL
+iRawSZRFZnz/zGnqpx0vswgvijkuPfcNGMSzdwaiDgQz8D0GkJ7s9VgzZJazNy+1
+ET/4YIECgYEA612rwP9Ar9qdYbmmMPaJzITnaIrNGfO2JvaQqZt+DG8sVgdxL7V5
+D6emcw406drKRZvFAxnW6ZW2bVpmit02osl0re2A/nOTXLNuo338Qkap/hG8YZrF
+bw7w75pFa/rwlDtedjBnGHO2KbRXeU5Hn5wLoKjYgJoF6Ht+PPdL0IsCgYEA2lnC
+pQEhM51iRMDqNdmVJyvsTNU1ikoO8HaXHq+LwOQETaKMnDwp4Bn14E815CTulAc/
+tsDTKSDk6umZ+IufG1a2v7CqgKVwkB4HkgxKFQs2gQdTFfoMi5eeHR+njuNtklp1
+9fWfKHsP/ddrg+iTVTRZBLWexgKK89IMHYalpAkCgYEAy0Q3a9NF81mTJ+3kOE8C
+zO1OyLtuzGXsvxOb9c6C+owctyNwPeq05a89EgqH6hr5K0qOx9HOCCcyyJgVDQJl
+CAuByB/gkmAQOTQBbhMFA9vxPanljknTDsnRjKwoHkw2712ig+Hjd3ufK79C+FGB
+i7eBVzva1p2uUowshsxv3mcCgYAOFiRciMofjlO8o8V4W+Undcn02vxtQ4HbOYte
+S2z0sMEmUQpJOghpkMMwCWwsn8VUf3M40w/MY3bhQNjSFA/br6hyjW8yhXnRkl5i
+qbBN0z9c66AMlukgSFPHBTfGHB4Bhxx9Fa+C6Q2LDs6839BBevMTPrRTie509GQb
+s4gUIQKBgAvE8wLcmozno0GLDnBdKRZP/C7tmVnAINuraITPUBTASwI+Qo8ILigQ
+LRLaDqF84BEpjb8vdzkYFQqRQSZ8BI8NydfuKEFSBfL27sBvSGMYQJVm6bryUmPq
+T3ayaeZ4Wb3FFDijgtM9dRKyf7p4hQPOqM44QrntAtb43b2Q5L7M
+-----END RSA PRIVATE KEY-----
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_tls/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_tls/tasks/main.yml
new file mode 100644
index 000000000..ea4b9ecaa
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_tls/tasks/main.yml
@@ -0,0 +1,30 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Generated certificate with: https://github.com/michaelklishin/tls-gen
+# ~/tls-gen/basic# make PASSWORD=bunnies CN=ansible.tls.tests
+# verify with: make info
+
+- name: ensure target directory is present
+ file:
+ path: /tls
+ state: directory
+
+- name: ensure TLS files are present
+ copy:
+ src: "{{ item }}"
+ dest: "/tls/{{ item }}"
+ loop:
+ - ca_certificate.pem
+ - ca_key.pem
+ - client_certificate.pem
+ - client_key.pem
+ - server_certificate.pem
+ - server_key.pem
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/defaults/main.yml
new file mode 100644
index 000000000..03b12c95c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/defaults/main.yml
@@ -0,0 +1,13 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+wf_tmp_dir: '{{ remote_tmp_dir }}/wildfly_tmp'
+wf_homedir: '{{ wf_tmp_dir }}/wildfly'
+wf_service_file_path: /etc/systemd/system/wildfly.service
+wf_version: 16.0.0.Final
+wf_user: wildfly
+jboss_root: '{{ wf_homedir }}'
+deploy_dir: '{{ jboss_root }}/standalone/deployments'
+default_deploy_root: /var/lib/jbossas/standalone/deployments
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/files/wildfly.conf b/ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/files/wildfly.conf
new file mode 100644
index 000000000..684ce12a2
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/files/wildfly.conf
@@ -0,0 +1,12 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# The configuration you want to run
+WILDFLY_CONFIG=standalone.xml
+
+# The mode you want to run
+WILDFLY_MODE=standalone
+
+# The address to bind to
+WILDFLY_BIND=0.0.0.0
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/handlers/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/handlers/main.yml
new file mode 100644
index 000000000..1383b1575
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/handlers/main.yml
@@ -0,0 +1,18 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Stop wildfly (jboss)
+ systemd:
+ name: wildfly
+ state: stopped
+ ignore_errors: true
+
+- name: Remove files
+ file:
+ path: '{{ item }}'
+ state: absent
+ loop:
+ - '{{ wf_service_file_path }}'
+ - '{{ default_deploy_root }}'
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/meta/main.yml
new file mode 100644
index 000000000..2d29ebb67
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/meta/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+- setup_pkg_mgr
+- setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/tasks/main.yml
new file mode 100644
index 000000000..26f5083b0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/tasks/main.yml
@@ -0,0 +1,107 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Skip unsupported platforms
+ meta: end_play
+ when: (ansible_distribution != 'CentOS') or
+ (ansible_distribution == 'CentOS' and ansible_distribution_major_version is not version('7', '>='))
+
+- name: Install java
+ package:
+ name: java-1.8.0-openjdk-devel
+
+- name: Create wf_tmp_dir
+ file:
+ path: '{{ wf_tmp_dir }}'
+ state: directory
+
+- name: Download wildfly
+ get_url:
+ url: 'https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/setup_wildfly_server/wildfly-{{ wf_version }}.tar.gz'
+ dest: '{{ wf_tmp_dir }}/wildfly-{{ wf_version }}.tar.gz'
+
+- name: Unarchive tar
+ unarchive:
+ src: '{{ wf_tmp_dir }}/wildfly-{{ wf_version }}.tar.gz'
+ dest: '{{ wf_tmp_dir }}'
+ remote_src: true
+
+- name: Remove tar
+ file:
+ path: '{{ wf_tmp_dir }}/wildfly-{{ wf_version }}.tar.gz'
+ state: absent
+
+- name: Create symlink
+ file:
+ src: '{{ wf_tmp_dir }}/wildfly-{{ wf_version }}'
+ dest: '{{ wf_tmp_dir }}/wildfly'
+ state: link
+
+- name: Create group for wildfly
+ group:
+ name: '{{ wf_user }}'
+ system: true
+
+- name: Create user for wildfly
+ user:
+ name: '{{ wf_user }}'
+ system: true
+ group: '{{ wf_user }}'
+ home: '{{ wf_homedir }}'
+
+- name: Set permissions
+ file:
+ path: '{{ remote_tmp_dir }}'
+ state: directory
+ owner: '{{ wf_user }}'
+ group: '{{ wf_user }}'
+ recurse: true
+
+- name: Create config file
+ copy:
+ src: wildfly.conf
+ dest: '{{ wf_homedir }}/wildfly.conf'
+ mode: "0644"
+
+- name: Create launcher
+ template:
+ src: launch.sh.j2
+ dest: '{{ wf_homedir }}/bin/launch.sh'
+ mode: "0755"
+
+- name: Make scripts executable
+ shell: 'chmod +rx {{ wf_homedir }}/bin/*.sh'
+
+- name: Create service file
+ template:
+ src: wildfly.service.j2
+ dest: '{{ wf_service_file_path }}'
+ mode: "0644"
+
+- name: Create directories for testing the default deploy_path
+ become: true
+ file:
+ path: '{{ default_deploy_root }}'
+ state: directory
+ recurse: true
+ owner: '{{ wf_user }}'
+ group: '{{ wf_user }}'
+
+- name: Create simlink for testing the default deploy_path
+ file:
+ state: link
+ src: '{{ deploy_dir }}'
+ dest: '{{ default_deploy_root }}/deployments'
+
+- name: Reload systemd and start wildfly
+ systemd:
+ daemon_reload: true
+ name: wildfly
+ state: started
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/templates/launch.sh.j2 b/ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/templates/launch.sh.j2
new file mode 100644
index 000000000..7a80251a1
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/templates/launch.sh.j2
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+if [ "x$WILDFLY_HOME" = "x" ]; then
+ WILDFLY_HOME="{{ wf_homedir }}"
+fi
+
+if [[ "$1" == "domain" ]]; then
+ $WILDFLY_HOME/bin/domain.sh -c "$2" -b "$3"
+else
+ $WILDFLY_HOME/bin/standalone.sh -c "$2" -b "$3"
+fi
diff --git a/ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/templates/wildfly.service.j2 b/ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/templates/wildfly.service.j2
new file mode 100644
index 000000000..ec1055132
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/setup_wildfly_server/templates/wildfly.service.j2
@@ -0,0 +1,20 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+[Unit]
+Description=The WildFly Application Server
+After=syslog.target network.target
+Before=httpd.service
+
+[Service]
+Environment=LAUNCH_JBOSS_IN_BACKGROUND=1
+EnvironmentFile=-{{ wf_homedir }}/wildfly.conf
+User=wildfly
+LimitNOFILE=102642
+PIDFile=/var/run/wildfly/wildfly.pid
+ExecStart={{ wf_homedir }}/bin/launch.sh $WILDFLY_MODE $WILDFLY_CONFIG $WILDFLY_BIND
+StandardOutput=null
+
+[Install]
+WantedBy=multi-user.target
diff --git a/ansible_collections/community/general/tests/integration/targets/shutdown/aliases b/ansible_collections/community/general/tests/integration/targets/shutdown/aliases
new file mode 100644
index 000000000..afda346c4
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/shutdown/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
diff --git a/ansible_collections/community/general/tests/integration/targets/shutdown/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/shutdown/tasks/main.yml
new file mode 100644
index 000000000..dadeb6269
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/shutdown/tasks/main.yml
@@ -0,0 +1,93 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install systemd-sysv on Ubuntu 18 and Debian
+ apt:
+ name: systemd-sysv
+ state: present
+ when: (ansible_distribution == 'Ubuntu' and ansible_distribution_major_version is version('18', '>=')) or (ansible_distribution == 'Debian')
+ register: systemd_sysv_install
+
+- name: Execute shutdown with custom message and delay
+ community.general.shutdown:
+ delay: 100
+ msg: "Custom Message"
+ register: shutdown_result
+ check_mode: true
+
+- name: Execute shutdown with minus delay
+ community.general.shutdown:
+ delay: -100
+ register: shutdown_result_minus
+ check_mode: true
+
+- name: Verify Custom Message except Alpine, AIX
+ assert:
+ that:
+ - '"Custom Message" in shutdown_result["shutdown_command"]'
+ - '"Shut down initiated by Ansible" in shutdown_result_minus["shutdown_command"]'
+ - '"Custom Message" not in shutdown_result_minus["shutdown_command"]'
+ when: ansible_os_family not in ['Alpine', 'AIX']
+
+- name: Verify shutdown command is present except Alpine, VMKernel
+ assert:
+ that: '"shutdown" in shutdown_result["shutdown_command"]'
+ when: ansible_os_family != 'Alpine' and ansible_system != 'VMKernel'
+
+- name: Verify shutdown command is present in Alpine
+ assert:
+ that: '"poweroff" in shutdown_result["shutdown_command"]'
+ when: ansible_os_family == 'Alpine'
+
+- name: Verify shutdown command is present in VMKernel
+ assert:
+ that: '"halt" in shutdown_result["shutdown_command"]'
+ when: ansible_system == 'VMKernel'
+
+- name: Verify shutdown delay is present in minutes in Linux
+ assert:
+ that:
+ - '"-h 1" in shutdown_result["shutdown_command"]'
+ - '"-h 0" in shutdown_result_minus["shutdown_command"]'
+ when: ansible_system == 'Linux' and ansible_os_family != 'Alpine'
+
+- name: Verify shutdown delay is present in minutes in Void, MacOSX, OpenBSD
+ assert:
+ that:
+ - '"-h +1" in shutdown_result["shutdown_command"]'
+ - '"-h +0" in shutdown_result_minus["shutdown_command"]'
+ when: ansible_system in ['Void', 'Darwin', 'OpenBSD']
+
+- name: Verify shutdown delay is present in seconds in FreeBSD
+ assert:
+ that:
+ - '"-h +100s" in shutdown_result["shutdown_command"]'
+ - '"-h +0s" in shutdown_result_minus["shutdown_command"]'
+ when: ansible_system == 'FreeBSD'
+
+- name: Verify shutdown delay is present in seconds in Solaris, SunOS
+ assert:
+ that:
+ - '"-g 100" in shutdown_result["shutdown_command"]'
+ - '"-g 0" in shutdown_result_minus["shutdown_command"]'
+ when: ansible_system in ['Solaris', 'SunOS']
+
+- name: Verify shutdown delay is present in seconds, VMKernel
+ assert:
+ that:
+ - '"-d 100" in shutdown_result["shutdown_command"]'
+ - '"-d 0" in shutdown_result_minus["shutdown_command"]'
+ when: ansible_system == 'VMKernel'
+
+- name: Remove systemd-sysv in ubuntu 18 in case it has been installed in test
+ apt:
+ name: systemd-sysv
+ state: absent
+ when: systemd_sysv_install is changed
diff --git a/ansible_collections/community/general/tests/integration/targets/snap/aliases b/ansible_collections/community/general/tests/integration/targets/snap/aliases
new file mode 100644
index 000000000..b209bbc01
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/snap/aliases
@@ -0,0 +1,13 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+azp/posix/vm
+skip/aix
+skip/alpine
+skip/fedora
+skip/freebsd
+skip/osx
+skip/macos
+skip/docker
diff --git a/ansible_collections/community/general/tests/integration/targets/snap/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/snap/meta/main.yml
new file mode 100644
index 000000000..f36427f71
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/snap/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_snap
diff --git a/ansible_collections/community/general/tests/integration/targets/snap/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/snap/tasks/main.yml
new file mode 100644
index 000000000..0f24e69f3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/snap/tasks/main.yml
@@ -0,0 +1,243 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Has-snap block
+ when: has_snap
+ block:
+ - name: Make sure package is not installed (hello-world)
+ community.general.snap:
+ name: hello-world
+ state: absent
+
+ - name: Install package (hello-world) (check mode)
+ community.general.snap:
+ name: hello-world
+ state: present
+ register: install_check
+ check_mode: true
+
+ - name: Install package (hello-world)
+ community.general.snap:
+ name: hello-world
+ state: present
+ register: install
+
+ - name: Install package again (hello-world) (check mode)
+ community.general.snap:
+ name: hello-world
+ state: present
+ register: install_again_check
+ check_mode: true
+
+ - name: Install package again (hello-world)
+ community.general.snap:
+ name: hello-world
+ state: present
+ register: install_again
+
+ - name: Assert package has been installed just once (hello-world)
+ assert:
+ that:
+ - install is changed
+ - install_check is changed
+ - install_again is not changed
+ - install_again_check is not changed
+
+ - name: Check package has been installed correctly (hello-world)
+ command: hello-world
+ environment:
+ PATH: /snap/bin/
+
+ - name: Remove package (hello-world) (check mode)
+ community.general.snap:
+ name: hello-world
+ state: absent
+ register: remove_check
+ check_mode: true
+
+ - name: Remove package (hello-world)
+ community.general.snap:
+ name: hello-world
+ state: absent
+ register: remove
+
+ - name: Remove package again (hello-world) (check mode)
+ community.general.snap:
+ name: hello-world
+ state: absent
+ register: remove_again_check
+ check_mode: true
+
+ - name: Remove package again (hello-world)
+ community.general.snap:
+ name: hello-world
+ state: absent
+ register: remove_again
+
+ - name: Assert package has been removed just once (hello-world)
+ assert:
+ that:
+ - remove is changed
+ - remove_check is changed
+ - remove_again is not changed
+ - remove_again_check is not changed
+
+ - name: Make sure package from classic snap is not installed (nvim)
+ community.general.snap:
+ name: nvim
+ state: absent
+
+ - name: Install package from classic snap (nvim)
+ community.general.snap:
+ name: nvim
+ state: present
+ classic: true
+ register: classic_install
+
+ # testing classic idempotency
+ - name: Install package from classic snap again (nvim)
+ community.general.snap:
+ name: nvim
+ state: present
+ classic: true
+ register: classic_install_again
+
+ - name: Assert package has been installed just once (nvim)
+ assert:
+ that:
+ - classic_install is changed
+ - classic_install_again is not changed
+
+ # this is just testing if a package which has been installed
+ # with true classic can be removed without setting classic to true
+ - name: Remove package from classic snap without setting classic to true (nvim)
+ community.general.snap:
+ name: nvim
+ state: absent
+ register: classic_remove_without_true_classic
+
+ - name: Remove package from classic snap with setting classic to true (nvim)
+ community.general.snap:
+ name: nvim
+ state: absent
+ classic: true
+ register: classic_remove_with_true_classic
+
+ - name: Assert package has been removed without setting classic to true (nvim)
+ assert:
+ that:
+ - classic_remove_without_true_classic is changed
+ - classic_remove_with_true_classic is not changed
+
+
+ - name: Make sure package is not installed (uhttpd)
+ community.general.snap:
+ name: uhttpd
+ state: absent
+
+ - name: Install package (uhttpd)
+ community.general.snap:
+ name: uhttpd
+ state: present
+ register: install
+
+ - name: Install package (uhttpd)
+ community.general.snap:
+ name: uhttpd
+ state: present
+ options:
+ - "listening-port=8080"
+ register: install_with_option
+
+ - name: Install package again with option (uhttpd)
+ community.general.snap:
+ name: uhttpd
+ state: present
+ options:
+ - "listening-port=8080"
+ register: install_with_option_again
+
+ - name: Install package again with different options (uhttpd)
+ community.general.snap:
+ name: uhttpd
+ state: present
+ options:
+ - "listening-port=8088"
+ - "document-root-dir=/tmp"
+ register: install_with_option_changed
+
+ - name: Remove package (uhttpd)
+ community.general.snap:
+ name: uhttpd
+ state: absent
+ register: remove
+
+ - name: Assert package has been installed with options just once and only changed options trigger a change (uhttpd)
+ assert:
+ that:
+ - install is changed
+ - install_with_option is changed
+ - "install_with_option.options_changed[0] == 'uhttpd:listening-port=8080'"
+ - install_with_option_again is not changed
+ - install_with_option_changed is changed
+ - "'uhttpd:listening-port=8088' in install_with_option_changed.options_changed"
+ - "'uhttpd:document-root-dir=/tmp' in install_with_option_changed.options_changed"
+ - "'uhttpd:listening-port=8080' not in install_with_option_changed.options_changed"
+ - remove is changed
+
+ - name: Install two packages at the same time
+ community.general.snap:
+ name:
+ - hello-world
+ - uhttpd
+ state: present
+ register: install_two
+
+ - name: Install two packages at the same time (again)
+ community.general.snap:
+ name:
+ - hello-world
+ - uhttpd
+ state: present
+ register: install_two_again
+
+ - name: Remove packages (hello-world & uhttpd)
+ community.general.snap:
+ name:
+ - hello-world
+ - uhttpd
+ state: absent
+ register: install_two_remove
+
+ - name: Remove packages again (hello-world & uhttpd)
+ community.general.snap:
+ name:
+ - hello-world
+ - uhttpd
+ state: absent
+ register: install_two_remove_again
+
+ - name: Assert installation of two packages
+ assert:
+ that:
+ - install_two is changed
+ - "'hello-world' in install_two.snaps_installed"
+ - "'uhttpd' in install_two.snaps_installed"
+ - install_two.snaps_removed is not defined
+ - install_two_again is not changed
+ - install_two_again.snaps_installed is not defined
+ - install_two_again.snaps_removed is not defined
+ - install_two_remove is changed
+ - install_two_again.snaps_installed is not defined
+ - "'hello-world' in install_two_remove.snaps_removed"
+ - "'uhttpd' in install_two_remove.snaps_removed"
+ - install_two_remove_again is not changed
+ - install_two_remove_again.snaps_installed is not defined
+ - install_two_remove_again.snaps_removed is not defined
diff --git a/ansible_collections/community/general/tests/integration/targets/snap_alias/aliases b/ansible_collections/community/general/tests/integration/targets/snap_alias/aliases
new file mode 100644
index 000000000..b209bbc01
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/snap_alias/aliases
@@ -0,0 +1,13 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+azp/posix/vm
+skip/aix
+skip/alpine
+skip/fedora
+skip/freebsd
+skip/osx
+skip/macos
+skip/docker
diff --git a/ansible_collections/community/general/tests/integration/targets/snap_alias/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/snap_alias/meta/main.yml
new file mode 100644
index 000000000..f36427f71
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/snap_alias/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_snap
diff --git a/ansible_collections/community/general/tests/integration/targets/snap_alias/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/snap_alias/tasks/main.yml
new file mode 100644
index 000000000..1934eeb9f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/snap_alias/tasks/main.yml
@@ -0,0 +1,13 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Test
+ include_tasks: test.yml
+ when: has_snap
diff --git a/ansible_collections/community/general/tests/integration/targets/snap_alias/tasks/test.yml b/ansible_collections/community/general/tests/integration/targets/snap_alias/tasks/test.yml
new file mode 100644
index 000000000..50e6e33b4
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/snap_alias/tasks/test.yml
@@ -0,0 +1,159 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Ensure snap 'hello-world' is not installed
+ community.general.snap:
+ name: hello-world
+ state: absent
+
+- name: Ensure snap 'hello-world' is installed fresh
+ community.general.snap:
+ name: hello-world
+
+################################################################################
+
+- name: Create snap alias (check mode)
+ community.general.snap_alias:
+ name: hello-world
+ alias: hw
+ check_mode: true
+ register: alias_single_0
+
+- name: Create snap alias
+ community.general.snap_alias:
+ name: hello-world
+ alias: hw
+ register: alias_single_1
+
+- name: Create snap alias (check mode idempotent)
+ community.general.snap_alias:
+ name: hello-world
+ alias: hw
+ check_mode: true
+ register: alias_single_2
+
+- name: Create snap alias (idempotent)
+ community.general.snap_alias:
+ name: hello-world
+ alias: hw
+ register: alias_single_3
+
+- name: assert single alias
+ assert:
+ that:
+ - alias_single_0 is changed
+ - alias_single_1 is changed
+ - alias_single_2 is not changed
+ - alias_single_3 is not changed
+ - 'alias_single_1.snap_aliases["hello-world"] == ["hw"]'
+ - 'alias_single_3.snap_aliases["hello-world"] == ["hw"]'
+
+- name: Create multiple aliases (check mode)
+ community.general.snap_alias:
+ name: hello-world
+ aliases: [hw, hw2, hw3]
+ check_mode: true
+ register: alias_multi_0
+
+- name: Create multiple aliases
+ community.general.snap_alias:
+ name: hello-world
+ aliases: [hw, hw2, hw3]
+ register: alias_multi_1
+
+- name: Create multiple aliases (check mode idempotent)
+ community.general.snap_alias:
+ name: hello-world
+ aliases: [hw, hw2, hw3]
+ check_mode: true
+ register: alias_multi_2
+
+- name: Create multiple aliases (idempotent)
+ community.general.snap_alias:
+ name: hello-world
+ aliases: [hw, hw2, hw3]
+ register: alias_multi_3
+
+- name: assert multi alias
+ assert:
+ that:
+ - alias_multi_0 is changed
+ - alias_multi_1 is changed
+ - alias_multi_2 is not changed
+ - alias_multi_3 is not changed
+ - 'alias_multi_1.snap_aliases["hello-world"] == ["hw", "hw2", "hw3"]'
+ - 'alias_multi_3.snap_aliases["hello-world"] == ["hw", "hw2", "hw3"]'
+
+- name: Remove one specific alias (check mode)
+ community.general.snap_alias:
+ alias: hw
+ state: absent
+ check_mode: true
+ register: alias_remove_0
+
+- name: Remove one specific alias
+ community.general.snap_alias:
+ alias: hw
+ state: absent
+ register: alias_remove_1
+
+- name: Remove one specific alias (check mode idempotent)
+ community.general.snap_alias:
+ alias: hw
+ state: absent
+ check_mode: true
+ register: alias_remove_2
+
+- name: Remove one specific alias (idempotent)
+ community.general.snap_alias:
+ alias: hw
+ state: absent
+ register: alias_remove_3
+
+- name: assert remove alias
+ assert:
+ that:
+ - alias_remove_0 is changed
+ - alias_remove_1 is changed
+ - alias_remove_2 is not changed
+ - alias_remove_3 is not changed
+ - 'alias_remove_1.snap_aliases["hello-world"] == ["hw2", "hw3"]'
+ - 'alias_remove_3.snap_aliases["hello-world"] == ["hw2", "hw3"]'
+
+- name: Remove all aliases for snap (check mode)
+ community.general.snap_alias:
+ name: hello-world
+ state: absent
+ check_mode: true
+ register: alias_remove_all_0
+
+- name: Remove all aliases for snap
+ community.general.snap_alias:
+ name: hello-world
+ state: absent
+ register: alias_remove_all_1
+
+- name: Remove all aliases for snap (check mode idempotent)
+ community.general.snap_alias:
+ name: hello-world
+ state: absent
+ check_mode: true
+ register: alias_remove_all_2
+
+- name: Remove all aliases for snap (idempotent)
+ community.general.snap_alias:
+ name: hello-world
+ state: absent
+ register: alias_remove_all_3
+
+- name: assert remove_all alias
+ assert:
+ that:
+ - alias_remove_all_0 is changed
+ - alias_remove_all_1 is changed
+ - alias_remove_all_2 is not changed
+ - alias_remove_all_3 is not changed
+ - 'alias_remove_all_1.snap_aliases["hello-world"] == []'
+ - 'alias_remove_all_3.snap_aliases["hello-world"] == []'
diff --git a/ansible_collections/community/general/tests/integration/targets/spectrum_model_attrs/aliases b/ansible_collections/community/general/tests/integration/targets/spectrum_model_attrs/aliases
new file mode 100644
index 000000000..bd1f02444
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/spectrum_model_attrs/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+unsupported
diff --git a/ansible_collections/community/general/tests/integration/targets/spectrum_model_attrs/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/spectrum_model_attrs/tasks/main.yml
new file mode 100644
index 000000000..42e53d7d7
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/spectrum_model_attrs/tasks/main.yml
@@ -0,0 +1,78 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: "Verify required variables: model_name, model_type, oneclick_username, oneclick_password, oneclick_url"
+ fail:
+ msg: "One or more of the following variables are not set: model_name, model_type, oneclick_username, oneclick_password, oneclick_url"
+ when: >
+ model_name is not defined
+ or model_type is not defined
+ or oneclick_username is not defined
+ or oneclick_password is not defined
+ or oneclick_url is not defined
+
+- block:
+ - name: "001: Enforce maintenance mode for {{ model_name }} with a note about why [check_mode test]"
+ spectrum_model_attrs: &mm_enabled_args
+ url: "{{ oneclick_url }}"
+ username: "{{ oneclick_username }}"
+ password: "{{ oneclick_password }}"
+ name: "{{ model_name }}"
+ type: "{{ model_type }}"
+ validate_certs: false
+ attributes:
+ - name: "isManaged"
+ value: "false"
+ - name: "Notes"
+ value: "{{ note_mm_enabled }}"
+ check_mode: true
+ register: mm_enabled_check_mode
+
+ - name: "001: assert that changes were made"
+ assert:
+ that:
+ - mm_enabled_check_mode is changed
+
+ - name: "001: assert that changed_attrs is properly set"
+ assert:
+ that:
+ - mm_enabled_check_mode.changed_attrs.Notes == note_mm_enabled
+ - mm_enabled_check_mode.changed_attrs.isManaged == "false"
+
+ - name: "002: Enforce maintenance mode for {{ model_name }} with a note about why"
+ spectrum_model_attrs:
+ <<: *mm_enabled_args
+ register: mm_enabled
+ check_mode: false
+
+ - name: "002: assert that changes were made"
+ assert:
+ that:
+ - mm_enabled is changed
+
+ - name: "002: assert that changed_attrs is properly set"
+ assert:
+ that:
+ - mm_enabled.changed_attrs.Notes == note_mm_enabled
+ - mm_enabled.changed_attrs.isManaged == "false"
+
+ - name: "003: Enforce maintenance mode for {{ model_name }} with a note about why [idempontence test]"
+ spectrum_model_attrs:
+ <<: *mm_enabled_args
+ register: mm_enabled_idp
+ check_mode: false
+
+ - name: "003: assert that changes were not made"
+ assert:
+ that:
+ - mm_enabled_idp is not changed
+
+ - name: "003: assert that changed_attrs is not set"
+ assert:
+ that:
+ - mm_enabled_idp.changed_attrs == {}
+
+ vars:
+ note_mm_enabled: "MM set via CO #1234 by OJ Simpson"
diff --git a/ansible_collections/community/general/tests/integration/targets/ssh_config/aliases b/ansible_collections/community/general/tests/integration/targets/ssh_config/aliases
new file mode 100644
index 000000000..6011128da
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ssh_config/aliases
@@ -0,0 +1,9 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+destructive
+skip/python2.6 # stromssh only supports python3
+skip/python2.7 # stromssh only supports python3
+skip/freebsd # stromssh installation fails on freebsd
diff --git a/ansible_collections/community/general/tests/integration/targets/ssh_config/files/fake_id_rsa b/ansible_collections/community/general/tests/integration/targets/ssh_config/files/fake_id_rsa
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ssh_config/files/fake_id_rsa
diff --git a/ansible_collections/community/general/tests/integration/targets/ssh_config/files/ssh_config_test b/ansible_collections/community/general/tests/integration/targets/ssh_config/files/ssh_config_test
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ssh_config/files/ssh_config_test
diff --git a/ansible_collections/community/general/tests/integration/targets/ssh_config/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/ssh_config/meta/main.yml
new file mode 100644
index 000000000..4cdaaefba
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ssh_config/meta/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_remote_constraints
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/ssh_config/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/ssh_config/tasks/main.yml
new file mode 100644
index 000000000..c8b96d0c0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ssh_config/tasks/main.yml
@@ -0,0 +1,245 @@
+# Test code for ssh_config module
+# Copyright (c) 2021, Abhijeet Kasurde (@Akasurde) <akasurde@redhat.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install required libs
+ pip:
+ name:
+ - 'paramiko<3.0.0'
+ state: present
+ extra_args: "-c {{ remote_constraints }}"
+
+- set_fact:
+ output_test_dir: '{{ remote_tmp_dir }}/test_ssh_config'
+
+- set_fact:
+ ssh_config_test: '{{ output_test_dir }}/ssh_config_test'
+ ssh_private_key: '{{ output_test_dir }}/fake_id_rsa'
+
+- name: create a temporary directory
+ file:
+ path: "{{ output_test_dir }}"
+ state: directory
+
+- name: Copy sample config file
+ copy:
+ src: 'files/ssh_config_test'
+ dest: '{{ ssh_config_test }}'
+
+- name: Copy sample private key file
+ copy:
+ src: 'files/fake_id_rsa'
+ dest: '{{ ssh_private_key }}'
+
+- name: Fail for required argument
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ ignore_errors: true
+ register: host_required
+
+- name: Check if ssh_config fails for required parameter host
+ assert:
+ that:
+ - not host_required.changed
+
+- name: Add a host in check mode
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "example.com"
+ hostname: github.com
+ identity_file: '{{ ssh_private_key }}'
+ port: '2223'
+ state: present
+ register: host_add
+ check_mode: true
+
+- name: Check if changes are made in check mode
+ assert:
+ that:
+ - host_add.changed
+ - "'example.com' in host_add.hosts_added"
+ - host_add.hosts_changed is defined
+ - host_add.hosts_removed is defined
+
+- name: Add a host
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "example.com"
+ hostname: github.com
+ identity_file: '{{ ssh_private_key }}'
+ port: '2223'
+ state: present
+ register: host_add
+
+- name: Check if changes are made
+ assert:
+ that:
+ - host_add.changed
+ - "'example.com' in host_add.hosts_added"
+ - host_add.hosts_changed is defined
+ - host_add.hosts_removed is defined
+
+- name: Add same host again for idempotency
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "example.com"
+ hostname: github.com
+ identity_file: '{{ ssh_private_key }}'
+ port: '2223'
+ state: present
+ register: host_add_again
+
+- name: Check for idempotency
+ assert:
+ that:
+ - not host_add_again.changed
+ - host_add.hosts_changed is defined
+ - host_add.hosts_removed is defined
+ - host_add.hosts_added is defined
+
+- name: Update host
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "example.com"
+ hostname: github.com
+ identity_file: '{{ ssh_private_key }}'
+ port: '2224'
+ state: present
+ register: host_update
+
+- name: Check for update operation
+ assert:
+ that:
+ - host_update.changed
+ - host_update.hosts_changed is defined
+ - "'example.com' in host_update.hosts_changed"
+ - host_update.hosts_removed is defined
+ - host_update.hosts_added is defined
+ - host_update.hosts_change_diff is defined
+
+- name: Update host again
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "example.com"
+ hostname: github.com
+ identity_file: '{{ ssh_private_key }}'
+ port: '2224'
+ state: present
+ register: host_update
+
+- name: Check update operation for idempotency
+ assert:
+ that:
+ - not host_update.changed
+ - host_update.hosts_changed is defined
+ - host_update.hosts_removed is defined
+ - host_update.hosts_added is defined
+ - host_update.hosts_change_diff is defined
+
+- name: Delete a host
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "example.com"
+ state: absent
+ register: host_delete
+
+- name: Check if changes are made
+ assert:
+ that:
+ - host_delete.changed
+ - "'example.com' in host_delete.hosts_removed"
+ - host_delete.hosts_changed is defined
+ - host_delete.hosts_added is defined
+
+- name: Delete same host again for idempotency
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "example.com"
+ hostname: github.com
+ state: absent
+ register: host_delete_again
+
+- name: Check for idempotency
+ assert:
+ that:
+ - not host_delete_again.changed
+ - host_delete_again.hosts_changed is defined
+ - host_delete_again.hosts_removed is defined
+ - host_delete_again.hosts_added is defined
+
+- name: Check if user and ssh_config_file are mutually exclusive
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ user: root
+ host: "example.com"
+ hostname: github.com
+ identity_file: '{{ ssh_private_key }}'
+ port: '2223'
+ state: present
+ register: mut_ex
+ ignore_errors: true
+
+- name: Check mutual exclusive test - user and ssh_config_file
+ assert:
+ that:
+ - not mut_ex.changed
+ - "'parameters are mutually exclusive' in mut_ex.msg"
+
+- name: Check if proxycommand and proxyjump are mutually exclusive
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "example.com"
+ hostname: github.com
+ proxycommand: "ssh jumphost.example.com -W %h:%p"
+ proxyjump: "jumphost.example.com"
+ identity_file: '{{ ssh_private_key }}'
+ port: '2224'
+ state: present
+ register: proxy_mut_ex
+ ignore_errors: true
+
+- name: Check mutual exclusive test - proxycommand and proxyjump
+ assert:
+ that:
+ - not proxy_mut_ex.changed
+ - "'parameters are mutually exclusive' in proxy_mut_ex.msg"
+
+- name: Add a full name host
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "full_name"
+ hostname: full_name.com
+ identity_file: '{{ ssh_private_key }}'
+ port: '2223'
+ state: present
+ register: full_name
+
+- name: Check if changes are made
+ assert:
+ that:
+ - full_name is changed
+ - full_name.hosts_added == ["full_name"]
+ - full_name.hosts_changed == []
+ - full_name.hosts_removed == []
+
+- name: Add a host with name which is contained in full name host
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "full"
+ hostname: full.com
+ identity_file: '{{ ssh_private_key }}'
+ port: '2223'
+ state: present
+ register: short_name
+
+- name: Check that short name host is added and full name host is not updated
+ assert:
+ that:
+ - short_name is changed
+ - short_name.hosts_added == ["full"]
+ - short_name.hosts_changed == []
+ - short_name.hosts_removed == []
+
+- name: Include integration tests for additional options (e.g. proxycommand, proxyjump)
+ include_tasks: 'options.yml'
diff --git a/ansible_collections/community/general/tests/integration/targets/ssh_config/tasks/options.yml b/ansible_collections/community/general/tests/integration/targets/ssh_config/tasks/options.yml
new file mode 100644
index 000000000..406de6831
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ssh_config/tasks/options.yml
@@ -0,0 +1,422 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Reset ssh_config before testing options
+- name: Copy sample config file
+ copy:
+ src: 'files/ssh_config_test'
+ dest: '{{ ssh_config_test }}'
+
+- name: Options - Add in check mode
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "options.example.com"
+ proxycommand: "ssh jumphost.example.com -W %h:%p"
+ forward_agent: true
+ host_key_algorithms: "+ssh-rsa"
+ state: present
+ register: options_add
+ check_mode: true
+
+- name: Options - Check if changes are made in check mode
+ assert:
+ that:
+ - options_add.changed
+ - "'options.example.com' in options_add.hosts_added"
+ - options_add.hosts_changed is defined
+ - options_add.hosts_removed is defined
+
+- name: "Options - Get content of {{ ssh_config_test }}"
+ slurp:
+ src: "{{ ssh_config_test }}"
+ register: slurp_ssh_config
+
+- name: "Options - Verify that nothign was added to {{ ssh_config_test }} during change mode"
+ assert:
+ that:
+ - "'options.example.com' not in slurp_ssh_config['content'] | b64decode"
+
+- name: Options - Add a host
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "options.example.com"
+ proxycommand: "ssh jumphost.example.com -W %h:%p"
+ forward_agent: true
+ host_key_algorithms: "+ssh-rsa"
+ state: present
+ register: options_add
+
+- name: Options - Check if changes are made
+ assert:
+ that:
+ - options_add.changed
+ - "'options.example.com' in options_add.hosts_added"
+ - options_add.hosts_changed is defined
+ - options_add.hosts_removed is defined
+
+- name: Options - Add same host again for idempotency
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "options.example.com"
+ proxycommand: "ssh jumphost.example.com -W %h:%p"
+ forward_agent: true
+ host_key_algorithms: "+ssh-rsa"
+ state: present
+ register: options_add_again
+
+- name: Options - Check for idempotency
+ assert:
+ that:
+ - not options_add_again.changed
+ - options_add.hosts_changed is defined
+ - options_add.hosts_removed is defined
+ - options_add.hosts_added is defined
+
+- name: "Options - Get content of {{ ssh_config_test }}"
+ slurp:
+ src: "{{ ssh_config_test }}"
+ register: slurp_ssh_config
+
+- name: "Verify that {{ ssh_config_test }} contains added options"
+ assert:
+ that:
+ - "'proxycommand ssh jumphost.example.com -W %h:%p' in slurp_ssh_config['content'] | b64decode"
+ - "'forwardagent yes' in slurp_ssh_config['content'] | b64decode"
+ - "'hostkeyalgorithms +ssh-rsa' in slurp_ssh_config['content'] | b64decode"
+
+- name: Options - Update host
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "options.example.com"
+ proxycommand: "ssh new-jumphost.example.com -W %h:%p"
+ forward_agent: false
+ host_key_algorithms: "+ssh-ed25519"
+ state: present
+ register: options_update
+
+- name: Options - Check for update operation
+ assert:
+ that:
+ - options_update.changed
+ - options_update.hosts_changed is defined
+ - "'options.example.com' in options_update.hosts_changed"
+ - options_update.hosts_removed is defined
+ - options_update.hosts_added is defined
+ - options_update.hosts_change_diff is defined
+
+- name: Options - Update host again
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "options.example.com"
+ proxycommand: "ssh new-jumphost.example.com -W %h:%p"
+ forward_agent: false
+ host_key_algorithms: "+ssh-ed25519"
+ state: present
+ register: options_update
+
+- name: Options - Check update operation for idempotency
+ assert:
+ that:
+ - not options_update.changed
+ - options_update.hosts_changed is defined
+ - options_update.hosts_removed is defined
+ - options_update.hosts_added is defined
+ - options_update.hosts_change_diff is defined
+
+- name: "Options - Get content of {{ ssh_config_test }}"
+ slurp:
+ src: "{{ ssh_config_test }}"
+ register: slurp_ssh_config
+
+- name: "Verify that {{ ssh_config_test }} contains changed options"
+ assert:
+ that:
+ - "'proxycommand ssh new-jumphost.example.com -W %h:%p' in slurp_ssh_config['content'] | b64decode"
+ - "'forwardagent no' in slurp_ssh_config['content'] | b64decode"
+ - "'hostkeyalgorithms +ssh-ed25519' in slurp_ssh_config['content'] | b64decode"
+
+- name: Options - Ensure no update in case option exist in ssh_config file but wasn't defined in playbook
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "options.example.com"
+ state: present
+ register: options_no_update
+
+- name: Options - Check that no update took place
+ assert:
+ that:
+ - not options_update.changed
+ - options_update.hosts_changed is defined
+ - options_update.hosts_removed is defined
+ - options_update.hosts_added is defined
+ - options_update.hosts_change_diff is defined
+
+- name: "Options - Get content of {{ ssh_config_test }}"
+ slurp:
+ src: "{{ ssh_config_test }}"
+ register: slurp_ssh_config
+
+- name: "Verify that {{ ssh_config_test }} wasn't changed"
+ assert:
+ that:
+ - "'proxycommand ssh new-jumphost.example.com -W %h:%p' in slurp_ssh_config['content'] | b64decode"
+ - "'forwardagent no' in slurp_ssh_config['content'] | b64decode"
+ - "'hostkeyalgorithms +ssh-ed25519' in slurp_ssh_config['content'] | b64decode"
+
+- name: Debug
+ debug:
+ msg: "{{ slurp_ssh_config['content'] | b64decode }}"
+
+- name: Options - Delete a host
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "options.example.com"
+ state: absent
+ register: options_delete
+
+- name: Options - Check if host was removed
+ assert:
+ that:
+ - options_delete.changed
+ - "'options.example.com' in options_delete.hosts_removed"
+ - options_delete.hosts_changed is defined
+ - options_delete.hosts_added is defined
+
+- name: Options - Delete same host again for idempotency
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "options.example.com"
+ state: absent
+ register: options_delete_again
+
+- name: Options - Check delete operation for idempotency
+ assert:
+ that:
+ - not options_delete_again.changed
+ - options_delete_again.hosts_changed is defined
+ - options_delete_again.hosts_removed is defined
+ - options_delete_again.hosts_added is defined
+
+- name: "Options - Get content of {{ ssh_config_test }}"
+ slurp:
+ src: "{{ ssh_config_test }}"
+ register: slurp_ssh_config
+
+- name: "Verify that {{ ssh_config_test }} does not contains deleted options"
+ assert:
+ that:
+ - "'proxycommand ssh new-jumphost.example.com -W %h:%p' not in slurp_ssh_config['content'] | b64decode"
+ - "'forwardagent no' not in slurp_ssh_config['content'] | b64decode"
+ - "'hostkeyalgorithms +ssh-ed25519' not in slurp_ssh_config['content'] | b64decode"
+
+# Proxycommand and ProxyJump are mutually exclusive.
+# Reset ssh_config before testing options with proxyjump
+
+- name: Copy sample config file
+ copy:
+ src: 'files/ssh_config_test'
+ dest: '{{ ssh_config_test }}'
+
+- name: Options - Add in check mode
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "options.example.com"
+ proxyjump: "jumphost.example.com"
+ forward_agent: true
+ host_key_algorithms: "+ssh-rsa"
+ state: present
+ register: options_add
+ check_mode: true
+
+- name: Options - Check if changes are made in check mode
+ assert:
+ that:
+ - options_add.changed
+ - "'options.example.com' in options_add.hosts_added"
+ - options_add.hosts_changed is defined
+ - options_add.hosts_removed is defined
+
+- name: "Options - Get content of {{ ssh_config_test }}"
+ slurp:
+ src: "{{ ssh_config_test }}"
+ register: slurp_ssh_config
+
+- name: "Options - Verify that nothign was added to {{ ssh_config_test }} during change mode"
+ assert:
+ that:
+ - "'options.example.com' not in slurp_ssh_config['content'] | b64decode"
+
+- name: Options - Add a host
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "options.example.com"
+ proxyjump: "jumphost.example.com"
+ forward_agent: true
+ host_key_algorithms: "+ssh-rsa"
+ state: present
+ register: options_add
+
+- name: Options - Check if changes are made
+ assert:
+ that:
+ - options_add.changed
+ - "'options.example.com' in options_add.hosts_added"
+ - options_add.hosts_changed is defined
+ - options_add.hosts_removed is defined
+
+- name: Options - Add same host again for idempotency
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "options.example.com"
+ proxyjump: "jumphost.example.com"
+ forward_agent: true
+ host_key_algorithms: "+ssh-rsa"
+ state: present
+ register: options_add_again
+
+- name: Options - Check for idempotency
+ assert:
+ that:
+ - not options_add_again.changed
+ - options_add.hosts_changed is defined
+ - options_add.hosts_removed is defined
+ - options_add.hosts_added is defined
+
+- name: "Options - Get content of {{ ssh_config_test }}"
+ slurp:
+ src: "{{ ssh_config_test }}"
+ register: slurp_ssh_config
+
+- name: "Verify that {{ ssh_config_test }} contains added options"
+ assert:
+ that:
+ - "'proxyjump jumphost.example.com' in slurp_ssh_config['content'] | b64decode"
+ - "'forwardagent yes' in slurp_ssh_config['content'] | b64decode"
+ - "'hostkeyalgorithms +ssh-rsa' in slurp_ssh_config['content'] | b64decode"
+
+- name: Options - Update host
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "options.example.com"
+ proxyjump: "new-jumphost.example.com"
+ forward_agent: false
+ host_key_algorithms: "+ssh-ed25519"
+ state: present
+ register: options_update
+
+- name: Options - Check for update operation
+ assert:
+ that:
+ - options_update.changed
+ - options_update.hosts_changed is defined
+ - "'options.example.com' in options_update.hosts_changed"
+ - options_update.hosts_removed is defined
+ - options_update.hosts_added is defined
+ - options_update.hosts_change_diff is defined
+
+- name: Options - Update host again
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "options.example.com"
+ proxyjump: "new-jumphost.example.com"
+ forward_agent: false
+ host_key_algorithms: "+ssh-ed25519"
+ state: present
+ register: options_update
+
+- name: Options - Check update operation for idempotency
+ assert:
+ that:
+ - not options_update.changed
+ - options_update.hosts_changed is defined
+ - options_update.hosts_removed is defined
+ - options_update.hosts_added is defined
+ - options_update.hosts_change_diff is defined
+
+- name: "Options - Get content of {{ ssh_config_test }}"
+ slurp:
+ src: "{{ ssh_config_test }}"
+ register: slurp_ssh_config
+
+- name: "Verify that {{ ssh_config_test }} contains changed options"
+ assert:
+ that:
+ - "'proxyjump new-jumphost.example.com' in slurp_ssh_config['content'] | b64decode"
+ - "'forwardagent no' in slurp_ssh_config['content'] | b64decode"
+ - "'hostkeyalgorithms +ssh-ed25519' in slurp_ssh_config['content'] | b64decode"
+
+- name: Options - Ensure no update in case option exist in ssh_config file but wasn't defined in playbook
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "options.example.com"
+ state: present
+ register: options_no_update
+
+- name: Options - Check that no update took place
+ assert:
+ that:
+ - not options_update.changed
+ - options_update.hosts_changed is defined
+ - options_update.hosts_removed is defined
+ - options_update.hosts_added is defined
+ - options_update.hosts_change_diff is defined
+
+- name: "Options - Get content of {{ ssh_config_test }}"
+ slurp:
+ src: "{{ ssh_config_test }}"
+ register: slurp_ssh_config
+
+- name: "Verify that {{ ssh_config_test }} wasn't changed"
+ assert:
+ that:
+ - "'proxyjump new-jumphost.example.com' in slurp_ssh_config['content'] | b64decode"
+ - "'forwardagent no' in slurp_ssh_config['content'] | b64decode"
+ - "'hostkeyalgorithms +ssh-ed25519' in slurp_ssh_config['content'] | b64decode"
+
+- name: Debug
+ debug:
+ msg: "{{ slurp_ssh_config['content'] | b64decode }}"
+
+- name: Options - Delete a host
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "options.example.com"
+ state: absent
+ register: options_delete
+
+- name: Options - Check if host was removed
+ assert:
+ that:
+ - options_delete.changed
+ - "'options.example.com' in options_delete.hosts_removed"
+ - options_delete.hosts_changed is defined
+ - options_delete.hosts_added is defined
+
+- name: Options - Delete same host again for idempotency
+ community.general.ssh_config:
+ ssh_config_file: "{{ ssh_config_test }}"
+ host: "options.example.com"
+ state: absent
+ register: options_delete_again
+
+- name: Options - Check delete operation for idempotency
+ assert:
+ that:
+ - not options_delete_again.changed
+ - options_delete_again.hosts_changed is defined
+ - options_delete_again.hosts_removed is defined
+ - options_delete_again.hosts_added is defined
+
+- name: "Options - Get content of {{ ssh_config_test }}"
+ slurp:
+ src: "{{ ssh_config_test }}"
+ register: slurp_ssh_config
+
+- name: "Verify that {{ ssh_config_test }} does not contains deleted options"
+ assert:
+ that:
+ - "'proxyjump new-jumphost.example.com' not in slurp_ssh_config['content'] | b64decode"
+ - "'forwardagent no' not in slurp_ssh_config['content'] | b64decode"
+ - "'hostkeyalgorithms +ssh-ed25519' not in slurp_ssh_config['content'] | b64decode"
diff --git a/ansible_collections/community/general/tests/integration/targets/sudoers/aliases b/ansible_collections/community/general/tests/integration/targets/sudoers/aliases
new file mode 100644
index 000000000..12d1d6617
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/sudoers/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
diff --git a/ansible_collections/community/general/tests/integration/targets/sudoers/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/sudoers/tasks/main.yml
new file mode 100644
index 000000000..dd62025d5
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/sudoers/tasks/main.yml
@@ -0,0 +1,279 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Initialise environment
+
+- name: Register variables
+ set_fact:
+ sudoers_path: /etc/sudoers.d
+ alt_sudoers_path: /etc/sudoers_alt
+
+- name: Install sudo package
+ ansible.builtin.package:
+ name: sudo
+ when: ansible_os_family != 'Darwin'
+
+- name: Ensure sudoers directory exists
+ ansible.builtin.file:
+ path: "{{ sudoers_path }}"
+ state: directory
+ recurse: true
+
+- name: Ensure alternative sudoers directory exists
+ ansible.builtin.file:
+ path: "{{ alt_sudoers_path }}"
+ state: directory
+ recurse: true
+
+
+# Run module and collect data
+
+- name: Create first rule
+ community.general.sudoers:
+ name: my-sudo-rule-1
+ state: present
+ user: alice
+ commands: /usr/local/bin/command
+ register: rule_1
+
+- name: Stat my-sudo-rule-1 file
+ ansible.builtin.stat:
+ path: "{{ sudoers_path }}/my-sudo-rule-1"
+ register: rule_1_stat
+
+- name: Grab contents of my-sudo-rule-1
+ ansible.builtin.slurp:
+ src: "{{ sudoers_path }}/my-sudo-rule-1"
+ register: rule_1_contents
+
+- name: Create first rule again
+ community.general.sudoers:
+ name: my-sudo-rule-1
+ state: present
+ user: alice
+ commands: /usr/local/bin/command
+ register: rule_1_again
+
+
+- name: Create second rule with two commands
+ community.general.sudoers:
+ name: my-sudo-rule-2
+ state: present
+ user: alice
+ commands:
+ - /usr/local/bin/command1
+ - /usr/local/bin/command2
+ register: rule_2
+
+- name: Grab contents of my-sudo-rule-2
+ ansible.builtin.slurp:
+ src: "{{ sudoers_path }}/my-sudo-rule-2"
+ register: rule_2_contents
+
+
+- name: Create rule requiring a password
+ community.general.sudoers:
+ name: my-sudo-rule-3
+ state: present
+ user: alice
+ commands: /usr/local/bin/command
+ nopassword: false
+ register: rule_3
+
+- name: Grab contents of my-sudo-rule-3
+ ansible.builtin.slurp:
+ src: "{{ sudoers_path }}/my-sudo-rule-3"
+ register: rule_3_contents
+
+
+- name: Create rule using a group
+ community.general.sudoers:
+ name: my-sudo-rule-4
+ state: present
+ group: students
+ commands: /usr/local/bin/command
+ register: rule_4
+
+- name: Grab contents of my-sudo-rule-4
+ ansible.builtin.slurp:
+ src: "{{ sudoers_path }}/my-sudo-rule-4"
+ register: rule_4_contents
+
+
+- name: Create rule in a alternative directory
+ community.general.sudoers:
+ name: my-sudo-rule-5
+ state: present
+ user: alice
+ commands: /usr/local/bin/command
+ sudoers_path: "{{ alt_sudoers_path }}"
+ register: rule_5
+
+- name: Grab contents of my-sudo-rule-5 (in alternative directory)
+ ansible.builtin.slurp:
+ src: "{{ alt_sudoers_path }}/my-sudo-rule-5"
+ register: rule_5_contents
+
+- name: Create rule to runas another user
+ community.general.sudoers:
+ name: my-sudo-rule-6
+ state: present
+ user: alice
+ commands: /usr/local/bin/command
+ runas: bob
+ sudoers_path: "{{ sudoers_path }}"
+ register: rule_6
+
+- name: Grab contents of my-sudo-rule-6 (in alternative directory)
+ ansible.builtin.slurp:
+ src: "{{ sudoers_path }}/my-sudo-rule-6"
+ register: rule_6_contents
+
+- name: Create rule to allow user to sudo just on host-1
+ community.general.sudoers:
+ name: my-sudo-rule-7
+ state: present
+ user: alice
+ host: host-1
+ commands: /usr/local/bin/command
+ register: rule_7
+
+- name: Grab contents of my-sudo-rule-7
+ ansible.builtin.slurp:
+ src: "{{ sudoers_path }}/my-sudo-rule-7"
+ register: rule_7_contents
+
+- name: Create rule with setenv parameters
+ community.general.sudoers:
+ name: my-sudo-rule-8
+ state: present
+ user: alice
+ commands: /usr/local/bin/command
+ setenv: true
+ register: rule_8
+
+- name: Grab contents of my-sudo-rule-8
+ ansible.builtin.slurp:
+ src: "{{ sudoers_path }}/my-sudo-rule-8"
+ register: rule_8_contents
+
+- name: Revoke rule 1
+ community.general.sudoers:
+ name: my-sudo-rule-1
+ state: absent
+ register: revoke_rule_1
+
+- name: Stat rule 1
+ ansible.builtin.stat:
+ path: "{{ sudoers_path }}/my-sudo-rule-1"
+ register: revoke_rule_1_stat
+
+
+# Validation testing
+
+- name: Attempt command without full path to executable
+ community.general.sudoers:
+ name: edge-case-1
+ state: present
+ user: alice
+ commands: systemctl
+ ignore_errors: true
+ register: edge_case_1
+
+
+- name: Attempt command without full path to executable, but disabling validation
+ community.general.sudoers:
+ name: edge-case-2
+ state: present
+ user: alice
+ commands: systemctl
+ validation: absent
+ sudoers_path: "{{ alt_sudoers_path }}"
+ register: edge_case_2
+
+- name: find visudo
+ command:
+ cmd: which visudo
+ register: which_visudo
+ when: ansible_os_family != 'Darwin'
+
+- name: Prevent visudo being executed
+ file:
+ path: "{{ which_visudo.stdout }}"
+ mode: '-x'
+ when: ansible_os_family != 'Darwin'
+
+- name: Attempt command without full path to executable, but enforcing validation with no visudo present
+ community.general.sudoers:
+ name: edge-case-3
+ state: present
+ user: alice
+ commands: systemctl
+ validation: required
+ ignore_errors: true
+ when: ansible_os_family != 'Darwin'
+ register: edge_case_3
+
+- name: Revoke non-existing rule
+ community.general.sudoers:
+ name: non-existing-rule
+ state: absent
+ register: revoke_non_existing_rule
+
+- name: Stat non-existing rule
+ ansible.builtin.stat:
+ path: "{{ sudoers_path }}/non-existing-rule"
+ register: revoke_non_existing_rule_stat
+
+
+# Run assertions
+
+- name: Check rule 1 file stat
+ ansible.builtin.assert:
+ that:
+ - rule_1_stat.stat.exists
+ - rule_1_stat.stat.isreg
+ - rule_1_stat.stat.mode == '0440'
+
+- name: Check changed status
+ ansible.builtin.assert:
+ that:
+ - rule_1 is changed
+ - rule_1_again is not changed
+ - rule_5 is changed
+ - revoke_rule_1 is changed
+ - revoke_non_existing_rule is not changed
+
+- name: Check contents
+ ansible.builtin.assert:
+ that:
+ - "rule_1_contents['content'] | b64decode == 'alice ALL=NOPASSWD: /usr/local/bin/command\n'"
+ - "rule_2_contents['content'] | b64decode == 'alice ALL=NOPASSWD: /usr/local/bin/command1, /usr/local/bin/command2\n'"
+ - "rule_3_contents['content'] | b64decode == 'alice ALL= /usr/local/bin/command\n'"
+ - "rule_4_contents['content'] | b64decode == '%students ALL=NOPASSWD: /usr/local/bin/command\n'"
+ - "rule_5_contents['content'] | b64decode == 'alice ALL=NOPASSWD: /usr/local/bin/command\n'"
+ - "rule_6_contents['content'] | b64decode == 'alice ALL=(bob)NOPASSWD: /usr/local/bin/command\n'"
+ - "rule_7_contents['content'] | b64decode == 'alice host-1=NOPASSWD: /usr/local/bin/command\n'"
+ - "rule_8_contents['content'] | b64decode == 'alice ALL=NOPASSWD:SETENV: /usr/local/bin/command\n'"
+
+- name: Check revocation stat
+ ansible.builtin.assert:
+ that:
+ - not revoke_rule_1_stat.stat.exists
+ - not revoke_non_existing_rule_stat.stat.exists
+
+- name: Check edge case responses
+ ansible.builtin.assert:
+ that:
+ - edge_case_1 is failed
+ - "'Failed to validate sudoers rule' in edge_case_1.msg"
+ - edge_case_2 is not failed
+
+- name: Check missing validation edge case
+ ansible.builtin.assert:
+ that:
+ - edge_case_3 is failed
+ - "'Failed to find required executable' in edge_case_3.msg"
+ when: ansible_os_family != 'Darwin'
diff --git a/ansible_collections/community/general/tests/integration/targets/supervisorctl/aliases b/ansible_collections/community/general/tests/integration/targets/supervisorctl/aliases
new file mode 100644
index 000000000..58524f1fb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/supervisorctl/aliases
@@ -0,0 +1,8 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+destructive
+skip/python3
+skip/aix
diff --git a/ansible_collections/community/general/tests/integration/targets/supervisorctl/files/sendProcessStdin.py b/ansible_collections/community/general/tests/integration/targets/supervisorctl/files/sendProcessStdin.py
new file mode 100644
index 000000000..8635b0749
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/supervisorctl/files/sendProcessStdin.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# -*- coding: utf-8 -*-
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+import sys
+
+proc = sys.argv[1]
+value = sys.argv[2]
+username = sys.argv[3]
+password = sys.argv[4]
+
+if sys.version_info[0] == 2:
+ from xmlrpclib import ServerProxy
+ from urllib import quote
+else:
+ from xmlrpc.client import ServerProxy
+ from urllib.parse import quote
+
+if username:
+ url = 'http://%s:%s@127.0.0.1:9001/RPC2' % (quote(username, safe=''), quote(password, safe=''))
+else:
+ url = 'http://127.0.0.1:9001/RPC2'
+
+server = ServerProxy(url, verbose=True)
+server.supervisor.sendProcessStdin(proc, 'import sys; print(%s); sys.stdout.flush();\n' % value)
diff --git a/ansible_collections/community/general/tests/integration/targets/supervisorctl/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/supervisorctl/meta/main.yml
new file mode 100644
index 000000000..ca1915e05
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/supervisorctl/meta/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/install_Darwin.yml b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/install_Darwin.yml
new file mode 100644
index 000000000..b1d3bd779
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/install_Darwin.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: install supervisord
+ pip:
+ name: supervisor<4.0.0 # supervisor version 4.0.0 fails tests
+ state: present
diff --git a/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/install_FreeBSD.yml b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/install_FreeBSD.yml
new file mode 100644
index 000000000..b1d3bd779
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/install_FreeBSD.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: install supervisord
+ pip:
+ name: supervisor<4.0.0 # supervisor version 4.0.0 fails tests
+ state: present
diff --git a/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/install_Linux.yml b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/install_Linux.yml
new file mode 100644
index 000000000..2f70b284c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/install_Linux.yml
@@ -0,0 +1,15 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: install supervisor
+ package:
+ name: supervisor
+ state: present
+
+- name: disable supervisord system service
+ service:
+ name: '{{ supervisor_service_name }}'
+ state: stopped
+ enabled: false
diff --git a/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/install_RedHat.yml b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/install_RedHat.yml
new file mode 100644
index 000000000..b1d3bd779
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/install_RedHat.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: install supervisord
+ pip:
+ name: supervisor<4.0.0 # supervisor version 4.0.0 fails tests
+ state: present
diff --git a/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/install_Suse.yml b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/install_Suse.yml
new file mode 100644
index 000000000..b1d3bd779
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/install_Suse.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: install supervisord
+ pip:
+ name: supervisor<4.0.0 # supervisor version 4.0.0 fails tests
+ state: present
diff --git a/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/install_pip.yml b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/install_pip.yml
new file mode 100644
index 000000000..b1d3bd779
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/install_pip.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: install supervisord
+ pip:
+ name: supervisor<4.0.0 # supervisor version 4.0.0 fails tests
+ state: present
diff --git a/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/main.yml
new file mode 100644
index 000000000..6f8c7968c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/main.yml
@@ -0,0 +1,57 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- block:
+ - tempfile:
+ state: directory
+ suffix: supervisorctl-tests
+ register: supervisord_sock_path
+
+ - command: 'echo {{ remote_tmp_dir }}'
+ register: echo
+ - set_fact:
+ remote_dir: '{{ echo.stdout }}'
+
+ - include_vars: '{{ item }}'
+ with_first_found:
+ - files:
+ - '{{ ansible_distribution }}.yml'
+ - '{{ ansible_os_family }}.yml'
+ - 'defaults.yml'
+
+ - include_tasks: '{{ item }}'
+ with_first_found:
+ - files:
+ - 'install_{{ ansible_distribution }}.yml' # CentOS
+ - 'install_{{ ansible_os_family }}.yml' # RedHat
+ - 'install_{{ ansible_system }}.yml' # Linux
+
+ - include_tasks: test.yml
+ with_items:
+ - { username: '', password: '' }
+ - { username: 'testétest', password: 'passéword' } # non-ASCII credentials
+ loop_control:
+ loop_var: credentials
+
+ # setuptools is too old on RHEL/CentOS 6 (https://github.com/Supervisor/meld3/issues/23)
+ when: ansible_os_family != 'RedHat' or ansible_distribution_major_version|int > 6
+
+ always:
+ - include_tasks: '{{ item }}'
+ when: ansible_os_family != 'RedHat' or ansible_distribution_major_version|int > 6
+ with_first_found:
+ - files:
+ - 'uninstall_{{ ansible_distribution }}.yml' # CentOS
+ - 'uninstall_{{ ansible_os_family }}.yml' # RedHat
+ - 'uninstall_{{ ansible_system }}.yml' # Linux
+
+ - file:
+ path: '{{ supervisord_sock_path.path }}'
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/start_supervisord.yml b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/start_supervisord.yml
new file mode 100644
index 000000000..906d7aca4
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/start_supervisord.yml
@@ -0,0 +1,14 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: start supervisord
+ command: 'supervisord -c {{ remote_dir }}/supervisord.conf'
+
+- name: wait_for supervisord
+ ansible.builtin.wait_for:
+ port: 9001
+ host: 127.0.0.1
+ timeout: 15
+ state: started
diff --git a/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/stop_supervisord.yml b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/stop_supervisord.yml
new file mode 100644
index 000000000..52e064d15
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/stop_supervisord.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: stop supervisord
+ command: "supervisorctl -c {{ remote_dir }}/supervisord.conf {% if credentials.username %}-u {{ credentials.username }} -p {{ credentials.password }}{% endif %} shutdown"
diff --git a/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/test.yml b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/test.yml
new file mode 100644
index 000000000..5d1a867ed
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/test.yml
@@ -0,0 +1,17 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: generate supervisor configuration
+ template:
+ src: supervisord.conf
+ dest: '{{ remote_dir }}/supervisord.conf'
+
+- block:
+ - import_tasks: start_supervisord.yml
+
+ - import_tasks: test_start.yml
+ - import_tasks: test_stop.yml
+ always:
+ - import_tasks: stop_supervisord.yml
diff --git a/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/test_start.yml b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/test_start.yml
new file mode 100644
index 000000000..b814486cd
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/test_start.yml
@@ -0,0 +1,140 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: start py1 service (without auth)
+ supervisorctl:
+ name: 'pys:py1'
+ state: started
+ config: '{{ remote_dir }}/supervisord.conf'
+ register: result
+ when: credentials.username == ''
+
+- name: start py1 service (with auth)
+ supervisorctl:
+ name: 'pys:py1'
+ state: started
+ server_url: http://127.0.0.1:9001
+ username: '{{ credentials.username }}'
+ password: '{{ credentials.password }}'
+ register: result_with_auth
+ when: credentials.username != ''
+
+- command: "supervisorctl -c {{ remote_dir }}/supervisord.conf {% if credentials.username %}-u {{ credentials.username }} -p {{ credentials.password }}{% endif %} status"
+
+- name: check that service is started
+ assert:
+ that:
+ - (result is success and result_with_auth is skip) or (result is skip and result_with_auth is changed)
+ - (result is changed and result_with_auth is skip) or (result is skip and result_with_auth is changed)
+
+- name: check that service is running (part1) # py1.log content is checked below
+ script: "files/sendProcessStdin.py 'pys:py1' 2 \
+ '{{ credentials.username }}' '{{ credentials.password }}'"
+
+- name: try again to start py1 service (without auth)
+ supervisorctl:
+ name: pys:py1
+ state: started
+ config: '{{ remote_dir }}/supervisord.conf'
+ register: result
+ when: credentials.username == ''
+
+- name: try again to start py1 service (with auth)
+ supervisorctl:
+ name: pys:py1
+ state: started
+ server_url: http://127.0.0.1:9001
+ username: '{{ credentials.username }}'
+ password: '{{ credentials.password }}'
+ register: result_with_auth
+ when: credentials.username != ''
+
+- name: check that service is already running
+ assert:
+ that:
+ - (result is success and result_with_auth is skip) or (result is skip and result_with_auth is success)
+ - (result is not changed and result_with_auth is skip) or (result is skip and result_with_auth is not changed)
+
+- import_tasks: stop_supervisord.yml
+
+# supervisord has been stopped, check logfile
+- name: check that service has done what it was expected (part 2)
+ shell: 'test "$(tail -2 {{ remote_dir }}/py1.log | head -1)" = ">>> 2"'
+
+# restart supervisord and py1 service for next tasks
+- import_tasks: start_supervisord.yml
+
+- name: start py1 service (without auth)
+ supervisorctl:
+ name: 'pys:py1'
+ state: started
+ config: '{{ remote_dir }}/supervisord.conf'
+ register: result
+ when: credentials.username == ''
+
+- name: start py1 service (with auth)
+ supervisorctl:
+ name: 'pys:py1'
+ state: started
+ server_url: http://127.0.0.1:9001
+ username: '{{ credentials.username }}'
+ password: '{{ credentials.password }}'
+ register: result_with_auth
+ when: credentials.username != ''
+
+- name: check that service is started
+ assert:
+ that:
+ - (result is success and result_with_auth is skip) or (result is skip and result_with_auth is changed)
+ - (result is changed and result_with_auth is skip) or (result is skip and result_with_auth is changed)
+
+#############################################################
+
+- name: Check an error occurs when wrong credentials are used
+ supervisorctl:
+ name: pys:py1
+ state: started
+ server_url: http://127.0.0.1:9001
+ username: '{{ credentials.username }}wrong_creds'
+ password: '{{ credentials.password }}same_here'
+ register: result
+ failed_when: result is not skip and (result is success or result is not failed)
+ when: credentials.username != ''
+
+- name: Check an error occurs when wrong URL is used
+ supervisorctl:
+ name: pys:py1
+ state: started
+ server_url: http://127.0.0.1:9002
+ register: result
+ failed_when: result is success or result is not failed
+
+- name: Check an error occurs when wrong config path is used
+ supervisorctl:
+ name: 'pys:py1'
+ state: started
+ config: '{{ remote_dir }}/supervisord_not_here.conf'
+ register: result
+ failed_when: result is success or result is not failed
+
+- name: Check an error occurs wrong name is used (without auth)
+ supervisorctl:
+ name: 'invalid'
+ state: started
+ config: '{{ remote_dir }}/supervisord.conf'
+ register: result
+ failed_when: result is skip or (result is success or result is not failed)
+ when: credentials.username == ''
+
+- name: Check an error occurs wrong name is used (with auth)
+ supervisorctl:
+ name: 'invalid'
+ state: started
+ config: '{{ remote_dir }}/supervisord.conf'
+ username: '{{ credentials.username }}wrong_creds'
+ password: '{{ credentials.password }}same_here'
+ register: result
+ failed_when: result is skip or (result is success or result is not failed)
+ when: credentials.username != ''
diff --git a/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/test_stop.yml b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/test_stop.yml
new file mode 100644
index 000000000..8d8fdd42a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/test_stop.yml
@@ -0,0 +1,64 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: stop py1 service
+ supervisorctl:
+ name: 'pys:py1'
+ state: stopped
+ # test with 'server_url' parameter
+ server_url: 'unix://{{ supervisord_sock_path.path }}/supervisord.sock'
+ register: result
+ when: credentials.username == ''
+
+- name: stop py1 service
+ supervisorctl:
+ name: 'pys:py1'
+ state: stopped
+ # test with unix socket
+ server_url: 'unix://{{ supervisord_sock_path.path }}/supervisord.sock'
+ username: '{{ credentials.username }}'
+ password: '{{ credentials.password }}'
+ register: result_with_auth
+ when: credentials.username != ''
+
+- command: "supervisorctl -c {{ remote_dir }}/supervisord.conf {% if credentials.username %}-u {{ credentials.username }} -p {{ credentials.password }}{% endif %} status"
+
+- name: check that service is stopped
+ assert:
+ that:
+ - (result is success and result_with_auth is skip) or (result is skip and result_with_auth is success)
+ - (result is changed and result_with_auth is skip) or (result is skip and result_with_auth is changed)
+
+- name: "check that service isn't running"
+ script: "files/sendProcessStdin.py 'pys:py1' 1 \
+ '{{ credentials.username }}' '{{ credentials.password }}'"
+ register: is_py1_alive
+ failed_when: is_py1_alive is success
+
+- name: try again to stop py1 service (without auth)
+ supervisorctl:
+ name: pys:py1
+ state: stopped
+ # test with 'server_url' parameter
+ server_url: 'unix://{{ supervisord_sock_path.path }}/supervisord.sock'
+ register: result
+ when: credentials.username == ''
+
+- name: try again to stop py1 service (with auth)
+ supervisorctl:
+ name: pys:py1
+ state: stopped
+ # test with unix socket
+ server_url: 'unix://{{ supervisord_sock_path.path }}/supervisord.sock'
+ username: '{{ credentials.username }}'
+ password: '{{ credentials.password }}'
+ register: result_with_auth
+ when: credentials.username != ''
+
+- name: check that service is already stopped
+ assert:
+ that:
+ - (result is success and result_with_auth is skip) or (result is skip and result_with_auth is success)
+ - (result is not changed and result_with_auth is skip) or (result is skip and result_with_auth is not changed)
diff --git a/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/uninstall_Darwin.yml b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/uninstall_Darwin.yml
new file mode 100644
index 000000000..cf339dfd1
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/uninstall_Darwin.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: uninstall supervisord
+ pip:
+ name: supervisor
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/uninstall_FreeBSD.yml b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/uninstall_FreeBSD.yml
new file mode 100644
index 000000000..cf339dfd1
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/uninstall_FreeBSD.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: uninstall supervisord
+ pip:
+ name: supervisor
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/uninstall_Linux.yml b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/uninstall_Linux.yml
new file mode 100644
index 000000000..442c61b72
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/uninstall_Linux.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: uninstall supervisor
+ package:
+ name: supervisor
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/uninstall_RedHat.yml b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/uninstall_RedHat.yml
new file mode 100644
index 000000000..cf339dfd1
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/uninstall_RedHat.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: uninstall supervisord
+ pip:
+ name: supervisor
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/uninstall_Suse.yml b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/uninstall_Suse.yml
new file mode 100644
index 000000000..cf339dfd1
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/uninstall_Suse.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: uninstall supervisord
+ pip:
+ name: supervisor
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/uninstall_pip.yml b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/uninstall_pip.yml
new file mode 100644
index 000000000..cf339dfd1
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/supervisorctl/tasks/uninstall_pip.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: uninstall supervisord
+ pip:
+ name: supervisor
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/supervisorctl/templates/supervisord.conf b/ansible_collections/community/general/tests/integration/targets/supervisorctl/templates/supervisord.conf
new file mode 100644
index 000000000..f3d36b92e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/supervisorctl/templates/supervisord.conf
@@ -0,0 +1,48 @@
+{#
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+#}
+
+[supervisord]
+pidfile={{ remote_dir }}/supervisord.pid
+logfile={{ remote_dir }}/supervisord.log
+
+[program:py1]
+command={{ ansible_python.executable }} -i -u -
+user={{ ansible_user_id }}
+autostart=false
+autorestart=false
+stdout_logfile={{ remote_dir }}/py1.log
+redirect_stderr=yes
+
+[program:py2]
+command={{ ansible_python.executable }} -i -u -
+user={{ ansible_user_id }}
+autostart=false
+autorestart=false
+stdout_logfile={{ remote_dir }}/py2.log
+redirect_stderr=yes
+
+[group:pys]
+programs=py1,py2
+
+[unix_http_server]
+file={{ supervisord_sock_path.path }}/supervisord.sock
+{% if credentials.username is defined and credentials.username|default(false, boolean=true) %}
+username = {{ credentials.username }}
+password = {{ credentials.password }}
+{% endif %}
+
+[inet_http_server]
+port=127.0.0.1:9001
+{% if credentials.username is defined and credentials.username|default(false, boolean=true) %}
+username = {{ credentials.username }}
+password = {{ credentials.password }}
+{% endif %}
+
+[supervisorctl]
+serverurl=unix://{{ supervisord_sock_path.path }}/supervisord.sock
+
+[rpcinterface:supervisor]
+supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
diff --git a/ansible_collections/community/general/tests/integration/targets/supervisorctl/vars/Debian.yml b/ansible_collections/community/general/tests/integration/targets/supervisorctl/vars/Debian.yml
new file mode 100644
index 000000000..cba575a7c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/supervisorctl/vars/Debian.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+supervisor_service_name: supervisor
diff --git a/ansible_collections/community/general/tests/integration/targets/supervisorctl/vars/defaults.yml b/ansible_collections/community/general/tests/integration/targets/supervisorctl/vars/defaults.yml
new file mode 100644
index 000000000..1df9ae250
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/supervisorctl/vars/defaults.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+supervisor_service_name: supervisord
diff --git a/ansible_collections/community/general/tests/integration/targets/sysrc/aliases b/ansible_collections/community/general/tests/integration/targets/sysrc/aliases
new file mode 100644
index 000000000..e13fde32c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/sysrc/aliases
@@ -0,0 +1,9 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+needs/root
+skip/docker
+skip/osx
+skip/rhel
diff --git a/ansible_collections/community/general/tests/integration/targets/sysrc/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/sysrc/tasks/main.yml
new file mode 100644
index 000000000..2c45c3b1c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/sysrc/tasks/main.yml
@@ -0,0 +1,343 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Test on FreeBSD VMs
+ when:
+ - ansible_facts.virtualization_type != 'docker'
+ - ansible_facts.distribution == 'FreeBSD'
+ block:
+ - name: Cache original contents of /etc/rc.conf
+ shell: "cat /etc/rc.conf"
+ register: cached_etc_rcconf_content
+
+ - name: Cache original contents of /boot/loader.conf
+ shell: "cat /boot/loader.conf"
+ register: cached_boot_loaderconf_content
+
+ ##
+ ## sysrc - example - set mysqlpidfile
+ ##
+ - name: Configure mysql pid file
+ sysrc:
+ name: mysql_pidfile
+ value: /tmp/mysql.pid
+ register: sysrc_example1
+
+ - name: Configure mysql pid file (checkmode)
+ sysrc:
+ name: mysql_pidfile
+ value: checkmode
+ check_mode: true
+ register: sysrc_example1_checkmode
+
+ - name: Configure mysql pid file (idempotent)
+ sysrc:
+ name: mysql_pidfile
+ value: /tmp/mysql.pid
+ register: sysrc_example1_idempotent
+
+ - name: Get file content
+ shell: "cat /etc/rc.conf | egrep -v ^\\#"
+ register: sysrc_example1_content
+
+ - name: Ensure sysrc updates rc.conf properly
+ assert:
+ that:
+ - sysrc_example1.changed
+ - sysrc_example1_checkmode.changed
+ - not sysrc_example1_idempotent.changed
+ - "'mysql_pidfile=\"/tmp/mysql.pid\"' in sysrc_example1_content.stdout_lines"
+ - "'mysql_pidfile=\"checkmode\"' not in sysrc_example1_content.stdout_lines"
+
+ ##
+ ## sysrc - example - Enable accf_http kld in /boot/loader.conf
+ ##
+ - name: Enable accf_http kld in /boot/loader.conf
+ sysrc:
+ name: accf_http_load
+ state: present
+ value: "YES"
+ path: /boot/loader.conf
+ register: sysrc_example2
+
+ - name: Enable accf_http kld in /boot/loader.conf (checkmode)
+ sysrc:
+ name: accf_http_load
+ state: present
+ value: "NO"
+ path: /boot/loader.conf
+ check_mode: true
+ register: sysrc_example2_checkmode
+
+ - name: Enable accf_http kld in /boot/loader.conf (idempotent)
+ sysrc:
+ name: accf_http_load
+ state: present
+ value: "YES"
+ path: /boot/loader.conf
+ register: sysrc_example2_idempotent
+
+ - name: Get file content
+ shell: "cat /boot/loader.conf | egrep -v ^\\#"
+ register: sysrc_example2_content
+
+ - name: Ensure sysrc did not change the file, but marked as changed
+ assert:
+ that:
+ - sysrc_example2.changed
+ - sysrc_example2_checkmode.changed
+ - not sysrc_example2_idempotent.changed
+ - "'accf_http_load=\"YES\"' in sysrc_example2_content.stdout_lines"
+ - "'accf_http_load=\"NO\"' not in sysrc_example2_content.stdout_lines"
+
+ ##
+ ## sysrc - example - Add gif0 interface
+ ##
+ - name: Set cloned_interfaces
+ sysrc:
+ name: cloned_interfaces
+ value: "lo0"
+
+ - name: Add gif0 interface
+ sysrc:
+ name: cloned_interfaces
+ state: value_present
+ value: "gif0"
+ register: sysrc_example3
+
+ - name: Add gif1 interface (checkmode)
+ sysrc:
+ name: cloned_interfaces
+ state: value_present
+ value: "gif1"
+ check_mode: true
+ register: sysrc_example3_checkmode
+
+ - name: Add gif0 interface (idempotent)
+ sysrc:
+ name: cloned_interfaces
+ state: value_present
+ value: "gif0"
+ register: sysrc_example3_idempotent
+
+ - name: Get file content
+ shell: "cat /etc/rc.conf | egrep -v ^\\#"
+ register: sysrc_example3_content
+
+ - name: Ensure sysrc did not change the file, but marked as changed
+ assert:
+ that:
+ - sysrc_example3.changed
+ - sysrc_example3_checkmode.changed
+ - not sysrc_example3_idempotent.changed
+ - "'cloned_interfaces=\"lo0 gif0\"' in sysrc_example3_content.stdout_lines"
+
+ ##
+ ## sysrc - example - Enable nginx in testjail
+ ##
+ - name: Test within jail
+ #
+ # NOTE: currently fails with FreeBSD 12 with minor version less than 4
+ # NOTE: currently fails with FreeBSD 13 with minor version less than 1
+ #
+ when: >-
+ ansible_distribution_version is version('12.4', '>=') and ansible_distribution_version is version('13', '<')
+ or ansible_distribution_version is version('13.1', '>=')
+ block:
+ - name: Setup testjail
+ include_tasks: setup-testjail.yml
+
+ - name: Enable nginx in test jail
+ sysrc:
+ name: nginx_enable
+ value: "YES"
+ jail: testjail
+ register: sysrc_example4
+
+ - name: Enable nginx in test jail (checkmode)
+ sysrc:
+ name: nginx_enable
+ value: "NO"
+ jail: testjail
+ check_mode: true
+ register: sysrc_example4_checkmode
+
+ - name: Enable nginx in test jail (idempotent)
+ sysrc:
+ name: nginx_enable
+ value: "YES"
+ jail: testjail
+ register: sysrc_example4_idempotent
+
+ - name: Get file content
+ shell: "cat /usr/jails/testjail/etc/rc.conf | grep nginx_enable"
+ register: sysrc_example4_content
+
+ - name: Ensure sysrc worked in testjail
+ assert:
+ that:
+ - sysrc_example4.changed
+ - sysrc_example4_checkmode.changed
+ - not sysrc_example4_idempotent.changed
+ - "'nginx_enable=\"YES\"' in sysrc_example4_content.stdout_lines"
+ always:
+ - name: Stop and remove testjail
+ failed_when: false
+ changed_when: false
+ command: "ezjail-admin delete -wf testjail"
+
+ ##
+ ## sysrc - Test Absent
+ ##
+ - name: Set sysrc_absent to test removal
+ sysrc:
+ name: sysrc_absent
+ value: test
+
+ - name: Remove sysrc_absent (checkmode)
+ sysrc:
+ name: sysrc_absent
+ state: absent
+ check_mode: true
+ register: sysrc_absent_checkmode
+
+ - name: Remove sysrc_absent
+ sysrc:
+ name: sysrc_absent
+ state: absent
+ register: sysrc_absent
+
+ - name: Remove sysrc_absent (idempotent)
+ sysrc:
+ name: sysrc_absent
+ state: absent
+ register: sysrc_absent_idempotent
+
+ - name: Get file content
+ shell: "cat /etc/rc.conf | egrep -v ^\\#"
+ register: sysrc_absent_content
+
+ - name: Ensure sysrc did as intended
+ assert:
+ that:
+ - sysrc_absent_checkmode.changed
+ - sysrc_absent.changed
+ - not sysrc_absent_idempotent.changed
+ - "'sysrc_absent=\"test\"' not in sysrc_absent_content.stdout_lines"
+
+ ##
+ ## sysrc - Test alternate delimiter
+ ##
+ - name: Set sysrc_delim to known value
+ sysrc:
+ name: sysrc_delim
+ value: "t1,t2"
+
+ - name: Add to value with delimiter (not-exists)
+ sysrc:
+ name: sysrc_delim_create
+ state: value_present
+ delim: ","
+ value: t3
+ register: sysrc_delim_create
+
+ - name: Add to value with delimiter
+ sysrc:
+ name: sysrc_delim
+ state: value_present
+ delim: ","
+ value: t3
+ register: sysrc_delim
+
+ - name: Add to value with delimiter (checkmode)
+ sysrc:
+ name: sysrc_delim
+ state: value_present
+ delim: ","
+ value: t4
+ check_mode: true
+ register: sysrc_delim_checkmode
+
+ - name: Add to value with delimiter (idempotent)
+ sysrc:
+ name: sysrc_delim
+ state: value_present
+ delim: ","
+ value: t3
+ register: sysrc_delim_idempotent
+
+ - name: Get file content
+ shell: "cat /etc/rc.conf | egrep -v ^\\#"
+ register: sysrc_delim_content
+
+ - name: Ensure sysrc did as intended
+ assert:
+ that:
+ - sysrc_delim_create.changed
+ - sysrc_delim.changed
+ - sysrc_delim_checkmode.changed
+ - not sysrc_delim_idempotent.changed
+ - "'sysrc_delim=\"t1,t2,t3\"' in sysrc_delim_content.stdout_lines"
+ - "'sysrc_delim_create=\"t3\"' in sysrc_delim_content.stdout_lines"
+
+ ##
+ ## sysrc - value_absent
+ ##
+ - name: Remove value (when not exists)
+ sysrc:
+ name: sysrc_value_absent_delete
+ state: value_absent
+ delim: ","
+ value: t3
+ register: sysrc_value_absent_ignored
+
+ - name: Remove value from sysrc_delim
+ sysrc:
+ name: sysrc_delim
+ state: value_absent
+ value: t3
+ delim: ","
+ register: sysrc_value_absent
+
+ - name: Remove value from sysrc_delim (checkmode)
+ sysrc:
+ name: sysrc_delim
+ state: value_absent
+ value: t2
+ delim: ","
+ check_mode: true
+ register: sysrc_value_absent_checkmode
+
+ - name: Remove value from sysrc_delim (idempotent
+ sysrc:
+ name: sysrc_delim
+ state: value_absent
+ value: t3
+ delim: ","
+ register: sysrc_value_absent_idempotent
+
+ - name: Get file content
+ shell: "cat /etc/rc.conf | egrep -v ^\\#"
+ register: sysrc_delim_content
+
+ - name: Ensure sysrc did as intended with value_absent
+ assert:
+ that:
+ - not sysrc_value_absent_ignored.changed
+ - sysrc_value_absent.changed
+ - sysrc_value_absent_checkmode.changed
+ - not sysrc_value_absent_idempotent.changed
+ - "'sysrc_delim=\"t1,t2\"' in sysrc_delim_content.stdout_lines"
+ - "'sysrc_delim_delete' not in sysrc_delim_content.stdout_lines"
+ always:
+ - name: Restore /etc/rc.conf
+ copy:
+ content: "{{ cached_etc_rcconf_content }}"
+ dest: /etc/rc.conf
+
+ - name: Restore /boot/loader.conf
+ copy:
+ content: "{{ cached_boot_loaderconf_content }}"
+ dest: /boot/loader.conf
diff --git a/ansible_collections/community/general/tests/integration/targets/sysrc/tasks/setup-testjail.yml b/ansible_collections/community/general/tests/integration/targets/sysrc/tasks/setup-testjail.yml
new file mode 100644
index 000000000..8aac7a430
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/sysrc/tasks/setup-testjail.yml
@@ -0,0 +1,73 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+#
+# Instructions for setting up a jail
+# https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/jails-ezjail.html
+#
+- name: Setup cloned interfaces
+ lineinfile:
+ dest: /etc/rc.conf
+ regexp: ^cloned_interfaces=lo1
+ line: cloned_interfaces=lo1
+
+- name: Activate cloned interfaces
+ command: "service netif cloneup"
+ changed_when: false
+
+- name: Install ezjail
+ pkgng:
+ name: ezjail
+
+- name: Configure ezjail to use http
+ when: ansible_distribution_version is version('11.01', '>')
+ lineinfile:
+ dest: /usr/local/etc/ezjail.conf
+ regexp: ^ezjail_ftphost
+ line: ezjail_ftphost=http://ftp.freebsd.org
+
+- name: Configure ezjail to use archive for old freebsd releases
+ when: ansible_distribution_version is version('11.01', '<=')
+ lineinfile:
+ dest: /usr/local/etc/ezjail.conf
+ regexp: ^ezjail_ftphost
+ line: ezjail_ftphost=http://ftp-archive.freebsd.org
+
+- name: Start ezjail
+ ignore_errors: true
+ service:
+ name: ezjail
+ state: started
+ enabled: true
+
+- name: Has ezjail
+ register: ezjail_base_jail
+ stat:
+ path: /usr/jails/basejail
+
+- name: Setup ezjail base
+ when: not ezjail_base_jail.stat.exists
+ shell: "ezjail-admin install >> /tmp/ezjail.log"
+ changed_when: false
+
+- name: Has testjail
+ register: ezjail_test_jail
+ stat:
+ path: /usr/jails/testjail
+
+- name: Create testjail
+ when: not ezjail_test_jail.stat.exists
+ shell: "ezjail-admin create testjail 'lo1|127.0.1.1' >> /tmp/ezjail.log"
+ changed_when: false
+
+- name: Is testjail running
+ shell: "jls | grep testjail"
+ changed_when: false
+ failed_when: false
+ register: is_testjail_up
+
+- name: Start testjail
+ when: is_testjail_up.rc == 1
+ command: "ezjail-admin start testjail"
diff --git a/ansible_collections/community/general/tests/integration/targets/terraform/.gitignore b/ansible_collections/community/general/tests/integration/targets/terraform/.gitignore
new file mode 100644
index 000000000..c477f5db7
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/terraform/.gitignore
@@ -0,0 +1,8 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+**/.terraform/*
+*.tfstate
+*.tfstate.*
+.terraform.lock.hcl
diff --git a/ansible_collections/community/general/tests/integration/targets/terraform/aliases b/ansible_collections/community/general/tests/integration/targets/terraform/aliases
new file mode 100644
index 000000000..1b6e4a26d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/terraform/aliases
@@ -0,0 +1,11 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+skip/windows
+skip/aix
+skip/osx
+skip/macos
+skip/freebsd
+skip/python2
diff --git a/ansible_collections/community/general/tests/integration/targets/terraform/files/complex_variables/main.tf b/ansible_collections/community/general/tests/integration/targets/terraform/files/complex_variables/main.tf
new file mode 100644
index 000000000..8b7956ec0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/terraform/files/complex_variables/main.tf
@@ -0,0 +1,35 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+resource "null_resource" "mynullresource" {
+ triggers = {
+ # plain dictionaries
+ dict_name = var.dictionaries.name
+ dict_age = var.dictionaries.age
+
+ # list of dicrs
+ join_dic_name = join(",", var.list_of_objects.*.name)
+
+ # list-of-strings
+ join_list = join(",", var.list_of_strings.*)
+
+ # testing boolean
+ name = var.boolean ? var.dictionaries.name : var.list_of_objects[0].name
+
+ # top level string
+ sample_string_1 = var.string_type
+
+ # nested lists
+ num_from_matrix = var.list_of_lists[1][2]
+ }
+
+}
+
+output "string_type" {
+ value = var.string_type
+}
+
+output "multiline_string" {
+ value = var.multiline_string
+}
diff --git a/ansible_collections/community/general/tests/integration/targets/terraform/files/complex_variables/variables.tf b/ansible_collections/community/general/tests/integration/targets/terraform/files/complex_variables/variables.tf
new file mode 100644
index 000000000..34b050747
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/terraform/files/complex_variables/variables.tf
@@ -0,0 +1,62 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+variable "dictionaries" {
+ type = object({
+ name = string
+ age = number
+ })
+ description = "Same as ansible Dict"
+ default = {
+ age = 1
+ name = "value"
+ }
+}
+
+variable "list_of_strings" {
+ type = list(string)
+ description = "list of strings"
+ validation {
+ condition = (var.list_of_strings[1] == "cli specials\"&$%@#*!(){}[]:\"\" \\\\")
+ error_message = "Strings do not match."
+ }
+}
+
+variable "list_of_objects" {
+ type = list(object({
+ name = string
+ age = number
+ }))
+ validation {
+ condition = (var.list_of_objects[1].name == "cli specials\"&$%@#*!(){}[]:\"\" \\\\")
+ error_message = "Strings do not match."
+ }
+}
+
+variable "boolean" {
+ type = bool
+ description = "boolean"
+
+}
+
+variable "string_type" {
+ type = string
+ validation {
+ condition = (var.string_type == "cli specials\"&$%@#*!(){}[]:\"\" \\\\")
+ error_message = "Strings do not match."
+ }
+}
+
+variable "multiline_string" {
+ type = string
+ validation {
+ condition = (var.multiline_string == "one\ntwo\n")
+ error_message = "Strings do not match."
+ }
+}
+
+variable "list_of_lists" {
+ type = list(list(any))
+ default = [ [ 1 ], [1, 2, 3], [3] ]
+}
diff --git a/ansible_collections/community/general/tests/integration/targets/terraform/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/terraform/meta/main.yml
new file mode 100644
index 000000000..ca1915e05
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/terraform/meta/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/terraform/tasks/complex_variables.yml b/ansible_collections/community/general/tests/integration/targets/terraform/tasks/complex_variables.yml
new file mode 100644
index 000000000..9788a3eed
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/terraform/tasks/complex_variables.yml
@@ -0,0 +1,60 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create terraform project directory (complex variables)
+ ansible.builtin.file:
+ path: "{{ terraform_project_dir }}/complex_vars"
+ state: directory
+ mode: 0755
+
+- name: copy terraform files to work space
+ ansible.builtin.copy:
+ src: "complex_variables/{{ item }}"
+ dest: "{{ terraform_project_dir }}/complex_vars/{{ item }}"
+ with_items:
+ - main.tf
+ - variables.tf
+
+# This task would test the various complex variable structures of the with the
+# terraform null_resource
+- name: test complex variables
+ community.general.terraform:
+ project_path: "{{ terraform_project_dir }}/complex_vars"
+ binary_path: "{{ terraform_binary_path }}"
+ force_init: true
+ complex_vars: true
+ variables:
+ dictionaries:
+ name: "kosala"
+ age: 99
+ list_of_strings:
+ - "kosala"
+ - 'cli specials"&$%@#*!(){}[]:"" \\'
+ - "xxx"
+ - "zzz"
+ list_of_objects:
+ - name: "kosala"
+ age: 99
+ - name: 'cli specials"&$%@#*!(){}[]:"" \\'
+ age: 0.1
+ - name: "zzz"
+ age: 9.789
+ - name: "lll"
+ age: 1000
+ boolean: true
+ string_type: 'cli specials"&$%@#*!(){}[]:"" \\'
+ multiline_string: |
+ one
+ two
+ list_of_lists:
+ - [ 1 ]
+ - [ 11, 12, 13 ]
+ - [ 2 ]
+ - [ 3 ]
+ state: present
+ register: terraform_init_result
+
+- assert:
+ that: terraform_init_result is not failed
diff --git a/ansible_collections/community/general/tests/integration/targets/terraform/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/terraform/tasks/main.yml
new file mode 100644
index 000000000..1c66990be
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/terraform/tasks/main.yml
@@ -0,0 +1,67 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+
+# This block checks and registers Terraform version of the binary found in path.
+
+- name: Check for existing Terraform in path
+ block:
+ - name: Check if terraform is present in path
+ ansible.builtin.command: "command -v terraform"
+ register: terraform_binary_path
+ ignore_errors: true
+
+ - name: Check Terraform version
+ ansible.builtin.command: terraform version
+ register: terraform_version_output
+ when: terraform_binary_path.rc == 0
+
+ - name: Set terraform version
+ ansible.builtin.set_fact:
+ terraform_version_installed: "{{ terraform_version_output.stdout | regex_search('(?!Terraform.*v)([0-9]+\\.[0-9]+\\.[0-9]+)') }}"
+ when: terraform_version_output.changed
+
+# This block handles the tasks of installing the Terraform binary. This happens if there is no existing
+# terraform in $PATH OR version does not match `terraform_version`.
+
+- name: Execute Terraform install tasks
+ block:
+
+ - name: Install Terraform
+ ansible.builtin.debug:
+ msg: "Installing terraform {{ terraform_version }}, found: {{ terraform_version_installed | default('no terraform binary found') }}."
+
+ - name: Ensure unzip is present
+ ansible.builtin.package:
+ name: unzip
+ state: present
+
+ - name: Install Terraform binary
+ ansible.builtin.unarchive:
+ src: "{{ terraform_url }}"
+ dest: "{{ remote_tmp_dir }}"
+ mode: 0755
+ remote_src: true
+ validate_certs: "{{ validate_certs }}"
+
+ when: terraform_version_installed is not defined or terraform_version_installed != terraform_version
+
+# This sets `terraform_binary_path` to coalesced output of first non-empty string in this order:
+# path from the 'Check if terraform is present in path' task, and lastly, the fallback path.
+
+- name: Set path to terraform binary
+ ansible.builtin.set_fact:
+ terraform_binary_path: "{{ terraform_binary_path.stdout or remote_tmp_dir ~ '/terraform' }}"
+
+- name: Loop over provider upgrade test tasks
+ ansible.builtin.include_tasks: test_provider_upgrade.yml
+ vars:
+ tf_provider: "{{ terraform_provider_versions[provider_index] }}"
+ loop: "{{ terraform_provider_versions }}"
+ loop_control:
+ index_var: provider_index
+
+- name: Test Complex Varibles
+ ansible.builtin.include_tasks: complex_variables.yml
diff --git a/ansible_collections/community/general/tests/integration/targets/terraform/tasks/test_provider_upgrade.yml b/ansible_collections/community/general/tests/integration/targets/terraform/tasks/test_provider_upgrade.yml
new file mode 100644
index 000000000..b20182c9f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/terraform/tasks/test_provider_upgrade.yml
@@ -0,0 +1,35 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create terraform project directory (provider upgrade)
+ file:
+ path: "{{ terraform_project_dir }}/{{ item['name'] }}"
+ state: directory
+ mode: 0755
+ loop: "{{ terraform_provider_versions }}"
+ loop_control:
+ index_var: provider_index
+
+- name: Output terraform provider test project
+ ansible.builtin.template:
+ src: templates/provider_test/main.tf.j2
+ dest: "{{ terraform_project_dir }}/{{ tf_provider['name'] }}/main.tf"
+ force: true
+ register: terraform_provider_hcl
+
+# The purpose of this task is to init terraform multiple times with different provider module
+# versions, so that we can verify that provider upgrades during init work as intended.
+
+- name: Init Terraform configuration with pinned provider version
+ community.general.terraform:
+ project_path: "{{ terraform_provider_hcl.dest | dirname }}"
+ binary_path: "{{ terraform_binary_path }}"
+ force_init: true
+ provider_upgrade: "{{ terraform_provider_upgrade }}"
+ state: present
+ register: terraform_init_result
+
+- assert:
+ that: terraform_init_result is not failed
diff --git a/ansible_collections/community/general/tests/integration/targets/terraform/templates/provider_test/main.tf.j2 b/ansible_collections/community/general/tests/integration/targets/terraform/templates/provider_test/main.tf.j2
new file mode 100644
index 000000000..886a0c2de
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/terraform/templates/provider_test/main.tf.j2
@@ -0,0 +1,13 @@
+{#
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+#}
+terraform {
+ required_providers {
+ {{ tf_provider['name'] }} = {
+ source = "{{ tf_provider['source'] }}"
+ version = "{{ tf_provider['version'] }}"
+ }
+ }
+}
diff --git a/ansible_collections/community/general/tests/integration/targets/terraform/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/terraform/vars/main.yml
new file mode 100644
index 000000000..1032adee4
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/terraform/vars/main.yml
@@ -0,0 +1,40 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Terraform version that will be downloaded
+terraform_version: 1.1.7
+
+# Architecture of the downloaded Terraform release (needs to match target testing platform)
+
+terraform_arch: "{{ ansible_system | lower }}_{{terraform_arch_map[ansible_architecture] }}"
+
+# URL of where the Terraform binary will be downloaded from
+terraform_url: "https://releases.hashicorp.com/terraform/{{ terraform_version }}/terraform_{{ terraform_version }}_{{ terraform_arch }}.zip"
+
+# Controls whether the unarchive task will validate TLS certs of the Terraform binary host
+validate_certs: true
+
+# Directory where Terraform tests will be created
+terraform_project_dir: "{{ remote_tmp_dir }}/tf_provider_test"
+
+# Controls whether terraform init will use the `-upgrade` flag
+terraform_provider_upgrade: true
+
+# list of dicts containing Terraform providers that will be tested
+# The null provider is a good candidate, as it's small and has no external dependencies
+terraform_provider_versions:
+ - name: "null"
+ source: "hashicorp/null"
+ version: ">=2.0.0, < 3.0.0"
+ - name: "null"
+ source: "hashicorp/null"
+ version: ">=3.0.0"
+
+# mapping between values returned from ansible_architecture and arch names used by golang builds of Terraform
+# see https://www.terraform.io/downloads
+
+terraform_arch_map:
+ x86_64: amd64
+ arm64: arm64
diff --git a/ansible_collections/community/general/tests/integration/targets/test_a_module/aliases b/ansible_collections/community/general/tests/integration/targets/test_a_module/aliases
new file mode 100644
index 000000000..343f119da
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/test_a_module/aliases
@@ -0,0 +1,5 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/3
diff --git a/ansible_collections/community/general/tests/integration/targets/test_a_module/collections/ansible_collections/testns/testcoll/galaxy.yml b/ansible_collections/community/general/tests/integration/targets/test_a_module/collections/ansible_collections/testns/testcoll/galaxy.yml
new file mode 100644
index 000000000..2243e0dba
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/test_a_module/collections/ansible_collections/testns/testcoll/galaxy.yml
@@ -0,0 +1,12 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+namespace: testns
+name: testcoll
+version: 0.0.1
+authors:
+ - Ansible (https://github.com/ansible)
+description: null
+tags: [community]
diff --git a/ansible_collections/community/general/tests/integration/targets/test_a_module/collections/ansible_collections/testns/testcoll/plugins/modules/collection_module.py b/ansible_collections/community/general/tests/integration/targets/test_a_module/collections/ansible_collections/testns/testcoll/plugins/modules/collection_module.py
new file mode 100644
index 000000000..e7f1a987a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/test_a_module/collections/ansible_collections/testns/testcoll/plugins/modules/collection_module.py
@@ -0,0 +1,33 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2021, Felix Fontein <felix@fontein.de>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: collection_module
+short_description: Test collection module
+description:
+ - This is a test module in a local collection.
+author: "Felix Fontein (@felixfontein)"
+options: {}
+'''
+
+EXAMPLES = ''' # '''
+
+RETURN = ''' # '''
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ AnsibleModule(argument_spec={}).exit_json()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/general/tests/integration/targets/test_a_module/library/local_module.py b/ansible_collections/community/general/tests/integration/targets/test_a_module/library/local_module.py
new file mode 100644
index 000000000..9e9e649cb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/test_a_module/library/local_module.py
@@ -0,0 +1,33 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2021, Felix Fontein <felix@fontein.de>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+DOCUMENTATION = '''
+---
+module: local_module
+short_description: Test local module
+description:
+ - This is a test module locally next to a playbook.
+author: "Felix Fontein (@felixfontein)"
+options: {}
+'''
+
+EXAMPLES = ''' # '''
+
+RETURN = ''' # '''
+
+from ansible.module_utils.basic import AnsibleModule
+
+
+def main():
+ AnsibleModule(argument_spec={}).exit_json()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/ansible_collections/community/general/tests/integration/targets/test_a_module/runme.sh b/ansible_collections/community/general/tests/integration/targets/test_a_module/runme.sh
new file mode 100755
index 000000000..118abbc29
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/test_a_module/runme.sh
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+set -eux
+
+source virtualenv.sh
+
+# The collection loader ignores paths which have more than one ansible_collections in it.
+# That's why we have to copy this directory to a temporary place and run the test there.
+
+# Create temporary folder
+TEMPDIR=$(mktemp -d)
+trap '{ rm -rf ${TEMPDIR}; }' EXIT
+
+cp -r . "${TEMPDIR}"
+cd "${TEMPDIR}"
+
+ansible-playbook runme.yml "$@"
diff --git a/ansible_collections/community/general/tests/integration/targets/test_a_module/runme.yml b/ansible_collections/community/general/tests/integration/targets/test_a_module/runme.yml
new file mode 100644
index 000000000..4b7a5ec2c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/test_a_module/runme.yml
@@ -0,0 +1,42 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- hosts: localhost
+ tasks:
+ - name: Test a_module
+ assert:
+ that:
+ # Modules/actions that do not exist
+ - "'foo_bar' is not community.general.a_module"
+ - "'foo.bar.baz' is not community.general.a_module"
+ # Short name and FQCN for builtin and other collections
+ - "'file' is community.general.a_module"
+ - "'set_fact' is community.general.a_module"
+ - "'ansible.builtin.file' is community.general.a_module"
+ - "'ansible.builtin.set_fact' is community.general.a_module"
+ - "'ansible.builtin.foo_bar' is not community.general.a_module"
+ - "'community.crypto.acme_certificate' is community.general.a_module"
+ - "'community.crypto.openssl_privatekey_pipe' is community.general.a_module"
+ - "'community.crypto.foo_bar' is not community.general.a_module"
+ # Modules from this collection (that exist or not)
+ - "'community.general.ufw' is community.general.a_module"
+ - "'community.general.foooo_really_does_not_exist' is not community.general.a_module"
+ # Local module
+ - "'local_module' is community.general.a_module"
+ # Local collection module (that exist or not)
+ - "'testns.testcoll.collection_module' is community.general.a_module"
+ - "'testns.testcoll.foobar' is not community.general.a_module"
+
+ - name: Test a_module in case of routing
+ assert:
+ that:
+ # Redirected module
+ - "'ufw' is community.general.a_module"
+ # Redirected module where target collection does not exist
+ # (the target collection must not have been installed in CI!)
+ - "'onyx_pfc_interface' is not community.general.a_module"
+ # Tombstoned module
+ - "'community.general.docker_image_facts' is not community.general.a_module"
+ when: ansible_version.string is version('2.10.0', '>=')
diff --git a/ansible_collections/community/general/tests/integration/targets/timezone/aliases b/ansible_collections/community/general/tests/integration/targets/timezone/aliases
new file mode 100644
index 000000000..007bed538
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/timezone/aliases
@@ -0,0 +1,9 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+destructive
+skip/aix
+skip/osx
+skip/macos
diff --git a/ansible_collections/community/general/tests/integration/targets/timezone/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/timezone/meta/main.yml
new file mode 100644
index 000000000..2fcd152f9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/timezone/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
diff --git a/ansible_collections/community/general/tests/integration/targets/timezone/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/timezone/tasks/main.yml
new file mode 100644
index 000000000..3644eeafa
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/timezone/tasks/main.yml
@@ -0,0 +1,96 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Because hwclock usually isn't available inside Docker containers in Shippable
+# these tasks will detect if hwclock works and only run hwclock tests if it is
+# supported. That is why it is recommended to run these tests locally with
+# `--docker-privileged` on centos6, centos7 and ubuntu1404 images. Example
+# command to run on centos6:
+#
+# ansible-test integration --docker centos6 --docker-privileged -v timezone
+
+##
+## set path to timezone config files
+##
+
+- name: set config file path on Debian
+ set_fact:
+ timezone_config_file: '/etc/timezone'
+ when: ansible_os_family == 'Debian'
+
+- name: set config file path on RedHat
+ set_fact:
+ timezone_config_file: '/etc/sysconfig/clock'
+ when: ansible_os_family == 'RedHat'
+
+##
+## set path to hwclock config files
+##
+
+- name: set config file path on Debian
+ set_fact:
+ hwclock_config_file: '/etc/default/rcS'
+ when: ansible_os_family == 'Debian'
+
+- name: set config file path on RedHat
+ set_fact:
+ hwclock_config_file: '/etc/sysconfig/clock'
+ when: ansible_os_family == 'RedHat'
+
+####
+#### timezone tests
+####
+
+- name: make sure diffutils are installed on ArchLinux
+ package:
+ name: diffutils
+ state: present
+ when: ansible_distribution == 'Archlinux'
+
+- name: make sure tzdata is installed on Alpine
+ package:
+ name: tzdata
+ state: present
+ when: ansible_distribution == 'Alpine'
+
+- name: make sure the dbus service is started under systemd
+ systemd:
+ name: dbus
+ state: started
+ when:
+ - ansible_service_mgr == 'systemd'
+ - ansible_distribution == 'Fedora'
+ - ansible_facts.distribution_major_version is version('31', '<')
+
+
+- name: Run tests
+ # Skip tests on Fedora 31 and 32 because dbus fails to start unless the container is run in privileged mode.
+ # Even then, it starts unreliably. This may be due to the move to cgroup v2 in Fedora 31 and 32.
+ # https://www.redhat.com/sysadmin/fedora-31-control-group-v2
+ when:
+ - ansible_facts.distribution ~ ansible_facts.distribution_major_version not in ['Fedora31', 'Fedora32']
+ - not (ansible_os_family == 'Alpine') # TODO
+ block:
+ - name: set timezone to Etc/UTC
+ timezone:
+ name: Etc/UTC
+ register: original_timezone
+
+ - name: Value of original_timezone
+ debug:
+ msg: "{{ original_timezone }}"
+
+ - block:
+ - include_tasks: test.yml
+ always:
+ - name: Restore original system timezone - {{ original_timezone.diff.before.name }}
+ timezone:
+ name: "{{ original_timezone.diff.before.name }}"
+ when: original_timezone is changed
diff --git a/ansible_collections/community/general/tests/integration/targets/timezone/tasks/test.yml b/ansible_collections/community/general/tests/integration/targets/timezone/tasks/test.yml
new file mode 100644
index 000000000..975526800
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/timezone/tasks/test.yml
@@ -0,0 +1,612 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+##
+## test setting timezone, idempotency and checkmode
+##
+
+- name: set timezone to Australia/Brisbane (checkmode)
+ timezone:
+ name: Australia/Brisbane
+ check_mode: true
+ register: timezone_set_checkmode
+
+- name: ensure timezone reported as changed in checkmode
+ assert:
+ that:
+ - timezone_set_checkmode.changed
+ - timezone_set_checkmode.diff.after.name == 'Australia/Brisbane'
+ - timezone_set_checkmode.diff.before.name == 'Etc/UTC'
+
+- name: ensure checkmode didn't change the timezone
+ command: cmp /etc/localtime /usr/share/zoneinfo/Australia/Brisbane
+ register: result
+ failed_when: result is not failed
+ changed_when: false
+
+- name: ensure that checkmode didn't update the timezone in the config file
+ command: egrep '^(TIME)?ZONE="Etc/UTC"' {{ timezone_config_file }}
+ when:
+ - ansible_service_mgr != 'systemd'
+ - ansible_os_family == 'RedHat'
+
+- name: ensure that checkmode didn't update the timezone in the config file
+ command: egrep '^Etc/UTC' {{ timezone_config_file }}
+ when:
+ - ansible_service_mgr != 'systemd'
+ - ansible_os_family == 'Debian'
+
+- name: set timezone to Australia/Brisbane
+ timezone:
+ name: Australia/Brisbane
+ register: timezone_set
+
+- name: ensure timezone changed
+ assert:
+ that:
+ - timezone_set.changed
+ - timezone_set.diff.after.name == 'Australia/Brisbane'
+ - timezone_set.diff.before.name == 'Etc/UTC'
+
+- name: ensure that the timezone is actually set
+ command: cmp /etc/localtime /usr/share/zoneinfo/Australia/Brisbane
+ changed_when: false
+
+- name: ensure that the timezone is updated in the config file
+ command: egrep '^(TIME)?ZONE="Australia/Brisbane"' {{ timezone_config_file }}
+ when:
+ - ansible_service_mgr != 'systemd'
+ - ansible_os_family == 'RedHat'
+
+- name: ensure that the timezone is updated in the config file
+ command: egrep '^Australia/Brisbane' {{ timezone_config_file }}
+ when:
+ - ansible_service_mgr != 'systemd'
+ - ansible_os_family == 'Debian'
+
+- name: set timezone to Australia/Brisbane again
+ timezone:
+ name: Australia/Brisbane
+ register: timezone_again
+
+- name: ensure timezone idempotency
+ assert:
+ that:
+ - not timezone_again.changed
+
+- name: set timezone to Australia/Brisbane again in checkmode
+ timezone:
+ name: Australia/Brisbane
+ register: timezone_again_checkmode
+
+- name: set timezone idempotency (checkmode)
+ assert:
+ that:
+ - not timezone_again_checkmode.changed
+
+##
+## tests for same timezones with different names
+##
+
+- name: check dpkg-reconfigure
+ shell: type dpkg-reconfigure
+ register: check_dpkg_reconfigure
+ ignore_errors: true
+ changed_when: false
+
+- name: check timedatectl
+ shell: type timedatectl && timedatectl
+ register: check_timedatectl
+ ignore_errors: true
+ changed_when: false
+
+- block:
+ - name: set timezone to Etc/UTC
+ timezone:
+ name: Etc/UTC
+
+ - name: change timezone from Etc/UTC to UTC
+ timezone:
+ name: UTC
+ register: timezone_etcutc_to_utc
+
+ - name: check timezone changed from Etc/UTC to UTC
+ assert:
+ that:
+ - timezone_etcutc_to_utc.changed
+ - timezone_etcutc_to_utc.diff.before.name == 'Etc/UTC'
+ - timezone_etcutc_to_utc.diff.after.name == 'UTC'
+
+ - name: change timezone from UTC to Etc/UTC
+ timezone:
+ name: Etc/UTC
+ register: timezone_utc_to_etcutc
+
+ - name: check timezone changed from UTC to Etc/UTC
+ assert:
+ that:
+ - timezone_utc_to_etcutc.changed
+ - timezone_utc_to_etcutc.diff.before.name == 'UTC'
+ - timezone_utc_to_etcutc.diff.after.name == 'Etc/UTC'
+
+ when:
+ # FIXME: Due to the bug of the dpkg-reconfigure, those tests failed on non-systemd debian
+ - check_dpkg_reconfigure.rc != 0 or check_timedatectl.rc == 0
+
+##
+## no systemd tests for timezone
+##
+
+- block:
+ ##
+ ## test with empty config file
+ ##
+
+ - name: empty config file
+ command: cp /dev/null {{ timezone_config_file }}
+
+ - name: set timezone to Europe/Belgrade (empty config file)
+ timezone:
+ name: Europe/Belgrade
+ register: timezone_empty_conf
+
+ - name: check if timezone set (empty config file)
+ assert:
+ that:
+ - timezone_empty_conf.changed
+ - timezone_empty_conf.diff.after.name == 'Europe/Belgrade'
+ - timezone_empty_conf.diff.before.name == 'n/a'
+
+ - name: check if the timezone is actually set (empty config file)
+ command: cmp /etc/localtime /usr/share/zoneinfo/Europe/Belgrade
+ changed_when: false
+
+
+ ##
+ ## test with deleted config file
+ ##
+
+ - name: remove config file
+ file:
+ path: '{{ timezone_config_file }}'
+ state: absent
+
+ - name: set timezone to Europe/Belgrade (no config file)
+ timezone:
+ name: Europe/Belgrade
+ register: timezone_missing_conf
+
+ - name: check if timezone set (no config file)
+ assert:
+ that:
+ - timezone_missing_conf.changed
+ - timezone_missing_conf.diff.after.name == 'Europe/Belgrade'
+ - timezone_missing_conf.diff.before.name == 'n/a'
+
+ - name: check if the timezone is actually set (no config file)
+ command: cmp /etc/localtime /usr/share/zoneinfo/Europe/Belgrade
+ changed_when: false
+
+
+ ##
+ ## test with /etc/localtime as symbolic link to a zoneinfo file
+ ##
+
+ - name: create symlink /etc/locatime -> /usr/share/zoneinfo/Etc/UTC
+ file:
+ src: /usr/share/zoneinfo/Etc/UTC
+ dest: /etc/localtime
+ state: link
+ force: true
+
+ - name: set timezone to Europe/Belgrade (over symlink)
+ timezone:
+ name: Europe/Belgrade
+ register: timezone_symllink
+
+ - name: check if timezone set (over symlink)
+ assert:
+ that:
+ - timezone_symllink.changed
+ - timezone_symllink.diff.after.name == 'Europe/Belgrade'
+ - timezone_symllink.diff.before.name == 'Etc/UTC'
+
+ - name: check if the timezone is actually set (over symlink)
+ command: cmp /etc/localtime /usr/share/zoneinfo/Europe/Belgrade
+ changed_when: false
+
+
+ ##
+ ## test with /etc/localtime as broken symbolic link
+ ##
+
+ - name: set timezone to a broken symlink
+ file:
+ src: /tmp/foo
+ dest: /etc/localtime
+ state: link
+ force: true
+
+ - name: set timezone to Europe/Belgrade (over broken symlink)
+ timezone:
+ name: Europe/Belgrade
+ register: timezone_symllink_broken
+
+ - name: check if timezone set (over broken symlink)
+ assert:
+ that:
+ - timezone_symllink_broken.changed
+ - timezone_symllink_broken.diff.after.name == 'Europe/Belgrade'
+ - timezone_symllink_broken.diff.before.name == 'n/a'
+
+ - name: check if the timezone is actually set (over broken symlink)
+ command: cmp /etc/localtime /usr/share/zoneinfo/Europe/Belgrade
+ changed_when: false
+
+
+ ##
+ ## test with /etc/localtime set manually using copy
+ ##
+
+ - name: set timezone manually by coping zone info file to /etc/localtime
+ copy:
+ src: /usr/share/zoneinfo/Etc/UTC
+ dest: /etc/localtime
+ remote_src: true
+
+ - name: set timezone to Europe/Belgrade (over copied file)
+ timezone:
+ name: Europe/Belgrade
+ register: timezone_copied
+
+ - name: check if timezone set (over copied file)
+ assert:
+ that:
+ - timezone_copied.changed
+ - timezone_copied.diff.after.name == 'Europe/Belgrade'
+ - timezone_copied.diff.before.name == 'n/a'
+
+ - name: check if the timezone is actually set (over copied file)
+ command: cmp /etc/localtime /usr/share/zoneinfo/Europe/Belgrade
+ changed_when: false
+ when:
+ - ansible_service_mgr != 'systemd'
+ - timezone_config_file is defined
+
+
+####
+#### hwclock tests
+####
+
+- name: check if hwclock is supported in the environment
+ command: hwclock --test
+ register: hwclock_test
+ ignore_errors: true
+
+- name: check if timedatectl works in the environment
+ command: timedatectl
+ register: timedatectl_test
+ ignore_errors: true
+
+- name:
+ set_fact:
+ hwclock_supported: '{{ hwclock_test is successful or (timedatectl_test is successful and "RTC time: n/a" not in timedatectl_test.stdout) }}'
+##
+## test set hwclock, idempotency and checkmode
+##
+
+- block:
+ - name: set hwclock to local
+ timezone:
+ hwclock: local
+
+ - name: set hwclock to UTC (checkmode)
+ timezone:
+ hwclock: UTC
+ check_mode: true
+ register: hwclock_set_checkmode
+
+ - name: ensure hwclock reported as changed (checkmode)
+ assert:
+ that:
+ - hwclock_set_checkmode.changed
+ - hwclock_set_checkmode.diff.after.hwclock == 'UTC'
+ - hwclock_set_checkmode.diff.before.hwclock == 'local'
+
+ - block:
+ - name: ensure that checkmode didn't update hwclock in /etc/adjtime
+ command: grep ^UTC /etc/adjtime
+ register: result
+ failed_when: result is not failed
+
+ - name: ensure that checkmode didn't update hwclock the config file
+ command: grep ^UTC=no {{ hwclock_config_file }}
+ when: ansible_service_mgr != 'systemd'
+
+ - name: set hwclock to UTC
+ timezone:
+ hwclock: UTC
+ register: hwclock_set
+
+ - name: ensure hwclock changed
+ assert:
+ that:
+ - hwclock_set.changed
+ - hwclock_set.diff.after.hwclock == 'UTC'
+ - hwclock_set.diff.before.hwclock == 'local'
+
+ - block:
+ - name: ensure that hwclock is updated in /etc/adjtime
+ command: grep ^UTC /etc/adjtime
+
+ - name: ensure that hwclock is updated in the config file
+ command: grep ^UTC=yes {{ hwclock_config_file }}
+ when: ansible_service_mgr != 'systemd'
+
+ - name: set hwclock to RTC again
+ timezone:
+ hwclock: UTC
+ register: hwclock_again
+
+ - name: set hwclock idempotency
+ assert:
+ that:
+ - not hwclock_again.changed
+
+ - name: set hwclock to RTC again (checkmode)
+ timezone:
+ hwclock: UTC
+ check_mode: true
+ register: hwclock_again_checkmode
+
+ - name: set hwclock idempotency (checkmode)
+ assert:
+ that:
+ - not hwclock_again_checkmode.changed
+
+
+ ##
+ ## no systemd tests for hwclock
+ ##
+
+ - block:
+ ##
+ ## test set hwclock with both /etc/adjtime and conf file deleted
+ ##
+
+ - name: remove /etc/adjtime and conf file
+ file:
+ path: '{{ item }}'
+ state: absent
+ with_items:
+ - /etc/adjtime
+ - '{{ hwclock_config_file }}'
+
+ - name: set hwclock to UTC with deleted /etc/adjtime and conf file
+ timezone:
+ hwclock: UTC
+ register: hwclock_set_utc_deleted_adjtime_and_conf
+
+ - name: ensure hwclock changed with deleted /etc/adjtime and conf
+ assert:
+ that:
+ - hwclock_set_utc_deleted_adjtime_and_conf.changed
+ - hwclock_set_utc_deleted_adjtime_and_conf.diff.after.hwclock == 'UTC'
+ - hwclock_set_utc_deleted_adjtime_and_conf.diff.before.hwclock == 'n/a'
+
+
+ ##
+ ## test set hwclock with /etc/adjtime deleted
+ ##
+
+ - name: remove /etc/adjtime
+ file:
+ path: '{{ item }}'
+ state: absent
+ with_items:
+ - /etc/adjtime
+
+ - name: set hwclock to UTC with deleted /etc/adjtime
+ timezone:
+ hwclock: UTC
+ register: hwclock_set_utc_deleted_adjtime_utc
+
+ - name: ensure hwclock changed with deleted /etc/adjtime
+ assert:
+ that:
+ - not hwclock_set_utc_deleted_adjtime_utc.changed
+ - hwclock_set_utc_deleted_adjtime_utc.diff.after.hwclock == 'UTC'
+ - hwclock_set_utc_deleted_adjtime_utc.diff.before.hwclock == 'UTC'
+
+ - name: set hwclock to LOCAL with deleted /etc/adjtime
+ timezone:
+ hwclock: local
+ register: hwclock_set_local_deleted_adjtime_local
+
+ - name: ensure hwclock changed to LOCAL with deleted /etc/adjtime
+ assert:
+ that:
+ - hwclock_set_local_deleted_adjtime_local.changed
+ - hwclock_set_local_deleted_adjtime_local.diff.after.hwclock == 'local'
+ - hwclock_set_local_deleted_adjtime_local.diff.before.hwclock == 'UTC'
+
+
+ ##
+ ## test set hwclock with conf file deleted
+ ##
+
+ - name: remove conf file
+ file:
+ path: '{{ item }}'
+ state: absent
+ with_items:
+ - '{{ hwclock_config_file }}'
+
+ - name: set hwclock to UTC with deleted conf
+ timezone:
+ hwclock: UTC
+ register: hwclock_set_utc_deleted_conf
+
+ - name: ensure hwclock changed with deleted /etc/adjtime
+ assert:
+ that:
+ - hwclock_set_utc_deleted_conf.changed
+ - hwclock_set_utc_deleted_conf.diff.after.hwclock == 'UTC'
+ - hwclock_set_utc_deleted_conf.diff.before.hwclock == 'n/a'
+
+
+ ##
+ ## test set hwclock with /etc/adjtime missing UTC/LOCAL strings
+ ##
+
+ - name: create /etc/adjtime without UTC/LOCAL
+ copy:
+ content: '0.0 0 0\n0'
+ dest: /etc/adjtime
+
+ - name: set hwclock to UTC with broken /etc/adjtime
+ timezone:
+ hwclock: UTC
+ register: hwclock_set_utc_broken_adjtime
+
+ - name: ensure hwclock doesn't report changed with broken /etc/adjtime
+ assert:
+ that:
+ - not hwclock_set_utc_broken_adjtime.changed
+ - hwclock_set_utc_broken_adjtime.diff.after.hwclock == 'UTC'
+ - hwclock_set_utc_broken_adjtime.diff.before.hwclock == 'UTC'
+
+ - name: set hwclock to LOCAL with broken /etc/adjtime
+ timezone:
+ hwclock: local
+ register: hwclock_set_local_broken_adjtime
+
+ - name: ensure hwclock changed to LOCAL with broken /etc/adjtime
+ assert:
+ that:
+ - hwclock_set_local_broken_adjtime.changed
+ - hwclock_set_local_broken_adjtime.diff.after.hwclock == 'local'
+ - hwclock_set_local_broken_adjtime.diff.before.hwclock == 'UTC'
+ when:
+ - ansible_service_mgr != 'systemd'
+ - hwclock_config_file is defined
+
+ ####
+ #### timezone + hwclock tests
+ ####
+
+ ##
+ ## test set timezone and hwclock, idempotency and checkmode
+ ##
+
+ - name: set timezone to Etc/UTC and hwclock to local
+ timezone:
+ name: Etc/UTC
+ hwclock: local
+
+ - name: set timezone to Europe/Belgrade and hwclock to UTC (checkmode)
+ timezone:
+ name: Europe/Belgrade
+ hwclock: UTC
+ check_mode: true
+ register: tzclock_set_checkmode
+
+ - name: ensure timezone and hwclock reported as changed in checkmode
+ assert:
+ that:
+ - tzclock_set_checkmode.changed
+ - tzclock_set_checkmode.diff.after.name == 'Europe/Belgrade'
+ - tzclock_set_checkmode.diff.before.name == 'Etc/UTC'
+ - tzclock_set_checkmode.diff.after.hwclock == 'UTC'
+ - tzclock_set_checkmode.diff.before.hwclock == 'local'
+
+ - name: ensure checkmode didn't change the timezone
+ command: cmp /etc/localtime /usr/share/zoneinfo/Australia/Brisbane
+ register: result
+ failed_when: result is not failed
+ changed_when: false
+
+ - block:
+ - name: ensure that checkmode didn't update the timezone in the config file
+ command: egrep '^(TIME)?ZONE="Etc/UTC"' {{ timezone_config_file }}
+ when:
+ - ansible_os_family == 'RedHat'
+
+ - name: ensure that checkmode didn't update the timezone in the config file
+ command: egrep '^Etc/UTC' {{ timezone_config_file }}
+ when:
+ - ansible_os_family == 'Debian'
+
+ - name: ensure that checkmode didn't update hwclock in /etc/adjtime
+ command: grep ^UTC /etc/adjtime
+ register: result
+ failed_when: result is not failed
+
+ - name: ensure that checkmode didn't update hwclock the config file
+ command: grep ^UTC=no {{ hwclock_config_file }}
+ when: ansible_service_mgr != 'systemd'
+
+ - name: set timezone to Europe/Belgrade and hwclock to UTC
+ timezone:
+ name: Europe/Belgrade
+ hwclock: UTC
+ register: tzclock_set
+
+ - name: ensure timezone and hwclock changed
+ assert:
+ that:
+ - tzclock_set.changed
+ - tzclock_set.diff.after.name == 'Europe/Belgrade'
+ - tzclock_set.diff.before.name == 'Etc/UTC'
+ - tzclock_set.diff.after.hwclock == 'UTC'
+ - tzclock_set.diff.before.hwclock == 'local'
+
+ - name: ensure that the timezone is actually set
+ command: cmp /etc/localtime /usr/share/zoneinfo/Europe/Belgrade
+ changed_when: false
+
+ - block:
+ - name: ensure that the timezone is updated in the config file
+ command: egrep '^(TIME)?ZONE="Europe/Belgrade"' {{ timezone_config_file }}
+ when:
+ - ansible_os_family == 'RedHat'
+
+ - name: ensure that the timezone is updated in the config file
+ command: egrep 'Europe/Belgrade' {{ timezone_config_file }}
+ when:
+ - ansible_os_family == 'Debian'
+
+ - name: ensure that hwclock is updated in /etc/adjtime
+ command: grep ^UTC /etc/adjtime
+
+ - name: ensure that hwclock is updated in the config file
+ command: grep ^UTC=yes {{ hwclock_config_file }}
+ when: ansible_service_mgr != 'systemd'
+
+ - name: set timezone to Europe/Belgrade and hwclock to UTC again
+ timezone:
+ name: Europe/Belgrade
+ hwclock: UTC
+ register: tzclock_set_again
+
+ - name: set timezone and hwclock idempotency
+ assert:
+ that:
+ - not tzclock_set_again.changed
+
+ - name: set timezone to Europe/Belgrade and hwclock to UTC again (checkmode)
+ timezone:
+ name: Europe/Belgrade
+ hwclock: UTC
+ register: tzclock_set_again_checkmode
+
+ - name: set timezone and hwclock idempotency in checkmode
+ assert:
+ that:
+ - not tzclock_set_again_checkmode.changed
+
+ when:
+ - ansible_system == 'Linux'
+ - hwclock_supported
diff --git a/ansible_collections/community/general/tests/integration/targets/ufw/aliases b/ansible_collections/community/general/tests/integration/targets/ufw/aliases
new file mode 100644
index 000000000..2ef1a4133
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ufw/aliases
@@ -0,0 +1,17 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+azp/posix/vm
+skip/aix
+skip/osx
+skip/macos
+skip/freebsd
+skip/rhel8.0 # FIXME
+skip/rhel9.0 # FIXME
+skip/rhel9.1 # FIXME
+skip/docker
+needs/root
+needs/target/setup_epel
+destructive
diff --git a/ansible_collections/community/general/tests/integration/targets/ufw/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/ufw/meta/main.yml
new file mode 100644
index 000000000..2fcd152f9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ufw/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
diff --git a/ansible_collections/community/general/tests/integration/targets/ufw/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/ufw/tasks/main.yml
new file mode 100644
index 000000000..5fba2fa4d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ufw/tasks/main.yml
@@ -0,0 +1,45 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# Make sure ufw is installed
+- name: Install EPEL repository (RHEL only)
+ include_role:
+ name: setup_epel
+ when:
+ - ansible_distribution in ['RedHat', 'CentOS']
+ - ansible_distribution_major_version is version('9', '<')
+- name: Install iptables (SuSE only)
+ package:
+ name: iptables
+ become: true
+ when: ansible_os_family == 'Suse'
+- name: Install ufw
+ become: true
+ package:
+ name: ufw
+
+# Run the tests
+- block:
+ - include_tasks: run-test.yml
+ with_fileglob:
+ - "tests/*.yml"
+ become: true
+
+ # Cleanup
+ always:
+ - pause:
+ # ufw creates backups of the rule files with a timestamp; if reset is called
+ # twice in a row fast enough (so that both timestamps are taken in the same second),
+ # the second call will notice that the backup files are already there and fail.
+ # Waiting one second fixes this problem.
+ seconds: 1
+ - name: Reset ufw to factory defaults and disable
+ ufw:
+ state: reset
diff --git a/ansible_collections/community/general/tests/integration/targets/ufw/tasks/run-test.yml b/ansible_collections/community/general/tests/integration/targets/ufw/tasks/run-test.yml
new file mode 100644
index 000000000..e9e7b33f5
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ufw/tasks/run-test.yml
@@ -0,0 +1,25 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- pause:
+ # ufw creates backups of the rule files with a timestamp; if reset is called
+ # twice in a row fast enough (so that both timestamps are taken in the same second),
+ # the second call will notice that the backup files are already there and fail.
+ # Waiting one second fixes this problem.
+ seconds: 1
+- name: Reset ufw to factory defaults
+ ufw:
+ state: reset
+- name: Disable ufw
+ ufw:
+ # Some versions of ufw have a bug which won't disable on reset.
+ # That's why we explicitly deactivate here. See
+ # https://bugs.launchpad.net/ufw/+bug/1810082
+ state: disabled
+- name: "Loading tasks from {{ item }}"
+ include_tasks: "{{ item }}"
+- name: Reset to factory defaults
+ ufw:
+ state: reset
diff --git a/ansible_collections/community/general/tests/integration/targets/ufw/tasks/tests/basic.yml b/ansible_collections/community/general/tests/integration/targets/ufw/tasks/tests/basic.yml
new file mode 100644
index 000000000..8c179d7ae
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ufw/tasks/tests/basic.yml
@@ -0,0 +1,406 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# ############################################
+- name: Make sure it is off
+ ufw:
+ state: disabled
+- name: Enable (check mode)
+ ufw:
+ state: enabled
+ check_mode: true
+ register: enable_check
+- name: Enable
+ ufw:
+ state: enabled
+ register: enable
+- name: Enable (idempotency)
+ ufw:
+ state: enabled
+ register: enable_idem
+- name: Enable (idempotency, check mode)
+ ufw:
+ state: enabled
+ check_mode: true
+ register: enable_idem_check
+- assert:
+ that:
+ - enable_check is changed
+ - enable is changed
+ - enable_idem is not changed
+ - enable_idem_check is not changed
+
+# ############################################
+- name: ipv4 allow (check mode)
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: 0.0.0.0
+ check_mode: true
+ register: ipv4_allow_check
+- name: ipv4 allow
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: 0.0.0.0
+ register: ipv4_allow
+- name: ipv4 allow (idempotency)
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: 0.0.0.0
+ register: ipv4_allow_idem
+- name: ipv4 allow (idempotency, check mode)
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: 0.0.0.0
+ check_mode: true
+ register: ipv4_allow_idem_check
+- assert:
+ that:
+ - ipv4_allow_check is changed
+ - ipv4_allow is changed
+ - ipv4_allow_idem is not changed
+ - ipv4_allow_idem_check is not changed
+
+# ############################################
+- name: delete ipv4 allow (check mode)
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: 0.0.0.0
+ delete: true
+ check_mode: true
+ register: delete_ipv4_allow_check
+- name: delete ipv4 allow
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: 0.0.0.0
+ delete: true
+ register: delete_ipv4_allow
+- name: delete ipv4 allow (idempotency)
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: 0.0.0.0
+ delete: true
+ register: delete_ipv4_allow_idem
+- name: delete ipv4 allow (idempotency, check mode)
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: 0.0.0.0
+ delete: true
+ check_mode: true
+ register: delete_ipv4_allow_idem_check
+- assert:
+ that:
+ - delete_ipv4_allow_check is changed
+ - delete_ipv4_allow is changed
+ - delete_ipv4_allow_idem is not changed
+ - delete_ipv4_allow_idem_check is not changed
+
+# ############################################
+- name: ipv6 allow (check mode)
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: "::"
+ check_mode: true
+ register: ipv6_allow_check
+- name: ipv6 allow
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: "::"
+ register: ipv6_allow
+- name: ipv6 allow (idempotency)
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: "::"
+ register: ipv6_allow_idem
+- name: ipv6 allow (idempotency, check mode)
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: "::"
+ check_mode: true
+ register: ipv6_allow_idem_check
+- assert:
+ that:
+ - ipv6_allow_check is changed
+ - ipv6_allow is changed
+ - ipv6_allow_idem is not changed
+ - ipv6_allow_idem_check is not changed
+
+# ############################################
+- name: delete ipv6 allow (check mode)
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: "::"
+ delete: true
+ check_mode: true
+ register: delete_ipv6_allow_check
+- name: delete ipv6 allow
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: "::"
+ delete: true
+ register: delete_ipv6_allow
+- name: delete ipv6 allow (idempotency)
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: "::"
+ delete: true
+ register: delete_ipv6_allow_idem
+- name: delete ipv6 allow (idempotency, check mode)
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: "::"
+ delete: true
+ check_mode: true
+ register: delete_ipv6_allow_idem_check
+- assert:
+ that:
+ - delete_ipv6_allow_check is changed
+ - delete_ipv6_allow is changed
+ - delete_ipv6_allow_idem is not changed
+ - delete_ipv6_allow_idem_check is not changed
+
+
+# ############################################
+- name: ipv4 allow (check mode)
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: 0.0.0.0
+ check_mode: true
+ register: ipv4_allow_check
+- name: ipv4 allow
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: 0.0.0.0
+ register: ipv4_allow
+- name: ipv4 allow (idempotency)
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: 0.0.0.0
+ register: ipv4_allow_idem
+- name: ipv4 allow (idempotency, check mode)
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: 0.0.0.0
+ check_mode: true
+ register: ipv4_allow_idem_check
+- assert:
+ that:
+ - ipv4_allow_check is changed
+ - ipv4_allow is changed
+ - ipv4_allow_idem is not changed
+ - ipv4_allow_idem_check is not changed
+
+# ############################################
+- name: delete ipv4 allow (check mode)
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: 0.0.0.0
+ delete: true
+ check_mode: true
+ register: delete_ipv4_allow_check
+- name: delete ipv4 allow
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: 0.0.0.0
+ delete: true
+ register: delete_ipv4_allow
+- name: delete ipv4 allow (idempotency)
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: 0.0.0.0
+ delete: true
+ register: delete_ipv4_allow_idem
+- name: delete ipv4 allow (idempotency, check mode)
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: 0.0.0.0
+ delete: true
+ check_mode: true
+ register: delete_ipv4_allow_idem_check
+- assert:
+ that:
+ - delete_ipv4_allow_check is changed
+ - delete_ipv4_allow is changed
+ - delete_ipv4_allow_idem is not changed
+ - delete_ipv4_allow_idem_check is not changed
+
+# ############################################
+- name: ipv6 allow (check mode)
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: "::"
+ check_mode: true
+ register: ipv6_allow_check
+- name: ipv6 allow
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: "::"
+ register: ipv6_allow
+- name: ipv6 allow (idempotency)
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: "::"
+ register: ipv6_allow_idem
+- name: ipv6 allow (idempotency, check mode)
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: "::"
+ check_mode: true
+ register: ipv6_allow_idem_check
+- assert:
+ that:
+ - ipv6_allow_check is changed
+ - ipv6_allow is changed
+ - ipv6_allow_idem is not changed
+ - ipv6_allow_idem_check is not changed
+
+# ############################################
+- name: delete ipv6 allow (check mode)
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: "::"
+ delete: true
+ check_mode: true
+ register: delete_ipv6_allow_check
+- name: delete ipv6 allow
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: "::"
+ delete: true
+ register: delete_ipv6_allow
+- name: delete ipv6 allow (idempotency)
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: "::"
+ delete: true
+ register: delete_ipv6_allow_idem
+- name: delete ipv6 allow (idempotency, check mode)
+ ufw:
+ rule: allow
+ port: 23
+ to_ip: "::"
+ delete: true
+ check_mode: true
+ register: delete_ipv6_allow_idem_check
+- assert:
+ that:
+ - delete_ipv6_allow_check is changed
+ - delete_ipv6_allow is changed
+ - delete_ipv6_allow_idem is not changed
+ - delete_ipv6_allow_idem_check is not changed
+
+# ############################################
+- name: Reload ufw
+ ufw:
+ state: reloaded
+ register: reload
+- name: Reload ufw (check mode)
+ ufw:
+ state: reloaded
+ check_mode: true
+ register: reload_check
+- assert:
+ that:
+ - reload is changed
+ - reload_check is changed
+
+# ############################################
+- name: Disable (check mode)
+ ufw:
+ state: disabled
+ check_mode: true
+ register: disable_check
+- name: Disable
+ ufw:
+ state: disabled
+ register: disable
+- name: Disable (idempotency)
+ ufw:
+ state: disabled
+ register: disable_idem
+- name: Disable (idempotency, check mode)
+ ufw:
+ state: disabled
+ check_mode: true
+ register: disable_idem_check
+- assert:
+ that:
+ - disable_check is changed
+ - disable is changed
+ - disable_idem is not changed
+ - disable_idem_check is not changed
+
+# ############################################
+- name: Re-enable
+ ufw:
+ state: enabled
+- name: Reset (check mode)
+ ufw:
+ state: reset
+ check_mode: true
+ register: reset_check
+- pause:
+ # Should not be needed, but since ufw is ignoring --dry-run for reset
+ # (https://bugs.launchpad.net/ufw/+bug/1810082) we have to wait here as well.
+ seconds: 1
+- name: Reset
+ ufw:
+ state: reset
+ register: reset
+- pause:
+ # ufw creates backups of the rule files with a timestamp; if reset is called
+ # twice in a row fast enough (so that both timestamps are taken in the same second),
+ # the second call will notice that the backup files are already there and fail.
+ # Waiting one second fixes this problem.
+ seconds: 1
+- name: Reset (idempotency)
+ ufw:
+ state: reset
+ register: reset_idem
+- pause:
+ # Should not be needed, but since ufw is ignoring --dry-run for reset
+ # (https://bugs.launchpad.net/ufw/+bug/1810082) we have to wait here as well.
+ seconds: 1
+- name: Reset (idempotency, check mode)
+ ufw:
+ state: reset
+ check_mode: true
+ register: reset_idem_check
+- assert:
+ that:
+ - reset_check is changed
+ - reset is changed
+ - reset_idem is changed
+ - reset_idem_check is changed
diff --git a/ansible_collections/community/general/tests/integration/targets/ufw/tasks/tests/global-state.yml b/ansible_collections/community/general/tests/integration/targets/ufw/tasks/tests/global-state.yml
new file mode 100644
index 000000000..f5f100751
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ufw/tasks/tests/global-state.yml
@@ -0,0 +1,154 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Enable ufw
+ ufw:
+ state: enabled
+
+# ############################################
+- name: Make sure logging is off
+ ufw:
+ logging: false
+- name: Logging (check mode)
+ ufw:
+ logging: true
+ check_mode: true
+ register: logging_check
+- name: Logging
+ ufw:
+ logging: true
+ register: logging
+- name: Get logging
+ shell: |
+ ufw status verbose | grep "^Logging:"
+ register: ufw_logging
+ environment:
+ LC_ALL: C
+- name: Logging (idempotency)
+ ufw:
+ logging: true
+ register: logging_idem
+- name: Logging (idempotency, check mode)
+ ufw:
+ logging: true
+ check_mode: true
+ register: logging_idem_check
+- name: Logging (change, check mode)
+ ufw:
+ logging: full
+ check_mode: true
+ register: logging_change_check
+- name: Logging (change)
+ ufw:
+ logging: full
+ register: logging_change
+- name: Get logging
+ shell: |
+ ufw status verbose | grep "^Logging:"
+ register: ufw_logging_change
+ environment:
+ LC_ALL: C
+- assert:
+ that:
+ - logging_check is changed
+ - logging is changed
+ - "ufw_logging.stdout == 'Logging: on (low)'"
+ - logging_idem is not changed
+ - logging_idem_check is not changed
+ - "ufw_logging_change.stdout == 'Logging: on (full)'"
+ - logging_change is changed
+ - logging_change_check is changed
+
+# ############################################
+- name: Default (check mode)
+ ufw:
+ default: reject
+ direction: incoming
+ check_mode: true
+ register: default_check
+- name: Default
+ ufw:
+ default: reject
+ direction: incoming
+ register: default
+- name: Get defaults
+ shell: |
+ ufw status verbose | grep "^Default:"
+ register: ufw_defaults
+ environment:
+ LC_ALL: C
+- name: Default (idempotency)
+ ufw:
+ default: reject
+ direction: incoming
+ register: default_idem
+- name: Default (idempotency, check mode)
+ ufw:
+ default: reject
+ direction: incoming
+ check_mode: true
+ register: default_idem_check
+- name: Default (change, check mode)
+ ufw:
+ default: allow
+ direction: incoming
+ check_mode: true
+ register: default_change_check
+- name: Default (change)
+ ufw:
+ default: allow
+ direction: incoming
+ register: default_change
+- name: Get defaults
+ shell: |
+ ufw status verbose | grep "^Default:"
+ register: ufw_defaults_change
+ environment:
+ LC_ALL: C
+- name: Default (change again)
+ ufw:
+ default: deny
+ direction: incoming
+ register: default_change_2
+- name: Default (change incoming implicitly, check mode)
+ ufw:
+ default: allow
+ check_mode: true
+ register: default_change_implicit_check
+- name: Default (change incoming implicitly)
+ ufw:
+ default: allow
+ register: default_change_implicit
+- name: Get defaults
+ shell: |
+ ufw status verbose | grep "^Default:"
+ register: ufw_defaults_change_implicit
+ environment:
+ LC_ALL: C
+- name: Default (change incoming implicitly, idempotent, check mode)
+ ufw:
+ default: allow
+ check_mode: true
+ register: default_change_implicit_idem_check
+- name: Default (change incoming implicitly, idempotent)
+ ufw:
+ default: allow
+ register: default_change_implicit_idem
+- assert:
+ that:
+ - default_check is changed
+ - default is changed
+ - "'reject (incoming)' in ufw_defaults.stdout"
+ - default_idem is not changed
+ - default_idem_check is not changed
+ - default_change_check is changed
+ - default_change is changed
+ - "'allow (incoming)' in ufw_defaults_change.stdout"
+ - default_change_2 is changed
+ - default_change_implicit_check is changed
+ - default_change_implicit is changed
+ - default_change_implicit_idem_check is not changed
+ - default_change_implicit_idem is not changed
+ - "'allow (incoming)' in ufw_defaults_change_implicit.stdout"
diff --git a/ansible_collections/community/general/tests/integration/targets/ufw/tasks/tests/insert_relative_to.yml b/ansible_collections/community/general/tests/integration/targets/ufw/tasks/tests/insert_relative_to.yml
new file mode 100644
index 000000000..67328a0e3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ufw/tasks/tests/insert_relative_to.yml
@@ -0,0 +1,84 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Enable
+ ufw:
+ state: enabled
+ register: enable
+
+# ## CREATE RULES ############################
+- name: ipv4
+ ufw:
+ rule: deny
+ port: 22
+ to_ip: 0.0.0.0
+- name: ipv4
+ ufw:
+ rule: deny
+ port: 23
+ to_ip: 0.0.0.0
+
+- name: ipv6
+ ufw:
+ rule: deny
+ port: 122
+ to_ip: "::"
+- name: ipv6
+ ufw:
+ rule: deny
+ port: 123
+ to_ip: "::"
+
+- name: first-ipv4
+ ufw:
+ rule: deny
+ port: 10
+ to_ip: 0.0.0.0
+ insert: 0
+ insert_relative_to: first-ipv4
+- name: last-ipv4
+ ufw:
+ rule: deny
+ port: 11
+ to_ip: 0.0.0.0
+ insert: 0
+ insert_relative_to: last-ipv4
+
+- name: first-ipv6
+ ufw:
+ rule: deny
+ port: 110
+ to_ip: "::"
+ insert: 0
+ insert_relative_to: first-ipv6
+- name: last-ipv6
+ ufw:
+ rule: deny
+ port: 111
+ to_ip: "::"
+ insert: 0
+ insert_relative_to: last-ipv6
+
+# ## CHECK RESULT ############################
+- name: Get rules
+ shell: |
+ ufw status | grep DENY | cut -f 1-2 -d ' ' | grep -E "^(0\.0\.0\.0|::) [123]+"
+ # Note that there was also a rule "ff02::fb mDNS" on at least one CI run;
+ # to ignore these, the extra filtering (grepping for DENY and the regex) makes
+ # sure to remove all rules not added here.
+ register: ufw_status
+- assert:
+ that:
+ - ufw_status.stdout_lines == expected_stdout
+ vars:
+ expected_stdout:
+ - "0.0.0.0 10"
+ - "0.0.0.0 22"
+ - "0.0.0.0 11"
+ - "0.0.0.0 23"
+ - ":: 110"
+ - ":: 122"
+ - ":: 111"
+ - ":: 123"
diff --git a/ansible_collections/community/general/tests/integration/targets/ufw/tasks/tests/interface.yml b/ansible_collections/community/general/tests/integration/targets/ufw/tasks/tests/interface.yml
new file mode 100644
index 000000000..1ec3568aa
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/ufw/tasks/tests/interface.yml
@@ -0,0 +1,86 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Enable
+ ufw:
+ state: enabled
+
+- name: Route with interface in and out
+ ufw:
+ rule: allow
+ route: true
+ interface_in: foo
+ interface_out: bar
+ proto: tcp
+ from_ip: 1.1.1.1
+ to_ip: 8.8.8.8
+ from_port: 1111
+ to_port: 2222
+
+- name: Route with interface in
+ ufw:
+ rule: allow
+ route: true
+ interface_in: foo
+ proto: tcp
+ from_ip: 1.1.1.1
+ from_port: 1111
+
+- name: Route with interface out
+ ufw:
+ rule: allow
+ route: true
+ interface_out: bar
+ proto: tcp
+ from_ip: 1.1.1.1
+ from_port: 1111
+
+- name: Non-route with interface in
+ ufw:
+ rule: allow
+ interface_in: foo
+ proto: tcp
+ from_ip: 1.1.1.1
+ from_port: 3333
+
+- name: Non-route with interface out
+ ufw:
+ rule: allow
+ interface_out: bar
+ proto: tcp
+ from_ip: 1.1.1.1
+ from_port: 4444
+
+- name: Check result
+ shell: ufw status |grep -E '(ALLOW|DENY|REJECT|LIMIT)' |sed -E 's/[ \t]+/ /g'
+ register: ufw_status
+
+- assert:
+ that:
+ - '"8.8.8.8 2222/tcp on bar ALLOW FWD 1.1.1.1 1111/tcp on foo " in stdout'
+ - '"Anywhere ALLOW FWD 1.1.1.1 1111/tcp on foo " in stdout'
+ - '"Anywhere on bar ALLOW FWD 1.1.1.1 1111/tcp " in stdout'
+ - '"Anywhere on foo ALLOW 1.1.1.1 3333/tcp " in stdout'
+ - '"Anywhere ALLOW OUT 1.1.1.1 4444/tcp on bar " in stdout'
+ vars:
+ stdout: '{{ ufw_status.stdout_lines }}'
+
+- name: Non-route with interface_in and interface_out
+ ufw:
+ rule: allow
+ interface_in: foo
+ interface_out: bar
+ proto: tcp
+ from_ip: 1.1.1.1
+ from_port: 1111
+ to_ip: 8.8.8.8
+ to_port: 2222
+ ignore_errors: true
+ register: ufw_non_route_iface
+
+- assert:
+ that:
+ - ufw_non_route_iface is failed
+ - '"Only route rules" in ufw_non_route_iface.msg'
diff --git a/ansible_collections/community/general/tests/integration/targets/wakeonlan/aliases b/ansible_collections/community/general/tests/integration/targets/wakeonlan/aliases
new file mode 100644
index 000000000..dadd9f37a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/wakeonlan/aliases
@@ -0,0 +1,6 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+skip/aix
diff --git a/ansible_collections/community/general/tests/integration/targets/wakeonlan/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/wakeonlan/tasks/main.yml
new file mode 100644
index 000000000..059748031
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/wakeonlan/tasks/main.yml
@@ -0,0 +1,58 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Send a magic Wake-on-LAN packet to 00:00:5E:00:53:66
+ wakeonlan:
+ mac: 00:00:5E:00:53:66
+ broadcast: 192.0.2.255
+
+- name: Send a magic Wake-on-LAN packet on port 9 to 00-00-5E-00-53-66
+ wakeonlan:
+ mac: 00-00-5E-00-53-66
+ port: 9
+
+- name: Provide an incorrect MAC length
+ wakeonlan:
+ mac: 00-00-5E-00-53-66-AB
+ port: 9
+ ignore_errors: true
+ register: incorrect_mac_length
+
+- name: Check error message
+ assert:
+ that:
+ - incorrect_mac_length is failed
+ - incorrect_mac_length.msg is search('Incorrect MAC address length')
+
+- name: Provide an incorrect MAC format
+ wakeonlan:
+ mac: ZW-YX-WV-UT-SR-QP
+ port: 9
+ ignore_errors: true
+ register: incorrect_mac_format
+
+- name: Check error message
+ assert:
+ that:
+ - incorrect_mac_format is failed
+ - incorrect_mac_format.msg is search('Incorrect MAC address format')
+
+- name: Cause a socket error
+ wakeonlan:
+ mac: 00-00-5E-00-53-66
+ broadcast: 345.567.678.890
+ ignore_errors: true
+ register: incorrect_broadcast_address
+
+- name: Check error message
+ assert:
+ that:
+ - incorrect_broadcast_address is failed
+ - incorrect_broadcast_address.msg is search('not known|Name does not resolve')
diff --git a/ansible_collections/community/general/tests/integration/targets/xattr/aliases b/ansible_collections/community/general/tests/integration/targets/xattr/aliases
new file mode 100644
index 000000000..5cd9c012e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xattr/aliases
@@ -0,0 +1,12 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/2
+azp/posix/vm
+skip/aix
+skip/docker
+skip/freebsd
+skip/osx
+skip/macos
+destructive
diff --git a/ansible_collections/community/general/tests/integration/targets/xattr/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/xattr/defaults/main.yml
new file mode 100644
index 000000000..29c6d5d15
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xattr/defaults/main.yml
@@ -0,0 +1,6 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+test_file: "{{ remote_tmp_dir }}/foo.txt"
diff --git a/ansible_collections/community/general/tests/integration/targets/xattr/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/xattr/meta/main.yml
new file mode 100644
index 000000000..ca1915e05
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xattr/meta/main.yml
@@ -0,0 +1,8 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/xattr/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/xattr/tasks/main.yml
new file mode 100644
index 000000000..6c1c02b3e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xattr/tasks/main.yml
@@ -0,0 +1,21 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Setup
+ include_tasks: setup.yml
+
+- name: Check availability of xattr support
+ command: setfattr -n user.foo {{ test_file }}
+ ignore_errors: true
+ register: xattr
+
+- name: Test
+ include_tasks: test.yml
+ when: xattr is not failed
diff --git a/ansible_collections/community/general/tests/integration/targets/xattr/tasks/setup.yml b/ansible_collections/community/general/tests/integration/targets/xattr/tasks/setup.yml
new file mode 100644
index 000000000..0eda72d8c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xattr/tasks/setup.yml
@@ -0,0 +1,14 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install
+ package:
+ name: attr
+ state: present
+
+- name: Create file
+ file:
+ path: "{{ test_file }}"
+ state: touch
diff --git a/ansible_collections/community/general/tests/integration/targets/xattr/tasks/test.yml b/ansible_collections/community/general/tests/integration/targets/xattr/tasks/test.yml
new file mode 100644
index 000000000..7fe852d77
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xattr/tasks/test.yml
@@ -0,0 +1,72 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Set attributes
+ xattr:
+ path: "{{ test_file }}"
+ key: user.foo
+ value: bar
+ register: xattr_set_result
+
+- name: Get attributes
+ xattr:
+ path: "{{ test_file }}"
+ register: xattr_get_all_result
+
+- name: Get specific attribute
+ xattr:
+ path: "{{ test_file }}"
+ key: foo
+ register: xattr_get_specific_result
+
+- assert:
+ that:
+ - "xattr_set_result.changed"
+ - "xattr_get_all_result['xattr']['user.foo'] == 'bar'"
+ - "not xattr_get_all_result.changed"
+ - "xattr_get_specific_result['xattr']['user.foo'] == 'bar'"
+ - "not xattr_get_specific_result.changed"
+
+- name: Set attribute again
+ xattr:
+ path: "{{ test_file }}"
+ namespace: user
+ key: foo
+ value: bar
+ register: xattr_set_again_result
+
+- assert:
+ that:
+ - "not xattr_set_again_result.changed"
+
+- name: Unset attribute
+ xattr:
+ path: "{{ test_file }}"
+ key: foo
+ state: absent
+ register: xattr_unset_result
+
+- name: Get attributes
+ xattr:
+ path: "{{ test_file }}"
+ register: xattr_get_after_unset_result
+
+- assert:
+ that:
+ - "xattr_unset_result.changed"
+ - "xattr_get_after_unset_result['xattr'] == {}"
+ - "not xattr_get_after_unset_result.changed"
+
+- name: Unset attribute again
+ xattr:
+ path: "{{ test_file }}"
+ namespace: user
+ key: foo
+ state: absent
+ register: xattr_unset_result
+
+- assert:
+ that:
+ - "not xattr_set_again_result.changed"
diff --git a/ansible_collections/community/general/tests/integration/targets/xfs_quota/aliases b/ansible_collections/community/general/tests/integration/targets/xfs_quota/aliases
new file mode 100644
index 000000000..d9f5f0fa3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xfs_quota/aliases
@@ -0,0 +1,12 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+azp/posix/vm
+needs/privileged
+needs/root
+skip/aix
+skip/osx
+skip/macos
+skip/freebsd
diff --git a/ansible_collections/community/general/tests/integration/targets/xfs_quota/defaults/main.yml b/ansible_collections/community/general/tests/integration/targets/xfs_quota/defaults/main.yml
new file mode 100644
index 000000000..b209f949a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xfs_quota/defaults/main.yml
@@ -0,0 +1,46 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+uquota_default_bsoft: 1m
+uquota_default_bhard: 2m
+uquota_default_isoft: 100
+uquota_default_ihard: 200
+uquota_default_rtbsoft: 1m
+uquota_default_rtbhard: 2m
+
+uquota_user_bsoft: 2m
+uquota_user_bhard: 3m
+uquota_user_isoft: 300
+uquota_user_ihard: 400
+uquota_user_rtbsoft: 3m
+uquota_user_rtbhard: 4m
+
+gquota_default_bsoft: 1m
+gquota_default_bhard: 2m
+gquota_default_isoft: 100
+gquota_default_ihard: 200
+gquota_default_rtbsoft: 1m
+gquota_default_rtbhard: 2m
+
+gquota_group_bsoft: 2m
+gquota_group_bhard: 3m
+gquota_group_isoft: 300
+gquota_group_ihard: 400
+gquota_group_rtbsoft: 3m
+gquota_group_rtbhard: 4m
+
+pquota_default_bsoft: 1m
+pquota_default_bhard: 2m
+pquota_default_isoft: 100
+pquota_default_ihard: 200
+pquota_default_rtbsoft: 1m
+pquota_default_rtbhard: 2m
+
+pquota_project_bsoft: 2m
+pquota_project_bhard: 3m
+pquota_project_isoft: 300
+pquota_project_ihard: 400
+pquota_project_rtbsoft: 3m
+pquota_project_rtbhard: 4m
diff --git a/ansible_collections/community/general/tests/integration/targets/xfs_quota/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/xfs_quota/meta/main.yml
new file mode 100644
index 000000000..982de6eb0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xfs_quota/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/xfs_quota/tasks/gquota.yml b/ansible_collections/community/general/tests/integration/targets/xfs_quota/tasks/gquota.yml
new file mode 100644
index 000000000..caca1d341
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xfs_quota/tasks/gquota.yml
@@ -0,0 +1,147 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create disk image
+ command: 'dd if=/dev/zero of={{ remote_tmp_dir }}/img-gquota bs=1M count=400
+
+ '
+- name: Create XFS filesystem
+ filesystem:
+ dev: '{{ remote_tmp_dir }}/img-gquota'
+ fstype: xfs
+- block:
+ - name: Mount filesystem
+ become: true
+ ansible.posix.mount:
+ fstab: '{{ remote_tmp_dir }}/fstab'
+ src: '{{ remote_tmp_dir }}/img-gquota'
+ path: '{{ remote_tmp_dir }}/gquota'
+ fstype: xfs
+ opts: gquota
+ state: mounted
+ - name: Apply default group limits
+ xfs_quota:
+ bsoft: '{{ gquota_default_bsoft }}'
+ bhard: '{{ gquota_default_bhard }}'
+ isoft: '{{ gquota_default_isoft }}'
+ ihard: '{{ gquota_default_ihard }}'
+ mountpoint: '{{ remote_tmp_dir }}/gquota'
+ rtbsoft: '{{ gquota_default_rtbsoft }}'
+ rtbhard: '{{ gquota_default_rtbhard }}'
+ type: group
+ become: true
+ register: test_gquota_default_before
+ - name: Assert default group limits results
+ assert:
+ that:
+ - test_gquota_default_before.changed
+ - test_gquota_default_before.bsoft == gquota_default_bsoft|human_to_bytes
+ - test_gquota_default_before.bhard == gquota_default_bhard|human_to_bytes
+ - test_gquota_default_before.isoft == gquota_default_isoft
+ - test_gquota_default_before.ihard == gquota_default_ihard
+ - test_gquota_default_before.rtbsoft == gquota_default_rtbsoft|human_to_bytes
+ - test_gquota_default_before.rtbhard == gquota_default_rtbhard|human_to_bytes
+ - name: Apply group limits
+ xfs_quota:
+ bsoft: '{{ gquota_group_bsoft }}'
+ bhard: '{{ gquota_group_bhard }}'
+ isoft: '{{ gquota_group_isoft }}'
+ ihard: '{{ gquota_group_ihard }}'
+ mountpoint: '{{ remote_tmp_dir }}/gquota'
+ name: xfsquotauser
+ rtbsoft: '{{ gquota_group_rtbsoft }}'
+ rtbhard: '{{ gquota_group_rtbhard }}'
+ type: group
+ become: true
+ register: test_gquota_group_before
+ - name: Assert group limits results for xfsquotauser
+ assert:
+ that:
+ - test_gquota_group_before.changed
+ - test_gquota_group_before.bsoft == gquota_group_bsoft|human_to_bytes
+ - test_gquota_group_before.bhard == gquota_group_bhard|human_to_bytes
+ - test_gquota_group_before.isoft == gquota_group_isoft
+ - test_gquota_group_before.ihard == gquota_group_ihard
+ - test_gquota_group_before.rtbsoft == gquota_group_rtbsoft|human_to_bytes
+ - test_gquota_group_before.rtbhard == gquota_group_rtbhard|human_to_bytes
+ - name: Re-apply default group limits
+ xfs_quota:
+ bsoft: '{{ gquota_default_bsoft }}'
+ bhard: '{{ gquota_default_bhard }}'
+ isoft: '{{ gquota_default_isoft }}'
+ ihard: '{{ gquota_default_ihard }}'
+ mountpoint: '{{ remote_tmp_dir }}/gquota'
+ rtbsoft: '{{ gquota_default_rtbsoft }}'
+ rtbhard: '{{ gquota_default_rtbhard }}'
+ type: group
+ become: true
+ register: test_gquota_default_after
+ - name: Assert default group limits results after re-apply
+ assert:
+ that:
+ - not test_gquota_default_after.changed
+ - name: Re-apply group limits
+ xfs_quota:
+ bsoft: '{{ gquota_group_bsoft }}'
+ bhard: '{{ gquota_group_bhard }}'
+ isoft: '{{ gquota_group_isoft }}'
+ ihard: '{{ gquota_group_ihard }}'
+ mountpoint: '{{ remote_tmp_dir }}/gquota'
+ name: xfsquotauser
+ rtbsoft: '{{ gquota_group_rtbsoft }}'
+ rtbhard: '{{ gquota_group_rtbhard }}'
+ type: group
+ become: true
+ register: test_gquota_group_after
+ - name: Assert group limits results for xfsquotauser after re-apply
+ assert:
+ that:
+ - not test_gquota_group_after.changed
+ - name: Reset default group limits
+ xfs_quota:
+ mountpoint: '{{ remote_tmp_dir }}/gquota'
+ state: absent
+ type: group
+ become: true
+ register: test_reset_gquota_default
+ - name: Assert reset of default group limits results
+ assert:
+ that:
+ - test_reset_gquota_default.changed
+ - test_reset_gquota_default.bsoft == 0
+ - test_reset_gquota_default.bhard == 0
+ - test_reset_gquota_default.isoft == 0
+ - test_reset_gquota_default.ihard == 0
+ - test_reset_gquota_default.rtbsoft == 0
+ - test_reset_gquota_default.rtbhard == 0
+ - name: Reset group limits for xfsquotauser
+ xfs_quota:
+ mountpoint: '{{ remote_tmp_dir }}/gquota'
+ name: xfsquotauser
+ state: absent
+ type: group
+ become: true
+ register: test_reset_gquota_group
+ - name: Assert reset of default group limits results
+ assert:
+ that:
+ - test_reset_gquota_group.changed
+ - test_reset_gquota_group.bsoft == 0
+ - test_reset_gquota_group.bhard == 0
+ - test_reset_gquota_group.isoft == 0
+ - test_reset_gquota_group.ihard == 0
+ - test_reset_gquota_group.rtbsoft == 0
+ - test_reset_gquota_group.rtbhard == 0
+ always:
+ - name: Unmount filesystem
+ become: true
+ ansible.posix.mount:
+ fstab: '{{ remote_tmp_dir }}/fstab'
+ path: '{{ remote_tmp_dir }}/gquota'
+ state: unmounted
+ - name: Remove disk image
+ file:
+ path: '{{ remote_tmp_dir }}/img-gquota'
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/xfs_quota/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/xfs_quota/tasks/main.yml
new file mode 100644
index 000000000..8977cf9ec
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xfs_quota/tasks/main.yml
@@ -0,0 +1,37 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: setup Alpine
+ when: ansible_distribution == 'Alpine'
+ package:
+ name:
+ - xfsprogs
+ - xfsprogs-extra
+ - mount
+ - umount
+ state: latest
+
+- block:
+ - name: Create test user
+ user:
+ name: xfsquotauser
+ state: present
+ become: true
+
+ - include_tasks: uquota.yml
+ - include_tasks: gquota.yml
+ - include_tasks: pquota.yml
+
+ always:
+ - name: cleanup test user
+ user:
+ name: xfsquotauser
+ state: absent
+ become: true
diff --git a/ansible_collections/community/general/tests/integration/targets/xfs_quota/tasks/pquota.yml b/ansible_collections/community/general/tests/integration/targets/xfs_quota/tasks/pquota.yml
new file mode 100644
index 000000000..db364ffd5
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xfs_quota/tasks/pquota.yml
@@ -0,0 +1,184 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create disk image
+ command: 'dd if=/dev/zero of={{ remote_tmp_dir }}/img-pquota bs=1M count=400
+
+ '
+- name: Create XFS filesystem
+ filesystem:
+ dev: '{{ remote_tmp_dir }}/img-pquota'
+ fstype: xfs
+- name: Create xfs related files
+ file:
+ path: /etc/{{ item }}
+ state: touch
+ become: true
+ loop:
+ - projid
+ - projects
+- name: Add test xfs quota project id
+ lineinfile:
+ path: /etc/projid
+ line: xft_quotaval:99999
+ state: present
+ become: true
+- name: Add test xfs quota project path
+ lineinfile:
+ path: /etc/projects
+ line: 99999:{{ remote_tmp_dir }}/pquota/test
+ state: present
+ become: true
+- block:
+ - name: Mount filesystem
+ become: true
+ ansible.posix.mount:
+ fstab: '{{ remote_tmp_dir }}/fstab'
+ src: '{{ remote_tmp_dir }}/img-pquota'
+ path: '{{ remote_tmp_dir }}/pquota'
+ fstype: xfs
+ opts: pquota
+ state: mounted
+ - name: Create test directory
+ file:
+ path: '{{ remote_tmp_dir }}/pquota/test'
+ state: directory
+ become: true
+ - name: Apply default project limits
+ xfs_quota:
+ bsoft: '{{ pquota_default_bsoft }}'
+ bhard: '{{ pquota_default_bhard }}'
+ isoft: '{{ pquota_default_isoft }}'
+ ihard: '{{ pquota_default_ihard }}'
+ mountpoint: '{{ remote_tmp_dir }}/pquota'
+ rtbsoft: '{{ pquota_default_rtbsoft }}'
+ rtbhard: '{{ pquota_default_rtbhard }}'
+ type: project
+ become: true
+ register: test_pquota_default_before
+ - name: Assert default project limits results
+ assert:
+ that:
+ - test_pquota_default_before.changed
+ - test_pquota_default_before.bsoft == pquota_default_bsoft|human_to_bytes
+ - test_pquota_default_before.bhard == pquota_default_bhard|human_to_bytes
+ - test_pquota_default_before.isoft == pquota_default_isoft
+ - test_pquota_default_before.ihard == pquota_default_ihard
+ - test_pquota_default_before.rtbsoft == pquota_default_rtbsoft|human_to_bytes
+ - test_pquota_default_before.rtbhard == pquota_default_rtbhard|human_to_bytes
+ - name: Apply project limits
+ xfs_quota:
+ bsoft: '{{ pquota_project_bsoft }}'
+ bhard: '{{ pquota_project_bhard }}'
+ isoft: '{{ pquota_project_isoft }}'
+ ihard: '{{ pquota_project_ihard }}'
+ mountpoint: '{{ remote_tmp_dir }}/pquota'
+ name: xft_quotaval
+ rtbsoft: '{{ pquota_project_rtbsoft }}'
+ rtbhard: '{{ pquota_project_rtbhard }}'
+ type: project
+ become: true
+ register: test_pquota_project_before
+ - name: Assert project limits results for xft_quotaval
+ assert:
+ that:
+ - test_pquota_project_before.changed
+ - test_pquota_project_before.bsoft == pquota_project_bsoft|human_to_bytes
+ - test_pquota_project_before.bhard == pquota_project_bhard|human_to_bytes
+ - test_pquota_project_before.isoft == pquota_project_isoft
+ - test_pquota_project_before.ihard == pquota_project_ihard
+ - test_pquota_project_before.rtbsoft == pquota_project_rtbsoft|human_to_bytes
+ - test_pquota_project_before.rtbhard == pquota_project_rtbhard|human_to_bytes
+ - name: Re-apply default project limits
+ xfs_quota:
+ bsoft: '{{ pquota_default_bsoft }}'
+ bhard: '{{ pquota_default_bhard }}'
+ isoft: '{{ pquota_default_isoft }}'
+ ihard: '{{ pquota_default_ihard }}'
+ mountpoint: '{{ remote_tmp_dir }}/pquota'
+ rtbsoft: '{{ pquota_default_rtbsoft }}'
+ rtbhard: '{{ pquota_default_rtbhard }}'
+ type: project
+ become: true
+ register: test_pquota_default_after
+ - name: Assert default project limits results after re-apply
+ assert:
+ that:
+ - not test_pquota_default_after.changed
+ - name: Re-apply project limits
+ xfs_quota:
+ bsoft: '{{ pquota_project_bsoft }}'
+ bhard: '{{ pquota_project_bhard }}'
+ isoft: '{{ pquota_project_isoft }}'
+ ihard: '{{ pquota_project_ihard }}'
+ mountpoint: '{{ remote_tmp_dir }}/pquota'
+ name: xft_quotaval
+ rtbsoft: '{{ pquota_project_rtbsoft }}'
+ rtbhard: '{{ pquota_project_rtbhard }}'
+ type: project
+ become: true
+ register: test_pquota_project_after
+ - name: Assert project limits results for xft_quotaval after re-apply
+ assert:
+ that:
+ - test_pquota_project_after is not changed
+ - name: Reset default project limits
+ xfs_quota:
+ mountpoint: '{{ remote_tmp_dir }}/pquota'
+ state: absent
+ type: project
+ become: true
+ register: test_reset_pquota_default
+ - name: Assert reset of default projecy limits results
+ assert:
+ that:
+ - test_reset_pquota_default.changed
+ - test_reset_pquota_default.bsoft == 0
+ - test_reset_pquota_default.bhard == 0
+ - test_reset_pquota_default.isoft == 0
+ - test_reset_pquota_default.ihard == 0
+ - test_reset_pquota_default.rtbsoft == 0
+ - test_reset_pquota_default.rtbhard == 0
+ - name: Reset project limits for xft_quotaval
+ xfs_quota:
+ mountpoint: '{{ remote_tmp_dir }}/pquota'
+ name: xft_quotaval
+ state: absent
+ type: project
+ become: true
+ register: test_reset_pquota_project
+ - name: Assert reset of project limits results for xft_quotaval
+ assert:
+ that:
+ - test_reset_pquota_project.changed
+ - test_reset_pquota_project.bsoft == 0
+ - test_reset_pquota_project.bhard == 0
+ - test_reset_pquota_project.isoft == 0
+ - test_reset_pquota_project.ihard == 0
+ - test_reset_pquota_project.rtbsoft == 0
+ - test_reset_pquota_project.rtbhard == 0
+ always:
+ - name: Unmount filesystem
+ become: true
+ ansible.posix.mount:
+ fstab: '{{ remote_tmp_dir }}/fstab'
+ path: '{{ remote_tmp_dir }}/pquota'
+ state: unmounted
+ - name: Remove disk image
+ file:
+ path: '{{ remote_tmp_dir }}/img-pquota'
+ state: absent
+ - name: Remove xfs quota project id
+ lineinfile:
+ path: /etc/projid
+ regexp: ^xft_quotaval:99999$
+ state: absent
+ become: true
+ - name: Remove xfs quota project path
+ lineinfile:
+ path: /etc/projects
+ regexp: ^99999:.*$
+ state: absent
+ become: true
diff --git a/ansible_collections/community/general/tests/integration/targets/xfs_quota/tasks/uquota.yml b/ansible_collections/community/general/tests/integration/targets/xfs_quota/tasks/uquota.yml
new file mode 100644
index 000000000..36a7eff76
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xfs_quota/tasks/uquota.yml
@@ -0,0 +1,147 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Create disk image
+ command: 'dd if=/dev/zero of={{ remote_tmp_dir }}/img-uquota bs=1M count=400
+
+ '
+- name: Create XFS filesystem
+ filesystem:
+ dev: '{{ remote_tmp_dir }}/img-uquota'
+ fstype: xfs
+- block:
+ - name: Mount filesystem
+ become: true
+ ansible.posix.mount:
+ fstab: '{{ remote_tmp_dir }}/fstab'
+ src: '{{ remote_tmp_dir }}/img-uquota'
+ path: '{{ remote_tmp_dir }}/uquota'
+ fstype: xfs
+ opts: uquota
+ state: mounted
+ - name: Apply default user limits
+ xfs_quota:
+ bsoft: '{{ uquota_default_bsoft }}'
+ bhard: '{{ uquota_default_bhard }}'
+ isoft: '{{ uquota_default_isoft }}'
+ ihard: '{{ uquota_default_ihard }}'
+ mountpoint: '{{ remote_tmp_dir }}/uquota'
+ rtbsoft: '{{ uquota_default_rtbsoft }}'
+ rtbhard: '{{ uquota_default_rtbhard }}'
+ type: user
+ become: true
+ register: test_uquota_default_before
+ - name: Assert default user limits results
+ assert:
+ that:
+ - test_uquota_default_before.changed
+ - test_uquota_default_before.bsoft == uquota_default_bsoft|human_to_bytes
+ - test_uquota_default_before.bhard == uquota_default_bhard|human_to_bytes
+ - test_uquota_default_before.isoft == uquota_default_isoft
+ - test_uquota_default_before.ihard == uquota_default_ihard
+ - test_uquota_default_before.rtbsoft == uquota_default_rtbsoft|human_to_bytes
+ - test_uquota_default_before.rtbhard == uquota_default_rtbhard|human_to_bytes
+ - name: Apply user limits
+ xfs_quota:
+ bsoft: '{{ uquota_user_bsoft }}'
+ bhard: '{{ uquota_user_bhard }}'
+ isoft: '{{ uquota_user_isoft }}'
+ ihard: '{{ uquota_user_ihard }}'
+ mountpoint: '{{ remote_tmp_dir }}/uquota'
+ name: xfsquotauser
+ rtbsoft: '{{ uquota_user_rtbsoft }}'
+ rtbhard: '{{ uquota_user_rtbhard }}'
+ type: user
+ become: true
+ register: test_uquota_user_before
+ - name: Assert user limits results
+ assert:
+ that:
+ - test_uquota_user_before.changed
+ - test_uquota_user_before.bsoft == uquota_user_bsoft|human_to_bytes
+ - test_uquota_user_before.bhard == uquota_user_bhard|human_to_bytes
+ - test_uquota_user_before.isoft == uquota_user_isoft
+ - test_uquota_user_before.ihard == uquota_user_ihard
+ - test_uquota_user_before.rtbsoft == uquota_user_rtbsoft|human_to_bytes
+ - test_uquota_user_before.rtbhard == uquota_user_rtbhard|human_to_bytes
+ - name: Re-apply default user limits
+ xfs_quota:
+ bsoft: '{{ uquota_default_bsoft }}'
+ bhard: '{{ uquota_default_bhard }}'
+ isoft: '{{ uquota_default_isoft }}'
+ ihard: '{{ uquota_default_ihard }}'
+ mountpoint: '{{ remote_tmp_dir }}/uquota'
+ rtbsoft: '{{ uquota_default_rtbsoft }}'
+ rtbhard: '{{ uquota_default_rtbhard }}'
+ type: user
+ become: true
+ register: test_uquota_default_after
+ - name: Assert default user limits results after re-apply
+ assert:
+ that:
+ - not test_uquota_default_after.changed
+ - name: Re-apply user limits
+ xfs_quota:
+ bsoft: '{{ uquota_user_bsoft }}'
+ bhard: '{{ uquota_user_bhard }}'
+ isoft: '{{ uquota_user_isoft }}'
+ ihard: '{{ uquota_user_ihard }}'
+ mountpoint: '{{ remote_tmp_dir }}/uquota'
+ name: xfsquotauser
+ rtbsoft: '{{ uquota_user_rtbsoft }}'
+ rtbhard: '{{ uquota_user_rtbhard }}'
+ type: user
+ become: true
+ register: test_uquota_user_after
+ - name: Assert user limits results for xfsquotauser after re-apply
+ assert:
+ that:
+ - not test_uquota_user_after.changed
+ - name: Reset default user limits
+ xfs_quota:
+ mountpoint: '{{ remote_tmp_dir }}/uquota'
+ state: absent
+ type: user
+ become: true
+ register: test_reset_uquota_default
+ - name: Assert reset of default user limits results
+ assert:
+ that:
+ - test_reset_uquota_default.changed
+ - test_reset_uquota_default.bsoft == 0
+ - test_reset_uquota_default.bhard == 0
+ - test_reset_uquota_default.isoft == 0
+ - test_reset_uquota_default.ihard == 0
+ - test_reset_uquota_default.rtbsoft == 0
+ - test_reset_uquota_default.rtbhard == 0
+ - name: Reset user limits for xfsquotauser
+ xfs_quota:
+ mountpoint: '{{ remote_tmp_dir }}/uquota'
+ name: xfsquotauser
+ state: absent
+ type: user
+ become: true
+ register: test_reset_uquota_user
+ - name: Assert reset of default user limits results
+ assert:
+ that:
+ - test_reset_uquota_user.changed
+ - test_reset_uquota_user.bsoft == 0
+ - test_reset_uquota_user.bhard == 0
+ - test_reset_uquota_user.isoft == 0
+ - test_reset_uquota_user.ihard == 0
+ - test_reset_uquota_user.rtbsoft == 0
+ - test_reset_uquota_user.rtbhard == 0
+ always:
+ - name: Unmount filesystem
+ become: true
+ ansible.posix.mount:
+ fstab: '{{ remote_tmp_dir }}/fstab'
+ path: '{{ remote_tmp_dir }}/uquota'
+ state: unmounted
+ - name: Remove disk image
+ file:
+ path: '{{ remote_tmp_dir }}/img-uquota'
+ state: absent
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/aliases b/ansible_collections/community/general/tests/integration/targets/xml/aliases
new file mode 100644
index 000000000..0d1324b22
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/aliases
@@ -0,0 +1,7 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/3
+destructive
+skip/aix
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/fixtures/ansible-xml-beers-unicode.xml b/ansible_collections/community/general/tests/integration/targets/xml/fixtures/ansible-xml-beers-unicode.xml
new file mode 100644
index 000000000..d0e3e39af
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/fixtures/ansible-xml-beers-unicode.xml
@@ -0,0 +1,13 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business type="bar">
+ <name>Толстый бар</name>
+ <beers>
+ <beer>Окское</beer>
+ <beer>Невское</beer>
+ </beers>
+ <rating subjective="да">десять</rating>
+ <website>
+ <mobilefriendly/>
+ <address>http://tolstyybar.com</address>
+ </website>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/fixtures/ansible-xml-beers-unicode.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/fixtures/ansible-xml-beers-unicode.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/fixtures/ansible-xml-beers-unicode.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/fixtures/ansible-xml-beers.xml b/ansible_collections/community/general/tests/integration/targets/xml/fixtures/ansible-xml-beers.xml
new file mode 100644
index 000000000..f47909ac6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/fixtures/ansible-xml-beers.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers>
+ <beer>Rochefort 10</beer>
+ <beer>St. Bernardus Abbot 12</beer>
+ <beer>Schlitz</beer>
+ </beers>
+ <rating subjective="true">10</rating>
+ <website>
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/fixtures/ansible-xml-beers.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/fixtures/ansible-xml-beers.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/fixtures/ansible-xml-beers.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/fixtures/ansible-xml-namespaced-beers.xml b/ansible_collections/community/general/tests/integration/targets/xml/fixtures/ansible-xml-namespaced-beers.xml
new file mode 100644
index 000000000..acaca7f59
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/fixtures/ansible-xml-namespaced-beers.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business xmlns="http://test.business" xmlns:attr="http://test.attribute" type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers xmlns="http://test.beers">
+ <beer>Rochefort 10</beer>
+ <beer>St. Bernardus Abbot 12</beer>
+ <beer>Schlitz</beer>
+ </beers>
+ <rating xmlns="http://test.rating" attr:subjective="true">10</rating>
+ <website xmlns="http://test.website">
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/fixtures/ansible-xml-namespaced-beers.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/fixtures/ansible-xml-namespaced-beers.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/fixtures/ansible-xml-namespaced-beers.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/xml/meta/main.yml
new file mode 100644
index 000000000..2fcd152f9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-elements-unicode.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-elements-unicode.xml
new file mode 100644
index 000000000..ebf02ecf5
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-elements-unicode.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers>
+ <beer>Rochefort 10</beer>
+ <beer>St. Bernardus Abbot 12</beer>
+ <beer>Schlitz</beer>
+ <beer>Окское</beer></beers>
+ <rating subjective="true">10</rating>
+ <website>
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-elements-unicode.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-elements-unicode.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-elements-unicode.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-elements.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-elements.xml
new file mode 100644
index 000000000..3fff3d0d2
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-elements.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers>
+ <beer>Rochefort 10</beer>
+ <beer>St. Bernardus Abbot 12</beer>
+ <beer>Schlitz</beer>
+ <beer>Old Rasputin</beer></beers>
+ <rating subjective="true">10</rating>
+ <website>
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-elements.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-elements.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-elements.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-from-groupvars.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-from-groupvars.xml
new file mode 100644
index 000000000..e9b59a6ac
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-from-groupvars.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers>
+ <beer>Rochefort 10</beer>
+ <beer>St. Bernardus Abbot 12</beer>
+ <beer>Schlitz</beer>
+ <beer>Natty Lite</beer><beer>Miller Lite</beer><beer>Coors Lite</beer></beers>
+ <rating subjective="true">10</rating>
+ <website>
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-from-groupvars.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-from-groupvars.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-from-groupvars.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-insertafter.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-insertafter.xml
new file mode 100644
index 000000000..8da963363
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-insertafter.xml
@@ -0,0 +1,17 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers>
+ <beer>Rochefort 10</beer>
+ <beer>St. Bernardus Abbot 12</beer>
+ <beer>Old Rasputin</beer>
+ <beer>Old Motor Oil</beer>
+ <beer>Old Curmudgeon</beer>
+ <beer>Schlitz</beer>
+ </beers>
+ <rating subjective="true">10</rating>
+ <website>
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-insertafter.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-insertafter.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-insertafter.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-insertbefore.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-insertbefore.xml
new file mode 100644
index 000000000..c409e54bf
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-insertbefore.xml
@@ -0,0 +1,17 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers>
+ <beer>Rochefort 10</beer>
+ <beer>Old Rasputin</beer>
+ <beer>Old Motor Oil</beer>
+ <beer>Old Curmudgeon</beer>
+ <beer>St. Bernardus Abbot 12</beer>
+ <beer>Schlitz</beer>
+ </beers>
+ <rating subjective="true">10</rating>
+ <website>
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-insertbefore.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-insertbefore.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-insertbefore.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-with-attributes-unicode.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-with-attributes-unicode.xml
new file mode 100644
index 000000000..f206af231
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-with-attributes-unicode.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers>
+ <beer>Rochefort 10</beer>
+ <beer>St. Bernardus Abbot 12</beer>
+ <beer>Schlitz</beer>
+ <beer name="Окское" type="экстра"/></beers>
+ <rating subjective="true">10</rating>
+ <website>
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-with-attributes-unicode.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-with-attributes-unicode.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-with-attributes-unicode.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-with-attributes.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-with-attributes.xml
new file mode 100644
index 000000000..a4471b7f1
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-with-attributes.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers>
+ <beer>Rochefort 10</beer>
+ <beer>St. Bernardus Abbot 12</beer>
+ <beer>Schlitz</beer>
+ <beer name="Ansible Brew" type="light"/></beers>
+ <rating subjective="true">10</rating>
+ <website>
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-with-attributes.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-with-attributes.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-children-with-attributes.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-element-implicitly.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-element-implicitly.xml
new file mode 100644
index 000000000..fa1ddfca2
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-element-implicitly.xml
@@ -0,0 +1,32 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers>
+ <beer>Rochefort 10</beer>
+ <beer>St. Bernardus Abbot 12</beer>
+ <beer>Schlitz</beer>
+ <beer color="red">George Killian's Irish Red</beer>
+ <beer origin="CZ" color="blonde">Pilsner Urquell</beer>
+ </beers>
+ <rating subjective="true">10</rating>
+ <website>
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ <validxhtml validateon=""/>
+ </website>
+ <phonenumber>555-555-1234</phonenumber>
+ <owner dob="1976-04-12">
+ <name>
+ <last>Smith</last>
+ <first>John</first>
+ <middle>Q</middle>
+ </name>
+ </owner>
+ <website_bis>
+ <validxhtml validateon=""/>
+ </website_bis>
+ <testnormalelement>xml tag with no special characters</testnormalelement>
+ <test-with-dash>xml tag with dashes</test-with-dash>
+ <test-with-dash.and.dot>xml tag with dashes and dots</test-with-dash.and.dot>
+ <test-with.dash_and.dot_and-underscores>xml tag with dashes, dots and underscores</test-with.dash_and.dot_and-underscores>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-element-implicitly.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-element-implicitly.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-element-implicitly.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-namespaced-children-elements.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-namespaced-children-elements.xml
new file mode 100644
index 000000000..dc53d2f8a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-namespaced-children-elements.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business xmlns="http://test.business" xmlns:attr="http://test.attribute" type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers xmlns="http://test.beers">
+ <beer>Rochefort 10</beer>
+ <beer>St. Bernardus Abbot 12</beer>
+ <beer>Schlitz</beer>
+ <beer>Old Rasputin</beer></beers>
+ <rating xmlns="http://test.rating" attr:subjective="true">10</rating>
+ <website xmlns="http://test.website">
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-namespaced-children-elements.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-namespaced-children-elements.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-add-namespaced-children-elements.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-pretty-print-only.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-pretty-print-only.xml
new file mode 100644
index 000000000..f47909ac6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-pretty-print-only.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers>
+ <beer>Rochefort 10</beer>
+ <beer>St. Bernardus Abbot 12</beer>
+ <beer>Schlitz</beer>
+ </beers>
+ <rating subjective="true">10</rating>
+ <website>
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-pretty-print-only.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-pretty-print-only.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-pretty-print-only.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-pretty-print.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-pretty-print.xml
new file mode 100644
index 000000000..b5c38262f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-pretty-print.xml
@@ -0,0 +1,15 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers>
+ <beer>Rochefort 10</beer>
+ <beer>St. Bernardus Abbot 12</beer>
+ <beer>Schlitz</beer>
+ <beer>Old Rasputin</beer>
+ </beers>
+ <rating subjective="true">10</rating>
+ <website>
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-pretty-print.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-pretty-print.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-pretty-print.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-attribute.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-attribute.xml
new file mode 100644
index 000000000..579741918
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-attribute.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers>
+ <beer>Rochefort 10</beer>
+ <beer>St. Bernardus Abbot 12</beer>
+ <beer>Schlitz</beer>
+ </beers>
+ <rating>10</rating>
+ <website>
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-attribute.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-attribute.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-attribute.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-element.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-element.xml
new file mode 100644
index 000000000..b7b1a1a5c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-element.xml
@@ -0,0 +1,13 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers>
+ <beer>Rochefort 10</beer>
+ <beer>St. Bernardus Abbot 12</beer>
+ <beer>Schlitz</beer>
+ </beers>
+ <website>
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-element.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-element.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-element.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-namespaced-attribute.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-namespaced-attribute.xml
new file mode 100644
index 000000000..4c4dcb180
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-namespaced-attribute.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business xmlns="http://test.business" xmlns:attr="http://test.attribute" type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers xmlns="http://test.beers">
+ <beer>Rochefort 10</beer>
+ <beer>St. Bernardus Abbot 12</beer>
+ <beer>Schlitz</beer>
+ </beers>
+ <rating xmlns="http://test.rating">10</rating>
+ <website xmlns="http://test.website">
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-namespaced-attribute.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-namespaced-attribute.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-namespaced-attribute.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-namespaced-element.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-namespaced-element.xml
new file mode 100644
index 000000000..e72312032
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-namespaced-element.xml
@@ -0,0 +1,13 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business xmlns="http://test.business" xmlns:attr="http://test.attribute" type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers xmlns="http://test.beers">
+ <beer>Rochefort 10</beer>
+ <beer>St. Bernardus Abbot 12</beer>
+ <beer>Schlitz</beer>
+ </beers>
+ <website xmlns="http://test.website">
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-namespaced-element.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-namespaced-element.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-remove-namespaced-element.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-attribute-value-unicode.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-attribute-value-unicode.xml
new file mode 100644
index 000000000..df50daba4
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-attribute-value-unicode.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers>
+ <beer>Rochefort 10</beer>
+ <beer>St. Bernardus Abbot 12</beer>
+ <beer>Schlitz</beer>
+ </beers>
+ <rating subjective="нет">10</rating>
+ <website>
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-attribute-value-unicode.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-attribute-value-unicode.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-attribute-value-unicode.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-attribute-value.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-attribute-value.xml
new file mode 100644
index 000000000..28dcff81a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-attribute-value.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers>
+ <beer>Rochefort 10</beer>
+ <beer>St. Bernardus Abbot 12</beer>
+ <beer>Schlitz</beer>
+ </beers>
+ <rating subjective="false">10</rating>
+ <website>
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-attribute-value.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-attribute-value.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-attribute-value.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements-empty-list.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements-empty-list.xml
new file mode 100644
index 000000000..51eb98f16
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements-empty-list.xml
@@ -0,0 +1,11 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers>
+ </beers>
+ <rating subjective="true">10</rating>
+ <website>
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+</business> \ No newline at end of file
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements-empty-list.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements-empty-list.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements-empty-list.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements-level.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements-level.xml
new file mode 100644
index 000000000..b985090d7
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements-level.xml
@@ -0,0 +1,11 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers>
+ <beer alcohol="0.5" name="90 Minute IPA"><Water liter="0.2" quantity="200g"/><Starch quantity="10g"/><Hops quantity="50g"/><Yeast quantity="20g"/></beer><beer alcohol="0.3" name="Harvest Pumpkin Ale"><Water liter="0.2" quantity="200g"/><Hops quantity="25g"/><Yeast quantity="20g"/></beer></beers>
+ <rating subjective="true">10</rating>
+ <website>
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements-level.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements-level.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements-level.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements-unicode.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements-unicode.xml
new file mode 100644
index 000000000..3cd586dd0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements-unicode.xml
@@ -0,0 +1,11 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers>
+ <beer>Окское</beer><beer>Невское</beer></beers>
+ <rating subjective="true">10</rating>
+ <website>
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements-unicode.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements-unicode.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements-unicode.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements.xml
new file mode 100644
index 000000000..6348c3e8f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements.xml
@@ -0,0 +1,11 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers>
+ <beer>90 Minute IPA</beer><beer>Harvest Pumpkin Ale</beer></beers>
+ <rating subjective="true">10</rating>
+ <website>
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-children-elements.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-element-value-empty.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-element-value-empty.xml
new file mode 100644
index 000000000..5ecab798e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-element-value-empty.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers>
+ <beer>Rochefort 10</beer>
+ <beer>St. Bernardus Abbot 12</beer>
+ <beer>Schlitz</beer>
+ </beers>
+ <rating subjective="true">10</rating>
+ <website>
+ <mobilefriendly/>
+ <address></address>
+ </website>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-element-value-empty.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-element-value-empty.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-element-value-empty.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-element-value-unicode.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-element-value-unicode.xml
new file mode 100644
index 000000000..6c5ca8dd9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-element-value-unicode.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers>
+ <beer>Rochefort 10</beer>
+ <beer>St. Bernardus Abbot 12</beer>
+ <beer>Schlitz</beer>
+ </beers>
+ <rating subjective="true">пять</rating>
+ <website>
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+<rating>пять</rating></business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-element-value-unicode.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-element-value-unicode.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-element-value-unicode.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-element-value.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-element-value.xml
new file mode 100644
index 000000000..59fb1e516
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-element-value.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers>
+ <beer>Rochefort 10</beer>
+ <beer>St. Bernardus Abbot 12</beer>
+ <beer>Schlitz</beer>
+ </beers>
+ <rating subjective="true">5</rating>
+ <website>
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+<rating>5</rating></business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-element-value.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-element-value.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-element-value.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-namespaced-attribute-value.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-namespaced-attribute-value.xml
new file mode 100644
index 000000000..229b31ad7
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-namespaced-attribute-value.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business xmlns="http://test.business" xmlns:attr="http://test.attribute" type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers xmlns="http://test.beers">
+ <beer>Rochefort 10</beer>
+ <beer>St. Bernardus Abbot 12</beer>
+ <beer>Schlitz</beer>
+ </beers>
+ <rating xmlns="http://test.rating" attr:subjective="false">10</rating>
+ <website xmlns="http://test.website">
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-namespaced-attribute-value.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-namespaced-attribute-value.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-namespaced-attribute-value.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-namespaced-element-value.xml b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-namespaced-element-value.xml
new file mode 100644
index 000000000..f78873e7a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-namespaced-element-value.xml
@@ -0,0 +1,14 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<business xmlns="http://test.business" xmlns:attr="http://test.attribute" type="bar">
+ <name>Tasty Beverage Co.</name>
+ <beers xmlns="http://test.beers">
+ <beer>Rochefort 10</beer>
+ <beer>St. Bernardus Abbot 12</beer>
+ <beer>Schlitz</beer>
+ </beers>
+ <rating xmlns="http://test.rating" attr:subjective="true">11</rating>
+ <website xmlns="http://test.website">
+ <mobilefriendly/>
+ <address>http://tastybeverageco.com</address>
+ </website>
+</business>
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-namespaced-element-value.xml.license b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-namespaced-element-value.xml.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/results/test-set-namespaced-element-value.xml.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/main.yml
new file mode 100644
index 000000000..fe46b3ae5
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/main.yml
@@ -0,0 +1,77 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Install lxml (FreeBSD)
+ package:
+ name: 'py{{ ansible_python.version.major }}{{ ansible_python.version.minor }}-lxml'
+ state: present
+ when: ansible_os_family == "FreeBSD"
+
+# Needed for MacOSX !
+- name: Install lxml
+ pip:
+ name: lxml
+ state: present
+# when: ansible_os_family == "Darwin"
+
+- name: Get lxml version
+ command: "{{ ansible_python_interpreter }} -c 'from lxml import etree; print(\".\".join(str(v) for v in etree.LXML_VERSION))'"
+ register: lxml_version
+
+- name: Set lxml capabilities as variables
+ set_fact:
+ # NOTE: Some tests require predictable element attribute order,
+ # which is only guaranteed starting from lxml v3.0alpha1
+ lxml_predictable_attribute_order: '{{ lxml_version.stdout is version("3", ">=") }}'
+
+ # NOTE: The xml module requires at least lxml v2.3.0
+ lxml_xpath_attribute_result_attrname: '{{ lxml_version.stdout is version("2.3.0", ">=") }}'
+
+- name: Only run the tests when lxml v2.3.0+
+ when: lxml_xpath_attribute_result_attrname
+ block:
+
+ - include_tasks: test-add-children-elements.yml
+ - include_tasks: test-add-children-from-groupvars.yml
+ - include_tasks: test-add-children-insertafter.yml
+ - include_tasks: test-add-children-insertbefore.yml
+ - include_tasks: test-add-children-with-attributes.yml
+ - include_tasks: test-add-element-implicitly.yml
+ - include_tasks: test-count.yml
+ - include_tasks: test-mutually-exclusive-attributes.yml
+ - include_tasks: test-remove-attribute.yml
+ - include_tasks: test-remove-attribute-nochange.yml
+ - include_tasks: test-remove-element.yml
+ - include_tasks: test-remove-element-nochange.yml
+ - include_tasks: test-set-attribute-value.yml
+ - include_tasks: test-set-children-elements.yml
+ - include_tasks: test-set-children-elements-level.yml
+ - include_tasks: test-set-element-value.yml
+ - include_tasks: test-set-element-value-empty.yml
+ - include_tasks: test-pretty-print.yml
+ - include_tasks: test-pretty-print-only.yml
+ - include_tasks: test-add-namespaced-children-elements.yml
+ - include_tasks: test-remove-namespaced-attribute.yml
+ - include_tasks: test-remove-namespaced-attribute-nochange.yml
+ - include_tasks: test-set-namespaced-attribute-value.yml
+ - include_tasks: test-set-namespaced-element-value.yml
+ - include_tasks: test-set-namespaced-children-elements.yml
+ - include_tasks: test-get-element-content.yml
+ - include_tasks: test-xmlstring.yml
+ - include_tasks: test-children-elements-xml.yml
+
+ # Unicode tests
+ - include_tasks: test-add-children-elements-unicode.yml
+ - include_tasks: test-add-children-with-attributes-unicode.yml
+ - include_tasks: test-set-attribute-value-unicode.yml
+ - include_tasks: test-count-unicode.yml
+ - include_tasks: test-get-element-content.yml
+ - include_tasks: test-set-children-elements-unicode.yml
+ - include_tasks: test-set-element-value-unicode.yml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-elements-unicode.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-elements-unicode.yml
new file mode 100644
index 000000000..e15ac5fd9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-elements-unicode.yml
@@ -0,0 +1,36 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers.xml
+ dest: /tmp/ansible-xml-beers.xml
+
+
+ - name: Add child element
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/beers
+ add_children:
+ - beer: Окское
+ register: add_children_elements_unicode
+
+ - name: Add trailing newline
+ shell: echo "" >> /tmp/ansible-xml-beers.xml
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-add-children-elements-unicode.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - add_children_elements_unicode is changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-add-children-elements-unicode.xml /tmp/ansible-xml-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-elements.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-elements.yml
new file mode 100644
index 000000000..29467f6d6
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-elements.yml
@@ -0,0 +1,36 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers.xml
+ dest: /tmp/ansible-xml-beers.xml
+
+
+ - name: Add child element
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/beers
+ add_children:
+ - beer: Old Rasputin
+ register: add_children_elements
+
+ - name: Add trailing newline
+ shell: echo "" >> /tmp/ansible-xml-beers.xml
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-add-children-elements.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - add_children_elements is changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-add-children-elements.xml /tmp/ansible-xml-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-from-groupvars.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-from-groupvars.yml
new file mode 100644
index 000000000..2b232b6d0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-from-groupvars.yml
@@ -0,0 +1,35 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers.xml
+ dest: /tmp/ansible-xml-beers.xml
+
+
+ - name: Add child element
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/beers
+ add_children: '{{ bad_beers }}'
+ register: add_children_from_groupvars
+
+ - name: Add trailing newline
+ shell: echo "" >> /tmp/ansible-xml-beers.xml
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-add-children-from-groupvars.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - add_children_from_groupvars is changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-add-children-from-groupvars.xml /tmp/ansible-xml-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-insertafter.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-insertafter.yml
new file mode 100644
index 000000000..7795c8966
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-insertafter.yml
@@ -0,0 +1,36 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers.xml
+ dest: /tmp/ansible-xml-beers.xml
+
+
+ - name: Add child element
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: '/business/beers/beer[text()="St. Bernardus Abbot 12"]'
+ insertafter: true
+ add_children:
+ - beer: Old Rasputin
+ - beer: Old Motor Oil
+ - beer: Old Curmudgeon
+ pretty_print: true
+ register: add_children_insertafter
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-add-children-insertafter.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - add_children_insertafter is changed
+ - comparison is not changed # identical
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-insertbefore.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-insertbefore.yml
new file mode 100644
index 000000000..b14c5e06f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-insertbefore.yml
@@ -0,0 +1,36 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers.xml
+ dest: /tmp/ansible-xml-beers.xml
+
+
+ - name: Add child element
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: '/business/beers/beer[text()="St. Bernardus Abbot 12"]'
+ insertbefore: true
+ add_children:
+ - beer: Old Rasputin
+ - beer: Old Motor Oil
+ - beer: Old Curmudgeon
+ pretty_print: true
+ register: add_children_insertbefore
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-add-children-insertbefore.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - add_children_insertbefore is changed
+ - comparison is not changed # identical
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-with-attributes-unicode.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-with-attributes-unicode.yml
new file mode 100644
index 000000000..07905aa15
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-with-attributes-unicode.yml
@@ -0,0 +1,38 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers.xml
+ dest: /tmp/ansible-xml-beers.xml
+
+
+ - name: Add child element
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/beers
+ add_children:
+ - beer:
+ name: Окское
+ type: экстра
+ register: add_children_with_attributes_unicode
+
+ - name: Add trailing newline
+ shell: echo "" >> /tmp/ansible-xml-beers.xml
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-add-children-with-attributes-unicode.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - add_children_with_attributes_unicode is changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-add-children-with-attributes-unicode.xml /tmp/ansible-xml-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-with-attributes.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-with-attributes.yml
new file mode 100644
index 000000000..fede24395
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-children-with-attributes.yml
@@ -0,0 +1,42 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers.xml
+ dest: /tmp/ansible-xml-beers.xml
+
+
+ - name: Add child element
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/beers
+ add_children:
+ - beer:
+ name: Ansible Brew
+ type: light
+ register: add_children_with_attributes
+
+ - name: Add trailing newline
+ shell: echo "" >> /tmp/ansible-xml-beers.xml
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-add-children-with-attributes.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ # NOTE: This test may fail if lxml does not support predictable element attribute order
+ # So we filter the failure out for these platforms (e.g. CentOS 6)
+ # The module still works fine, we simply are not comparing as smart as we should.
+ - name: Test expected result
+ assert:
+ that:
+ - add_children_with_attributes is changed
+ - comparison is not changed # identical
+ when: lxml_predictable_attribute_order
+ #command: diff -u {{ role_path }}/results/test-add-children-with-attributes.xml /tmp/ansible-xml-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-element-implicitly.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-element-implicitly.yml
new file mode 100644
index 000000000..b1718e452
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-element-implicitly.yml
@@ -0,0 +1,241 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers.xml
+ dest: /tmp/ansible-xml-beers-implicit.xml
+
+
+- name: Add a phonenumber element to the business element. Implicit mkdir -p behavior where applicable
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/phonenumber
+ value: 555-555-1234
+
+- name: Add a owner element to the business element, testing implicit mkdir -p behavior 1/2
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/owner/name/last
+ value: Smith
+
+- name: Add a owner element to the business element, testing implicit mkdir -p behavior 2/2
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/owner/name/first
+ value: John
+
+- name: Add a validxhtml element to the website element. Note that ensure is present by default and while value defaults to null for elements, if one doesn't specify it we don't know what to do.
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/website/validxhtml
+
+- name: Add an empty validateon attribute to the validxhtml element. This actually makes the previous example redundant because of the implicit parent-node creation behavior.
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/website/validxhtml/@validateon
+
+- name: Add an empty validateon attribute to the validxhtml element. Actually verifies the implicit parent-node creation behavior.
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/website_bis/validxhtml/@validateon
+
+- name: Add an attribute with a value
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/owner/@dob='1976-04-12'
+
+- name: Add an element with a value, alternate syntax
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/beers/beer/text()="George Killian's Irish Red" # note the quote within an XPath string thing
+
+- name: Add an element without special characters
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/testnormalelement
+ value: xml tag with no special characters
+ pretty_print: true
+
+- name: Add an element with dash
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/test-with-dash
+ value: xml tag with dashes
+ pretty_print: true
+
+- name: Add an element with dot
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/test-with-dash.and.dot
+ value: xml tag with dashes and dots
+ pretty_print: true
+
+- name: Add an element with underscore
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/test-with.dash_and.dot_and-underscores
+ value: xml tag with dashes, dots and underscores
+ pretty_print: true
+
+- name: Add an attribute on a conditional element
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/beers/beer[text()="George Killian's Irish Red"]/@color='red'
+
+- name: Add two attributes on a conditional element
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/beers/beer[text()="Pilsner Urquell" and @origin='CZ']/@color='blonde'
+
+- name: Add a owner element to the business element, testing implicit mkdir -p behavior 3/2 -- complex lookup
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/owner/name[first/text()='John']/middle
+ value: Q
+
+- name: Pretty Print this!
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ pretty_print: true
+
+- name: Compare to expected result
+ copy:
+ src: results/test-add-element-implicitly.xml
+ dest: /tmp/ansible-xml-beers-implicit.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+- name: Test expected result
+ assert:
+ that:
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-add-element-implicitly.xml /tmp/ansible-xml-beers-implicit.xml
+
+
+# Now we repeat the same, just to ensure proper use of namespaces
+- name: Add a phonenumber element to the business element. Implicit mkdir -p behavior where applicable
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/a:phonenumber
+ value: 555-555-1234
+ namespaces:
+ a: http://example.com/some/namespace
+
+- name: Add a owner element to the business element, testing implicit mkdir -p behavior 1/2
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/a:owner/a:name/a:last
+ value: Smith
+ namespaces:
+ a: http://example.com/some/namespace
+
+- name: Add a owner element to the business element, testing implicit mkdir -p behavior 2/2
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/a:owner/a:name/a:first
+ value: John
+ namespaces:
+ a: http://example.com/some/namespace
+
+- name: Add a validxhtml element to the website element. Note that ensure is present by default and while value defaults to null for elements, if one doesn't specify it we don't know what to do.
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/a:website/a:validxhtml
+ namespaces:
+ a: http://example.com/some/namespace
+
+- name: Add an empty validateon attribute to the validxhtml element. This actually makes the previous example redundant because of the implicit parent-node creation behavior.
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/a:website/a:validxhtml/@a:validateon
+ namespaces:
+ a: http://example.com/some/namespace
+
+- name: Add an empty validateon attribute to the validxhtml element. Actually verifies the implicit parent-node creation behavior.
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/a:website_bis/a:validxhtml/@a:validateon
+ namespaces:
+ a: http://example.com/some/namespace
+
+- name: Add an attribute with a value
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/a:owner/@a:dob='1976-04-12'
+ namespaces:
+ a: http://example.com/some/namespace
+
+- name: Add an element with a value, alternate syntax
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/a:beers/a:beer/text()="George Killian's Irish Red" # note the quote within an XPath string thing
+ namespaces:
+ a: http://example.com/some/namespace
+
+- name: Add an attribute on a conditional element
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/a:beers/a:beer[text()="George Killian's Irish Red"]/@a:color='red'
+ namespaces:
+ a: http://example.com/some/namespace
+
+- name: Add two attributes on a conditional element
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/a:beers/a:beer[text()="Pilsner Urquell" and @a:origin='CZ']/@a:color='blonde'
+ namespaces:
+ a: http://example.com/some/namespace
+
+- name: Add a owner element to the business element, testing implicit mkdir -p behavior 3/2 -- complex lookup
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/a:owner/a:name[a:first/text()='John']/a:middle
+ value: Q
+ namespaces:
+ a: http://example.com/some/namespace
+
+- name: Add an element without special characters
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/testnormalelement
+ value: xml tag with no special characters
+ pretty_print: true
+ namespaces:
+ a: http://example.com/some/namespace
+
+
+- name: Add an element with dash
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/test-with-dash
+ value: xml tag with dashes
+ pretty_print: true
+ namespaces:
+ a: http://example.com/some/namespace
+
+- name: Add an element with dot
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/test-with-dash.and.dot
+ value: xml tag with dashes and dots
+ pretty_print: true
+ namespaces:
+ a: http://example.com/some/namespace
+
+- name: Add an element with underscore
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ xpath: /business/test-with.dash_and.dot_and-underscores
+ value: xml tag with dashes, dots and underscores
+ pretty_print: true
+ namespaces:
+ a: http://example.com/some/namespace
+
+- name: Pretty Print this!
+ xml:
+ file: /tmp/ansible-xml-beers-implicit.xml
+ pretty_print: true
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-namespaced-children-elements.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-namespaced-children-elements.yml
new file mode 100644
index 000000000..2a9daab78
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-add-namespaced-children-elements.yml
@@ -0,0 +1,39 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-namespaced-beers.xml
+ dest: /tmp/ansible-xml-namespaced-beers.xml
+
+
+ - name: Add namespaced child element
+ xml:
+ path: /tmp/ansible-xml-namespaced-beers.xml
+ xpath: /bus:business/ber:beers
+ namespaces:
+ bus: http://test.business
+ ber: http://test.beers
+ add_children:
+ - beer: Old Rasputin
+ register: add_namespaced_children_elements
+
+ - name: Add trailing newline
+ shell: echo "" >> /tmp/ansible-xml-namespaced-beers.xml
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-add-namespaced-children-elements.xml
+ dest: /tmp/ansible-xml-namespaced-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - add_namespaced_children_elements is changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-add-namespaced-children-elements.xml /tmp/ansible-xml-namespaced-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-children-elements-xml.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-children-elements-xml.yml
new file mode 100644
index 000000000..1c8c2b804
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-children-elements-xml.yml
@@ -0,0 +1,37 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers.xml
+ dest: /tmp/ansible-xml-beers.xml
+
+
+ - name: Add child element with xml format
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/beers
+ input_type: xml
+ add_children:
+ - '<beer>Old Rasputin</beer>'
+ register: children_elements
+
+ - name: Add trailing newline
+ shell: echo "" >> /tmp/ansible-xml-beers.xml
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-add-children-elements.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - children_elements is changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-add-children-elements.xml /tmp/ansible-xml-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-count-unicode.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-count-unicode.yml
new file mode 100644
index 000000000..118e2986d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-count-unicode.yml
@@ -0,0 +1,23 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers-unicode.xml
+ dest: /tmp/ansible-xml-beers-unicode.xml
+
+
+ - name: Count child element
+ xml:
+ path: /tmp/ansible-xml-beers-unicode.xml
+ xpath: /business/beers/beer
+ count: true
+ register: beers
+
+ - name: Test expected result
+ assert:
+ that:
+ - beers is not changed
+ - beers.count == 2
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-count.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-count.yml
new file mode 100644
index 000000000..79be9402f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-count.yml
@@ -0,0 +1,23 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers.xml
+ dest: /tmp/ansible-xml-beers.xml
+
+
+ - name: Add child element
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/beers/beer
+ count: true
+ register: beers
+
+ - name: Test expected result
+ assert:
+ that:
+ - beers is not changed
+ - beers.count == 3
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-get-element-content-unicode.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-get-element-content-unicode.yml
new file mode 100644
index 000000000..475f962eb
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-get-element-content-unicode.yml
@@ -0,0 +1,36 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers-unicode.xml
+ dest: /tmp/ansible-xml-beers-unicode.xml
+
+
+ - name: Get element attributes
+ xml:
+ path: /tmp/ansible-xml-beers-unicode.xml
+ xpath: /business/rating
+ content: attribute
+ register: get_element_attribute
+
+ - name: Test expected result
+ assert:
+ that:
+ - get_element_attribute is not changed
+ - get_element_attribute.matches[0]['rating'] is defined and get_element_attribute.matches[0]['rating']['subjective'] == 'да'
+
+ - name: Get element text
+ xml:
+ path: /tmp/ansible-xml-beers-unicode.xml
+ xpath: /business/rating
+ content: text
+ register: get_element_text
+
+ - name: Test expected result
+ assert:
+ that:
+ - get_element_text is not changed
+ - get_element_text.matches[0]['rating'] == 'десять'
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-get-element-content.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-get-element-content.yml
new file mode 100644
index 000000000..c75bdb223
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-get-element-content.yml
@@ -0,0 +1,51 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers.xml
+ dest: /tmp/ansible-xml-beers.xml
+
+
+ - name: Get element attributes
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/rating
+ content: attribute
+ register: get_element_attribute
+
+ - name: Test expected result
+ assert:
+ that:
+ - get_element_attribute is not changed
+ - get_element_attribute.matches[0]['rating'] is defined
+ - get_element_attribute.matches[0]['rating']['subjective'] == 'true'
+
+ - name: Get element attributes (should fail)
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/rating
+ content: attribute
+ attribute: subjective
+ register: get_element_attribute_wrong
+ ignore_errors: true
+
+ - name: Test expected result
+ assert:
+ that:
+ - get_element_attribute_wrong is failed
+
+ - name: Get element text
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/rating
+ content: text
+ register: get_element_text
+
+ - name: Test expected result
+ assert:
+ that:
+ - get_element_text is not changed
+ - get_element_text.matches[0]['rating'] == '10'
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-mutually-exclusive-attributes.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-mutually-exclusive-attributes.yml
new file mode 100644
index 000000000..33f129e2e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-mutually-exclusive-attributes.yml
@@ -0,0 +1,26 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers.xml
+ dest: /tmp/ansible-xml-beers.xml
+
+
+ - name: Specify both children to add and a value
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ add_children:
+ - child01
+ - child02
+ value: conflict!
+ register: module_output
+ ignore_errors: true
+
+ - name: Test expected result
+ assert:
+ that:
+ - module_output is not changed
+ - module_output is failed
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-pretty-print-only.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-pretty-print-only.yml
new file mode 100644
index 000000000..03d3299aa
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-pretty-print-only.yml
@@ -0,0 +1,33 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers.xml
+ dest: /tmp/ansible-xml-beers.xml.orig
+
+ - name: Remove spaces from test fixture
+ shell: sed 's/^[ ]*//g' < /tmp/ansible-xml-beers.xml.orig > /tmp/ansible-xml-beers.xml
+
+ - name: Pretty print without modification
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ pretty_print: true
+ register: pretty_print_only
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-pretty-print-only.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - pretty_print_only is changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-pretty-print-only.xml /tmp/ansible-xml-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-pretty-print.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-pretty-print.yml
new file mode 100644
index 000000000..51b34502d
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-pretty-print.yml
@@ -0,0 +1,34 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers.xml
+ dest: /tmp/ansible-xml-beers.xml
+
+
+ - name: Pretty print
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/beers
+ pretty_print: true
+ add_children:
+ - beer: Old Rasputin
+ register: pretty_print
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-pretty-print.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - pretty_print is changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-pretty-print.xml /tmp/ansible-xml-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-attribute-nochange.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-attribute-nochange.yml
new file mode 100644
index 000000000..3222bd436
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-attribute-nochange.yml
@@ -0,0 +1,32 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: results/test-remove-attribute.xml
+ dest: /tmp/ansible-xml-beers.xml
+
+
+ - name: Remove non-existing '/business/rating/@subjective'
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/rating/@subjective
+ state: absent
+ register: remove_attribute
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-remove-attribute.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - remove_attribute is not changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-remove-attribute.xml /tmp/ansible-xml-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-attribute.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-attribute.yml
new file mode 100644
index 000000000..e8952a655
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-attribute.yml
@@ -0,0 +1,35 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers.xml
+ dest: /tmp/ansible-xml-beers.xml
+
+
+ - name: Remove '/business/rating/@subjective'
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/rating/@subjective
+ state: absent
+ register: remove_attribute
+
+ - name: Add trailing newline
+ shell: echo "" >> /tmp/ansible-xml-beers.xml
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-remove-attribute.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - remove_attribute is changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-remove-attribute.xml /tmp/ansible-xml-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-element-nochange.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-element-nochange.yml
new file mode 100644
index 000000000..c1312c5a7
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-element-nochange.yml
@@ -0,0 +1,32 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: results/test-remove-element.xml
+ dest: /tmp/ansible-xml-beers.xml
+
+
+ - name: Remove non-existing '/business/rating'
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/rating
+ state: absent
+ register: remove_element
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-remove-element.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - remove_element is not changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-remove-element.xml /tmp/ansible-xml-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-element.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-element.yml
new file mode 100644
index 000000000..bea376ba9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-element.yml
@@ -0,0 +1,35 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers.xml
+ dest: /tmp/ansible-xml-beers.xml
+
+
+ - name: Remove '/business/rating'
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/rating
+ state: absent
+ register: remove_element
+
+ - name: Add trailing newline
+ shell: echo "" >> /tmp/ansible-xml-beers.xml
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-remove-element.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - remove_element is changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-remove-element.xml /tmp/ansible-xml-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-namespaced-attribute-nochange.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-namespaced-attribute-nochange.yml
new file mode 100644
index 000000000..61b7179ba
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-namespaced-attribute-nochange.yml
@@ -0,0 +1,37 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: results/test-remove-namespaced-attribute.xml
+ dest: /tmp/ansible-xml-namespaced-beers.xml
+
+
+ - name: Remove non-existing namespaced '/bus:business/rat:rating/@attr:subjective'
+ xml:
+ path: /tmp/ansible-xml-namespaced-beers.xml
+ xpath: /bus:business/rat:rating/@attr:subjective
+ namespaces:
+ bus: http://test.business
+ ber: http://test.beers
+ rat: http://test.rating
+ attr: http://test.attribute
+ state: absent
+ register: remove_namespaced_attribute
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-remove-namespaced-attribute.xml
+ dest: /tmp/ansible-xml-namespaced-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - remove_namespaced_attribute is not changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-remove-namespaced-attribute.xml /tmp/ansible-xml-namespaced-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-namespaced-attribute.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-namespaced-attribute.yml
new file mode 100644
index 000000000..a725ee79c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-namespaced-attribute.yml
@@ -0,0 +1,40 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-namespaced-beers.xml
+ dest: /tmp/ansible-xml-namespaced-beers.xml
+
+
+ - name: Remove namespaced '/bus:business/rat:rating/@attr:subjective'
+ xml:
+ path: /tmp/ansible-xml-namespaced-beers.xml
+ xpath: /bus:business/rat:rating/@attr:subjective
+ namespaces:
+ bus: http://test.business
+ ber: http://test.beers
+ rat: http://test.rating
+ attr: http://test.attribute
+ state: absent
+ register: remove_namespaced_attribute
+
+ - name: Add trailing newline
+ shell: echo "" >> /tmp/ansible-xml-namespaced-beers.xml
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-remove-namespaced-attribute.xml
+ dest: /tmp/ansible-xml-namespaced-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - remove_namespaced_attribute is changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-remove-namespaced-attribute.xml /tmp/ansible-xml-namespaced-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-namespaced-element-nochange.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-namespaced-element-nochange.yml
new file mode 100644
index 000000000..fd83c54c3
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-namespaced-element-nochange.yml
@@ -0,0 +1,37 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: results/test-remove-element.xml
+ dest: /tmp/ansible-xml-namespaced-beers.xml
+
+
+ - name: Remove non-existing namespaced '/bus:business/rat:rating'
+ xml:
+ path: /tmp/ansible-xml-namespaced-beers.xml
+ xpath: /bus:business/rat:rating
+ namespaces:
+ bus: http://test.business
+ ber: http://test.beers
+ rat: http://test.rating
+ attr: http://test.attribute
+ state: absent
+ register: remove_namespaced_element
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-remove-element.xml
+ dest: /tmp/ansible-xml-namespaced-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - remove_namespaced_element is not changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-remove-element.xml /tmp/ansible-xml-namespaced-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-namespaced-element.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-namespaced-element.yml
new file mode 100644
index 000000000..c4129f33e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-remove-namespaced-element.yml
@@ -0,0 +1,40 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-namespaced-beers.xml
+ dest: /tmp/ansible-xml-namespaced-beers.xml
+
+
+ - name: Remove namespaced '/bus:business/rat:rating'
+ xml:
+ path: /tmp/ansible-xml-namespaced-beers.xml
+ xpath: /bus:business/rat:rating
+ namespaces:
+ bus: http://test.business
+ ber: http://test.beers
+ rat: http://test.rating
+ attr: http://test.attribute
+ state: absent
+ register: remove_namespaced_element
+
+ - name: Add trailing newline
+ shell: echo "" >> /tmp/ansible-xml-namespaced-beers.xml
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-remove-element.xml
+ dest: /tmp/ansible-xml-namespaced-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - remove_namespaced_element is changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-remove-element.xml /tmp/ansible-xml-namespaced-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-attribute-value-unicode.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-attribute-value-unicode.yml
new file mode 100644
index 000000000..bf35bfdd9
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-attribute-value-unicode.yml
@@ -0,0 +1,36 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers.xml
+ dest: /tmp/ansible-xml-beers.xml
+
+
+ - name: Set '/business/rating/@subjective' to 'нет'
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/rating
+ attribute: subjective
+ value: нет
+ register: set_attribute_value_unicode
+
+ - name: Add trailing newline
+ shell: echo "" >> /tmp/ansible-xml-beers.xml
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-set-attribute-value-unicode.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - set_attribute_value_unicode is changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-set-attribute-value-unicode.xml /tmp/ansible-xml-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-attribute-value.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-attribute-value.yml
new file mode 100644
index 000000000..2908e00aa
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-attribute-value.yml
@@ -0,0 +1,36 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers.xml
+ dest: /tmp/ansible-xml-beers.xml
+
+
+ - name: Set '/business/rating/@subjective' to 'false'
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/rating
+ attribute: subjective
+ value: 'false'
+ register: set_attribute_value
+
+ - name: Add trailing newline
+ shell: echo "" >> /tmp/ansible-xml-beers.xml
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-set-attribute-value.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - set_attribute_value is changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-set-attribute-value.xml /tmp/ansible-xml-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-children-elements-level.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-children-elements-level.yml
new file mode 100644
index 000000000..648f5b25a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-children-elements-level.yml
@@ -0,0 +1,81 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers.xml
+ dest: /tmp/ansible-xml-beers.xml
+
+
+ - name: Set child elements
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/beers
+ set_children: &children
+ - beer:
+ alcohol: "0.5"
+ name: 90 Minute IPA
+ _:
+ - Water:
+ liter: "0.2"
+ quantity: 200g
+ - Starch:
+ quantity: 10g
+ - Hops:
+ quantity: 50g
+ - Yeast:
+ quantity: 20g
+ - beer:
+ alcohol: "0.3"
+ name: Harvest Pumpkin Ale
+ _:
+ - Water:
+ liter: "0.2"
+ quantity: 200g
+ - Hops:
+ quantity: 25g
+ - Yeast:
+ quantity: 20g
+ register: set_children_elements_level
+
+ - name: Add trailing newline
+ shell: echo "" >> /tmp/ansible-xml-beers.xml
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-set-children-elements-level.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - set_children_elements_level is changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-set-children-elements-level.xml /tmp/ansible-xml-beers.xml
+
+
+ - name: Set child elements (again)
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/beers
+ set_children: *children
+ register: set_children_again
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-set-children-elements-level.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - set_children_again is not changed
+ - comparison is not changed # identical
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-children-elements-unicode.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-children-elements-unicode.yml
new file mode 100644
index 000000000..8c4fc1094
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-children-elements-unicode.yml
@@ -0,0 +1,53 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers.xml
+ dest: /tmp/ansible-xml-beers.xml
+
+
+ - name: Set child elements
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/beers
+ set_children: &children
+ - beer: Окское
+ - beer: Невское
+ register: set_children_elements_unicode
+
+ - name: Add trailing newline
+ shell: echo "" >> /tmp/ansible-xml-beers.xml
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-set-children-elements-unicode.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - set_children_elements_unicode is changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-set-children-elements-unicode.xml /tmp/ansible-xml-beers.xml
+
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-set-children-elements-unicode.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - set_children_again is not changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-set-children-elements-unicode.xml /tmp/ansible-xml-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-children-elements.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-children-elements.yml
new file mode 100644
index 000000000..ed9e4a54e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-children-elements.yml
@@ -0,0 +1,86 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers.xml
+ dest: /tmp/ansible-xml-beers.xml
+
+ - name: Set child elements - empty list
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/beers
+ set_children: []
+ register: set_children_elements
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-set-children-elements-empty-list.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - set_children_elements is changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-set-children-elements.xml /tmp/ansible-xml-beers.xml
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers.xml
+ dest: /tmp/ansible-xml-beers.xml
+
+ - name: Set child elements
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/beers
+ set_children: &children
+ - beer: 90 Minute IPA
+ - beer: Harvest Pumpkin Ale
+ register: set_children_elements
+
+ - name: Add trailing newline
+ shell: echo "" >> /tmp/ansible-xml-beers.xml
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-set-children-elements.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - set_children_elements is changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-set-children-elements.xml /tmp/ansible-xml-beers.xml
+
+
+ - name: Set child elements (again)
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/beers
+ set_children: *children
+ register: set_children_again
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-set-children-elements.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - set_children_again is not changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-set-children-elements.xml /tmp/ansible-xml-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-element-value-empty.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-element-value-empty.yml
new file mode 100644
index 000000000..4041bf910
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-element-value-empty.yml
@@ -0,0 +1,35 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers.xml
+ dest: /tmp/ansible-xml-beers.xml
+
+
+ - name: Set '/business/website/address' to empty string.
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/website/address
+ value: ''
+ register: set_element_value_empty
+
+ - name: Add trailing newline
+ shell: echo "" >> /tmp/ansible-xml-beers.xml
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-set-element-value-empty.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - set_element_value_empty is changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-set-element-value-empty.xml /tmp/ansible-xml-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-element-value-unicode.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-element-value-unicode.yml
new file mode 100644
index 000000000..616f26ddc
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-element-value-unicode.yml
@@ -0,0 +1,50 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers.xml
+ dest: /tmp/ansible-xml-beers.xml
+
+
+ - name: Add 2nd '/business/rating' with value 'пять'
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business
+ add_children:
+ - rating: пять
+
+ - name: Set '/business/rating' to 'пять'
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/rating
+ value: пять
+ register: set_element_first_run
+
+ - name: Set '/business/rating' to 'false'... again
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/rating
+ value: пять
+ register: set_element_second_run
+
+ - name: Add trailing newline
+ shell: echo "" >> /tmp/ansible-xml-beers.xml
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-set-element-value-unicode.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - set_element_first_run is changed
+ - set_element_second_run is not changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-set-element-value-unicode.xml /tmp/ansible-xml-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-element-value.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-element-value.yml
new file mode 100644
index 000000000..b563b2576
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-element-value.yml
@@ -0,0 +1,50 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-beers.xml
+ dest: /tmp/ansible-xml-beers.xml
+
+
+ - name: Add 2nd '/business/rating' with value '5'
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business
+ add_children:
+ - rating: '5'
+
+ - name: Set '/business/rating' to '5'
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/rating
+ value: '5'
+ register: set_element_first_run
+
+ - name: Set '/business/rating' to '5'... again
+ xml:
+ path: /tmp/ansible-xml-beers.xml
+ xpath: /business/rating
+ value: '5'
+ register: set_element_second_run
+
+ - name: Add trailing newline
+ shell: echo "" >> /tmp/ansible-xml-beers.xml
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-set-element-value.xml
+ dest: /tmp/ansible-xml-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - set_element_first_run is changed
+ - set_element_second_run is not changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-set-element-value.xml /tmp/ansible-xml-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-namespaced-attribute-value.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-namespaced-attribute-value.yml
new file mode 100644
index 000000000..7c1bbd237
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-namespaced-attribute-value.yml
@@ -0,0 +1,41 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-namespaced-beers.xml
+ dest: /tmp/ansible-xml-namespaced-beers.xml
+
+
+ - name: Set namespaced '/bus:business/rat:rating/@attr:subjective' to 'false'
+ xml:
+ path: /tmp/ansible-xml-namespaced-beers.xml
+ xpath: /bus:business/rat:rating
+ namespaces:
+ bus: http://test.business
+ ber: http://test.beers
+ rat: http://test.rating
+ attr: http://test.attribute
+ attribute: attr:subjective
+ value: 'false'
+ register: set_namespaced_attribute_value
+
+ - name: Add trailing newline
+ shell: echo "" >> /tmp/ansible-xml-namespaced-beers.xml
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-set-namespaced-attribute-value.xml
+ dest: /tmp/ansible-xml-namespaced-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - set_namespaced_attribute_value is changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-set-namespaced-attribute-value.xml /tmp/ansible-xml-namespaced-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-namespaced-children-elements.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-namespaced-children-elements.yml
new file mode 100644
index 000000000..e6ed1bdec
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-namespaced-children-elements.yml
@@ -0,0 +1,61 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-namespaced-beers.xml
+ dest: /tmp/ansible-xml-namespaced-beers-xml.xml
+
+ - name: Set child elements
+ xml:
+ path: /tmp/ansible-xml-namespaced-beers-xml.xml
+ xpath: /bus:business/ber:beers
+ namespaces:
+ bus: http://test.business
+ ber: http://test.beers
+ set_children:
+ - beer: 90 Minute IPA
+ - beer: Harvest Pumpkin Ale
+
+ - name: Copy state after first set_children
+ copy:
+ src: /tmp/ansible-xml-namespaced-beers.xml
+ dest: /tmp/ansible-xml-namespaced-beers-1.xml
+ remote_src: true
+
+ - name: Set child elements again
+ xml:
+ path: /tmp/ansible-xml-namespaced-beers-xml.xml
+ xpath: /bus:business/ber:beers
+ namespaces:
+ bus: http://test.business
+ ber: http://test.beers
+ set_children:
+ - beer: 90 Minute IPA
+ - beer: Harvest Pumpkin Ale
+ register: set_children_again
+
+ - name: Copy state after second set_children
+ copy:
+ src: /tmp/ansible-xml-namespaced-beers.xml
+ dest: /tmp/ansible-xml-namespaced-beers-2.xml
+ remote_src: true
+
+ - name: Compare to expected result
+ copy:
+ src: /tmp/ansible-xml-namespaced-beers-1.xml
+ dest: /tmp/ansible-xml-namespaced-beers-2.xml
+ remote_src: true
+ check_mode: true
+ diff: true
+ register: comparison
+ #command: diff /tmp/ansible-xml-namespaced-beers-1.xml /tmp/ansible-xml-namespaced-beers-2.xml
+
+ - name: Test expected result
+ assert:
+ that:
+ - set_children_again is not changed # idempotency
+ - set_namespaced_attribute_value is changed
+ - comparison is not changed # identical
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-namespaced-element-value.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-namespaced-element-value.yml
new file mode 100644
index 000000000..9944da8a5
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-set-namespaced-element-value.yml
@@ -0,0 +1,53 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Setup test fixture
+ copy:
+ src: fixtures/ansible-xml-namespaced-beers.xml
+ dest: /tmp/ansible-xml-namespaced-beers.xml
+
+
+ - name: Set namespaced '/bus:business/rat:rating' to '11'
+ xml:
+ path: /tmp/ansible-xml-namespaced-beers.xml
+ namespaces:
+ bus: http://test.business
+ ber: http://test.beers
+ rat: http://test.rating
+ attr: http://test.attribute
+ xpath: /bus:business/rat:rating
+ value: '11'
+ register: set_element_first_run
+
+ - name: Set namespaced '/bus:business/rat:rating' to '11' again
+ xml:
+ path: /tmp/ansible-xml-namespaced-beers.xml
+ namespaces:
+ bus: http://test.business
+ ber: http://test.beers
+ rat: http://test.rating
+ attr: http://test.attribute
+ xpath: /bus:business/rat:rating
+ value: '11'
+ register: set_element_second_run
+
+ - name: Add trailing newline
+ shell: echo "" >> /tmp/ansible-xml-namespaced-beers.xml
+
+ - name: Compare to expected result
+ copy:
+ src: results/test-set-namespaced-element-value.xml
+ dest: /tmp/ansible-xml-namespaced-beers.xml
+ check_mode: true
+ diff: true
+ register: comparison
+ #command: diff -u {{ role_path }}/results/test-set-namespaced-element-value.xml /tmp/ansible-xml-namespaced-beers.xml
+
+ - name: Test expected result
+ assert:
+ that:
+ - set_element_first_run is changed
+ - set_element_second_run is not changed
+ - comparison is not changed # identical
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-xmlstring.yml b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-xmlstring.yml
new file mode 100644
index 000000000..1c2e4de4a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/tasks/test-xmlstring.yml
@@ -0,0 +1,85 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+ - name: Copy expected results to remote
+ copy:
+ src: "results/{{ item }}"
+ dest: "/tmp/{{ item }}"
+ with_items:
+ - test-pretty-print.xml
+ - test-pretty-print-only.xml
+
+ # NOTE: Jinja2 templating eats trailing newlines
+ - name: Read from xmlstring (not using pretty_print)
+ xml:
+ xmlstring: "{{ lookup('file', '{{ role_path }}/fixtures/ansible-xml-beers.xml') }}"
+ xpath: .
+ register: xmlresponse
+
+ - name: Compare to expected result
+ copy:
+ content: "{{ xmlresponse.xmlstring }}\n"
+ dest: '/tmp/test-pretty-print-only.xml'
+ check_mode: true
+ diff: true
+ register: comparison
+
+ - name: Test expected result
+ assert:
+ that:
+ - xmlresponse is not changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-pretty-print-only.xml /tmp/ansible-xml-beers.xml
+
+
+ # NOTE: Jinja2 templating eats trailing newlines
+ - name: Read from xmlstring (using pretty_print)
+ xml:
+ xmlstring: "{{ lookup('file', '{{ role_path }}/fixtures/ansible-xml-beers.xml') }}"
+ pretty_print: true
+ register: xmlresponse
+
+ - name: Compare to expected result
+ copy:
+ content: '{{ xmlresponse.xmlstring }}'
+ dest: '/tmp/test-pretty-print-only.xml'
+ check_mode: true
+ diff: true
+ register: comparison
+
+ # FIXME: This change is related to the newline added by pretty_print
+ - name: Test expected result
+ assert:
+ that:
+ - xmlresponse is changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-pretty-print-only.xml /tmp/ansible-xml-beers.xml
+
+
+ # NOTE: Jinja2 templating eats trailing newlines
+ - name: Read from xmlstring
+ xml:
+ xmlstring: "{{ lookup('file', '{{ role_path }}/fixtures/ansible-xml-beers.xml') }}"
+ xpath: /business/beers
+ pretty_print: true
+ add_children:
+ - beer: Old Rasputin
+ register: xmlresponse_modification
+
+ - name: Compare to expected result
+ copy:
+ content: '{{ xmlresponse_modification.xmlstring }}'
+ dest: '/tmp/test-pretty-print.xml'
+ check_mode: true
+ diff: true
+ register: comparison
+
+ # FIXME: This change is related to the newline added by pretty_print
+ - name: Test expected result
+ assert:
+ that:
+ - xmlresponse_modification is changed
+ - comparison is not changed # identical
+ #command: diff -u {{ role_path }}/results/test-pretty-print.xml /tmp/ansible-xml-beers.xml
diff --git a/ansible_collections/community/general/tests/integration/targets/xml/vars/main.yml b/ansible_collections/community/general/tests/integration/targets/xml/vars/main.yml
new file mode 100644
index 000000000..a8dfc2396
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/xml/vars/main.yml
@@ -0,0 +1,11 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# -*- mode: yaml -*
+
+bad_beers:
+- beer: "Natty Lite"
+- beer: "Miller Lite"
+- beer: "Coors Lite"
diff --git a/ansible_collections/community/general/tests/integration/targets/yarn/aliases b/ansible_collections/community/general/tests/integration/targets/yarn/aliases
new file mode 100644
index 000000000..cb1bc115a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/yarn/aliases
@@ -0,0 +1,8 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+destructive
+skip/aix
+skip/freebsd
diff --git a/ansible_collections/community/general/tests/integration/targets/yarn/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/yarn/meta/main.yml
new file mode 100644
index 000000000..6147ad33e
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/yarn/meta/main.yml
@@ -0,0 +1,9 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_pkg_mgr
+ - setup_gnutar
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/yarn/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/yarn/tasks/main.yml
new file mode 100644
index 000000000..e12d891c2
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/yarn/tasks/main.yml
@@ -0,0 +1,23 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Yarn package manager integration tests
+# Copyright (c) 2018 David Gunter, <david.gunter@tivix.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+# ============================================================
+
+- include_tasks: run.yml
+ vars:
+ nodejs_version: '{{ item.node_version }}'
+ nodejs_path: 'node-v{{ nodejs_version }}-{{ ansible_system|lower }}-x{{ ansible_userspace_bits }}'
+ yarn_version: '{{ item.yarn_version }}'
+ with_items:
+ - {node_version: 4.8.0, yarn_version: 1.6.0} # Lowest compatible nodejs version
+ - {node_version: 8.0.0, yarn_version: 1.6.0}
+ when:
+ - not (ansible_os_family == 'Alpine') # TODO
diff --git a/ansible_collections/community/general/tests/integration/targets/yarn/tasks/run.yml b/ansible_collections/community/general/tests/integration/targets/yarn/tasks/run.yml
new file mode 100644
index 000000000..0d7d6fb42
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/yarn/tasks/run.yml
@@ -0,0 +1,233 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: 'Create directory for Node'
+ file:
+ path: /usr/local/lib/nodejs
+ state: directory
+
+- name: 'Download Nodejs'
+ unarchive:
+ src: 'https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/yarn/{{ nodejs_path }}.tar.gz'
+ dest: '{{ remote_tmp_dir }}'
+ remote_src: true
+ creates: '{{ remote_tmp_dir }}/{{ nodejs_path }}.tar.gz'
+
+- name: 'Download Yarn'
+ unarchive:
+ src: 'https://ansible-ci-files.s3.amazonaws.com/test/integration/targets/yarn/yarn-v{{yarn_version}}.tar.gz'
+ dest: '{{ remote_tmp_dir }}'
+ remote_src: true
+ creates: '{{ remote_tmp_dir }}/yarn-v{{yarn_version}}_pkg.tar.gz'
+
+- name: 'Copy node to directory created earlier'
+ command: "mv {{ remote_tmp_dir }}/{{ nodejs_path }} /usr/local/lib/nodejs/{{nodejs_path}}"
+
+# Clean up before running tests
+- name: Remove any previous Nodejs modules
+ file:
+ path: '{{remote_tmp_dir}}/node_modules'
+ state: absent
+
+# Set vars for our test harness
+- vars:
+ #node_bin_path: "/usr/local/lib/nodejs/node-v{{nodejs_version}}/bin"
+ node_bin_path: "/usr/local/lib/nodejs/{{ nodejs_path }}/bin"
+ yarn_bin_path: "{{ remote_tmp_dir }}/yarn-v{{ yarn_version }}/bin"
+ package: 'iconv-lite'
+ environment:
+ PATH: "{{ node_bin_path }}:{{ansible_env.PATH}}"
+ YARN_IGNORE_ENGINES: true
+ block:
+
+ # Get the version of Yarn and register to a variable
+ - shell: '{{ yarn_bin_path }}/yarn --version'
+ environment:
+ PATH: '{{ node_bin_path }}:{{ ansible_env.PATH }}'
+ register: yarn_version
+
+ - name: 'Create dummy package.json'
+ template:
+ src: package.j2
+ dest: '{{ remote_tmp_dir }}/package.json'
+
+ - name: 'Install all packages.'
+ yarn:
+ path: '{{ remote_tmp_dir }}'
+ executable: '{{ yarn_bin_path }}/yarn'
+ state: present
+ environment:
+ PATH: '{{ node_bin_path }}:{{ ansible_env.PATH }}'
+
+ - name: 'Install the same package from package.json again.'
+ yarn:
+ path: '{{ remote_tmp_dir }}'
+ executable: '{{ yarn_bin_path }}/yarn'
+ name: '{{ package }}'
+ state: present
+ environment:
+ PATH: '{{ node_bin_path }}:{{ ansible_env.PATH }}'
+ register: yarn_install
+
+ - assert:
+ that:
+ - not (yarn_install is changed)
+
+ - name: 'Install all packages in check mode.'
+ yarn:
+ path: '{{ remote_tmp_dir }}'
+ executable: '{{ yarn_bin_path }}/yarn'
+ state: present
+ environment:
+ PATH: '{{ node_bin_path }}:{{ ansible_env.PATH }}'
+ check_mode: true
+ register: yarn_install_check
+
+ - name: verify test yarn global installation in check mode
+ assert:
+ that:
+ - yarn_install_check.err is defined
+ - yarn_install_check.out is defined
+ - yarn_install_check.err is none
+ - yarn_install_check.out is none
+
+ - name: 'Install package with explicit version (older version of package)'
+ yarn:
+ path: '{{ remote_tmp_dir }}'
+ executable: '{{ yarn_bin_path }}/yarn'
+ name: left-pad
+ version: 1.1.0
+ state: present
+ environment:
+ PATH: '{{ node_bin_path }}:{{ ansible_env.PATH }}'
+ register: yarn_install_old_package
+
+ - assert:
+ that:
+ - yarn_install_old_package is changed
+
+ - name: 'Again but without explicit executable path'
+ yarn:
+ path: '{{ remote_tmp_dir }}'
+ name: left-pad
+ version: 1.1.0
+ state: present
+ environment:
+ PATH: '{{ yarn_bin_path }}:{{ node_bin_path }}:{{ ansible_env.PATH }}'
+
+ - name: 'Upgrade old package'
+ yarn:
+ path: '{{ remote_tmp_dir }}'
+ executable: '{{ yarn_bin_path }}/yarn'
+ name: left-pad
+ state: latest
+ environment:
+ PATH: '{{ node_bin_path }}:{{ ansible_env.PATH }}'
+ register: yarn_update_old_package
+
+ - assert:
+ that:
+ - yarn_update_old_package is changed
+
+ - name: 'Remove a package'
+ yarn:
+ path: '{{ remote_tmp_dir }}'
+ executable: '{{ yarn_bin_path }}/yarn'
+ name: '{{ package }}'
+ state: absent
+ environment:
+ PATH: '{{ node_bin_path }}:{{ ansible_env.PATH }}'
+ register: yarn_uninstall_package
+
+ - name: 'Assert package removed'
+ assert:
+ that:
+ - yarn_uninstall_package is changed
+
+ - name: 'Global install binary with explicit version (older version of package)'
+ yarn:
+ global: true
+ executable: '{{ yarn_bin_path }}/yarn'
+ name: prettier
+ version: 2.0.0
+ state: present
+ environment:
+ PATH: '{{ node_bin_path }}:{{ ansible_env.PATH }}'
+ register: yarn_global_install_old_binary
+
+ - assert:
+ that:
+ - yarn_global_install_old_binary is changed
+
+ - name: 'Global upgrade old binary'
+ yarn:
+ global: true
+ executable: '{{ yarn_bin_path }}/yarn'
+ name: prettier
+ state: latest
+ environment:
+ PATH: '{{ node_bin_path }}:{{ ansible_env.PATH }}'
+ register: yarn_global_update_old_binary
+
+ - assert:
+ that:
+ - yarn_global_update_old_binary is changed
+
+ - name: 'Global remove a binary'
+ yarn:
+ global: true
+ executable: '{{ yarn_bin_path }}/yarn'
+ name: prettier
+ state: absent
+ environment:
+ PATH: '{{ node_bin_path }}:{{ ansible_env.PATH }}'
+ register: yarn_global_uninstall_binary
+
+ - assert:
+ that:
+ - yarn_global_uninstall_binary is changed
+
+ - name: 'Global install package with no binary with explicit version (older version of package)'
+ yarn:
+ global: true
+ executable: '{{ yarn_bin_path }}/yarn'
+ name: left-pad
+ version: 1.1.0
+ state: present
+ environment:
+ PATH: '{{ node_bin_path }}:{{ ansible_env.PATH }}'
+ register: yarn_global_install_old_package
+
+ - assert:
+ that:
+ - yarn_global_install_old_package is changed
+
+ - name: 'Global upgrade old package with no binary'
+ yarn:
+ global: true
+ executable: '{{ yarn_bin_path }}/yarn'
+ name: left-pad
+ state: latest
+ environment:
+ PATH: '{{ node_bin_path }}:{{ ansible_env.PATH }}'
+ register: yarn_global_update_old_package
+
+ - assert:
+ that:
+ - yarn_global_update_old_package is changed
+
+ - name: 'Global remove a package with no binary'
+ yarn:
+ global: true
+ executable: '{{ yarn_bin_path }}/yarn'
+ name: left-pad
+ state: absent
+ environment:
+ PATH: '{{ node_bin_path }}:{{ ansible_env.PATH }}'
+ register: yarn_global_uninstall_package
+
+ - assert:
+ that:
+ - yarn_global_uninstall_package is changed
diff --git a/ansible_collections/community/general/tests/integration/targets/yarn/templates/package.j2 b/ansible_collections/community/general/tests/integration/targets/yarn/templates/package.j2
new file mode 100644
index 000000000..3f5456ad2
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/yarn/templates/package.j2
@@ -0,0 +1,14 @@
+{#
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+#}
+{
+ "name": "ansible-yarn-testing",
+ "version": "1.0.0",
+ "license": "MIT",
+ "dependencies": {
+ "iconv-lite": "^0.4.21",
+ "@types/node": "^12.0.0"
+ }
+}
diff --git a/ansible_collections/community/general/tests/integration/targets/yum_versionlock/aliases b/ansible_collections/community/general/tests/integration/targets/yum_versionlock/aliases
new file mode 100644
index 000000000..ca3f7e796
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/yum_versionlock/aliases
@@ -0,0 +1,11 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+skip/aix
+skip/freebsd
+skip/osx
+skip/macos
+skip/rhel8.4 # TODO make sure that tests work on 8.4 as well!
+disabled # TODO
diff --git a/ansible_collections/community/general/tests/integration/targets/yum_versionlock/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/yum_versionlock/tasks/main.yml
new file mode 100644
index 000000000..05f1f7495
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/yum_versionlock/tasks/main.yml
@@ -0,0 +1,87 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Update procps-ng temporary until issue (#2539) is fixed
+ yum:
+ name: procps-ng
+ state: latest
+ when: ansible_distribution == 'Fedora' and ansible_distribution_major_version == '34'
+
+- block:
+ - name: Install necessary packages to test yum_versionlock
+ yum:
+ name: yum-plugin-versionlock
+ state: present
+ register: yum_versionlock_install
+
+ - name: Yum checkupdate
+ yum:
+ list: updates
+ register: yum_updates
+
+ - block:
+ - name: Lock all packages
+ community.general.yum_versionlock:
+ name: "{{ yum_updates.results | map(attribute='name') | list }}"
+ state: present
+ register: lock_all_packages
+
+ - name: Lock all packages again
+ community.general.yum_versionlock:
+ name: "{{ yum_updates.results | map(attribute='name') | list }}"
+ state: present
+ register: lock_all_packages_again
+
+ - name: Lock packages wildcard
+ community.general.yum_versionlock:
+ name: "nss*"
+ state: present
+ register: lock_nss_wildcard
+
+ # This should fail when it needs user interaction and missing -y is on purpose.
+ - name: Update all packages (not really)
+ command: yum update --setopt=obsoletes=0
+ register: update_all_locked_packages
+ changed_when:
+ - '"No packages marked for update" not in update_all_locked_packages.stdout'
+ - '"Nothing to do" not in update_all_locked_packages.stdout'
+
+ - name: Unlock all packages
+ community.general.yum_versionlock:
+ name: "{{ yum_updates.results | map(attribute='name') | list }}"
+ state: absent
+ register: unlock_all_packages
+
+ - name: Update all packages
+ yum:
+ name: '*'
+ state: latest
+ check_mode: true
+ register: update_all_packages
+ when: yum_updates.results | length != 0
+
+ - name: Assert everything is fine
+ assert:
+ that:
+ - lock_all_packages is changed
+ - lock_all_packages_again is not changed
+ - lock_nss_wildcard is not changed
+ - update_all_locked_packages is not changed
+ - unlock_all_packages is changed
+ - update_all_packages is changed
+ when: yum_updates.results | length != 0
+
+ - name: Remove installed packages in case it was not installed
+ yum:
+ name: yum-plugin-versionlock
+ state: absent
+ when: yum_versionlock_install is changed
+ when: (ansible_distribution in ['CentOS', 'RedHat'] and ansible_distribution_major_version is version('7', '>=')) or
+ (ansible_distribution == 'Fedora')
diff --git a/ansible_collections/community/general/tests/integration/targets/zypper/aliases b/ansible_collections/community/general/tests/integration/targets/zypper/aliases
new file mode 100644
index 000000000..e0a62a673
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/zypper/aliases
@@ -0,0 +1,11 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+destructive
+skip/aix
+skip/freebsd
+skip/osx
+skip/macos
+skip/rhel
diff --git a/ansible_collections/community/general/tests/integration/targets/zypper/files/empty.spec b/ansible_collections/community/general/tests/integration/targets/zypper/files/empty.spec
new file mode 100644
index 000000000..044ea3a54
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/zypper/files/empty.spec
@@ -0,0 +1,12 @@
+Summary: Empty RPM
+Name: empty
+Version: 1
+Release: 0
+License: GPLv3
+Group: Applications/System
+BuildArch: noarch
+
+%description
+Empty RPM
+
+%files
diff --git a/ansible_collections/community/general/tests/integration/targets/zypper/files/empty.spec.license b/ansible_collections/community/general/tests/integration/targets/zypper/files/empty.spec.license
new file mode 100644
index 000000000..edff8c768
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/zypper/files/empty.spec.license
@@ -0,0 +1,3 @@
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+SPDX-FileCopyrightText: Ansible Project
diff --git a/ansible_collections/community/general/tests/integration/targets/zypper/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/zypper/meta/main.yml
new file mode 100644
index 000000000..982de6eb0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/zypper/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/zypper/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/zypper/tasks/main.yml
new file mode 100644
index 000000000..185f2f90a
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/zypper/tasks/main.yml
@@ -0,0 +1,15 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# test code for the zypper module
+# Copyright 2015, Guido Günther <agx@sigxcpu.org>
+# heavily based on the yum tests which are
+# Copyright 2014, James Tanner <tanner.jc@gmail.com>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- include_tasks: 'zypper.yml'
+ when: ansible_os_family == 'Suse'
diff --git a/ansible_collections/community/general/tests/integration/targets/zypper/tasks/zypper.yml b/ansible_collections/community/general/tests/integration/targets/zypper/tasks/zypper.yml
new file mode 100644
index 000000000..3eefddbdf
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/zypper/tasks/zypper.yml
@@ -0,0 +1,530 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: get hello package version
+ shell: zypper --xmlout se -svx hello | grep 'name="hello"' | grep 'repository="Main Repository"' | sed 's/.*edition="\([^ ]*\)".*/\1/'
+ register: hello_version
+
+- name: set URL of test package
+ set_fact:
+ hello_package_url: https://download.opensuse.org/distribution/leap/{{ ansible_distribution_version }}/repo/oss/x86_64/hello-{{ hello_version.stdout }}.x86_64.rpm
+
+- debug: var=hello_package_url
+
+# UNINSTALL
+- name: uninstall hello
+ zypper:
+ name: hello
+ state: removed
+ register: zypper_result
+
+- name: check hello with rpm
+ shell: rpm -q hello
+ failed_when: false
+ register: rpm_result
+
+- debug: var=zypper_result
+- debug: var=rpm_result
+
+- name: verify uninstallation of hello
+ assert:
+ that:
+ - "zypper_result.rc == 0"
+ - "rpm_result.rc == 1"
+
+# UNINSTALL AGAIN
+- name: uninstall hello again
+ zypper:
+ name: hello
+ state: removed
+ register: zypper_result
+
+- name: verify no change on re-uninstall
+ assert:
+ that:
+ - "not zypper_result.changed"
+
+# INSTALL
+- name: install hello
+ zypper:
+ name: hello
+ state: present
+ register: zypper_result
+
+- name: check hello with rpm
+ shell: rpm -q hello
+ failed_when: false
+ register: rpm_result
+
+- debug: var=zypper_result
+- debug: var=rpm_result
+
+- name: verify installation of hello
+ assert:
+ that:
+ - "zypper_result.rc == 0"
+ - "zypper_result.changed"
+ - "rpm_result.rc == 0"
+
+# INSTALL AGAIN
+- name: install hello again
+ zypper:
+ name: hello
+ state: present
+ register: zypper_result
+
+- name: verify no change on second install
+ assert:
+ that:
+ - "not zypper_result.changed"
+
+# Multiple packages
+- name: uninstall hello and metamail
+ zypper:
+ name:
+ - hello
+ - metamail
+ state: removed
+ register: zypper_result
+
+- name: check hello with rpm
+ shell: rpm -q hello
+ failed_when: false
+ register: rpm_hello_result
+
+- name: check metamail with rpm
+ shell: rpm -q metamail
+ failed_when: false
+ register: rpm_metamail_result
+
+- name: verify packages uninstalled
+ assert:
+ that:
+ - "rpm_hello_result.rc != 0"
+ - "rpm_metamail_result.rc != 0"
+
+- name: install hello and metamail
+ zypper:
+ name:
+ - hello
+ - metamail
+ state: present
+ register: zypper_result
+
+- name: check hello with rpm
+ shell: rpm -q hello
+ failed_when: false
+ register: rpm_hello_result
+
+- name: check metamail with rpm
+ shell: rpm -q metamail
+ failed_when: false
+ register: rpm_metamail_result
+
+- name: verify packages installed
+ assert:
+ that:
+ - "zypper_result.rc == 0"
+ - "zypper_result.changed"
+ - "rpm_hello_result.rc == 0"
+ - "rpm_metamail_result.rc == 0"
+
+- name: uninstall hello and metamail
+ zypper:
+ name:
+ - hello
+ - metamail
+ state: removed
+
+# INSTALL nonexistent package
+- name: install hello from url
+ zypper:
+ name: doesnotexist
+ state: present
+ register: zypper_result
+ ignore_errors: true
+
+- name: verify package installation failed
+ assert:
+ that:
+ - "zypper_result.rc == 104"
+ - "zypper_result.msg.startswith('No provider of')"
+
+# INSTALL broken local package
+- name: create directory
+ file:
+ path: "{{remote_tmp_dir | expanduser}}/zypper1"
+ state: directory
+
+- name: fake rpm package
+ file:
+ path: "{{remote_tmp_dir | expanduser}}/zypper1/broken.rpm"
+ state: touch
+
+- name: install broken rpm
+ zypper:
+ name: "{{remote_tmp_dir | expanduser}}/zypper1/broken.rpm"
+ state: present
+ register: zypper_result
+ ignore_errors: true
+
+- debug: var=zypper_result
+
+- name: verify we failed installation of broken rpm
+ assert:
+ that:
+ - "zypper_result.rc == 3"
+ - "'Problem reading the RPM header' in zypper_result.stdout"
+
+# Build and install an empty rpm
+- name: uninstall empty
+ zypper:
+ name: empty
+ state: removed
+
+- name: install rpmbuild
+ zypper:
+ name: rpmbuild
+ state: present
+
+- name: clean zypper RPM cache
+ file:
+ name: /var/cache/zypper/RPMS
+ state: absent
+
+- name: create directory
+ file:
+ path: "{{remote_tmp_dir | expanduser}}/zypper2"
+ state: directory
+
+- name: copy spec file
+ copy:
+ src: empty.spec
+ dest: "{{ remote_tmp_dir | expanduser }}/zypper2/empty.spec"
+
+- name: build rpm
+ command: |
+ rpmbuild -bb \
+ --define "_topdir {{remote_tmp_dir | expanduser }}/zypper2/rpm-build"
+ --define "_builddir %{_topdir}" \
+ --define "_rpmdir %{_topdir}" \
+ --define "_srcrpmdir %{_topdir}" \
+ --define "_specdir {{remote_tmp_dir | expanduser}}/zypper2" \
+ --define "_sourcedir %{_topdir}" \
+ {{ remote_tmp_dir }}/zypper2/empty.spec
+ register: rpm_build_result
+
+- name: install empty rpm
+ zypper:
+ name: "{{ remote_tmp_dir | expanduser }}/zypper2/rpm-build/noarch/empty-1-0.noarch.rpm"
+ disable_gpg_check: true
+ register: zypper_result
+
+- name: check empty with rpm
+ shell: rpm -q empty
+ failed_when: false
+ register: rpm_result
+
+- name: verify installation of empty
+ assert:
+ that:
+ - "zypper_result.rc == 0"
+ - "zypper_result.changed"
+ - "rpm_result.rc == 0"
+
+- name: uninstall empty
+ zypper:
+ name: empty
+ state: removed
+
+- name: extract from rpm
+ zypper:
+ name: "{{ remote_tmp_dir | expanduser }}/zypper2/rpm-build/noarch/empty-1-0.noarch.rpm"
+ state: installed
+ disable_gpg_check: true
+ extra_args_precommand: --root {{ remote_tmp_dir | expanduser }}/testdir/
+
+- name: check that dir var is exist
+ stat: path={{ remote_tmp_dir | expanduser }}/testdir/var
+ register: stat_result
+
+- name: check that we extract rpm package in testdir folder and folder var is exist
+ assert:
+ that:
+ - "stat_result.stat.exists == true"
+
+
+# test simultaneous remove and install using +- prefixes
+
+- name: install hello to prep next task
+ zypper:
+ name: hello
+ state: present
+
+- name: remove metamail to prep next task
+ zypper:
+ name: metamail
+ state: absent
+
+- name: install and remove in the same run, with +- prefix
+ zypper:
+ name:
+ - -hello
+ - +metamail
+ state: present
+ register: zypper_res1
+
+- name: install and remove again, leave out plus
+ zypper:
+ name:
+ - metamail
+ - -hello
+ state: present
+ register: zypper_res1a
+
+- name: in and rm swapped
+ zypper:
+ name:
+ - -metamail
+ - hello
+ state: present
+ register: zypper_res1b
+
+- name: install metamail
+ zypper:
+ name: metamail
+ state: absent
+ register: zypper_res2
+
+- name: remove hello
+ zypper:
+ name: hello
+ state: present
+ register: zypper_res3
+
+- name: verify simultaneous install/remove worked
+ assert:
+ that:
+ - zypper_res1 is successful
+ - zypper_res1 is changed
+ - zypper_res1a is not changed
+ - zypper_res1b is changed
+ - zypper_res2 is not changed
+ - zypper_res3 is not changed
+
+
+- name: install and remove with state=absent
+ zypper:
+ name:
+ - metamail
+ - +hello
+ state: absent
+ register: zypper_res
+ ignore_errors: true
+
+- name: verify simultaneous install/remove failed with absent
+ assert:
+ that:
+ - zypper_res is failed
+ - zypper_res.msg == "Can not combine '+' prefix with state=remove/absent."
+
+- name: try rm patch
+ zypper:
+ name: openSUSE-2016-128
+ type: patch
+ state: absent
+ ignore_errors: true
+ register: zypper_patch
+- assert:
+ that:
+ - zypper_patch is failed
+ - zypper_patch.msg.startswith('Can not remove patches.')
+
+- name: try rm URL
+ zypper:
+ name: "{{ hello_package_url }}"
+ state: absent
+ ignore_errors: true
+ register: zypper_rm
+- assert:
+ that:
+ - zypper_rm is failed
+ - zypper_rm.msg.startswith('Can not remove via URL.')
+
+- name: remove pattern update_test
+ zypper:
+ name: update_test
+ type: pattern
+ state: absent
+
+- name: install pattern update_test
+ zypper:
+ name: update_test
+ type: pattern
+ state: present
+ register: zypper_install_pattern1
+
+- name: install pattern update_test again
+ zypper:
+ name: update_test
+ type: pattern
+ state: present
+ register: zypper_install_pattern2
+
+- assert:
+ that:
+ - zypper_install_pattern1 is changed
+ - zypper_install_pattern2 is not changed
+
+- name: remove hello
+ zypper:
+ name: hello
+ state: absent
+
+- name: install via URL
+ zypper:
+ state: present
+ name: "{{ hello_package_url }}"
+ register: zypperin1
+
+- name: test install
+ zypper:
+ name: hello
+ state: present
+ register: zypperin2
+
+- assert:
+ that:
+ - zypperin1 is succeeded
+ - zypperin1 is changed
+ - zypperin2 is not changed
+
+# check for https://github.com/ansible/ansible/issues/20139
+- name: run updatecache
+ zypper:
+ name: hello
+ state: present
+ update_cache: true
+ register: zypper_result_update_cache
+
+- name: run updatecache in check mode
+ zypper:
+ name: hello
+ state: present
+ update_cache: true
+ check_mode: true
+ register: zypper_result_update_cache_check
+
+
+- assert:
+ that:
+ - zypper_result_update_cache is successful
+ - zypper_result_update_cache_check is successful
+ - zypper_result_update_cache_check is not changed
+
+# - name: ensure no previous netcat package still exists
+# zypper:
+# name:
+# - netcat-openbsd
+# - gnu-netcat
+# state: absent
+#
+# - name: install netcat-openbsd which conflicts with gnu-netcat
+# zypper:
+# name: netcat-openbsd
+# state: present
+#
+# - name: try installation of gnu-netcat which should fail due to the conflict
+# zypper:
+# name: gnu-netcat
+# state: present
+# ignore_errors: true
+# register: zypper_pkg_conflict
+#
+# - assert:
+# that:
+# - zypper_pkg_conflict is failed
+# - "'conflicts with netcat-openbsd provided' in zypper_pkg_conflict.stdout"
+#
+# - name: retry installation of gnu-netcat with force_resolution set to choose a resolution
+# zypper:
+# name: gnu-netcat
+# state: present
+# force_resolution: True
+
+- name: duplicate rpms block
+ vars:
+ looplist:
+ - 1
+ - 2
+ block:
+ - name: Deploy spec files to build 2 packages with duplicate files.
+ template:
+ src: duplicate.spec.j2
+ dest: "{{ remote_tmp_dir | expanduser }}/zypper2/duplicate{{ item }}.spec"
+ loop: "{{ looplist }}"
+
+ - name: build rpms with duplicate files
+ command: |
+ rpmbuild -bb \
+ --define "_topdir {{remote_tmp_dir | expanduser }}/zypper2/rpm-build"
+ --define "_builddir %{_topdir}" \
+ --define "_rpmdir %{_topdir}" \
+ --define "_srcrpmdir %{_topdir}" \
+ --define "_specdir {{remote_tmp_dir | expanduser}}/zypper2" \
+ --define "_sourcedir %{_topdir}" \
+ {{ remote_tmp_dir | expanduser }}/zypper2/duplicate{{ item }}.spec
+ loop: "{{ looplist }}"
+
+ - name: install duplicate rpms
+ zypper:
+ name: >-
+ {{ remote_tmp_dir | expanduser }}/zypper2/rpm-build/noarch/duplicate{{ item }}-1-0.noarch.rpm
+ disable_gpg_check: true
+ ignore_errors: true
+ register: zypper_duplicate_result
+ loop: "{{ looplist }}"
+
+ - name: Read in duplicate file contents
+ slurp:
+ src: /usr/lib/duplicate/duplicate.txt
+ register: duplicate_out
+
+ - name: Check failure when installing rpms with duplicate files without replacefiles option
+ assert:
+ that:
+ - zypper_duplicate_result.results[0] is successful
+ - zypper_duplicate_result.results[1] is failed
+ - '"fileconflict" in zypper_duplicate_result.results[1].stdout'
+ - '"/usr/lib/duplicate/duplicate.txt" in zypper_duplicate_result.results[1].stdout'
+ - '"duplicate1" in duplicate_out.content | b64decode'
+
+ - name: install duplicate rpms
+ zypper:
+ name: >-
+ {{ remote_tmp_dir | expanduser }}/zypper2/rpm-build/noarch/duplicate{{ item }}-1-0.noarch.rpm
+ disable_gpg_check: true
+ replacefiles: true
+ ignore_errors: true
+ register: zypper_duplicate_result
+ loop: "{{ looplist }}"
+
+ - name: Read in duplicate file contents
+ slurp:
+ src: /usr/lib/duplicate/duplicate.txt
+ register: duplicate_out
+
+ - name: Check success installing rpms with duplicate files using replacefiles option
+ assert:
+ that:
+ - zypper_duplicate_result is successful
+ - zypper_duplicate_result is changed
+ - '"duplicate2" in duplicate_out.content | b64decode'
+
+ - name: Remove installed duplicate rpms
+ zypper:
+ name: "duplicate{{ item }}-1-0"
+ state: absent
+ loop: "{{ looplist }}"
diff --git a/ansible_collections/community/general/tests/integration/targets/zypper/templates/duplicate.spec.j2 b/ansible_collections/community/general/tests/integration/targets/zypper/templates/duplicate.spec.j2
new file mode 100644
index 000000000..6f63b665c
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/zypper/templates/duplicate.spec.j2
@@ -0,0 +1,24 @@
+{#
+Copyright (c) Ansible Project
+GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+SPDX-License-Identifier: GPL-3.0-or-later
+#}
+
+Summary: Duplicate{{ item }} RPM. Installs one file that is a duplicate of other Duplicate# RPMs
+Name: duplicate{{ item }}
+Version: 1
+Release: 0
+License: GPLv3
+Group: Applications/System
+BuildArch: noarch
+
+%description
+Duplicate {{ item }} RPM. Package one file that will be a duplicate of other Duplicate RPM contents.
+This is only for testing of the replacefiles zypper option.
+
+%install
+mkdir -p "%{buildroot}/usr/lib/duplicate"
+echo "%{name}" > "%{buildroot}/usr/lib/duplicate/duplicate.txt"
+
+%files
+/usr/lib/duplicate/duplicate.txt
diff --git a/ansible_collections/community/general/tests/integration/targets/zypper_repository/aliases b/ansible_collections/community/general/tests/integration/targets/zypper_repository/aliases
new file mode 100644
index 000000000..e0a62a673
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/zypper_repository/aliases
@@ -0,0 +1,11 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+azp/posix/1
+destructive
+skip/aix
+skip/freebsd
+skip/osx
+skip/macos
+skip/rhel
diff --git a/ansible_collections/community/general/tests/integration/targets/zypper_repository/files/systemsmanagement_Uyuni_Utils.repo b/ansible_collections/community/general/tests/integration/targets/zypper_repository/files/systemsmanagement_Uyuni_Utils.repo
new file mode 100644
index 000000000..aaa486d92
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/zypper_repository/files/systemsmanagement_Uyuni_Utils.repo
@@ -0,0 +1,11 @@
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+[systemsmanagement_Uyuni_Utils]
+name=Several utilities to develop, build or release Uyuni (openSUSE_Leap_15.3)
+type=rpm-md
+baseurl=https://download.opensuse.org/repositories/systemsmanagement:/Uyuni:/Utils/openSUSE_Leap_15.3/
+gpgcheck=1
+gpgkey=https://download.opensuse.org/repositories/systemsmanagement:/Uyuni:/Utils/openSUSE_Leap_15.3/repodata/repomd.xml.key
+enabled=1
diff --git a/ansible_collections/community/general/tests/integration/targets/zypper_repository/meta/main.yml b/ansible_collections/community/general/tests/integration/targets/zypper_repository/meta/main.yml
new file mode 100644
index 000000000..982de6eb0
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/zypper_repository/meta/main.yml
@@ -0,0 +1,7 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+dependencies:
+ - setup_remote_tmp_dir
diff --git a/ansible_collections/community/general/tests/integration/targets/zypper_repository/tasks/main.yml b/ansible_collections/community/general/tests/integration/targets/zypper_repository/tasks/main.yml
new file mode 100644
index 000000000..1d655a56f
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/zypper_repository/tasks/main.yml
@@ -0,0 +1,13 @@
+---
+####################################################################
+# WARNING: These are designed specifically for Ansible tests #
+# and should not be used as examples of how to write Ansible roles #
+####################################################################
+
+# test code for the zypper repository module
+# Copyright (c) 2016, Guido Günther <agx@sigxcpu.org>
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- include_tasks: 'test.yml'
+ when: ansible_os_family == 'Suse'
diff --git a/ansible_collections/community/general/tests/integration/targets/zypper_repository/tasks/test.yml b/ansible_collections/community/general/tests/integration/targets/zypper_repository/tasks/test.yml
new file mode 100644
index 000000000..739b4c264
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/zypper_repository/tasks/test.yml
@@ -0,0 +1,40 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: collect repo configuration before test
+ shell: "grep . /etc/zypp/repos.d/*"
+ register: before
+
+- name: ensure zypper ref works
+ command: zypper -n ref
+
+- block:
+ - include_tasks: 'zypper_repository.yml'
+ always:
+ - name: remove repositories added during test
+ community.general.zypper_repository:
+ name: "{{item}}"
+ state: absent
+ with_items:
+ - chrome1
+ - chrome2
+ - test
+ - testrefresh
+ - testprio
+ - Apache_PHP_Modules
+ - systemsmanagement_Uyuni_Stable
+ - systemsmanagement_Uyuni_Utils
+
+ - name: collect repo configuration after test
+ shell: "grep . /etc/zypp/repos.d/*"
+ register: after
+
+ - name: verify repo configuration has been restored
+ assert:
+ that:
+ - before.stdout == after.stdout
+
+ - name: ensure zypper ref still works
+ command: zypper -n ref
diff --git a/ansible_collections/community/general/tests/integration/targets/zypper_repository/tasks/zypper_repository.yml b/ansible_collections/community/general/tests/integration/targets/zypper_repository/tasks/zypper_repository.yml
new file mode 100644
index 000000000..ec362af10
--- /dev/null
+++ b/ansible_collections/community/general/tests/integration/targets/zypper_repository/tasks/zypper_repository.yml
@@ -0,0 +1,289 @@
+---
+# Copyright (c) Ansible Project
+# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+- name: Delete test repo
+ community.general.zypper_repository:
+ name: test
+ state: absent
+ register: zypper_result
+
+- name: verify no change on test repo deletion
+ assert:
+ that:
+ - "not zypper_result.changed"
+
+- name: Add test repo
+ community.general.zypper_repository:
+ name: test
+ state: present
+ repo: http://dl.google.com/linux/chrome/rpm/stable/x86_64
+ register: zypper_result
+
+- name: verify repo addition
+ assert:
+ that:
+ - "zypper_result.changed"
+
+- name: Add same repo again
+ community.general.zypper_repository:
+ name: test
+ state: present
+ repo: http://dl.google.com/linux/chrome/rpm/stable/x86_64
+ register: zypper_result
+
+- name: verify no change on second install
+ assert:
+ that:
+ - "not zypper_result.changed"
+
+- name: Change repo URL
+ community.general.zypper_repository:
+ name: test
+ state: present
+ repo: http://download.videolan.org/pub/vlc/SuSE/Leap_{{ ansible_distribution_version }}/
+ register: zypper_result
+
+- name: Verify change on URL only change
+ assert:
+ that:
+ - "zypper_result.changed"
+
+- name: use refresh option
+ community.general.zypper_repository:
+ name: testrefresh
+ refresh: false
+ state: present
+ repo: http://download.videolan.org/pub/vlc/SuSE/Leap_{{ ansible_distribution_version }}/
+
+- name: check refreshoption
+ command: zypper -x lr testrefresh
+ register: zypper_result
+
+- name: verify autorefresh option set properly
+ assert:
+ that:
+ - '"autorefresh=\"0\"" in zypper_result.stdout'
+
+- name: set repo priority
+ community.general.zypper_repository:
+ name: testprio
+ priority: 55
+ state: present
+ repo: http://download.videolan.org/pub/vlc/SuSE/Leap_{{ ansible_distribution_version }}/
+
+- name: check refreshoption
+ command: zypper -x lr testprio
+ register: zypper_result
+
+- name: verify priority option set properly
+ assert:
+ that:
+ - '"priority=\"55\"" in zypper_result.stdout'
+
+- name: add two repos with same url
+ community.general.zypper_repository:
+ name: "{{item}}"
+ state: present
+ repo: http://dl.google.com/linux/chrome/rpm/stable/x86_64
+ with_items:
+ - chrome1
+ - chrome2
+
+- name: check repo is updated by url
+ command: zypper lr chrome1
+ register: zypper_result1
+ ignore_errors: true
+
+- name: check repo is updated by url
+ command: zypper lr chrome2
+ register: zypper_result2
+
+- name: ensure same url cause update of existing repo even if name differ
+ assert:
+ that:
+ - "zypper_result1.rc != 0"
+ - "'not found' in zypper_result1.stderr"
+ - "zypper_result2.rc == 0"
+ - "'http://dl.google.com/linux/chrome/rpm/stable/x86_64' in zypper_result2.stdout"
+
+- name: add two repos with same name
+ community.general.zypper_repository:
+ name: samename
+ state: present
+ repo: "{{ item }}"
+ with_items:
+ - http://download.opensuse.org/repositories/science/openSUSE_Leap_{{ ansible_distribution_version }}/
+ - http://download.opensuse.org/repositories/devel:/languages:/ruby/openSUSE_Leap_{{ ansible_distribution_version }}/
+
+- name: check repo is updated by name
+ command: zypper lr samename
+ register: zypper_result
+
+- name: ensure url get updated on repo with same name
+ assert:
+ that:
+ - "'/science/' not in zypper_result.stdout"
+ - "'/devel:/languages:/ruby/' in zypper_result.stdout"
+
+- name: remove last added repos (by URL to test that)
+ community.general.zypper_repository:
+ repo: http://download.opensuse.org/repositories/devel:/languages:/ruby/openSUSE_Leap_{{ ansible_distribution_version }}/
+ state: absent
+
+# FIXME: this currently fails with `Repository 'Apache_PHP_Modules' is invalid.`
+# - name: "Test adding a repo with custom GPG key"
+# community.general.zypper_repository:
+# name: "Apache_PHP_Modules"
+# repo: "http://download.opensuse.org/repositories/server:/php:/applications/openSUSE_Tumbleweed/"
+# priority: 100
+# auto_import_keys: true
+# state: "present"
+
+- name: add a repo by releasever
+ community.general.zypper_repository:
+ name: releaseverrepo
+ repo: http://download.opensuse.org/repositories/devel:/languages:/ruby/openSUSE_Leap_$releasever/
+ state: present
+ register: add_repo
+
+- name: add a repo by releasever again
+ community.general.zypper_repository:
+ name: releaseverrepo
+ repo: http://download.opensuse.org/repositories/devel:/languages:/ruby/openSUSE_Leap_$releasever/
+ state: present
+ register: add_repo_again
+
+- name: no update in case of $releasever usage in url
+ assert:
+ that:
+ - add_repo is changed
+ - add_repo_again is not changed
+
+- name: remove added repo
+ community.general.zypper_repository:
+ repo: http://download.opensuse.org/repositories/devel:/languages:/ruby/openSUSE_Leap_{{ ansible_distribution_version }}/
+ state: absent
+ register: remove_repo
+
+- name: verify repo was removed
+ assert:
+ that:
+ - remove_repo is changed
+
+- name: get list of files in /etc/zypp/repos.d/
+ command: ls /etc/zypp/repos.d/
+ changed_when: false
+ register: releaseverrepo_etc_zypp_reposd
+
+- name: verify removal of file releaseverrepo.repo in /etc/zypp/repos.d/
+ assert:
+ that:
+ - "'releaseverrepo' not in releaseverrepo_etc_zypp_reposd.stdout"
+
+- name: add a repo by basearch
+ community.general.zypper_repository:
+ name: basearchrepo
+ repo: https://packagecloud.io/netdata/netdata/opensuse/13.2/$basearch
+ state: present
+ register: add_repo
+
+- name: add a repo by basearch again
+ community.general.zypper_repository:
+ name: basearchrepo
+ repo: https://packagecloud.io/netdata/netdata/opensuse/13.2/$basearch
+ state: present
+ register: add_repo_again
+
+- name: no update in case of $basearch usage in url
+ assert:
+ that:
+ - add_repo is changed
+ - add_repo_again is not changed
+
+- name: remove added repo
+ community.general.zypper_repository:
+ repo: https://packagecloud.io/netdata/netdata/opensuse/13.2/x86_64
+ state: absent
+ register: remove_repo
+
+- name: verify repo was removed
+ assert:
+ that:
+ - remove_repo is changed
+
+# For now, the URL does not work for 15.4
+# FIXME: Try to get this working with newer versions
+# (Maybe 'Uyuni' needs to be replaced with something else?)
+- when: ansible_distribution_version is version('15.4', '<')
+ block:
+ - name: add new repository via url to .repo file
+ community.general.zypper_repository:
+ repo: http://download.opensuse.org/repositories/systemsmanagement:/Uyuni:/Stable/openSUSE_Leap_{{ ansible_distribution_version }}/systemsmanagement:Uyuni:Stable.repo
+ state: present
+ register: added_by_repo_file
+
+ - name: get repository details from zypper
+ command: zypper lr systemsmanagement_Uyuni_Stable
+ register: get_repository_details_from_zypper
+
+ - name: verify adding via .repo file was successful
+ assert:
+ that:
+ - "added_by_repo_file is changed"
+ - "get_repository_details_from_zypper.rc == 0"
+ - "'/systemsmanagement:/Uyuni:/Stable/' in get_repository_details_from_zypper.stdout"
+
+ - name: add same repository via url to .repo file again to verify idempotency
+ community.general.zypper_repository:
+ repo: http://download.opensuse.org/repositories/systemsmanagement:/Uyuni:/Stable/openSUSE_Leap_{{ ansible_distribution_version }}/systemsmanagement:Uyuni:Stable.repo
+ state: present
+ register: added_again_by_repo_file
+
+ - name: verify nothing was changed adding a repo with the same .repo file
+ assert:
+ that:
+ - added_again_by_repo_file is not changed
+
+ - name: remove repository via url to .repo file
+ community.general.zypper_repository:
+ repo: http://download.opensuse.org/repositories/systemsmanagement:/Uyuni:/Stable/openSUSE_Leap_{{ ansible_distribution_version }}/systemsmanagement:Uyuni:Stable.repo
+ state: absent
+ register: removed_by_repo_file
+
+ - name: get list of files in /etc/zypp/repos.d/
+ command: ls /etc/zypp/repos.d/
+ changed_when: false
+ register: etc_zypp_reposd
+
+ - name: verify removal via .repo file was successful, including cleanup of local .repo file in /etc/zypp/repos.d/
+ assert:
+ that:
+ - "removed_by_repo_file"
+ - "'/systemsmanagement:/Uyuni:/Stable/' not in etc_zypp_reposd.stdout"
+
+# FIXME: THIS DOESN'T SEEM TO WORK ANYMORE WITH ANY OPENSUSE VERSION IN CI!
+- when: false
+ block:
+ - name: Copy test .repo file
+ copy:
+ src: 'files/systemsmanagement_Uyuni_Utils.repo'
+ dest: '{{ remote_tmp_dir }}'
+
+ - name: add new repository via local path to .repo file
+ community.general.zypper_repository:
+ repo: "{{ remote_tmp_dir }}/systemsmanagement_Uyuni_Utils.repo"
+ state: present
+ register: added_by_repo_local_file
+
+ - name: get repository details for systemsmanagement_Uyuni_Utils from zypper
+ command: zypper lr systemsmanagement_Uyuni_Utils
+ register: get_repository_details_from_zypper_for_systemsmanagement_Uyuni_Utils
+
+ - name: verify adding repository via local .repo file was successful
+ assert:
+ that:
+ - "added_by_repo_local_file is changed"
+ - "get_repository_details_from_zypper_for_systemsmanagement_Uyuni_Utils.rc == 0"
+ - "'/systemsmanagement:/Uyuni:/Utils/' in get_repository_details_from_zypper_for_systemsmanagement_Uyuni_Utils.stdout"